Integrating Bakery shader features to custom shaders

From Bakery GPU Lightmapper: Wiki
Revision as of 21:27, 5 May 2024 by Mr F (talk | contribs) (Examples)
Jump to navigation Jump to search

If you have a custom shader but want to add support for e.g.

...there are a few steps you need to take:

Include the functions

1. You can use existing functions from Bakery.cginc, but the easiest starting point is including BakeryDecodeLightmap.hlsl which comes with the URP graph package (starting with URP graphs (rev 5.1) (16.0.4)). The latest package is always listed and freely downloadable from the main page. Unpack the package, copy the file to your shaders' folder and include it:

#define NOURP // add this if you're not on URP
#define SURFACE // add this if it's a surface shader
#include "BakeryDecodeLightmap.hlsl"


Select and call a function

2. Select a function for the desired feature and call it. For example:


(In the following functions normalWorld and viewDir are always world-space).


void LightmapUV_float(float2 uv, out float2 lightmapUV)

Computes final lightmap UV by applying renderer.lightmapScaleOffset to UV2. Following functions expect lightmapUV to be transformed this way.



void DirectionalSpecular_float(float2 lightmapUV, float3 normalWorld, float3 viewDir, float smoothness, out float3 color)

Computes approximate specular from a directional lightmap. color will contain new specular highlights.



BakerySH_float(float3 L0, float3 normalWorld, float2 lightmapUV, out float3 sh)

Samples Bakery SH lightmaps. L0 must be the default lightmap (decoded unity_Lightmap) value. sh will contain new diffuse lighting.



BakeryMonoSH_float(float3 normalWorld, float2 lightmapUV, out float3 sh) // samples Bakery MonoSH lightmaps

Samples Bakery MonoSH lightmaps. sh will contain new diffuse lighting.



void BakerySpecSHFull_float(float3 L0, float3 normalWorld, float2 lightmapUV, float3 viewDir, float smoothness, float3 albedo, float metalness, out float3 diffuseSH, out float3 specularSH)

Samples Bakery SH lightmaps and computes approximate specular from them. L0 must be the default lightmap (decoded unity_Lightmap) value. diffuseSH will contain new diffuse lighting; specularSH will contain new specular highlights.



void BakerySpecMonoSHFull_float(float3 normalWorld, float2 lightmapUV, float3 viewDir, float smoothness, float3 albedo, float metalness, out float3 diffuseSH, out float3 specularSH)

Samples Bakery MonoSH lightmaps and computes approximate specular from them. diffuseSH will contain new diffuse lighting; specularSH will contain new specular highlights.



BakeryVolume_float(float3 posWorld, float3 normalWorld, out float3 sh)

Samples Bakery Volumes. sh will contain new diffuse lighting.



void BakeryVolumeSpec_float(float3 posWorld, float3 normalWorld, float3 viewDir, float smoothness, float3 albedo, float metalness, out float3 diffuseSH, out float3 specularSH)

Samples Bakery Volumes and computes approximate specular from them. diffuseSH will contain new diffuse lighting; specularSH will contain new specular highlights.



void NonLinearLightProbe_float(float3 normalWorld, out float3 color)

Samples light probes in a non-linear way, fixing negative color artifacts. color will contain new diffuse lighting.



Use the computed data

3. Given new diffuse/specular lighting, apply it to your shading calculations. The simplest approach would be:

albedo * diffuseLighting + specularLighting

However, if you want to take fresnel, metalness, specular color, and other properties into account, you can use this complex function:

void WeightReflection2_float(float smoothness, float metallic, float occlusion, float3 baseColor, float3 worldPos, float3 normal, float3 viewDir, float3 diffuse, float3 specular, float3 specularColor, out float3 newDiffuse, out float3 newSpecular)

After that just output (newDiffuse + newSpecular).


If you use a surface shader or a shader graph that doesn't allow outputting final color, a typical workaround is:

  • Set Occlusion to 0 to cancel built-in indirect lighting and reflections.
  • Add reflections back to newSpecular. You can use this function:
void GetReflectionProjected_float(float3 worldPos, float3 viewDir, float3 normal, float lod, out float3 reflection)
  • Output final computed color to Emission.

Examples

Minimal unlit shader using SH lightmaps

Minimal surface shader using SH lightmaps