cnq3/code/renderer/shaders/crp/vl_shadow_sun.hlsl

76 lines
2.8 KiB
HLSL
Raw Permalink Normal View History

/*
===========================================================================
Copyright (C) 2024 Gian 'myT' Schellenbaum
This file is part of Challenge Quake 3 (CNQ3).
Challenge Quake 3 is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Challenge Quake 3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
===========================================================================
*/
// volumetric lighting: sunlight shadow volume
#include "common.hlsli"
#include "scene_view.h.hlsli"
cbuffer RootConstants
{
uint shadowTextureIndex;
uint sourceTextureIndex;
float shadowWorldScale;
float sourceWorldScale;
}
[numthreads(8, 8, 1)]
void cs(uint3 id : SV_DispatchThreadID)
{
RWTexture3D<float> shadowTexture = ResourceDescriptorHeap[shadowTextureIndex];
uint3 shadowSize = GetTextureSize(shadowTexture);
if(any(id.xy >= shadowSize.xy))
{
return;
}
SceneView scene = GetSceneView();
ExtinctionCascade cascade = scene.GetExtinctionCascade(shadowWorldScale);
float3 cameraPosition = scene.cameraPosition;
float accumTrans = 1.0;
if(sourceTextureIndex != 0)
{
SamplerState linearClampSampler = SamplerDescriptorHeap[scene.linearClampSamplerIndex];
Texture3D<float> sourceTexture = ResourceDescriptorHeap[sourceTextureIndex];
int3 index = int3(id.xy, -1);
float3 destPositionSS = AABoxIndexToWorldSpace(index, cameraPosition, shadowSize, shadowWorldScale);
float3 destPositionWS = cameraPosition + mul(scene.sunToZMatrix, destPositionSS - cameraPosition);
float3 sourcePositionSS = cameraPosition + mul(scene.zToSunMatrix, destPositionWS - cameraPosition);
float3 sourceSize = float3(GetTextureSize(sourceTexture));
float3 tc = AABoxWorldSpaceToTC(sourcePositionSS, cameraPosition, sourceSize, sourceWorldScale);
float transmittance = sourceTexture.SampleLevel(linearClampSampler, tc, 0);
accumTrans = transmittance;
}
for(uint d = 0; d < shadowSize.z; d++)
{
uint3 index = uint3(id.xy, d);
float3 voxelPositionSS = AABoxIndexToWorldSpace(index, cameraPosition, shadowSize, shadowWorldScale);
float3 voxelPositionWS = cameraPosition + mul(scene.sunToZMatrix, voxelPositionSS - cameraPosition);
float extinction = max(cascade.ExtinctionAt(voxelPositionWS), 0.0);
float transmittance = saturate(Transmittance(shadowWorldScale, extinction));
accumTrans *= transmittance;
shadowTexture[index] = accumTrans;
}
}