Add PBR support (#91)

* Add PBR support
* Fix physics props turning black
This commit is contained in:
LegendGuard 2022-08-10 16:41:01 +02:00 committed by GitHub
parent 08073ae622
commit a87918565a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 2481 additions and 2 deletions

View File

@ -12,6 +12,7 @@ Discord: https://discord.gg/hZRB7WMgGw
- [x] rewrite achivement system( to work without steam )
- [x] 64-bit support
- [x] VTF 7.5 support
- [x] PBR support
- [ ] improve performance
- [ ] fixing bugs
- [ ] dxvk-native support

View File

@ -20,11 +20,17 @@
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define PBR_CHANGE
IMPLEMENT_CLIENTCLASS_DT(C_PhysicsProp, DT_PhysicsProp, CPhysicsProp)
RecvPropBool( RECVINFO( m_bAwake ) ),
END_RECV_TABLE()
ConVar r_PhysPropStaticLighting( "r_PhysPropStaticLighting", "1" );
#ifdef PBR_CHANGE
ConVar r_PhysPropStaticLighting( "r_PhysPropStaticLighting", "0" );
#else
ConVar r_PhysPropStaticLighting( "r_PhysPropStaticLighting", "1" );
#endif
//-----------------------------------------------------------------------------

View File

@ -0,0 +1,287 @@
#include "shaderlib/cshader.h"
class pbr_ps20b_Static_Index
{
private:
int m_nFLASHLIGHT;
#ifdef _DEBUG
bool m_bFLASHLIGHT;
#endif
public:
void SetFLASHLIGHT( int i )
{
Assert( i >= 0 && i <= 1 );
m_nFLASHLIGHT = i;
#ifdef _DEBUG
m_bFLASHLIGHT = true;
#endif
}
void SetFLASHLIGHT( bool i )
{
m_nFLASHLIGHT = i ? 1 : 0;
#ifdef _DEBUG
m_bFLASHLIGHT = true;
#endif
}
private:
int m_nFLASHLIGHTDEPTHFILTERMODE;
#ifdef _DEBUG
bool m_bFLASHLIGHTDEPTHFILTERMODE;
#endif
public:
void SetFLASHLIGHTDEPTHFILTERMODE( int i )
{
Assert( i >= 0 && i <= 2 );
m_nFLASHLIGHTDEPTHFILTERMODE = i;
#ifdef _DEBUG
m_bFLASHLIGHTDEPTHFILTERMODE = true;
#endif
}
void SetFLASHLIGHTDEPTHFILTERMODE( bool i )
{
m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0;
#ifdef _DEBUG
m_bFLASHLIGHTDEPTHFILTERMODE = true;
#endif
}
private:
int m_nLIGHTMAPPED;
#ifdef _DEBUG
bool m_bLIGHTMAPPED;
#endif
public:
void SetLIGHTMAPPED( int i )
{
Assert( i >= 0 && i <= 1 );
m_nLIGHTMAPPED = i;
#ifdef _DEBUG
m_bLIGHTMAPPED = true;
#endif
}
void SetLIGHTMAPPED( bool i )
{
m_nLIGHTMAPPED = i ? 1 : 0;
#ifdef _DEBUG
m_bLIGHTMAPPED = true;
#endif
}
private:
int m_nEMISSIVE;
#ifdef _DEBUG
bool m_bEMISSIVE;
#endif
public:
void SetEMISSIVE( int i )
{
Assert( i >= 0 && i <= 1 );
m_nEMISSIVE = i;
#ifdef _DEBUG
m_bEMISSIVE = true;
#endif
}
void SetEMISSIVE( bool i )
{
m_nEMISSIVE = i ? 1 : 0;
#ifdef _DEBUG
m_bEMISSIVE = true;
#endif
}
private:
int m_nSPECULAR;
#ifdef _DEBUG
bool m_bSPECULAR;
#endif
public:
void SetSPECULAR( int i )
{
Assert( i >= 0 && i <= 1 );
m_nSPECULAR = i;
#ifdef _DEBUG
m_bSPECULAR = true;
#endif
}
void SetSPECULAR( bool i )
{
m_nSPECULAR = i ? 1 : 0;
#ifdef _DEBUG
m_bSPECULAR = true;
#endif
}
public:
pbr_ps20b_Static_Index( )
{
#ifdef _DEBUG
m_bFLASHLIGHT = false;
#endif // _DEBUG
m_nFLASHLIGHT = 0;
#ifdef _DEBUG
m_bFLASHLIGHTDEPTHFILTERMODE = false;
#endif // _DEBUG
m_nFLASHLIGHTDEPTHFILTERMODE = 0;
#ifdef _DEBUG
m_bLIGHTMAPPED = false;
#endif // _DEBUG
m_nLIGHTMAPPED = 0;
#ifdef _DEBUG
m_bEMISSIVE = false;
#endif // _DEBUG
m_nEMISSIVE = 0;
#ifdef _DEBUG
m_bSPECULAR = false;
#endif // _DEBUG
m_nSPECULAR = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllStaticVarsDefined = m_bFLASHLIGHT && m_bFLASHLIGHTDEPTHFILTERMODE && m_bLIGHTMAPPED && m_bEMISSIVE && m_bSPECULAR;
Assert( bAllStaticVarsDefined );
#endif // _DEBUG
return ( 80 * m_nFLASHLIGHT ) + ( 160 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 480 * m_nLIGHTMAPPED ) + ( 960 * m_nEMISSIVE ) + ( 1920 * m_nSPECULAR ) + 0;
}
};
#define shaderStaticTest_pbr_ps20b psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_LIGHTMAPPED + psh_forgot_to_set_static_EMISSIVE + psh_forgot_to_set_static_SPECULAR + 0
class pbr_ps20b_Dynamic_Index
{
private:
int m_nWRITEWATERFOGTODESTALPHA;
#ifdef _DEBUG
bool m_bWRITEWATERFOGTODESTALPHA;
#endif
public:
void SetWRITEWATERFOGTODESTALPHA( int i )
{
Assert( i >= 0 && i <= 1 );
m_nWRITEWATERFOGTODESTALPHA = i;
#ifdef _DEBUG
m_bWRITEWATERFOGTODESTALPHA = true;
#endif
}
void SetWRITEWATERFOGTODESTALPHA( bool i )
{
m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0;
#ifdef _DEBUG
m_bWRITEWATERFOGTODESTALPHA = true;
#endif
}
private:
int m_nPIXELFOGTYPE;
#ifdef _DEBUG
bool m_bPIXELFOGTYPE;
#endif
public:
void SetPIXELFOGTYPE( int i )
{
Assert( i >= 0 && i <= 1 );
m_nPIXELFOGTYPE = i;
#ifdef _DEBUG
m_bPIXELFOGTYPE = true;
#endif
}
void SetPIXELFOGTYPE( bool i )
{
m_nPIXELFOGTYPE = i ? 1 : 0;
#ifdef _DEBUG
m_bPIXELFOGTYPE = true;
#endif
}
private:
int m_nNUM_LIGHTS;
#ifdef _DEBUG
bool m_bNUM_LIGHTS;
#endif
public:
void SetNUM_LIGHTS( int i )
{
Assert( i >= 0 && i <= 4 );
m_nNUM_LIGHTS = i;
#ifdef _DEBUG
m_bNUM_LIGHTS = true;
#endif
}
void SetNUM_LIGHTS( bool i )
{
m_nNUM_LIGHTS = i ? 1 : 0;
#ifdef _DEBUG
m_bNUM_LIGHTS = true;
#endif
}
private:
int m_nWRITE_DEPTH_TO_DESTALPHA;
#ifdef _DEBUG
bool m_bWRITE_DEPTH_TO_DESTALPHA;
#endif
public:
void SetWRITE_DEPTH_TO_DESTALPHA( int i )
{
Assert( i >= 0 && i <= 1 );
m_nWRITE_DEPTH_TO_DESTALPHA = i;
#ifdef _DEBUG
m_bWRITE_DEPTH_TO_DESTALPHA = true;
#endif
}
void SetWRITE_DEPTH_TO_DESTALPHA( bool i )
{
m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0;
#ifdef _DEBUG
m_bWRITE_DEPTH_TO_DESTALPHA = true;
#endif
}
private:
int m_nFLASHLIGHTSHADOWS;
#ifdef _DEBUG
bool m_bFLASHLIGHTSHADOWS;
#endif
public:
void SetFLASHLIGHTSHADOWS( int i )
{
Assert( i >= 0 && i <= 1 );
m_nFLASHLIGHTSHADOWS = i;
#ifdef _DEBUG
m_bFLASHLIGHTSHADOWS = true;
#endif
}
void SetFLASHLIGHTSHADOWS( bool i )
{
m_nFLASHLIGHTSHADOWS = i ? 1 : 0;
#ifdef _DEBUG
m_bFLASHLIGHTSHADOWS = true;
#endif
}
public:
pbr_ps20b_Dynamic_Index()
{
#ifdef _DEBUG
m_bWRITEWATERFOGTODESTALPHA = false;
#endif // _DEBUG
m_nWRITEWATERFOGTODESTALPHA = 0;
#ifdef _DEBUG
m_bPIXELFOGTYPE = false;
#endif // _DEBUG
m_nPIXELFOGTYPE = 0;
#ifdef _DEBUG
m_bNUM_LIGHTS = false;
#endif // _DEBUG
m_nNUM_LIGHTS = 0;
#ifdef _DEBUG
m_bWRITE_DEPTH_TO_DESTALPHA = false;
#endif // _DEBUG
m_nWRITE_DEPTH_TO_DESTALPHA = 0;
#ifdef _DEBUG
m_bFLASHLIGHTSHADOWS = false;
#endif // _DEBUG
m_nFLASHLIGHTSHADOWS = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS;
Assert( bAllDynamicVarsDefined );
#endif // _DEBUG
return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nNUM_LIGHTS ) + ( 20 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 40 * m_nFLASHLIGHTSHADOWS ) + 0;
}
};
#define shaderDynamicTest_pbr_ps20b psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0

View File

@ -0,0 +1,337 @@
#include "shaderlib/cshader.h"
class pbr_ps30_Static_Index
{
private:
int m_nFLASHLIGHT;
#ifdef _DEBUG
bool m_bFLASHLIGHT;
#endif
public:
void SetFLASHLIGHT( int i )
{
Assert( i >= 0 && i <= 1 );
m_nFLASHLIGHT = i;
#ifdef _DEBUG
m_bFLASHLIGHT = true;
#endif
}
void SetFLASHLIGHT( bool i )
{
m_nFLASHLIGHT = i ? 1 : 0;
#ifdef _DEBUG
m_bFLASHLIGHT = true;
#endif
}
private:
int m_nFLASHLIGHTDEPTHFILTERMODE;
#ifdef _DEBUG
bool m_bFLASHLIGHTDEPTHFILTERMODE;
#endif
public:
void SetFLASHLIGHTDEPTHFILTERMODE( int i )
{
Assert( i >= 0 && i <= 2 );
m_nFLASHLIGHTDEPTHFILTERMODE = i;
#ifdef _DEBUG
m_bFLASHLIGHTDEPTHFILTERMODE = true;
#endif
}
void SetFLASHLIGHTDEPTHFILTERMODE( bool i )
{
m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0;
#ifdef _DEBUG
m_bFLASHLIGHTDEPTHFILTERMODE = true;
#endif
}
private:
int m_nLIGHTMAPPED;
#ifdef _DEBUG
bool m_bLIGHTMAPPED;
#endif
public:
void SetLIGHTMAPPED( int i )
{
Assert( i >= 0 && i <= 1 );
m_nLIGHTMAPPED = i;
#ifdef _DEBUG
m_bLIGHTMAPPED = true;
#endif
}
void SetLIGHTMAPPED( bool i )
{
m_nLIGHTMAPPED = i ? 1 : 0;
#ifdef _DEBUG
m_bLIGHTMAPPED = true;
#endif
}
private:
int m_nUSEENVAMBIENT;
#ifdef _DEBUG
bool m_bUSEENVAMBIENT;
#endif
public:
void SetUSEENVAMBIENT( int i )
{
Assert( i >= 0 && i <= 1 );
m_nUSEENVAMBIENT = i;
#ifdef _DEBUG
m_bUSEENVAMBIENT = true;
#endif
}
void SetUSEENVAMBIENT( bool i )
{
m_nUSEENVAMBIENT = i ? 1 : 0;
#ifdef _DEBUG
m_bUSEENVAMBIENT = true;
#endif
}
private:
int m_nEMISSIVE;
#ifdef _DEBUG
bool m_bEMISSIVE;
#endif
public:
void SetEMISSIVE( int i )
{
Assert( i >= 0 && i <= 1 );
m_nEMISSIVE = i;
#ifdef _DEBUG
m_bEMISSIVE = true;
#endif
}
void SetEMISSIVE( bool i )
{
m_nEMISSIVE = i ? 1 : 0;
#ifdef _DEBUG
m_bEMISSIVE = true;
#endif
}
private:
int m_nSPECULAR;
#ifdef _DEBUG
bool m_bSPECULAR;
#endif
public:
void SetSPECULAR( int i )
{
Assert( i >= 0 && i <= 1 );
m_nSPECULAR = i;
#ifdef _DEBUG
m_bSPECULAR = true;
#endif
}
void SetSPECULAR( bool i )
{
m_nSPECULAR = i ? 1 : 0;
#ifdef _DEBUG
m_bSPECULAR = true;
#endif
}
private:
int m_nPARALLAXOCCLUSION;
#ifdef _DEBUG
bool m_bPARALLAXOCCLUSION;
#endif
public:
void SetPARALLAXOCCLUSION( int i )
{
Assert( i >= 0 && i <= 1 );
m_nPARALLAXOCCLUSION = i;
#ifdef _DEBUG
m_bPARALLAXOCCLUSION = true;
#endif
}
void SetPARALLAXOCCLUSION( bool i )
{
m_nPARALLAXOCCLUSION = i ? 1 : 0;
#ifdef _DEBUG
m_bPARALLAXOCCLUSION = true;
#endif
}
public:
pbr_ps30_Static_Index( )
{
#ifdef _DEBUG
m_bFLASHLIGHT = false;
#endif // _DEBUG
m_nFLASHLIGHT = 0;
#ifdef _DEBUG
m_bFLASHLIGHTDEPTHFILTERMODE = false;
#endif // _DEBUG
m_nFLASHLIGHTDEPTHFILTERMODE = 0;
#ifdef _DEBUG
m_bLIGHTMAPPED = false;
#endif // _DEBUG
m_nLIGHTMAPPED = 0;
#ifdef _DEBUG
m_bUSEENVAMBIENT = false;
#endif // _DEBUG
m_nUSEENVAMBIENT = 0;
#ifdef _DEBUG
m_bEMISSIVE = false;
#endif // _DEBUG
m_nEMISSIVE = 0;
#ifdef _DEBUG
m_bSPECULAR = false;
#endif // _DEBUG
m_nSPECULAR = 0;
#ifdef _DEBUG
m_bPARALLAXOCCLUSION = false;
#endif // _DEBUG
m_nPARALLAXOCCLUSION = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllStaticVarsDefined = m_bFLASHLIGHT && m_bFLASHLIGHTDEPTHFILTERMODE && m_bLIGHTMAPPED && m_bUSEENVAMBIENT && m_bEMISSIVE && m_bSPECULAR && m_bPARALLAXOCCLUSION;
Assert( bAllStaticVarsDefined );
#endif // _DEBUG
return ( 80 * m_nFLASHLIGHT ) + ( 160 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 480 * m_nLIGHTMAPPED ) + ( 960 * m_nUSEENVAMBIENT ) + ( 1920 * m_nEMISSIVE ) + ( 3840 * m_nSPECULAR ) + ( 7680 * m_nPARALLAXOCCLUSION ) + 0;
}
};
#define shaderStaticTest_pbr_ps30 psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_LIGHTMAPPED + psh_forgot_to_set_static_USEENVAMBIENT + psh_forgot_to_set_static_EMISSIVE + psh_forgot_to_set_static_SPECULAR + psh_forgot_to_set_static_PARALLAXOCCLUSION + 0
class pbr_ps30_Dynamic_Index
{
private:
int m_nWRITEWATERFOGTODESTALPHA;
#ifdef _DEBUG
bool m_bWRITEWATERFOGTODESTALPHA;
#endif
public:
void SetWRITEWATERFOGTODESTALPHA( int i )
{
Assert( i >= 0 && i <= 1 );
m_nWRITEWATERFOGTODESTALPHA = i;
#ifdef _DEBUG
m_bWRITEWATERFOGTODESTALPHA = true;
#endif
}
void SetWRITEWATERFOGTODESTALPHA( bool i )
{
m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0;
#ifdef _DEBUG
m_bWRITEWATERFOGTODESTALPHA = true;
#endif
}
private:
int m_nPIXELFOGTYPE;
#ifdef _DEBUG
bool m_bPIXELFOGTYPE;
#endif
public:
void SetPIXELFOGTYPE( int i )
{
Assert( i >= 0 && i <= 1 );
m_nPIXELFOGTYPE = i;
#ifdef _DEBUG
m_bPIXELFOGTYPE = true;
#endif
}
void SetPIXELFOGTYPE( bool i )
{
m_nPIXELFOGTYPE = i ? 1 : 0;
#ifdef _DEBUG
m_bPIXELFOGTYPE = true;
#endif
}
private:
int m_nNUM_LIGHTS;
#ifdef _DEBUG
bool m_bNUM_LIGHTS;
#endif
public:
void SetNUM_LIGHTS( int i )
{
Assert( i >= 0 && i <= 4 );
m_nNUM_LIGHTS = i;
#ifdef _DEBUG
m_bNUM_LIGHTS = true;
#endif
}
void SetNUM_LIGHTS( bool i )
{
m_nNUM_LIGHTS = i ? 1 : 0;
#ifdef _DEBUG
m_bNUM_LIGHTS = true;
#endif
}
private:
int m_nWRITE_DEPTH_TO_DESTALPHA;
#ifdef _DEBUG
bool m_bWRITE_DEPTH_TO_DESTALPHA;
#endif
public:
void SetWRITE_DEPTH_TO_DESTALPHA( int i )
{
Assert( i >= 0 && i <= 1 );
m_nWRITE_DEPTH_TO_DESTALPHA = i;
#ifdef _DEBUG
m_bWRITE_DEPTH_TO_DESTALPHA = true;
#endif
}
void SetWRITE_DEPTH_TO_DESTALPHA( bool i )
{
m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0;
#ifdef _DEBUG
m_bWRITE_DEPTH_TO_DESTALPHA = true;
#endif
}
private:
int m_nFLASHLIGHTSHADOWS;
#ifdef _DEBUG
bool m_bFLASHLIGHTSHADOWS;
#endif
public:
void SetFLASHLIGHTSHADOWS( int i )
{
Assert( i >= 0 && i <= 1 );
m_nFLASHLIGHTSHADOWS = i;
#ifdef _DEBUG
m_bFLASHLIGHTSHADOWS = true;
#endif
}
void SetFLASHLIGHTSHADOWS( bool i )
{
m_nFLASHLIGHTSHADOWS = i ? 1 : 0;
#ifdef _DEBUG
m_bFLASHLIGHTSHADOWS = true;
#endif
}
public:
pbr_ps30_Dynamic_Index()
{
#ifdef _DEBUG
m_bWRITEWATERFOGTODESTALPHA = false;
#endif // _DEBUG
m_nWRITEWATERFOGTODESTALPHA = 0;
#ifdef _DEBUG
m_bPIXELFOGTYPE = false;
#endif // _DEBUG
m_nPIXELFOGTYPE = 0;
#ifdef _DEBUG
m_bNUM_LIGHTS = false;
#endif // _DEBUG
m_nNUM_LIGHTS = 0;
#ifdef _DEBUG
m_bWRITE_DEPTH_TO_DESTALPHA = false;
#endif // _DEBUG
m_nWRITE_DEPTH_TO_DESTALPHA = 0;
#ifdef _DEBUG
m_bFLASHLIGHTSHADOWS = false;
#endif // _DEBUG
m_nFLASHLIGHTSHADOWS = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS;
Assert( bAllDynamicVarsDefined );
#endif // _DEBUG
return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nNUM_LIGHTS ) + ( 20 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 40 * m_nFLASHLIGHTSHADOWS ) + 0;
}
};
#define shaderDynamicTest_pbr_ps30 psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0

View File

@ -0,0 +1,160 @@
#include "shaderlib/cshader.h"
class pbr_vs20b_Static_Index
{
public:
pbr_vs20b_Static_Index( )
{
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
#endif // _DEBUG
return 0;
}
};
#define shaderStaticTest_pbr_vs20b 0
class pbr_vs20b_Dynamic_Index
{
private:
int m_nCOMPRESSED_VERTS;
#ifdef _DEBUG
bool m_bCOMPRESSED_VERTS;
#endif
public:
void SetCOMPRESSED_VERTS( int i )
{
Assert( i >= 0 && i <= 1 );
m_nCOMPRESSED_VERTS = i;
#ifdef _DEBUG
m_bCOMPRESSED_VERTS = true;
#endif
}
void SetCOMPRESSED_VERTS( bool i )
{
m_nCOMPRESSED_VERTS = i ? 1 : 0;
#ifdef _DEBUG
m_bCOMPRESSED_VERTS = true;
#endif
}
private:
int m_nDOWATERFOG;
#ifdef _DEBUG
bool m_bDOWATERFOG;
#endif
public:
void SetDOWATERFOG( int i )
{
Assert( i >= 0 && i <= 1 );
m_nDOWATERFOG = i;
#ifdef _DEBUG
m_bDOWATERFOG = true;
#endif
}
void SetDOWATERFOG( bool i )
{
m_nDOWATERFOG = i ? 1 : 0;
#ifdef _DEBUG
m_bDOWATERFOG = true;
#endif
}
private:
int m_nSKINNING;
#ifdef _DEBUG
bool m_bSKINNING;
#endif
public:
void SetSKINNING( int i )
{
Assert( i >= 0 && i <= 1 );
m_nSKINNING = i;
#ifdef _DEBUG
m_bSKINNING = true;
#endif
}
void SetSKINNING( bool i )
{
m_nSKINNING = i ? 1 : 0;
#ifdef _DEBUG
m_bSKINNING = true;
#endif
}
private:
int m_nLIGHTING_PREVIEW;
#ifdef _DEBUG
bool m_bLIGHTING_PREVIEW;
#endif
public:
void SetLIGHTING_PREVIEW( int i )
{
Assert( i >= 0 && i <= 1 );
m_nLIGHTING_PREVIEW = i;
#ifdef _DEBUG
m_bLIGHTING_PREVIEW = true;
#endif
}
void SetLIGHTING_PREVIEW( bool i )
{
m_nLIGHTING_PREVIEW = i ? 1 : 0;
#ifdef _DEBUG
m_bLIGHTING_PREVIEW = true;
#endif
}
private:
int m_nNUM_LIGHTS;
#ifdef _DEBUG
bool m_bNUM_LIGHTS;
#endif
public:
void SetNUM_LIGHTS( int i )
{
Assert( i >= 0 && i <= 4 );
m_nNUM_LIGHTS = i;
#ifdef _DEBUG
m_bNUM_LIGHTS = true;
#endif
}
void SetNUM_LIGHTS( bool i )
{
m_nNUM_LIGHTS = i ? 1 : 0;
#ifdef _DEBUG
m_bNUM_LIGHTS = true;
#endif
}
public:
pbr_vs20b_Dynamic_Index()
{
#ifdef _DEBUG
m_bCOMPRESSED_VERTS = false;
#endif // _DEBUG
m_nCOMPRESSED_VERTS = 0;
#ifdef _DEBUG
m_bDOWATERFOG = false;
#endif // _DEBUG
m_nDOWATERFOG = 0;
#ifdef _DEBUG
m_bSKINNING = false;
#endif // _DEBUG
m_nSKINNING = 0;
#ifdef _DEBUG
m_bLIGHTING_PREVIEW = false;
#endif // _DEBUG
m_nLIGHTING_PREVIEW = 0;
#ifdef _DEBUG
m_bNUM_LIGHTS = false;
#endif // _DEBUG
m_nNUM_LIGHTS = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bNUM_LIGHTS;
Assert( bAllDynamicVarsDefined );
#endif // _DEBUG
return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nLIGHTING_PREVIEW ) + ( 16 * m_nNUM_LIGHTS ) + 0;
}
};
#define shaderDynamicTest_pbr_vs20b vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0

View File

@ -0,0 +1,160 @@
#include "shaderlib/cshader.h"
class pbr_vs30_Static_Index
{
public:
pbr_vs30_Static_Index( )
{
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
#endif // _DEBUG
return 0;
}
};
#define shaderStaticTest_pbr_vs30 0
class pbr_vs30_Dynamic_Index
{
private:
int m_nCOMPRESSED_VERTS;
#ifdef _DEBUG
bool m_bCOMPRESSED_VERTS;
#endif
public:
void SetCOMPRESSED_VERTS( int i )
{
Assert( i >= 0 && i <= 1 );
m_nCOMPRESSED_VERTS = i;
#ifdef _DEBUG
m_bCOMPRESSED_VERTS = true;
#endif
}
void SetCOMPRESSED_VERTS( bool i )
{
m_nCOMPRESSED_VERTS = i ? 1 : 0;
#ifdef _DEBUG
m_bCOMPRESSED_VERTS = true;
#endif
}
private:
int m_nDOWATERFOG;
#ifdef _DEBUG
bool m_bDOWATERFOG;
#endif
public:
void SetDOWATERFOG( int i )
{
Assert( i >= 0 && i <= 1 );
m_nDOWATERFOG = i;
#ifdef _DEBUG
m_bDOWATERFOG = true;
#endif
}
void SetDOWATERFOG( bool i )
{
m_nDOWATERFOG = i ? 1 : 0;
#ifdef _DEBUG
m_bDOWATERFOG = true;
#endif
}
private:
int m_nSKINNING;
#ifdef _DEBUG
bool m_bSKINNING;
#endif
public:
void SetSKINNING( int i )
{
Assert( i >= 0 && i <= 1 );
m_nSKINNING = i;
#ifdef _DEBUG
m_bSKINNING = true;
#endif
}
void SetSKINNING( bool i )
{
m_nSKINNING = i ? 1 : 0;
#ifdef _DEBUG
m_bSKINNING = true;
#endif
}
private:
int m_nLIGHTING_PREVIEW;
#ifdef _DEBUG
bool m_bLIGHTING_PREVIEW;
#endif
public:
void SetLIGHTING_PREVIEW( int i )
{
Assert( i >= 0 && i <= 1 );
m_nLIGHTING_PREVIEW = i;
#ifdef _DEBUG
m_bLIGHTING_PREVIEW = true;
#endif
}
void SetLIGHTING_PREVIEW( bool i )
{
m_nLIGHTING_PREVIEW = i ? 1 : 0;
#ifdef _DEBUG
m_bLIGHTING_PREVIEW = true;
#endif
}
private:
int m_nNUM_LIGHTS;
#ifdef _DEBUG
bool m_bNUM_LIGHTS;
#endif
public:
void SetNUM_LIGHTS( int i )
{
Assert( i >= 0 && i <= 4 );
m_nNUM_LIGHTS = i;
#ifdef _DEBUG
m_bNUM_LIGHTS = true;
#endif
}
void SetNUM_LIGHTS( bool i )
{
m_nNUM_LIGHTS = i ? 1 : 0;
#ifdef _DEBUG
m_bNUM_LIGHTS = true;
#endif
}
public:
pbr_vs30_Dynamic_Index()
{
#ifdef _DEBUG
m_bCOMPRESSED_VERTS = false;
#endif // _DEBUG
m_nCOMPRESSED_VERTS = 0;
#ifdef _DEBUG
m_bDOWATERFOG = false;
#endif // _DEBUG
m_nDOWATERFOG = 0;
#ifdef _DEBUG
m_bSKINNING = false;
#endif // _DEBUG
m_nSKINNING = 0;
#ifdef _DEBUG
m_bLIGHTING_PREVIEW = false;
#endif // _DEBUG
m_nLIGHTING_PREVIEW = 0;
#ifdef _DEBUG
m_bNUM_LIGHTS = false;
#endif // _DEBUG
m_nNUM_LIGHTS = 0;
}
int GetIndex()
{
// Asserts to make sure that we aren't using any skipped combinations.
// Asserts to make sure that we are setting all of the combination vars.
#ifdef _DEBUG
bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bNUM_LIGHTS;
Assert( bAllDynamicVarsDefined );
#endif // _DEBUG
return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nLIGHTING_PREVIEW ) + ( 16 * m_nNUM_LIGHTS ) + 0;
}
};
#define shaderDynamicTest_pbr_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0

View File

@ -0,0 +1,257 @@
//==================================================================================================
//
// Physically Based Rendering Header for brushes and models
//
//==================================================================================================
// Universal Constants
static const float PI = 3.141592;
static const float ONE_OVER_PI = 0.318309;
static const float EPSILON = 0.00001;
// Shlick's approximation of the Fresnel factor
float3 fresnelSchlick(float3 F0, float cosTheta)
{
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
}
// GGX/Towbridge-Reitz normal distribution function
// Uses Disney's reparametrization of alpha = roughness^2
float ndfGGX(float cosLh, float roughness)
{
float alpha = roughness * roughness;
float alphaSq = alpha * alpha;
float denom = (cosLh * cosLh) * (alphaSq - 1.0) + 1.0;
return alphaSq / (PI * denom * denom);
}
// Single term for separable Schlick-GGX below
float gaSchlickG1(float cosTheta, float k)
{
return cosTheta / (cosTheta * (1.0 - k) + k);
}
// Schlick-GGX approximation of geometric attenuation function using Smith's method
float gaSchlickGGX(float cosLi, float cosLo, float roughness)
{
float r = roughness + 1.0;
float k = (r * r) / 8.0; // Epic suggests using this roughness remapping for analytic lights
return gaSchlickG1(cosLi, k) * gaSchlickG1(cosLo, k);
}
// Monte Carlo integration, approximate analytic version based on Dimitar Lazarov's work
// https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile
float3 EnvBRDFApprox(float3 SpecularColor, float Roughness, float NoV)
{
const float4 c0 = { -1, -0.0275, -0.572, 0.022 };
const float4 c1 = { 1, 0.0425, 1.04, -0.04 };
float4 r = Roughness * c0 + c1;
float a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;
float2 AB = float2(-1.04, 1.04) * a004 + r.zw;
return SpecularColor * AB.x + AB.y;
}
// Compute the matrix used to transform tangent space normals to world space
// This expects DirectX normal maps in Mikk Tangent Space http://www.mikktspace.com
float3x3 compute_tangent_frame(float3 N, float3 P, float2 uv, out float3 T, out float3 B, out float sign_det)
{
float3 dp1 = ddx(P);
float3 dp2 = ddy(P);
float2 duv1 = ddx(uv);
float2 duv2 = ddy(uv);
sign_det = dot(dp2, cross(N, dp1)) > 0.0 ? -1 : 1;
float3x3 M = float3x3(dp1, dp2, cross(dp1, dp2));
float2x3 inverseM = float2x3(cross(M[1], M[2]), cross(M[2], M[0]));
T = normalize(mul(float2(duv1.x, duv2.x), inverseM));
B = normalize(mul(float2(duv1.y, duv2.y), inverseM));
return float3x3(T, B, N);
}
float GetAttenForLight(float4 lightAtten, int lightNum)
{
#if (NUM_LIGHTS > 1)
if (lightNum == 1) return lightAtten.y;
#endif
#if (NUM_LIGHTS > 2)
if (lightNum == 2) return lightAtten.z;
#endif
#if (NUM_LIGHTS > 3)
if (lightNum == 3) return lightAtten.w;
#endif
return lightAtten.x;
}
// Calculate direct light for one source
float3 calculateLight(float3 lightIn, float3 lightIntensity, float3 lightOut, float3 normal, float3 fresnelReflectance, float roughness, float metalness, float lightDirectionAngle, float3 albedo)
{
// Lh
float3 HalfAngle = normalize(lightIn + lightOut);
float cosLightIn = max(0.0, dot(normal, lightIn));
float cosHalfAngle = max(0.0, dot(normal, HalfAngle));
// F - Calculate Fresnel term for direct lighting
float3 F = fresnelSchlick(fresnelReflectance, max(0.0, dot(HalfAngle, lightOut)));
// D - Calculate normal distribution for specular BRDF
float D = ndfGGX(cosHalfAngle, roughness);
// Calculate geometric attenuation for specular BRDF
float G = gaSchlickGGX(cosLightIn, lightDirectionAngle, roughness);
// Diffuse scattering happens due to light being refracted multiple times by a dielectric medium
// Metals on the other hand either reflect or absorb energso diffuse contribution is always, zero
// To be energy conserving we must scale diffuse BRDF contribution based on Fresnel factor & metalness
#if SPECULAR
// Metalness is not used if F0 map is available
float3 kd = float3(1, 1, 1) - F;
#else
float3 kd = lerp(float3(1, 1, 1) - F, float3(0, 0, 0), metalness);
#endif
float3 diffuseBRDF = kd * albedo;
// Cook-Torrance specular microfacet BRDF
float3 specularBRDF = (F * D * G) / max(EPSILON, 4.0 * cosLightIn * lightDirectionAngle);
#if LIGHTMAPPED && !FLASHLIGHT
// Ambient light from static lights is already precomputed in the lightmap. Don't add it again
return specularBRDF * lightIntensity * cosLightIn;
#else
return (diffuseBRDF + specularBRDF) * lightIntensity * cosLightIn;
#endif
}
// Get diffuse ambient light
float3 ambientLookupLightmap(float3 normal, float3 EnvAmbientCube[6], float3 textureNormal, float4 lightmapTexCoord1And2, float4 lightmapTexCoord3, sampler LightmapSampler, float4 g_DiffuseModulation)
{
float2 bumpCoord1;
float2 bumpCoord2;
float2 bumpCoord3;
ComputeBumpedLightmapCoordinates(
lightmapTexCoord1And2, lightmapTexCoord3.xy,
bumpCoord1, bumpCoord2, bumpCoord3);
float3 lightmapColor1 = LightMapSample(LightmapSampler, bumpCoord1);
float3 lightmapColor2 = LightMapSample(LightmapSampler, bumpCoord2);
float3 lightmapColor3 = LightMapSample(LightmapSampler, bumpCoord3);
float3 dp;
dp.x = saturate(dot(textureNormal, bumpBasis[0]));
dp.y = saturate(dot(textureNormal, bumpBasis[1]));
dp.z = saturate(dot(textureNormal, bumpBasis[2]));
dp *= dp;
float3 diffuseLighting = dp.x * lightmapColor1 +
dp.y * lightmapColor2 +
dp.z * lightmapColor3;
float sum = dot(dp, float3(1, 1, 1));
diffuseLighting *= g_DiffuseModulation.xyz / sum;
return diffuseLighting;
}
float3 ambientLookup(float3 normal, float3 EnvAmbientCube[6], float3 textureNormal, float4 lightmapTexCoord1And2, float4 lightmapTexCoord3, sampler LightmapSampler, float4 g_DiffuseModulation)
{
#if LIGHTMAPPED
return ambientLookupLightmap(normal, EnvAmbientCube, textureNormal, lightmapTexCoord1And2, lightmapTexCoord3, LightmapSampler, g_DiffuseModulation);
#else
return PixelShaderAmbientLight(normal, EnvAmbientCube);
#endif
}
// Create an ambient cube from the envmap
void setupEnvMapAmbientCube(out float3 EnvAmbientCube[6], sampler EnvmapSampler)
{
float4 directionPosX = { 1, 0, 0, 12 }; float4 directionNegX = {-1, 0, 0, 12 };
float4 directionPosY = { 0, 1, 0, 12 }; float4 directionNegY = { 0,-1, 0, 12 };
float4 directionPosZ = { 0, 0, 1, 12 }; float4 directionNegZ = { 0, 0,-1, 12 };
EnvAmbientCube[0] = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionPosX).rgb;
EnvAmbientCube[1] = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionNegX).rgb;
EnvAmbientCube[2] = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionPosY).rgb;
EnvAmbientCube[3] = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionNegY).rgb;
EnvAmbientCube[4] = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionPosZ).rgb;
EnvAmbientCube[5] = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, directionNegZ).rgb;
}
#if PARALLAXOCCLUSION
float2 parallaxCorrect(float2 texCoord, float3 viewRelativeDir, sampler depthMap, float parallaxDepth, float parallaxCenter)
{
float fLength = length( viewRelativeDir );
float fParallaxLength = sqrt( fLength * fLength - viewRelativeDir.z * viewRelativeDir.z ) / viewRelativeDir.z;
float2 vParallaxDirection = normalize( viewRelativeDir.xy );
float2 vParallaxOffsetTS = vParallaxDirection * fParallaxLength;
vParallaxOffsetTS *= parallaxDepth;
// Compute all the derivatives:
float2 dx = ddx( texCoord );
float2 dy = ddy( texCoord );
int nNumSteps = 20;
float fCurrHeight = 0.0;
float fStepSize = 1.0 / (float) nNumSteps;
float fPrevHeight = 1.0;
float fNextHeight = 0.0;
int nStepIndex = 0;
bool bCondition = true;
float2 vTexOffsetPerStep = fStepSize * vParallaxOffsetTS;
float2 vTexCurrentOffset = texCoord;
float fCurrentBound = 1.0;
float fParallaxAmount = 0.0;
float2 pt1 = 0;
float2 pt2 = 0;
float2 texOffset2 = 0;
while ( nStepIndex < nNumSteps )
{
vTexCurrentOffset -= vTexOffsetPerStep;
// Sample height map which in this case is stored in the alpha channel of the normal map:
fCurrHeight = parallaxCenter + tex2Dgrad( depthMap, vTexCurrentOffset, dx, dy ).a;
fCurrentBound -= fStepSize;
if ( fCurrHeight > fCurrentBound )
{
pt1 = float2( fCurrentBound, fCurrHeight );
pt2 = float2( fCurrentBound + fStepSize, fPrevHeight );
texOffset2 = vTexCurrentOffset - vTexOffsetPerStep;
nStepIndex = nNumSteps + 1;
}
else
{
nStepIndex++;
fPrevHeight = fCurrHeight;
}
} // End of while ( nStepIndex < nNumSteps )
float fDelta2 = pt2.x - pt2.y;
float fDelta1 = pt1.x - pt1.y;
fParallaxAmount = (pt1.x * fDelta2 - pt2.x * fDelta1 ) / ( fDelta2 - fDelta1 );
float2 vParallaxOffset = vParallaxOffsetTS * (1 - fParallaxAmount);
// The computed texture offset for the displaced point on the pseudo-extruded surface:
float2 texSample = texCoord - vParallaxOffset;
return texSample;
}
#endif
float3 worldToRelative(float3 worldVector, float3 surfTangent, float3 surfBasis, float3 surfNormal)
{
return float3(
dot(worldVector, surfTangent),
dot(worldVector, surfBasis),
dot(worldVector, surfNormal)
);
}

View File

@ -0,0 +1,616 @@
//==================================================================================================
//
// Physically Based Rendering shader for brushes and models
//
//==================================================================================================
// Includes for all shaders
#include "BaseVSShader.h"
#include "cpp_shader_constant_register_map.h"
// Includes for PS30
#include "pbr_vs30.inc"
#include "pbr_ps30.inc"
// Includes for PS20b
#include "pbr_vs20b.inc"
#include "pbr_ps20b.inc"
// Defining samplers
const Sampler_t SAMPLER_BASETEXTURE = SHADER_SAMPLER0;
const Sampler_t SAMPLER_NORMAL = SHADER_SAMPLER1;
const Sampler_t SAMPLER_ENVMAP = SHADER_SAMPLER2;
const Sampler_t SAMPLER_SHADOWDEPTH = SHADER_SAMPLER4;
const Sampler_t SAMPLER_RANDOMROTATION = SHADER_SAMPLER5;
const Sampler_t SAMPLER_FLASHLIGHT = SHADER_SAMPLER6;
const Sampler_t SAMPLER_LIGHTMAP = SHADER_SAMPLER7;
const Sampler_t SAMPLER_MRAO = SHADER_SAMPLER10;
const Sampler_t SAMPLER_EMISSIVE = SHADER_SAMPLER11;
const Sampler_t SAMPLER_SPECULAR = SHADER_SAMPLER12;
// Convars
static ConVar mat_fullbright("mat_fullbright", "0", FCVAR_CHEAT);
static ConVar mat_specular("mat_specular", "1", FCVAR_CHEAT);
static ConVar mat_pbr_force_20b("mat_pbr_force_20b", "0", FCVAR_CHEAT);
static ConVar mat_pbr_parallaxmap("mat_pbr_parallaxmap", "1");
// Variables for this shader
struct PBR_Vars_t
{
PBR_Vars_t()
{
memset(this, 0xFF, sizeof(*this));
}
int baseTexture;
int baseColor;
int normalTexture;
int bumpMap;
int envMap;
int baseTextureFrame;
int baseTextureTransform;
int useParallax;
int parallaxDepth;
int parallaxCenter;
int alphaTestReference;
int flashlightTexture;
int flashlightTextureFrame;
int emissionTexture;
int mraoTexture;
int useEnvAmbient;
int specularTexture;
};
// Beginning the shader
BEGIN_VS_SHADER(PBR, "PBR shader")
// Setting up vmt parameters
BEGIN_SHADER_PARAMS;
SHADER_PARAM(ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0", "");
SHADER_PARAM(ENVMAP, SHADER_PARAM_TYPE_ENVMAP, "", "Set the cubemap for this material.");
SHADER_PARAM(MRAOTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Texture with metalness in R, roughness in G, ambient occlusion in B.");
SHADER_PARAM(EMISSIONTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Emission texture");
SHADER_PARAM(NORMALTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Normal texture (deprecated, use $bumpmap)");
SHADER_PARAM(BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "", "Normal texture");
SHADER_PARAM(USEENVAMBIENT, SHADER_PARAM_TYPE_BOOL, "0", "Use the cubemaps to compute ambient light.");
SHADER_PARAM(SPECULARTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Specular F0 RGB map");
SHADER_PARAM(PARALLAX, SHADER_PARAM_TYPE_BOOL, "0", "Use Parallax Occlusion Mapping.");
SHADER_PARAM(PARALLAXDEPTH, SHADER_PARAM_TYPE_FLOAT, "0.0030", "Depth of the Parallax Map");
SHADER_PARAM(PARALLAXCENTER, SHADER_PARAM_TYPE_FLOAT, "0.5", "Center depth of the Parallax Map");
END_SHADER_PARAMS;
// Setting up variables for this shader
void SetupVars(PBR_Vars_t &info)
{
info.baseTexture = BASETEXTURE;
info.baseColor = COLOR;
info.normalTexture = NORMALTEXTURE;
info.bumpMap = BUMPMAP;
info.baseTextureFrame = FRAME;
info.baseTextureTransform = BASETEXTURETRANSFORM;
info.alphaTestReference = ALPHATESTREFERENCE;
info.flashlightTexture = FLASHLIGHTTEXTURE;
info.flashlightTextureFrame = FLASHLIGHTTEXTUREFRAME;
info.envMap = ENVMAP;
info.emissionTexture = EMISSIONTEXTURE;
info.mraoTexture = MRAOTEXTURE;
info.useEnvAmbient = USEENVAMBIENT;
info.specularTexture = SPECULARTEXTURE;
info.useParallax = PARALLAX;
info.parallaxDepth = PARALLAXDEPTH;
info.parallaxCenter = PARALLAXCENTER;
};
// Initializing parameters
SHADER_INIT_PARAMS()
{
// Fallback for changed parameter
if (params[NORMALTEXTURE]->IsDefined())
params[BUMPMAP]->SetStringValue(params[NORMALTEXTURE]->GetStringValue());
// Dynamic lights need a bumpmap
if (!params[BUMPMAP]->IsDefined())
params[BUMPMAP]->SetStringValue("dev/flat_normal");
// Set a good default mrao texture
if (!params[MRAOTEXTURE]->IsDefined())
params[MRAOTEXTURE]->SetStringValue("dev/pbr_mraotexture");
// PBR relies heavily on envmaps
if (!params[ENVMAP]->IsDefined())
params[ENVMAP]->SetStringValue("env_cubemap");
// Check if the hardware supports flashlight border color
if (g_pHardwareConfig->SupportsBorderColor())
{
params[FLASHLIGHTTEXTURE]->SetStringValue("effects/flashlight_border");
}
else
{
params[FLASHLIGHTTEXTURE]->SetStringValue("effects/flashlight001");
}
};
// Define shader fallback
SHADER_FALLBACK
{
return 0;
};
SHADER_INIT
{
PBR_Vars_t info;
SetupVars(info);
Assert(info.flashlightTexture >= 0);
LoadTexture(info.flashlightTexture, TEXTUREFLAGS_SRGB);
Assert(info.bumpMap >= 0);
LoadBumpMap(info.bumpMap);
Assert(info.envMap >= 0);
int envMapFlags = g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0;
envMapFlags |= TEXTUREFLAGS_ALL_MIPS;
LoadCubeMap(info.envMap, envMapFlags);
if (info.emissionTexture >= 0 && params[EMISSIONTEXTURE]->IsDefined())
LoadTexture(info.emissionTexture, TEXTUREFLAGS_SRGB);
Assert(info.mraoTexture >= 0);
LoadTexture(info.mraoTexture, 0);
if (params[info.baseTexture]->IsDefined())
{
LoadTexture(info.baseTexture, TEXTUREFLAGS_SRGB);
}
if (params[info.specularTexture]->IsDefined())
{
LoadTexture(info.specularTexture, TEXTUREFLAGS_SRGB);
}
if (IS_FLAG_SET(MATERIAL_VAR_MODEL)) // Set material var2 flags specific to models
{
SET_FLAGS2(MATERIAL_VAR2_SUPPORTS_HW_SKINNING); // Required for skinning
SET_FLAGS2(MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL); // Required for dynamic lighting
SET_FLAGS2(MATERIAL_VAR2_NEEDS_TANGENT_SPACES); // Required for dynamic lighting
SET_FLAGS2(MATERIAL_VAR2_LIGHTING_VERTEX_LIT); // Required for dynamic lighting
SET_FLAGS2(MATERIAL_VAR2_NEEDS_BAKED_LIGHTING_SNAPSHOTS); // Required for ambient cube
SET_FLAGS2(MATERIAL_VAR2_SUPPORTS_FLASHLIGHT); // Required for flashlight
SET_FLAGS2(MATERIAL_VAR2_USE_FLASHLIGHT); // Required for flashlight
}
else // Set material var2 flags specific to brushes
{
SET_FLAGS2(MATERIAL_VAR2_LIGHTING_LIGHTMAP); // Required for lightmaps
SET_FLAGS2(MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP); // Required for lightmaps
SET_FLAGS2(MATERIAL_VAR2_SUPPORTS_FLASHLIGHT); // Required for flashlight
SET_FLAGS2(MATERIAL_VAR2_USE_FLASHLIGHT); // Required for flashlight
}
};
// Drawing the shader
SHADER_DRAW
{
PBR_Vars_t info;
SetupVars(info);
// Setting up booleans
bool bHasBaseTexture = (info.baseTexture != -1) && params[info.baseTexture]->IsTexture();
bool bHasNormalTexture = (info.bumpMap != -1) && params[info.bumpMap]->IsTexture();
bool bHasMraoTexture = (info.mraoTexture != -1) && params[info.mraoTexture]->IsTexture();
bool bHasEmissionTexture = (info.emissionTexture != -1) && params[info.emissionTexture]->IsTexture();
bool bHasEnvTexture = (info.envMap != -1) && params[info.envMap]->IsTexture();
bool bIsAlphaTested = IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) != 0;
bool bHasFlashlight = UsingFlashlight(params);
bool bHasColor = (info.baseColor != -1) && params[info.baseColor]->IsDefined();
bool bLightMapped = !IS_FLAG_SET(MATERIAL_VAR_MODEL);
bool bUseEnvAmbient = (info.useEnvAmbient != -1) && (params[info.useEnvAmbient]->GetIntValue() == 1);
bool bHasSpecularTexture = (info.specularTexture != -1) && params[info.specularTexture]->IsTexture();
// Determining whether we're dealing with a fully opaque material
BlendType_t nBlendType = EvaluateBlendRequirements(info.baseTexture, true);
bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !bIsAlphaTested;
if (IsSnapshotting())
{
// If alphatest is on, enable it
pShaderShadow->EnableAlphaTest(bIsAlphaTested);
if (info.alphaTestReference != -1 && params[info.alphaTestReference]->GetFloatValue() > 0.0f)
{
pShaderShadow->AlphaFunc(SHADER_ALPHAFUNC_GEQUAL, params[info.alphaTestReference]->GetFloatValue());
}
if (bHasFlashlight )
{
pShaderShadow->EnableBlending(true);
pShaderShadow->BlendFunc(SHADER_BLEND_ONE, SHADER_BLEND_ONE); // Additive blending
}
else
{
SetDefaultBlendingShadowState(info.baseTexture, true);
}
int nShadowFilterMode = bHasFlashlight ? g_pHardwareConfig->GetShadowFilterMode() : 0;
// Setting up samplers
pShaderShadow->EnableTexture(SAMPLER_BASETEXTURE, true); // Basecolor texture
pShaderShadow->EnableSRGBRead(SAMPLER_BASETEXTURE, true); // Basecolor is sRGB
pShaderShadow->EnableTexture(SAMPLER_EMISSIVE, true); // Emission texture
pShaderShadow->EnableSRGBRead(SAMPLER_EMISSIVE, true); // Emission is sRGB
pShaderShadow->EnableTexture(SAMPLER_LIGHTMAP, true); // Lightmap texture
pShaderShadow->EnableSRGBRead(SAMPLER_LIGHTMAP, false); // Lightmaps aren't sRGB
pShaderShadow->EnableTexture(SAMPLER_MRAO, true); // MRAO texture
pShaderShadow->EnableSRGBRead(SAMPLER_MRAO, false); // MRAO isn't sRGB
pShaderShadow->EnableTexture(SAMPLER_NORMAL, true); // Normal texture
pShaderShadow->EnableSRGBRead(SAMPLER_NORMAL, false); // Normals aren't sRGB
pShaderShadow->EnableTexture(SAMPLER_SPECULAR, true); // Specular F0 texture
pShaderShadow->EnableSRGBRead(SAMPLER_SPECULAR, true); // Specular F0 is sRGB
// If the flashlight is on, set up its textures
if (bHasFlashlight)
{
pShaderShadow->EnableTexture(SAMPLER_SHADOWDEPTH, true); // Shadow depth map
pShaderShadow->SetShadowDepthFiltering(SAMPLER_SHADOWDEPTH);
pShaderShadow->EnableSRGBRead(SAMPLER_SHADOWDEPTH, false);
pShaderShadow->EnableTexture(SAMPLER_RANDOMROTATION, true); // Noise map
pShaderShadow->EnableTexture(SAMPLER_FLASHLIGHT, true); // Flashlight cookie
pShaderShadow->EnableSRGBRead(SAMPLER_FLASHLIGHT, true);
}
// Setting up envmap
if (bHasEnvTexture)
{
pShaderShadow->EnableTexture(SAMPLER_ENVMAP, true); // Envmap
if (g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE)
{
pShaderShadow->EnableSRGBRead(SAMPLER_ENVMAP, true); // Envmap is only sRGB with HDR disabled?
}
}
// Enabling sRGB writing
// See common_ps_fxc.h line 349
// PS2b shaders and up write sRGB
pShaderShadow->EnableSRGBWrite(true);
if (IS_FLAG_SET(MATERIAL_VAR_MODEL))
{
// We only need the position and surface normal
unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED;
// We need three texcoords, all in the default float2 size
pShaderShadow->VertexShaderVertexFormat(flags, 1, 0, 0);
}
else
{
// We need the position, surface normal, and vertex compression format
unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL;
// We only need one texcoord, in the default float2 size
pShaderShadow->VertexShaderVertexFormat(flags, 3, 0, 0);
}
int useParallax = params[info.useParallax]->GetIntValue();
if (!mat_pbr_parallaxmap.GetBool())
{
useParallax = 0;
}
if (!g_pHardwareConfig->SupportsShaderModel_3_0() || mat_pbr_force_20b.GetBool())
{
// Setting up static vertex shader
DECLARE_STATIC_VERTEX_SHADER(pbr_vs20b);
SET_STATIC_VERTEX_SHADER(pbr_vs20b);
// Setting up static pixel shader
DECLARE_STATIC_PIXEL_SHADER(pbr_ps20b);
SET_STATIC_PIXEL_SHADER_COMBO(FLASHLIGHT, bHasFlashlight);
SET_STATIC_PIXEL_SHADER_COMBO(FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode);
SET_STATIC_PIXEL_SHADER_COMBO(LIGHTMAPPED, bLightMapped);
SET_STATIC_PIXEL_SHADER_COMBO(EMISSIVE, bHasEmissionTexture);
SET_STATIC_PIXEL_SHADER_COMBO(SPECULAR, 0);
SET_STATIC_PIXEL_SHADER(pbr_ps20b);
}
else
{
// Setting up static vertex shader
DECLARE_STATIC_VERTEX_SHADER(pbr_vs30);
SET_STATIC_VERTEX_SHADER(pbr_vs30);
// Setting up static pixel shader
DECLARE_STATIC_PIXEL_SHADER(pbr_ps30);
SET_STATIC_PIXEL_SHADER_COMBO(FLASHLIGHT, bHasFlashlight);
SET_STATIC_PIXEL_SHADER_COMBO(FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode);
SET_STATIC_PIXEL_SHADER_COMBO(LIGHTMAPPED, bLightMapped);
SET_STATIC_PIXEL_SHADER_COMBO(USEENVAMBIENT, bUseEnvAmbient);
SET_STATIC_PIXEL_SHADER_COMBO(EMISSIVE, bHasEmissionTexture);
SET_STATIC_PIXEL_SHADER_COMBO(SPECULAR, bHasSpecularTexture);
SET_STATIC_PIXEL_SHADER_COMBO(PARALLAXOCCLUSION, useParallax);
SET_STATIC_PIXEL_SHADER(pbr_ps30);
}
// Setting up fog
DefaultFog(); // I think this is correct
// HACK HACK HACK - enable alpha writes all the time so that we have them for underwater stuff
pShaderShadow->EnableAlphaWrites(bFullyOpaque);
}
else // Not snapshotting -- begin dynamic state
{
bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET(MATERIAL_VAR_NO_DEBUG_OVERRIDE);
// Setting up albedo texture
if (bHasBaseTexture)
{
BindTexture(SAMPLER_BASETEXTURE, info.baseTexture, info.baseTextureFrame);
}
else
{
pShaderAPI->BindStandardTexture(SAMPLER_BASETEXTURE, TEXTURE_GREY);
}
// Setting up vmt color
Vector color;
if (bHasColor)
{
params[info.baseColor]->GetVecValue(color.Base(), 3);
}
else
{
color = Vector{1.f, 1.f, 1.f};
}
pShaderAPI->SetPixelShaderConstant(PSREG_SELFILLUMTINT, color.Base());
// Setting up environment map
if (bHasEnvTexture)
{
BindTexture(SAMPLER_ENVMAP, info.envMap, 0);
}
else
{
pShaderAPI->BindStandardTexture(SAMPLER_ENVMAP, TEXTURE_BLACK);
}
// Setting up emissive texture
if (bHasEmissionTexture)
{
BindTexture(SAMPLER_EMISSIVE, info.emissionTexture, 0);
}
else
{
pShaderAPI->BindStandardTexture(SAMPLER_EMISSIVE, TEXTURE_BLACK);
}
// Setting up normal map
if (bHasNormalTexture)
{
BindTexture(SAMPLER_NORMAL, info.bumpMap, 0);
}
else
{
pShaderAPI->BindStandardTexture(SAMPLER_NORMAL, TEXTURE_NORMALMAP_FLAT);
}
// Setting up mrao map
if (bHasMraoTexture)
{
BindTexture(SAMPLER_MRAO, info.mraoTexture, 0);
}
else
{
pShaderAPI->BindStandardTexture(SAMPLER_MRAO, TEXTURE_WHITE);
}
if (bHasSpecularTexture)
{
BindTexture(SAMPLER_SPECULAR, info.specularTexture, 0);
}
else
{
pShaderAPI->BindStandardTexture(SAMPLER_SPECULAR, TEXTURE_BLACK);
}
// Getting the light state
LightState_t lightState;
pShaderAPI->GetDX9LightState(&lightState);
// Brushes don't need ambient cubes or dynamic lights
if (!IS_FLAG_SET(MATERIAL_VAR_MODEL))
{
lightState.m_bAmbientLight = false;
lightState.m_nNumLights = 0;
}
// Setting up the flashlight related textures and variables
bool bFlashlightShadows = false;
if (bHasFlashlight)
{
Assert(info.flashlightTexture >= 0 && info.flashlightTextureFrame >= 0);
Assert(params[info.flashlightTexture]->IsTexture());
BindTexture(SAMPLER_FLASHLIGHT, info.flashlightTexture, info.flashlightTextureFrame);
VMatrix worldToTexture;
ITexture *pFlashlightDepthTexture;
FlashlightState_t state = pShaderAPI->GetFlashlightStateEx(worldToTexture, &pFlashlightDepthTexture);
bFlashlightShadows = state.m_bEnableShadows && (pFlashlightDepthTexture != NULL);
SetFlashLightColorFromState(state, pShaderAPI, PSREG_FLASHLIGHT_COLOR);
if (pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows)
{
BindTexture(SAMPLER_SHADOWDEPTH, pFlashlightDepthTexture, 0);
pShaderAPI->BindStandardTexture(SAMPLER_RANDOMROTATION, TEXTURE_SHADOW_NOISE_2D);
}
}
// Getting fog info
MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode();
int fogIndex = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z) ? 1 : 0;
// Getting skinning info
int numBones = pShaderAPI->GetCurrentNumBones();
// Some debugging stuff
bool bWriteDepthToAlpha = false;
bool bWriteWaterFogToAlpha = false;
if (bFullyOpaque)
{
bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha();
bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z);
AssertMsg(!(bWriteDepthToAlpha && bWriteWaterFogToAlpha),
"Can't write two values to alpha at the same time.");
}
float vEyePos_SpecExponent[4];
pShaderAPI->GetWorldSpaceCameraPosition(vEyePos_SpecExponent);
// Determining the max level of detail for the envmap
int iEnvMapLOD = 6;
auto envTexture = params[info.envMap]->GetTextureValue();
if (envTexture)
{
// Get power of 2 of texture width
int width = envTexture->GetMappingWidth();
int mips = 0;
while (width >>= 1)
++mips;
// Cubemap has 4 sides so 2 mips less
iEnvMapLOD = mips;
}
// Dealing with very high and low resolution cubemaps
if (iEnvMapLOD > 12)
iEnvMapLOD = 12;
if (iEnvMapLOD < 4)
iEnvMapLOD = 4;
// This has some spare space
vEyePos_SpecExponent[3] = iEnvMapLOD;
pShaderAPI->SetPixelShaderConstant(PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1);
// Setting lightmap texture
s_pShaderAPI->BindStandardTexture(SAMPLER_LIGHTMAP, TEXTURE_LIGHTMAP_BUMPED);
if (!g_pHardwareConfig->SupportsShaderModel_3_0() || mat_pbr_force_20b.GetBool())
{
// Setting up dynamic vertex shader
DECLARE_DYNAMIC_VERTEX_SHADER(pbr_vs20b);
SET_DYNAMIC_VERTEX_SHADER_COMBO(DOWATERFOG, fogIndex);
SET_DYNAMIC_VERTEX_SHADER_COMBO(SKINNING, numBones > 0);
SET_DYNAMIC_VERTEX_SHADER_COMBO(LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) != 0);
SET_DYNAMIC_VERTEX_SHADER_COMBO(COMPRESSED_VERTS, (int)vertexCompression);
SET_DYNAMIC_VERTEX_SHADER_COMBO(NUM_LIGHTS, lightState.m_nNumLights);
SET_DYNAMIC_VERTEX_SHADER(pbr_vs20b);
// Setting up dynamic pixel shader
DECLARE_DYNAMIC_PIXEL_SHADER(pbr_ps20b);
SET_DYNAMIC_PIXEL_SHADER_COMBO(NUM_LIGHTS, lightState.m_nNumLights);
SET_DYNAMIC_PIXEL_SHADER_COMBO(WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha);
SET_DYNAMIC_PIXEL_SHADER_COMBO(WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha);
SET_DYNAMIC_PIXEL_SHADER_COMBO(PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo());
SET_DYNAMIC_PIXEL_SHADER_COMBO(FLASHLIGHTSHADOWS, bFlashlightShadows);
SET_DYNAMIC_PIXEL_SHADER(pbr_ps20b);
}
else
{
// Setting up dynamic vertex shader
DECLARE_DYNAMIC_VERTEX_SHADER(pbr_vs30);
SET_DYNAMIC_VERTEX_SHADER_COMBO(DOWATERFOG, fogIndex);
SET_DYNAMIC_VERTEX_SHADER_COMBO(SKINNING, numBones > 0);
SET_DYNAMIC_VERTEX_SHADER_COMBO(LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) != 0);
SET_DYNAMIC_VERTEX_SHADER_COMBO(COMPRESSED_VERTS, (int)vertexCompression);
SET_DYNAMIC_VERTEX_SHADER_COMBO(NUM_LIGHTS, lightState.m_nNumLights);
SET_DYNAMIC_VERTEX_SHADER(pbr_vs30);
// Setting up dynamic pixel shader
DECLARE_DYNAMIC_PIXEL_SHADER(pbr_ps30);
SET_DYNAMIC_PIXEL_SHADER_COMBO(NUM_LIGHTS, lightState.m_nNumLights);
SET_DYNAMIC_PIXEL_SHADER_COMBO(WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha);
SET_DYNAMIC_PIXEL_SHADER_COMBO(WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha);
SET_DYNAMIC_PIXEL_SHADER_COMBO(PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo());
SET_DYNAMIC_PIXEL_SHADER_COMBO(FLASHLIGHTSHADOWS, bFlashlightShadows);
SET_DYNAMIC_PIXEL_SHADER(pbr_ps30);
}
// Setting up base texture transform
SetVertexShaderTextureTransform(VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.baseTextureTransform);
// This is probably important
SetModulationPixelShaderDynamicState_LinearColorSpace(1);
// Send ambient cube to the pixel shader, force to black if not available
pShaderAPI->SetPixelShaderStateAmbientLightCube(PSREG_AMBIENT_CUBE, !lightState.m_bAmbientLight);
// Send lighting array to the pixel shader
pShaderAPI->CommitPixelShaderLighting(PSREG_LIGHT_INFO_ARRAY);
// Handle mat_fullbright 2 (diffuse lighting only)
if (bLightingOnly)
{
pShaderAPI->BindStandardTexture(SAMPLER_BASETEXTURE, TEXTURE_GREY); // Basecolor
}
// Handle mat_specular 0 (no envmap reflections)
if (!mat_specular.GetBool())
{
pShaderAPI->BindStandardTexture(SAMPLER_ENVMAP, TEXTURE_BLACK); // Envmap
}
// Sending fog info to the pixel shader
pShaderAPI->SetPixelShaderFogParams(PSREG_FOG_PARAMS);
// Set up shader modulation color
float modulationColor[4] = { 1.0, 1.0, 1.0, 1.0 };
ComputeModulationColor(modulationColor);
float flLScale = pShaderAPI->GetLightMapScaleFactor();
modulationColor[0] *= flLScale;
modulationColor[1] *= flLScale;
modulationColor[2] *= flLScale;
pShaderAPI->SetPixelShaderConstant(PSREG_DIFFUSE_MODULATION, modulationColor);
// More flashlight related stuff
if (bHasFlashlight)
{
VMatrix worldToTexture;
float atten[4], pos[4], tweaks[4];
const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState(worldToTexture);
SetFlashLightColorFromState(flashlightState, pShaderAPI, PSREG_FLASHLIGHT_COLOR);
BindTexture(SAMPLER_FLASHLIGHT, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame);
// Set the flashlight attenuation factors
atten[0] = flashlightState.m_fConstantAtten;
atten[1] = flashlightState.m_fLinearAtten;
atten[2] = flashlightState.m_fQuadraticAtten;
atten[3] = flashlightState.m_FarZ;
pShaderAPI->SetPixelShaderConstant(PSREG_FLASHLIGHT_ATTENUATION, atten, 1);
// Set the flashlight origin
pos[0] = flashlightState.m_vecLightOrigin[0];
pos[1] = flashlightState.m_vecLightOrigin[1];
pos[2] = flashlightState.m_vecLightOrigin[2];
pShaderAPI->SetPixelShaderConstant(PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1);
pShaderAPI->SetPixelShaderConstant(PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4);
// Tweaks associated with a given flashlight
tweaks[0] = ShadowFilterFromState(flashlightState);
tweaks[1] = ShadowAttenFromState(flashlightState);
HashShadow2DJitter(flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3]);
pShaderAPI->SetPixelShaderConstant(PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1);
}
float flParams[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
// Parallax Depth (the strength of the effect)
flParams[0] = GetFloatParam(info.parallaxDepth, params, 3.0f);
// Parallax Center (the height at which it's not moved)
flParams[1] = GetFloatParam(info.parallaxCenter, params, 3.0f);
pShaderAPI->SetPixelShaderConstant(27, flParams, 1);
}
// Actually draw the shader
Draw();
};
// Closing it off
END_SHADER;

View File

@ -0,0 +1,193 @@
//==================================================================================================
//
// Physically Based Rendering pixel shader for brushes and models
//
//==================================================================================================
// STATIC: "FLASHLIGHT" "0..1"
// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2"
// STATIC: "LIGHTMAPPED" "0..1"
// STATIC: "EMISSIVE" "0..1"
// STATIC: "SPECULAR" "0..1"
// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1"
// DYNAMIC: "PIXELFOGTYPE" "0..1"
// DYNAMIC: "NUM_LIGHTS" "0..4"
// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1"
// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1"
// Can't write fog to alpha if there is no fog
// SKIP: ($PIXELFOGTYPE == 0) && ($WRITEWATERFOGTODESTALPHA != 0)
// We don't care about flashlight depth unless the flashlight is on
// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 )
// Flashlight shadow filter mode is irrelevant if there is no flashlight
// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 )
#include "common_ps_fxc.h"
#include "common_flashlight_fxc.h"
#include "common_lightmappedgeneric_fxc.h"
#include "shader_constant_register_map.h"
#include "pbr_common_ps2_3_x.h"
const float4 g_DiffuseModulation : register(PSREG_DIFFUSE_MODULATION);
const float4 g_ShadowTweaks : register(PSREG_ENVMAP_TINT__SHADOW_TWEAKS);
const float3 cAmbientCube[6] : register(PSREG_AMBIENT_CUBE);
const float4 g_EyePos : register(PSREG_EYEPOS_SPEC_EXPONENT);
const float4 g_FogParams : register(PSREG_FOG_PARAMS);
const float4 g_FlashlightAttenuationFactors : register(PSREG_FLASHLIGHT_ATTENUATION);
const float4 g_FlashlightPos : register(PSREG_FLASHLIGHT_POSITION_RIM_BOOST);
const float4x4 g_FlashlightWorldToTexture : register(PSREG_FLASHLIGHT_TO_WORLD_TEXTURE);
PixelShaderLightInfo cLightInfo[3] : register(PSREG_LIGHT_INFO_ARRAY); // 2 registers each - 6 registers total (4th light spread across w's)
const float4 g_BaseColor : register(PSREG_SELFILLUMTINT);
sampler BaseTextureSampler : register(s0); // Base map, selfillum in alpha
sampler NormalTextureSampler : register(s1); // Normal map
sampler EnvmapSampler : register(s2); // Cubemap
sampler ShadowDepthSampler : register(s4); // Flashlight shadow depth map sampler
sampler RandRotSampler : register(s5); // RandomRotation sampler
sampler FlashlightSampler : register(s6); // Flashlight cookie
sampler LightmapSampler : register(s7); // Lightmap
sampler MRAOTextureSampler : register(s10); // MRAO texture
#if EMISSIVE
sampler EmissionTextureSampler : register(s11); // Emission texture
#endif
#if SPECULAR
sampler SpecularTextureSampler : register(s12); // Specular F0 texture
#endif
#define ENVMAPLOD (g_EyePos.a)
struct PS_INPUT
{
float2 baseTexCoord : TEXCOORD0;
float4 lightAtten : TEXCOORD1;
float3 worldNormal : TEXCOORD2;
float3 worldTangent : TEXCOORD3;
float3 worldPos : TEXCOORD4;
float3 projPos : TEXCOORD5;
float4 lightmapTexCoord1And2 : TEXCOORD6;
float4 lightmapTexCoord3 : TEXCOORD7;
};
// Entry point
float4 main(PS_INPUT i) : COLOR
{
float2 correctedTexCoord = i.baseTexCoord;
float4 albedo = tex2D(BaseTextureSampler, correctedTexCoord);
albedo.xyz *= g_BaseColor;
float3 mrao = tex2D(MRAOTextureSampler, correctedTexCoord).xyz;
float metalness = mrao.x, roughness = mrao.y, ambientOcclusion = mrao.z;
#if EMISSIVE
float3 emission = tex2D(EmissionTextureSampler, correctedTexCoord).xyz;
#endif
#if SPECULAR
float3 specular = tex2D(SpecularTextureSampler, correctedTexCoord).xyz;
#endif
float3x3 normalBasis = float3x3(i.worldTangent, cross(i.worldNormal, i.worldTangent), i.worldNormal);
float3 textureNormal = normalize((tex2D( NormalTextureSampler, correctedTexCoord).xyz - float3(0.5, 0.5, 0.5)) * 2);
float3 normal = normalize(mul(textureNormal, normalBasis)); // World Normal
float3 outgoingLightDirection = normalize(g_EyePos.xyz - i.worldPos); // Lo
float lightDirectionAngle = max(0, dot(normal, outgoingLightDirection)); // cosLo
float3 specularReflectionVector = 2.0 * lightDirectionAngle * normal - outgoingLightDirection; // Lr
#if SPECULAR
float3 fresnelReflectance = specular.rgb; // F0
#else
float3 dielectricCoefficient = 0.04; //F0 dielectric
float3 fresnelReflectance = lerp(dielectricCoefficient, albedo.rgb, metalness); // F0
#endif
// Start ambient
float3 ambientLighting = 0.0;
if (!FLASHLIGHT)
{
float3 diffuseIrradiance = ambientLookup(normal, cAmbientCube, textureNormal, i.lightmapTexCoord1And2, i.lightmapTexCoord3, LightmapSampler, g_DiffuseModulation);
float3 ambientLightingFresnelTerm = fresnelSchlick(fresnelReflectance, lightDirectionAngle); // F
#if SPECULAR
float3 diffuseContributionFactor = 1 - ambientLightingFresnelTerm; // kd
#else
float3 diffuseContributionFactor = lerp(1 - ambientLightingFresnelTerm, 0, metalness); ; // kd
#endif
float3 diffuseIBL = diffuseContributionFactor * albedo.rgb * diffuseIrradiance;
float4 specularUV = float4(specularReflectionVector, roughness * ENVMAPLOD);
float3 lookupHigh = ENV_MAP_SCALE * texCUBE(EnvmapSampler, specularUV).xyz;
float3 lookupLow = PixelShaderAmbientLight(specularReflectionVector, cAmbientCube);
float3 specularIrradiance = lerp(lookupHigh, lookupLow, roughness * roughness);
float3 specularIBL = specularIrradiance * EnvBRDFApprox(fresnelReflectance, roughness, lightDirectionAngle);
ambientLighting = (diffuseIBL + specularIBL) * ambientOcclusion;
}
// End ambient
// Start direct
float3 directLighting = 0.0;
if (!FLASHLIGHT) {
for (int n = 0; n < NUM_LIGHTS; ++n)
{
float3 LightIn = normalize(PixelShaderGetLightVector(i.worldPos, cLightInfo, n));
float3 LightColor = PixelShaderGetLightColor(cLightInfo, n) * GetAttenForLight(i.lightAtten, n); // Li
directLighting += calculateLight(LightIn, LightColor, outgoingLightDirection,
normal, fresnelReflectance, roughness, metalness, lightDirectionAngle, albedo.rgb);
}
}
// End direct
// Start flashlight
if (FLASHLIGHT)
{
float4 flashlightSpacePosition = mul(float4(i.worldPos, 1.0), g_FlashlightWorldToTexture);
clip( flashlightSpacePosition.w ); // stop projected textures from projecting backwards (only really happens if they have a big FOV because they get frustum culled.)
float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w;
float3 delta = g_FlashlightPos.xyz - i.worldPos;
float distSquared = dot(delta, delta);
float dist = sqrt(distSquared);
float3 flashlightColor = tex2D(FlashlightSampler, vProjCoords.xy);
flashlightColor *= cFlashlightColor.xyz;
#if FLASHLIGHTSHADOWS
float flashlightShadow = DoFlashlightShadow(ShadowDepthSampler, RandRotSampler, vProjCoords, i.projPos, FLASHLIGHTDEPTHFILTERMODE, g_ShadowTweaks, true);
float flashlightAttenuated = lerp(flashlightShadow, 1.0, g_ShadowTweaks.y); // Blend between fully attenuated and not attenuated
float fAtten = saturate(dot(g_FlashlightAttenuationFactors.xyz, float3(1.0, 1.0 / dist, 1.0 / distSquared)));
flashlightShadow = saturate(lerp(flashlightAttenuated, flashlightShadow, fAtten)); // Blend between shadow and above, according to light attenuation
flashlightColor *= flashlightShadow;
#endif
float farZ = g_FlashlightAttenuationFactors.w;
float endFalloffFactor = RemapValClamped(dist, farZ, 0.6 * farZ, 0.0, 1.0);
float3 flashLightIntensity = flashlightColor * endFalloffFactor;
float3 flashLightIn = normalize(g_FlashlightPos.xyz - i.worldPos);
directLighting += max(0, calculateLight(flashLightIn, flashLightIntensity, outgoingLightDirection,
normal, fresnelReflectance, roughness, metalness, lightDirectionAngle, albedo.rgb));
}
// End flashlight
float fogFactor = CalcPixelFogFactor(PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos.z, i.projPos.z);
#if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT)
float alpha = fogFactor;
#else
float alpha = albedo.a;
#endif
bool bWriteDepthToAlpha = (WRITE_DEPTH_TO_DESTALPHA != 0) && (WRITEWATERFOGTODESTALPHA == 0);
float3 combinedLighting = directLighting + ambientLighting;
#if EMISSIVE && !FLASHLIGHT
combinedLighting += emission;
#endif
return FinalOutput(float4(combinedLighting, alpha), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.projPos.z);
}

View File

@ -0,0 +1,227 @@
//==================================================================================================
//
// Physically Based Rendering pixel shader for brushes and models
//
//==================================================================================================
// STATIC: "FLASHLIGHT" "0..1"
// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2"
// STATIC: "LIGHTMAPPED" "0..1"
// STATIC: "USEENVAMBIENT" "0..1"
// STATIC: "EMISSIVE" "0..1"
// STATIC: "SPECULAR" "0..1"
// STATIC: "PARALLAXOCCLUSION" "0..1"
// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1"
// DYNAMIC: "PIXELFOGTYPE" "0..1"
// DYNAMIC: "NUM_LIGHTS" "0..4"
// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1"
// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1"
// Can't write fog to alpha if there is no fog
// SKIP: ($PIXELFOGTYPE == 0) && ($WRITEWATERFOGTODESTALPHA != 0)
// We don't care about flashlight depth unless the flashlight is on
// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 )
// Flashlight shadow filter mode is irrelevant if there is no flashlight
// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 )
#include "common_ps_fxc.h"
#include "common_flashlight_fxc.h"
#include "common_lightmappedgeneric_fxc.h"
#include "shader_constant_register_map.h"
#include "pbr_common_ps2_3_x.h"
const float4 g_DiffuseModulation : register(PSREG_DIFFUSE_MODULATION);
const float4 g_ShadowTweaks : register(PSREG_ENVMAP_TINT__SHADOW_TWEAKS);
const float3 cAmbientCube[6] : register(PSREG_AMBIENT_CUBE);
const float4 g_EyePos : register(PSREG_EYEPOS_SPEC_EXPONENT);
const float4 g_FogParams : register(PSREG_FOG_PARAMS);
const float4 g_FlashlightAttenuationFactors : register(PSREG_FLASHLIGHT_ATTENUATION);
const float4 g_FlashlightPos : register(PSREG_FLASHLIGHT_POSITION_RIM_BOOST);
const float4x4 g_FlashlightWorldToTexture : register(PSREG_FLASHLIGHT_TO_WORLD_TEXTURE);
PixelShaderLightInfo cLightInfo[3] : register(PSREG_LIGHT_INFO_ARRAY); // 2 registers each - 6 registers total (4th light spread across w's)
const float4 g_BaseColor : register(PSREG_SELFILLUMTINT);
#if PARALLAXOCCLUSION
const float4 g_ParallaxParms : register( c27 );
#define PARALLAX_DEPTH g_ParallaxParms.r
#define PARALLAX_CENTER g_ParallaxParms.g
#endif
sampler BaseTextureSampler : register(s0); // Base map, selfillum in alpha
sampler NormalTextureSampler : register(s1); // Normal map
sampler EnvmapSampler : register(s2); // Cubemap
sampler ShadowDepthSampler : register(s4); // Flashlight shadow depth map sampler
sampler RandRotSampler : register(s5); // RandomRotation sampler
sampler FlashlightSampler : register(s6); // Flashlight cookie
sampler LightmapSampler : register(s7); // Lightmap
sampler MRAOTextureSampler : register(s10); // MRAO texture
#if EMISSIVE
sampler EmissionTextureSampler : register(s11); // Emission texture
#endif
#if SPECULAR
sampler SpecularTextureSampler : register(s12); // Specular F0 texture
#endif
#define ENVMAPLOD (g_EyePos.a)
struct PS_INPUT
{
float2 baseTexCoord : TEXCOORD0;
float4 lightAtten : TEXCOORD1;
float3 worldNormal : TEXCOORD2;
float3 worldPos : TEXCOORD3;
float3 projPos : TEXCOORD4;
float4 lightmapTexCoord1And2 : TEXCOORD5;
float4 lightmapTexCoord3 : TEXCOORD6;
};
// Entry point
float4 main(PS_INPUT i) : COLOR
{
#if USEENVAMBIENT
float3 EnvAmbientCube[6];
setupEnvMapAmbientCube(EnvAmbientCube, EnvmapSampler);
#else
#define EnvAmbientCube cAmbientCube
#endif
float3 surfNormal = normalize(i.worldNormal);
float3 surfTangent;
float3 surfBase;
float flipSign;
float3x3 normalBasis = compute_tangent_frame(surfNormal, i.worldPos, i.baseTexCoord , surfTangent, surfBase, flipSign);
#if PARALLAXOCCLUSION
float3 outgoingLightRay = g_EyePos.xyz - i.worldPos;
float3 outgoingLightDirectionTS = worldToRelative( outgoingLightRay, surfTangent, surfBase, surfNormal);
float2 correctedTexCoord = parallaxCorrect(i.baseTexCoord, outgoingLightDirectionTS , NormalTextureSampler , PARALLAX_DEPTH , PARALLAX_CENTER);
#else
float2 correctedTexCoord = i.baseTexCoord;
#endif
float3 textureNormal = normalize((tex2D( NormalTextureSampler, correctedTexCoord).xyz - float3(0.5, 0.5, 0.5)) * 2);
float3 normal = normalize(mul(textureNormal, normalBasis)); // World Normal
float4 albedo = tex2D(BaseTextureSampler, correctedTexCoord);
albedo.xyz *= g_BaseColor;
float3 mrao = tex2D(MRAOTextureSampler, correctedTexCoord).xyz;
float metalness = mrao.x, roughness = mrao.y, ambientOcclusion = mrao.z;
#if EMISSIVE
float3 emission = tex2D(EmissionTextureSampler, correctedTexCoord).xyz;
#endif
#if SPECULAR
float3 specular = tex2D(SpecularTextureSampler, correctedTexCoord).xyz;
#endif
textureNormal.y *= flipSign; // Fixup textureNormal for ambient lighting
float3 outgoingLightDirection = normalize(g_EyePos.xyz - i.worldPos); // Lo
float lightDirectionAngle = max(0, dot(normal, outgoingLightDirection)); // cosLo
float3 specularReflectionVector = 2.0 * lightDirectionAngle * normal - outgoingLightDirection; // Lr
#if SPECULAR
float3 fresnelReflectance = specular.rgb; // F0
#else
float3 dielectricCoefficient = 0.04; //F0 dielectric
float3 fresnelReflectance = lerp(dielectricCoefficient, albedo.rgb, metalness); // F0
#endif
// Start ambient
float3 ambientLighting = 0.0;
if (!FLASHLIGHT)
{
float3 diffuseIrradiance = ambientLookup(normal, EnvAmbientCube, textureNormal, i.lightmapTexCoord1And2, i.lightmapTexCoord3, LightmapSampler, g_DiffuseModulation);
// return float4(diffuseIrradiance, 1); // testing diffuse irraciance
float3 ambientLightingFresnelTerm = fresnelSchlick(fresnelReflectance, lightDirectionAngle); // F
#if SPECULAR
float3 diffuseContributionFactor = 1 - ambientLightingFresnelTerm; // kd
#else
float3 diffuseContributionFactor = lerp(1 - ambientLightingFresnelTerm, 0, metalness); ; // kd
#endif
float3 diffuseIBL = diffuseContributionFactor * albedo.rgb * diffuseIrradiance;
float4 specularUV = float4(specularReflectionVector, roughness * ENVMAPLOD);
float3 lookupHigh = ENV_MAP_SCALE * texCUBElod(EnvmapSampler, specularUV).xyz;
float3 lookupLow = PixelShaderAmbientLight(specularReflectionVector, EnvAmbientCube);
float3 specularIrradiance = lerp(lookupHigh, lookupLow, roughness * roughness);
float3 specularIBL = specularIrradiance * EnvBRDFApprox(fresnelReflectance, roughness, lightDirectionAngle);
ambientLighting = (diffuseIBL + specularIBL) * ambientOcclusion;
}
// End ambient
// Start direct
float3 directLighting = 0.0;
if (!FLASHLIGHT) {
for (uint n = 0; n < NUM_LIGHTS; ++n)
{
float3 LightIn = normalize(PixelShaderGetLightVector(i.worldPos, cLightInfo, n));
float3 LightColor = PixelShaderGetLightColor(cLightInfo, n) * GetAttenForLight(i.lightAtten, n); // Li
directLighting += calculateLight(LightIn, LightColor, outgoingLightDirection,
normal, fresnelReflectance, roughness, metalness, lightDirectionAngle, albedo.rgb);
}
}
// End direct
// Start flashlight
if (FLASHLIGHT)
{
float4 flashlightSpacePosition = mul(float4(i.worldPos, 1.0), g_FlashlightWorldToTexture);
clip( flashlightSpacePosition.w ); // stop projected textures from projecting backwards (only really happens if they have a big FOV because they get frustum culled.)
float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w;
float3 delta = g_FlashlightPos.xyz - i.worldPos;
float distSquared = dot(delta, delta);
float dist = sqrt(distSquared);
float3 flashlightColor = tex2D(FlashlightSampler, vProjCoords.xy);
flashlightColor *= cFlashlightColor.xyz;
#if FLASHLIGHTSHADOWS
float flashlightShadow = DoFlashlightShadow(ShadowDepthSampler, RandRotSampler, vProjCoords, i.projPos, FLASHLIGHTDEPTHFILTERMODE, g_ShadowTweaks, true);
float flashlightAttenuated = lerp(flashlightShadow, 1.0, g_ShadowTweaks.y); // Blend between fully attenuated and not attenuated
float fAtten = saturate(dot(g_FlashlightAttenuationFactors.xyz, float3(1.0, 1.0 / dist, 1.0 / distSquared)));
flashlightShadow = saturate(lerp(flashlightAttenuated, flashlightShadow, fAtten)); // Blend between shadow and above, according to light attenuation
flashlightColor *= flashlightShadow;
#endif
float farZ = g_FlashlightAttenuationFactors.w;
float endFalloffFactor = RemapValClamped(dist, farZ, 0.6 * farZ, 0.0, 1.0);
float3 flashLightIntensity = flashlightColor * endFalloffFactor;
float3 flashLightIn = normalize(g_FlashlightPos.xyz - i.worldPos);
directLighting += max(0, calculateLight(flashLightIn, flashLightIntensity, outgoingLightDirection,
normal, fresnelReflectance, roughness, metalness, lightDirectionAngle, albedo.rgb));
}
// End flashlight
float fogFactor = 0.0f;
#if !FLASHLIGHT
fogFactor = CalcPixelFogFactor(PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos.z, i.projPos.z);
#endif
float alpha = 0.0f;
#if !FLASHLIGHT
#if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT)
alpha = fogFactor;
#else
alpha = albedo.a;
#endif
#endif
bool bWriteDepthToAlpha = (WRITE_DEPTH_TO_DESTALPHA != 0) && (WRITEWATERFOGTODESTALPHA == 0);
float3 combinedLighting = directLighting + ambientLighting;
#if EMISSIVE && !FLASHLIGHT
combinedLighting += emission;
#endif
return FinalOutput(float4(combinedLighting, alpha), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.projPos.z);
}

View File

@ -0,0 +1,116 @@
//==================================================================================================
//
// Physically Based Rendering vertex shader for brushes and models
//
//==================================================================================================
// DYNAMIC: "COMPRESSED_VERTS" "0..1"
// DYNAMIC: "DOWATERFOG" "0..1"
// DYNAMIC: "SKINNING" "0..1"
// DYNAMIC: "LIGHTING_PREVIEW" "0..1"
// DYNAMIC: "NUM_LIGHTS" "0..4"
#include "common_vs_fxc.h"
static const bool g_bSkinning = SKINNING ? true : false;
static const int g_FogType = DOWATERFOG;
const float4 cBaseTexCoordTransform[2] : register(SHADER_SPECIFIC_CONST_0);
//-----------------------------------------------------------------------------
// Input vertex format
//-----------------------------------------------------------------------------
struct VS_INPUT
{
// This is all of the stuff that we ever use
float4 vPos : POSITION;
float4 vBoneWeights : BLENDWEIGHT;
float4 vBoneIndices : BLENDINDICES;
float4 vNormal : NORMAL;
float4 vTangent : TANGENT;
float2 vTexCoord0 : TEXCOORD0;
float4 vLightmapTexCoord : TEXCOORD1;
float4 vLightmapTexCoordOffset : TEXCOORD2;
};
struct VS_OUTPUT
{
// Stuff that isn't seen by the pixel shader
float4 projPosSetup : POSITION;
float fog : FOG;
// Stuff that is seen by the pixel shader
float2 baseTexCoord : TEXCOORD0;
float4 lightAtten : TEXCOORD1;
float3 worldNormal : TEXCOORD2;
float3 worldTangent : TEXCOORD3;
float3 worldPos : TEXCOORD4;
float3 projPos : TEXCOORD5;
float4 lightmapTexCoord1And2 : TEXCOORD6;
float4 lightmapTexCoord3 : TEXCOORD7;
};
//-----------------------------------------------------------------------------
// Main shader entry point
//-----------------------------------------------------------------------------
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
o.lightmapTexCoord3.z = dot(v.vTexCoord0, cBaseTexCoordTransform[0].xy) + cBaseTexCoordTransform[0].w;
o.lightmapTexCoord3.w = dot(v.vTexCoord0, cBaseTexCoordTransform[1].xy) + cBaseTexCoordTransform[1].w;
o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord + v.vLightmapTexCoordOffset;
float2 lightmapTexCoord2 = o.lightmapTexCoord1And2.xy + v.vLightmapTexCoordOffset.xy;
float2 lightmapTexCoord3 = lightmapTexCoord2 + v.vLightmapTexCoordOffset.xy;
// Reversed component order
o.lightmapTexCoord1And2.w = lightmapTexCoord2.x;
o.lightmapTexCoord1And2.z = lightmapTexCoord2.y;
o.lightmapTexCoord3.xy = lightmapTexCoord3;
// Get normal and tangent and stuff
float3 vNormal; float4 vTangent;
DecompressVertex_NormalTangent(v.vNormal, v.vTangent, vNormal, vTangent);
float3 worldNormal, worldPos, worldTangentS, worldTangentT;
SkinPositionNormalAndTangentSpace(g_bSkinning, v.vPos, vNormal, vTangent, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal, worldTangentS, worldTangentT);
// Transform into projection space
float4 vProjPos = mul(float4(worldPos, 1), cViewProj);
o.projPosSetup = vProjPos;
vProjPos.z = dot(float4(worldPos, 1), cViewProjZ);
o.projPos = vProjPos.xyz;
o.fog = CalcFog(worldPos, vProjPos.xyz, g_FogType);
// Needed for water fog alpha and diffuse lighting
o.worldPos = worldPos;
o.worldNormal = normalize(worldNormal);
//o.worldTangent = float4(worldTangentS.xyz, vTangent.w);
o.worldTangent = normalize(worldTangentS);
// Scalar attenuations for four lights
o.lightAtten = float4(0, 0, 0, 0);
#if (NUM_LIGHTS > 0)
o.lightAtten.x = GetVertexAttenForLight(worldPos, 0, false);
#endif
#if (NUM_LIGHTS > 1)
o.lightAtten.y = GetVertexAttenForLight(worldPos, 1, false);
#endif
#if (NUM_LIGHTS > 2)
o.lightAtten.z = GetVertexAttenForLight(worldPos, 2, false);
#endif
#if (NUM_LIGHTS > 3)
o.lightAtten.w = GetVertexAttenForLight(worldPos, 3, false);
#endif
// Base texture coordinate transform
o.baseTexCoord.x = dot(v.vTexCoord0, cBaseTexCoordTransform[0].xy);
o.baseTexCoord.y = dot(v.vTexCoord0, cBaseTexCoordTransform[1].xy);
return o;
}

View File

@ -0,0 +1,111 @@
//==================================================================================================
//
// Physically Based Rendering vertex shader for brushes and models
//
//==================================================================================================
// DYNAMIC: "COMPRESSED_VERTS" "0..1"
// DYNAMIC: "DOWATERFOG" "0..1"
// DYNAMIC: "SKINNING" "0..1"
// DYNAMIC: "LIGHTING_PREVIEW" "0..1"
// DYNAMIC: "NUM_LIGHTS" "0..4"
#include "common_vs_fxc.h"
static const bool g_bSkinning = SKINNING ? true : false;
static const int g_FogType = DOWATERFOG;
const float4 cBaseTexCoordTransform[2] : register(SHADER_SPECIFIC_CONST_0);
//-----------------------------------------------------------------------------
// Input vertex format
//-----------------------------------------------------------------------------
struct VS_INPUT
{
// This is all of the stuff that we ever use
float4 vPos : POSITION;
float4 vBoneWeights : BLENDWEIGHT;
float4 vBoneIndices : BLENDINDICES;
float4 vNormal : NORMAL;
float2 vTexCoord0 : TEXCOORD0;
float4 vLightmapTexCoord : TEXCOORD1;
float4 vLightmapTexCoordOffset : TEXCOORD2;
};
struct VS_OUTPUT
{
// Stuff that isn't seen by the pixel shader
float4 projPosSetup : POSITION;
float fog : FOG;
// Stuff that is seen by the pixel shader
float2 baseTexCoord : TEXCOORD0;
float4 lightAtten : TEXCOORD1;
float3 worldNormal : TEXCOORD2;
float3 worldPos : TEXCOORD3;
float3 projPos : TEXCOORD4;
float4 lightmapTexCoord1And2 : TEXCOORD5;
float4 lightmapTexCoord3 : TEXCOORD6;
};
//-----------------------------------------------------------------------------
// Main shader entry point
//-----------------------------------------------------------------------------
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
o.lightmapTexCoord3.z = dot(v.vTexCoord0, cBaseTexCoordTransform[0]) + cBaseTexCoordTransform[0].w;
o.lightmapTexCoord3.w = dot(v.vTexCoord0, cBaseTexCoordTransform[1]) + cBaseTexCoordTransform[1].w;
o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord + v.vLightmapTexCoordOffset;
float2 lightmapTexCoord2 = o.lightmapTexCoord1And2.xy + v.vLightmapTexCoordOffset;
float2 lightmapTexCoord3 = lightmapTexCoord2 + v.vLightmapTexCoordOffset;
// Reversed component order
o.lightmapTexCoord1And2.w = lightmapTexCoord2.x;
o.lightmapTexCoord1And2.z = lightmapTexCoord2.y;
o.lightmapTexCoord3.xy = lightmapTexCoord3;
float3 vNormal;
DecompressVertex_Normal(v.vNormal, vNormal);
float3 worldNormal, worldPos;
SkinPositionAndNormal(g_bSkinning, v.vPos, vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal);
// Transform into projection space
float4 vProjPos = mul(float4(worldPos, 1), cViewProj);
o.projPosSetup = vProjPos;
vProjPos.z = dot(float4(worldPos, 1), cViewProjZ);
o.projPos = vProjPos.xyz;
o.fog = CalcFog(worldPos, vProjPos.xyz, g_FogType);
// Needed for water fog alpha and diffuse lighting
o.worldPos = worldPos;
o.worldNormal = normalize(worldNormal);
// Scalar attenuations for four lights
o.lightAtten = float4(0, 0, 0, 0);
#if (NUM_LIGHTS > 0)
o.lightAtten.x = GetVertexAttenForLight(worldPos, 0, false);
#endif
#if (NUM_LIGHTS > 1)
o.lightAtten.y = GetVertexAttenForLight(worldPos, 1, false);
#endif
#if (NUM_LIGHTS > 2)
o.lightAtten.z = GetVertexAttenForLight(worldPos, 2, false);
#endif
#if (NUM_LIGHTS > 3)
o.lightAtten.w = GetVertexAttenForLight(worldPos, 3, false);
#endif
// Base texture coordinate transform
o.baseTexCoord.x = dot(v.vTexCoord0, cBaseTexCoordTransform[0]);
o.baseTexCoord.y = dot(v.vTexCoord0, cBaseTexCoordTransform[1]);
return o;
}

View File

@ -120,6 +120,7 @@ $Project "stdshader_dx9"
$File "particlelitgeneric_dx9.cpp"
$File "particlelitgeneric_dx9_helper.cpp"
$File "particlesphere_dx9.cpp"
$File "pbr_dx9.cpp"
$File "portal.cpp"
$File "portalstaticoverlay.cpp"
$File "portal_refract.cpp"
@ -212,6 +213,7 @@ $Project "stdshader_dx9"
$File "shader_constant_register_map.h"
$File "skin_dx9_helper.h"
$File "particlelitgeneric_dx9_helper.h"
$File "pbr_common_ps2_3_x.h"
$File "vertexlitgeneric_dx95_helper.h"
$File "vortwarp_vs20_helper.h"
$File "worldvertextransition_dx8_helper.h"
@ -244,4 +246,4 @@ $Project "stdshader_dx9"
$Shaders "stdshader_dx9_20b.txt"
$Shaders "stdshader_dx9_30.txt"
//$Shaders "stdshader_dx10.txt"
}
}

View File

@ -272,6 +272,9 @@ particlesphere_vs11.fxc
particlesphere_ps2x.fxc
particlesphere_vs20.fxc
pbr_ps20b.fxc
pbr_vs20b.fxc
portal_ps11.fxc
portal_vs11.fxc
portal_ps2x.fxc

View File

@ -26,6 +26,8 @@ morphaccumulate_vs30.fxc
morphaccumulate_ps30.fxc
morphweight_vs30.fxc
morphweight_ps30.fxc
pbr_ps30.fxc
pbr_vs30.fxc
pyro_vision_ps2x.fxc
pyro_vision_vs20.fxc
skin_vs20.fxc

View File

@ -78,6 +78,7 @@ def build(bld):
'particlelitgeneric_dx9.cpp',
'particlelitgeneric_dx9_helper.cpp',
'particlesphere_dx9.cpp',
'pbr_dx9.cpp',
'portal.cpp',
'portalstaticoverlay.cpp',
'portal_refract.cpp',