diff --git a/neo/renderer/RenderBackend.cpp b/neo/renderer/RenderBackend.cpp index 2e81dd34..e21edc08 100644 --- a/neo/renderer/RenderBackend.cpp +++ b/neo/renderer/RenderBackend.cpp @@ -3385,7 +3385,13 @@ void idRenderBackend::ShadowMapPass( const drawSurf_t* drawSurfs, const viewLigh lightProjectionMatrix[0 * 4 + 2] = 0.0f; lightProjectionMatrix[1 * 4 + 2] = 0.0f; lightProjectionMatrix[2 * 4 + 2] = -0.999f; // adjust value to prevent imprecision issues + +#if 0 //defined( USE_NVRHI ) + // the D3D clip space Z is in range [0,1] instead of [-1,1] + lightProjectionMatrix[3 * 4 + 2] = -zNear; +#else lightProjectionMatrix[3 * 4 + 2] = -2.0f * zNear; +#endif lightProjectionMatrix[0 * 4 + 3] = 0.0f; lightProjectionMatrix[1 * 4 + 3] = 0.0f; @@ -3404,6 +3410,18 @@ void idRenderBackend::ShadowMapPass( const drawSurf_t* drawSurfs, const viewLigh shadowV[0] = lightViewRenderMatrix; shadowP[0] = lightProjectionRenderMatrix; + +#if defined( USE_NVRHI ) + // Calculate alternate matrix that maps to [0, 1] UV space instead of [-1, 1] clip space + ALIGNTYPE16 const idRenderMatrix matClipToUvzw( + 0.5f, 0.0f, 0.0f, 0.5f, + 0.0f, -0.5f, 0.0f, 0.5f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + ); + + idRenderMatrix::Multiply( matClipToUvzw, lightProjectionRenderMatrix, shadowP[0] ); +#endif } @@ -3411,14 +3429,13 @@ void idRenderBackend::ShadowMapPass( const drawSurf_t* drawSurfs, const viewLigh #if defined( USE_NVRHI ) if( side < 0 ) { - side = 0; + globalFramebuffers.shadowFBO[vLight->shadowLOD][0]->Bind(); } - if( side > 5 ) + else { - side = 5; + globalFramebuffers.shadowFBO[vLight->shadowLOD][side]->Bind(); } - globalFramebuffers.shadowFBO[vLight->shadowLOD][side]->Bind(); GL_ViewportAndScissor( 0, 0, shadowMapResolutions[vLight->shadowLOD], shadowMapResolutions[vLight->shadowLOD] ); @@ -3478,9 +3495,11 @@ void idRenderBackend::ShadowMapPass( const drawSurf_t* drawSurfs, const viewLigh if( drawSurf->space != currentSpace ) { + // model -> world idRenderMatrix modelRenderMatrix; idRenderMatrix::Transpose( *( idRenderMatrix* )drawSurf->space->modelMatrix, modelRenderMatrix ); + // world -> light = light camera view of model in Doom idRenderMatrix modelToLightRenderMatrix; idRenderMatrix::Multiply( lightViewRenderMatrix, modelRenderMatrix, modelToLightRenderMatrix ); @@ -3489,6 +3508,7 @@ void idRenderBackend::ShadowMapPass( const drawSurf_t* drawSurfs, const viewLigh if( vLight->parallel ) { + // cascaded sun light shadowmap idRenderMatrix MVP; idRenderMatrix::Multiply( renderMatrix_clipSpaceToWindowSpace, clipMVP, MVP ); @@ -3496,7 +3516,7 @@ void idRenderBackend::ShadowMapPass( const drawSurf_t* drawSurfs, const viewLigh } else if( side < 0 ) { - // from OpenGL view space to OpenGL NDC ( -1 : 1 in XYZ ) + // spot light idRenderMatrix MVP; idRenderMatrix::Multiply( renderMatrix_windowSpaceToClipSpace, clipMVP, MVP ); @@ -3504,6 +3524,7 @@ void idRenderBackend::ShadowMapPass( const drawSurf_t* drawSurfs, const viewLigh } else { + // point light RB_SetMVP( clipMVP ); } diff --git a/neo/shaders/builtin/lighting/interactionSM.ps.hlsl b/neo/shaders/builtin/lighting/interactionSM.ps.hlsl index 99ff2164..53a005c7 100644 --- a/neo/shaders/builtin/lighting/interactionSM.ps.hlsl +++ b/neo/shaders/builtin/lighting/interactionSM.ps.hlsl @@ -204,6 +204,7 @@ void main( PS_IN fragment, out PS_OUT result ) return; #endif + // rpShadowMatrices contain model -> world -> shadow transformation for evaluation float4 shadowMatrixX = rpShadowMatrices[ int ( shadowIndex * 4 + 0 ) ]; float4 shadowMatrixY = rpShadowMatrices[ int ( shadowIndex * 4 + 1 ) ]; float4 shadowMatrixZ = rpShadowMatrices[ int ( shadowIndex * 4 + 2 ) ]; @@ -211,6 +212,7 @@ void main( PS_IN fragment, out PS_OUT result ) float4 modelPosition = float4( fragment.texcoord7.xyz, 1.0 ); + float4 shadowTexcoord; shadowTexcoord.x = dot4( modelPosition, shadowMatrixX ); shadowTexcoord.y = dot4( modelPosition, shadowMatrixY ); @@ -309,7 +311,7 @@ void main( PS_IN fragment, out PS_OUT result ) shadow *= stepSize; -#elif 1 +#elif 0 #if 0 @@ -391,9 +393,46 @@ void main( PS_IN fragment, out PS_OUT result ) #endif #else - float shadow = idtex2Dproj( samp1, t_ShadowMapArray, shadowTexcoord ); + float3 uvzShadow; + uvzShadow.x = shadowTexcoord.x; + uvzShadow.y = shadowTexcoord.y; + uvzShadow.z = shadowTexcoord.w; + float shadow = t_ShadowMapArray.SampleCmpLevelZero( samp2, uvzShadow, shadowTexcoord.z ); + +#if 1 + if( shadowIndex == 0 ) + { + result.color = float4( 1.0, 0.0, 0.0, 1.0 ); + } + else if( shadowIndex == 1 ) + { + result.color = float4( 0.0, 1.0, 0.0, 1.0 ); + } + else if( shadowIndex == 2 ) + { + result.color = float4( 0.0, 0.0, 1.0, 1.0 ); + } + else if( shadowIndex == 3 ) + { + result.color = float4( 1.0, 1.0, 0.0, 1.0 ); + } + else if( shadowIndex == 4 ) + { + result.color = float4( 1.0, 0.0, 1.0, 1.0 ); + } + else if( shadowIndex == 5 ) + { + result.color = float4( 0.0, 1.0, 1.0, 1.0 ); + } + + result.color.rgb *= shadow; + return; #endif +#endif + + + half3 halfAngleVector = normalize( lightVector + viewVector ); half hdotN = clamp( dot3( halfAngleVector, localNormal ), 0.0, 1.0 );