summaryrefslogtreecommitdiffstats
path: root/filamented.cginc
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-02-12 16:10:26 -0800
committeryum <yum.food.vr@gmail.com>2025-02-12 16:10:26 -0800
commit19bdcec2b69aff8b75d5c9c6c4d0cb4d0d9ec5c3 (patch)
tree0bbc695c04af083c0c2408d6dbdef35ae386b3f8 /filamented.cginc
parentcaf02458737f93b20978f41613ad5b56e074e154 (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.cginc89
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