mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-14 22:50:45 +00:00
Don't use 1 pixel border for non-lightgrid octahedrons
This commit is contained in:
parent
dcf9cc4e6d
commit
b96b085d04
10 changed files with 83 additions and 84 deletions
|
@ -59,12 +59,14 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
float2 normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5;
|
||||
|
||||
// offset by one pixel border bleed size for linear filtering
|
||||
#if 0
|
||||
float2 octCoordNormalizedToTextureDimensions = ( normalizedOctCoordZeroOne * ( rpCascadeDistances.x - float( 2.0 ) ) ) / rpCascadeDistances.xy;
|
||||
|
||||
float2 probeTopLeftPosition = float2( 1.0, 1.0 );
|
||||
float2 normalizedProbeTopLeftPosition = probeTopLeftPosition * rpCascadeDistances.zw;
|
||||
|
||||
normalizedOctCoordZeroOne.xy = normalizedProbeTopLeftPosition + octCoordNormalizedToTextureDimensions;
|
||||
#endif
|
||||
|
||||
//normalizedOctCoordZeroOne = TextureCoordFromDirection( reflectionVector, 0, int( rpCascadeDistances.x ), int( rpCascadeDistances.y ), int( rpCascadeDistances.x ) - 2 );
|
||||
|
||||
|
|
|
@ -119,6 +119,26 @@ bool AABBRayIntersection( float3 b[2], float3 start, float3 dir, out float scale
|
|||
hit[ax2] >= b[0][ax2] && hit[ax2] <= b[1][ax2] );
|
||||
}
|
||||
|
||||
|
||||
float2 OctTexCoord( float3 worldDir )
|
||||
{
|
||||
float2 normalizedOctCoord = octEncode( worldDir );
|
||||
float2 normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5;
|
||||
|
||||
// offset by one pixel border bleed size for linear filtering
|
||||
#if 0
|
||||
// texcoord sizes in rpCascadeDistances are not valid
|
||||
float2 octCoordNormalizedToTextureDimensions = ( normalizedOctCoordZeroOne * ( rpCascadeDistances.x - float( 2.0 ) ) ) / rpCascadeDistances.xy;
|
||||
|
||||
float2 probeTopLeftPosition = float2( 1.0, 1.0 );
|
||||
float2 normalizedProbeTopLeftPosition = probeTopLeftPosition * rpCascadeDistances.zw;
|
||||
|
||||
normalizedOctCoordZeroOne.xy = normalizedProbeTopLeftPosition + octCoordNormalizedToTextureDimensions;
|
||||
#endif
|
||||
|
||||
return normalizedOctCoordZeroOne;
|
||||
}
|
||||
|
||||
void main( PS_IN fragment, out PS_OUT result )
|
||||
{
|
||||
half4 bumpMap = tex2D( samp0, fragment.texcoord0.xy );
|
||||
|
@ -236,8 +256,7 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
|
||||
// evaluate diffuse IBL
|
||||
|
||||
float2 normalizedOctCoord = octEncode( globalNormal );
|
||||
float2 normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5;
|
||||
float2 normalizedOctCoordZeroOne = OctTexCoord( globalNormal );
|
||||
|
||||
float3 irradiance = tex2D( samp7, normalizedOctCoordZeroOne ).rgb;
|
||||
float3 diffuseLight = ( kD * irradiance * diffuseColor ) * ao * ( rpDiffuseModifier.xyz * 1.0 );
|
||||
|
@ -249,8 +268,7 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
float mip = clamp( ( roughness * MAX_REFLECTION_LOD ), 0.0, MAX_REFLECTION_LOD );
|
||||
//float mip = 0.0;
|
||||
|
||||
normalizedOctCoord = octEncode( reflectionVector );
|
||||
normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5;
|
||||
normalizedOctCoordZeroOne = OctTexCoord( reflectionVector );
|
||||
|
||||
float3 radiance = textureLod( samp8, normalizedOctCoordZeroOne, mip ).rgb;
|
||||
//radiance = float3( 0.0 );
|
||||
|
|
|
@ -35,7 +35,7 @@ static const int MAX_SSAO_BUFFERS = 2;
|
|||
static const int MAX_HIERARCHICAL_ZBUFFERS = 6; // native resolution + 5 MIP LEVELS
|
||||
|
||||
static const int RADIANCE_CUBEMAP_SIZE = 256;
|
||||
static const int IRRADIANCE_CUBEMAP_SIZE = 34;
|
||||
static const int IRRADIANCE_CUBEMAP_SIZE = 30 + 2;
|
||||
|
||||
#if 1
|
||||
static int shadowMapResolutions[MAX_SHADOWMAP_RESOLUTIONS] = { 2048, 1024, 512, 512, 256 };
|
||||
|
|
|
@ -1323,7 +1323,7 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useFas
|
|||
const textureUsage_t specUsage = din->specularImage->GetUsage();
|
||||
|
||||
// RB begin
|
||||
if( useIBL && currentSpace->useLightGrid )
|
||||
if( useIBL && currentSpace->useLightGrid && r_useLightGrid.GetBool() )
|
||||
{
|
||||
idVec4 probeMins, probeMaxs, probeCenter;
|
||||
|
||||
|
|
|
@ -516,7 +516,7 @@ struct calcEnvprobeParms_t
|
|||
|
||||
|
||||
static const int LIGHTGRID_IRRADIANCE_BORDER_SIZE = 2; // one pixel border all around the octahedron so 2 on each side
|
||||
static const int LIGHTGRID_IRRADIANCE_SIZE = ( 16 * 1 ) + LIGHTGRID_IRRADIANCE_BORDER_SIZE;
|
||||
static const int LIGHTGRID_IRRADIANCE_SIZE = 30 + LIGHTGRID_IRRADIANCE_BORDER_SIZE;
|
||||
|
||||
struct calcLightGridPointParms_t
|
||||
{
|
||||
|
@ -1208,6 +1208,8 @@ extern idCVar r_pbrDebug;
|
|||
extern idCVar r_showViewEnvprobes;
|
||||
extern idCVar r_showLightGrid; // show Quake 3 style light grid points
|
||||
|
||||
extern idCVar r_useLightGrid;
|
||||
|
||||
extern idCVar r_exposure;
|
||||
// RB end
|
||||
|
||||
|
|
|
@ -2628,12 +2628,14 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" float2 normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5;\n"
|
||||
"\n"
|
||||
" // offset by one pixel border bleed size for linear filtering\n"
|
||||
"#if 0\n"
|
||||
" float2 octCoordNormalizedToTextureDimensions = ( normalizedOctCoordZeroOne * ( rpCascadeDistances.x - float( 2.0 ) ) ) / rpCascadeDistances.xy;\n"
|
||||
"\n"
|
||||
" float2 probeTopLeftPosition = float2( 1.0, 1.0 );\n"
|
||||
" float2 normalizedProbeTopLeftPosition = probeTopLeftPosition * rpCascadeDistances.zw;\n"
|
||||
"\n"
|
||||
" normalizedOctCoordZeroOne.xy = normalizedProbeTopLeftPosition + octCoordNormalizedToTextureDimensions;\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
" //normalizedOctCoordZeroOne = TextureCoordFromDirection( reflectionVector, 0, int( rpCascadeDistances.x ), int( rpCascadeDistances.y ), int( rpCascadeDistances.x ) - 2 );\n"
|
||||
"\n"
|
||||
|
@ -4884,6 +4886,26 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" hit[ax2] >= b[0][ax2] && hit[ax2] <= b[1][ax2] );\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"float2 OctTexCoord( float3 worldDir )\n"
|
||||
"{\n"
|
||||
" float2 normalizedOctCoord = octEncode( worldDir );\n"
|
||||
" float2 normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5;\n"
|
||||
"\n"
|
||||
" // offset by one pixel border bleed size for linear filtering\n"
|
||||
"#if 0\n"
|
||||
" // texcoord sizes in rpCascadeDistances are not valid\n"
|
||||
" float2 octCoordNormalizedToTextureDimensions = ( normalizedOctCoordZeroOne * ( rpCascadeDistances.x - float( 2.0 ) ) ) / rpCascadeDistances.xy;\n"
|
||||
"\n"
|
||||
" float2 probeTopLeftPosition = float2( 1.0, 1.0 );\n"
|
||||
" float2 normalizedProbeTopLeftPosition = probeTopLeftPosition * rpCascadeDistances.zw;\n"
|
||||
"\n"
|
||||
" normalizedOctCoordZeroOne.xy = normalizedProbeTopLeftPosition + octCoordNormalizedToTextureDimensions;\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
" return normalizedOctCoordZeroOne;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void main( PS_IN fragment, out PS_OUT result )\n"
|
||||
"{\n"
|
||||
" half4 bumpMap = tex2D( samp0, fragment.texcoord0.xy );\n"
|
||||
|
@ -5001,8 +5023,7 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
"\n"
|
||||
" // evaluate diffuse IBL\n"
|
||||
"\n"
|
||||
" float2 normalizedOctCoord = octEncode( globalNormal );\n"
|
||||
" float2 normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5;\n"
|
||||
" float2 normalizedOctCoordZeroOne = OctTexCoord( globalNormal );\n"
|
||||
"\n"
|
||||
" float3 irradiance = tex2D( samp7, normalizedOctCoordZeroOne ).rgb;\n"
|
||||
" float3 diffuseLight = ( kD * irradiance * diffuseColor ) * ao * ( rpDiffuseModifier.xyz * 1.0 );\n"
|
||||
|
@ -5014,8 +5035,7 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" float mip = clamp( ( roughness * MAX_REFLECTION_LOD ), 0.0, MAX_REFLECTION_LOD );\n"
|
||||
" //float mip = 0.0;\n"
|
||||
"\n"
|
||||
" normalizedOctCoord = octEncode( reflectionVector );\n"
|
||||
" normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5;\n"
|
||||
" normalizedOctCoordZeroOne = OctTexCoord( reflectionVector );\n"
|
||||
"\n"
|
||||
" float3 radiance = textureLod( samp8, normalizedOctCoordZeroOne, mip ).rgb;\n"
|
||||
" //radiance = float3( 0.0 );\n"
|
||||
|
|
|
@ -301,6 +301,8 @@ idCVar r_pbrDebug( "r_pbrDebug", "0", CVAR_RENDERER | CVAR_INTEGER, "show which
|
|||
idCVar r_showViewEnvprobes( "r_showViewEnvprobes", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = displays the bounding boxes of all view environment probes, 2 = show irradiance" );
|
||||
idCVar r_showLightGrid( "r_showLightGrid", "0", CVAR_RENDERER | CVAR_INTEGER, "show Quake 3 style light grid points" );
|
||||
|
||||
idCVar r_useLightGrid( "r_useLightGrid", "1", CVAR_RENDERER | CVAR_BOOL, "" );
|
||||
|
||||
idCVar r_exposure( "r_exposure", "0.5", CVAR_ARCHIVE | CVAR_RENDERER | CVAR_FLOAT, "HDR exposure or LDR brightness [0.0 .. 1.0]", 0.0f, 1.0f );
|
||||
// RB end
|
||||
|
||||
|
|
|
@ -769,10 +769,10 @@ void R_DeriveEnvprobeData( RenderEnvprobeLocal* probe )
|
|||
|
||||
// TODO get preconvolved cubemaps
|
||||
fullname.Format( "env/%s/envprobe%i_amb", basename.c_str(), probeIndex );
|
||||
probe->irradianceImage = globalImages->ImageFromFile( fullname, TF_LINEAR, TR_REPEAT, TD_R11G11B10F, CF_2D_PACKED_MIPCHAIN );
|
||||
probe->irradianceImage = globalImages->ImageFromFile( fullname, TF_LINEAR, TR_CLAMP, TD_R11G11B10F, CF_2D_PACKED_MIPCHAIN );
|
||||
|
||||
fullname.Format( "env/%s/envprobe%i_spec", basename.c_str(), probeIndex );
|
||||
probe->radianceImage = globalImages->ImageFromFile( fullname, TF_DEFAULT, TR_REPEAT, TD_R11G11B10F, CF_2D_PACKED_MIPCHAIN );
|
||||
probe->radianceImage = globalImages->ImageFromFile( fullname, TF_DEFAULT, TR_CLAMP, TD_R11G11B10F, CF_2D_PACKED_MIPCHAIN );
|
||||
|
||||
// ------------------------------------
|
||||
// compute the probe projection matrix
|
||||
|
|
|
@ -467,6 +467,7 @@ idVec2 NormalizedOctCoord( int x, int y, const int probeWithBorderSide )
|
|||
const int margin = 2;
|
||||
|
||||
// RB: FIXME - margin * 2 is wrong but looks better
|
||||
// figure out why
|
||||
int probeSideLength = Max( 2, probeWithBorderSide - ( margin * 2 ) );
|
||||
|
||||
idVec2 octFragCoord = idVec2( ( x - margin ) % probeWithBorderSide, ( y - margin ) % probeWithBorderSide );
|
||||
|
@ -477,6 +478,16 @@ idVec2 NormalizedOctCoord( int x, int y, const int probeWithBorderSide )
|
|||
#endif
|
||||
}
|
||||
|
||||
static inline idVec2 NormalizedOctCoordNoBorder( int x, int y, const int probeWithBorderSide )
|
||||
{
|
||||
int probeSideLength = probeWithBorderSide;
|
||||
|
||||
idVec2 octFragCoord = idVec2( x % probeWithBorderSide, y % probeWithBorderSide );
|
||||
|
||||
// Add back the half pixel to get pixel center normalized coordinates
|
||||
return ( idVec2( octFragCoord ) + idVec2( 0.5f, 0.5f ) ) * ( 2.0f / float( probeSideLength ) ) - idVec2( 1.0f, 1.0f );
|
||||
}
|
||||
|
||||
/*
|
||||
static inline float LatLongTexelArea( const idVec2i& pos, const idVec2i& imageSize )
|
||||
{
|
||||
|
@ -615,7 +626,7 @@ void CalculateIrradianceJob( calcEnvprobeParms_t* parms )
|
|||
{
|
||||
for( int y = dstRect.y; y < ( dstRect.y + dstRect.w ); y++ )
|
||||
{
|
||||
idVec2 octCoord = NormalizedOctCoord( x, y, dstRect.z );
|
||||
idVec2 octCoord = NormalizedOctCoordNoBorder( x, y, dstRect.z );
|
||||
|
||||
// convert UV coord to 3D direction
|
||||
idVec3 dir;
|
||||
|
@ -727,11 +738,11 @@ void CalculateIrradianceJob( calcEnvprobeParms_t* parms )
|
|||
if( mip > 0 )
|
||||
{
|
||||
// move back to [0, 1] coords
|
||||
octCoord = NormalizedOctCoord( x - dstRect.x, y - dstRect.y, dstRect.z );
|
||||
octCoord = NormalizedOctCoordNoBorder( x - dstRect.x, y - dstRect.y, dstRect.z );
|
||||
}
|
||||
else
|
||||
{
|
||||
octCoord = NormalizedOctCoord( x, y, dstRect.z );
|
||||
octCoord = NormalizedOctCoordNoBorder( x, y, dstRect.z );
|
||||
}
|
||||
|
||||
// convert UV coord to 3D direction
|
||||
|
@ -838,11 +849,11 @@ void CalculateRadianceJob( calcEnvprobeParms_t* parms )
|
|||
if( mip > 0 )
|
||||
{
|
||||
// move back to [0, 1] coords
|
||||
octCoord = NormalizedOctCoord( x - dstRect.x, y - dstRect.y, dstRect.z );
|
||||
octCoord = NormalizedOctCoordNoBorder( x - dstRect.x, y - dstRect.y, dstRect.z );
|
||||
}
|
||||
else
|
||||
{
|
||||
octCoord = NormalizedOctCoord( x, y, dstRect.z );
|
||||
octCoord = NormalizedOctCoordNoBorder( x, y, dstRect.z );
|
||||
}
|
||||
|
||||
// convert UV coord to 3D direction
|
||||
|
|
|
@ -38,7 +38,7 @@ If you have questions concerning this license or the applicable additional terms
|
|||
|
||||
#define STORE_LIGHTGRID_SHDATA 0
|
||||
|
||||
static const byte BLGRID_VERSION = 3;
|
||||
static const byte BLGRID_VERSION = 4;
|
||||
static const unsigned int BLGRID_MAGIC = ( 'P' << 24 ) | ( 'R' << 16 ) | ( 'O' << 8 ) | BLGRID_VERSION;
|
||||
|
||||
|
||||
|
@ -513,7 +513,7 @@ bool idRenderWorldLocal::LoadLightGridFile( const char* name )
|
|||
|
||||
// if we are reloading the same map, check the timestamp
|
||||
// and try to skip all the work
|
||||
ID_TIME_T currentTimeStamp = fileSystem->GetTimestamp( fileName );
|
||||
ID_TIME_T sourceTimeStamp = fileSystem->GetTimestamp( fileName );
|
||||
|
||||
// see if we have a generated version of this
|
||||
bool loaded = false;
|
||||
|
@ -524,11 +524,14 @@ bool idRenderWorldLocal::LoadLightGridFile( const char* name )
|
|||
{
|
||||
int numEntries = 0;
|
||||
int magic = 0;
|
||||
ID_TIME_T storedTimeStamp;
|
||||
file->ReadBig( magic );
|
||||
file->ReadBig( storedTimeStamp );
|
||||
file->ReadBig( numEntries );
|
||||
if( magic == BLGRID_MAGIC && numEntries > 0 )
|
||||
if( ( magic == BLGRID_MAGIC ) && ( sourceTimeStamp == storedTimeStamp ) && ( numEntries > 0 ) )
|
||||
{
|
||||
loaded = true;
|
||||
|
||||
for( int i = 0; i < numEntries; i++ )
|
||||
{
|
||||
idStrStatic< MAX_OSPATH > type;
|
||||
|
@ -564,6 +567,7 @@ bool idRenderWorldLocal::LoadLightGridFile( const char* name )
|
|||
{
|
||||
int magic = BLGRID_MAGIC;
|
||||
outputFile->WriteBig( magic );
|
||||
outputFile->WriteBig( sourceTimeStamp );
|
||||
outputFile->WriteBig( numEntries );
|
||||
}
|
||||
|
||||
|
@ -646,8 +650,10 @@ bool idRenderWorldLocal::LoadLightGridFile( const char* name )
|
|||
if( outputFile != NULL )
|
||||
{
|
||||
outputFile->Seek( 0, FS_SEEK_SET );
|
||||
|
||||
int magic = BLGRID_MAGIC;
|
||||
outputFile->WriteBig( magic );
|
||||
outputFile->WriteBig( sourceTimeStamp );
|
||||
outputFile->WriteBig( numEntries );
|
||||
}
|
||||
}
|
||||
|
@ -913,58 +919,6 @@ void CalculateLightGridPointJob( calcLightGridPointParms_t* parms )
|
|||
shRadiance[i].Zero();
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
// build SH by only iterating over the octahedron
|
||||
// RB: not used because I don't know the texel area of an octahedron pixel and the cubemap texel area is too small
|
||||
// however it would be nice to use this because it would be 6 times faster
|
||||
|
||||
idVec4 dstRect = R_CalculateMipRect( parms->outHeight, 0 );
|
||||
|
||||
for( int x = dstRect.x; x < ( dstRect.x + dstRect.z ); x++ )
|
||||
{
|
||||
for( int y = dstRect.y; y < ( dstRect.y + dstRect.w ); y++ )
|
||||
{
|
||||
idVec2 octCoord = NormalizedOctCoord( x, y, dstRect.z );
|
||||
|
||||
// convert UV coord to 3D direction
|
||||
idVec3 dir;
|
||||
|
||||
dir.FromOctahedral( octCoord );
|
||||
|
||||
float u, v;
|
||||
idVec3 radiance;
|
||||
R_SampleCubeMapHDR( dir, parms->outHeight, buffers, &radiance[0], u, v );
|
||||
|
||||
//radiance = dir * 0.5 + idVec3( 0.5f, 0.5f, 0.5f );
|
||||
|
||||
// convert from [0 .. size-1] to [-1.0 + invSize .. 1.0 - invSize]
|
||||
const float uu = 2.0f * ( u * invDstSize ) - 1.0f;
|
||||
const float vv = 2.0f * ( v * invDstSize ) - 1.0f;
|
||||
|
||||
float texelArea = CubemapTexelSolidAngle( uu, vv, invDstSize );
|
||||
|
||||
const SphericalHarmonicsT<float, 4>& sh = shEvaluate<4>( dir );
|
||||
|
||||
bool shValid = true;
|
||||
for( int i = 0; i < 25; i++ )
|
||||
{
|
||||
if( IsNAN( sh[i] ) )
|
||||
{
|
||||
shValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( shValid )
|
||||
{
|
||||
shAddWeighted( shRadiance, sh, radiance * texelArea );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// build SH by iterating over all cubemap pixels
|
||||
|
||||
for( int side = 0; side < 6; side++ )
|
||||
|
@ -1008,8 +962,6 @@ void CalculateLightGridPointJob( calcLightGridPointParms_t* parms )
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
for( int i = 0; i < shSize( 3 ); i++ )
|
||||
{
|
||||
parms->shRadiance[i] = shRadiance[i];
|
||||
|
@ -1259,7 +1211,7 @@ CONSOLE_COMMAND( bakeLightGrids, "Bake irradiance/vis light grid data", NULL )
|
|||
lightGridPoint_t* gridPoint = &area->lightGrid.lightGridPoints[ gridCoord[0] * gridStep[0] + gridCoord[1] * gridStep[1] + gridCoord[2] * gridStep[2] ];
|
||||
if( !gridPoint->valid )
|
||||
{
|
||||
progressBar.Increment();
|
||||
//progressBar.Increment();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1284,14 +1236,6 @@ CONSOLE_COMMAND( bakeLightGrids, "Bake irradiance/vis light grid data", NULL )
|
|||
byte* float16FRGB = tr.CaptureRenderToBuffer( captureSize, captureSize, &ref );
|
||||
|
||||
jobParms->radiance[ side ] = float16FRGB;
|
||||
|
||||
#if 0
|
||||
if( i < 3 )
|
||||
{
|
||||
filename.Format( "env/%s/area%i_lightgridpoint%i%s.exr", baseName.c_str(), a, i, extension );
|
||||
R_WriteEXR( filename, float16FRGB, 3, size, size, "fs_basepath" );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
tr.lightGridJobs.Append( jobParms );
|
||||
|
|
Loading…
Reference in a new issue