mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-14 22:50:45 +00:00
Combined lightgrid trilerp with IBL PBR lighting
This commit is contained in:
parent
884658d6dd
commit
0596300c45
10 changed files with 1397 additions and 3 deletions
|
@ -42,6 +42,8 @@ return
|
|||
"builtin/lighting/ambient_lighting.vs.hlsl",
|
||||
"builtin/lighting/ambient_lighting_IBL.ps.hlsl",
|
||||
"builtin/lighting/ambient_lighting_IBL.vs.hlsl",
|
||||
"builtin/lighting/ambient_lightgrid_IBL.ps.hlsl",
|
||||
"builtin/lighting/ambient_lightgrid_IBL.vs.hlsl",
|
||||
"builtin/lighting/interaction.ps.hlsl",
|
||||
"builtin/lighting/interaction.vs.hlsl",
|
||||
"builtin/lighting/interactionAmbient.ps.hlsl",
|
||||
|
|
414
base/renderprogs/builtin/lighting/ambient_lightgrid_IBL.ps.hlsl
Normal file
414
base/renderprogs/builtin/lighting/ambient_lightgrid_IBL.ps.hlsl
Normal file
|
@ -0,0 +1,414 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2013-2021 Robert Beckebans
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "renderprogs/global.inc.hlsl"
|
||||
|
||||
#include "renderprogs/BRDF.inc.hlsl"
|
||||
|
||||
|
||||
// *INDENT-OFF*
|
||||
uniform sampler2D samp0 : register(s0); // texture 0 is the per-surface normal map
|
||||
uniform sampler2D samp1 : register(s1); // texture 1 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 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
|
||||
|
||||
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 texcoord7 : TEXCOORD7_centroid;
|
||||
half4 color : COLOR0;
|
||||
};
|
||||
|
||||
struct PS_OUT
|
||||
{
|
||||
half4 color : COLOR;
|
||||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
|
||||
float3 lightGridOrigin = float3( -192.0, -128.0, 0 );
|
||||
float3 lightGridSize = float3( 64.0, 64.0, 128.0 );
|
||||
int3 lightGridBounds = int3( 7, 7, 3 );
|
||||
|
||||
int3 GetBaseGridCoord( float3 origin )
|
||||
{
|
||||
int3 pos;
|
||||
|
||||
float3 lightOrigin = origin - lightGridOrigin;
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
float v;
|
||||
|
||||
v = lightOrigin[i] * ( 1.0f / lightGridSize[i] );
|
||||
pos[i] = int( floor( v ) );
|
||||
|
||||
if( pos[i] < 0 )
|
||||
{
|
||||
pos[i] = 0;
|
||||
}
|
||||
else if( pos[i] >= lightGridBounds[i] - 1 )
|
||||
{
|
||||
pos[i] = lightGridBounds[i] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
// RB: TODO OPTIMIZE
|
||||
// this is a straight port of idBounds::RayIntersection
|
||||
bool AABBRayIntersection( float3 b[2], float3 start, float3 dir, out float scale )
|
||||
{
|
||||
int i, ax0, ax1, ax2, side, inside;
|
||||
float f;
|
||||
float3 hit;
|
||||
|
||||
ax0 = -1;
|
||||
inside = 0;
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
if( start[i] < b[0][i] )
|
||||
{
|
||||
side = 0;
|
||||
}
|
||||
else if( start[i] > b[1][i] )
|
||||
{
|
||||
side = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
inside++;
|
||||
continue;
|
||||
}
|
||||
if( dir[i] == 0.0f )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
f = ( start[i] - b[side][i] );
|
||||
|
||||
if( ax0 < 0 || abs( f ) > abs( scale * dir[i] ) )
|
||||
{
|
||||
scale = - ( f / dir[i] );
|
||||
ax0 = i;
|
||||
}
|
||||
}
|
||||
|
||||
if( ax0 < 0 )
|
||||
{
|
||||
scale = 0.0f;
|
||||
|
||||
// return true if the start point is inside the bounds
|
||||
return ( inside == 3 );
|
||||
}
|
||||
|
||||
ax1 = ( ax0 + 1 ) % 3;
|
||||
ax2 = ( ax0 + 2 ) % 3;
|
||||
hit[ax1] = start[ax1] + scale * dir[ax1];
|
||||
hit[ax2] = start[ax2] + scale * dir[ax2];
|
||||
|
||||
return ( hit[ax1] >= b[0][ax1] && hit[ax1] <= b[1][ax1] &&
|
||||
hit[ax2] >= b[0][ax2] && hit[ax2] <= b[1][ax2] );
|
||||
}
|
||||
|
||||
void main( PS_IN fragment, out PS_OUT result )
|
||||
{
|
||||
half4 bumpMap = tex2D( samp0, fragment.texcoord0.xy );
|
||||
half4 YCoCG = tex2D( samp2, fragment.texcoord1.xy );
|
||||
half4 specMapSRGB = tex2D( samp1, fragment.texcoord2.xy );
|
||||
half4 specMap = sRGBAToLinearRGBA( specMapSRGB );
|
||||
|
||||
half3 diffuseMap = sRGBToLinearRGB( ConvertYCoCgToRGB( YCoCG ) );
|
||||
|
||||
half3 localNormal;
|
||||
#if defined(USE_NORMAL_FMT_RGB8)
|
||||
localNormal.xy = bumpMap.rg - 0.5;
|
||||
#else
|
||||
localNormal.xy = bumpMap.wy - 0.5;
|
||||
#endif
|
||||
localNormal.z = sqrt( abs( dot( localNormal.xy, localNormal.xy ) - 0.25 ) );
|
||||
localNormal = normalize( localNormal );
|
||||
|
||||
float3 globalNormal;
|
||||
globalNormal.x = dot3( localNormal, fragment.texcoord4 );
|
||||
globalNormal.y = dot3( localNormal, fragment.texcoord5 );
|
||||
globalNormal.z = dot3( localNormal, fragment.texcoord6 );
|
||||
globalNormal = normalize( globalNormal );
|
||||
|
||||
float3 globalPosition = fragment.texcoord7.xyz;
|
||||
|
||||
// RB: rpGlobalLightOrigin is global view origin
|
||||
float3 globalEye = normalize( rpGlobalLightOrigin.xyz - globalPosition );
|
||||
|
||||
float3 reflectionVector = globalNormal * dot3( globalEye, globalNormal );
|
||||
reflectionVector = normalize( ( reflectionVector * 2.0f ) - globalEye );
|
||||
|
||||
#if 1
|
||||
// parallax box correction using portal area bounds
|
||||
float hitScale;
|
||||
float3 bounds[2];
|
||||
bounds[0].x = rpWobbleSkyX.x;
|
||||
bounds[0].y = rpWobbleSkyX.y;
|
||||
bounds[0].z = rpWobbleSkyX.z;
|
||||
|
||||
bounds[1].x = rpWobbleSkyY.x;
|
||||
bounds[1].y = rpWobbleSkyY.y;
|
||||
bounds[1].z = rpWobbleSkyY.z;
|
||||
|
||||
// global fragment position
|
||||
float3 rayStart = fragment.texcoord7.xyz;
|
||||
|
||||
// we can't start inside the box so move this outside and use the reverse path
|
||||
rayStart += reflectionVector * 10000.0;
|
||||
|
||||
// only do a box <-> ray intersection test if we use a local cubemap
|
||||
if( ( rpWobbleSkyX.w > 0.0 ) && AABBRayIntersection( bounds, rayStart, -reflectionVector, hitScale ) )
|
||||
{
|
||||
float3 hitPoint = rayStart - reflectionVector * hitScale;
|
||||
|
||||
// rpWobbleSkyZ is cubemap center
|
||||
reflectionVector = hitPoint - rpWobbleSkyZ.xyz;
|
||||
}
|
||||
#endif
|
||||
|
||||
half vDotN = saturate( dot3( globalEye, globalNormal ) );
|
||||
|
||||
#if defined( USE_PBR )
|
||||
const half metallic = specMapSRGB.g;
|
||||
const half roughness = specMapSRGB.r;
|
||||
const half glossiness = 1.0 - roughness;
|
||||
|
||||
// the vast majority of real-world materials (anything not metal or gems) have F(0°)
|
||||
// values in a very narrow range (~0.02 - 0.08)
|
||||
|
||||
// approximate non-metals with linear RGB 0.04 which is 0.08 * 0.5 (default in UE4)
|
||||
const half3 dielectricColor = half3( 0.04 );
|
||||
|
||||
// derive diffuse and specular from albedo(m) base color
|
||||
const half3 baseColor = diffuseMap;
|
||||
|
||||
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
|
||||
|
||||
float3 kS = Fresnel_SchlickRoughness( specularColor, vDotN, roughness );
|
||||
float3 kD = ( float3( 1.0, 1.0, 1.0 ) - kS ) * ( 1.0 - metallic );
|
||||
|
||||
#else
|
||||
const float roughness = EstimateLegacyRoughness( specMapSRGB.rgb );
|
||||
|
||||
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
|
||||
|
||||
float3 kS = Fresnel_SchlickRoughness( specularColor, vDotN, roughness );
|
||||
|
||||
// NOTE: metalness is missing
|
||||
float3 kD = ( float3( 1.0, 1.0, 1.0 ) - kS );
|
||||
|
||||
#endif
|
||||
|
||||
//diffuseColor = half3( 1.0, 1.0, 1.0 );
|
||||
//diffuseColor = half3( 0.0, 0.0, 0.0 );
|
||||
|
||||
// calculate the screen texcoord in the 0.0 to 1.0 range
|
||||
//float2 screenTexCoord = vposToScreenPosTexCoord( fragment.position.xy );
|
||||
float2 screenTexCoord = fragment.position.xy * rpWindowCoord.xy;
|
||||
|
||||
float ao = 1.0;
|
||||
ao = tex2D( samp4, screenTexCoord ).r;
|
||||
//diffuseColor.rgb *= ao;
|
||||
|
||||
// evaluate diffuse IBL
|
||||
|
||||
float2 normalizedOctCoord = octEncode( globalNormal );
|
||||
float2 normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5;
|
||||
|
||||
// lightgrid atlas
|
||||
float invXY = ( 1.0 / ( lightGridBounds[0] * lightGridBounds[1] ) );
|
||||
float invZ = ( 1.0 / lightGridBounds[2] );
|
||||
|
||||
normalizedOctCoordZeroOne.x *= invXY;
|
||||
normalizedOctCoordZeroOne.y *= invZ;
|
||||
|
||||
int3 gridCoord;
|
||||
float3 frac;
|
||||
float3 lightOrigin = globalPosition - lightGridOrigin;
|
||||
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
float v;
|
||||
|
||||
v = lightOrigin[i] * ( 1.0f / lightGridSize[i] );
|
||||
gridCoord[i] = int( floor( v ) );
|
||||
frac[ i ] = v - gridCoord[ i ];
|
||||
|
||||
if( gridCoord[i] < 0 )
|
||||
{
|
||||
gridCoord[i] = 0;
|
||||
}
|
||||
else if( gridCoord[i] >= lightGridBounds[i] - 1 )
|
||||
{
|
||||
gridCoord[i] = lightGridBounds[i] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// trilerp the light value
|
||||
int3 gridStep;
|
||||
|
||||
gridStep[0] = 1;
|
||||
gridStep[1] = lightGridBounds[0];
|
||||
gridStep[2] = lightGridBounds[0] * lightGridBounds[1];
|
||||
|
||||
float totalFactor = 0.0;
|
||||
float3 irradiance;
|
||||
|
||||
/*
|
||||
for( int i = 0; i < 8; i++ )
|
||||
{
|
||||
for( int j = 0; j < 3; j++ )
|
||||
{
|
||||
if( i & ( 1 << j ) )
|
||||
|
||||
results in these offsets
|
||||
*/
|
||||
const float3 cornerOffsets[8] = float3[](
|
||||
float3( 0.0, 0.0, 0.0 ),
|
||||
float3( 1.0, 0.0, 0.0 ),
|
||||
float3( 0.0, 2.0, 0.0 ),
|
||||
float3( 1.0, 2.0, 0.0 ),
|
||||
float3( 0.0, 0.0, 4.0 ),
|
||||
float3( 1.0, 0.0, 4.0 ),
|
||||
float3( 0.0, 2.0, 4.0 ),
|
||||
float3( 1.0, 2.0, 4.0 ) );
|
||||
|
||||
for( int i = 0; i < 8; i++ )
|
||||
{
|
||||
float factor = 1.0;
|
||||
|
||||
int3 gridCoord2 = gridCoord;
|
||||
|
||||
for( int j = 0; j < 3; j++ )
|
||||
{
|
||||
if( cornerOffsets[ i ][ j ] > 0.0f )
|
||||
{
|
||||
factor *= frac[ j ];
|
||||
|
||||
gridCoord2[ j ] += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
factor *= ( 1.0f - frac[ j ] );
|
||||
}
|
||||
}
|
||||
|
||||
float2 atlasOffset;
|
||||
|
||||
atlasOffset.x = ( gridCoord2[0] * gridStep[0] + gridCoord2[1] * gridStep[1] ) * invXY;
|
||||
atlasOffset.y = ( gridCoord2[2] * invZ );
|
||||
|
||||
irradiance += tex2D( samp7, normalizedOctCoordZeroOne + atlasOffset ).rgb * factor;
|
||||
|
||||
totalFactor += factor;
|
||||
}
|
||||
|
||||
if( totalFactor > 0 && totalFactor < 0.99 )
|
||||
{
|
||||
totalFactor = 1.0f / totalFactor;
|
||||
|
||||
irradiance *= totalFactor;
|
||||
}
|
||||
|
||||
// lightgrid atlas
|
||||
|
||||
|
||||
float3 diffuseLight = ( kD * irradiance * diffuseColor ) * ao * ( rpDiffuseModifier.xyz * 1.0 );
|
||||
|
||||
// evaluate specular IBL
|
||||
|
||||
// should be 8 = numMips - 1, 256^2 = 9 mips
|
||||
const float MAX_REFLECTION_LOD = 10.0;
|
||||
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;
|
||||
|
||||
float3 radiance = textureLod( samp8, normalizedOctCoordZeroOne, mip ).rgb;
|
||||
//radiance = float3( 0.0 );
|
||||
|
||||
float2 envBRDF = texture( samp3, float2( max( vDotN, 0.0 ), roughness ) ).rg;
|
||||
|
||||
#if 0
|
||||
result.color.rgb = float3( envBRDF.x, envBRDF.y, 0.0 );
|
||||
result.color.w = fragment.color.a;
|
||||
return;
|
||||
#endif
|
||||
|
||||
float specAO = ComputeSpecularAO( vDotN, ao, roughness );
|
||||
float3 specularLight = radiance * ( kS * envBRDF.x + float3( envBRDF.y ) ) * specAO * ( rpSpecularModifier.xyz * 0.5 );
|
||||
|
||||
#if 0
|
||||
// Marmoset Horizon Fade trick
|
||||
const half horizonFade = 1.3;
|
||||
half horiz = saturate( 1.0 + horizonFade * saturate( dot3( reflectionVector, globalNormal ) ) );
|
||||
horiz *= horiz;
|
||||
//horiz = clamp( horiz, 0.0, 1.0 );
|
||||
#endif
|
||||
|
||||
half3 lightColor = sRGBToLinearRGB( rpAmbientColor.rgb );
|
||||
|
||||
//result.color.rgb = diffuseLight;
|
||||
//result.color.rgb = diffuseLight * lightColor;
|
||||
//result.color.rgb = specularLight;
|
||||
result.color.rgb = ( diffuseLight + specularLight ) * lightColor * fragment.color.rgb;
|
||||
//result.color.rgb = localNormal.xyz * 0.5 + 0.5;
|
||||
//result.color.rgb = float3( ao );
|
||||
result.color.w = fragment.color.a;
|
||||
}
|
200
base/renderprogs/builtin/lighting/ambient_lightgrid_IBL.vs.hlsl
Normal file
200
base/renderprogs/builtin/lighting/ambient_lightgrid_IBL.vs.hlsl
Normal file
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2013-2015 Robert Beckebans
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "renderprogs/global.inc.hlsl"
|
||||
|
||||
|
||||
#if defined( USE_GPU_SKINNING )
|
||||
uniform matrices_ubo { float4 matrices[408]; };
|
||||
#endif
|
||||
|
||||
// *INDENT-OFF*
|
||||
struct VS_IN {
|
||||
float4 position : POSITION;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float4 normal : NORMAL;
|
||||
float4 tangent : TANGENT;
|
||||
float4 color : COLOR0;
|
||||
float4 color2 : COLOR1;
|
||||
};
|
||||
|
||||
struct VS_OUT {
|
||||
float4 position : POSITION;
|
||||
float4 texcoord0 : TEXCOORD0;
|
||||
float4 texcoord1 : TEXCOORD1;
|
||||
float4 texcoord2 : TEXCOORD2;
|
||||
float4 texcoord3 : TEXCOORD3;
|
||||
float4 texcoord4 : TEXCOORD4;
|
||||
float4 texcoord5 : TEXCOORD5;
|
||||
float4 texcoord6 : TEXCOORD6;
|
||||
float4 texcoord7 : TEXCOORD7;
|
||||
float4 color : COLOR0;
|
||||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
void main( VS_IN vertex, out VS_OUT result )
|
||||
{
|
||||
|
||||
float4 vNormal = vertex.normal * 2.0 - 1.0;
|
||||
float4 vTangent = vertex.tangent * 2.0 - 1.0;
|
||||
float3 vBitangent = cross( vNormal.xyz, vTangent.xyz ) * vTangent.w;
|
||||
|
||||
#if defined( USE_GPU_SKINNING )
|
||||
//--------------------------------------------------------------
|
||||
// GPU transformation of the normal / tangent / bitangent
|
||||
//
|
||||
// multiplying with 255.1 give us the same result and is faster than floor( w * 255 + 0.5 )
|
||||
//--------------------------------------------------------------
|
||||
const float w0 = vertex.color2.x;
|
||||
const float w1 = vertex.color2.y;
|
||||
const float w2 = vertex.color2.z;
|
||||
const float w3 = vertex.color2.w;
|
||||
|
||||
float4 matX, matY, matZ; // must be float4 for vec4
|
||||
int joint = int( vertex.color.x * 255.1 * 3.0 );
|
||||
matX = matrices[int( joint + 0 )] * w0;
|
||||
matY = matrices[int( joint + 1 )] * w0;
|
||||
matZ = matrices[int( joint + 2 )] * w0;
|
||||
|
||||
joint = int( vertex.color.y * 255.1 * 3.0 );
|
||||
matX += matrices[int( joint + 0 )] * w1;
|
||||
matY += matrices[int( joint + 1 )] * w1;
|
||||
matZ += matrices[int( joint + 2 )] * w1;
|
||||
|
||||
joint = int( vertex.color.z * 255.1 * 3.0 );
|
||||
matX += matrices[int( joint + 0 )] * w2;
|
||||
matY += matrices[int( joint + 1 )] * w2;
|
||||
matZ += matrices[int( joint + 2 )] * w2;
|
||||
|
||||
joint = int( vertex.color.w * 255.1 * 3.0 );
|
||||
matX += matrices[int( joint + 0 )] * w3;
|
||||
matY += matrices[int( joint + 1 )] * w3;
|
||||
matZ += matrices[int( joint + 2 )] * w3;
|
||||
|
||||
float3 normal;
|
||||
normal.x = dot3( matX, vNormal );
|
||||
normal.y = dot3( matY, vNormal );
|
||||
normal.z = dot3( matZ, vNormal );
|
||||
normal = normalize( normal );
|
||||
|
||||
float3 tangent;
|
||||
tangent.x = dot3( matX, vTangent );
|
||||
tangent.y = dot3( matY, vTangent );
|
||||
tangent.z = dot3( matZ, vTangent );
|
||||
tangent = normalize( tangent );
|
||||
|
||||
float3 bitangent;
|
||||
bitangent.x = dot3( matX, vBitangent );
|
||||
bitangent.y = dot3( matY, vBitangent );
|
||||
bitangent.z = dot3( matZ, vBitangent );
|
||||
bitangent = normalize( bitangent );
|
||||
|
||||
float4 modelPosition;
|
||||
modelPosition.x = dot4( matX, vertex.position );
|
||||
modelPosition.y = dot4( matY, vertex.position );
|
||||
modelPosition.z = dot4( matZ, vertex.position );
|
||||
modelPosition.w = 1.0;
|
||||
|
||||
#else
|
||||
float4 modelPosition = vertex.position;
|
||||
float3 normal = vNormal.xyz;
|
||||
float3 tangent = vTangent.xyz;
|
||||
float3 bitangent = vBitangent.xyz;
|
||||
#endif
|
||||
|
||||
result.position.x = dot4( modelPosition, rpMVPmatrixX );
|
||||
result.position.y = dot4( modelPosition, rpMVPmatrixY );
|
||||
result.position.z = dot4( modelPosition, rpMVPmatrixZ );
|
||||
result.position.w = dot4( modelPosition, rpMVPmatrixW );
|
||||
|
||||
float4 defaultTexCoord = float4( 0.0f, 0.5f, 0.0f, 1.0f );
|
||||
|
||||
//calculate vector to light
|
||||
//float4 toLight = rpLocalLightOrigin;
|
||||
float4 toLight = normalize( float4( 0.0f, 0.5f, 1.0f, 1.0f ) );
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
||||
|
||||
//# textures 0 takes the base coordinates by the texture matrix
|
||||
result.texcoord0 = defaultTexCoord;
|
||||
result.texcoord0.x = dot4( vertex.texcoord.xy, rpBumpMatrixS );
|
||||
result.texcoord0.y = dot4( vertex.texcoord.xy, rpBumpMatrixT );
|
||||
|
||||
//# textures 1 takes the base coordinates by the texture matrix
|
||||
result.texcoord1 = defaultTexCoord;
|
||||
result.texcoord1.x = dot4( vertex.texcoord.xy, rpDiffuseMatrixS );
|
||||
result.texcoord1.y = dot4( vertex.texcoord.xy, rpDiffuseMatrixT );
|
||||
|
||||
//# textures 2 takes the base coordinates by the texture matrix
|
||||
result.texcoord2 = defaultTexCoord;
|
||||
result.texcoord2.x = dot4( vertex.texcoord.xy, rpSpecularMatrixS );
|
||||
result.texcoord2.y = dot4( vertex.texcoord.xy, rpSpecularMatrixT );
|
||||
|
||||
//# calculate normalized vector to viewer in R1
|
||||
//result.texcoord3 = modelPosition;
|
||||
|
||||
float4 toEye = normalize( rpLocalViewOrigin - modelPosition );
|
||||
|
||||
result.texcoord3.x = dot3( toEye, rpModelMatrixX );
|
||||
result.texcoord3.y = dot3( toEye, rpModelMatrixY );
|
||||
result.texcoord3.z = dot3( toEye, rpModelMatrixZ );
|
||||
|
||||
result.texcoord4.x = dot3( tangent, rpModelMatrixX );
|
||||
result.texcoord5.x = dot3( tangent, rpModelMatrixY );
|
||||
result.texcoord6.x = dot3( tangent, rpModelMatrixZ );
|
||||
|
||||
result.texcoord4.y = dot3( bitangent, rpModelMatrixX );
|
||||
result.texcoord5.y = dot3( bitangent, rpModelMatrixY );
|
||||
result.texcoord6.y = dot3( bitangent, rpModelMatrixZ );
|
||||
|
||||
result.texcoord4.z = dot3( normal, rpModelMatrixX );
|
||||
result.texcoord5.z = dot3( normal, rpModelMatrixY );
|
||||
result.texcoord6.z = dot3( normal, rpModelMatrixZ );
|
||||
|
||||
float4 worldPosition;
|
||||
worldPosition.x = dot4( modelPosition, rpModelMatrixX );
|
||||
worldPosition.y = dot4( modelPosition, rpModelMatrixY );
|
||||
worldPosition.z = dot4( modelPosition, rpModelMatrixZ );
|
||||
worldPosition.w = dot4( modelPosition, rpModelMatrixW );
|
||||
result.texcoord7 = worldPosition;
|
||||
|
||||
#if defined( USE_GPU_SKINNING )
|
||||
// for joint transformation of the tangent space, we use color and
|
||||
// color2 for weighting information, so hopefully there aren't any
|
||||
// effects that need vertex color...
|
||||
result.color = float4( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
#else
|
||||
//# generate the vertex color, which can be 1.0, color, or 1.0 - color
|
||||
//# for 1.0 : env[16] = 0, env[17] = 1
|
||||
//# for color : env[16] = 1, env[17] = 0
|
||||
//# for 1.0-color : env[16] = -1, env[17] = 1
|
||||
result.color = ( swizzleColor( vertex.color ) * rpVertexColorModulate ) + rpVertexColorAdd;
|
||||
#endif
|
||||
}
|
|
@ -1972,6 +1972,8 @@ void idRenderBackend::DBG_ShowLightGrid()
|
|||
gridPoint = &area->lightGrid.lightGridPoints[ gridPointIndex ];
|
||||
|
||||
totalFactor = 0;
|
||||
idVec3 cornerOffsets[8];
|
||||
|
||||
for( int i = 0; i < 8; i++ )
|
||||
{
|
||||
float factor = 1.0;
|
||||
|
@ -1981,7 +1983,9 @@ void idRenderBackend::DBG_ShowLightGrid()
|
|||
|
||||
for( int j = 0; j < 3; j++ )
|
||||
{
|
||||
if( i & ( 1 << j ) )
|
||||
cornerOffsets[i][j] = i & ( 1 << j );
|
||||
|
||||
if( cornerOffsets[i][j] > 0.0f )
|
||||
{
|
||||
factor *= frac[j];
|
||||
|
||||
|
|
|
@ -1323,7 +1323,89 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useFas
|
|||
const textureUsage_t specUsage = din->specularImage->GetUsage();
|
||||
|
||||
// RB begin
|
||||
if( useIBL )
|
||||
if( useIBL && viewDef->useLightGrid )
|
||||
{
|
||||
idVec4 probeMins, probeMaxs, probeCenter;
|
||||
|
||||
probeMins[0] = viewDef->globalProbeBounds[0][0];
|
||||
probeMins[1] = viewDef->globalProbeBounds[0][1];
|
||||
probeMins[2] = viewDef->globalProbeBounds[0][2];
|
||||
probeMins[3] = viewDef->globalProbeBounds.IsCleared() ? 0.0f : 1.0f;
|
||||
|
||||
probeMaxs[0] = viewDef->globalProbeBounds[1][0];
|
||||
probeMaxs[1] = viewDef->globalProbeBounds[1][1];
|
||||
probeMaxs[2] = viewDef->globalProbeBounds[1][2];
|
||||
probeMaxs[3] = 0.0f;
|
||||
|
||||
idVec3 center = viewDef->globalProbeBounds.GetCenter();
|
||||
probeCenter.Set( center.x, center.y, center.z, 1.0f );
|
||||
|
||||
SetVertexParm( RENDERPARM_WOBBLESKY_X, probeMins.ToFloatPtr() );
|
||||
SetVertexParm( RENDERPARM_WOBBLESKY_Y, probeMaxs.ToFloatPtr() );
|
||||
SetVertexParm( RENDERPARM_WOBBLESKY_Z, probeCenter.ToFloatPtr() );
|
||||
|
||||
if( specUsage == TD_SPECULAR_PBR_RMAO || specUsage == TD_SPECULAR_PBR_RMAOD )
|
||||
{
|
||||
// PBR path with roughness, metal and AO
|
||||
if( din->surf->jointCache )
|
||||
{
|
||||
renderProgManager.BindShader_ImageBasedLightGridSkinned_PBR();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderProgManager.BindShader_ImageBasedLightGrid_PBR();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( din->surf->jointCache )
|
||||
{
|
||||
renderProgManager.BindShader_ImageBasedLightGridSkinned();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderProgManager.BindShader_ImageBasedLightGrid();
|
||||
}
|
||||
}
|
||||
|
||||
GL_SelectTexture( INTERACTION_TEXUNIT_FALLOFF );
|
||||
globalImages->brdfLutImage->Bind();
|
||||
|
||||
GL_SelectTexture( INTERACTION_TEXUNIT_PROJECTION );
|
||||
#if defined( USE_VULKAN )
|
||||
globalImages->whiteImage->Bind();
|
||||
#else
|
||||
if( !r_useSSAO.GetBool() )
|
||||
{
|
||||
globalImages->whiteImage->Bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
globalImages->ambientOcclusionImage[0]->Bind();
|
||||
}
|
||||
#endif
|
||||
|
||||
GL_SelectTexture( INTERACTION_TEXUNIT_AMBIENT_CUBE1 );
|
||||
if( viewDef->irradianceImage )
|
||||
{
|
||||
viewDef->irradianceImage->Bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
globalImages->defaultUACIrradianceCube->Bind();
|
||||
}
|
||||
|
||||
GL_SelectTexture( INTERACTION_TEXUNIT_SPECULAR_CUBE1 );
|
||||
if( viewDef->radianceImage )
|
||||
{
|
||||
viewDef->radianceImage->Bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
globalImages->defaultUACRadianceCube->Bind();
|
||||
}
|
||||
}
|
||||
else if( useIBL )
|
||||
{
|
||||
idVec4 probeMins, probeMaxs, probeCenter;
|
||||
|
||||
|
|
|
@ -636,6 +636,12 @@ struct viewDef_t
|
|||
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
|
||||
|
||||
// lightGrid
|
||||
bool useLightGrid;
|
||||
idVec3 lightGridOrigin;
|
||||
idVec3 lightGridSize;
|
||||
int lightGridBounds[3];
|
||||
// RB end
|
||||
};
|
||||
|
||||
|
|
|
@ -109,10 +109,17 @@ void idRenderProgManager::Init()
|
|||
{ BUILTIN_VERTEX_COLOR, "builtin/vertex_color", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_AMBIENT_LIGHTING, "builtin/lighting/ambient_lighting", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_AMBIENT_LIGHTING_SKINNED, "builtin/lighting/ambient_lighting", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
|
||||
{ BUILTIN_AMBIENT_LIGHTING_IBL, "builtin/lighting/ambient_lighting_IBL", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_AMBIENT_LIGHTING_IBL_SKINNED, "builtin/lighting/ambient_lighting_IBL", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_AMBIENT_LIGHTING_IBL_PBR, "builtin/lighting/ambient_lighting_IBL", "_PBR", BIT( USE_PBR ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_AMBIENT_LIGHTING_IBL_PBR_SKINNED, "builtin/lighting/ambient_lighting_IBL", "_PBR_skinned", BIT( USE_GPU_SKINNING | USE_PBR ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
|
||||
{ BUILTIN_AMBIENT_LIGHTGRID_IBL, "builtin/lighting/ambient_lightgrid_IBL", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_AMBIENT_LIGHTGRID_IBL_SKINNED, "builtin/lighting/ambient_lightgrid_IBL", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_AMBIENT_LIGHTGRID_IBL_PBR, "builtin/lighting/ambient_lightgrid_IBL", "_PBR", BIT( USE_PBR ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_AMBIENT_LIGHTGRID_IBL_PBR_SKINNED, "builtin/lighting/ambient_lightgrid_IBL", "_PBR_skinned", BIT( USE_GPU_SKINNING | USE_PBR ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
|
||||
{ BUILTIN_SMALL_GEOMETRY_BUFFER, "builtin/gbuffer", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_SMALL_GEOMETRY_BUFFER_SKINNED, "builtin/gbuffer", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
// RB end
|
||||
|
@ -279,8 +286,13 @@ void idRenderProgManager::Init()
|
|||
renderProgs[builtinShaders[BUILTIN_DEBUG_LIGHTGRID_SKINNED]].usesJoints = true;
|
||||
renderProgs[builtinShaders[BUILTIN_DEBUG_OCTAHEDRON_SKINNED]].usesJoints = true;
|
||||
renderProgs[builtinShaders[BUILTIN_AMBIENT_LIGHTING_SKINNED]].usesJoints = true;
|
||||
|
||||
renderProgs[builtinShaders[BUILTIN_AMBIENT_LIGHTING_IBL_SKINNED]].usesJoints = true;
|
||||
renderProgs[builtinShaders[BUILTIN_AMBIENT_LIGHTING_IBL_PBR_SKINNED]].usesJoints = true;
|
||||
|
||||
renderProgs[builtinShaders[BUILTIN_AMBIENT_LIGHTGRID_IBL_SKINNED]].usesJoints = true;
|
||||
renderProgs[builtinShaders[BUILTIN_AMBIENT_LIGHTGRID_IBL_PBR_SKINNED]].usesJoints = true;
|
||||
|
||||
renderProgs[builtinShaders[BUILTIN_SMALL_GEOMETRY_BUFFER_SKINNED]].usesJoints = true;
|
||||
renderProgs[builtinShaders[BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED]].usesJoints = true;
|
||||
renderProgs[builtinShaders[BUILTIN_INTERACTION_SHADOW_MAPPING_POINT_SKINNED]].usesJoints = true;
|
||||
|
|
|
@ -311,6 +311,28 @@ public:
|
|||
BindShader_Builtin( BUILTIN_AMBIENT_LIGHTING_IBL_PBR_SKINNED );
|
||||
}
|
||||
|
||||
|
||||
void BindShader_ImageBasedLightGrid()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_AMBIENT_LIGHTGRID_IBL );
|
||||
}
|
||||
|
||||
void BindShader_ImageBasedLightGridSkinned()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_AMBIENT_LIGHTGRID_IBL_SKINNED );
|
||||
}
|
||||
|
||||
void BindShader_ImageBasedLightGrid_PBR()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_AMBIENT_LIGHTGRID_IBL_PBR );
|
||||
}
|
||||
|
||||
void BindShader_ImageBasedLightGridSkinned_PBR()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_AMBIENT_LIGHTGRID_IBL_PBR_SKINNED );
|
||||
}
|
||||
|
||||
|
||||
void BindShader_SmallGeometryBuffer()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_SMALL_GEOMETRY_BUFFER );
|
||||
|
@ -741,10 +763,17 @@ private:
|
|||
BUILTIN_VERTEX_COLOR,
|
||||
BUILTIN_AMBIENT_LIGHTING,
|
||||
BUILTIN_AMBIENT_LIGHTING_SKINNED,
|
||||
|
||||
BUILTIN_AMBIENT_LIGHTING_IBL,
|
||||
BUILTIN_AMBIENT_LIGHTING_IBL_SKINNED,
|
||||
BUILTIN_AMBIENT_LIGHTING_IBL_PBR,
|
||||
BUILTIN_AMBIENT_LIGHTING_IBL_PBR_SKINNED,
|
||||
|
||||
BUILTIN_AMBIENT_LIGHTGRID_IBL,
|
||||
BUILTIN_AMBIENT_LIGHTGRID_IBL_SKINNED,
|
||||
BUILTIN_AMBIENT_LIGHTGRID_IBL_PBR,
|
||||
BUILTIN_AMBIENT_LIGHTGRID_IBL_PBR_SKINNED,
|
||||
|
||||
BUILTIN_SMALL_GEOMETRY_BUFFER,
|
||||
BUILTIN_SMALL_GEOMETRY_BUFFER_SKINNED,
|
||||
// RB end
|
||||
|
|
|
@ -5229,6 +5229,631 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
|
||||
},
|
||||
|
||||
{
|
||||
"renderprogs/builtin/lighting/ambient_lightgrid_IBL.ps.hlsl",
|
||||
"/*\n"
|
||||
"===========================================================================\n"
|
||||
"\n"
|
||||
"Doom 3 BFG Edition GPL Source Code\n"
|
||||
"Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.\n"
|
||||
"Copyright (C) 2013-2021 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"
|
||||
"Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify\n"
|
||||
"it under the terms of the GNU General Public License as published by\n"
|
||||
"the Free Software Foundation, either version 3 of the License, or\n"
|
||||
"(at your option) any later version.\n"
|
||||
"\n"
|
||||
"Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,\n"
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
"GNU General Public License for more details.\n"
|
||||
"\n"
|
||||
"You should have received a copy of the GNU General Public License\n"
|
||||
"along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.\n"
|
||||
"\n"
|
||||
"In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.\n"
|
||||
"\n"
|
||||
"If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.\n"
|
||||
"\n"
|
||||
"===========================================================================\n"
|
||||
"*/\n"
|
||||
"\n"
|
||||
"#include \"renderprogs/global.inc.hlsl\"\n"
|
||||
"\n"
|
||||
"#include \"renderprogs/BRDF.inc.hlsl\"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"// *INDENT-OFF*\n"
|
||||
"uniform sampler2D samp0 : register(s0); // texture 0 is the per-surface normal map\n"
|
||||
"uniform sampler2D samp1 : register(s1); // texture 1 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 3 is the BRDF LUT\n"
|
||||
"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"
|
||||
"\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 texcoord7 : TEXCOORD7_centroid;\n"
|
||||
" half4 color : COLOR0;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct PS_OUT\n"
|
||||
"{\n"
|
||||
" half4 color : COLOR;\n"
|
||||
"};\n"
|
||||
"// *INDENT-ON*\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"float3 lightGridOrigin = float3( -192.0, -128.0, 0 );\n"
|
||||
"float3 lightGridSize = float3( 64.0, 64.0, 128.0 );\n"
|
||||
"int3 lightGridBounds = int3( 7, 7, 3 );\n"
|
||||
"\n"
|
||||
"int3 GetBaseGridCoord( float3 origin )\n"
|
||||
"{\n"
|
||||
" int3 pos;\n"
|
||||
"\n"
|
||||
" float3 lightOrigin = origin - lightGridOrigin;\n"
|
||||
" for( int i = 0; i < 3; i++ )\n"
|
||||
" {\n"
|
||||
" float v;\n"
|
||||
"\n"
|
||||
" v = lightOrigin[i] * ( 1.0f / lightGridSize[i] );\n"
|
||||
" pos[i] = int( floor( v ) );\n"
|
||||
"\n"
|
||||
" if( pos[i] < 0 )\n"
|
||||
" {\n"
|
||||
" pos[i] = 0;\n"
|
||||
" }\n"
|
||||
" else if( pos[i] >= lightGridBounds[i] - 1 )\n"
|
||||
" {\n"
|
||||
" pos[i] = lightGridBounds[i] - 1;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return pos;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"// RB: TODO OPTIMIZE\n"
|
||||
"// this is a straight port of idBounds::RayIntersection\n"
|
||||
"bool AABBRayIntersection( float3 b[2], float3 start, float3 dir, out float scale )\n"
|
||||
"{\n"
|
||||
" int i, ax0, ax1, ax2, side, inside;\n"
|
||||
" float f;\n"
|
||||
" float3 hit;\n"
|
||||
"\n"
|
||||
" ax0 = -1;\n"
|
||||
" inside = 0;\n"
|
||||
" for( i = 0; i < 3; i++ )\n"
|
||||
" {\n"
|
||||
" if( start[i] < b[0][i] )\n"
|
||||
" {\n"
|
||||
" side = 0;\n"
|
||||
" }\n"
|
||||
" else if( start[i] > b[1][i] )\n"
|
||||
" {\n"
|
||||
" side = 1;\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" inside++;\n"
|
||||
" continue;\n"
|
||||
" }\n"
|
||||
" if( dir[i] == 0.0f )\n"
|
||||
" {\n"
|
||||
" continue;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" f = ( start[i] - b[side][i] );\n"
|
||||
"\n"
|
||||
" if( ax0 < 0 || abs( f ) > abs( scale * dir[i] ) )\n"
|
||||
" {\n"
|
||||
" scale = - ( f / dir[i] );\n"
|
||||
" ax0 = i;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" if( ax0 < 0 )\n"
|
||||
" {\n"
|
||||
" scale = 0.0f;\n"
|
||||
"\n"
|
||||
" // return true if the start point is inside the bounds\n"
|
||||
" return ( inside == 3 );\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" ax1 = ( ax0 + 1 ) % 3;\n"
|
||||
" ax2 = ( ax0 + 2 ) % 3;\n"
|
||||
" hit[ax1] = start[ax1] + scale * dir[ax1];\n"
|
||||
" hit[ax2] = start[ax2] + scale * dir[ax2];\n"
|
||||
"\n"
|
||||
" return ( hit[ax1] >= b[0][ax1] && hit[ax1] <= b[1][ax1] &&\n"
|
||||
" hit[ax2] >= b[0][ax2] && hit[ax2] <= b[1][ax2] );\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void main( PS_IN fragment, out PS_OUT result )\n"
|
||||
"{\n"
|
||||
" half4 bumpMap = tex2D( samp0, fragment.texcoord0.xy );\n"
|
||||
" half4 YCoCG = tex2D( samp2, fragment.texcoord1.xy );\n"
|
||||
" half4 specMapSRGB = tex2D( samp1, fragment.texcoord2.xy );\n"
|
||||
" half4 specMap = sRGBAToLinearRGBA( specMapSRGB );\n"
|
||||
"\n"
|
||||
" half3 diffuseMap = sRGBToLinearRGB( ConvertYCoCgToRGB( YCoCG ) );\n"
|
||||
"\n"
|
||||
" half3 localNormal;\n"
|
||||
"#if defined(USE_NORMAL_FMT_RGB8)\n"
|
||||
" localNormal.xy = bumpMap.rg - 0.5;\n"
|
||||
"#else\n"
|
||||
" localNormal.xy = bumpMap.wy - 0.5;\n"
|
||||
"#endif\n"
|
||||
" localNormal.z = sqrt( abs( dot( localNormal.xy, localNormal.xy ) - 0.25 ) );\n"
|
||||
" localNormal = normalize( localNormal );\n"
|
||||
"\n"
|
||||
" float3 globalNormal;\n"
|
||||
" 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 globalPosition = fragment.texcoord7.xyz;\n"
|
||||
"\n"
|
||||
" // RB: rpGlobalLightOrigin is global view origin\n"
|
||||
" float3 globalEye = normalize( rpGlobalLightOrigin.xyz - globalPosition );\n"
|
||||
"\n"
|
||||
" float3 reflectionVector = globalNormal * dot3( globalEye, globalNormal );\n"
|
||||
" reflectionVector = normalize( ( reflectionVector * 2.0f ) - globalEye );\n"
|
||||
"\n"
|
||||
"#if 1\n"
|
||||
" // parallax box correction using portal area bounds\n"
|
||||
" float hitScale;\n"
|
||||
" float3 bounds[2];\n"
|
||||
" bounds[0].x = rpWobbleSkyX.x;\n"
|
||||
" bounds[0].y = rpWobbleSkyX.y;\n"
|
||||
" bounds[0].z = rpWobbleSkyX.z;\n"
|
||||
"\n"
|
||||
" bounds[1].x = rpWobbleSkyY.x;\n"
|
||||
" bounds[1].y = rpWobbleSkyY.y;\n"
|
||||
" bounds[1].z = rpWobbleSkyY.z;\n"
|
||||
"\n"
|
||||
" // global fragment position\n"
|
||||
" float3 rayStart = fragment.texcoord7.xyz;\n"
|
||||
"\n"
|
||||
" // we can't start inside the box so move this outside and use the reverse path\n"
|
||||
" rayStart += reflectionVector * 10000.0;\n"
|
||||
"\n"
|
||||
" // only do a box <-> ray intersection test if we use a local cubemap\n"
|
||||
" if( ( rpWobbleSkyX.w > 0.0 ) && AABBRayIntersection( bounds, rayStart, -reflectionVector, hitScale ) )\n"
|
||||
" {\n"
|
||||
" float3 hitPoint = rayStart - reflectionVector * hitScale;\n"
|
||||
"\n"
|
||||
" // rpWobbleSkyZ is cubemap center\n"
|
||||
" reflectionVector = hitPoint - rpWobbleSkyZ.xyz;\n"
|
||||
" }\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
" half vDotN = saturate( dot3( globalEye, globalNormal ) );\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"
|
||||
"\n"
|
||||
" // the vast majority of real-world materials (anything not metal or gems) have F(0°)\n"
|
||||
" // values in a very narrow range (~0.02 - 0.08)\n"
|
||||
"\n"
|
||||
" // approximate non-metals with linear RGB 0.04 which is 0.08 * 0.5 (default in UE4)\n"
|
||||
" const half3 dielectricColor = half3( 0.04 );\n"
|
||||
"\n"
|
||||
" // derive diffuse and specular from albedo(m) base color\n"
|
||||
" const half3 baseColor = diffuseMap;\n"
|
||||
"\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"
|
||||
" float3 kS = Fresnel_SchlickRoughness( specularColor, vDotN, roughness );\n"
|
||||
" float3 kD = ( float3( 1.0, 1.0, 1.0 ) - kS ) * ( 1.0 - metallic );\n"
|
||||
"\n"
|
||||
"#else\n"
|
||||
" const float roughness = EstimateLegacyRoughness( specMapSRGB.rgb );\n"
|
||||
"\n"
|
||||
" 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"
|
||||
" float3 kS = Fresnel_SchlickRoughness( specularColor, vDotN, roughness );\n"
|
||||
"\n"
|
||||
" // NOTE: metalness is missing\n"
|
||||
" float3 kD = ( float3( 1.0, 1.0, 1.0 ) - kS );\n"
|
||||
"\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
" //diffuseColor = half3( 1.0, 1.0, 1.0 );\n"
|
||||
" //diffuseColor = half3( 0.0, 0.0, 0.0 );\n"
|
||||
"\n"
|
||||
" // calculate the screen texcoord in the 0.0 to 1.0 range\n"
|
||||
" //float2 screenTexCoord = vposToScreenPosTexCoord( fragment.position.xy );\n"
|
||||
" float2 screenTexCoord = fragment.position.xy * rpWindowCoord.xy;\n"
|
||||
"\n"
|
||||
" float ao = 1.0;\n"
|
||||
" ao = tex2D( samp4, screenTexCoord ).r;\n"
|
||||
" //diffuseColor.rgb *= ao;\n"
|
||||
"\n"
|
||||
" // evaluate diffuse IBL\n"
|
||||
"\n"
|
||||
" float2 normalizedOctCoord = octEncode( globalNormal );\n"
|
||||
" float2 normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5;\n"
|
||||
"\n"
|
||||
"// lightgrid atlas\n"
|
||||
" float invXY = ( 1.0 / ( lightGridBounds[0] * lightGridBounds[1] ) );\n"
|
||||
" float invZ = ( 1.0 / lightGridBounds[2] );\n"
|
||||
"\n"
|
||||
" normalizedOctCoordZeroOne.x *= invXY;\n"
|
||||
" normalizedOctCoordZeroOne.y *= invZ;\n"
|
||||
"\n"
|
||||
" int3 gridCoord;\n"
|
||||
" float3 frac;\n"
|
||||
" float3 lightOrigin = globalPosition - lightGridOrigin;\n"
|
||||
"\n"
|
||||
" for( int i = 0; i < 3; i++ )\n"
|
||||
" {\n"
|
||||
" float v;\n"
|
||||
"\n"
|
||||
" v = lightOrigin[i] * ( 1.0f / lightGridSize[i] );\n"
|
||||
" gridCoord[i] = int( floor( v ) );\n"
|
||||
" frac[ i ] = v - gridCoord[ i ];\n"
|
||||
"\n"
|
||||
" if( gridCoord[i] < 0 )\n"
|
||||
" {\n"
|
||||
" gridCoord[i] = 0;\n"
|
||||
" }\n"
|
||||
" else if( gridCoord[i] >= lightGridBounds[i] - 1 )\n"
|
||||
" {\n"
|
||||
" gridCoord[i] = lightGridBounds[i] - 1;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" // trilerp the light value\n"
|
||||
" int3 gridStep;\n"
|
||||
"\n"
|
||||
" gridStep[0] = 1;\n"
|
||||
" gridStep[1] = lightGridBounds[0];\n"
|
||||
" gridStep[2] = lightGridBounds[0] * lightGridBounds[1];\n"
|
||||
"\n"
|
||||
" float totalFactor = 0.0;\n"
|
||||
" float3 irradiance;\n"
|
||||
"\n"
|
||||
" /*\n"
|
||||
" for( int i = 0; i < 8; i++ )\n"
|
||||
" {\n"
|
||||
" for( int j = 0; j < 3; j++ )\n"
|
||||
" {\n"
|
||||
" if( i & ( 1 << j ) )\n"
|
||||
"\n"
|
||||
" results in these offsets\n"
|
||||
" */\n"
|
||||
" const float3 cornerOffsets[8] = float3[](\n"
|
||||
" float3( 0.0, 0.0, 0.0 ),\n"
|
||||
" float3( 1.0, 0.0, 0.0 ),\n"
|
||||
" float3( 0.0, 2.0, 0.0 ),\n"
|
||||
" float3( 1.0, 2.0, 0.0 ),\n"
|
||||
" float3( 0.0, 0.0, 4.0 ),\n"
|
||||
" float3( 1.0, 0.0, 4.0 ),\n"
|
||||
" float3( 0.0, 2.0, 4.0 ),\n"
|
||||
" float3( 1.0, 2.0, 4.0 ) );\n"
|
||||
"\n"
|
||||
" for( int i = 0; i < 8; i++ )\n"
|
||||
" {\n"
|
||||
" float factor = 1.0;\n"
|
||||
"\n"
|
||||
" int3 gridCoord2 = gridCoord;\n"
|
||||
"\n"
|
||||
" for( int j = 0; j < 3; j++ )\n"
|
||||
" {\n"
|
||||
" if( cornerOffsets[ i ][ j ] > 0.0f )\n"
|
||||
" {\n"
|
||||
" factor *= frac[ j ];\n"
|
||||
"\n"
|
||||
" gridCoord2[ j ] += 1;\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" factor *= ( 1.0f - frac[ j ] );\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" float2 atlasOffset;\n"
|
||||
"\n"
|
||||
" atlasOffset.x = ( gridCoord2[0] * gridStep[0] + gridCoord2[1] * gridStep[1] ) * invXY;\n"
|
||||
" atlasOffset.y = ( gridCoord2[2] * invZ );\n"
|
||||
"\n"
|
||||
" irradiance += tex2D( samp7, normalizedOctCoordZeroOne + atlasOffset ).rgb * factor;\n"
|
||||
"\n"
|
||||
" totalFactor += factor;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" if( totalFactor > 0 && totalFactor < 0.99 )\n"
|
||||
" {\n"
|
||||
" totalFactor = 1.0f / totalFactor;\n"
|
||||
"\n"
|
||||
" irradiance *= totalFactor;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
"// lightgrid atlas\n"
|
||||
"\n"
|
||||
"\n"
|
||||
" float3 diffuseLight = ( kD * irradiance * diffuseColor ) * ao * ( rpDiffuseModifier.xyz * 1.0 );\n"
|
||||
"\n"
|
||||
" // evaluate specular IBL\n"
|
||||
"\n"
|
||||
" // should be 8 = numMips - 1, 256^2 = 9 mips\n"
|
||||
" 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"
|
||||
"\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"
|
||||
"#if 0\n"
|
||||
" result.color.rgb = float3( envBRDF.x, envBRDF.y, 0.0 );\n"
|
||||
" result.color.w = fragment.color.a;\n"
|
||||
" return;\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
" float specAO = ComputeSpecularAO( vDotN, ao, roughness );\n"
|
||||
" float3 specularLight = radiance * ( kS * envBRDF.x + float3( envBRDF.y ) ) * specAO * ( rpSpecularModifier.xyz * 0.5 );\n"
|
||||
"\n"
|
||||
"#if 0\n"
|
||||
" // Marmoset Horizon Fade trick\n"
|
||||
" const half horizonFade = 1.3;\n"
|
||||
" half horiz = saturate( 1.0 + horizonFade * saturate( dot3( reflectionVector, globalNormal ) ) );\n"
|
||||
" horiz *= horiz;\n"
|
||||
" //horiz = clamp( horiz, 0.0, 1.0 );\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
" half3 lightColor = sRGBToLinearRGB( rpAmbientColor.rgb );\n"
|
||||
"\n"
|
||||
" //result.color.rgb = diffuseLight;\n"
|
||||
" //result.color.rgb = diffuseLight * lightColor;\n"
|
||||
" //result.color.rgb = specularLight;\n"
|
||||
" result.color.rgb = ( diffuseLight + specularLight ) * lightColor * fragment.color.rgb;\n"
|
||||
" //result.color.rgb = localNormal.xyz * 0.5 + 0.5;\n"
|
||||
" //result.color.rgb = float3( ao );\n"
|
||||
" result.color.w = fragment.color.a;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
"renderprogs/builtin/lighting/ambient_lightgrid_IBL.vs.hlsl",
|
||||
"/*\n"
|
||||
"===========================================================================\n"
|
||||
"\n"
|
||||
"Doom 3 BFG Edition GPL Source Code\n"
|
||||
"Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.\n"
|
||||
"Copyright (C) 2013-2015 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"
|
||||
"Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify\n"
|
||||
"it under the terms of the GNU General Public License as published by\n"
|
||||
"the Free Software Foundation, either version 3 of the License, or\n"
|
||||
"(at your option) any later version.\n"
|
||||
"\n"
|
||||
"Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,\n"
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
"GNU General Public License for more details.\n"
|
||||
"\n"
|
||||
"You should have received a copy of the GNU General Public License\n"
|
||||
"along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.\n"
|
||||
"\n"
|
||||
"In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.\n"
|
||||
"\n"
|
||||
"If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.\n"
|
||||
"\n"
|
||||
"===========================================================================\n"
|
||||
"*/\n"
|
||||
"\n"
|
||||
"#include \"renderprogs/global.inc.hlsl\"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"#if defined( USE_GPU_SKINNING )\n"
|
||||
"uniform matrices_ubo { float4 matrices[408]; };\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"// *INDENT-OFF*\n"
|
||||
"struct VS_IN {\n"
|
||||
" float4 position : POSITION;\n"
|
||||
" float2 texcoord : TEXCOORD0;\n"
|
||||
" float4 normal : NORMAL;\n"
|
||||
" float4 tangent : TANGENT;\n"
|
||||
" float4 color : COLOR0;\n"
|
||||
" float4 color2 : COLOR1;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct VS_OUT {\n"
|
||||
" float4 position : POSITION;\n"
|
||||
" float4 texcoord0 : TEXCOORD0;\n"
|
||||
" float4 texcoord1 : TEXCOORD1;\n"
|
||||
" float4 texcoord2 : TEXCOORD2;\n"
|
||||
" float4 texcoord3 : TEXCOORD3;\n"
|
||||
" float4 texcoord4 : TEXCOORD4;\n"
|
||||
" float4 texcoord5 : TEXCOORD5;\n"
|
||||
" float4 texcoord6 : TEXCOORD6;\n"
|
||||
" float4 texcoord7 : TEXCOORD7;\n"
|
||||
" float4 color : COLOR0;\n"
|
||||
"};\n"
|
||||
"// *INDENT-ON*\n"
|
||||
"\n"
|
||||
"void main( VS_IN vertex, out VS_OUT result )\n"
|
||||
"{\n"
|
||||
"\n"
|
||||
" float4 vNormal = vertex.normal * 2.0 - 1.0;\n"
|
||||
" float4 vTangent = vertex.tangent * 2.0 - 1.0;\n"
|
||||
" float3 vBitangent = cross( vNormal.xyz, vTangent.xyz ) * vTangent.w;\n"
|
||||
"\n"
|
||||
"#if defined( USE_GPU_SKINNING )\n"
|
||||
" //--------------------------------------------------------------\n"
|
||||
" // GPU transformation of the normal / tangent / bitangent\n"
|
||||
" //\n"
|
||||
" // multiplying with 255.1 give us the same result and is faster than floor( w * 255 + 0.5 )\n"
|
||||
" //--------------------------------------------------------------\n"
|
||||
" const float w0 = vertex.color2.x;\n"
|
||||
" const float w1 = vertex.color2.y;\n"
|
||||
" const float w2 = vertex.color2.z;\n"
|
||||
" const float w3 = vertex.color2.w;\n"
|
||||
"\n"
|
||||
" float4 matX, matY, matZ; // must be float4 for vec4\n"
|
||||
" int joint = int( vertex.color.x * 255.1 * 3.0 );\n"
|
||||
" matX = matrices[int( joint + 0 )] * w0;\n"
|
||||
" matY = matrices[int( joint + 1 )] * w0;\n"
|
||||
" matZ = matrices[int( joint + 2 )] * w0;\n"
|
||||
"\n"
|
||||
" joint = int( vertex.color.y * 255.1 * 3.0 );\n"
|
||||
" matX += matrices[int( joint + 0 )] * w1;\n"
|
||||
" matY += matrices[int( joint + 1 )] * w1;\n"
|
||||
" matZ += matrices[int( joint + 2 )] * w1;\n"
|
||||
"\n"
|
||||
" joint = int( vertex.color.z * 255.1 * 3.0 );\n"
|
||||
" matX += matrices[int( joint + 0 )] * w2;\n"
|
||||
" matY += matrices[int( joint + 1 )] * w2;\n"
|
||||
" matZ += matrices[int( joint + 2 )] * w2;\n"
|
||||
"\n"
|
||||
" joint = int( vertex.color.w * 255.1 * 3.0 );\n"
|
||||
" matX += matrices[int( joint + 0 )] * w3;\n"
|
||||
" matY += matrices[int( joint + 1 )] * w3;\n"
|
||||
" matZ += matrices[int( joint + 2 )] * w3;\n"
|
||||
"\n"
|
||||
" float3 normal;\n"
|
||||
" normal.x = dot3( matX, vNormal );\n"
|
||||
" normal.y = dot3( matY, vNormal );\n"
|
||||
" normal.z = dot3( matZ, vNormal );\n"
|
||||
" normal = normalize( normal );\n"
|
||||
"\n"
|
||||
" float3 tangent;\n"
|
||||
" tangent.x = dot3( matX, vTangent );\n"
|
||||
" tangent.y = dot3( matY, vTangent );\n"
|
||||
" tangent.z = dot3( matZ, vTangent );\n"
|
||||
" tangent = normalize( tangent );\n"
|
||||
"\n"
|
||||
" float3 bitangent;\n"
|
||||
" bitangent.x = dot3( matX, vBitangent );\n"
|
||||
" bitangent.y = dot3( matY, vBitangent );\n"
|
||||
" bitangent.z = dot3( matZ, vBitangent );\n"
|
||||
" bitangent = normalize( bitangent );\n"
|
||||
"\n"
|
||||
" float4 modelPosition;\n"
|
||||
" modelPosition.x = dot4( matX, vertex.position );\n"
|
||||
" modelPosition.y = dot4( matY, vertex.position );\n"
|
||||
" modelPosition.z = dot4( matZ, vertex.position );\n"
|
||||
" modelPosition.w = 1.0;\n"
|
||||
"\n"
|
||||
"#else\n"
|
||||
" float4 modelPosition = vertex.position;\n"
|
||||
" float3 normal = vNormal.xyz;\n"
|
||||
" float3 tangent = vTangent.xyz;\n"
|
||||
" float3 bitangent = vBitangent.xyz;\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
" result.position.x = dot4( modelPosition, rpMVPmatrixX );\n"
|
||||
" result.position.y = dot4( modelPosition, rpMVPmatrixY );\n"
|
||||
" result.position.z = dot4( modelPosition, rpMVPmatrixZ );\n"
|
||||
" result.position.w = dot4( modelPosition, rpMVPmatrixW );\n"
|
||||
"\n"
|
||||
" float4 defaultTexCoord = float4( 0.0f, 0.5f, 0.0f, 1.0f );\n"
|
||||
"\n"
|
||||
" //calculate vector to light\n"
|
||||
" //float4 toLight = rpLocalLightOrigin;\n"
|
||||
" float4 toLight = normalize( float4( 0.0f, 0.5f, 1.0f, 1.0f ) );\n"
|
||||
"\n"
|
||||
" //--------------------------------------------------------------\n"
|
||||
"\n"
|
||||
"\n"
|
||||
" //# textures 0 takes the base coordinates by the texture matrix\n"
|
||||
" result.texcoord0 = defaultTexCoord;\n"
|
||||
" result.texcoord0.x = dot4( vertex.texcoord.xy, rpBumpMatrixS );\n"
|
||||
" result.texcoord0.y = dot4( vertex.texcoord.xy, rpBumpMatrixT );\n"
|
||||
"\n"
|
||||
" //# textures 1 takes the base coordinates by the texture matrix\n"
|
||||
" result.texcoord1 = defaultTexCoord;\n"
|
||||
" result.texcoord1.x = dot4( vertex.texcoord.xy, rpDiffuseMatrixS );\n"
|
||||
" result.texcoord1.y = dot4( vertex.texcoord.xy, rpDiffuseMatrixT );\n"
|
||||
"\n"
|
||||
" //# textures 2 takes the base coordinates by the texture matrix\n"
|
||||
" result.texcoord2 = defaultTexCoord;\n"
|
||||
" result.texcoord2.x = dot4( vertex.texcoord.xy, rpSpecularMatrixS );\n"
|
||||
" result.texcoord2.y = dot4( vertex.texcoord.xy, rpSpecularMatrixT );\n"
|
||||
"\n"
|
||||
" //# calculate normalized vector to viewer in R1\n"
|
||||
" //result.texcoord3 = modelPosition;\n"
|
||||
"\n"
|
||||
" float4 toEye = normalize( rpLocalViewOrigin - modelPosition );\n"
|
||||
"\n"
|
||||
" result.texcoord3.x = dot3( toEye, rpModelMatrixX );\n"
|
||||
" result.texcoord3.y = dot3( toEye, rpModelMatrixY );\n"
|
||||
" result.texcoord3.z = dot3( toEye, rpModelMatrixZ );\n"
|
||||
"\n"
|
||||
" result.texcoord4.x = dot3( tangent, rpModelMatrixX );\n"
|
||||
" result.texcoord5.x = dot3( tangent, rpModelMatrixY );\n"
|
||||
" result.texcoord6.x = dot3( tangent, rpModelMatrixZ );\n"
|
||||
"\n"
|
||||
" result.texcoord4.y = dot3( bitangent, rpModelMatrixX );\n"
|
||||
" result.texcoord5.y = dot3( bitangent, rpModelMatrixY );\n"
|
||||
" result.texcoord6.y = dot3( bitangent, rpModelMatrixZ );\n"
|
||||
"\n"
|
||||
" result.texcoord4.z = dot3( normal, rpModelMatrixX );\n"
|
||||
" result.texcoord5.z = dot3( normal, rpModelMatrixY );\n"
|
||||
" result.texcoord6.z = dot3( normal, rpModelMatrixZ );\n"
|
||||
"\n"
|
||||
" float4 worldPosition;\n"
|
||||
" worldPosition.x = dot4( modelPosition, rpModelMatrixX );\n"
|
||||
" worldPosition.y = dot4( modelPosition, rpModelMatrixY );\n"
|
||||
" worldPosition.z = dot4( modelPosition, rpModelMatrixZ );\n"
|
||||
" worldPosition.w = dot4( modelPosition, rpModelMatrixW );\n"
|
||||
" result.texcoord7 = worldPosition;\n"
|
||||
"\n"
|
||||
"#if defined( USE_GPU_SKINNING )\n"
|
||||
" // for joint transformation of the tangent space, we use color and\n"
|
||||
" // color2 for weighting information, so hopefully there aren't any\n"
|
||||
" // effects that need vertex color...\n"
|
||||
" result.color = float4( 1.0f, 1.0f, 1.0f, 1.0f );\n"
|
||||
"#else\n"
|
||||
" //# generate the vertex color, which can be 1.0, color, or 1.0 - color\n"
|
||||
" //# for 1.0 : env[16] = 0, env[17] = 1\n"
|
||||
" //# for color : env[16] = 1, env[17] = 0\n"
|
||||
" //# for 1.0-color : env[16] = -1, env[17] = 1\n"
|
||||
" result.color = ( swizzleColor( vertex.color ) * rpVertexColorModulate ) + rpVertexColorAdd;\n"
|
||||
"#endif\n"
|
||||
"}\n"
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
"renderprogs/builtin/lighting/interaction.ps.hlsl",
|
||||
"/*\n"
|
||||
|
|
|
@ -549,6 +549,22 @@ void R_RenderView( viewDef_t* parms )
|
|||
tr.viewDef->irradianceImage = globalImages->defaultUACIrradianceCube;
|
||||
tr.viewDef->radianceImage = globalImages->defaultUACRadianceCube;
|
||||
|
||||
bool useLightGrid = tr.viewDef->useLightGrid = false;
|
||||
|
||||
portalArea_t* area = &tr.primaryWorld->portalAreas[tr.viewDef->areaNum];
|
||||
if( area->lightGrid.irradianceImage && !area->lightGrid.irradianceImage->IsDefaulted() )
|
||||
{
|
||||
tr.viewDef->irradianceImage = area->lightGrid.irradianceImage;
|
||||
tr.viewDef->useLightGrid = useLightGrid = true;
|
||||
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
tr.viewDef->lightGridOrigin[i] = area->lightGrid.lightGridOrigin[i];
|
||||
tr.viewDef->lightGridSize[i] = area->lightGrid.lightGridSize[i];
|
||||
tr.viewDef->lightGridBounds[i] = area->lightGrid.lightGridBounds[i];
|
||||
}
|
||||
}
|
||||
|
||||
for( viewEnvprobe_t* vProbe = tr.viewDef->viewEnvprobes; vProbe != NULL; vProbe = vProbe->next )
|
||||
{
|
||||
float dist = ( tr.viewDef->renderView.vieworg - vProbe->globalOrigin ).Length();
|
||||
|
@ -557,7 +573,11 @@ void R_RenderView( viewDef_t* parms )
|
|||
if( vProbe->irradianceImage->IsLoaded() && !vProbe->irradianceImage->IsDefaulted() )
|
||||
{
|
||||
tr.viewDef->globalProbeBounds = vProbe->globalProbeBounds;
|
||||
tr.viewDef->irradianceImage = vProbe->irradianceImage;
|
||||
|
||||
if( !useLightGrid )
|
||||
{
|
||||
tr.viewDef->irradianceImage = vProbe->irradianceImage;
|
||||
}
|
||||
tr.viewDef->radianceImage = vProbe->radianceImage;
|
||||
|
||||
bestDist = dist;
|
||||
|
|
Loading…
Reference in a new issue