summaryrefslogtreecommitdiffstats
path: root/yum_lighting.cginc
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-02-11 16:54:10 -0800
committeryum <yum.food.vr@gmail.com>2025-02-11 16:54:10 -0800
commit20c32dcb055058b770062b7e9dd07f79d33a8caa (patch)
treea712206014334ab41a012c2cc27086c5f0591c45 /yum_lighting.cginc
parent2dcf39113fab3aac8fe280f3b0ead9cf87fa958d (diff)
Add code
Implement basic diffuse and specular BRDF based heavily on silent's filamented shader.
Diffstat (limited to 'yum_lighting.cginc')
-rw-r--r--yum_lighting.cginc127
1 files changed, 127 insertions, 0 deletions
diff --git a/yum_lighting.cginc b/yum_lighting.cginc
new file mode 100644
index 0000000..d62b95e
--- /dev/null
+++ b/yum_lighting.cginc
@@ -0,0 +1,127 @@
+#ifndef __YUM_LIGHTING_INC
+#define __YUM_LIGHTING_INC
+
+#include "UnityCG.cginc"
+#include "AutoLight.cginc"
+#include "UnityPBSLighting.cginc"
+
+#include "yum_pbr.cginc"
+
+struct YumLighting {
+ float3 view_dir;
+ float3 dir;
+ float3 direct;
+ float3 diffuse;
+ float3 specular;
+ float NoL;
+};
+
+float getShadowAttenuation(v2f i)
+{
+ float attenuation;
+ // This whole block is yoinked from AutoLight.cginc. I needed a way to
+ // control shadow strength so I had to duplicate the code.
+#if defined(DIRECTIONAL_COOKIE)
+ DECLARE_LIGHT_COORD(i, i.worldPos);
+ float shadow = UNITY_SHADOW_ATTENUATION(i, i.worldPos);
+ attenuation = tex2D(_LightTexture0, lightCoord).w;
+#elif defined(POINT_COOKIE)
+ DECLARE_LIGHT_COORD(i, i.worldPos);
+ float shadow = UNITY_SHADOW_ATTENUATION(i, i.worldPos);
+ attenuation = tex2D(_LightTextureB0, dot(lightCoord, lightCoord).rr).r *
+ texCUBE(_LightTexture0, lightCoord).w;
+#elif defined(DIRECTIONAL)
+ float shadow = UNITY_SHADOW_ATTENUATION(i, i.worldPos);
+ attenuation = 1;
+#elif defined(SPOT)
+ DECLARE_LIGHT_COORD(i, i.worldPos);
+ float shadow = UNITY_SHADOW_ATTENUATION(i, i.worldPos);
+ attenuation = (lightCoord.z > 0) * UnitySpotCookie(lightCoord) * UnitySpotAttenuate(lightCoord.xyz);
+#elif defined(POINT)
+ unityShadowCoord3 lightCoord = mul(unity_WorldToLight, unityShadowCoord4(i.worldPos, 1)).xyz;
+ float shadow = UNITY_SHADOW_ATTENUATION(i, i.worldPos);
+ attenuation = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).r;
+#else
+ float shadow = 1;
+ attenuation = 1;
+#endif
+ //attenuation *= lerp(1, shadow, _Shadow_Strength);
+ return attenuation;
+}
+
+float3 getDirectLightDirection(v2f i) {
+#if defined(POINT) || defined(POINT_COOKIE) || defined(SPOT)
+ return normalize((_WorldSpaceLightPos0 - i.worldPos).xyz);
+#else
+ return _WorldSpaceLightPos0;
+#endif
+}
+
+float GetLodRoughness(float roughness) {
+ return (1.0 / UNITY_SPECCUBE_LOD_STEPS) * roughness * (1.7 - 0.7 * roughness);
+}
+
+float3 getIndirectSpecular(v2f i, YumPbr pbr, float3 view_dir) {
+ float roughness = GetLodRoughness(pbr.roughness_perceptual);
+ float3 reflect_dir = reflect(-view_dir, pbr.normal);
+
+ UnityGIInput data;
+ data.worldPos = i.worldPos;
+ data.worldViewDir = view_dir;
+ data.probeHDR[0] = unity_SpecCube0_HDR;
+ data.probeHDR[1] = unity_SpecCube1_HDR;
+#if defined(UNITY_SPECCUBE_BLENDING) || defined(UNITY_SPECCUBE_BOX_PROJECTION)
+ data.boxMin[0] = unity_SpecCube0_BoxMin; // .w holds lerp value for blending
+#endif
+#ifdef UNITY_SPECCUBE_BOX_PROJECTION
+ data.boxMax[0] = unity_SpecCube0_BoxMax;
+ data.probePosition[0] = unity_SpecCube0_ProbePosition;
+ data.boxMax[1] = unity_SpecCube1_BoxMax;
+ data.boxMin[1] = unity_SpecCube1_BoxMin;
+ data.probePosition[1] = unity_SpecCube1_ProbePosition;
+#endif
+ return UnityGI_prefilteredRadiance(data, pbr.roughness_perceptual, reflect_dir);
+}
+
+float4 getIndirectDiffuse(v2f i, float4 vertexLightColor) {
+ float4 diffuse = vertexLightColor;
+#if defined(FORWARD_BASE_PASS)
+#if defined(LIGHTMAP_ON)
+ diffuse.xyz = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uv2));
+#else
+ diffuse.xyz += max(0, BetterSH9(float4(0, 0, 0, 1)));
+#endif
+#endif
+ return diffuse;
+}
+
+YumLighting GetYumLighting(v2f i, YumPbr pbr) {
+ YumLighting light;
+
+ light.view_dir = normalize(_WorldSpaceCameraPos - i.worldPos);
+
+#if defined(POINT) || defined(POINT_COOKIE) || defined(SPOT)
+ light.dir = normalize((_WorldSpaceLightPos0 - i.worldPos).xyz);
+#else
+ light.dir = _WorldSpaceLightPos0;
+#endif
+
+ light.direct = _LightColor0.rgb;
+ // TODO filament's spherical harmonics look nicer than this.
+ // See FilamentLightIndirect.cginc::UnityGI_Irradiance in filamented.
+ //ifex _Spherical_Harmonics==0
+ light.diffuse = max(0, BetterSH9(float4(i.normal, 1)));
+ //endex
+ //ifex _Spherical_Harmonics==1
+ light.diffuse = max(0, BetterSH9(float4(0, 0, 0, 1)));
+ //endex
+
+ light.specular = getIndirectSpecular(i, pbr, light.view_dir);
+
+ light.NoL = saturate(dot(i.normal, light.dir));
+
+ return light;
+}
+
+#endif // __YUM_LIGHTING_INC
+