summaryrefslogtreecommitdiffstats
path: root/lighting.cginc
diff options
context:
space:
mode:
Diffstat (limited to 'lighting.cginc')
-rw-r--r--lighting.cginc140
1 files changed, 140 insertions, 0 deletions
diff --git a/lighting.cginc b/lighting.cginc
new file mode 100644
index 0000000..db3c4ff
--- /dev/null
+++ b/lighting.cginc
@@ -0,0 +1,140 @@
+#ifndef __LIGHTING_INC
+#define __LIGHTING_INC
+
+#include "UnityCG.cginc"
+#include "AutoLight.cginc"
+#include "UnityPBSLighting.cginc"
+#include "UnityLightingCommon.cginc"
+#include "UnityStandardCoreMinimal.cginc"
+
+#include "features.cginc"
+#include "filamented.cginc"
+#include "interpolators.cginc"
+#include "LightVolumes.cginc"
+#include "pbr.cginc"
+
+struct LightCommon {
+ float3 V;
+ float3 N;
+ float NoV;
+};
+
+struct LightDirect {
+ float3 dir;
+
+ float3 H;
+ float NoH;
+ float NoL;
+ float LoH;
+ float LoV;
+ float double_LoV;
+
+ float3 color;
+};
+
+struct LightIndirect {
+ float3 dir;
+
+ float3 H;
+ float NoH;
+ float NoL;
+ float LoH;
+ float LoV;
+ float double_LoV;
+
+ float3 specular;
+ float3 diffuse;
+
+ float3 L00;
+ float3 L01r;
+ float3 L01g;
+ float3 L01b;
+};
+
+struct LightData {
+ LightCommon common;
+ LightDirect direct;
+ LightIndirect indirect;
+};
+
+float3 getDirectLightDirection(v2f i) {
+#if defined(POINT) || defined(POINT_COOKIE) || defined(SPOT)
+ return normalize((_WorldSpaceLightPos0 - i.worldPos).xyz);
+#else
+ return _WorldSpaceLightPos0;
+#endif
+}
+
+float getShadowAttenuation(v2f i)
+{
+ UNITY_LIGHT_ATTENUATION(attenuation, i, i.worldPos);
+ return attenuation;
+}
+
+float4 getDirectLightColorIntensity() {
+ // Properly separate light color from intensity like filamented
+ if (_LightColor0.w <= 0) return float4(0, 0, 0, 0);
+ _LightColor0 += 1e-6f;
+ return float4(_LightColor0.xyz / _LightColor0.w, _LightColor0.w);
+}
+
+float3 getIndirectSpecular(v2f i, Pbr pbr, float3 view_dir, float3 reflect_dir) {
+ UnityGIInput data = InitialiseUnityGIInput(i.worldPos, view_dir);
+ float3 env_refl = UnityGI_prefilteredRadiance(data, pbr.roughness_perceptual, reflect_dir);
+ return env_refl;
+}
+
+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));
+}
+
+float4 getIndirectDiffuse(v2f i, Pbr pbr, inout LightIndirect light) {
+ float4 diffuse = 0;
+#if defined(FORWARD_BASE_PASS)
+ diffuse.xyz += max(0, yumSH9(float4(pbr.normal, 0), i.worldPos, light));
+#endif
+ return diffuse;
+}
+
+void GetLighting(v2f i, Pbr pbr, out LightData data) {
+ data = (LightData) 0;
+
+ float3 view_dir = normalize(i.eyeVec.xyz);
+
+ data.common.V = -view_dir;
+ data.common.N = pbr.normal;
+ data.common.NoV = saturate(dot(pbr.normal, data.common.V));
+
+ // Direct lighting
+ data.direct.dir = getDirectLightDirection(i);
+ data.direct.H = normalize(data.common.V + data.direct.dir);
+ data.direct.NoL = saturate(dot(pbr.normal, data.direct.dir));
+ data.direct.NoH = saturate(dot(pbr.normal, data.direct.H));
+ data.direct.LoH = saturate(dot(data.direct.dir, data.direct.H));
+ float direct_LoV = dot(data.direct.dir, data.common.V);
+ data.direct.LoV = saturate(direct_LoV);
+ data.direct.double_LoV = saturate(2.0f * direct_LoV * direct_LoV - 1.0f);
+
+ float4 lightColorIntensity = getDirectLightColorIntensity();
+ data.direct.color = lightColorIntensity.rgb * lightColorIntensity.w;
+
+ // Indirect lighting
+ data.indirect.dir = -reflect(data.common.V, pbr.normal);
+ data.indirect.H = normalize(data.common.V + data.indirect.dir);
+ data.indirect.NoL = saturate(dot(pbr.normal, data.indirect.dir));
+ data.indirect.NoH = saturate(dot(pbr.normal, data.indirect.H));
+ data.indirect.LoH = saturate(dot(data.indirect.dir, data.indirect.H));
+ float indirect_LoV = dot(data.direct.dir, data.common.V);
+ data.indirect.LoV = saturate(indirect_LoV);
+ data.indirect.double_LoV = saturate(2.0f * indirect_LoV * indirect_LoV - 1.0f);
+
+ data.indirect.diffuse = getIndirectDiffuse(i, pbr, data.indirect);
+ data.indirect.specular = getIndirectSpecular(i, pbr, view_dir, data.indirect.dir);
+}
+
+#endif // __LIGHTING_INC
+