verus/Verus/src/Shaders/Bloom.hlsl

108 lines
2.8 KiB
HLSL

// Copyright (C) 2020, Dmitry Maluev (dmaluev@gmail.com)
#include "Lib.hlsl"
#include "LibDeferredShading.hlsl"
#include "LibDepth.hlsl"
#include "Bloom.inc.hlsl"
ConstantBuffer<UB_BloomVS> g_ubBloomVS : register(b0, space0);
ConstantBuffer<UB_BloomFS> g_ubBloomFS : register(b0, space1);
ConstantBuffer<UB_BloomGodRaysFS> g_ubBloomGodRaysFS : register(b0, space2);
Texture2D g_tex : register(t1, space1);
SamplerState g_sam : register(s1, space1);
Texture2D g_texDepth : register(t1, space2);
SamplerState g_samDepth : register(s1, space2);
Texture2D g_texShadow : register(t2, space2);
SamplerComparisonState g_samShadow : register(s2, space2);
struct VSI
{
VK_LOCATION_POSITION float4 pos : POSITION;
};
struct VSO
{
float4 pos : SV_Position;
float2 tc0 : TEXCOORD0;
};
struct FSO
{
float4 color : SV_Target0;
};
#ifdef _VS
VSO mainVS(VSI si)
{
VSO so;
// Standard quad:
so.pos = float4(mul(si.pos, g_ubBloomVS._matW), 1);
so.tc0 = mul(si.pos, g_ubBloomVS._matV).xy;
return so;
}
#endif
#ifdef _FS
FSO mainFS(VSO si)
{
FSO so;
const float4 rawColor = g_tex.SampleLevel(g_sam, si.tc0, 0.0);
const float3 color = rawColor.rgb * g_ubBloomFS._exposure.x;
const float3 bloom = saturate((color - 1.0) * 0.4);
#ifdef DEF_GOD_RAYS
const float2 ndcPos = ToNdcPos(si.tc0);
const float rawDepth = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0).r;
const float3 posW = DS_GetPosition(rawDepth, g_ubBloomGodRaysFS._matInvVP, ndcPos);
const float3 eyePos = g_ubBloomGodRaysFS._eyePos.xyz;
const float3 toPosW = posW - eyePos;
const float depth = length(toPosW);
const float3 pickingRayDir = toPosW / depth;
const float strength = pow(saturate(dot(g_ubBloomGodRaysFS._dirToSun.xyz, pickingRayDir)), 7.0) * 0.2;
float3 godRays = 0.0;
if (strength > 0.0)
{
const float3 rand = Rand(si.pos.xy);
const int sampleCount = 20;
float acc = 0.0;
[unroll] for (int i = 0; i < sampleCount; ++i)
{
const float pickingRayLen = rand.y + i;
const float3 pos = eyePos + pickingRayDir * pickingRayLen;
const float4 tcShadow = ShadowCoords(float4(pos, 1), g_ubBloomGodRaysFS._matSunShadow, pickingRayLen);
const float shadowMask = SimpleShadowMapCSM(
g_texShadow,
g_samShadow,
tcShadow,
g_ubBloomGodRaysFS._shadowConfig,
g_ubBloomGodRaysFS._splitRanges,
g_ubBloomGodRaysFS._matSunShadow,
g_ubBloomGodRaysFS._matSunShadowCSM1,
g_ubBloomGodRaysFS._matSunShadowCSM2,
g_ubBloomGodRaysFS._matSunShadowCSM3);
acc += shadowMask * step(pickingRayLen, depth);
}
godRays = acc * (1.0 / sampleCount) * g_ubBloomGodRaysFS._sunColor.rgb * g_ubBloomFS._exposure.x * strength;
}
so.color.rgb = bloom + godRays;
#else
so.color.rgb = bloom;
#endif
so.color.a = 1.0;
return so;
}
#endif
//@main:#
//@main:#GodRays GOD_RAYS