158 lines
5.2 KiB
HLSL
158 lines
5.2 KiB
HLSL
#include "common.hlsli"
|
|
#include "reflections.hlsli"
|
|
#include "metalic_roughness_ambient.hlsli"
|
|
#include "metalic_roughness_light.hlsli"
|
|
|
|
struct PSInput
|
|
{
|
|
float4 hpos : SV_POSITION;
|
|
float2 texcoord : TEXCOORD0;
|
|
};
|
|
|
|
float IntersectAABB(float3 Dir, float3 Org, float3 Box) {
|
|
float3 RcpDir = rcp(Dir);
|
|
|
|
float3 TNeg = (Box - Org) * RcpDir;
|
|
float3 TPos = -RcpDir * (Box + Org);
|
|
|
|
return max(min(TNeg.x, TPos.x), max(min(TNeg.y, TPos.y), min(TNeg.z, TPos.z)));
|
|
}
|
|
|
|
float HistoryClamp(float3 History, float3 Filtered, float3 aabb_min, float3 aabb_max) {
|
|
float3 Min = min(Filtered, min(aabb_min, aabb_max));
|
|
float3 Max = max(Filtered, max(aabb_min, aabb_max));
|
|
|
|
float3 Avg2 = Max + Min;
|
|
float3 Dir = Filtered - History;
|
|
|
|
float3 Org = History - Avg2 * 0.5f;
|
|
float3 Scale = Max - Avg2 * 0.5f;
|
|
|
|
return saturate(IntersectAABB(Dir, Org, Scale));
|
|
}
|
|
|
|
void sort(inout float4 a1, inout float4 a2) {
|
|
float4 t = min(a1, a2);
|
|
a2 = max(a1, a2);
|
|
a1 = t;
|
|
}
|
|
|
|
float4 median3(float4 a1, float4 a2, float4 a3) {
|
|
sort(a2, a3);
|
|
sort(a1, a2);
|
|
|
|
return min(a2, a3);
|
|
}
|
|
|
|
float4 median5(float4 a1, float4 a2, float4 a3, float4 a4, float4 a5) {
|
|
sort(a1, a2);
|
|
sort(a3, a4);
|
|
sort(a1, a3);
|
|
sort(a2, a4);
|
|
|
|
return median3(a2, a3, a5);
|
|
}
|
|
|
|
float4 median9(float4 a1, float4 a2, float4 a3, float4 a4, float4 a5, float4 a6, float4 a7, float4 a8, float4 a9) {
|
|
sort(a1, a2);
|
|
sort(a3, a4);
|
|
sort(a5, a6);
|
|
sort(a7, a8);
|
|
sort(a1, a3);
|
|
sort(a5, a7);
|
|
sort(a1, a5);
|
|
|
|
sort(a3, a5);
|
|
sort(a3, a7);
|
|
sort(a2, a4);
|
|
sort(a6, a8);
|
|
sort(a4, a8);
|
|
sort(a4, a6);
|
|
sort(a2, a6);
|
|
|
|
return median5(a2, a4, a5, a7, a9);
|
|
}
|
|
|
|
float4 main(PSInput I) : SV_Target
|
|
{
|
|
IXrayGbuffer O;
|
|
GbufferUnpack(I.texcoord.xy, I.hpos.xy, O);
|
|
|
|
float4 SSLR4 = s_image.SampleLevel(smp_nofilter, I.texcoord, 0);
|
|
|
|
if(O.Depth >= 1.0f) {
|
|
return float4(SSLR4.xyz, O.Depth);
|
|
}
|
|
|
|
float4 SSLR0 = s_image.SampleLevel(smp_nofilter, I.texcoord, 0, int2(+1, +0));
|
|
float4 SSLR1 = s_image.SampleLevel(smp_nofilter, I.texcoord, 0, int2(-0, +1));
|
|
float4 SSLR2 = s_image.SampleLevel(smp_nofilter, I.texcoord, 0, int2(-1, -0));
|
|
float4 SSLR3 = s_image.SampleLevel(smp_nofilter, I.texcoord, 0, int2(-0, -1));
|
|
|
|
float4 SSLR5 = s_image.SampleLevel(smp_nofilter, I.texcoord, 0, int2(+1, +1));
|
|
float4 SSLR6 = s_image.SampleLevel(smp_nofilter, I.texcoord, 0, int2(-1, +1));
|
|
float4 SSLR7 = s_image.SampleLevel(smp_nofilter, I.texcoord, 0, int2(-1, -1));
|
|
float4 SSLR8 = s_image.SampleLevel(smp_nofilter, I.texcoord, 0, int2(-1, -1));
|
|
|
|
float4 SSLRBoxMinPos = min(SSLR0, min(SSLR2, min(SSLR6, SSLR8)));
|
|
float4 SSLRBoxMaxPos = max(SSLR0, max(SSLR2, max(SSLR6, SSLR8)));
|
|
|
|
float4 SSLRBoxMin = min(SSLR1, min(SSLR3, min(SSLR5, SSLR7)));
|
|
float4 SSLRBoxMax = max(SSLR1, max(SSLR3, max(SSLR5, SSLR7)));
|
|
|
|
SSLRBoxMinPos = min(SSLRBoxMin, SSLRBoxMinPos);
|
|
SSLRBoxMaxPos = max(SSLRBoxMax, SSLRBoxMaxPos);
|
|
|
|
SSLRBoxMin = SSLRBoxMinPos; //SSLRBoxMin * 0.5f + SSLRBoxMinPos * 0.5f;
|
|
SSLRBoxMax = SSLRBoxMaxPos; //SSLRBoxMax * 0.5f + SSLRBoxMaxPos * 0.5f;
|
|
|
|
float4 SSLRMain = SSLR4; //rcp(9) * (SSLR0 + SSLR1 + SSLR2 + SSLR3 + SSLR4 + SSLR5 + SSLR6 + SSLR7 + SSLR8);
|
|
SSLRMain = median9(SSLR0, SSLR1, SSLR2, SSLR3, SSLR4, SSLR5, SSLR6, SSLR7, SSLR8);
|
|
|
|
float3 Point = gbuf_unpack_position(I.texcoord.xy, O.PointReal.z);
|
|
float3 View = normalize(Point);
|
|
|
|
float Fog = saturate(SSLRMain.w * fog_params.w + fog_params.x);
|
|
float3 ReflectPoint = View.xyz * SSLRMain.w;
|
|
|
|
float2 PrevDiffuseUV = I.texcoord.xy + s_velocity.SampleLevel(smp_rtlinear, I.texcoord.xy, 0).xy * float2(-0.5f, 0.5f);
|
|
float4 PrevSpecularUV = mul(m_VP_old, float4(mul(m_invV, float4(ReflectPoint, 1.0f)).xyz, 1.0f));
|
|
|
|
PrevSpecularUV.xy = PrevSpecularUV.xy / PrevSpecularUV.w * float2(0.5f, -0.5f) + 0.5f;
|
|
PrevSpecularUV.xy = O.Depth > 0.02f ? PrevSpecularUV.xy : PrevDiffuseUV.xy;
|
|
SSLRMain.w = O.Depth;
|
|
|
|
float4 SSLR_OldDiffyse = s_refl.SampleLevel(smp_rtlinear, PrevDiffuseUV.xy, 0.0f);
|
|
SSLR_OldDiffyse = lerp(SSLRMain, SSLR_OldDiffyse, GetBorderAtten(PrevDiffuseUV));
|
|
|
|
float Fade = 1.0f; // - Fog * 0.1f;
|
|
|
|
float DepthClamp = 1.0f - saturate(50.0f * abs(SSLR_OldDiffyse.w - O.Depth));
|
|
|
|
if(O.Depth < 0.02f) {
|
|
Fade = 0.95f - Fog * 0.1f;
|
|
|
|
DepthClamp = 1.0f - saturate(80.0f * abs(SSLR_OldDiffyse.w - O.Depth) * rcp(O.Depth) - 0.5f);
|
|
SSLRMain.xyz = lerp(SSLRMain.xyz, SSLR4.xyz, GetBorderAtten(PrevDiffuseUV));
|
|
SSLRMain.xyz = lerp(SSLRMain.xyz, SSLR_OldDiffyse.xyz, DepthClamp * 0.98f * Fade);
|
|
|
|
return saturate(SSLRMain);
|
|
}
|
|
|
|
float4 SSLR_Diffuse = lerp(SSLRMain, SSLR_OldDiffyse, 0.98f * Fade);
|
|
float4 SSLR_OldSpecular = s_refl.SampleLevel(smp_rtlinear, PrevSpecularUV.xy, 0.0f);
|
|
|
|
SSLR_OldSpecular = lerp(SSLR_Diffuse, SSLR_OldSpecular, GetBorderAtten(PrevSpecularUV));
|
|
|
|
float SpecularFactor = 1.0f - HistoryClamp(SSLR_OldSpecular.xyz, SSLRMain.xyz, SSLRBoxMin.xyz, SSLRBoxMax.xyz);
|
|
SSLR_OldSpecular = lerp(SSLRMain * 0.5f + SSLR_Diffuse * 0.5f, SSLR_OldSpecular, 0.98 * SpecularFactor * Fade);
|
|
|
|
SpecularFactor = 1.0f - saturate(length(PrevDiffuseUV.xy - PrevSpecularUV.xy) * 300.0f);
|
|
float4 SSLR_Specular = lerp(SSLR_OldSpecular, SSLR_Diffuse, 0.95f * SpecularFactor);
|
|
|
|
SSLR_Diffuse.xyz = lerp(SSLR_Specular.xyz, SSLR_Diffuse.xyz, O.Roughness);
|
|
SSLRMain.xyz = lerp(SSLRMain.xyz, SSLR_Diffuse.xyz, DepthClamp);
|
|
|
|
return saturate(SSLRMain);
|
|
}
|
|
|