summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--brdf.cginc2
-rw-r--r--lighting.cginc70
2 files changed, 67 insertions, 5 deletions
diff --git a/brdf.cginc b/brdf.cginc
index 2260c96..c2ebc22 100644
--- a/brdf.cginc
+++ b/brdf.cginc
@@ -108,6 +108,7 @@ float4 brdf(Pbr pbr, LightData data) {
}
// Indirect
+#if defined(FORWARD_BASE_PASS)
if (true) {
float remainder = 1.0f;
#if defined(_CLEARCOAT)
@@ -127,6 +128,7 @@ float4 brdf(Pbr pbr, LightData data) {
float3 indirect_diffuse = Fd * remainder * pbr.albedo.xyz * data.indirect.diffuse;
diffuse += indirect_diffuse;
}
+#endif
return float4(diffuse + specular, 1);
}
diff --git a/lighting.cginc b/lighting.cginc
index 66b7220..5055798 100644
--- a/lighting.cginc
+++ b/lighting.cginc
@@ -98,11 +98,71 @@ float3 getIndirectSpecular(v2f i, float roughness, float3 view_dir, float3 refle
}
float3 yumSH9(float4 n, float3 worldPos, inout LightIndirect light) {
- LightVolumeSH(worldPos, light.L00, light.L01r, light.L01g, light.L01b);
- return light.L00 + float3(
- dot(light.L01r, n.xyz),
- dot(light.L01g, n.xyz),
- dot(light.L01b, n.xyz));
+ [branch]
+ if (_UdonLightVolumeEnabled) {
+ LightVolumeSH(worldPos, light.L00, light.L01r, light.L01g, light.L01b);
+ return light.L00 + float3(
+ dot(light.L01r, n.xyz),
+ dot(light.L01g, n.xyz),
+ dot(light.L01b, n.xyz));
+ }
+
+ // No light volumes - use SH9
+ // Unity gives us the first three bands (L0-L2) of SH coefficients as follows:
+ // unity_SHA*.w: L0 coefficients
+ // unity_SHA*.xyz: L1 coefficients
+ // unity_SHB*: first four of the L2 coefficients
+ // unity_SHC: last L2 coefficient
+
+ // Parse out coefficients into a simpler but less efficient format.
+ float3 L00 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
+ float3 L1_1 = float3(unity_SHAr.x, unity_SHAg.x, unity_SHAb.x);
+ float3 L10 = float3(unity_SHAr.y, unity_SHAg.y, unity_SHAb.y);
+ float3 L11 = float3(unity_SHAr.z, unity_SHAg.z, unity_SHAb.z);
+ float3 L2_2 = float3(unity_SHBr.x, unity_SHBg.x, unity_SHBb.x);
+ float3 L2_1 = float3(unity_SHBr.y, unity_SHBg.y, unity_SHBb.y);
+ float3 L20 = float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z);
+ float3 L21 = float3(unity_SHBr.w, unity_SHBg.w, unity_SHBb.w);
+ float3 L22 = unity_SHC;
+
+ // Equation 13 from "An Efficient Representation for Irradiance Environment
+ // Maps" by Ramamoorthi and Hanrahan. Note that the order of some
+ // coefficients is different, and normalization constants have been
+ // premultiplied by Unity.
+ float3 L0 = L00;
+ float3 L1 = L1_1 * n.x + L10 * n.y + L11 * n.z;
+ float3 L2 =
+ L2_2 * n.x * n.y +
+ L2_1 * n.y * n.z +
+ L20 * n.z * n.z +
+ L21 * n.x * n.z +
+ L22 * (n.x * n.x - n.y * n.y);
+
+ // TODO expose this as a parameter
+ float wrap_term = 0.0f;
+ // Original coefficients: 1, 2/3, 1/4.
+ // Wrapped coefficients: 1, (2-w)/3, ((1-w)^2)/4.
+
+ // Setting w=0, the l1 band is:
+ // (2-w)/3 = 2/3
+ // 2-w = 2
+ // 1-w/2 = 1
+ float l1_wrap = 1.0f - wrap_term * 0.75f;
+ L1 *= l1_wrap;
+
+ // The l2 band is:
+ // ((1-w)^2)/4 = 1/4
+ // (1-w)^2 = 1
+ float l2_wrap = (1.0f-wrap_term);
+ l2_wrap *= l2_wrap;
+ L2 *= l2_wrap;
+
+ light.L00 = L00;
+ light.L01r = unity_SHAr.xyz * l1_wrap;
+ light.L01g = unity_SHAg.xyz * l1_wrap;
+ light.L01b = unity_SHAb.xyz * l1_wrap;
+
+ return L0 + L1 + L2;
}
float4 getIndirectDiffuse(v2f i, Pbr pbr, inout LightIndirect light) {