From 409fc56a56638b907abf9e270da47d4f174c67fa Mon Sep 17 00:00:00 2001 From: Alexandre Coirier Date: Wed, 10 Jun 2026 22:15:50 +0200 Subject: [PATCH] wip: Main shader --- .../Include/EnkiBillalFullscreen.hlsl | 137 +++++++++++------- 1 file changed, 82 insertions(+), 55 deletions(-) diff --git a/Assets/_Content/Shaders/Postprocess/Include/EnkiBillalFullscreen.hlsl b/Assets/_Content/Shaders/Postprocess/Include/EnkiBillalFullscreen.hlsl index 7a4e1ae2..ae049925 100644 --- a/Assets/_Content/Shaders/Postprocess/Include/EnkiBillalFullscreen.hlsl +++ b/Assets/_Content/Shaders/Postprocess/Include/EnkiBillalFullscreen.hlsl @@ -152,42 +152,52 @@ float BipyramidHatch(float3 PositionWS, float3 NormalWS, float Angle, float Scal return hatchSum / max(weightSum, 0.0001); } -float ComputeOutline(float2 uv, float2 texel, float depthMeters, float3 normalWS, float3 positionWS) +float SampleSceneDepthMeter(float2 UV) +{ + float rawDepth = SampleSceneDepth(UV); + return (LinearEyeDepth(rawDepth, _ZBufferParams)); +} + +float ComputeOutline(float2 UV, float2 Thickness, float3 NormalWS, float3 ViewDir, float DepthMeters, float DepthAtten) { // DEPTH OUTLINE - float depthL = LinearEyeDepth(SampleSceneDepth(uv + float2(-texel.x, 0)), _ZBufferParams); - float depthR = LinearEyeDepth(SampleSceneDepth(uv + float2(texel.x, 0)), _ZBufferParams); - float depthD = LinearEyeDepth(SampleSceneDepth(uv + float2(0, -texel.y)), _ZBufferParams); - float depthU = LinearEyeDepth(SampleSceneDepth(uv + float2(0, texel.y)), _ZBufferParams); + float2 o = Thickness * (1 - DepthAtten); + + float d0 = DepthMeters; + float d1 = SampleSceneDepthMeter(UV + float2(-o.x,0)); + float d2 = SampleSceneDepthMeter(UV + float2( o.x,0)); + float d3 = SampleSceneDepthMeter(UV + float2(0,-o.y)); + float d4 = SampleSceneDepthMeter(UV + float2(0, o.y)); - float depthDiff = - max(abs(depthMeters - depthL), abs(depthMeters - depthR)) + - max(abs(depthMeters - depthD), abs(depthMeters - depthU)); + float depthDiff = max(max(abs(d0 - d1), abs(d0 - d2)), max(abs(d0 - d3), abs(d0 - d4))); - float viewFacing = abs(dot(normalWS, normalize(_WorldSpaceCameraPos - positionWS))); - float grazingMask = smoothstep(0.08, 0.35, viewFacing); - - float depthThreshold = max(0.01, depthMeters * 0.03); - float depthOutline = smoothstep(depthThreshold, depthThreshold * 3.0, depthDiff); - depthOutline *= grazingMask; + float incidence = abs(dot(NormalWS, ViewDir)); + float incidenceAtten = smoothstep(.22, .35, incidence); + + float2 depthMinRange = float2(.15, 0.3); + float2 depthMaxRange = float2(0.5, 1.1); + float2 depthRange = lerp(depthMinRange, depthMaxRange, DepthAtten); + + float depthOutline = smoothstep(depthRange.x, depthRange.y, depthDiff); + depthOutline *= incidenceAtten; // NORMAL OUTLINE + + o *= .5; + + float3 n0 = NormalWS; + float3 n1 = normalize(SampleSceneNormals(UV + float2(-o.x, 0))); + float3 n2 = normalize(SampleSceneNormals(UV + float2( o.x, 0))); + float3 n3 = normalize(SampleSceneNormals(UV + float2(0, -o.y))); + float3 n4 = normalize(SampleSceneNormals(UV + float2(0, o.y))); - float3 normalL = normalize(SampleSceneNormals(uv + float2(-texel.x, 0))); - float3 normalR = normalize(SampleSceneNormals(uv + float2(texel.x, 0))); - float3 normalD = normalize(SampleSceneNormals(uv + float2(0, -texel.y))); - float3 normalU = normalize(SampleSceneNormals(uv + float2(0, texel.y))); + float normalDiff = distance(n0, n1) + distance(n0, n2) + distance(n0, n3) + distance(n0, n4); - float normalDiff = - distance(normalWS, normalL) + - distance(normalWS, normalR) + - distance(normalWS, normalD) + - distance(normalWS, normalU); + float normalOutline = smoothstep(0.6, 0.8, normalDiff) * smoothstep(10, 3, DepthMeters); - float normalOutline = smoothstep(0.6, 0.8, normalDiff); - - return saturate(normalOutline + depthOutline); + return saturate(depthOutline + normalOutline * .8); + //return depthOutline; } void EnkiBillalFullscreen_float @@ -196,13 +206,14 @@ void EnkiBillalFullscreen_float out float3 Output ) { - // DEPTH + // INPUTS + + float3 sceneColor = SampleSceneColor(UV); + float rawDepth = SampleSceneDepth(UV); float depthMeters = LinearEyeDepth(rawDepth, _ZBufferParams); - float depth01 = Linear01Depth(rawDepth, _ZBufferParams); - - // POSITION WORLD SPACE + //float depth01 = Linear01Depth(rawDepth, _ZBufferParams); float depthForReconstruct = rawDepth; #if !UNITY_REVERSED_Z @@ -210,43 +221,57 @@ void EnkiBillalFullscreen_float #endif float3 positionWS = ComputeWorldSpacePosition(UV, depthForReconstruct, UNITY_MATRIX_I_VP); - - // NORMAL WORLD SPACE + + float np1 = PerlinNoise3D(positionWS, 10) * 2 - 1; + float2 uv1 = UV + np1 * lerp(.002, .004, pow(smoothstep(1, 20, depthMeters), 2)); float3 normalWS = normalize(SampleSceneNormals(UV)); - - // SCENE COLOR + float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - positionWS); - float3 sceneColor = SampleSceneColor(UV); - - // SETTINGS + float np2 = RidgedNoise3D(positionWS + np1 * .2, 1, 2, 2, .5) * 1.4 - 1; + float2 uv2 = uv1 + np2 * lerp(0, .04, pow(smoothstep(1, 20, depthMeters), 2)); + + float3 sceneColor2 = SampleSceneColor(uv2); + + // OUTLINE float outlineAtten = smoothstep(3, 30, depthMeters); - float thicknessNoise = (PerlinNoise3D(positionWS, 1.7) - .4) * 18; - thicknessNoise *= sqrt(1 - outlineAtten); + float outline = 0; + float n0 = PerlinNoise3D(positionWS, 80); - float thicknessRaw = lerp(thicknessNoise, 1, outlineAtten); - float thicknessA = floor(thicknessRaw); - float thicknessB = thicknessA + 1; - float thicknessBlend = frac(thicknessRaw); + [Unroll] + for (float i = 0; i < 2; i++) + { + float t = floor(cos((_Time.y + positionWS) * (4 + i * 3) * .8) * .1); + t = 0; + + float n1 = PerlinNoise3D(positionWS + i * 3.3 + n0, 1.7 + 1 * .2 + t); - float2 texelA = (thicknessA * _ScreenParams.y / 1080) / _ScreenParams.xy; - float2 texelB = (thicknessB * _ScreenParams.y / 1080) / _ScreenParams.xy; + float2 thickness = lerp(0, 20, pow(n1, 2)); + thickness = thickness * _ScreenParams.y / 1080 / _ScreenParams.xy; - // OUTLINE + float2 uv = UV; - float2 uvA = UV; - float2 uvB = UV; + outline += ComputeOutline(uv, thickness, normalWS, viewDir, depthMeters, outlineAtten); + } - float outlineA = ComputeOutline(uvA, texelA, depthMeters, normalWS, positionWS); - float outlineB = ComputeOutline(uvB, texelB, depthMeters, normalWS, positionWS); - - float outline = lerp(outlineA, outlineB, thicknessBlend); + outline /= 2; // COLOR (WIP) float3 c = sceneColor; + float3 greyscale = smoothstep(.1, .5, (sceneColor2.r + sceneColor2.g + sceneColor2.b) / 3.); + + //c = lerp(sceneColor, sceneColor2, smoothstep(1, .9, (sceneColor2.r + sceneColor2.g + sceneColor2.b) / 3)); + //c = (sceneColor2.r + sceneColor2.g + sceneColor2.b) / 3.; + c = lerp(c, sceneColor2, (greyscale + smoothstep(5, 35, depthMeters) * .8) * .5); + //c += sceneColor2 * greyscale * .5; + c = lerp(c, float3(.001, .002, .0015), outline); + //c = ((c + 1) * (sceneColor2 + 0)); + //c = sceneColor2; + //c = smoothstep(-.1, 0, np2); + //c = greyscale; /*float3 pWS = positionWS; //scaledPositionOS; float n0 = PerlinNoise3D(pWS, 2); @@ -273,7 +298,7 @@ void EnkiBillalFullscreen_float // SHADOW - float sceneLuminance = dot(sceneColor, float3(.299, .587, .114)); + /*float sceneLuminance = dot(sceneColor, float3(.299, .587, .114)); float hatchAtten = smoothstep(15, 1, depthMeters); @@ -295,11 +320,13 @@ void EnkiBillalFullscreen_float float hatches = saturate(hatchesA + hatchesB * hatchLayerMask * .55); - c = lerp(c, float3(0, 0, 0), hatches * hatchMask * .3); + c = lerp(c, float3(0, 0, 0), hatches * hatchMask * .3);*/ // OUTPUT - Output = lerp(c, float3(0.0, 0.0, 0.0), outline); + Output = c; + Output = sceneColor; //Output = hatchMask; + //Output = dot(normalWS, viewDir); } #endif \ No newline at end of file