Added second interaction shader path for PBR so old materials don't look glossy

This commit is contained in:
Robert Beckebans 2020-04-16 18:08:50 +02:00
parent 41d8bd9ec2
commit 1972bcdad4
11 changed files with 398 additions and 258 deletions

View file

@ -55,7 +55,8 @@ struct PS_OUT {
half4 color : COLOR;
};
void main( PS_IN fragment, out PS_OUT result ) {
void main( PS_IN fragment, out PS_OUT result )
{
half4 bumpMap = tex2D( samp0, fragment.texcoord0.xy );
// half4 lightFalloff = idtex2Dproj( samp1, fragment.texcoord2 );
// half4 lightProj = idtex2Dproj( samp2, fragment.texcoord3 );
@ -100,9 +101,8 @@ void main( PS_IN fragment, out PS_OUT result ) {
float3 reflectionVector = globalNormal * dot3( globalEye, globalNormal );
reflectionVector = ( reflectionVector * 2.0f ) - globalEye;
#if 1 //defined(USE_PBR)
#if defined(USE_PBR)
#if defined( USE_PBR )
const half metallic = specMapSRGB.g;
const half roughness = specMapSRGB.r;
const half glossiness = 1.0 - roughness;
@ -119,8 +119,11 @@ void main( PS_IN fragment, out PS_OUT result ) {
half3 diffuseColor = baseColor * ( 1.0 - metallic );
half3 specularColor = lerp( dielectricColor, baseColor, metallic );
#if defined( DEBUG_PBR )
diffuseColor = half3( 0.0, 0.0, 0.0 );
specularColor = half3( 0.0, 1.0, 0.0 );
#endif
#else
// HACK calculate roughness from D3 gloss maps
float Y = dot( LUMINANCE_SRGB.rgb, specMapSRGB.rgb );
@ -133,8 +136,11 @@ void main( PS_IN fragment, out PS_OUT result ) {
half3 diffuseColor = diffuseMap;
half3 specularColor = specMap.rgb;
#if defined( DEBUG_PBR )
diffuseColor = half3( 0.0, 0.0, 0.0 );
specularColor = half3( 1.0, 0.0, 0.0 );
#endif
#endif
float3 diffuseLight = ( texCUBE( samp7, globalNormal ).rgb ) * diffuseColor * ( rpDiffuseModifier.xyz ) * 3.5f;
@ -144,27 +150,6 @@ void main( PS_IN fragment, out PS_OUT result ) {
float3 specularLight = envColor * specularColor;
#else
// non PBR path
float3 diffuseLight = ( texCUBE( samp7, globalNormal ).rgb ) * diffuseMap.rgb * ( rpDiffuseModifier.xyz ) * 3.5f;
//float3 diffuseLight = diffuseMap.rgb * ( rpDiffuseModifier.xyz ) * 1.5f;
// HACK calculate roughness from D3 gloss maps
float Y = dot( LUMINANCE_SRGB.rgb, specMapSRGB.rgb );
//const float glossiness = clamp( 1.0 - specMapSRGB.r, 0.0, 0.98 );
const float glossiness = clamp( pow( Y, 1.0 / 2.0 ), 0.0, 0.98 );
const float roughness = 1.0 - glossiness;
float mip = clamp( ( roughness * 7.0 ) + 0.0, 0.0, 10.0 );
float3 envColor = ( textureLod( samp8, reflectionVector, mip ).rgb ) * ( rpSpecularModifier.xyz ) * 0.5f;
float3 specularLight = envColor * specMap.rgb;
#endif
// add glossy fresnel
half hDotN = saturate( dot3( globalEye, globalNormal ) );

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-2014 Robert Beckebans
Copyright (C) 2013-2020 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -30,23 +30,23 @@ If you have questions concerning this license or the applicable additional terms
#include "global.inc.hlsl"
#include "BRDF.inc.hlsl"
uniform sampler2D samp0 : register(s0); // texture 1 is the per-surface normal map
uniform sampler2D samp1 : register(s1); // texture 3 is the per-surface specular or roughness/metallic/AO mixer map
uniform sampler2D samp2 : register(s2); // texture 2 is the per-surface baseColor map
uniform sampler2D samp3 : register(s3); // texture 4 is the light falloff texture
uniform sampler2D samp4 : register(s4); // texture 5 is the light projection texture
uniform sampler2D samp0 : register(s0); // texture 1 is the per-surface normal map
uniform sampler2D samp1 : register(s1); // texture 3 is the per-surface specular or roughness/metallic/AO mixer map
uniform sampler2D samp2 : register(s2); // texture 2 is the per-surface baseColor map
uniform sampler2D samp3 : register(s3); // texture 4 is the light falloff texture
uniform sampler2D samp4 : register(s4); // texture 5 is the light projection texture
struct PS_IN
{
half4 position : VPOS;
half4 texcoord0 : TEXCOORD0_centroid;
half4 texcoord1 : TEXCOORD1_centroid;
half4 texcoord2 : TEXCOORD2_centroid;
half4 texcoord3 : TEXCOORD3_centroid;
half4 texcoord4 : TEXCOORD4_centroid;
half4 texcoord5 : TEXCOORD5_centroid;
half4 texcoord6 : TEXCOORD6_centroid;
half4 color : COLOR0;
half4 position : VPOS;
half4 texcoord0 : TEXCOORD0_centroid;
half4 texcoord1 : TEXCOORD1_centroid;
half4 texcoord2 : TEXCOORD2_centroid;
half4 texcoord3 : TEXCOORD3_centroid;
half4 texcoord4 : TEXCOORD4_centroid;
half4 texcoord5 : TEXCOORD5_centroid;
half4 texcoord6 : TEXCOORD6_centroid;
half4 color : COLOR0;
};
struct PS_OUT
@ -96,9 +96,9 @@ void main( PS_IN fragment, out PS_OUT result )
half3 halfAngleVector = normalize( lightVector + viewVector );
half hdotN = clamp( dot3( halfAngleVector, localNormal ), 0.0, 1.0 );
#if 1 //defined(USE_PBR)
#if 1
#if 1 //defined(USE_METALNESS)
#if defined( USE_PBR )
const half metallic = specMapSRGB.g;
const half roughness = specMapSRGB.r;
const half glossiness = 1.0 - roughness;

View file

@ -30,16 +30,14 @@ If you have questions concerning this license or the applicable additional terms
#include "global.inc.hlsl"
#include "BRDF.inc.hlsl"
uniform sampler2D samp0 : register(s0); // texture 1 is the per-surface normal map
uniform sampler2D samp1 : register(s1); // texture 3 is the per-surface specular or roughness/metallic/AO mixer map
uniform sampler2D samp2 : register(s2); // texture 2 is the per-surface baseColor map
uniform sampler2D samp3 : register(s3); // texture 4 is the light falloff texture
uniform sampler2D samp4 : register(s4); // texture 5 is the light projection texture
uniform sampler2D samp0 : register(s0); // texture 1 is the per-surface normal map
uniform sampler2D samp1 : register(s1); // texture 3 is the per-surface specular or roughness/metallic/AO mixer map
uniform sampler2D samp2 : register(s2); // texture 2 is the per-surface baseColor map
uniform sampler2D samp3 : register(s3); // texture 4 is the light falloff texture
uniform sampler2D samp4 : register(s4); // texture 5 is the light projection texture
uniform sampler2DArrayShadow samp5 : register(s5); // texture 6 is the shadowmap array
uniform sampler2D samp6 : register(s6); // texture 7 is the jitter texture
struct PS_IN
{
half4 position : VPOS;
@ -278,9 +276,9 @@ void main( PS_IN fragment, out PS_OUT result )
half3 halfAngleVector = normalize( lightVector + viewVector );
half hdotN = clamp( dot3( halfAngleVector, localNormal ), 0.0, 1.0 );
#if 1 //defined(USE_PBR)
#if 1
#if 1 //defined(USE_METALNESS)
#if defined( USE_PBR )
const half metallic = specMapSRGB.g;
const half roughness = specMapSRGB.r;
const half glossiness = 1.0 - roughness;

View file

@ -1273,43 +1273,64 @@ void idRenderBackend::SetupInteractionStage( const shaderStage_t* surfaceStage,
idRenderBackend::DrawSingleInteraction
=================
*/
void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useIBL )
void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useFastPath, bool useIBL, bool setInteractionShader )
{
if( din->bumpImage == NULL )
if( !useFastPath )
{
// stage wasn't actually an interaction
return;
if( din->bumpImage == NULL )
{
// stage wasn't actually an interaction
return;
}
if( din->diffuseImage == NULL || r_skipDiffuse.GetBool() )
{
// this isn't a YCoCg black, but it doesn't matter, because
// the diffuseColor will also be 0
din->diffuseImage = globalImages->blackImage;
}
if( din->specularImage == NULL || r_skipSpecular.GetBool() || ( din->vLight && din->vLight->lightShader->IsAmbientLight() ) )
{
din->specularImage = globalImages->blackImage;
}
if( r_skipBump.GetBool() )
{
din->bumpImage = globalImages->flatNormalMap;
}
// if we wouldn't draw anything, don't call the Draw function
const bool diffuseIsBlack = ( din->diffuseImage == globalImages->blackImage )
|| ( ( din->diffuseColor[0] <= 0 ) && ( din->diffuseColor[1] <= 0 ) && ( din->diffuseColor[2] <= 0 ) );
const bool specularIsBlack = ( din->specularImage == globalImages->blackImage )
|| ( ( din->specularColor[0] <= 0 ) && ( din->specularColor[1] <= 0 ) && ( din->specularColor[2] <= 0 ) );
if( diffuseIsBlack && specularIsBlack )
{
return;
}
// bump matrix
SetVertexParm( RENDERPARM_BUMPMATRIX_S, din->bumpMatrix[0].ToFloatPtr() );
SetVertexParm( RENDERPARM_BUMPMATRIX_T, din->bumpMatrix[1].ToFloatPtr() );
// diffuse matrix
SetVertexParm( RENDERPARM_DIFFUSEMATRIX_S, din->diffuseMatrix[0].ToFloatPtr() );
SetVertexParm( RENDERPARM_DIFFUSEMATRIX_T, din->diffuseMatrix[1].ToFloatPtr() );
// specular matrix
SetVertexParm( RENDERPARM_SPECULARMATRIX_S, din->specularMatrix[0].ToFloatPtr() );
SetVertexParm( RENDERPARM_SPECULARMATRIX_T, din->specularMatrix[1].ToFloatPtr() );
RB_SetVertexColorParms( din->vertexColor );
SetFragmentParm( RENDERPARM_DIFFUSEMODIFIER, din->diffuseColor.ToFloatPtr() );
SetFragmentParm( RENDERPARM_SPECULARMODIFIER, din->specularColor.ToFloatPtr() );
}
if( din->diffuseImage == NULL || r_skipDiffuse.GetBool() )
{
// this isn't a YCoCg black, but it doesn't matter, because
// the diffuseColor will also be 0
din->diffuseImage = globalImages->blackImage;
}
if( din->specularImage == NULL || r_skipSpecular.GetBool() || din->ambientLight )
{
din->specularImage = globalImages->blackImage;
}
if( r_skipBump.GetBool() )
{
din->bumpImage = globalImages->flatNormalMap;
}
// if we wouldn't draw anything, don't call the Draw function
const bool diffuseIsBlack = ( din->diffuseImage == globalImages->blackImage )
|| ( ( din->diffuseColor[0] <= 0 ) && ( din->diffuseColor[1] <= 0 ) && ( din->diffuseColor[2] <= 0 ) );
const bool specularIsBlack = ( din->specularImage == globalImages->blackImage )
|| ( ( din->specularColor[0] <= 0 ) && ( din->specularColor[1] <= 0 ) && ( din->specularColor[2] <= 0 ) );
if( diffuseIsBlack && specularIsBlack )
{
return;
}
const textureUsage_t specUsage = din->specularImage->GetUsage();
// RB begin
if( useIBL )
{
const textureUsage_t specUsage = din->specularImage->GetUsage();
if( specUsage == TD_SPECULAR_PBR_RMAO || specUsage == TD_SPECULAR_PBR_RMAOD )
{
// PBR path with roughness, metal and AO
@ -1333,24 +1354,154 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useIBL
renderProgManager.BindShader_ImageBasedLighting();
}
}
GL_SelectTexture( INTERACTION_TEXUNIT_AMBIENT_CUBE1 );
globalImages->defaultUACIrradianceCube->Bind();
GL_SelectTexture( INTERACTION_TEXUNIT_SPECULAR_CUBE1 );
globalImages->defaultUACRadianceCube->Bind();
}
else if( setInteractionShader )
{
if( specUsage == TD_SPECULAR_PBR_RMAO || specUsage == TD_SPECULAR_PBR_RMAOD )
{
// PBR path with roughness, metal and AO
// select the render prog
// bump matrix
SetVertexParm( RENDERPARM_BUMPMATRIX_S, din->bumpMatrix[0].ToFloatPtr() );
SetVertexParm( RENDERPARM_BUMPMATRIX_T, din->bumpMatrix[1].ToFloatPtr() );
if( din->vLight->lightShader->IsAmbientLight() )
{
if( din->surf->jointCache )
{
renderProgManager.BindShader_PBR_InteractionAmbientSkinned();
}
else
{
renderProgManager.BindShader_PBR_InteractionAmbient();
}
}
else
{
if( r_useShadowMapping.GetBool() && din->vLight->globalShadows )
{
// RB: we have shadow mapping enabled and shadow maps so do a shadow compare
// diffuse matrix
SetVertexParm( RENDERPARM_DIFFUSEMATRIX_S, din->diffuseMatrix[0].ToFloatPtr() );
SetVertexParm( RENDERPARM_DIFFUSEMATRIX_T, din->diffuseMatrix[1].ToFloatPtr() );
if( din->vLight->parallel )
{
if( din->surf->jointCache )
{
renderProgManager.BindShader_PBR_Interaction_ShadowMapping_Parallel_Skinned();
}
else
{
renderProgManager.BindShader_PBR_Interaction_ShadowMapping_Parallel();
}
}
else if( din->vLight->pointLight )
{
if( din->surf->jointCache )
{
renderProgManager.BindShader_PBR_Interaction_ShadowMapping_Point_Skinned();
}
else
{
renderProgManager.BindShader_PBR_Interaction_ShadowMapping_Point();
}
}
else
{
if( din->surf->jointCache )
{
renderProgManager.BindShader_PBR_Interaction_ShadowMapping_Spot_Skinned();
}
else
{
renderProgManager.BindShader_PBR_Interaction_ShadowMapping_Spot();
}
}
}
else
{
if( din->surf->jointCache )
{
renderProgManager.BindShader_PBR_InteractionSkinned();
}
else
{
renderProgManager.BindShader_PBR_Interaction();
}
}
}
}
else
{
// only oldschool D3 gloss maps provided
// specular matrix
SetVertexParm( RENDERPARM_SPECULARMATRIX_S, din->specularMatrix[0].ToFloatPtr() );
SetVertexParm( RENDERPARM_SPECULARMATRIX_T, din->specularMatrix[1].ToFloatPtr() );
if( din->vLight->lightShader->IsAmbientLight() )
{
if( din->surf->jointCache )
{
renderProgManager.BindShader_InteractionAmbientSkinned();
}
else
{
renderProgManager.BindShader_InteractionAmbient();
}
}
else
{
if( r_useShadowMapping.GetBool() && din->vLight->globalShadows )
{
// RB: we have shadow mapping enabled and shadow maps so do a shadow compare
RB_SetVertexColorParms( din->vertexColor );
SetFragmentParm( RENDERPARM_DIFFUSEMODIFIER, din->diffuseColor.ToFloatPtr() );
SetFragmentParm( RENDERPARM_SPECULARMODIFIER, din->specularColor.ToFloatPtr() );
if( din->vLight->parallel )
{
if( din->surf->jointCache )
{
renderProgManager.BindShader_Interaction_ShadowMapping_Parallel_Skinned();
}
else
{
renderProgManager.BindShader_Interaction_ShadowMapping_Parallel();
}
}
else if( din->vLight->pointLight )
{
if( din->surf->jointCache )
{
renderProgManager.BindShader_Interaction_ShadowMapping_Point_Skinned();
}
else
{
renderProgManager.BindShader_Interaction_ShadowMapping_Point();
}
}
else
{
if( din->surf->jointCache )
{
renderProgManager.BindShader_Interaction_ShadowMapping_Spot_Skinned();
}
else
{
renderProgManager.BindShader_Interaction_ShadowMapping_Spot();
}
}
}
else
{
if( din->surf->jointCache )
{
renderProgManager.BindShader_InteractionSkinned();
}
else
{
renderProgManager.BindShader_Interaction();
}
}
}
}
}
// RB end
// texture 0 will be the per-surface bump map
GL_SelectTexture( INTERACTION_TEXUNIT_BUMP );
@ -1450,7 +1601,7 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view
const float* lightRegs = vLight->shaderRegisters;
drawInteraction_t inter = {};
inter.ambientLight = lightShader->IsAmbientLight();
inter.vLight = vLight;
//---------------------------------
// Split out the complex surfaces from the fast-path surfaces
@ -1625,71 +1776,6 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view
{
const drawSurf_t* const surf = allSurfaces[ sortedSurfNum ];
// select the render prog
if( lightShader->IsAmbientLight() )
{
if( surf->jointCache )
{
renderProgManager.BindShader_InteractionAmbientSkinned();
}
else
{
renderProgManager.BindShader_InteractionAmbient();
}
}
else
{
if( r_useShadowMapping.GetBool() && vLight->globalShadows )
{
// RB: we have shadow mapping enabled and shadow maps so do a shadow compare
if( vLight->parallel )
{
if( surf->jointCache )
{
renderProgManager.BindShader_Interaction_ShadowMapping_Parallel_Skinned();
}
else
{
renderProgManager.BindShader_Interaction_ShadowMapping_Parallel();
}
}
else if( vLight->pointLight )
{
if( surf->jointCache )
{
renderProgManager.BindShader_Interaction_ShadowMapping_Point_Skinned();
}
else
{
renderProgManager.BindShader_Interaction_ShadowMapping_Point();
}
}
else
{
if( surf->jointCache )
{
renderProgManager.BindShader_Interaction_ShadowMapping_Spot_Skinned();
}
else
{
renderProgManager.BindShader_Interaction_ShadowMapping_Spot();
}
}
}
else
{
if( surf->jointCache )
{
renderProgManager.BindShader_InteractionSkinned();
}
else
{
renderProgManager.BindShader_Interaction();
}
}
}
const idMaterial* surfaceShader = surf->material;
const float* surfaceRegs = surf->shaderRegisters;
@ -1825,19 +1911,11 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view
{
renderLog.OpenBlock( surf->material->GetName() );
// texture 0 will be the per-surface bump map
GL_SelectTexture( INTERACTION_TEXUNIT_BUMP );
surfaceShader->GetFastPathBumpImage()->Bind();
inter.bumpImage = surfaceShader->GetFastPathBumpImage();
inter.specularImage = surfaceShader->GetFastPathSpecularImage();
inter.diffuseImage = surfaceShader->GetFastPathDiffuseImage();
// texture 1 is the per-surface specular map
GL_SelectTexture( INTERACTION_TEXUNIT_SPECULARMIX );
surfaceShader->GetFastPathSpecularImage()->Bind();
// texture 2 is the per-surface diffuse map
GL_SelectTexture( INTERACTION_TEXUNIT_BASECOLOR );
surfaceShader->GetFastPathDiffuseImage()->Bind();
DrawElementsWithCounters( surf );
DrawSingleInteraction( &inter, true, false, true );
renderLog.CloseBlock();
continue;
@ -1885,7 +1963,7 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view
// draw any previous interaction
if( inter.bumpImage != NULL )
{
DrawSingleInteraction( &inter, false );
DrawSingleInteraction( &inter, false, false, true );
}
inter.bumpImage = surfaceStage->texture.image;
inter.diffuseImage = NULL;
@ -1903,7 +1981,7 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view
// draw any previous interaction
if( inter.diffuseImage != NULL )
{
DrawSingleInteraction( &inter, false );
DrawSingleInteraction( &inter, false, false, true );
}
inter.diffuseImage = surfaceStage->texture.image;
inter.vertexColor = surfaceStage->vertexColor;
@ -1921,7 +1999,7 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view
// draw any previous interaction
if( inter.specularImage != NULL )
{
DrawSingleInteraction( &inter, false );
DrawSingleInteraction( &inter, false, false, true );
}
inter.specularImage = surfaceStage->texture.image;
inter.vertexColor = surfaceStage->vertexColor;
@ -1933,7 +2011,7 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view
}
// draw the final interaction
DrawSingleInteraction( &inter, false );
DrawSingleInteraction( &inter, false, false, true );
renderLog.CloseBlock();
}
@ -2118,9 +2196,11 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
else
#endif
{
#if 0
if( useIBL )
{
// draw Quake 4 style ambient
/*
if( drawSurf->jointCache )
{
renderProgManager.BindShader_ImageBasedLightingSkinned();
@ -2129,6 +2209,7 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
{
renderProgManager.BindShader_ImageBasedLighting();
}
*/
GL_SelectTexture( INTERACTION_TEXUNIT_AMBIENT_CUBE1 );
globalImages->defaultUACIrradianceCube->Bind();
@ -2137,7 +2218,10 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
globalImages->defaultUACRadianceCube->Bind();
}
else
#endif
{
// TODO support PBR textures
// draw Quake 4 style ambient
if( drawSurf->jointCache )
{
@ -2240,24 +2324,22 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
}
*/
drawInteraction_t inter = {};
inter.surf = drawSurf;
inter.diffuseColor[0] = inter.diffuseColor[1] = inter.diffuseColor[2] = inter.diffuseColor[3] = 1;
inter.specularColor[0] = inter.specularColor[1] = inter.specularColor[2] = inter.specularColor[3] = 0;
// check for the fast path
if( surfaceMaterial->GetFastPathBumpImage() && !r_skipInteractionFastPath.GetBool() )
{
renderLog.OpenBlock( surfaceMaterial->GetName() );
// texture 0 will be the per-surface bump map
GL_SelectTexture( INTERACTION_TEXUNIT_BUMP );
surfaceMaterial->GetFastPathBumpImage()->Bind();
inter.bumpImage = surfaceMaterial->GetFastPathBumpImage();
inter.specularImage = surfaceMaterial->GetFastPathSpecularImage();
inter.diffuseImage = surfaceMaterial->GetFastPathDiffuseImage();
// texture 1 is the per-surface specular map
GL_SelectTexture( INTERACTION_TEXUNIT_SPECULARMIX );
surfaceMaterial->GetFastPathSpecularImage()->Bind();
// texture 2 is the per-surface diffuse map
GL_SelectTexture( INTERACTION_TEXUNIT_BASECOLOR );
surfaceMaterial->GetFastPathDiffuseImage()->Bind();
DrawElementsWithCounters( drawSurf );
DrawSingleInteraction( &inter, true, useIBL, false );
renderLog.CloseBlock();
continue;
@ -2267,21 +2349,15 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
//bool drawSolid = false;
inter.bumpImage = NULL;
inter.specularImage = NULL;
inter.diffuseImage = NULL;
// we may have multiple alpha tested stages
// if the only alpha tested stages are condition register omitted,
// draw a normal opaque surface
bool didDraw = false;
drawInteraction_t inter = {};
inter.surf = drawSurf;
inter.bumpImage = NULL;
inter.specularImage = NULL;
inter.diffuseImage = NULL;
inter.diffuseColor[0] = inter.diffuseColor[1] = inter.diffuseColor[2] = inter.diffuseColor[3] = 1;
inter.specularColor[0] = inter.specularColor[1] = inter.specularColor[2] = inter.specularColor[3] = 0;
// perforated surfaces may have multiple alpha tested stages
for( stage = 0; stage < surfaceMaterial->GetNumStages(); stage++ )
{
@ -2312,7 +2388,7 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
// draw any previous interaction
if( inter.bumpImage != NULL )
{
DrawSingleInteraction( &inter, useIBL );
DrawSingleInteraction( &inter, false, useIBL, false );
}
inter.bumpImage = surfaceStage->texture.image;
inter.diffuseImage = NULL;
@ -2333,7 +2409,7 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
// draw any previous interaction
if( inter.diffuseImage != NULL )
{
DrawSingleInteraction( &inter, useIBL );
DrawSingleInteraction( &inter, false, useIBL, false );
}
inter.diffuseImage = surfaceStage->texture.image;
@ -2353,7 +2429,7 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
// draw any previous interaction
if( inter.specularImage != NULL )
{
DrawSingleInteraction( &inter, useIBL );
DrawSingleInteraction( &inter, false, useIBL, false );
}
inter.specularImage = surfaceStage->texture.image;
inter.vertexColor = surfaceStage->vertexColor;
@ -2365,7 +2441,7 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
}
// draw the final interaction
DrawSingleInteraction( &inter, useIBL );
DrawSingleInteraction( &inter, false, useIBL, false );
renderLog.CloseBlock();
}
@ -3355,7 +3431,6 @@ void idRenderBackend::DrawInteractions( const viewDef_t* _viewDef )
GL_SelectTexture( 0 );
const bool useLightDepthBounds = r_useLightDepthBounds.GetBool() && !r_useShadowMapping.GetBool();
//

View file

@ -287,7 +287,7 @@ private:
idVec4 matrix[2], float color[4] );
void DrawInteractions( const viewDef_t* _viewDef );
void DrawSingleInteraction( drawInteraction_t* din, bool useIBL );
void DrawSingleInteraction( drawInteraction_t* din, bool useFastPath, bool useIBL, bool setInteractionShader );
int DrawShaderPasses( const drawSurf_t* const* const drawSurfs, const int numDrawSurfs,
const float guiStereoScreenOffset, const int stereoEye );

View file

@ -552,6 +552,8 @@ struct viewDef_t
// simple interaction shader
struct drawInteraction_t
{
const viewLight_t* vLight;
const drawSurf_t* surf;
idImage* bumpImage;
@ -562,8 +564,6 @@ struct drawInteraction_t
idVec4 specularColor; // may have a light color baked into it
stageVertexColor_t vertexColor; // applies to both diffuse and specular
int ambientLight; // use tr.ambientNormalMap instead of normalization cube map
// these are loaded into the vertex program
idVec4 bumpMatrix[2];
idVec4 diffuseMatrix[2];
@ -1091,6 +1091,7 @@ extern idCVar r_ssaoFiltering;
extern idCVar r_useHierarchicalDepthBuffer;
extern idCVar r_useIBL;
extern idCVar r_pbrDebug;
extern idCVar r_exposure;
// RB end

View file

@ -121,18 +121,40 @@ void idRenderProgManager::Init()
{ BUILTIN_TEXTURE_VERTEXCOLOR_SRGB, "texture_color.vfp", "", BIT( USE_SRGB ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_TEXTURE_VERTEXCOLOR_SKINNED, "texture_color_skinned.vfp", "", 0, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_TEXTURE_TEXGEN_VERTEXCOLOR, "texture_color_texgen.vfp", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
// RB begin
{ BUILTIN_INTERACTION, "interaction.vfp", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION, "interaction", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_SKINNED, "interaction", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_AMBIENT, "interactionAmbient.vfp", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_AMBIENT_SKINNED, "interactionAmbient_skinned.vfp", "", 0, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT, "interactionSM", "_spot", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED, "interactionSM", "_spot_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_POINT, "interactionSM", "_point", BIT( LIGHT_POINT ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_POINT_SKINNED, "interactionSM", "_point_skinned", BIT( USE_GPU_SKINNING ) | BIT( LIGHT_POINT ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL, "interactionSM", "_parallel", BIT( LIGHT_PARALLEL ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED, "interactionSM", "_parallel_skinned", BIT( USE_GPU_SKINNING ) | BIT( LIGHT_PARALLEL ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
// PBR variants
{ BUILTIN_PBR_INTERACTION, "interaction", "_PBR", BIT( USE_PBR ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_SKINNED, "interaction", "_skinned_PBR", BIT( USE_GPU_SKINNING ) | BIT( USE_PBR ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_AMBIENT, "interactionAmbient", "_PBR", BIT( USE_PBR ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_AMBIENT_SKINNED, "interactionAmbient_skinned", "_PBR", BIT( USE_PBR ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_SPOT, "interactionSM", "_spot_PBR", BIT( USE_PBR ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED, "interactionSM", "_spot_skinned_PBR", BIT( USE_GPU_SKINNING ) | BIT( USE_PBR ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_POINT, "interactionSM", "_point_PBR", BIT( LIGHT_POINT ) | BIT( USE_PBR ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_POINT_SKINNED, "interactionSM", "_point_skinned_PBR", BIT( USE_GPU_SKINNING ) | BIT( LIGHT_POINT ) | BIT( USE_PBR ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL, "interactionSM", "_parallel_PBR", BIT( LIGHT_PARALLEL ) | BIT( USE_PBR ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED, "interactionSM", "_parallel_skinned_PBR", BIT( USE_GPU_SKINNING ) | BIT( LIGHT_PARALLEL ) | BIT( USE_PBR ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
// RB end
{ BUILTIN_ENVIRONMENT, "environment.vfp", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_ENVIRONMENT_SKINNED, "environment_skinned.vfp", "", 0, true , SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT},
{ BUILTIN_BUMPY_ENVIRONMENT, "bumpyenvironment.vfp", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },

View file

@ -396,6 +396,59 @@ public:
{
BindShader_Builtin( BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED );
}
// PBR variantes
void BindShader_PBR_Interaction()
{
BindShader_Builtin( BUILTIN_PBR_INTERACTION );
}
void BindShader_PBR_InteractionSkinned()
{
BindShader_Builtin( BUILTIN_PBR_INTERACTION_SKINNED );
}
void BindShader_PBR_InteractionAmbient()
{
BindShader_Builtin( BUILTIN_PBR_INTERACTION_AMBIENT );
}
void BindShader_PBR_InteractionAmbientSkinned()
{
BindShader_Builtin( BUILTIN_PBR_INTERACTION_AMBIENT_SKINNED );
}
// RB begin
void BindShader_PBR_Interaction_ShadowMapping_Spot()
{
BindShader_Builtin( BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_SPOT );
}
void BindShader_PBR_Interaction_ShadowMapping_Spot_Skinned()
{
BindShader_Builtin( BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED );
}
void BindShader_PBR_Interaction_ShadowMapping_Point()
{
BindShader_Builtin( BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_POINT );
}
void BindShader_PBR_Interaction_ShadowMapping_Point_Skinned()
{
BindShader_Builtin( BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_POINT_SKINNED );
}
void BindShader_PBR_Interaction_ShadowMapping_Parallel()
{
BindShader_Builtin( BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL );
}
void BindShader_PBR_Interaction_ShadowMapping_Parallel_Skinned()
{
BindShader_Builtin( BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED );
}
// RB end
void BindShader_Environment()
@ -690,6 +743,18 @@ private:
BUILTIN_INTERACTION_SHADOW_MAPPING_POINT_SKINNED,
BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL,
BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED,
BUILTIN_PBR_INTERACTION,
BUILTIN_PBR_INTERACTION_SKINNED,
BUILTIN_PBR_INTERACTION_AMBIENT,
BUILTIN_PBR_INTERACTION_AMBIENT_SKINNED,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_SPOT,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_POINT,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_POINT_SKINNED,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED,
// RB end
BUILTIN_ENVIRONMENT,
BUILTIN_ENVIRONMENT_SKINNED,

View file

@ -511,6 +511,11 @@ idStr idRenderProgManager::StripDeadCode( const idStr& in, const char* name, con
src.AddDefine( "USE_LINEAR_RGB" );
}
if( r_pbrDebug.GetBool() )
{
src.AddDefine( "DEBUG_PBR" );
}
// SMAA configuration
src.AddDefine( "SMAA_GLSL_3" );
src.AddDefine( "SMAA_RT_METRICS rpScreenCorrectionFactor " );

View file

@ -2249,7 +2249,8 @@ static const cgShaderDef_t cg_renderprogs[] =
" half4 color : COLOR;\n"
"};\n"
"\n"
"void main( PS_IN fragment, out PS_OUT result ) {\n"
"void main( PS_IN fragment, out PS_OUT result )\n"
"{\n"
" half4 bumpMap = tex2D( samp0, fragment.texcoord0.xy );\n"
"// half4 lightFalloff = idtex2Dproj( samp1, fragment.texcoord2 );\n"
"// half4 lightProj = idtex2Dproj( samp2, fragment.texcoord3 );\n"
@ -2294,9 +2295,8 @@ static const cgShaderDef_t cg_renderprogs[] =
" float3 reflectionVector = globalNormal * dot3( globalEye, globalNormal );\n"
" reflectionVector = ( reflectionVector * 2.0f ) - globalEye;\n"
" \n"
"#if 1 //defined(USE_PBR)\n"
" \n"
"#if 1 //defined(USE_METALNESS)\n"
"\n"
"#if defined( USE_PBR )\n"
" const half metallic = specMapSRGB.g;\n"
" const half roughness = specMapSRGB.r;\n"
" const half glossiness = 1.0 - roughness;\n"
@ -2312,6 +2312,12 @@ static const cgShaderDef_t cg_renderprogs[] =
" \n"
" half3 diffuseColor = baseColor * ( 1.0 - metallic );\n"
" half3 specularColor = lerp( dielectricColor, baseColor, metallic );\n"
"\n"
"#if defined( DEBUG_PBR )\n"
" diffuseColor = half3( 0.0, 0.0, 0.0 );\n"
" specularColor = half3( 0.0, 1.0, 0.0 );\n"
"#endif\n"
"\n"
"#else\n"
" // HACK calculate roughness from D3 gloss maps\n"
" float Y = dot( LUMINANCE_SRGB.rgb, specMapSRGB.rgb );\n"
@ -2324,6 +2330,11 @@ static const cgShaderDef_t cg_renderprogs[] =
" half3 diffuseColor = diffuseMap;\n"
" half3 specularColor = specMap.rgb;\n"
"\n"
"#if defined( DEBUG_PBR )\n"
" diffuseColor = half3( 0.0, 0.0, 0.0 );\n"
" specularColor = half3( 1.0, 0.0, 0.0 );\n"
"#endif\n"
"\n"
"#endif\n"
" \n"
" float3 diffuseLight = ( texCUBE( samp7, globalNormal ).rgb ) * diffuseColor * ( rpDiffuseModifier.xyz ) * 3.5f;\n"
@ -2333,27 +2344,6 @@ static const cgShaderDef_t cg_renderprogs[] =
" \n"
" float3 specularLight = envColor * specularColor;\n"
" \n"
"#else\n"
" \n"
" // non PBR path\n"
"\n"
" float3 diffuseLight = ( texCUBE( samp7, globalNormal ).rgb ) * diffuseMap.rgb * ( rpDiffuseModifier.xyz ) * 3.5f;\n"
" //float3 diffuseLight = diffuseMap.rgb * ( rpDiffuseModifier.xyz ) * 1.5f;\n"
"\n"
" // HACK calculate roughness from D3 gloss maps\n"
" float Y = dot( LUMINANCE_SRGB.rgb, specMapSRGB.rgb );\n"
" \n"
" //const float glossiness = clamp( 1.0 - specMapSRGB.r, 0.0, 0.98 );\n"
" const float glossiness = clamp( pow( Y, 1.0 / 2.0 ), 0.0, 0.98 );\n"
" \n"
" const float roughness = 1.0 - glossiness;\n"
" \n"
" float mip = clamp( ( roughness * 7.0 ) + 0.0, 0.0, 10.0 );\n"
" float3 envColor = ( textureLod( samp8, reflectionVector, mip ).rgb ) * ( rpSpecularModifier.xyz ) * 0.5f;\n"
" \n"
" float3 specularLight = envColor * specMap.rgb;\n"
" \n"
"#endif\n"
"\n"
" // add glossy fresnel\n"
" half hDotN = saturate( dot3( globalEye, globalNormal ) );\n"
@ -8577,7 +8567,7 @@ static const cgShaderDef_t cg_renderprogs[] =
"\n"
"Doom 3 BFG Edition GPL Source Code\n"
"Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. \n"
"Copyright (C) 2013-2014 Robert Beckebans\n"
"Copyright (C) 2013-2020 Robert Beckebans\n"
"\n"
"This file is part of the Doom 3 BFG Edition GPL Source Code (\"Doom 3 BFG Edition Source Code\"). \n"
"\n"
@ -8604,23 +8594,23 @@ static const cgShaderDef_t cg_renderprogs[] =
"#include \"global.inc.hlsl\"\n"
"#include \"BRDF.inc.hlsl\"\n"
"\n"
"uniform sampler2D samp0 : register(s0); // texture 1 is the per-surface normal map\n"
"uniform sampler2D samp1 : register(s1); // texture 3 is the per-surface specular or roughness/metallic/AO mixer map\n"
"uniform sampler2D samp2 : register(s2); // texture 2 is the per-surface baseColor map \n"
"uniform sampler2D samp3 : register(s3); // texture 4 is the light falloff texture\n"
"uniform sampler2D samp4 : register(s4); // texture 5 is the light projection texture\n"
"uniform sampler2D samp0 : register(s0); // texture 1 is the per-surface normal map\n"
"uniform sampler2D samp1 : register(s1); // texture 3 is the per-surface specular or roughness/metallic/AO mixer map\n"
"uniform sampler2D samp2 : register(s2); // texture 2 is the per-surface baseColor map \n"
"uniform sampler2D samp3 : register(s3); // texture 4 is the light falloff texture\n"
"uniform sampler2D samp4 : register(s4); // texture 5 is the light projection texture\n"
"\n"
"struct PS_IN\n"
"{\n"
" half4 position : VPOS;\n"
" half4 texcoord0 : TEXCOORD0_centroid;\n"
" half4 texcoord1 : TEXCOORD1_centroid;\n"
" half4 texcoord2 : TEXCOORD2_centroid;\n"
" half4 texcoord3 : TEXCOORD3_centroid;\n"
" half4 texcoord4 : TEXCOORD4_centroid;\n"
" half4 texcoord5 : TEXCOORD5_centroid;\n"
" half4 texcoord6 : TEXCOORD6_centroid;\n"
" half4 color : COLOR0;\n"
" half4 position : VPOS;\n"
" half4 texcoord0 : TEXCOORD0_centroid;\n"
" half4 texcoord1 : TEXCOORD1_centroid;\n"
" half4 texcoord2 : TEXCOORD2_centroid;\n"
" half4 texcoord3 : TEXCOORD3_centroid;\n"
" half4 texcoord4 : TEXCOORD4_centroid;\n"
" half4 texcoord5 : TEXCOORD5_centroid;\n"
" half4 texcoord6 : TEXCOORD6_centroid;\n"
" half4 color : COLOR0;\n"
"};\n"
"\n"
"struct PS_OUT\n"
@ -8670,9 +8660,9 @@ static const cgShaderDef_t cg_renderprogs[] =
" half3 halfAngleVector = normalize( lightVector + viewVector );\n"
" half hdotN = clamp( dot3( halfAngleVector, localNormal ), 0.0, 1.0 );\n"
"\n"
"#if 1 //defined(USE_PBR)\n"
"#if 1\n"
" \n"
"#if 1 //defined(USE_METALNESS)\n"
"#if defined( USE_PBR )\n"
" const half metallic = specMapSRGB.g;\n"
" const half roughness = specMapSRGB.r;\n"
" const half glossiness = 1.0 - roughness;\n"
@ -9509,16 +9499,14 @@ static const cgShaderDef_t cg_renderprogs[] =
"#include \"global.inc.hlsl\"\n"
"#include \"BRDF.inc.hlsl\"\n"
"\n"
"uniform sampler2D samp0 : register(s0); // texture 1 is the per-surface normal map\n"
"uniform sampler2D samp1 : register(s1); // texture 3 is the per-surface specular or roughness/metallic/AO mixer map\n"
"uniform sampler2D samp2 : register(s2); // texture 2 is the per-surface baseColor map \n"
"uniform sampler2D samp3 : register(s3); // texture 4 is the light falloff texture\n"
"uniform sampler2D samp4 : register(s4); // texture 5 is the light projection texture\n"
"uniform sampler2D samp0 : register(s0); // texture 1 is the per-surface normal map\n"
"uniform sampler2D samp1 : register(s1); // texture 3 is the per-surface specular or roughness/metallic/AO mixer map\n"
"uniform sampler2D samp2 : register(s2); // texture 2 is the per-surface baseColor map \n"
"uniform sampler2D samp3 : register(s3); // texture 4 is the light falloff texture\n"
"uniform sampler2D samp4 : register(s4); // texture 5 is the light projection texture\n"
"uniform sampler2DArrayShadow samp5 : register(s5); // texture 6 is the shadowmap array\n"
"uniform sampler2D samp6 : register(s6); // texture 7 is the jitter texture \n"
"\n"
"\n"
"\n"
"struct PS_IN\n"
"{\n"
" half4 position : VPOS;\n"
@ -9757,9 +9745,9 @@ static const cgShaderDef_t cg_renderprogs[] =
" half3 halfAngleVector = normalize( lightVector + viewVector );\n"
" half hdotN = clamp( dot3( halfAngleVector, localNormal ), 0.0, 1.0 );\n"
"\n"
"#if 1 //defined(USE_PBR)\n"
"#if 1\n"
" \n"
"#if 1 //defined(USE_METALNESS)\n"
"#if defined( USE_PBR )\n"
" const half metallic = specMapSRGB.g;\n"
" const half roughness = specMapSRGB.r;\n"
" const half glossiness = 1.0 - roughness;\n"

View file

@ -266,7 +266,7 @@ idCVar r_shadowMapSunDepthBiasScale( "r_shadowMapSunDepthBiasScale", "0.999991",
idCVar r_useHDR( "r_useHDR", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "use high dynamic range rendering" );
#endif
idCVar r_hdrAutoExposure( "r_hdrAutoExposure", "1", CVAR_RENDERER | CVAR_BOOL, "EXPENSIVE: enables adapative HDR tone mapping otherwise the exposure is derived by r_exposure" );
idCVar r_hdrAutoExposure( "r_hdrAutoExposure", "0", CVAR_RENDERER | CVAR_BOOL, "EXPENSIVE: enables adapative HDR tone mapping otherwise the exposure is derived by r_exposure" );
idCVar r_hdrMinLuminance( "r_hdrMinLuminance", "0.005", CVAR_RENDERER | CVAR_FLOAT, "" );
idCVar r_hdrMaxLuminance( "r_hdrMaxLuminance", "300", CVAR_RENDERER | CVAR_FLOAT, "" );
idCVar r_hdrKey( "r_hdrKey", "0.015", CVAR_RENDERER | CVAR_FLOAT, "magic exposure key that works well with Doom 3 maps" );
@ -297,6 +297,7 @@ idCVar r_ssaoFiltering( "r_ssaoFiltering", "1", CVAR_RENDERER | CVAR_BOOL, "" );
idCVar r_useHierarchicalDepthBuffer( "r_useHierarchicalDepthBuffer", "1", CVAR_RENDERER | CVAR_BOOL, "" );
idCVar r_useIBL( "r_useIBL", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "use Image Based Lighting for ambient lighting (PBR)" );
idCVar r_pbrDebug( "r_pbrDebug", "0", CVAR_RENDERER | CVAR_INTEGER, "show which materials have PBR support (green = PBR, red = oldschool D3), requires reloadShaders" );
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