wip: Main postprocess
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
#ifndef BLUR_FULLSCREEN_INCLUDED
|
||||
#define BLUR_FULLSCREEN_INCLUDED
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareOpaqueTexture.hlsl"
|
||||
|
||||
float _BlurRadius;
|
||||
float _GlowThreshold;
|
||||
float _GlowIntensity;
|
||||
|
||||
TEXTURE2D_X(_BlurSource);
|
||||
SAMPLER(sampler_BlurSource);
|
||||
float4 _BlurSource_TexelSize;
|
||||
|
||||
float Hash(float2 p)
|
||||
{
|
||||
return frac(sin(dot(p, float2(127.1, 311.7))) * 43758.5453);
|
||||
}
|
||||
|
||||
float3 ApplyGlowThreshold(float3 color)
|
||||
{
|
||||
float luminance = dot(color, float3(0.2126, 0.7152, 0.0722));
|
||||
float mask = smoothstep(_GlowThreshold, _GlowThreshold + 0.3, luminance);
|
||||
return color * mask;
|
||||
}
|
||||
|
||||
void Blur_float
|
||||
(
|
||||
float2 UV,
|
||||
bool IsVertical,
|
||||
out float3 Output
|
||||
)
|
||||
{
|
||||
float rawDepth = SampleSceneDepth(UV);
|
||||
float depthMeters = LinearEyeDepth(rawDepth, _ZBufferParams);
|
||||
float depthFactor = smoothstep(3, 20, depthMeters);
|
||||
|
||||
float stepY = (_BlurRadius * depthFactor) / 6.0;
|
||||
float stepX = stepY * (_BlurSource_TexelSize.w / _BlurSource_TexelSize.z);
|
||||
float jitter = (Hash(UV * _BlurSource_TexelSize.zw) - 0.5) * _BlurRadius * depthFactor * 20.0;
|
||||
|
||||
float2 dir = IsVertical ? float2(0.0, stepY) : float2(stepX, 0.0);
|
||||
|
||||
const int TAPS = 13;
|
||||
const float offsets[13] = { -6.0, -4.7, -3.2, -2.1, -1.2, -0.4, 0.0, 0.4, 1.2, 2.1, 3.2, 4.7, 6.0 };
|
||||
const float weights[13] =
|
||||
{
|
||||
0.00650, 0.02981, 0.07810, 0.14624, 0.22230, 0.27240,
|
||||
0.29000,
|
||||
0.27240, 0.22230, 0.14624, 0.07810, 0.02981, 0.00650
|
||||
};
|
||||
|
||||
float3 centerColor = SAMPLE_TEXTURE2D_X(_BlurSource, sampler_BlurSource, UV).rgb;
|
||||
float3 result = float3(0.0, 0.0, 0.0);
|
||||
float totalWeight = 0.0;
|
||||
|
||||
for (int i = 0; i < TAPS; i++)
|
||||
{
|
||||
float2 offsetUV = UV + dir * (offsets[i] + jitter);
|
||||
float tapRawDepth = SampleSceneDepth(offsetUV);
|
||||
float tapDepth = LinearEyeDepth(tapRawDepth, _ZBufferParams);
|
||||
float depthDiff = abs(tapDepth - depthMeters);
|
||||
float depthWeight = exp(-depthDiff * 0.5);
|
||||
float sw = weights[i] * depthWeight;
|
||||
float3 tapColor = SAMPLE_TEXTURE2D_X(_BlurSource, sampler_BlurSource, offsetUV).rgb;
|
||||
|
||||
// GlowIntensity = 0 → full color blur, GlowIntensity = 1 → bright pixels only
|
||||
float3 contribution = lerp(tapColor, ApplyGlowThreshold(tapColor), saturate(_GlowIntensity));
|
||||
result += contribution * sw;
|
||||
totalWeight += sw;
|
||||
}
|
||||
|
||||
float3 center = lerp(centerColor, ApplyGlowThreshold(centerColor), saturate(_GlowIntensity));
|
||||
|
||||
// Scene color for additive glow compositing
|
||||
float3 sceneColor = SAMPLE_TEXTURE2D_X(_CameraOpaqueTexture, sampler_LinearClamp, UV).rgb;
|
||||
float3 blurred = totalWeight > 0.01 ? result / totalWeight : center;
|
||||
|
||||
// GlowIntensity = 0 → pure blur, GlowIntensity > 0 → scene + additive glow
|
||||
Output = lerp(blurred, sceneColor + blurred, saturate(_GlowIntensity));
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ee8e88c9f1853d42b4be28b04cb1a57
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,131 @@
|
||||
#ifndef ENKI_BILLAL_FULLSCREEN_INCLUDED
|
||||
#define ENKI_BILLAL_FULLSCREEN_INCLUDED
|
||||
#include "Assets/_Content/Shaders/Include/Noises.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareOpaqueTexture.hlsl"
|
||||
#include "Assets/_Content/Shaders/Postprocess/Include/BlurFullscreen.hlsl"
|
||||
|
||||
TEXTURE2D_X(_BlurredTexture);
|
||||
SAMPLER(sampler_BlurredTexture);
|
||||
|
||||
// ─── OUTLINE ────────────────────────────────────────────────────────────────
|
||||
// Width is expressed as a fraction of screen height.
|
||||
// Both depth discontinuities and normal discontinuities contribute.
|
||||
|
||||
float ComputeOutline(float2 uv, float outlineWidthPx, float depthThreshold, float normalThreshold)
|
||||
{
|
||||
// Pixel size in UV space, scaled by desired width
|
||||
float2 texel = outlineWidthPx / float2(_ScreenParams.x, _ScreenParams.y);
|
||||
|
||||
// ── Sample depth at 4 neighbours (Roberts Cross pattern) ────────────────
|
||||
float d0 = LinearEyeDepth(SampleSceneDepth(uv + float2(texel.x, texel.y)), _ZBufferParams);
|
||||
float d1 = LinearEyeDepth(SampleSceneDepth(uv + float2(-texel.x, texel.y)), _ZBufferParams);
|
||||
float d2 = LinearEyeDepth(SampleSceneDepth(uv + float2(texel.x, -texel.y)), _ZBufferParams);
|
||||
float d3 = LinearEyeDepth(SampleSceneDepth(uv + float2(-texel.x, -texel.y)), _ZBufferParams);
|
||||
|
||||
// Roberts Cross gradient magnitude on depth
|
||||
float depthEdge = sqrt(pow(d0 - d3, 2) + pow(d1 - d2, 2));
|
||||
|
||||
// Normalise by depth so far geometry doesn't get thick outlines
|
||||
float dCenter = LinearEyeDepth(SampleSceneDepth(uv), _ZBufferParams);
|
||||
depthEdge /= (dCenter + 1e-4);
|
||||
|
||||
// ── Sample normals at the same 4 neighbours ──────────────────────────────
|
||||
float3 n0 = SampleSceneNormals(uv + float2(texel.x, texel.y));
|
||||
float3 n1 = SampleSceneNormals(uv + float2(-texel.x, texel.y));
|
||||
float3 n2 = SampleSceneNormals(uv + float2(texel.x, -texel.y));
|
||||
float3 n3 = SampleSceneNormals(uv + float2(-texel.x, -texel.y));
|
||||
|
||||
// Dot-product difference: 0 = identical normals, 1 = orthogonal / flipped
|
||||
float normalEdge = 0;
|
||||
normalEdge += 1.0 - saturate(dot(n0, n3));
|
||||
normalEdge += 1.0 - saturate(dot(n1, n2));
|
||||
normalEdge *= 0.5;
|
||||
|
||||
// ── Combine and threshold ────────────────────────────────────────────────
|
||||
float edge = max(
|
||||
step(depthThreshold, depthEdge),
|
||||
step(normalThreshold, normalEdge)
|
||||
);
|
||||
|
||||
return edge;
|
||||
}
|
||||
|
||||
void EnkiBillalFullscreen_float
|
||||
(
|
||||
float2 UV,
|
||||
float Test,
|
||||
out float3 Output
|
||||
)
|
||||
{
|
||||
float2 screenUV = UV;
|
||||
|
||||
// DEPTH
|
||||
|
||||
float rawDepth = SampleSceneDepth(screenUV);
|
||||
float depthMeters = LinearEyeDepth(rawDepth, _ZBufferParams); // linear eye-space depth in metres
|
||||
float depth01 = Linear01Depth(rawDepth, _ZBufferParams); // normalised linear depth [0..1]
|
||||
|
||||
// POSITION WORLD SPACE
|
||||
|
||||
// Remap depth for non-reversed-Z platforms before reconstruction
|
||||
float depthForReconstruct = rawDepth;
|
||||
#if !UNITY_REVERSED_Z
|
||||
depthForReconstruct = lerp(UNITY_NEAR_CLIP_VALUE, 1.0, rawDepth);
|
||||
#endif
|
||||
// ComputeWorldSpacePosition handles perspective divide and platform differences
|
||||
float3 positionWS = ComputeWorldSpacePosition(screenUV, depthForReconstruct, UNITY_MATRIX_I_VP);
|
||||
|
||||
|
||||
// NORMAL WORLD SPACE
|
||||
|
||||
// Requires DepthNormals PrePass to be enabled in the URP Renderer
|
||||
float3 normalWS = SampleSceneNormals(screenUV);
|
||||
|
||||
// SCENE COLOR
|
||||
|
||||
float3 originColor = SampleSceneColor(screenUV);
|
||||
|
||||
float3 sceneColorBlurred = SAMPLE_TEXTURE2D_X(_BlurredTexture, sampler_BlurredTexture, screenUV).rgb;
|
||||
|
||||
float greyscale = (originColor.x + originColor.y + originColor.z);
|
||||
float greyscaleBlurred = (sceneColorBlurred.x + sceneColorBlurred.y + sceneColorBlurred.z);
|
||||
|
||||
float hilightMask = smoothstep(.7, 1, greyscale);
|
||||
hilightMask = lerp(hilightMask, smoothstep(.7, 1, greyscaleBlurred), .5);
|
||||
hilightMask *= pow(smoothstep(3, 20, depthMeters), 2);
|
||||
|
||||
float offsetMask = hilightMask;
|
||||
float3 offset3D = PerlinColor3D(positionWS * float3(1, 6, 1), 1);
|
||||
offset3D = smoothstep(.45, .55, offset3D);
|
||||
|
||||
float3 offsetUV = offset3D * offsetMask * .4 / depthMeters;
|
||||
|
||||
float3 sceneColor = SampleSceneColor(screenUV + offsetUV);
|
||||
sceneColor = lerp(sceneColor, sceneColorBlurred, hilightMask);
|
||||
sceneColor = lerp(sceneColor, originColor, .5);
|
||||
sceneColor = lerp(sceneColor * .5, sceneColor * 1, hilightMask);
|
||||
|
||||
//float3 sceneColor = SAMPLE_TEXTURE2D_X(_CameraOpaqueTexture, sampler_PointClamp, screenUV).rgb;
|
||||
|
||||
// OUTLINE
|
||||
|
||||
float OutlineWidthPx = max(PerlinNoise3D(positionWS, 1) * 3 - 1, 0);
|
||||
float OutlineDepthThreshold = .03;
|
||||
float OutlineNormalThreshold = .35;
|
||||
float OutlineColor = float3(0, 0, 0);
|
||||
|
||||
// Width is normalised to screen height so it stays consistent at any resolution.
|
||||
float widthInPixels = OutlineWidthPx * (_ScreenParams.y / 1080.0);
|
||||
|
||||
float outline = ComputeOutline(screenUV, widthInPixels, OutlineDepthThreshold, OutlineNormalThreshold);
|
||||
sceneColor = lerp(sceneColor, OutlineColor, outline);
|
||||
|
||||
// OUTPUT
|
||||
|
||||
Output = sceneColor; //BlurSceneColor(screenUV, .1);
|
||||
//Output = offsetMask;
|
||||
//Output = hilightMask; //BlurSceneColor(screenUV, .1);
|
||||
//Output = lerp(originColor, sceneColorBlurred, smoothstep(3, 20, depthMeters));
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7e00f5980c540647a242d8e50cca93a
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user