16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-18 22:39:18 +02:00
Files
maszyna/betterRenderer/shaders/manul/shadow.hlsli
2025-04-15 01:32:56 +02:00

88 lines
3.4 KiB
HLSL

#ifndef SHADOW_HLSLI
#define SHADOW_HLSLI
#include "view_data.hlsli"
#include "material_common.hlsli"
#define CASCADE_COUNT 8
cbuffer ShadowProjections : register(b11) {
float4x4 g_CascadeProjections[CASCADE_COUNT];
float4 g_CascadePlanes[(CASCADE_COUNT + 3) / 4];
}
SamplerComparisonState g_ShadowSampler : register(s11);
Texture2DArray<float> g_ShadowMap : register(t11);
float3 PosToShadow(in float4x4 cascade, in float3 pos) {
float4 shadow_view = mul(cascade, float4(pos, 1.));
shadow_view /= shadow_view.w;
shadow_view.xy = shadow_view.xy * float2(.5, -.5) + .5;
return shadow_view.xyz;
}
bool CalculateShadowView(in float4x4 cascade, in float plane, in MaterialData data, out float3 shadow_view, out float3 shadow_view_ddx, out float3 shadow_view_ddy) {
#ifdef DEFERRED_LIGHTING_PASS
if(dot(data.m_Position, data.m_Position) > plane) return false;
shadow_view = PosToShadow(cascade, data.m_Position);
shadow_view_ddx = PosToShadow(cascade, data.m_PositionDDX) - shadow_view;
shadow_view_ddy = PosToShadow(cascade, data.m_PositionDDY) - shadow_view;
return true;
#else
if(dot(data.m_Position, data.m_Position) > plane) return false;
shadow_view = PosToShadow(cascade, data.m_Position);
//if(any(shadow_view <= 0. || shadow_view >= 1.)) return false;
//shadow_view_ddx = PosToShadow(cascade, data.m_Position + ddx(data.m_Position)) - shadow_view;
//shadow_view_ddy = PosToShadow(cascade, data.m_Position + ddy(data.m_Position)) - shadow_view;
return true;
#endif
}
float GetShadow(in float3 view, in MaterialData data) {
float shadow = 1.;
uint3 shadowmap_size;
g_ShadowMap.GetDimensions(shadowmap_size.x, shadowmap_size.y, shadowmap_size.z);
for(int i = 0; i < shadowmap_size.z; ++i) {
float3 shadowView, vShadowTexDDX, vShadowTexDDY;
if(CalculateShadowView(mul(g_CascadeProjections[i], g_InverseModelView), g_CascadePlanes[i / 4][i % 4], data, shadowView, vShadowTexDDX, vShadowTexDDY)) {
shadow = 0.;
#ifdef DEFERRED_LIGHTING_PASS
float2x2 screenToShadow = float2x2(vShadowTexDDX.xy, vShadowTexDDY.xy);
float fDeterminant = determinant(screenToShadow);
float fInvDeterminant = 1.0f / fDeterminant;
float2x2 shadowToScreen = float2x2 (
screenToShadow._22 * fInvDeterminant,
screenToShadow._12 * -fInvDeterminant,
screenToShadow._21 * -fInvDeterminant,
screenToShadow._11 * fInvDeterminant );
float2 vRightTexelDepthRatio = mul( float2(1./shadowmap_size.x, 0.),
shadowToScreen );
float2 vUpTexelDepthRatio = mul( float2(0., 1./shadowmap_size.y),
shadowToScreen );
float fUpTexelDepthDelta =
vUpTexelDepthRatio.x * vShadowTexDDX.z
+ vUpTexelDepthRatio.y * vShadowTexDDY.z;
float fRightTexelDepthDelta =
vRightTexelDepthRatio.x * vShadowTexDDX.z
+ vRightTexelDepthRatio.y * vShadowTexDDY.z;
#endif
[unroll]
for (int y = -1; y <= 1; ++y) {
[unroll]
for (int x = -1; x <= 1; ++x) {
#ifdef DEFERRED_LIGHTING_PASS
shadow += g_ShadowMap.SampleCmpLevelZero(g_ShadowSampler, float3(shadowView.xy, float(i)), shadowView.z + x * fRightTexelDepthDelta + y * fUpTexelDepthDelta, int2(x, y)) / 9.;
#else
shadow += g_ShadowMap.SampleCmpLevelZero(g_ShadowSampler, float3(shadowView.xy, float(i)), shadowView.z, int2(x, y)) / 9.;
#endif
}
}
break;
}
}
return shadow;
}
#endif