mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-04-22 09:40:46 +00:00
Added interpolation of the 3 nearest reflection probes
This commit is contained in:
parent
167085385b
commit
0b4be8c73a
8 changed files with 416 additions and 65 deletions
|
@ -40,7 +40,11 @@ uniform sampler2D samp3 : register(s3); // texture 3 is the BRDF LUT
|
|||
uniform sampler2D samp4 : register(s4); // texture 4 is SSAO
|
||||
|
||||
uniform sampler2D samp7 : register(s7); // texture 7 is the irradiance cube map
|
||||
uniform sampler2D samp8 : register(s8); // texture 8 is the radiance cube map
|
||||
uniform sampler2D samp8 : register(s8); // texture 8 is the radiance cube map 1
|
||||
uniform sampler2D samp9 : register(s9); // texture 9 is the radiance cube map 2
|
||||
uniform sampler2D samp10 : register(s10); // texture 10 is the radiance cube map 3
|
||||
|
||||
uniform float4 rpUser0 : register( c128 );
|
||||
|
||||
struct PS_IN
|
||||
{
|
||||
|
@ -343,6 +347,7 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
// rpScreenCorrectionFactor.w = probeSize factor accounting account offset border, e.g = ( 16 / 18 ) = 0.8888
|
||||
float2 octCoordNormalizedToTextureDimensions = ( normalizedOctCoordZeroOne + atlasOffset ) * rpScreenCorrectionFactor.w;
|
||||
|
||||
// skip by default 2 pixels for each grid cell and offset the start position by (1,1)
|
||||
// rpScreenCorrectionFactor.z = borderSize e.g = 2
|
||||
float2 probeTopLeftPosition;
|
||||
probeTopLeftPosition.x = ( gridCoord2[0] * gridStep[0] + gridCoord2[2] * gridStep[1] ) * rpScreenCorrectionFactor.z + rpScreenCorrectionFactor.z * 0.5;
|
||||
|
@ -389,7 +394,10 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
normalizedOctCoord = octEncode( reflectionVector );
|
||||
normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5;
|
||||
|
||||
float3 radiance = textureLod( samp8, normalizedOctCoordZeroOne, mip ).rgb;
|
||||
float3 radiance = textureLod( samp8, normalizedOctCoordZeroOne, mip ).rgb * rpUser0.x;
|
||||
radiance += textureLod( samp9, normalizedOctCoordZeroOne, mip ).rgb * rpUser0.y;
|
||||
radiance += textureLod( samp10, normalizedOctCoordZeroOne, mip ).rgb * rpUser0.z;
|
||||
|
||||
//radiance = float3( 0.0 );
|
||||
|
||||
// RB: HACK dim down room radiance by better local irradiance brightness
|
||||
|
|
|
@ -40,7 +40,9 @@ uniform sampler2D samp3 : register(s3); // texture 3 is the BRDF LUT
|
|||
uniform sampler2D samp4 : register(s4); // texture 4 is SSAO
|
||||
|
||||
uniform sampler2D samp7 : register(s7); // texture 7 is the irradiance cube map
|
||||
uniform sampler2D samp8 : register(s8); // texture 8 is the radiance cube map
|
||||
uniform sampler2D samp8 : register(s8); // texture 8 is the radiance cube map 1
|
||||
uniform sampler2D samp9 : register(s9); // texture 9 is the radiance cube map 2
|
||||
uniform sampler2D samp10 : register(s10); // texture 10 is the radiance cube map 3
|
||||
|
||||
struct PS_IN
|
||||
{
|
||||
|
@ -270,7 +272,9 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
|
||||
normalizedOctCoordZeroOne = OctTexCoord( reflectionVector );
|
||||
|
||||
float3 radiance = textureLod( samp8, normalizedOctCoordZeroOne, mip ).rgb;
|
||||
float3 radiance = textureLod( samp8, normalizedOctCoordZeroOne, mip ).rgb * rpGlobalLightOrigin.x;
|
||||
radiance += textureLod( samp9, normalizedOctCoordZeroOne, mip ).rgb * rpGlobalLightOrigin.y;
|
||||
radiance += textureLod( samp10, normalizedOctCoordZeroOne, mip ).rgb * rpGlobalLightOrigin.z;
|
||||
//radiance = float3( 0.0 );
|
||||
|
||||
float2 envBRDF = texture( samp3, float2( max( vDotN, 0.0 ), roughness ) ).rg;
|
||||
|
|
|
@ -1702,9 +1702,38 @@ void idRenderBackend::DBG_ShowLights()
|
|||
==============
|
||||
RB_ShowViewEnvprobes
|
||||
|
||||
Visualize all environemnt probes used in the current scene
|
||||
Visualize all environment probes used in the current scene
|
||||
==============
|
||||
*/
|
||||
class idSort_DebugCompareViewEnvprobe : public idSort_Quick< RenderEnvprobeLocal*, idSort_DebugCompareViewEnvprobe >
|
||||
{
|
||||
idVec3 viewOrigin;
|
||||
|
||||
public:
|
||||
idSort_DebugCompareViewEnvprobe( const idVec3& origin )
|
||||
{
|
||||
viewOrigin = origin;
|
||||
}
|
||||
|
||||
int Compare( RenderEnvprobeLocal* const& a, RenderEnvprobeLocal* const& b ) const
|
||||
{
|
||||
float adist = ( viewOrigin - a->parms.origin ).LengthSqr();
|
||||
float bdist = ( viewOrigin - b->parms.origin ).LengthSqr();
|
||||
|
||||
if( adist < bdist )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( adist > bdist )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
void idRenderBackend::DBG_ShowViewEnvprobes()
|
||||
{
|
||||
if( !r_showViewEnvprobes.GetInteger() )
|
||||
|
@ -1794,6 +1823,134 @@ void idRenderBackend::DBG_ShowViewEnvprobes()
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//if( r_showViewEnvprobes.GetInteger() >= 3 )
|
||||
if( tr.primaryWorld )
|
||||
{
|
||||
/*
|
||||
idList<viewEnvprobe_t*, TAG_RENDER_ENVPROBE> viewEnvprobes;
|
||||
for( viewEnvprobe_t* vProbe = viewDef->viewEnvprobes; vProbe != NULL; vProbe = vProbe->next )
|
||||
{
|
||||
viewEnvprobes.AddUnique( vProbe );
|
||||
}
|
||||
*/
|
||||
|
||||
idList<RenderEnvprobeLocal*, TAG_RENDER_ENVPROBE> viewEnvprobes;
|
||||
for( int i = 0; i < tr.primaryWorld->envprobeDefs.Num(); i++ )
|
||||
{
|
||||
RenderEnvprobeLocal* vProbe = tr.primaryWorld->envprobeDefs[i];
|
||||
if( vProbe )
|
||||
{
|
||||
viewEnvprobes.AddUnique( vProbe );
|
||||
}
|
||||
}
|
||||
|
||||
if( viewEnvprobes.Num() == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
idVec3 testOrigin = viewDef->renderView.vieworg;
|
||||
//testOrigin += viewDef->renderView.viewaxis[0] * 150.0f;
|
||||
//testOrigin -= viewDef->renderView.viewaxis[2] * 16.0f;
|
||||
|
||||
// sort by distance
|
||||
viewEnvprobes.SortWithTemplate( idSort_DebugCompareViewEnvprobe( testOrigin ) );
|
||||
|
||||
// draw 3 nearest probes
|
||||
renderProgManager.BindShader_Color();
|
||||
|
||||
const int numColors = 3;
|
||||
static idVec4 colors[numColors] = { colorRed, colorGreen, colorBlue };
|
||||
|
||||
// form a triangle of the 3 closest probes
|
||||
idVec3 verts[3];
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
verts[i] = viewEnvprobes[0]->parms.origin;
|
||||
}
|
||||
|
||||
for( int i = 0; i < viewEnvprobes.Num() && i < 3; i++ )
|
||||
{
|
||||
RenderEnvprobeLocal* vProbe = viewEnvprobes[i];
|
||||
|
||||
verts[i] = vProbe->parms.origin;
|
||||
}
|
||||
|
||||
idVec3 closest = R_ClosestPointPointTriangle( testOrigin, verts[0], verts[1], verts[2] );
|
||||
idVec3 barycentricWeights;
|
||||
|
||||
// find the barycentric coordinates
|
||||
float denom = idWinding::TriangleArea( verts[0], verts[1], verts[2] );
|
||||
if( denom == 0 )
|
||||
{
|
||||
// all points at same location
|
||||
barycentricWeights.Set( 1, 0, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
float a, b, c;
|
||||
|
||||
a = idWinding::TriangleArea( closest, verts[1], verts[2] ) / denom;
|
||||
b = idWinding::TriangleArea( closest, verts[2], verts[0] ) / denom;
|
||||
c = idWinding::TriangleArea( closest, verts[0], verts[1] ) / denom;
|
||||
|
||||
barycentricWeights.Set( a, b, c );
|
||||
}
|
||||
|
||||
idMat3 axis;
|
||||
axis.Identity();
|
||||
|
||||
for( int i = 0; i < viewEnvprobes.Num() && i < 3; i++ )
|
||||
{
|
||||
RenderEnvprobeLocal* vProbe = viewEnvprobes[i];
|
||||
|
||||
verts[i] = vProbe->parms.origin;
|
||||
|
||||
//GL_Color( colors[i] );
|
||||
|
||||
idVec4 color = Lerp( colorBlack, colors[i], barycentricWeights[i] );
|
||||
GL_Color( color );
|
||||
|
||||
idRenderMatrix modelRenderMatrix;
|
||||
idRenderMatrix::CreateFromOriginAxis( vProbe->parms.origin, axis, modelRenderMatrix );
|
||||
|
||||
// calculate the matrix that transforms the unit cube to exactly cover the model in world space
|
||||
const float size = 16.0f;
|
||||
idBounds debugBounds( idVec3( -size ), idVec3( size ) );
|
||||
|
||||
idRenderMatrix inverseBaseModelProject;
|
||||
idRenderMatrix::OffsetScaleForBounds( modelRenderMatrix, debugBounds, inverseBaseModelProject );
|
||||
|
||||
idRenderMatrix invProjectMVPMatrix;
|
||||
idRenderMatrix::Multiply( viewDef->worldSpace.mvp, inverseBaseModelProject, invProjectMVPMatrix );
|
||||
RB_SetMVP( invProjectMVPMatrix );
|
||||
|
||||
DrawElementsWithCounters( &zeroOneSphereSurface );
|
||||
}
|
||||
|
||||
// draw closest hit
|
||||
{
|
||||
GL_Color( colorYellow );
|
||||
|
||||
idRenderMatrix modelRenderMatrix;
|
||||
idRenderMatrix::CreateFromOriginAxis( closest, axis, modelRenderMatrix );
|
||||
|
||||
// calculate the matrix that transforms the unit cube to exactly cover the model in world space
|
||||
const float size = 4.0f;
|
||||
idBounds debugBounds( idVec3( -size ), idVec3( size ) );
|
||||
|
||||
idRenderMatrix inverseBaseModelProject;
|
||||
idRenderMatrix::OffsetScaleForBounds( modelRenderMatrix, debugBounds, inverseBaseModelProject );
|
||||
|
||||
idRenderMatrix invProjectMVPMatrix;
|
||||
idRenderMatrix::Multiply( viewDef->worldSpace.mvp, inverseBaseModelProject, invProjectMVPMatrix );
|
||||
RB_SetMVP( invProjectMVPMatrix );
|
||||
|
||||
DrawElementsWithCounters( &zeroOneSphereSurface );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void idRenderBackend::DBG_ShowLightGrid()
|
||||
|
|
|
@ -1200,9 +1200,13 @@ const int INTERACTION_TEXUNIT_JITTER = 6;
|
|||
#if defined( USE_VULKAN )
|
||||
const int INTERACTION_TEXUNIT_AMBIENT_CUBE1 = 5;
|
||||
const int INTERACTION_TEXUNIT_SPECULAR_CUBE1 = 6;
|
||||
const int INTERACTION_TEXUNIT_SPECULAR_CUBE2 = 7;
|
||||
const int INTERACTION_TEXUNIT_SPECULAR_CUBE3 = 8;
|
||||
#else
|
||||
const int INTERACTION_TEXUNIT_AMBIENT_CUBE1 = 7;
|
||||
const int INTERACTION_TEXUNIT_SPECULAR_CUBE1 = 8;
|
||||
const int INTERACTION_TEXUNIT_SPECULAR_CUBE2 = 9;
|
||||
const int INTERACTION_TEXUNIT_SPECULAR_CUBE3 = 10;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -1344,8 +1348,6 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useFas
|
|||
SetVertexParm( RENDERPARM_WOBBLESKY_Y, probeMaxs.ToFloatPtr() );
|
||||
SetVertexParm( RENDERPARM_WOBBLESKY_Z, probeCenter.ToFloatPtr() );
|
||||
|
||||
//SetVertexParm( RENDERPARM_WOBBLESK_Z, probeCenter.ToFloatPtr() );
|
||||
|
||||
// use rpGlobalLightOrigin for lightGrid center
|
||||
idVec4 lightGridOrigin( currentSpace->lightGridOrigin.x, currentSpace->lightGridOrigin.y, currentSpace->lightGridOrigin.z, 1.0f );
|
||||
idVec4 lightGridSize( currentSpace->lightGridSize.x, currentSpace->lightGridSize.y, currentSpace->lightGridSize.z, 1.0f );
|
||||
|
@ -1363,6 +1365,9 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useFas
|
|||
probeSize[3] = float( currentSpace->lightGridAtlasSingleProbeSize - currentSpace->lightGridAtlasBorderSize ) / currentSpace->lightGridAtlasSingleProbeSize;
|
||||
renderProgManager.SetUniformValue( RENDERPARM_SCREENCORRECTIONFACTOR, probeSize.ToFloatPtr() ); // rpScreenCorrectionFactor
|
||||
|
||||
// specular cubemap blend weights
|
||||
renderProgManager.SetUniformValue( RENDERPARM_USER0, viewDef->radianceImageBlends.ToFloatPtr() );
|
||||
|
||||
if( specUsage == TD_SPECULAR_PBR_RMAO || specUsage == TD_SPECULAR_PBR_RMAOD )
|
||||
{
|
||||
// PBR path with roughness, metal and AO
|
||||
|
@ -1413,14 +1418,13 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useFas
|
|||
renderProgManager.SetUniformValue( RENDERPARM_CASCADEDISTANCES, textureSize.ToFloatPtr() );
|
||||
|
||||
GL_SelectTexture( INTERACTION_TEXUNIT_SPECULAR_CUBE1 );
|
||||
if( viewDef->radianceImage )
|
||||
{
|
||||
viewDef->radianceImage->Bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
globalImages->defaultUACRadianceCube->Bind();
|
||||
}
|
||||
viewDef->radianceImages[0]->Bind();
|
||||
|
||||
GL_SelectTexture( INTERACTION_TEXUNIT_SPECULAR_CUBE2 );
|
||||
viewDef->radianceImages[1]->Bind();
|
||||
|
||||
GL_SelectTexture( INTERACTION_TEXUNIT_SPECULAR_CUBE3 );
|
||||
viewDef->radianceImages[2]->Bind();
|
||||
}
|
||||
else if( useIBL )
|
||||
{
|
||||
|
@ -1443,6 +1447,9 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useFas
|
|||
SetVertexParm( RENDERPARM_WOBBLESKY_Y, probeMaxs.ToFloatPtr() );
|
||||
SetVertexParm( RENDERPARM_WOBBLESKY_Z, probeCenter.ToFloatPtr() );
|
||||
|
||||
// specular cubemap blend weights
|
||||
renderProgManager.SetUniformValue( RENDERPARM_GLOBALLIGHTORIGIN, viewDef->radianceImageBlends.ToFloatPtr() );
|
||||
|
||||
if( specUsage == TD_SPECULAR_PBR_RMAO || specUsage == TD_SPECULAR_PBR_RMAOD )
|
||||
{
|
||||
// PBR path with roughness, metal and AO
|
||||
|
@ -1484,26 +1491,17 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useFas
|
|||
}
|
||||
#endif
|
||||
|
||||
// TODO bind the 3 closest probes
|
||||
GL_SelectTexture( INTERACTION_TEXUNIT_AMBIENT_CUBE1 );
|
||||
if( viewDef->irradianceImage )
|
||||
{
|
||||
viewDef->irradianceImage->Bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
globalImages->defaultUACIrradianceCube->Bind();
|
||||
}
|
||||
viewDef->irradianceImage->Bind();
|
||||
|
||||
GL_SelectTexture( INTERACTION_TEXUNIT_SPECULAR_CUBE1 );
|
||||
if( viewDef->radianceImage )
|
||||
{
|
||||
viewDef->radianceImage->Bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
globalImages->defaultUACRadianceCube->Bind();
|
||||
}
|
||||
viewDef->radianceImages[0]->Bind();
|
||||
|
||||
GL_SelectTexture( INTERACTION_TEXUNIT_SPECULAR_CUBE2 );
|
||||
viewDef->radianceImages[1]->Bind();
|
||||
|
||||
GL_SelectTexture( INTERACTION_TEXUNIT_SPECULAR_CUBE3 );
|
||||
viewDef->radianceImages[2]->Bind();
|
||||
}
|
||||
else if( setInteractionShader )
|
||||
{
|
||||
|
|
|
@ -648,7 +648,8 @@ struct viewDef_t
|
|||
idBounds globalProbeBounds;
|
||||
idRenderMatrix inverseBaseEnvProbeProject; // the matrix for deforming the 'zeroOneCubeModel' to exactly cover the environent probe volume in world space
|
||||
idImage* irradianceImage; // cubemap image used for diffuse IBL by backend
|
||||
idImage* radianceImage; // cubemap image used for specular IBL by backend
|
||||
idImage* radianceImages[3]; // cubemap image used for specular IBL by backend
|
||||
idVec4 radianceImageBlends; // blending weights
|
||||
};
|
||||
|
||||
|
||||
|
@ -1613,6 +1614,9 @@ void R_InitDrawSurfFromTri( drawSurf_t& ds, srfTriangles_t& tri );
|
|||
// time, rather than being re-created each frame in the frame temporary buffers.
|
||||
void R_CreateStaticBuffersForTri( srfTriangles_t& tri );
|
||||
|
||||
// RB
|
||||
idVec3 R_ClosestPointPointTriangle( const idVec3& point, const idVec3& vertex1, const idVec3& vertex2, const idVec3& vertex3 );
|
||||
|
||||
// deformable meshes precalculate as much as possible from a base frame, then generate
|
||||
// complete srfTriangles_t from just a new set of vertexes
|
||||
struct deformInfo_t
|
||||
|
|
|
@ -4807,7 +4807,9 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
"uniform sampler2D samp4 : register(s4); // texture 4 is SSAO\n"
|
||||
"\n"
|
||||
"uniform sampler2D samp7 : register(s7); // texture 7 is the irradiance cube map\n"
|
||||
"uniform sampler2D samp8 : register(s8); // texture 8 is the radiance cube map\n"
|
||||
"uniform sampler2D samp8 : register(s8); // texture 8 is the radiance cube map 1\n"
|
||||
"uniform sampler2D samp9 : register(s9); // texture 9 is the radiance cube map 2\n"
|
||||
"uniform sampler2D samp10 : register(s10); // texture 10 is the radiance cube map 3\n"
|
||||
"\n"
|
||||
"struct PS_IN \n"
|
||||
"{\n"
|
||||
|
@ -5037,7 +5039,9 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
"\n"
|
||||
" normalizedOctCoordZeroOne = OctTexCoord( reflectionVector );\n"
|
||||
"\n"
|
||||
" float3 radiance = textureLod( samp8, normalizedOctCoordZeroOne, mip ).rgb;\n"
|
||||
" float3 radiance = textureLod( samp8, normalizedOctCoordZeroOne, mip ).rgb * rpGlobalLightOrigin.x;\n"
|
||||
" radiance += textureLod( samp9, normalizedOctCoordZeroOne, mip ).rgb * rpGlobalLightOrigin.y;\n"
|
||||
" radiance += textureLod( samp10, normalizedOctCoordZeroOne, mip ).rgb * rpGlobalLightOrigin.z;\n"
|
||||
" //radiance = float3( 0.0 );\n"
|
||||
"\n"
|
||||
" float2 envBRDF = texture( samp3, float2( max( vDotN, 0.0 ), roughness ) ).rg;\n"
|
||||
|
@ -5323,7 +5327,11 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
"uniform sampler2D samp4 : register(s4); // texture 4 is SSAO\n"
|
||||
"\n"
|
||||
"uniform sampler2D samp7 : register(s7); // texture 7 is the irradiance cube map\n"
|
||||
"uniform sampler2D samp8 : register(s8); // texture 8 is the radiance cube map\n"
|
||||
"uniform sampler2D samp8 : register(s8); // texture 8 is the radiance cube map 1\n"
|
||||
"uniform sampler2D samp9 : register(s9); // texture 9 is the radiance cube map 2\n"
|
||||
"uniform sampler2D samp10 : register(s10); // texture 10 is the radiance cube map 3\n"
|
||||
"\n"
|
||||
"uniform float4 rpUser0 : register( c128 );\n"
|
||||
"\n"
|
||||
"struct PS_IN \n"
|
||||
"{\n"
|
||||
|
@ -5626,6 +5634,7 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" // rpScreenCorrectionFactor.w = probeSize factor accounting account offset border, e.g = ( 16 / 18 ) = 0.8888\n"
|
||||
" float2 octCoordNormalizedToTextureDimensions = ( normalizedOctCoordZeroOne + atlasOffset ) * rpScreenCorrectionFactor.w;\n"
|
||||
"\n"
|
||||
" // skip by default 2 pixels for each grid cell and offset the start position by (1,1)\n"
|
||||
" // rpScreenCorrectionFactor.z = borderSize e.g = 2\n"
|
||||
" float2 probeTopLeftPosition;\n"
|
||||
" probeTopLeftPosition.x = ( gridCoord2[0] * gridStep[0] + gridCoord2[2] * gridStep[1] ) * rpScreenCorrectionFactor.z + rpScreenCorrectionFactor.z * 0.5;\n"
|
||||
|
@ -5672,7 +5681,10 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" normalizedOctCoord = octEncode( reflectionVector );\n"
|
||||
" normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5;\n"
|
||||
"\n"
|
||||
" float3 radiance = textureLod( samp8, normalizedOctCoordZeroOne, mip ).rgb;\n"
|
||||
" float3 radiance = textureLod( samp8, normalizedOctCoordZeroOne, mip ).rgb * rpUser0.x;\n"
|
||||
" radiance += textureLod( samp9, normalizedOctCoordZeroOne, mip ).rgb * rpUser0.y;\n"
|
||||
" radiance += textureLod( samp10, normalizedOctCoordZeroOne, mip ).rgb * rpUser0.z;\n"
|
||||
"\n"
|
||||
" //radiance = float3( 0.0 );\n"
|
||||
"\n"
|
||||
" // RB: HACK dim down room radiance by better local irradiance brightness\n"
|
||||
|
|
|
@ -454,6 +454,121 @@ static void R_SetupSplitFrustums( viewDef_t* viewDef )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class idSort_CompareEnvprobe : public idSort_Quick< RenderEnvprobeLocal*, idSort_CompareEnvprobe >
|
||||
{
|
||||
idVec3 viewOrigin;
|
||||
|
||||
public:
|
||||
idSort_CompareEnvprobe( const idVec3& origin )
|
||||
{
|
||||
viewOrigin = origin;
|
||||
}
|
||||
|
||||
int Compare( RenderEnvprobeLocal* const& a, RenderEnvprobeLocal* const& b ) const
|
||||
{
|
||||
float adist = ( viewOrigin - a->parms.origin ).LengthSqr();
|
||||
float bdist = ( viewOrigin - b->parms.origin ).LengthSqr();
|
||||
|
||||
if( adist < bdist )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( adist > bdist )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
static void R_FindClosestEnvironmentProbes()
|
||||
{
|
||||
// set safe defaults
|
||||
tr.viewDef->globalProbeBounds.Clear();
|
||||
|
||||
tr.viewDef->irradianceImage = globalImages->defaultUACIrradianceCube;
|
||||
tr.viewDef->radianceImageBlends.Set( 1, 0, 0, 0 );
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
tr.viewDef->radianceImages[i] = globalImages->defaultUACRadianceCube;
|
||||
}
|
||||
|
||||
// early out
|
||||
if( tr.viewDef->areaNum == -1 || tr.viewDef->isSubview )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
idList<RenderEnvprobeLocal*, TAG_RENDER_ENVPROBE> viewEnvprobes;
|
||||
for( int i = 0; i < tr.primaryWorld->envprobeDefs.Num(); i++ )
|
||||
{
|
||||
RenderEnvprobeLocal* vProbe = tr.primaryWorld->envprobeDefs[i];
|
||||
if( vProbe )
|
||||
{
|
||||
viewEnvprobes.AddUnique( vProbe );
|
||||
}
|
||||
}
|
||||
|
||||
if( viewEnvprobes.Num() == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
idVec3 testOrigin = tr.viewDef->renderView.vieworg;
|
||||
|
||||
// sort by distance
|
||||
// RB: each Doom 3 level has ~50 - 150 probes so this should be ok for each frame
|
||||
viewEnvprobes.SortWithTemplate( idSort_CompareEnvprobe( testOrigin ) );
|
||||
|
||||
RenderEnvprobeLocal* nearest = viewEnvprobes[0];
|
||||
tr.viewDef->globalProbeBounds = nearest->globalProbeBounds;
|
||||
tr.viewDef->irradianceImage = nearest->irradianceImage;
|
||||
|
||||
// form a triangle of the 3 closest probes
|
||||
idVec3 verts[3];
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
verts[i] = viewEnvprobes[0]->parms.origin;
|
||||
}
|
||||
|
||||
for( int i = 0; i < viewEnvprobes.Num() && i < 3; i++ )
|
||||
{
|
||||
RenderEnvprobeLocal* vProbe = viewEnvprobes[i];
|
||||
|
||||
verts[i] = vProbe->parms.origin;
|
||||
}
|
||||
|
||||
idVec3 closest = R_ClosestPointPointTriangle( testOrigin, verts[0], verts[1], verts[2] );
|
||||
idVec3 bary;
|
||||
|
||||
// find the barycentric coordinates
|
||||
float denom = idWinding::TriangleArea( verts[0], verts[1], verts[2] );
|
||||
if( denom == 0 )
|
||||
{
|
||||
// all points at same location
|
||||
bary.Set( 1, 0, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
float a, b, c;
|
||||
|
||||
a = idWinding::TriangleArea( closest, verts[1], verts[2] ) / denom;
|
||||
b = idWinding::TriangleArea( closest, verts[2], verts[0] ) / denom;
|
||||
c = idWinding::TriangleArea( closest, verts[0], verts[1] ) / denom;
|
||||
|
||||
bary.Set( a, b, c );
|
||||
}
|
||||
|
||||
tr.viewDef->radianceImageBlends.Set( bary.x, bary.y, bary.z, 0.0f );
|
||||
|
||||
for( int i = 0; i < viewEnvprobes.Num() && i < 3; i++ )
|
||||
{
|
||||
tr.viewDef->radianceImages[i] = viewEnvprobes[i]->radianceImage;
|
||||
}
|
||||
}
|
||||
// RB end
|
||||
|
||||
/*
|
||||
|
@ -539,33 +654,8 @@ void R_RenderView( viewDef_t* parms )
|
|||
}
|
||||
}
|
||||
|
||||
// RB: find closest environment probe
|
||||
if( tr.viewDef->areaNum != -1 && !tr.viewDef->isSubview )
|
||||
{
|
||||
float bestDist = idMath::INFINITY;
|
||||
|
||||
tr.viewDef->globalProbeBounds.Clear();
|
||||
|
||||
tr.viewDef->irradianceImage = globalImages->defaultUACIrradianceCube;
|
||||
tr.viewDef->radianceImage = globalImages->defaultUACRadianceCube;
|
||||
|
||||
for( viewEnvprobe_t* vProbe = tr.viewDef->viewEnvprobes; vProbe != NULL; vProbe = vProbe->next )
|
||||
{
|
||||
float dist = ( tr.viewDef->renderView.vieworg - vProbe->globalOrigin ).Length();
|
||||
if( ( dist < bestDist ) )
|
||||
{
|
||||
if( vProbe->irradianceImage->IsLoaded() && !vProbe->irradianceImage->IsDefaulted() )
|
||||
{
|
||||
tr.viewDef->globalProbeBounds = vProbe->globalProbeBounds;
|
||||
|
||||
tr.viewDef->irradianceImage = vProbe->irradianceImage;
|
||||
tr.viewDef->radianceImage = vProbe->radianceImage;
|
||||
|
||||
bestDist = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// RB: find closest environment probes so we can interpolate between them in the ambient shaders
|
||||
R_FindClosestEnvironmentProbes();
|
||||
|
||||
// write everything needed to the demo file
|
||||
if( common->WriteDemo() )
|
||||
|
|
|
@ -2367,4 +2367,82 @@ static void SetUpMikkTSpaceContext( SMikkTSpaceContext* context )
|
|||
context->m_pInterface = &mikkTSpaceInterface.mkInterface;
|
||||
}
|
||||
|
||||
// SP end
|
||||
// SP end
|
||||
|
||||
|
||||
// RB: Determines the closest point between a point and a triangle
|
||||
idVec3 R_ClosestPointPointTriangle( const idVec3& point, const idVec3& vertex1, const idVec3& vertex2, const idVec3& vertex3 )
|
||||
{
|
||||
idVec3 result;
|
||||
|
||||
// Source: Real-Time Collision Detection by Christer Ericson
|
||||
// Reference: Page 136
|
||||
|
||||
// check if P in vertex region outside A
|
||||
idVec3 ab = vertex2 - vertex1;
|
||||
idVec3 ac = vertex3 - vertex1;
|
||||
idVec3 ap = point - vertex1;
|
||||
|
||||
float d1 = ( ab * ap );
|
||||
float d2 = ( ac * ap );
|
||||
if( d1 <= 0.0f && d2 <= 0.0f )
|
||||
{
|
||||
result = vertex1; //Barycentric coordinates (1,0,0)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check if P in vertex region outside B
|
||||
idVec3 bp = point - vertex2;
|
||||
float d3 = ( ab * bp );
|
||||
float d4 = ( ac * bp );
|
||||
if( d3 >= 0.0f && d4 <= d3 )
|
||||
{
|
||||
result = vertex2; // barycentric coordinates (0,1,0)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check if P in edge region of AB, if so return projection of P onto AB
|
||||
float vc = d1 * d4 - d3 * d2;
|
||||
if( vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f )
|
||||
{
|
||||
float v = d1 / ( d1 - d3 );
|
||||
result = vertex1 + v * ab; //Barycentric coordinates (1-v,v,0)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check if P in vertex region outside C
|
||||
idVec3 cp = point - vertex3;
|
||||
float d5 = ( ab * cp );
|
||||
float d6 = ( ac * cp );
|
||||
if( d6 >= 0.0f && d5 <= d6 )
|
||||
{
|
||||
result = vertex3; //Barycentric coordinates (0,0,1)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check if P in edge region of AC, if so return projection of P onto AC
|
||||
float vb = d5 * d2 - d1 * d6;
|
||||
if( vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f )
|
||||
{
|
||||
float w = d2 / ( d2 - d6 );
|
||||
result = vertex1 + w * ac; //Barycentric coordinates (1-w,0,w)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check if P in edge region of BC, if so return projection of P onto BC
|
||||
float va = d3 * d6 - d5 * d4;
|
||||
if( va <= 0.0f && ( d4 - d3 ) >= 0.0f && ( d5 - d6 ) >= 0.0f )
|
||||
{
|
||||
float w = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) );
|
||||
result = vertex2 + w * ( vertex3 - vertex2 ); //Barycentric coordinates (0,1-w,w)
|
||||
return result;
|
||||
}
|
||||
|
||||
// P inside face region. Compute Q through its barycentric coordinates (u,v,w)
|
||||
float denom = 1.0f / ( va + vb + vc );
|
||||
float v2 = vb * denom;
|
||||
float w2 = vc * denom;
|
||||
result = vertex1 + ab * v2 + ac * w2; //= u*vertex1 + v*vertex2 + w*vertex3, u = va * denom = 1.0f - v - w
|
||||
|
||||
return result;
|
||||
}
|
Loading…
Reference in a new issue