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( 3, ( nvrhi::ITexture* )GetImageAt( 3 )->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
@ -1846,6 +1847,7 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
bindings[3].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 3 )->GetTextureID();
bindings[4].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 4 )->GetTextureID();
bindings[5].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 5 )->GetTextureID();
bindings[6].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 6 )->GetTextureID();
}
if( R_UsePixelatedLook() )

View file

@ -490,22 +490,26 @@ void idRenderBackend::PrepareStageTexturing( const shaderStage_t* pStage, const
globalImages->currentRenderImage->Bind();
GL_SelectTexture( 2 );
//if( r_useHierarchicalDepthBuffer.GetBool() )
//{
// globalImages->hierarchicalZbufferImage->Bind();
//}
//else
globalImages->gbufferNormalsRoughnessImage->Bind();
GL_SelectTexture( 3 );
if( r_useHierarchicalDepthBuffer.GetBool() )
{
// use hierachical Z to avoid read & write at the same time on the depth buffer
globalImages->hierarchicalZbufferImage->Bind();
}
else
{
globalImages->currentDepthImage->Bind();
}
GL_SelectTexture( 3 );
GL_SelectTexture( 4 );
viewDef->radianceImages[0]->Bind();
GL_SelectTexture( 4 );
GL_SelectTexture( 5 );
viewDef->radianceImages[1]->Bind();
GL_SelectTexture( 5 );
GL_SelectTexture( 6 );
viewDef->radianceImages[2]->Bind();
GL_SelectTexture( 0 );
@ -2207,13 +2211,13 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
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
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
// 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_EVENT( "DrawView" ); // SRS - now in DrawView() for 3D vs. GUI
bool is3D = _viewDef->viewEntitys && !_viewDef->is2Dgui;
// ugly but still faster than building the string
if( !_viewDef->viewEntitys || _viewDef->is2Dgui )
if( !is3D )
{
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
GL_State( GLS_DEFAULT | GLS_CULL_FRONTSIDED, true );
bool useHDR = !_viewDef->is2Dgui;
bool clearColor = false;
if( _viewDef->renderView.rdflags & RDF_IRRADIANCE )
@ -5627,7 +5632,7 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
globalFramebuffers.envprobeFBO->Bind();
clearColor = true;
}
else if( useHDR )
else if( is3D )
{
globalFramebuffers.hdrFBO->Bind();
}
@ -5725,7 +5730,7 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
//-------------------------------------------------
// build hierarchical depth buffer
//-------------------------------------------------
if( r_useHierarchicalDepthBuffer.GetBool() )
if( r_useHierarchicalDepthBuffer.GetBool() && is3D )
{
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
//-------------------------------------------------
if( viewDef->viewEntitys ) // 3D views only
if( is3D )
{
//OPTICK_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
//-------------------------------------------------
if( viewDef->viewEntitys ) // 3D views only
if( is3D )
{
//OPTICK_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
//-------------------------------------------------
if( useHDR && !( _viewDef->renderView.rdflags & RDF_IRRADIANCE ) && !_viewDef->targetRender )
if( is3D && !( _viewDef->renderView.rdflags & RDF_IRRADIANCE ) && !_viewDef->targetRender )
{
OPTICK_GPU_EVENT( "Render_ToneMapPass" );

View file

@ -3,7 +3,7 @@
Doom 3 BFG Edition GPL Source Code
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
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 )
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) ) // normal map
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 1 ) ) // HDR _currentRender
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 2 ) ) // _currentDepth
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 3 ) ) // radiance cube map 1
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 4 ) ) // radiance cube map 2
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 5 ) ); // radiance cube map 3
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 2 ) ) // _currentNormals
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 3 ) ) // _currentDepth
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 4 ) ) // radiance cube map 1
.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 );

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_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_ssrMaxSteps( "r_ssrMaxSteps", "100", 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 );
#if 1
// rotate into world space
// rotate from tangent space into world space
result.texcoord2.x = dot3( tangent, rpModelMatrixX );
result.texcoord3.x = dot3( tangent, rpModelMatrixY );
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 );
#else
// rotate into view space
// rotate from tangent space into view space
result.texcoord2.x = dot3( tangent, rpModelViewMatrixX );
result.texcoord3.x = dot3( tangent, rpModelViewMatrixY );
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*
Texture2D t_NormalMap : register( t0 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_Color : register( t1 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_Depth : register( t2 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_RadianceCubeMap1 : register( t3 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_RadianceCubeMap2 : register( t4 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_RadianceCubeMap3 : register( t5 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_ScreenColor : register( t1 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_ScreenNormals : register( t2 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_Depth : register( t3 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_RadianceCubeMap1 : register( t4 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_LinearClamp : register( s1 VK_DESCRIPTOR_SET( 2 ) );
@ -50,9 +51,6 @@ struct PS_IN
float3 texcoord3 : TEXCOORD3_centroid;
float3 texcoord4 : TEXCOORD4_centroid;
float4 texcoord5 : TEXCOORD5_centroid;
float4 texcoord6 : TEXCOORD6_centroid;
float4 texcoord7 : TEXCOORD7_centroid;
float4 texcoord8 : TEXCOORD8_centroid;
float4 color : COLOR0;
};
@ -118,9 +116,7 @@ bool IntersectsDepthBuffer( float z, float minZ, float maxZ, float zThickness )
//return ( maxZ >= z ) && ( minZ - zThickness <= z );
//IntersectsDepthBuffer( sceneZMax, rayZMin, rayZMax, zThickness );
// RB: like original version with negative linear Z
// like original version with negative linear 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.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 globalView = normalize( globalPosition - rpGlobalEyePos.xyz );
@ -389,10 +396,11 @@ void main( PS_IN fragment, out PS_OUT result )
float3 rayDir;
float3 viewNormal;
viewNormal.x = dot3( localNormal, fragment.texcoord6 );
viewNormal.y = dot3( localNormal, fragment.texcoord7 );
viewNormal.z = dot3( localNormal, fragment.texcoord8 );
viewNormal = normalize( viewNormal );
// TODO this should be rpViewMatrixX
viewNormal.x = dot3( rpModelViewMatrixX, globalNormal );
viewNormal.y = dot3( rpModelViewMatrixY, globalNormal );
viewNormal.z = dot3( rpModelViewMatrixZ, globalNormal );
rayStart = ReconstructPositionCS( fragment.position.xy );
@ -448,7 +456,7 @@ void main( PS_IN fragment, out PS_OUT result )
if( intersection )
{
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( 0, deltaLen, 0 );

View file

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