mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-14 22:50:45 +00:00
Fixed a problem with octahedron irradiance sampling
This commit is contained in:
parent
b8907b9754
commit
86ff6cea87
5 changed files with 83 additions and 20 deletions
|
@ -69,27 +69,27 @@ struct PS_OUT
|
|||
Available online http://jcgt.org/published/0003/02/01/
|
||||
*/
|
||||
|
||||
float signNotZero( in float k )
|
||||
float signNotZeroFloat( float k )
|
||||
{
|
||||
return ( k >= 0.0 ) ? 1.0 : -1.0;
|
||||
}
|
||||
|
||||
|
||||
float2 signNotZero( in float2 v )
|
||||
float2 signNotZero( float2 v )
|
||||
{
|
||||
return float2( signNotZero( v.x ), signNotZero( v.y ) );
|
||||
return float2( signNotZeroFloat( v.x ), signNotZeroFloat( v.y ) );
|
||||
}
|
||||
|
||||
/** Assumes that v is a unit vector. The result is an octahedral vector on the [-1, +1] square. */
|
||||
float2 octEncode( in float3 v )
|
||||
float2 octEncode( float3 v )
|
||||
{
|
||||
float l1norm = abs( v.x ) + abs( v.y ) + abs( v.z );
|
||||
float2 result = v.xy * ( 1.0 / l1norm );
|
||||
float2 oct = v.xy * ( 1.0 / l1norm );
|
||||
if( v.z < 0.0 )
|
||||
{
|
||||
result = ( 1.0 - abs( result.yx ) ) * signNotZero( result.xy );
|
||||
oct = ( 1.0 - abs( oct.yx ) ) * signNotZero( oct.xy );
|
||||
}
|
||||
return result;
|
||||
return oct;
|
||||
}
|
||||
|
||||
|
||||
|
@ -127,6 +127,7 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
globalNormal.x = dot3( localNormal, fragment.texcoord4 );
|
||||
globalNormal.y = dot3( localNormal, fragment.texcoord5 );
|
||||
globalNormal.z = dot3( localNormal, fragment.texcoord6 );
|
||||
globalNormal = normalize( globalNormal );
|
||||
|
||||
float3 globalEye = normalize( fragment.texcoord3.xyz );
|
||||
|
||||
|
@ -199,7 +200,7 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
float2 normalizedOctCoord = octEncode( globalNormal );
|
||||
float2 normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5;
|
||||
|
||||
float3 irradiance = tex2D( samp7, normalizedOctCoord ).rgb;
|
||||
float3 irradiance = tex2D( samp7, normalizedOctCoordZeroOne ).rgb;
|
||||
float3 diffuseLight = ( kD * irradiance * diffuseColor ) * ao * ( rpDiffuseModifier.xyz * 1.0 );
|
||||
|
||||
// evaluate specular IBL
|
||||
|
@ -213,6 +214,7 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5;
|
||||
|
||||
float3 radiance = textureLod( samp8, normalizedOctCoordZeroOne, mip ).rgb;
|
||||
//radiance = float3( 0.0 );
|
||||
|
||||
float2 envBRDF = texture( samp3, float2( max( vDotN, 0.0 ), roughness ) ).rg;
|
||||
|
||||
|
|
|
@ -358,6 +358,11 @@ void idVec3::ProjectSelfOntoSphere( const float radius )
|
|||
// A Survey of Efficient Representations for Independent Unit Vectors, Journal of Computer Graphics Techniques (JCGT), vol. 3, no. 2, 1-30, 2014
|
||||
// Available online http://jcgt.org/published/0003/02/01/
|
||||
|
||||
inline float signNotZero( float k )
|
||||
{
|
||||
return ( k >= 0.0f ) ? 1.0f : -1.0f;
|
||||
}
|
||||
|
||||
idVec2 idVec3::ToOctahedral() const
|
||||
{
|
||||
const float L1norm = idMath::Fabs( x ) + idMath::Fabs( x ) + idMath::Fabs( x );
|
||||
|
@ -365,8 +370,8 @@ idVec2 idVec3::ToOctahedral() const
|
|||
idVec2 result;
|
||||
if( z < 0.0f )
|
||||
{
|
||||
result.x = ( 1.0f - idMath::Fabs( y ) ) * ( x >= 0.0f ) ? 1.0f : -1.0f;
|
||||
result.y = ( 1.0f - idMath::Fabs( x ) ) * ( y >= 0.0f ) ? 1.0f : -1.0f;
|
||||
result.x = ( 1.0f - idMath::Fabs( y ) ) * signNotZero( x );
|
||||
result.y = ( 1.0f - idMath::Fabs( x ) ) * signNotZero( y );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -386,8 +391,8 @@ void idVec3::FromOctahedral( const idVec2& o )
|
|||
if( z < 0.0f )
|
||||
{
|
||||
float oldX = x;
|
||||
x = ( 1.0f - idMath::Fabs( y ) ) * ( oldX >= 0.0f ) ? 1.0f : -1.0f;
|
||||
y = ( 1.0f - idMath::Fabs( oldX ) ) * ( y >= 0.0f ) ? 1.0f : -1.0f;
|
||||
x = ( 1.0f - idMath::Fabs( y ) ) * signNotZero( oldX );
|
||||
y = ( 1.0f - idMath::Fabs( oldX ) ) * signNotZero( y );
|
||||
}
|
||||
|
||||
Normalize();
|
||||
|
|
|
@ -1041,8 +1041,8 @@ void idImageManager::CreateIntrinsicImages()
|
|||
hellLoadingIconImage = ImageFromFile( "textures/loadingicon3", TF_DEFAULT, TR_CLAMP, TD_DEFAULT, CF_2D );
|
||||
|
||||
// RB begin
|
||||
defaultUACIrradianceCube = ImageFromFile( "env/UAC1_amb", TF_DEFAULT, TR_CLAMP, TD_LOOKUP_TABLE_RGB1, CF_2D );
|
||||
defaultUACRadianceCube = ImageFromFile( "env/UAC1_spec", TF_DEFAULT, TR_CLAMP, TD_LOOKUP_TABLE_RGB1, CF_2D );
|
||||
defaultUACIrradianceCube = ImageFromFile( "env/UAC2_amb", TF_DEFAULT, TR_CLAMP, TD_LOOKUP_TABLE_RGB1, CF_2D );
|
||||
defaultUACRadianceCube = ImageFromFile( "env/UAC2_spec", TF_DEFAULT, TR_CLAMP, TD_LOOKUP_TABLE_RGB1, CF_2D );
|
||||
// RB end
|
||||
|
||||
release_assert( loadingIconImage->referencedOutsideLevelLoad );
|
||||
|
|
|
@ -2483,8 +2483,8 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
"uniform sampler2D samp3 : register(s3); // texture 3 is the BRDF LUT\n"
|
||||
"uniform sampler2D samp4 : register(s4); // texture 4 is SSAO\n"
|
||||
"\n"
|
||||
"uniform samplerCUBE samp7 : register(s7); // texture 7 is the irradiance cube map\n"
|
||||
"uniform samplerCUBE samp8 : register(s8); // texture 8 is the radiance cube map\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"
|
||||
"\n"
|
||||
"struct PS_IN \n"
|
||||
"{\n"
|
||||
|
@ -2505,6 +2505,52 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
"};\n"
|
||||
"// *INDENT-ON*\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"/** Efficient GPU implementation of the octahedral unit vector encoding from\n"
|
||||
"\n"
|
||||
" Cigolle, Donow, Evangelakos, Mara, McGuire, Meyer,\n"
|
||||
" A Survey of Efficient Representations for Independent Unit Vectors, Journal of Computer Graphics Techniques (JCGT), vol. 3, no. 2, 1-30, 2014\n"
|
||||
"\n"
|
||||
" Available online http://jcgt.org/published/0003/02/01/\n"
|
||||
"*/\n"
|
||||
"\n"
|
||||
"float signNotZeroFloat( float k )\n"
|
||||
"{\n"
|
||||
" return ( k >= 0.0 ) ? 1.0 : -1.0;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"float2 signNotZero( float2 v )\n"
|
||||
"{\n"
|
||||
" return float2( signNotZeroFloat( v.x ), signNotZeroFloat( v.y ) );\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"/** Assumes that v is a unit vector. The result is an octahedral vector on the [-1, +1] square. */\n"
|
||||
"float2 octEncode( float3 v )\n"
|
||||
"{\n"
|
||||
" float l1norm = abs( v.x ) + abs( v.y ) + abs( v.z );\n"
|
||||
" float2 oct = v.xy * ( 1.0 / l1norm );\n"
|
||||
" if( v.z < 0.0 )\n"
|
||||
" {\n"
|
||||
" oct = ( 1.0 - abs( oct.yx ) ) * signNotZero( oct.xy );\n"
|
||||
" }\n"
|
||||
" return oct;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"/** Returns a unit vector. Argument o is an octahedral vector packed via octEncode,\n"
|
||||
" on the [-1, +1] square*/\n"
|
||||
"float3 octDecode( float2 o )\n"
|
||||
"{\n"
|
||||
" float3 v = float3( o.x, o.y, 1.0 - abs( o.x ) - abs( o.y ) );\n"
|
||||
" if( v.z < 0.0 )\n"
|
||||
" {\n"
|
||||
" v.xy = ( 1.0 - abs( v.yx ) ) * signNotZero( v.xy );\n"
|
||||
" }\n"
|
||||
" return normalize( v );\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void main( PS_IN fragment, out PS_OUT result )\n"
|
||||
"{\n"
|
||||
" half4 bumpMap = tex2D( samp0, fragment.texcoord0.xy );\n"
|
||||
|
@ -2527,11 +2573,12 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" globalNormal.x = dot3( localNormal, fragment.texcoord4 );\n"
|
||||
" globalNormal.y = dot3( localNormal, fragment.texcoord5 );\n"
|
||||
" globalNormal.z = dot3( localNormal, fragment.texcoord6 );\n"
|
||||
" globalNormal = normalize( globalNormal );\n"
|
||||
"\n"
|
||||
" float3 globalEye = normalize( fragment.texcoord3.xyz );\n"
|
||||
"\n"
|
||||
" float3 reflectionVector = globalNormal * dot3( globalEye, globalNormal );\n"
|
||||
" reflectionVector = ( reflectionVector * 2.0f ) - globalEye;\n"
|
||||
" reflectionVector = normalize( ( reflectionVector * 2.0f ) - globalEye );\n"
|
||||
"\n"
|
||||
" half vDotN = saturate( dot3( globalEye, globalNormal ) );\n"
|
||||
"\n"
|
||||
|
@ -2596,7 +2643,10 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
"\n"
|
||||
" // evaluate diffuse IBL\n"
|
||||
"\n"
|
||||
" float3 irradiance = texCUBE( samp7, globalNormal ).rgb;\n"
|
||||
" float2 normalizedOctCoord = octEncode( globalNormal );\n"
|
||||
" float2 normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5;\n"
|
||||
"\n"
|
||||
" float3 irradiance = tex2D( samp7, normalizedOctCoordZeroOne ).rgb;\n"
|
||||
" float3 diffuseLight = ( kD * irradiance * diffuseColor ) * ao * ( rpDiffuseModifier.xyz * 1.0 );\n"
|
||||
"\n"
|
||||
" // evaluate specular IBL\n"
|
||||
|
@ -2605,7 +2655,12 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" const float MAX_REFLECTION_LOD = 10.0;\n"
|
||||
" float mip = clamp( ( roughness * MAX_REFLECTION_LOD ), 0.0, MAX_REFLECTION_LOD );\n"
|
||||
" //float mip = 0.0;\n"
|
||||
" float3 radiance = textureLod( samp8, reflectionVector, mip ).rgb;\n"
|
||||
"\n"
|
||||
" normalizedOctCoord = octEncode( reflectionVector );\n"
|
||||
" normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5;\n"
|
||||
"\n"
|
||||
" float3 radiance = textureLod( samp8, normalizedOctCoordZeroOne, mip ).rgb;\n"
|
||||
" //radiance = float3( 0.0 );\n"
|
||||
"\n"
|
||||
" float2 envBRDF = texture( samp3, float2( max( vDotN, 0.0 ), roughness ) ).rg;\n"
|
||||
"\n"
|
||||
|
|
|
@ -938,7 +938,7 @@ CONSOLE_COMMAND( generateEnvironmentProbes, "Generate environment probes", NULL
|
|||
axis[5][2][1] = 1;
|
||||
|
||||
//--------------------------------------------
|
||||
// CAPTURE SCENE LIGHTING
|
||||
// CAPTURE SCENE LIGHTING TO CUBEMAPS
|
||||
//--------------------------------------------
|
||||
|
||||
// let's get the game window to a "size" resolution
|
||||
|
@ -975,6 +975,7 @@ CONSOLE_COMMAND( generateEnvironmentProbes, "Generate environment probes", NULL
|
|||
ref.viewaxis = axis[j];
|
||||
fullname.Format( "env/%s/envprobe%i%s", baseName.c_str(), i, extension );
|
||||
|
||||
// TODO capture resolved HDR data without bloom aka _currentRender in 16bit float HDR RGB
|
||||
tr.TakeScreenshot( size, size, fullname, blends, &ref, PNG );
|
||||
//tr.CaptureRenderToFile( fullname, false );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue