diff options
| author | yum <yum.food.vr@gmail.com> | 2025-02-12 16:10:26 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2025-02-12 16:10:26 -0800 |
| commit | 19bdcec2b69aff8b75d5c9c6c4d0cb4d0d9ec5c3 (patch) | |
| tree | 0bbc695c04af083c0c2408d6dbdef35ae386b3f8 /filamented.cginc | |
| parent | caf02458737f93b20978f41613ad5b56e074e154 (diff) | |
fix normal bugs, add normal shadowing
going to remove normal shadowing, it's not worth the complexity
Diffstat (limited to 'filamented.cginc')
| -rw-r--r-- | filamented.cginc | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/filamented.cginc b/filamented.cginc index 2b1e876..b2f2ddb 100644 --- a/filamented.cginc +++ b/filamented.cginc @@ -389,5 +389,94 @@ inline half3 UnityGI_prefilteredRadiance(const UnityGIInput data, return specular; } +// R dither mask +float noiseR2(float2 pixel) { + const float a1 = 0.75487766624669276; + const float a2 = 0.569840290998; + return frac(a1 * float(pixel.x) + a2 * float(pixel.y)); +} + +#if defined(_BUMP_SHADOWS) +struct NormalMapShadowsParam +{ + float4 uv; + float2 dX; + float2 dY; +}; + +NormalMapShadowsParam InitNormalMapShadowsParam(float4 uv) +{ + NormalMapShadowsParam nms; + + nms.uv = uv; + nms.dX = ddx(uv.xy); + nms.dY = ddy(uv.xy); + + return nms; +} + +// Ref: Normal Mapping Shadows by Boris Vorontsov +// Please define a NormalMapShadowsParam parameter +// and SampleNormalMap function to sample the normal map. +float NormalMapShadows (float3 lightDirTangent, NormalMapShadowsParam nmsParam, float noise, + float heightScale, float shadowHardness) +{ + const float screenShadowSamples = 20; + const float hardness = heightScale * shadowHardness; + const float sampleStep = 1.0 / screenShadowSamples; + + float2 dir = lightDirTangent.xy * heightScale; + + // Redundancy can't be helped + float3 normal = UnpackScaleNormal(tex2D(_BumpMap, nmsParam.uv), _BumpScale); + + lightDirTangent = normalize(lightDirTangent); + float tangentNdotL = saturate(dot(lightDirTangent, normal)); + + float currentSample = sampleStep - sampleStep * noise; + + // Skip on backfaces + currentSample += (tangentNdotL <= 0.0); + + /* + From the PDF: + Trace from hit point to light direction and compute sum of dot products + between normal map and light direction. + If slope is bigger than 0, pixel is shadowed. If slope is also bigger + than previous maximal value, increase hardness of shadow. + */ + + float result = 0; + float slope = -tangentNdotL; + float maxslope = 0.0; + for (uint i = 0; i < 1; i++) + { + normal = UnpackScaleNormal(tex2D(_BumpMap, nmsParam.uv + dir * currentSample), _BumpScale); + tangentNdotL = dot(lightDirTangent, normal); + slope = slope - tangentNdotL; + if (slope > maxslope) + { + result += hardness * (1.0-currentSample); + } + maxslope = max(maxslope, slope); + currentSample += sampleStep; + if (currentSample <= 1.0) { + break; + } + } + + return result * sampleStep; +} + +float NormalTangentShadow(float4 texcoords, half3 lightDirTS, float noise) +{ + float _HeightScale = _BumpShadowHeightScale; + float _ShadowHardness = _BumpShadowHardness; + NormalMapShadowsParam nms = InitNormalMapShadowsParam(texcoords); + nms.uv = texcoords; + return NormalMapShadows(lightDirTS, nms, noise, _HeightScale, _ShadowHardness); +} +#endif // _BUMP_SHADOWS + #endif |
