Added Parallax Corrected Cubemaps
This commit is contained in:
parent
75bf03a4bc
commit
14f87c6263
9 changed files with 228 additions and 18 deletions
|
@ -207,7 +207,7 @@ char const *GetImpactDecal( C_BaseEntity *pEntity, int iMaterial, int iDamageTyp
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose: Perform custom effects based on the Decal index
|
// Purpose: Perform custom effects based on the Decal index
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static ConVar cl_new_impact_effects( "cl_new_impact_effects", "0" );
|
static ConVar cl_new_impact_effects( "cl_new_impact_effects", "1" );
|
||||||
|
|
||||||
struct ImpactEffect_t
|
struct ImpactEffect_t
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,6 +73,11 @@ BEGIN_VS_SHADER( LightmappedGeneric,
|
||||||
SHADER_PARAM( OUTLINESTART1, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner start value for outline")
|
SHADER_PARAM( OUTLINESTART1, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner start value for outline")
|
||||||
SHADER_PARAM( OUTLINEEND0, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner end value for outline")
|
SHADER_PARAM( OUTLINEEND0, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner end value for outline")
|
||||||
SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline")
|
SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline")
|
||||||
|
// Parallax cubemaps
|
||||||
|
SHADER_PARAM( ENVMAPPARALLAXOBB1, SHADER_PARAM_TYPE_VEC4, "[1 0 0 0]", "The first line of the parallax correction OBB matrix" )
|
||||||
|
SHADER_PARAM( ENVMAPPARALLAXOBB2, SHADER_PARAM_TYPE_VEC4, "[0 1 0 0]", "The second line of the parallax correction OBB matrix" )
|
||||||
|
SHADER_PARAM( ENVMAPPARALLAXOBB3, SHADER_PARAM_TYPE_VEC4, "[0 0 1 0]", "The third line of the parallax correction OBB matrix" )
|
||||||
|
SHADER_PARAM( ENVMAPORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "The world space position of the env_cubemap being corrected" )
|
||||||
END_SHADER_PARAMS
|
END_SHADER_PARAMS
|
||||||
|
|
||||||
void SetupVars( LightmappedGeneric_DX9_Vars_t& info )
|
void SetupVars( LightmappedGeneric_DX9_Vars_t& info )
|
||||||
|
@ -134,6 +139,12 @@ END_SHADER_PARAMS
|
||||||
info.m_nOutlineStart1 = OUTLINESTART1;
|
info.m_nOutlineStart1 = OUTLINESTART1;
|
||||||
info.m_nOutlineEnd0 = OUTLINEEND0;
|
info.m_nOutlineEnd0 = OUTLINEEND0;
|
||||||
info.m_nOutlineEnd1 = OUTLINEEND1;
|
info.m_nOutlineEnd1 = OUTLINEEND1;
|
||||||
|
|
||||||
|
// Parallax cubemaps
|
||||||
|
info.m_nEnvmapParallaxObb1 = ENVMAPPARALLAXOBB1;
|
||||||
|
info.m_nEnvmapParallaxObb2 = ENVMAPPARALLAXOBB2;
|
||||||
|
info.m_nEnvmapParallaxObb3 = ENVMAPPARALLAXOBB3;
|
||||||
|
info.m_nEnvmapOrigin = ENVMAPORIGIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHADER_FALLBACK
|
SHADER_FALLBACK
|
||||||
|
|
|
@ -58,6 +58,13 @@ public:
|
||||||
|
|
||||||
void InitParamsLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, LightmappedGeneric_DX9_Vars_t &info )
|
void InitParamsLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, LightmappedGeneric_DX9_Vars_t &info )
|
||||||
{
|
{
|
||||||
|
// Parallax cubemaps
|
||||||
|
// Cubemap parallax correction requires all 4 lines (if the 2nd, 3rd, or 4th are undef, undef the first one (checking done on first var)
|
||||||
|
if ( !( params[info.m_nEnvmapParallaxObb2]->IsDefined() && params[info.m_nEnvmapParallaxObb3]->IsDefined() && params[info.m_nEnvmapOrigin]->IsDefined() ) )
|
||||||
|
{
|
||||||
|
params[info.m_nEnvmapParallaxObb1]->SetUndefined();
|
||||||
|
}
|
||||||
|
|
||||||
if ( g_pHardwareConfig->SupportsBorderColor() )
|
if ( g_pHardwareConfig->SupportsBorderColor() )
|
||||||
{
|
{
|
||||||
params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" );
|
params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" );
|
||||||
|
@ -313,6 +320,8 @@ void DrawLightmappedGeneric_DX9_Internal(CBaseVSShader *pShader, IMaterialVar**
|
||||||
(info.m_nBlendModulateTexture != -1) &&
|
(info.m_nBlendModulateTexture != -1) &&
|
||||||
(params[info.m_nBlendModulateTexture]->IsTexture() );
|
(params[info.m_nBlendModulateTexture]->IsTexture() );
|
||||||
bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK );
|
bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK );
|
||||||
|
// Parallax cubemaps
|
||||||
|
bool hasParallaxCorrection = params[info.m_nEnvmapParallaxObb1]->IsDefined();
|
||||||
|
|
||||||
if ( hasFlashlight && !IsX360() )
|
if ( hasFlashlight && !IsX360() )
|
||||||
{
|
{
|
||||||
|
@ -574,6 +583,8 @@ void DrawLightmappedGeneric_DX9_Internal(CBaseVSShader *pShader, IMaterialVar**
|
||||||
#ifdef _X360
|
#ifdef _X360
|
||||||
SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight);
|
SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight);
|
||||||
#endif
|
#endif
|
||||||
|
// Parallax cubemaps enabled for 2_0b and onwards
|
||||||
|
SET_STATIC_PIXEL_SHADER_COMBO( PARALLAXCORRECT, hasParallaxCorrection );
|
||||||
SET_STATIC_PIXEL_SHADER( lightmappedgeneric_ps20b );
|
SET_STATIC_PIXEL_SHADER( lightmappedgeneric_ps20b );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -601,6 +612,8 @@ void DrawLightmappedGeneric_DX9_Internal(CBaseVSShader *pShader, IMaterialVar**
|
||||||
SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode );
|
SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode );
|
||||||
SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, 0 ); // No normal compression with ps_2_0 (yikes!)
|
SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, 0 ); // No normal compression with ps_2_0 (yikes!)
|
||||||
SET_STATIC_PIXEL_SHADER_COMBO( NORMALMASK_DECODE_MODE, 0 ); // No normal compression with ps_2_0
|
SET_STATIC_PIXEL_SHADER_COMBO( NORMALMASK_DECODE_MODE, 0 ); // No normal compression with ps_2_0
|
||||||
|
// Parallax cubemaps
|
||||||
|
SET_STATIC_PIXEL_SHADER_COMBO( PARALLAXCORRECT, 0 ); // No parallax cubemaps with ps_2_0 :(
|
||||||
SET_STATIC_PIXEL_SHADER( lightmappedgeneric_ps20 );
|
SET_STATIC_PIXEL_SHADER( lightmappedgeneric_ps20 );
|
||||||
}
|
}
|
||||||
// HACK HACK HACK - enable alpha writes all the time so that we have them for
|
// HACK HACK HACK - enable alpha writes all the time so that we have them for
|
||||||
|
@ -857,6 +870,28 @@ void DrawLightmappedGeneric_DX9_Internal(CBaseVSShader *pShader, IMaterialVar**
|
||||||
pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, info.m_nBlendModulateTexture, -1 );
|
pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, info.m_nBlendModulateTexture, -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parallax cubemaps
|
||||||
|
if ( hasParallaxCorrection )
|
||||||
|
{
|
||||||
|
pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 21, params[info.m_nEnvmapOrigin]->GetVecValue() );
|
||||||
|
|
||||||
|
float *vecs[3];
|
||||||
|
vecs[0] = const_cast<float *>( params[info.m_nEnvmapParallaxObb1]->GetVecValue() );
|
||||||
|
vecs[1] = const_cast<float *>( params[info.m_nEnvmapParallaxObb2]->GetVecValue() );
|
||||||
|
vecs[2] = const_cast<float *>( params[info.m_nEnvmapParallaxObb3]->GetVecValue() );
|
||||||
|
float matrix[4][4];
|
||||||
|
for ( int i = 0; i < 3; i++ )
|
||||||
|
{
|
||||||
|
for ( int j = 0; j < 4; j++ )
|
||||||
|
{
|
||||||
|
matrix[i][j] = vecs[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
matrix[3][0] = matrix[3][1] = matrix[3][2] = 0;
|
||||||
|
matrix[3][3] = 1;
|
||||||
|
pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 22, &matrix[0][0], 4 );
|
||||||
|
}
|
||||||
|
|
||||||
pContextData->m_SemiStaticCmdsOut.End();
|
pContextData->m_SemiStaticCmdsOut.End();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,11 @@ struct LightmappedGeneric_DX9_Vars_t
|
||||||
int m_nOutlineStart1;
|
int m_nOutlineStart1;
|
||||||
int m_nOutlineEnd0;
|
int m_nOutlineEnd0;
|
||||||
int m_nOutlineEnd1;
|
int m_nOutlineEnd1;
|
||||||
|
// Parallax cubemaps
|
||||||
|
int m_nEnvmapParallaxObb1;
|
||||||
|
int m_nEnvmapParallaxObb2;
|
||||||
|
int m_nEnvmapParallaxObb3;
|
||||||
|
int m_nEnvmapOrigin;
|
||||||
};
|
};
|
||||||
|
|
||||||
void InitParamsLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, LightmappedGeneric_DX9_Vars_t &info );
|
void InitParamsLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, LightmappedGeneric_DX9_Vars_t &info );
|
||||||
|
|
|
@ -100,7 +100,11 @@ const float4 g_FlashlightAttenuationFactors : register( c13 );
|
||||||
const float3 g_FlashlightPos : register( c14 );
|
const float3 g_FlashlightPos : register( c14 );
|
||||||
const float4x4 g_FlashlightWorldToTexture : register( c15 ); // through c18
|
const float4x4 g_FlashlightWorldToTexture : register( c15 ); // through c18
|
||||||
const float4 g_ShadowTweaks : register( c19 );
|
const float4 g_ShadowTweaks : register( c19 );
|
||||||
|
// Parallax cubemaps
|
||||||
|
#if ( PARALLAXCORRECT )
|
||||||
|
const float3 g_CubemapPos : register( c21 );
|
||||||
|
const float4x4 g_ObbMatrix : register( c22 ); // Through c25
|
||||||
|
#endif
|
||||||
|
|
||||||
sampler BaseTextureSampler : register( s0 );
|
sampler BaseTextureSampler : register( s0 );
|
||||||
sampler LightmapSampler : register( s1 );
|
sampler LightmapSampler : register( s1 );
|
||||||
|
@ -530,7 +534,24 @@ HALF4 main( PS_INPUT i ) : COLOR
|
||||||
HALF fresnel = 1.0 - dot( worldSpaceNormal, eyeVect );
|
HALF fresnel = 1.0 - dot( worldSpaceNormal, eyeVect );
|
||||||
fresnel = pow( fresnel, 5.0 );
|
fresnel = pow( fresnel, 5.0 );
|
||||||
fresnel = fresnel * g_OneMinusFresnelReflection + g_FresnelReflection;
|
fresnel = fresnel * g_OneMinusFresnelReflection + g_FresnelReflection;
|
||||||
|
// Parallax correction (2_0b and beyond)
|
||||||
|
// Adapted from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
|
||||||
|
#if !( defined( SHADER_MODEL_PS_1_1 ) || defined( SHADER_MODEL_PS_1_4 ) || defined( SHADER_MODEL_PS_2_0 ) )
|
||||||
|
#if ( PARALLAXCORRECT )
|
||||||
|
float3 worldPos = i.worldPos_projPosZ.xyz;
|
||||||
|
float3 positionLS = mul( float4( worldPos, 1 ), g_ObbMatrix );
|
||||||
|
float3 rayLS = mul( reflectVect, (float3x3)g_ObbMatrix );
|
||||||
|
|
||||||
|
float3 firstPlaneIntersect = ( float3( 1.0f, 1.0f, 1.0f ) - positionLS ) / rayLS;
|
||||||
|
float3 secondPlaneIntersect = ( -positionLS ) / rayLS;
|
||||||
|
float3 furthestPlane = max( firstPlaneIntersect, secondPlaneIntersect );
|
||||||
|
float distance = min( furthestPlane.x, min( furthestPlane.y, furthestPlane.z ) );
|
||||||
|
|
||||||
|
// Use distance in WS directly to recover intersection
|
||||||
|
float3 intersectPositionWS = worldPos + reflectVect * distance;
|
||||||
|
reflectVect = intersectPositionWS - g_CubemapPos;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect );
|
specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect );
|
||||||
specularLighting *= specularFactor;
|
specularLighting *= specularFactor;
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
// STATIC: "NORMALMASK_DECODE_MODE" "0..0" [PC]
|
// STATIC: "NORMALMASK_DECODE_MODE" "0..0" [PC]
|
||||||
// STATIC: "DETAIL_BLEND_MODE" "0..11"
|
// STATIC: "DETAIL_BLEND_MODE" "0..11"
|
||||||
// STATIC: "FLASHLIGHT" "0..1" [ps20b] [XBOX]
|
// STATIC: "FLASHLIGHT" "0..1" [ps20b] [XBOX]
|
||||||
|
// STATIC: "PARALLAXCORRECT" "0..1"
|
||||||
|
|
||||||
// DYNAMIC: "FASTPATHENVMAPCONTRAST" "0..1"
|
// DYNAMIC: "FASTPATHENVMAPCONTRAST" "0..1"
|
||||||
// DYNAMIC: "FASTPATH" "0..1"
|
// DYNAMIC: "FASTPATH" "0..1"
|
||||||
|
@ -54,6 +55,8 @@
|
||||||
// SKIP: ($DETAIL_BLEND_MODE == 8 ) || ($DETAIL_BLEND_MODE == 9 )
|
// SKIP: ($DETAIL_BLEND_MODE == 8 ) || ($DETAIL_BLEND_MODE == 9 )
|
||||||
// SKIP ($DETAIL_BLEND_MODE == 10 ) && ($BUMPMAP == 0 )
|
// SKIP ($DETAIL_BLEND_MODE == 10 ) && ($BUMPMAP == 0 )
|
||||||
// SKIP ($DETAIL_BLEND_MODE == 11 ) && ($BUMPMAP != 0 )
|
// SKIP ($DETAIL_BLEND_MODE == 11 ) && ($BUMPMAP != 0 )
|
||||||
|
// SKIP: $PARALLAXCORRECT && !$CUBEMAP
|
||||||
|
// SKIP: $PARALLAXCORRECT [ps20]
|
||||||
|
|
||||||
#include "lightmappedgeneric_ps2_3_x.h"
|
#include "lightmappedgeneric_ps2_3_x.h"
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ struct CubemapSideData_t
|
||||||
};
|
};
|
||||||
|
|
||||||
static CubemapSideData_t s_aCubemapSideData[MAX_MAP_BRUSHSIDES];
|
static CubemapSideData_t s_aCubemapSideData[MAX_MAP_BRUSHSIDES];
|
||||||
|
char *g_pParallaxObbStrs[MAX_MAP_CUBEMAPSAMPLES];
|
||||||
|
|
||||||
|
|
||||||
inline bool SideHasCubemapAndWasntManuallyReferenced( int iSide )
|
inline bool SideHasCubemapAndWasntManuallyReferenced( int iSide )
|
||||||
|
@ -85,8 +85,10 @@ inline bool SideHasCubemapAndWasntManuallyReferenced( int iSide )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Cubemap_InsertSample( const Vector& origin, int size )
|
void Cubemap_InsertSample( const Vector &origin, int size, char *pParallaxObbStr = "" )
|
||||||
{
|
{
|
||||||
|
g_pParallaxObbStrs[g_nCubemapSamples] = pParallaxObbStr;
|
||||||
|
|
||||||
dcubemapsample_t *pSample = &g_CubemapSamples[g_nCubemapSamples];
|
dcubemapsample_t *pSample = &g_CubemapSamples[g_nCubemapSamples];
|
||||||
pSample->origin[0] = ( int )origin[0];
|
pSample->origin[0] = ( int )origin[0];
|
||||||
pSample->origin[1] = ( int )origin[1];
|
pSample->origin[1] = ( int )origin[1];
|
||||||
|
@ -528,7 +530,7 @@ static void GeneratePatchedName( const char *pMaterialName, const PatchInfo_t &i
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Patches the $envmap for a material and all its dependents, returns true if any patching happened
|
// Patches the $envmap for a material and all its dependents, returns true if any patching happened
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, const PatchInfo_t &info, const char *pCubemapTexture )
|
static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, const PatchInfo_t &info, const char *pCubemapTexture, const char *pParallaxObbMatrix = "" )
|
||||||
{
|
{
|
||||||
// Do *NOT* patch the material if there is an $envmap specified and it's not 'env_cubemap'
|
// Do *NOT* patch the material if there is an $envmap specified and it's not 'env_cubemap'
|
||||||
|
|
||||||
|
@ -546,7 +548,7 @@ static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, cons
|
||||||
const char *pDependentMaterial = FindDependentMaterial( pMaterialName, &pDependentMaterialVar );
|
const char *pDependentMaterial = FindDependentMaterial( pMaterialName, &pDependentMaterialVar );
|
||||||
if ( pDependentMaterial )
|
if ( pDependentMaterial )
|
||||||
{
|
{
|
||||||
bDependentMaterialPatched = PatchEnvmapForMaterialAndDependents( pDependentMaterial, info, pCubemapTexture );
|
bDependentMaterialPatched = PatchEnvmapForMaterialAndDependents( pDependentMaterial, info, pCubemapTexture, pParallaxObbMatrix );
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have neither to patch, we're done
|
// If we have neither to patch, we're done
|
||||||
|
@ -557,7 +559,7 @@ static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, cons
|
||||||
char pPatchedMaterialName[1024];
|
char pPatchedMaterialName[1024];
|
||||||
GeneratePatchedName( pMaterialName, info, true, pPatchedMaterialName, 1024 );
|
GeneratePatchedName( pMaterialName, info, true, pPatchedMaterialName, 1024 );
|
||||||
|
|
||||||
MaterialPatchInfo_t pPatchInfo[2];
|
MaterialPatchInfo_t pPatchInfo[6];
|
||||||
int nPatchCount = 0;
|
int nPatchCount = 0;
|
||||||
if ( bShouldPatchEnvCubemap )
|
if ( bShouldPatchEnvCubemap )
|
||||||
{
|
{
|
||||||
|
@ -578,7 +580,30 @@ static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, cons
|
||||||
++nPatchCount;
|
++nPatchCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateMaterialPatch( pMaterialName, pPatchedMaterialName, nPatchCount, pPatchInfo, PATCH_REPLACE );
|
// Parallax cubemap matrix
|
||||||
|
CUtlVector<char *> matRowList;
|
||||||
|
if ( pParallaxObbMatrix[0] != '\0' )
|
||||||
|
{
|
||||||
|
V_SplitString( pParallaxObbMatrix, ";", matRowList );
|
||||||
|
|
||||||
|
pPatchInfo[nPatchCount].m_pKey = "$envMapParallaxOBB1";
|
||||||
|
pPatchInfo[nPatchCount].m_pValue = matRowList[0];
|
||||||
|
++nPatchCount;
|
||||||
|
pPatchInfo[nPatchCount].m_pKey = "$envMapParallaxOBB2";
|
||||||
|
pPatchInfo[nPatchCount].m_pValue = matRowList[1];
|
||||||
|
++nPatchCount;
|
||||||
|
pPatchInfo[nPatchCount].m_pKey = "$envMapParallaxOBB3";
|
||||||
|
pPatchInfo[nPatchCount].m_pValue = matRowList[2];
|
||||||
|
++nPatchCount;
|
||||||
|
pPatchInfo[nPatchCount].m_pKey = "$envMapOrigin";
|
||||||
|
pPatchInfo[nPatchCount].m_pValue = matRowList[3];
|
||||||
|
++nPatchCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateMaterialPatch( pMaterialName, pPatchedMaterialName, nPatchCount, pPatchInfo, PATCH_INSERT );
|
||||||
|
|
||||||
|
// Clean up parallax stuff
|
||||||
|
matRowList.PurgeAndDeleteElements();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -597,7 +622,7 @@ static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, cons
|
||||||
// default (skybox) cubemap into this file so the cubemap doesn't have the pink checkerboard at
|
// default (skybox) cubemap into this file so the cubemap doesn't have the pink checkerboard at
|
||||||
// runtime before they run buildcubemaps.
|
// runtime before they run buildcubemaps.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static int Cubemap_CreateTexInfo( int originalTexInfo, int origin[3] )
|
static int Cubemap_CreateTexInfo( int originalTexInfo, int origin[3], int cubemapIndex )
|
||||||
{
|
{
|
||||||
// Don't make cubemap tex infos for nodes
|
// Don't make cubemap tex infos for nodes
|
||||||
if ( originalTexInfo == TEXINFO_NODE )
|
if ( originalTexInfo == TEXINFO_NODE )
|
||||||
|
@ -638,9 +663,16 @@ static int Cubemap_CreateTexInfo( int originalTexInfo, int origin[3] )
|
||||||
char pTextureName[1024];
|
char pTextureName[1024];
|
||||||
GeneratePatchedName( "c", info, false, pTextureName, 1024 );
|
GeneratePatchedName( "c", info, false, pTextureName, 1024 );
|
||||||
|
|
||||||
|
// Append origin info if this cubemap has a parallax OBB
|
||||||
|
char originAppendedString[1024] = "";
|
||||||
|
if ( g_pParallaxObbStrs[cubemapIndex][0] != '\0' )
|
||||||
|
{
|
||||||
|
Q_snprintf( originAppendedString, 1024, "%s;[%d %d %d]", g_pParallaxObbStrs[cubemapIndex], origin[0], origin[1], origin[2] );
|
||||||
|
}
|
||||||
|
|
||||||
// Hook the texture into the material and all dependent materials
|
// Hook the texture into the material and all dependent materials
|
||||||
// but if no hooking was necessary, exit out
|
// but if no hooking was necessary, exit out
|
||||||
if ( !PatchEnvmapForMaterialAndDependents( pMaterialName, info, pTextureName ) )
|
if ( !PatchEnvmapForMaterialAndDependents( pMaterialName, info, pTextureName, originAppendedString ) )
|
||||||
return originalTexInfo;
|
return originalTexInfo;
|
||||||
|
|
||||||
// Store off the name of the cubemap that we need to create since we successfully patched
|
// Store off the name of the cubemap that we need to create since we successfully patched
|
||||||
|
@ -730,7 +762,7 @@ void Cubemap_FixupBrushSidesMaterials( void )
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[cubemapID].origin );
|
pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[cubemapID].origin, cubemapID );
|
||||||
if ( pSide->pMapDisp )
|
if ( pSide->pMapDisp )
|
||||||
{
|
{
|
||||||
pSide->pMapDisp->face.texinfo = pSide->texinfo;
|
pSide->pMapDisp->face.texinfo = pSide->texinfo;
|
||||||
|
@ -946,7 +978,7 @@ void Cubemap_AttachDefaultCubemapToSpecularSides( void )
|
||||||
Assert( pSide->texinfo == pSide->pMapDisp->face.texinfo );
|
Assert( pSide->texinfo == pSide->pMapDisp->face.texinfo );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[iCubemap].origin );
|
pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[iCubemap].origin, iCubemap );
|
||||||
if ( pSide->pMapDisp )
|
if ( pSide->pMapDisp )
|
||||||
{
|
{
|
||||||
pSide->pMapDisp->face.texinfo = pSide->texinfo;
|
pSide->pMapDisp->face.texinfo = pSide->texinfo;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
// $NoKeywords: $
|
// $NoKeywords: $
|
||||||
//=============================================================================//
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "matrixinvert.h"
|
||||||
#include "vbsp.h"
|
#include "vbsp.h"
|
||||||
#include "map_shared.h"
|
#include "map_shared.h"
|
||||||
#include "disp_vbsp.h"
|
#include "disp_vbsp.h"
|
||||||
|
@ -1618,16 +1619,96 @@ ChunkFileResult_t CMapFile::LoadEntityCallback(CChunkFile *pFile, int nParam)
|
||||||
if( ( g_nDXLevel == 0 ) || ( g_nDXLevel >= 70 ) )
|
if( ( g_nDXLevel == 0 ) || ( g_nDXLevel >= 70 ) )
|
||||||
{
|
{
|
||||||
const char* pSideListStr = ValueForKey( mapent, "sides" );
|
const char* pSideListStr = ValueForKey( mapent, "sides" );
|
||||||
|
char *pParallaxObbStr = ValueForKey( mapent, "parallaxobb" );
|
||||||
int size;
|
int size;
|
||||||
size = IntForKey( mapent, "cubemapsize" );
|
size = IntForKey( mapent, "cubemapsize" );
|
||||||
Cubemap_InsertSample( mapent->origin, size );
|
Cubemap_InsertSample( mapent->origin, size, pParallaxObbStr );
|
||||||
Cubemap_SaveBrushSides( pSideListStr );
|
|
||||||
}
|
}
|
||||||
// clear out this entity
|
// clear out this entity
|
||||||
mapent->epairs = NULL;
|
mapent->epairs = NULL;
|
||||||
return(ChunkFile_Ok);
|
return(ChunkFile_Ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// parallax_obb brushes are removed after the transformation matrix is found and saved into
|
||||||
|
// the entity's data (ent will be removed after data transferred to patched materials)
|
||||||
|
//
|
||||||
|
if ( !strcmp( "parallax_obb", pClassName ) )
|
||||||
|
{
|
||||||
|
matrix3x4_t obbMatrix, invObbMatrix;
|
||||||
|
SetIdentityMatrix( obbMatrix );
|
||||||
|
SetIdentityMatrix( invObbMatrix );
|
||||||
|
|
||||||
|
// Get corner and its 3 edges (scaled, local x, y, and z axes)
|
||||||
|
mapbrush_t *brush = &mapbrushes[mapent->firstbrush];
|
||||||
|
Vector corner, x, y, z;
|
||||||
|
|
||||||
|
// Find first valid winding (with these whiles, if not enough valid windings then identity matrix is passed through to VMTs)
|
||||||
|
int i = 0;
|
||||||
|
while ( i < brush->numsides )
|
||||||
|
{
|
||||||
|
winding_t *wind = brush->original_sides[i].winding;
|
||||||
|
if ( !wind )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
corner = wind->p[0];
|
||||||
|
y = wind->p[1] - corner;
|
||||||
|
z = wind->p[3] - corner;
|
||||||
|
x = CrossProduct( y, z ).Normalized();
|
||||||
|
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip second valid winding (opposite face from first, unusable for finding Z's length)
|
||||||
|
while ( i < brush->numsides )
|
||||||
|
{
|
||||||
|
winding_t *wind = brush->original_sides[i].winding;
|
||||||
|
if ( !wind )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find third valid winding
|
||||||
|
while ( i < brush->numsides )
|
||||||
|
{
|
||||||
|
winding_t *wind = brush->original_sides[i].winding;
|
||||||
|
if ( !wind )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find length of X
|
||||||
|
// Start with diagonal, then scale X by the projection of diag onto X
|
||||||
|
Vector diag = wind->p[0] - wind->p[2];
|
||||||
|
x *= abs( DotProduct( diag, x ) );
|
||||||
|
|
||||||
|
// Build transformation matrix (what is needed to turn a [0,0,0] - [1,1,1] cube into this brush)
|
||||||
|
MatrixSetColumn( x, 0, obbMatrix );
|
||||||
|
MatrixSetColumn( y, 1, obbMatrix );
|
||||||
|
MatrixSetColumn( z, 2, obbMatrix );
|
||||||
|
MatrixSetColumn( corner, 3, obbMatrix );
|
||||||
|
|
||||||
|
// Find inverse (we need the world to local matrix, "transformationmatrix" is kind of a misnomer)
|
||||||
|
MatrixInversion( obbMatrix, invObbMatrix );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char szMatrix[1024];
|
||||||
|
Q_snprintf( szMatrix, 1024, "[%f %f %f %f];[%f %f %f %f];[%f %f %f %f]", invObbMatrix[0][0], invObbMatrix[0][1], invObbMatrix[0][2], invObbMatrix[0][3], invObbMatrix[1][0], invObbMatrix[1][1], invObbMatrix[1][2], invObbMatrix[1][3], invObbMatrix[2][0], invObbMatrix[2][1], invObbMatrix[2][2], invObbMatrix[2][3] );
|
||||||
|
SetKeyValue( mapent, "transformationmatrix", szMatrix );
|
||||||
|
|
||||||
|
return ( ChunkFile_Ok );
|
||||||
|
}
|
||||||
|
|
||||||
if ( !strcmp( "test_sidelist", pClassName ) )
|
if ( !strcmp( "test_sidelist", pClassName ) )
|
||||||
{
|
{
|
||||||
ConvertSideList(mapent, "sides");
|
ConvertSideList(mapent, "sides");
|
||||||
|
@ -2611,6 +2692,28 @@ bool LoadMapFile( const char *pszFileName )
|
||||||
|
|
||||||
if ((eResult == ChunkFile_Ok) || (eResult == ChunkFile_EOF))
|
if ((eResult == ChunkFile_Ok) || (eResult == ChunkFile_EOF))
|
||||||
{
|
{
|
||||||
|
// Fill out parallax obb matrix array
|
||||||
|
for ( int i = 0; i < g_nCubemapSamples; i++ )
|
||||||
|
{
|
||||||
|
if ( g_pParallaxObbStrs[i][0] != '\0' )
|
||||||
|
{
|
||||||
|
entity_t *obbEnt = EntityByName( g_pParallaxObbStrs[i] );
|
||||||
|
g_pParallaxObbStrs[i] = ValueForKey( obbEnt, "transformationmatrix" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove parallax_obb entities (in a nice slow linear search)
|
||||||
|
for ( int i = 0; i < g_MainMap->num_entities; i++ )
|
||||||
|
{
|
||||||
|
entity_t *mapent = &g_MainMap->entities[i];
|
||||||
|
const char *pClassName = ValueForKey( mapent, "classname" );
|
||||||
|
if ( !strcmp( "parallax_obb", pClassName ) )
|
||||||
|
{
|
||||||
|
mapent->numbrushes = 0;
|
||||||
|
mapent->epairs = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update the overlay/side list(s).
|
// Update the overlay/side list(s).
|
||||||
Overlay_UpdateSideLists( g_LoadingMap->m_StartMapOverlays );
|
Overlay_UpdateSideLists( g_LoadingMap->m_StartMapOverlays );
|
||||||
OverlayTransition_UpdateSideLists( g_LoadingMap->m_StartMapWaterOverlays );
|
OverlayTransition_UpdateSideLists( g_LoadingMap->m_StartMapWaterOverlays );
|
||||||
|
|
|
@ -607,7 +607,8 @@ void SaveVertexNormals( void );
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// cubemap.cpp
|
// cubemap.cpp
|
||||||
void Cubemap_InsertSample( const Vector& origin, int size );
|
extern char *g_pParallaxObbStrs[MAX_MAP_CUBEMAPSAMPLES];
|
||||||
|
void Cubemap_InsertSample( const Vector &origin, int size, char *pParallaxObbStr );
|
||||||
void Cubemap_CreateDefaultCubemaps( void );
|
void Cubemap_CreateDefaultCubemaps( void );
|
||||||
void Cubemap_SaveBrushSides( const char *pSideListStr );
|
void Cubemap_SaveBrushSides( const char *pSideListStr );
|
||||||
void Cubemap_FixupBrushSidesMaterials( void );
|
void Cubemap_FixupBrushSidesMaterials( void );
|
||||||
|
|
Loading…
Add table
Reference in a new issue