Blend normals for SSR blood decals with the background

This commit is contained in:
Robert Beckebans 2024-12-06 17:09:15 +01:00
parent 93affb33af
commit c94b2caef6
7 changed files with 59 additions and 59 deletions

View file

@ -1834,7 +1834,8 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
nvrhi::BindingSetItem::Texture_SRV( 2, ( nvrhi::ITexture* )GetImageAt( 2 )->GetTextureID() ), nvrhi::BindingSetItem::Texture_SRV( 2, ( nvrhi::ITexture* )GetImageAt( 2 )->GetTextureID() ),
nvrhi::BindingSetItem::Texture_SRV( 3, ( nvrhi::ITexture* )GetImageAt( 3 )->GetTextureID() ), nvrhi::BindingSetItem::Texture_SRV( 3, ( nvrhi::ITexture* )GetImageAt( 3 )->GetTextureID() ),
nvrhi::BindingSetItem::Texture_SRV( 4, ( nvrhi::ITexture* )GetImageAt( 4 )->GetTextureID() ), nvrhi::BindingSetItem::Texture_SRV( 4, ( nvrhi::ITexture* )GetImageAt( 4 )->GetTextureID() ),
nvrhi::BindingSetItem::Texture_SRV( 5, ( nvrhi::ITexture* )GetImageAt( 5 )->GetTextureID() ) nvrhi::BindingSetItem::Texture_SRV( 5, ( nvrhi::ITexture* )GetImageAt( 5 )->GetTextureID() ),
nvrhi::BindingSetItem::Texture_SRV( 6, ( nvrhi::ITexture* )GetImageAt( 6 )->GetTextureID() )
}; };
} }
else else
@ -1846,6 +1847,7 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
bindings[3].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 3 )->GetTextureID(); bindings[3].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 3 )->GetTextureID();
bindings[4].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 4 )->GetTextureID(); bindings[4].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 4 )->GetTextureID();
bindings[5].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 5 )->GetTextureID(); bindings[5].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 5 )->GetTextureID();
bindings[6].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 6 )->GetTextureID();
} }
if( R_UsePixelatedLook() ) if( R_UsePixelatedLook() )

View file

@ -490,22 +490,26 @@ void idRenderBackend::PrepareStageTexturing( const shaderStage_t* pStage, const
globalImages->currentRenderImage->Bind(); globalImages->currentRenderImage->Bind();
GL_SelectTexture( 2 ); GL_SelectTexture( 2 );
//if( r_useHierarchicalDepthBuffer.GetBool() ) globalImages->gbufferNormalsRoughnessImage->Bind();
//{
// globalImages->hierarchicalZbufferImage->Bind(); GL_SelectTexture( 3 );
//} if( r_useHierarchicalDepthBuffer.GetBool() )
//else {
// use hierachical Z to avoid read & write at the same time on the depth buffer
globalImages->hierarchicalZbufferImage->Bind();
}
else
{ {
globalImages->currentDepthImage->Bind(); globalImages->currentDepthImage->Bind();
} }
GL_SelectTexture( 3 ); GL_SelectTexture( 4 );
viewDef->radianceImages[0]->Bind(); viewDef->radianceImages[0]->Bind();
GL_SelectTexture( 4 ); GL_SelectTexture( 5 );
viewDef->radianceImages[1]->Bind(); viewDef->radianceImages[1]->Bind();
GL_SelectTexture( 5 ); GL_SelectTexture( 6 );
viewDef->radianceImages[2]->Bind(); viewDef->radianceImages[2]->Bind();
GL_SelectTexture( 0 ); GL_SelectTexture( 0 );
@ -2207,13 +2211,13 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
if( fillGbuffer ) if( fillGbuffer )
{ {
commandList->clearTextureFloat( globalImages->gbufferNormalsRoughnessImage->GetTextureHandle(), nvrhi::AllSubresources, nvrhi::Color( 0.f ) ); commandList->clearTextureFloat( globalImages->gbufferNormalsRoughnessImage->GetTextureHandle(), nvrhi::AllSubresources, nvrhi::Color( 0.0f ) );
} }
// RB: TODO remove this // RB: TODO remove this
if( !fillGbuffer && r_useSSAO.GetBool() && r_ssaoDebug.GetBool() ) if( !fillGbuffer && r_useSSAO.GetBool() && r_ssaoDebug.GetBool() )
{ {
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS ); GL_State( GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS | GLS_CULL_TWOSIDED );
// We just want to do a quad pass - so make sure we disable any texgen and // We just want to do a quad pass - so make sure we disable any texgen and
// set the texture matrix to the identity so we don't get anomalies from // set the texture matrix to the identity so we don't get anomalies from
@ -5549,8 +5553,10 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
OPTICK_GPU_CONTEXT( ( void* ) commandList->getNativeObject( commandObject ) ); OPTICK_GPU_CONTEXT( ( void* ) commandList->getNativeObject( commandObject ) );
//OPTICK_GPU_EVENT( "DrawView" ); // SRS - now in DrawView() for 3D vs. GUI //OPTICK_GPU_EVENT( "DrawView" ); // SRS - now in DrawView() for 3D vs. GUI
bool is3D = _viewDef->viewEntitys && !_viewDef->is2Dgui;
// ugly but still faster than building the string // ugly but still faster than building the string
if( !_viewDef->viewEntitys || _viewDef->is2Dgui ) if( !is3D )
{ {
if( stereoEye == -1 ) if( stereoEye == -1 )
{ {
@ -5619,7 +5625,6 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
// ensures that depth writes are enabled for the depth clear // ensures that depth writes are enabled for the depth clear
GL_State( GLS_DEFAULT | GLS_CULL_FRONTSIDED, true ); GL_State( GLS_DEFAULT | GLS_CULL_FRONTSIDED, true );
bool useHDR = !_viewDef->is2Dgui;
bool clearColor = false; bool clearColor = false;
if( _viewDef->renderView.rdflags & RDF_IRRADIANCE ) if( _viewDef->renderView.rdflags & RDF_IRRADIANCE )
@ -5627,7 +5632,7 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
globalFramebuffers.envprobeFBO->Bind(); globalFramebuffers.envprobeFBO->Bind();
clearColor = true; clearColor = true;
} }
else if( useHDR ) else if( is3D )
{ {
globalFramebuffers.hdrFBO->Bind(); globalFramebuffers.hdrFBO->Bind();
} }
@ -5725,7 +5730,7 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
//------------------------------------------------- //-------------------------------------------------
// build hierarchical depth buffer // build hierarchical depth buffer
//------------------------------------------------- //-------------------------------------------------
if( r_useHierarchicalDepthBuffer.GetBool() ) if( r_useHierarchicalDepthBuffer.GetBool() && is3D )
{ {
renderLog.OpenBlock( "Render_HiZ" ); renderLog.OpenBlock( "Render_HiZ" );
@ -5747,7 +5752,7 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
// //
// fill the geometric buffer with normals and roughness // fill the geometric buffer with normals and roughness
//------------------------------------------------- //-------------------------------------------------
if( viewDef->viewEntitys ) // 3D views only if( is3D )
{ {
//OPTICK_EVENT( "Render_GeometryBuffer" ); //OPTICK_EVENT( "Render_GeometryBuffer" );
OPTICK_GPU_EVENT( "Render_GeometryBuffer" ); OPTICK_GPU_EVENT( "Render_GeometryBuffer" );
@ -5770,7 +5775,7 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
//------------------------------------------------- //-------------------------------------------------
// render static lighting and consider SSAO results // render static lighting and consider SSAO results
//------------------------------------------------- //-------------------------------------------------
if( viewDef->viewEntitys ) // 3D views only if( is3D )
{ {
//OPTICK_EVENT( "Render_AmbientPass" ); //OPTICK_EVENT( "Render_AmbientPass" );
OPTICK_GPU_EVENT( "Render_AmbientPass" ); OPTICK_GPU_EVENT( "Render_AmbientPass" );
@ -5932,7 +5937,7 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
// tonemapping: convert back from HDR to LDR range // tonemapping: convert back from HDR to LDR range
//------------------------------------------------- //-------------------------------------------------
if( useHDR && !( _viewDef->renderView.rdflags & RDF_IRRADIANCE ) && !_viewDef->targetRender ) if( is3D && !( _viewDef->renderView.rdflags & RDF_IRRADIANCE ) && !_viewDef->targetRender )
{ {
OPTICK_GPU_EVENT( "Render_ToneMapPass" ); OPTICK_GPU_EVENT( "Render_ToneMapPass" );

View file

@ -3,7 +3,7 @@
Doom 3 BFG Edition GPL Source Code Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2023 Robert Beckebans Copyright (C) 2013-2024 Robert Beckebans
Copyright (C) 2022 Stephen Pridham Copyright (C) 2022 Stephen Pridham
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -372,10 +372,11 @@ void idRenderProgManager::Init( nvrhi::IDevice* device )
.setVisibility( nvrhi::ShaderType::Pixel ) .setVisibility( nvrhi::ShaderType::Pixel )
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) ) // normal map .addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) ) // normal map
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 1 ) ) // HDR _currentRender .addItem( nvrhi::BindingLayoutItem::Texture_SRV( 1 ) ) // HDR _currentRender
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 2 ) ) // _currentDepth .addItem( nvrhi::BindingLayoutItem::Texture_SRV( 2 ) ) // _currentNormals
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 3 ) ) // radiance cube map 1 .addItem( nvrhi::BindingLayoutItem::Texture_SRV( 3 ) ) // _currentDepth
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 4 ) ) // radiance cube map 2 .addItem( nvrhi::BindingLayoutItem::Texture_SRV( 4 ) ) // radiance cube map 1
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 5 ) ); // radiance cube map 3 .addItem( nvrhi::BindingLayoutItem::Texture_SRV( 5 ) ) // radiance cube map 2
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 6 ) ); // radiance cube map 3
auto octahedronCubeBindingLayout = device->createBindingLayout( octahedronCubeBindingLayoutDesc ); auto octahedronCubeBindingLayout = device->createBindingLayout( octahedronCubeBindingLayoutDesc );

View file

@ -295,7 +295,7 @@ idCVar r_useLightGrid( "r_useLightGrid", "1", CVAR_RENDERER | CVAR_BOOL | CVAR_N
idCVar r_exposure( "r_exposure", "0.5", CVAR_ARCHIVE | CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "HDR exposure or LDR brightness [-4.0 .. 4.0]", -4.0f, 4.0f ); idCVar r_exposure( "r_exposure", "0.5", CVAR_ARCHIVE | CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "HDR exposure or LDR brightness [-4.0 .. 4.0]", -4.0f, 4.0f );
idCVar r_useSSR( "r_useSSR", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL | CVAR_NEW, "" ); idCVar r_useSSR( "r_useSSR", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL | CVAR_NEW, "" );
idCVar r_ssrJitter( "r_ssrJitter", "1", CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "" ); idCVar r_ssrJitter( "r_ssrJitter", "0", CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "" );
idCVar r_ssrMaxDistance( "r_ssrMaxDistance", "100", CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "In meters" ); idCVar r_ssrMaxDistance( "r_ssrMaxDistance", "100", CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "In meters" );
idCVar r_ssrMaxSteps( "r_ssrMaxSteps", "100", CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "" ); idCVar r_ssrMaxSteps( "r_ssrMaxSteps", "100", CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "" );
idCVar r_ssrStride( "r_ssrStride", "12", CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "" ); idCVar r_ssrStride( "r_ssrStride", "12", CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "" );

View file

@ -157,7 +157,7 @@ void main( VS_IN vertex, out VS_OUT result )
//result.texcoord1.z = dot3( toEye, rpModelMatrixZ ); //result.texcoord1.z = dot3( toEye, rpModelMatrixZ );
#if 1 #if 1
// rotate into world space // rotate from tangent space into world space
result.texcoord2.x = dot3( tangent, rpModelMatrixX ); result.texcoord2.x = dot3( tangent, rpModelMatrixX );
result.texcoord3.x = dot3( tangent, rpModelMatrixY ); result.texcoord3.x = dot3( tangent, rpModelMatrixY );
result.texcoord4.x = dot3( tangent, rpModelMatrixZ ); result.texcoord4.x = dot3( tangent, rpModelMatrixZ );
@ -171,7 +171,7 @@ void main( VS_IN vertex, out VS_OUT result )
result.texcoord4.z = dot3( normal, rpModelMatrixZ ); result.texcoord4.z = dot3( normal, rpModelMatrixZ );
#else #else
// rotate into view space // rotate from tangent space into view space
result.texcoord2.x = dot3( tangent, rpModelViewMatrixX ); result.texcoord2.x = dot3( tangent, rpModelViewMatrixX );
result.texcoord3.x = dot3( tangent, rpModelViewMatrixY ); result.texcoord3.x = dot3( tangent, rpModelViewMatrixY );
result.texcoord4.x = dot3( tangent, rpModelViewMatrixZ ); result.texcoord4.x = dot3( tangent, rpModelViewMatrixZ );

View file

@ -32,11 +32,12 @@ If you have questions concerning this license or the applicable additional terms
// *INDENT-OFF* // *INDENT-OFF*
Texture2D t_NormalMap : register( t0 VK_DESCRIPTOR_SET( 1 ) ); Texture2D t_NormalMap : register( t0 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_Color : register( t1 VK_DESCRIPTOR_SET( 1 ) ); Texture2D t_ScreenColor : register( t1 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_Depth : register( t2 VK_DESCRIPTOR_SET( 1 ) ); Texture2D t_ScreenNormals : register( t2 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_RadianceCubeMap1 : register( t3 VK_DESCRIPTOR_SET( 1 ) ); Texture2D t_Depth : register( t3 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_RadianceCubeMap2 : register( t4 VK_DESCRIPTOR_SET( 1 ) ); Texture2D t_RadianceCubeMap1 : register( t4 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_RadianceCubeMap3 : register( t5 VK_DESCRIPTOR_SET( 1 ) ); Texture2D t_RadianceCubeMap2 : register( t5 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_RadianceCubeMap3 : register( t6 VK_DESCRIPTOR_SET( 1 ) );
SamplerState s_Material : register( s0 VK_DESCRIPTOR_SET( 2 ) ); SamplerState s_Material : register( s0 VK_DESCRIPTOR_SET( 2 ) );
SamplerState s_LinearClamp : register( s1 VK_DESCRIPTOR_SET( 2 ) ); SamplerState s_LinearClamp : register( s1 VK_DESCRIPTOR_SET( 2 ) );
@ -50,9 +51,6 @@ struct PS_IN
float3 texcoord3 : TEXCOORD3_centroid; float3 texcoord3 : TEXCOORD3_centroid;
float3 texcoord4 : TEXCOORD4_centroid; float3 texcoord4 : TEXCOORD4_centroid;
float4 texcoord5 : TEXCOORD5_centroid; float4 texcoord5 : TEXCOORD5_centroid;
float4 texcoord6 : TEXCOORD6_centroid;
float4 texcoord7 : TEXCOORD7_centroid;
float4 texcoord8 : TEXCOORD8_centroid;
float4 color : COLOR0; float4 color : COLOR0;
}; };
@ -118,9 +116,7 @@ bool IntersectsDepthBuffer( float z, float minZ, float maxZ, float zThickness )
//return ( maxZ >= z ) && ( minZ - zThickness <= z ); //return ( maxZ >= z ) && ( minZ - zThickness <= z );
//IntersectsDepthBuffer( sceneZMax, rayZMin, rayZMax, zThickness ); // like original version with negative linear Z
// RB: like original version with negative linear Z
return ( maxZ >= z - zThickness ) && ( minZ <= z ); return ( maxZ >= z - zThickness ) && ( minZ <= z );
} }
@ -332,6 +328,17 @@ void main( PS_IN fragment, out PS_OUT result )
globalNormal.y = dot3( localNormal, fragment.texcoord3 ); globalNormal.y = dot3( localNormal, fragment.texcoord3 );
globalNormal.z = dot3( localNormal, fragment.texcoord4 ); globalNormal.z = dot3( localNormal, fragment.texcoord4 );
float3 screenNormalWS = ( ( 2.0 * t_ScreenNormals.Sample( s_LinearClamp, fragment.position.xy * rpWindowCoord.xy ).rgb ) - 1.0 );
// https://blog.selfshadow.com/publications/blending-in-detail/
// UDN blending
//globalNormal = normalize( float3( screenNormalWS.xy + globalNormal.xy, screenNormalWS.z ) );
// Whiteout blending
globalNormal = normalize( float3( screenNormalWS.xy + globalNormal.xy, screenNormalWS.z * globalNormal.z ) );
float3 globalPosition = fragment.texcoord5.xyz; float3 globalPosition = fragment.texcoord5.xyz;
float3 globalView = normalize( globalPosition - rpGlobalEyePos.xyz ); float3 globalView = normalize( globalPosition - rpGlobalEyePos.xyz );
@ -389,10 +396,11 @@ void main( PS_IN fragment, out PS_OUT result )
float3 rayDir; float3 rayDir;
float3 viewNormal; float3 viewNormal;
viewNormal.x = dot3( localNormal, fragment.texcoord6 );
viewNormal.y = dot3( localNormal, fragment.texcoord7 ); // TODO this should be rpViewMatrixX
viewNormal.z = dot3( localNormal, fragment.texcoord8 ); viewNormal.x = dot3( rpModelViewMatrixX, globalNormal );
viewNormal = normalize( viewNormal ); viewNormal.y = dot3( rpModelViewMatrixY, globalNormal );
viewNormal.z = dot3( rpModelViewMatrixZ, globalNormal );
rayStart = ReconstructPositionCS( fragment.position.xy ); rayStart = ReconstructPositionCS( fragment.position.xy );
@ -448,7 +456,7 @@ void main( PS_IN fragment, out PS_OUT result )
if( intersection ) if( intersection )
{ {
radiance = float3( 0, 1, 0 ); radiance = float3( 0, 1, 0 );
radiance = t_Color.Sample( s_LinearClamp, hitPixel * rpWindowCoord.xy ).rgb; radiance = t_ScreenColor.Sample( s_LinearClamp, hitPixel * rpWindowCoord.xy ).rgb;
//radiance = float3( delta, 0 ); //radiance = float3( delta, 0 );
//radiance = float3( 0, deltaLen, 0 ); //radiance = float3( 0, deltaLen, 0 );

View file

@ -53,9 +53,6 @@ struct VS_OUT
float3 texcoord3 : TEXCOORD3_centroid; float3 texcoord3 : TEXCOORD3_centroid;
float3 texcoord4 : TEXCOORD4_centroid; float3 texcoord4 : TEXCOORD4_centroid;
float4 texcoord5 : TEXCOORD5_centroid; float4 texcoord5 : TEXCOORD5_centroid;
float4 texcoord6 : TEXCOORD6_centroid;
float4 texcoord7 : TEXCOORD7_centroid;
float4 texcoord8 : TEXCOORD8_centroid;
float4 color : COLOR0; float4 color : COLOR0;
}; };
// *INDENT-ON* // *INDENT-ON*
@ -158,7 +155,7 @@ void main( VS_IN vertex, out VS_OUT result )
result.texcoord1.y = dot3( toEye, rpModelMatrixY ); result.texcoord1.y = dot3( toEye, rpModelMatrixY );
result.texcoord1.z = dot3( toEye, rpModelMatrixZ ); result.texcoord1.z = dot3( toEye, rpModelMatrixZ );
// rotate into world space // rotate from tangent space into world space
result.texcoord2.x = dot3( tangent, rpModelMatrixX ); result.texcoord2.x = dot3( tangent, rpModelMatrixX );
result.texcoord3.x = dot3( tangent, rpModelMatrixY ); result.texcoord3.x = dot3( tangent, rpModelMatrixY );
result.texcoord4.x = dot3( tangent, rpModelMatrixZ ); result.texcoord4.x = dot3( tangent, rpModelMatrixZ );
@ -178,18 +175,5 @@ void main( VS_IN vertex, out VS_OUT result )
worldPosition.w = dot4( modelPosition, rpModelMatrixW ); worldPosition.w = dot4( modelPosition, rpModelMatrixW );
result.texcoord5 = worldPosition; result.texcoord5 = worldPosition;
// rotate into view space
result.texcoord6.x = dot3( tangent, rpModelViewMatrixX );
result.texcoord7.x = dot3( tangent, rpModelViewMatrixY );
result.texcoord8.x = dot3( tangent, rpModelViewMatrixZ );
result.texcoord6.y = dot3( bitangent, rpModelViewMatrixX );
result.texcoord7.y = dot3( bitangent, rpModelViewMatrixY );
result.texcoord8.y = dot3( bitangent, rpModelViewMatrixZ );
result.texcoord6.z = dot3( normal, rpModelViewMatrixX );
result.texcoord7.z = dot3( normal, rpModelViewMatrixY );
result.texcoord8.z = dot3( normal, rpModelViewMatrixZ );
result.color = rpColor; result.color = rpColor;
} }