From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/materialsystem/shaderapidx9/locald3dtypes.h | 382 +- mp/src/materialsystem/stdshaders/BaseVSShader.cpp | 4468 ++++++++++---------- mp/src/materialsystem/stdshaders/BaseVSShader.h | 878 ++-- mp/src/materialsystem/stdshaders/Bloom.cpp | 180 +- mp/src/materialsystem/stdshaders/commandbuilder.h | 814 ++-- .../stdshaders/common_flashlight_fxc.h | 1642 +++---- mp/src/materialsystem/stdshaders/common_fxc.h | 652 +-- mp/src/materialsystem/stdshaders/common_fxc2.h | 38 +- .../stdshaders/common_hlsl_cpp_consts.h | 54 +- .../stdshaders/common_lightmappedgeneric_fxc.h | 404 +- mp/src/materialsystem/stdshaders/common_pragmas.h | 76 +- mp/src/materialsystem/stdshaders/common_ps_fxc.h | 1608 +++---- .../stdshaders/common_vertexlitgeneric_dx9.h | 846 ++-- mp/src/materialsystem/stdshaders/common_vs_fxc.h | 1910 ++++----- .../stdshaders/cpp_shader_constant_register_map.h | 90 +- mp/src/materialsystem/stdshaders/dx8fallbacks.cpp | 22 +- .../stdshaders/example_model_dx9.cpp | 120 +- .../stdshaders/example_model_dx9_helper.cpp | 682 +-- .../stdshaders/example_model_dx9_helper.h | 92 +- .../stdshaders/game_shader_dx9_base.vpc | 180 +- .../stdshaders/game_shader_dx9_hl2mp.vpc | 24 +- mp/src/materialsystem/stdshaders/genwaterloop.pl | 18 +- .../stdshaders/screenspace_general.cpp | 464 +- .../stdshaders/shader_constant_register_map.h | 162 +- 24 files changed, 7903 insertions(+), 7903 deletions(-) (limited to 'mp/src/materialsystem') diff --git a/mp/src/materialsystem/shaderapidx9/locald3dtypes.h b/mp/src/materialsystem/shaderapidx9/locald3dtypes.h index 31854816..ad453558 100644 --- a/mp/src/materialsystem/shaderapidx9/locald3dtypes.h +++ b/mp/src/materialsystem/shaderapidx9/locald3dtypes.h @@ -1,191 +1,191 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//===========================================================================// - -#ifndef LOCALD3DTYPES_H -#define LOCALD3DTYPES_H - -#ifdef _WIN32 -#pragma once -#endif - -#if defined( DX10 ) && !defined( DX_TO_GL_ABSTRACTION ) - -#include -#include - -struct IDirect3D10BaseTexture -{ - ID3D10Resource *m_pBaseTexture; - ID3D10ShaderResourceView *m_pSRView; - ID3D10RenderTargetView *m_pRTView; -}; - -class CDx10Types -{ -public: - typedef struct IDirect3D10BaseTexture IDirect3DTexture; - // FIXME: What is this called now ? - // typedef ID3D10TextureCube IDirect3DCubeTexture; - typedef ID3D10Texture3D IDirect3DVolumeTexture; - typedef ID3D10Device IDirect3DDevice; - typedef D3D10_VIEWPORT D3DVIEWPORT; - typedef ID3D10Buffer IDirect3DIndexBuffer; - typedef ID3D10Buffer IDirect3DVertexBuffer; - typedef ID3D10VertexShader IDirect3DVertexShader; - typedef ID3D10PixelShader IDirect3DPixelShader; - typedef ID3D10ShaderResourceView IDirect3DSurface; - typedef ID3DX10Font ID3DXFont; - typedef ID3D10Query ID3DQuery; - - typedef ID3D10Device *LPDIRECT3DDEVICE; - typedef ID3D10Buffer *LPDIRECT3DINDEXBUFFER; - typedef ID3D10Buffer *LPDIRECT3DVERTEXBUFFER; -}; - -#endif // defined( DX10 ) && !defined( DX_TO_GL_ABSTRACTION ) - - -#if !defined( _X360 ) && !defined( DX_TO_GL_ABSTRACTION ) -#ifdef _DEBUG -#define D3D_DEBUG_INFO 1 -#endif -#endif - -struct IDirect3DTexture9; -struct IDirect3DBaseTexture9; -struct IDirect3DCubeTexture9; -struct IDirect3D9; -struct IDirect3DDevice9; -struct IDirect3DSurface9; -struct IDirect3DIndexBuffer9; -struct IDirect3DVertexBuffer9; -struct IDirect3DVertexShader9; -struct IDirect3DPixelShader9; -struct IDirect3DVolumeTexture9; - -typedef struct _D3DLIGHT9 D3DLIGHT9; -typedef struct _D3DADAPTER_IDENTIFIER9 D3DADAPTER_IDENTIFIER9; -typedef struct _D3DCAPS9 D3DCAPS9; -typedef struct _D3DVIEWPORT9 D3DVIEWPORT9; -typedef struct _D3DMATERIAL9 D3DMATERIAL9; -typedef IDirect3DTexture9 IDirect3DTexture; -typedef IDirect3DBaseTexture9 IDirect3DBaseTexture; -typedef IDirect3DCubeTexture9 IDirect3DCubeTexture; -typedef IDirect3DVolumeTexture9 IDirect3DVolumeTexture; -typedef IDirect3DDevice9 IDirect3DDevice; -typedef D3DMATERIAL9 D3DMATERIAL; -typedef D3DLIGHT9 D3DLIGHT; -typedef IDirect3DSurface9 IDirect3DSurface; -typedef D3DCAPS9 D3DCAPS; -typedef IDirect3DIndexBuffer9 IDirect3DIndexBuffer; -typedef IDirect3DVertexBuffer9 IDirect3DVertexBuffer; -typedef IDirect3DPixelShader9 IDirect3DPixelShader; -typedef IDirect3DDevice *LPDIRECT3DDEVICE; -typedef IDirect3DIndexBuffer *LPDIRECT3DINDEXBUFFER; -typedef IDirect3DVertexBuffer *LPDIRECT3DVERTEXBUFFER; - -class CDx9Types -{ -public: - typedef IDirect3DTexture9 IDirect3DTexture; - typedef IDirect3DBaseTexture9 IDirect3DBaseTexture; - typedef IDirect3DCubeTexture9 IDirect3DCubeTexture; - typedef IDirect3DVolumeTexture9 IDirect3DVolumeTexture; - typedef IDirect3DDevice9 IDirect3DDevice; - typedef D3DMATERIAL9 D3DMATERIAL; - typedef D3DLIGHT9 D3DLIGHT; - typedef IDirect3DSurface9 IDirect3DSurface; - typedef D3DCAPS9 D3DCAPS; - typedef IDirect3DIndexBuffer9 IDirect3DIndexBuffer; - typedef IDirect3DVertexBuffer9 IDirect3DVertexBuffer; - typedef IDirect3DPixelShader9 IDirect3DPixelShader; - typedef IDirect3DDevice *LPDIRECT3DDEVICE; - typedef IDirect3DIndexBuffer *LPDIRECT3DINDEXBUFFER; - typedef IDirect3DVertexBuffer *LPDIRECT3DVERTEXBUFFER; -}; - -typedef void *HardwareShader_t; - -//----------------------------------------------------------------------------- -// The vertex and pixel shader type -//----------------------------------------------------------------------------- -typedef int VertexShader_t; -typedef int PixelShader_t; - -//----------------------------------------------------------------------------- -// Bitpattern for an invalid shader -//----------------------------------------------------------------------------- -#define INVALID_SHADER ( 0xFFFFFFFF ) -#define INVALID_HARDWARE_SHADER ( NULL ) - -#define D3DSAMP_NOTSUPPORTED D3DSAMP_FORCE_DWORD -#define D3DRS_NOTSUPPORTED D3DRS_FORCE_DWORD - -#include "togl/rendermechanism.h" - -#if defined( _X360 ) - -// not supported, keeping for port ease -#define D3DSAMP_SRGBTEXTURE D3DSAMP_NOTSUPPORTED -#define D3DRS_LIGHTING D3DRS_NOTSUPPORTED -#define D3DRS_DIFFUSEMATERIALSOURCE D3DRS_NOTSUPPORTED -#define D3DRS_SPECULARENABLE D3DRS_NOTSUPPORTED -#define D3DRS_SHADEMODE D3DRS_NOTSUPPORTED -#define D3DRS_LASTPIXEL D3DRS_NOTSUPPORTED -#define D3DRS_DITHERENABLE D3DRS_NOTSUPPORTED -#define D3DRS_FOGENABLE D3DRS_NOTSUPPORTED -#define D3DRS_FOGCOLOR D3DRS_NOTSUPPORTED -#define D3DRS_FOGTABLEMODE D3DRS_NOTSUPPORTED -#define D3DRS_FOGSTART D3DRS_NOTSUPPORTED -#define D3DRS_FOGEND D3DRS_NOTSUPPORTED -#define D3DRS_FOGDENSITY D3DRS_NOTSUPPORTED -#define D3DRS_RANGEFOGENABLE D3DRS_NOTSUPPORTED -#define D3DRS_TEXTUREFACTOR D3DRS_NOTSUPPORTED -#define D3DRS_CLIPPING D3DRS_NOTSUPPORTED -#define D3DRS_AMBIENT D3DRS_NOTSUPPORTED -#define D3DRS_FOGVERTEXMODE D3DRS_NOTSUPPORTED -#define D3DRS_COLORVERTEX D3DRS_NOTSUPPORTED -#define D3DRS_LOCALVIEWER D3DRS_NOTSUPPORTED -#define D3DRS_NORMALIZENORMALS D3DRS_NOTSUPPORTED -#define D3DRS_SPECULARMATERIALSOURCE D3DRS_NOTSUPPORTED -#define D3DRS_AMBIENTMATERIALSOURCE D3DRS_NOTSUPPORTED -#define D3DRS_EMISSIVEMATERIALSOURCE D3DRS_NOTSUPPORTED -#define D3DRS_VERTEXBLEND D3DRS_NOTSUPPORTED -#define D3DRS_POINTSCALEENABLE D3DRS_NOTSUPPORTED -#define D3DRS_POINTSCALE_A D3DRS_NOTSUPPORTED -#define D3DRS_POINTSCALE_B D3DRS_NOTSUPPORTED -#define D3DRS_POINTSCALE_C D3DRS_NOTSUPPORTED -#define D3DRS_PATCHEDGESTYLE D3DRS_NOTSUPPORTED -#define D3DRS_DEBUGMONITORTOKEN D3DRS_NOTSUPPORTED -#define D3DRS_INDEXEDVERTEXBLENDENABLE D3DRS_NOTSUPPORTED -#define D3DRS_TWEENFACTOR D3DRS_NOTSUPPORTED -#define D3DRS_POSITIONDEGREE D3DRS_NOTSUPPORTED -#define D3DRS_NORMALDEGREE D3DRS_NOTSUPPORTED -#define D3DRS_ANTIALIASEDLINEENABLE D3DRS_NOTSUPPORTED -#define D3DRS_ADAPTIVETESS_X D3DRS_NOTSUPPORTED -#define D3DRS_ADAPTIVETESS_Y D3DRS_NOTSUPPORTED -#define D3DRS_ADAPTIVETESS_Z D3DRS_NOTSUPPORTED -#define D3DRS_ADAPTIVETESS_W D3DRS_NOTSUPPORTED -#define D3DRS_ENABLEADAPTIVETESSELLATION D3DRS_NOTSUPPORTED -#define D3DRS_SRGBWRITEENABLE D3DRS_NOTSUPPORTED -#define D3DLOCK_DISCARD 0 -#define D3DUSAGE_DYNAMIC 0 -#define D3DUSAGE_AUTOGENMIPMAP 0 -#define D3DDEVTYPE_REF D3DDEVTYPE_HAL -#define D3DENUM_WHQL_LEVEL 0 -#define D3DCREATE_SOFTWARE_VERTEXPROCESSING D3DCREATE_HARDWARE_VERTEXPROCESSING -#define D3DDMT_ENABLE 0 - -typedef enum D3DSHADEMODE -{ - D3DSHADE_FLAT = 0, - D3DSHADE_GOURAUD = 0, -}; - -#endif // _X360 - -#endif // LOCALD3DTYPES_H +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef LOCALD3DTYPES_H +#define LOCALD3DTYPES_H + +#ifdef _WIN32 +#pragma once +#endif + +#if defined( DX10 ) && !defined( DX_TO_GL_ABSTRACTION ) + +#include +#include + +struct IDirect3D10BaseTexture +{ + ID3D10Resource *m_pBaseTexture; + ID3D10ShaderResourceView *m_pSRView; + ID3D10RenderTargetView *m_pRTView; +}; + +class CDx10Types +{ +public: + typedef struct IDirect3D10BaseTexture IDirect3DTexture; + // FIXME: What is this called now ? + // typedef ID3D10TextureCube IDirect3DCubeTexture; + typedef ID3D10Texture3D IDirect3DVolumeTexture; + typedef ID3D10Device IDirect3DDevice; + typedef D3D10_VIEWPORT D3DVIEWPORT; + typedef ID3D10Buffer IDirect3DIndexBuffer; + typedef ID3D10Buffer IDirect3DVertexBuffer; + typedef ID3D10VertexShader IDirect3DVertexShader; + typedef ID3D10PixelShader IDirect3DPixelShader; + typedef ID3D10ShaderResourceView IDirect3DSurface; + typedef ID3DX10Font ID3DXFont; + typedef ID3D10Query ID3DQuery; + + typedef ID3D10Device *LPDIRECT3DDEVICE; + typedef ID3D10Buffer *LPDIRECT3DINDEXBUFFER; + typedef ID3D10Buffer *LPDIRECT3DVERTEXBUFFER; +}; + +#endif // defined( DX10 ) && !defined( DX_TO_GL_ABSTRACTION ) + + +#if !defined( _X360 ) && !defined( DX_TO_GL_ABSTRACTION ) +#ifdef _DEBUG +#define D3D_DEBUG_INFO 1 +#endif +#endif + +struct IDirect3DTexture9; +struct IDirect3DBaseTexture9; +struct IDirect3DCubeTexture9; +struct IDirect3D9; +struct IDirect3DDevice9; +struct IDirect3DSurface9; +struct IDirect3DIndexBuffer9; +struct IDirect3DVertexBuffer9; +struct IDirect3DVertexShader9; +struct IDirect3DPixelShader9; +struct IDirect3DVolumeTexture9; + +typedef struct _D3DLIGHT9 D3DLIGHT9; +typedef struct _D3DADAPTER_IDENTIFIER9 D3DADAPTER_IDENTIFIER9; +typedef struct _D3DCAPS9 D3DCAPS9; +typedef struct _D3DVIEWPORT9 D3DVIEWPORT9; +typedef struct _D3DMATERIAL9 D3DMATERIAL9; +typedef IDirect3DTexture9 IDirect3DTexture; +typedef IDirect3DBaseTexture9 IDirect3DBaseTexture; +typedef IDirect3DCubeTexture9 IDirect3DCubeTexture; +typedef IDirect3DVolumeTexture9 IDirect3DVolumeTexture; +typedef IDirect3DDevice9 IDirect3DDevice; +typedef D3DMATERIAL9 D3DMATERIAL; +typedef D3DLIGHT9 D3DLIGHT; +typedef IDirect3DSurface9 IDirect3DSurface; +typedef D3DCAPS9 D3DCAPS; +typedef IDirect3DIndexBuffer9 IDirect3DIndexBuffer; +typedef IDirect3DVertexBuffer9 IDirect3DVertexBuffer; +typedef IDirect3DPixelShader9 IDirect3DPixelShader; +typedef IDirect3DDevice *LPDIRECT3DDEVICE; +typedef IDirect3DIndexBuffer *LPDIRECT3DINDEXBUFFER; +typedef IDirect3DVertexBuffer *LPDIRECT3DVERTEXBUFFER; + +class CDx9Types +{ +public: + typedef IDirect3DTexture9 IDirect3DTexture; + typedef IDirect3DBaseTexture9 IDirect3DBaseTexture; + typedef IDirect3DCubeTexture9 IDirect3DCubeTexture; + typedef IDirect3DVolumeTexture9 IDirect3DVolumeTexture; + typedef IDirect3DDevice9 IDirect3DDevice; + typedef D3DMATERIAL9 D3DMATERIAL; + typedef D3DLIGHT9 D3DLIGHT; + typedef IDirect3DSurface9 IDirect3DSurface; + typedef D3DCAPS9 D3DCAPS; + typedef IDirect3DIndexBuffer9 IDirect3DIndexBuffer; + typedef IDirect3DVertexBuffer9 IDirect3DVertexBuffer; + typedef IDirect3DPixelShader9 IDirect3DPixelShader; + typedef IDirect3DDevice *LPDIRECT3DDEVICE; + typedef IDirect3DIndexBuffer *LPDIRECT3DINDEXBUFFER; + typedef IDirect3DVertexBuffer *LPDIRECT3DVERTEXBUFFER; +}; + +typedef void *HardwareShader_t; + +//----------------------------------------------------------------------------- +// The vertex and pixel shader type +//----------------------------------------------------------------------------- +typedef int VertexShader_t; +typedef int PixelShader_t; + +//----------------------------------------------------------------------------- +// Bitpattern for an invalid shader +//----------------------------------------------------------------------------- +#define INVALID_SHADER ( 0xFFFFFFFF ) +#define INVALID_HARDWARE_SHADER ( NULL ) + +#define D3DSAMP_NOTSUPPORTED D3DSAMP_FORCE_DWORD +#define D3DRS_NOTSUPPORTED D3DRS_FORCE_DWORD + +#include "togl/rendermechanism.h" + +#if defined( _X360 ) + +// not supported, keeping for port ease +#define D3DSAMP_SRGBTEXTURE D3DSAMP_NOTSUPPORTED +#define D3DRS_LIGHTING D3DRS_NOTSUPPORTED +#define D3DRS_DIFFUSEMATERIALSOURCE D3DRS_NOTSUPPORTED +#define D3DRS_SPECULARENABLE D3DRS_NOTSUPPORTED +#define D3DRS_SHADEMODE D3DRS_NOTSUPPORTED +#define D3DRS_LASTPIXEL D3DRS_NOTSUPPORTED +#define D3DRS_DITHERENABLE D3DRS_NOTSUPPORTED +#define D3DRS_FOGENABLE D3DRS_NOTSUPPORTED +#define D3DRS_FOGCOLOR D3DRS_NOTSUPPORTED +#define D3DRS_FOGTABLEMODE D3DRS_NOTSUPPORTED +#define D3DRS_FOGSTART D3DRS_NOTSUPPORTED +#define D3DRS_FOGEND D3DRS_NOTSUPPORTED +#define D3DRS_FOGDENSITY D3DRS_NOTSUPPORTED +#define D3DRS_RANGEFOGENABLE D3DRS_NOTSUPPORTED +#define D3DRS_TEXTUREFACTOR D3DRS_NOTSUPPORTED +#define D3DRS_CLIPPING D3DRS_NOTSUPPORTED +#define D3DRS_AMBIENT D3DRS_NOTSUPPORTED +#define D3DRS_FOGVERTEXMODE D3DRS_NOTSUPPORTED +#define D3DRS_COLORVERTEX D3DRS_NOTSUPPORTED +#define D3DRS_LOCALVIEWER D3DRS_NOTSUPPORTED +#define D3DRS_NORMALIZENORMALS D3DRS_NOTSUPPORTED +#define D3DRS_SPECULARMATERIALSOURCE D3DRS_NOTSUPPORTED +#define D3DRS_AMBIENTMATERIALSOURCE D3DRS_NOTSUPPORTED +#define D3DRS_EMISSIVEMATERIALSOURCE D3DRS_NOTSUPPORTED +#define D3DRS_VERTEXBLEND D3DRS_NOTSUPPORTED +#define D3DRS_POINTSCALEENABLE D3DRS_NOTSUPPORTED +#define D3DRS_POINTSCALE_A D3DRS_NOTSUPPORTED +#define D3DRS_POINTSCALE_B D3DRS_NOTSUPPORTED +#define D3DRS_POINTSCALE_C D3DRS_NOTSUPPORTED +#define D3DRS_PATCHEDGESTYLE D3DRS_NOTSUPPORTED +#define D3DRS_DEBUGMONITORTOKEN D3DRS_NOTSUPPORTED +#define D3DRS_INDEXEDVERTEXBLENDENABLE D3DRS_NOTSUPPORTED +#define D3DRS_TWEENFACTOR D3DRS_NOTSUPPORTED +#define D3DRS_POSITIONDEGREE D3DRS_NOTSUPPORTED +#define D3DRS_NORMALDEGREE D3DRS_NOTSUPPORTED +#define D3DRS_ANTIALIASEDLINEENABLE D3DRS_NOTSUPPORTED +#define D3DRS_ADAPTIVETESS_X D3DRS_NOTSUPPORTED +#define D3DRS_ADAPTIVETESS_Y D3DRS_NOTSUPPORTED +#define D3DRS_ADAPTIVETESS_Z D3DRS_NOTSUPPORTED +#define D3DRS_ADAPTIVETESS_W D3DRS_NOTSUPPORTED +#define D3DRS_ENABLEADAPTIVETESSELLATION D3DRS_NOTSUPPORTED +#define D3DRS_SRGBWRITEENABLE D3DRS_NOTSUPPORTED +#define D3DLOCK_DISCARD 0 +#define D3DUSAGE_DYNAMIC 0 +#define D3DUSAGE_AUTOGENMIPMAP 0 +#define D3DDEVTYPE_REF D3DDEVTYPE_HAL +#define D3DENUM_WHQL_LEVEL 0 +#define D3DCREATE_SOFTWARE_VERTEXPROCESSING D3DCREATE_HARDWARE_VERTEXPROCESSING +#define D3DDMT_ENABLE 0 + +typedef enum D3DSHADEMODE +{ + D3DSHADE_FLAT = 0, + D3DSHADE_GOURAUD = 0, +}; + +#endif // _X360 + +#endif // LOCALD3DTYPES_H diff --git a/mp/src/materialsystem/stdshaders/BaseVSShader.cpp b/mp/src/materialsystem/stdshaders/BaseVSShader.cpp index ba1f6e15..31c2e9b2 100644 --- a/mp/src/materialsystem/stdshaders/BaseVSShader.cpp +++ b/mp/src/materialsystem/stdshaders/BaseVSShader.cpp @@ -1,2234 +1,2234 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// This is what all vs/ps (dx8+) shaders inherit from. -//===========================================================================// -#if !defined(_STATIC_LINKED) || defined(STDSHADER_DX8_DLL_EXPORT) || defined(STDSHADER_DX9_DLL_EXPORT) - -#include "BaseVSShader.h" -#include "mathlib/vmatrix.h" -#include "mathlib/bumpvects.h" -#include "cpp_shader_constant_register_map.h" -#include "convar.h" - -#ifndef GAME_SHADER_DLL -#ifdef HDR -#include "vertexlit_and_unlit_generic_hdr_ps20.inc" -#include "vertexlit_and_unlit_generic_hdr_ps20b.inc" -#endif - -#if SUPPORT_DX8 -#include "lightmappedgeneric_flashlight_vs11.inc" -#include "flashlight_ps11.inc" -#endif - -#ifdef STDSHADER_DX9_DLL_EXPORT -#include "lightmappedgeneric_flashlight_vs20.inc" -#endif -#ifdef STDSHADER_DX9_DLL_EXPORT -#include "flashlight_ps20.inc" -#include "flashlight_ps20b.inc" -#endif -#include "unlitgeneric_vs11.inc" -#include "VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.inc" -#include "VertexLitGeneric_EnvmappedBumpmap_NoLighting.inc" -#include "vertexlitgeneric_flashlight_vs11.inc" -#include "LightmappedGeneric_BaseTexture.inc" -#include "LightmappedGeneric_BumpmappedLightmap_Base_ps14.inc" -#include "LightmappedGeneric_BumpmappedLightmap_Blend_ps14.inc" -#include "lightmappedgeneric_bumpmappedenvmap_ps14.inc" -#include "lightmappedgeneric_bumpmappedenvmap.inc" -#include "lightmappedgeneric_basetextureblend.inc" -#include "lightmappedgeneric_bumpmappedlightmap.inc" -#endif // GAME_SHADER_DLL - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); - -// These functions are to be called from the shaders. - -//----------------------------------------------------------------------------- -// Pixel and vertex shader constants.... -//----------------------------------------------------------------------------- -void CBaseVSShader::SetPixelShaderConstant( int pixelReg, int constantVar, int constantVar2 ) -{ - Assert( !IsSnapshotting() ); - if ((!s_ppParams) || (constantVar == -1) || (constantVar2 == -1)) - return; - - IMaterialVar* pPixelVar = s_ppParams[constantVar]; - Assert( pPixelVar ); - IMaterialVar* pPixelVar2 = s_ppParams[constantVar2]; - Assert( pPixelVar2 ); - - float val[4]; - if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - { - pPixelVar->GetVecValue( val, 3 ); - } - else - { - val[0] = val[1] = val[2] = pPixelVar->GetFloatValue(); - } - - val[3] = pPixelVar2->GetFloatValue(); - s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); -} - -void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar, int constantVar2 ) -{ - Assert( !IsSnapshotting() ); - if ((!s_ppParams) || (constantVar == -1) || (constantVar2 == -1)) - return; - - IMaterialVar* pPixelVar = s_ppParams[constantVar]; - Assert( pPixelVar ); - IMaterialVar* pPixelVar2 = s_ppParams[constantVar2]; - Assert( pPixelVar2 ); - - float val[4]; - if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - { - pPixelVar->GetVecValue( val, 3 ); - } - else - { - val[0] = val[1] = val[2] = pPixelVar->GetFloatValue(); - } - - val[3] = pPixelVar2->GetFloatValue(); - val[0] = val[0] > 1.0f ? val[0] : GammaToLinear( val[0] ); - val[1] = val[1] > 1.0f ? val[1] : GammaToLinear( val[1] ); - val[2] = val[2] > 1.0f ? val[2] : GammaToLinear( val[2] ); - - s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); -} - -void CBaseVSShader::SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue ) -{ - Assert( !IsSnapshotting() ); - if ((!s_ppParams) || (constantVar == -1)) - return; - - IMaterialVar* pPixelVar = s_ppParams[constantVar]; - Assert( pPixelVar ); - - float val[4]; - if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pPixelVar->GetVecValue( val, 4 ); - else - val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue(); - val[3]=fWValue; - s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); -} - -void CBaseVSShader::SetPixelShaderConstant( int pixelReg, int constantVar ) -{ - Assert( !IsSnapshotting() ); - if ((!s_ppParams) || (constantVar == -1)) - return; - - IMaterialVar* pPixelVar = s_ppParams[constantVar]; - Assert( pPixelVar ); - - float val[4]; - if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pPixelVar->GetVecValue( val, 4 ); - else - val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue(); - s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); -} - -void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar ) -{ - Assert( !IsSnapshotting() ); - if ((!s_ppParams) || (constantVar == -1)) - return; - - IMaterialVar* pPixelVar = s_ppParams[constantVar]; - Assert( pPixelVar ); - - float val[4]; - if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pPixelVar->GetVecValue( val, 4 ); - else - val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue(); - - val[0] = val[0] > 1.0f ? val[0] : GammaToLinear( val[0] ); - val[1] = val[1] > 1.0f ? val[1] : GammaToLinear( val[1] ); - val[2] = val[2] > 1.0f ? val[2] : GammaToLinear( val[2] ); - - s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); -} - -void CBaseVSShader::SetVertexShaderConstantGammaToLinear( int var, float const* pVec, int numConst, bool bForce ) -{ - int i; - for( i = 0; i < numConst; i++ ) - { - float vec[4]; - vec[0] = pVec[i*4+0] > 1.0f ? pVec[i*4+0] : GammaToLinear( pVec[i*4+0] ); - vec[1] = pVec[i*4+1] > 1.0f ? pVec[i*4+1] : GammaToLinear( pVec[i*4+1] ); - vec[2] = pVec[i*4+2] > 1.0f ? pVec[i*4+2] : GammaToLinear( pVec[i*4+2] ); - vec[3] = pVec[i*4+3]; - - s_pShaderAPI->SetVertexShaderConstant( var + i, vec, 1, bForce ); - } -} - -void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int var, float const* pVec, int numConst, bool bForce ) -{ - int i; - for( i = 0; i < numConst; i++ ) - { - float vec[4]; - vec[0] = pVec[i*4+0] > 1.0f ? pVec[i*4+0] : GammaToLinear( pVec[i*4+0] ); - vec[1] = pVec[i*4+1] > 1.0f ? pVec[i*4+1] : GammaToLinear( pVec[i*4+1] ); - vec[2] = pVec[i*4+2] > 1.0f ? pVec[i*4+2] : GammaToLinear( pVec[i*4+2] ); - - vec[3] = pVec[i*4+3]; - - s_pShaderAPI->SetPixelShaderConstant( var + i, vec, 1, bForce ); - } -} - -// GR - special version with fix for const/lerp issue -void CBaseVSShader::SetPixelShaderConstantFudge( int pixelReg, int constantVar ) -{ - Assert( !IsSnapshotting() ); - if ((!s_ppParams) || (constantVar == -1)) - return; - - IMaterialVar* pPixelVar = s_ppParams[constantVar]; - Assert( pPixelVar ); - - float val[4]; - if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - { - pPixelVar->GetVecValue( val, 4 ); - val[0] = val[0] * 0.992f + 0.0078f; - val[1] = val[1] * 0.992f + 0.0078f; - val[2] = val[2] * 0.992f + 0.0078f; - val[3] = val[3] * 0.992f + 0.0078f; - } - else - val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue() * 0.992f + 0.0078f; - s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); -} - -void CBaseVSShader::SetVertexShaderConstant( int vertexReg, int constantVar ) -{ - Assert( !IsSnapshotting() ); - if ((!s_ppParams) || (constantVar == -1)) - return; - - IMaterialVar* pVertexVar = s_ppParams[constantVar]; - Assert( pVertexVar ); - - float val[4]; - if (pVertexVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pVertexVar->GetVecValue( val, 4 ); - else - val[0] = val[1] = val[2] = val[3] = pVertexVar->GetFloatValue(); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, val ); -} - -//----------------------------------------------------------------------------- -// Sets normalized light color for pixel shaders. -//----------------------------------------------------------------------------- -void CBaseVSShader::SetPixelShaderLightColors( int pixelReg ) -{ - int i; - int maxLights = s_pShaderAPI->GetMaxLights(); - for( i = 0; i < maxLights; i++ ) - { - const LightDesc_t & lightDesc = s_pShaderAPI->GetLight( i ); - if( lightDesc.m_Type != MATERIAL_LIGHT_DISABLE ) - { - Vector color( lightDesc.m_Color[0], lightDesc.m_Color[1], lightDesc.m_Color[2] ); - VectorNormalize( color ); - float val[4] = { color[0], color[1], color[2], 1.0f }; - s_pShaderAPI->SetPixelShaderConstant( pixelReg + i, val, 1 ); - } - else - { - float zero[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - s_pShaderAPI->SetPixelShaderConstant( pixelReg + i, zero, 1 ); - } - } -} - - -//----------------------------------------------------------------------------- -// Sets vertex shader texture transforms -//----------------------------------------------------------------------------- -void CBaseVSShader::SetVertexShaderTextureTranslation( int vertexReg, int translationVar ) -{ - float offset[2] = {0, 0}; - - IMaterialVar* pTranslationVar = s_ppParams[translationVar]; - if (pTranslationVar) - { - if (pTranslationVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pTranslationVar->GetVecValue( offset, 2 ); - else - offset[0] = offset[1] = pTranslationVar->GetFloatValue(); - } - - Vector4D translation[2]; - translation[0].Init( 1.0f, 0.0f, 0.0f, offset[0] ); - translation[1].Init( 0.0f, 1.0f, 0.0f, offset[1] ); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, translation[0].Base(), 2 ); -} - -void CBaseVSShader::SetVertexShaderTextureScale( int vertexReg, int scaleVar ) -{ - float scale[2] = {1, 1}; - - IMaterialVar* pScaleVar = s_ppParams[scaleVar]; - if (pScaleVar) - { - if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pScaleVar->GetVecValue( scale, 2 ); - else if (pScaleVar->IsDefined()) - scale[0] = scale[1] = pScaleVar->GetFloatValue(); - } - - Vector4D scaleMatrix[2]; - scaleMatrix[0].Init( scale[0], 0.0f, 0.0f, 0.0f ); - scaleMatrix[1].Init( 0.0f, scale[1], 0.0f, 0.0f ); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, scaleMatrix[0].Base(), 2 ); -} - -void CBaseVSShader::SetVertexShaderTextureTransform( int vertexReg, int transformVar ) -{ - Vector4D transformation[2]; - IMaterialVar* pTransformationVar = s_ppParams[transformVar]; - if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) - { - const VMatrix &mat = pTransformationVar->GetMatrixValue(); - transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); - transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); - } - else - { - transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); - transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); - } - s_pShaderAPI->SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 ); -} - -void CBaseVSShader::SetVertexShaderTextureScaledTransform( int vertexReg, int transformVar, int scaleVar ) -{ - Vector4D transformation[2]; - IMaterialVar* pTransformationVar = s_ppParams[transformVar]; - if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) - { - const VMatrix &mat = pTransformationVar->GetMatrixValue(); - transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); - transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); - } - else - { - transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); - transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); - } - - Vector2D scale( 1, 1 ); - IMaterialVar* pScaleVar = s_ppParams[scaleVar]; - if (pScaleVar) - { - if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pScaleVar->GetVecValue( scale.Base(), 2 ); - else if (pScaleVar->IsDefined()) - scale[0] = scale[1] = pScaleVar->GetFloatValue(); - } - - // Apply the scaling - transformation[0][0] *= scale[0]; - transformation[0][1] *= scale[1]; - transformation[1][0] *= scale[0]; - transformation[1][1] *= scale[1]; - transformation[0][3] *= scale[0]; - transformation[1][3] *= scale[1]; - s_pShaderAPI->SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 ); -} - - -//----------------------------------------------------------------------------- -// Sets pixel shader texture transforms -//----------------------------------------------------------------------------- -void CBaseVSShader::SetPixelShaderTextureTranslation( int pixelReg, int translationVar ) -{ - float offset[2] = {0, 0}; - - IMaterialVar* pTranslationVar = s_ppParams[translationVar]; - if (pTranslationVar) - { - if (pTranslationVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pTranslationVar->GetVecValue( offset, 2 ); - else - offset[0] = offset[1] = pTranslationVar->GetFloatValue(); - } - - Vector4D translation[2]; - translation[0].Init( 1.0f, 0.0f, 0.0f, offset[0] ); - translation[1].Init( 0.0f, 1.0f, 0.0f, offset[1] ); - s_pShaderAPI->SetPixelShaderConstant( pixelReg, translation[0].Base(), 2 ); -} - -void CBaseVSShader::SetPixelShaderTextureScale( int pixelReg, int scaleVar ) -{ - float scale[2] = {1, 1}; - - IMaterialVar* pScaleVar = s_ppParams[scaleVar]; - if (pScaleVar) - { - if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pScaleVar->GetVecValue( scale, 2 ); - else if (pScaleVar->IsDefined()) - scale[0] = scale[1] = pScaleVar->GetFloatValue(); - } - - Vector4D scaleMatrix[2]; - scaleMatrix[0].Init( scale[0], 0.0f, 0.0f, 0.0f ); - scaleMatrix[1].Init( 0.0f, scale[1], 0.0f, 0.0f ); - s_pShaderAPI->SetPixelShaderConstant( pixelReg, scaleMatrix[0].Base(), 2 ); -} - -void CBaseVSShader::SetPixelShaderTextureTransform( int pixelReg, int transformVar ) -{ - Vector4D transformation[2]; - IMaterialVar* pTransformationVar = s_ppParams[transformVar]; - if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) - { - const VMatrix &mat = pTransformationVar->GetMatrixValue(); - transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); - transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); - } - else - { - transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); - transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); - } - s_pShaderAPI->SetPixelShaderConstant( pixelReg, transformation[0].Base(), 2 ); -} - -void CBaseVSShader::SetPixelShaderTextureScaledTransform( int pixelReg, int transformVar, int scaleVar ) -{ - Vector4D transformation[2]; - IMaterialVar* pTransformationVar = s_ppParams[transformVar]; - if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) - { - const VMatrix &mat = pTransformationVar->GetMatrixValue(); - transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); - transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); - } - else - { - transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); - transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); - } - - Vector2D scale( 1, 1 ); - IMaterialVar* pScaleVar = s_ppParams[scaleVar]; - if (pScaleVar) - { - if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pScaleVar->GetVecValue( scale.Base(), 2 ); - else if (pScaleVar->IsDefined()) - scale[0] = scale[1] = pScaleVar->GetFloatValue(); - } - - // Apply the scaling - transformation[0][0] *= scale[0]; - transformation[0][1] *= scale[1]; - transformation[1][0] *= scale[0]; - transformation[1][1] *= scale[1]; - transformation[0][3] *= scale[0]; - transformation[1][3] *= scale[1]; - s_pShaderAPI->SetPixelShaderConstant( pixelReg, transformation[0].Base(), 2 ); -} - - -//----------------------------------------------------------------------------- -// Moves a matrix into vertex shader constants -//----------------------------------------------------------------------------- -void CBaseVSShader::SetVertexShaderMatrix3x4( int vertexReg, int matrixVar ) -{ - IMaterialVar* pTranslationVar = s_ppParams[matrixVar]; - if (pTranslationVar) - { - s_pShaderAPI->SetVertexShaderConstant( vertexReg, &pTranslationVar->GetMatrixValue( )[0][0], 3 ); - } - else - { - VMatrix matrix; - MatrixSetIdentity( matrix ); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, &matrix[0][0], 3 ); - } -} - -void CBaseVSShader::SetVertexShaderMatrix4x4( int vertexReg, int matrixVar ) -{ - IMaterialVar* pTranslationVar = s_ppParams[matrixVar]; - if (pTranslationVar) - { - s_pShaderAPI->SetVertexShaderConstant( vertexReg, &pTranslationVar->GetMatrixValue( )[0][0], 4 ); - } - else - { - VMatrix matrix; - MatrixSetIdentity( matrix ); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, &matrix[0][0], 4 ); - } -} - - -//----------------------------------------------------------------------------- -// Loads the view matrix into pixel shader constants -//----------------------------------------------------------------------------- -void CBaseVSShader::LoadViewMatrixIntoVertexShaderConstant( int vertexReg ) -{ - VMatrix mat, transpose; - s_pShaderAPI->GetMatrix( MATERIAL_VIEW, mat.m[0] ); - - MatrixTranspose( mat, transpose ); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, transpose.m[0], 3 ); -} - - -//----------------------------------------------------------------------------- -// Loads the projection matrix into pixel shader constants -//----------------------------------------------------------------------------- -void CBaseVSShader::LoadProjectionMatrixIntoVertexShaderConstant( int vertexReg ) -{ - VMatrix mat, transpose; - s_pShaderAPI->GetMatrix( MATERIAL_PROJECTION, mat.m[0] ); - - MatrixTranspose( mat, transpose ); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, transpose.m[0], 4 ); -} - - -//----------------------------------------------------------------------------- -// Loads the projection matrix into pixel shader constants -//----------------------------------------------------------------------------- -void CBaseVSShader::LoadModelViewMatrixIntoVertexShaderConstant( int vertexReg ) -{ - VMatrix view, model, modelView, transpose; - s_pShaderAPI->GetMatrix( MATERIAL_MODEL, model.m[0] ); - MatrixTranspose( model, model ); - s_pShaderAPI->GetMatrix( MATERIAL_VIEW, view.m[0] ); - MatrixTranspose( view, view ); - - MatrixMultiply( view, model, modelView ); - s_pShaderAPI->SetVertexShaderConstant( vertexReg, modelView.m[0], 3 ); -} - -//----------------------------------------------------------------------------- -// Loads a scale/offset version of the viewport transform into the specified constant. -//----------------------------------------------------------------------------- -void CBaseVSShader::LoadViewportTransformScaledIntoVertexShaderConstant( int vertexReg ) -{ - ShaderViewport_t viewport; - - s_pShaderAPI->GetViewports( &viewport, 1 ); - - int bbWidth = 0, - bbHeight = 0; - - s_pShaderAPI->GetBackBufferDimensions( bbWidth, bbHeight ); - - // (x, y, z, w) = (Width / bbWidth, Height / bbHeight, MinX / bbWidth, MinY / bbHeight) - Vector4D viewportTransform( - 1.0f * viewport.m_nWidth / bbWidth, - 1.0f * viewport.m_nHeight / bbHeight, - 1.0f * viewport.m_nTopLeftX / bbWidth, - 1.0f * viewport.m_nTopLeftY / bbHeight - ); - - s_pShaderAPI->SetVertexShaderConstant( vertexReg, viewportTransform.Base() ); -} - - - -//----------------------------------------------------------------------------- -// Loads bump lightmap coordinates into the pixel shader -//----------------------------------------------------------------------------- -void CBaseVSShader::LoadBumpLightmapCoordinateAxes_PixelShader( int pixelReg ) -{ - Vector4D basis[3]; - for (int i = 0; i < 3; ++i) - { - memcpy( &basis[i], &g_localBumpBasis[i], 3 * sizeof(float) ); - basis[i][3] = 0.0f; - } - s_pShaderAPI->SetPixelShaderConstant( pixelReg, (float*)basis, 3 ); -} - - -//----------------------------------------------------------------------------- -// Loads bump lightmap coordinates into the pixel shader -//----------------------------------------------------------------------------- -void CBaseVSShader::LoadBumpLightmapCoordinateAxes_VertexShader( int vertexReg ) -{ - Vector4D basis[3]; - - // transpose - int i; - for (i = 0; i < 3; ++i) - { - basis[i][0] = g_localBumpBasis[0][i]; - basis[i][1] = g_localBumpBasis[1][i]; - basis[i][2] = g_localBumpBasis[2][i]; - basis[i][3] = 0.0f; - } - s_pShaderAPI->SetVertexShaderConstant( vertexReg, (float*)basis, 3 ); - for (i = 0; i < 3; ++i) - { - memcpy( &basis[i], &g_localBumpBasis[i], 3 * sizeof(float) ); - basis[i][3] = 0.0f; - } - s_pShaderAPI->SetVertexShaderConstant( vertexReg + 3, (float*)basis, 3 ); -} - - -//----------------------------------------------------------------------------- -// Helper methods for pixel shader overbrighting -//----------------------------------------------------------------------------- -void CBaseVSShader::EnablePixelShaderOverbright( int reg, bool bEnable, bool bDivideByTwo ) -{ - // can't have other overbright values with pixel shaders as it stands. - float v[4]; - if( bEnable ) - { - v[0] = v[1] = v[2] = v[3] = bDivideByTwo ? OVERBRIGHT / 2.0f : OVERBRIGHT; - } - else - { - v[0] = v[1] = v[2] = v[3] = bDivideByTwo ? 1.0f / 2.0f : 1.0f; - } - s_pShaderAPI->SetPixelShaderConstant( reg, v, 1 ); -} - - -//----------------------------------------------------------------------------- -// Helper for dealing with modulation -//----------------------------------------------------------------------------- -void CBaseVSShader::SetModulationVertexShaderDynamicState() -{ - float color[4] = { 1.0, 1.0, 1.0, 1.0 }; - ComputeModulationColor( color ); - s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); -} - -void CBaseVSShader::SetModulationPixelShaderDynamicState( int modulationVar ) -{ - float color[4] = { 1.0, 1.0, 1.0, 1.0 }; - ComputeModulationColor( color ); - s_pShaderAPI->SetPixelShaderConstant( modulationVar, color ); -} - -void CBaseVSShader::SetModulationPixelShaderDynamicState_LinearColorSpace( int modulationVar ) -{ - float color[4] = { 1.0, 1.0, 1.0, 1.0 }; - ComputeModulationColor( color ); - color[0] = color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ); - color[1] = color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ); - color[2] = color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ); - - s_pShaderAPI->SetPixelShaderConstant( modulationVar, color ); -} - -void CBaseVSShader::SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( int modulationVar, float flScale ) -{ - float color[4] = { 1.0, 1.0, 1.0, 1.0 }; - ComputeModulationColor( color ); - color[0] = ( color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ) ) * flScale; - color[1] = ( color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ) ) * flScale; - color[2] = ( color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ) ) * flScale; - - s_pShaderAPI->SetPixelShaderConstant( modulationVar, color ); -} - - -//----------------------------------------------------------------------------- -// Converts a color + alpha into a vector4 -//----------------------------------------------------------------------------- -void CBaseVSShader::ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color ) -{ - color.Init( 1.0, 1.0, 1.0, 1.0 ); - if ( colorVar != -1 ) - { - IMaterialVar* pColorVar = s_ppParams[colorVar]; - if ( pColorVar->GetType() == MATERIAL_VAR_TYPE_VECTOR ) - { - pColorVar->GetVecValue( color.Base(), 3 ); - } - else - { - color[0] = color[1] = color[2] = pColorVar->GetFloatValue(); - } - } - if ( alphaVar != -1 ) - { - float flAlpha = s_ppParams[alphaVar]->GetFloatValue(); - color[3] = clamp( flAlpha, 0.0f, 1.0f ); - } -} - - -//----------------------------------------------------------------------------- -// Sets a color + alpha into shader constants -//----------------------------------------------------------------------------- -void CBaseVSShader::SetColorVertexShaderConstant( int nVertexReg, int colorVar, int alphaVar ) -{ - Vector4D color; - ColorVarsToVector( colorVar, alphaVar, color ); - s_pShaderAPI->SetVertexShaderConstant( nVertexReg, color.Base() ); -} - -void CBaseVSShader::SetColorPixelShaderConstant( int nPixelReg, int colorVar, int alphaVar ) -{ - Vector4D color; - ColorVarsToVector( colorVar, alphaVar, color ); - s_pShaderAPI->SetPixelShaderConstant( nPixelReg, color.Base() ); -} - -#ifdef _DEBUG -ConVar mat_envmaptintoverride( "mat_envmaptintoverride", "-1" ); -ConVar mat_envmaptintscale( "mat_envmaptintscale", "-1" ); -#endif - -//----------------------------------------------------------------------------- -// Helpers for dealing with envmap tint -//----------------------------------------------------------------------------- -// set alphaVar to -1 to ignore it. -void CBaseVSShader::SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear ) -{ - float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - if( g_pConfig->bShowSpecular && mat_fullbright.GetInt() != 2 ) - { - IMaterialVar* pAlphaVar = NULL; - if( alphaVar >= 0 ) - { - pAlphaVar = s_ppParams[alphaVar]; - } - if( pAlphaVar ) - { - color[3] = pAlphaVar->GetFloatValue(); - } - - IMaterialVar* pTintVar = s_ppParams[tintVar]; -#ifdef _DEBUG - pTintVar->GetVecValue( color, 3 ); - - float envmapTintOverride = mat_envmaptintoverride.GetFloat(); - float envmapTintScaleOverride = mat_envmaptintscale.GetFloat(); - - if( envmapTintOverride != -1.0f ) - { - color[0] = color[1] = color[2] = envmapTintOverride; - } - if( envmapTintScaleOverride != -1.0f ) - { - color[0] *= envmapTintScaleOverride; - color[1] *= envmapTintScaleOverride; - color[2] *= envmapTintScaleOverride; - } - - if( bConvertFromGammaToLinear ) - { - color[0] = color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ); - color[1] = color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ); - color[2] = color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ); - } -#else - if( bConvertFromGammaToLinear ) - { - pTintVar->GetLinearVecValue( color, 3 ); - } - else - { - pTintVar->GetVecValue( color, 3 ); - } -#endif - } - else - { - color[0] = color[1] = color[2] = color[3] = 0.0f; - } - s_pShaderAPI->SetPixelShaderConstant( pixelReg, color, 1 ); -} - -void CBaseVSShader::SetAmbientCubeDynamicStateVertexShader( ) -{ - s_pShaderAPI->SetVertexShaderStateAmbientLightCube(); -} - -float CBaseVSShader::GetAmbientLightCubeLuminance( ) -{ - return s_pShaderAPI->GetAmbientLightCubeLuminance(); -} - -#ifndef GAME_SHADER_DLL -const char *CBaseVSShader::UnlitGeneric_ComputePixelShaderName( bool bMask, - bool bEnvmap, - bool bBaseTexture, - bool bBaseAlphaEnvmapMask, - bool bDetail, - bool bDetailMultiplyMode, - bool bMaskBaseByDetailAlpha ) -{ - static char const* s_pPixelShaders[] = - { - "UnlitGeneric_NoTexture", - "UnlitGeneric", - "UnlitGeneric_EnvMapNoTexture", - "UnlitGeneric_EnvMap", - "UnlitGeneric_NoTexture", - "UnlitGeneric", - "UnlitGeneric_EnvMapMaskNoTexture", - "UnlitGeneric_EnvMapMask", - - // Detail texture - // The other commented-out versions are used if we want to - // apply the detail *after* the environment map is added - "UnlitGeneric_DetailNoTexture", - "UnlitGeneric_Detail", - "UnlitGeneric_EnvMapNoTexture", //"UnlitGeneric_DetailEnvMapNoTexture", - "UnlitGeneric_DetailEnvMap", - "UnlitGeneric_DetailNoTexture", - "UnlitGeneric_Detail", - "UnlitGeneric_EnvMapMaskNoTexture", //"UnlitGeneric_DetailEnvMapMaskNoTexture", - "UnlitGeneric_DetailEnvMapMask", - }; - - // handle hud elements - if ( bDetail & bDetailMultiplyMode ) - return "alphadist_ps11"; - - if ( bDetail & bMaskBaseByDetailAlpha ) - return "UnlitGeneric_MaskBaseByDetailAlpha_ps11"; - - if (!bMask && bEnvmap && bBaseTexture && bBaseAlphaEnvmapMask) - { - if (!bDetail) - return "UnlitGeneric_BaseAlphaMaskedEnvMap"; - else - return "UnlitGeneric_DetailBaseAlphaMaskedEnvMap"; - } - else - { - int pshIndex = 0; - if (bBaseTexture) - pshIndex |= 0x1; - if (bEnvmap) - pshIndex |= 0x2; - if (bMask) - pshIndex |= 0x4; - if (bDetail) - pshIndex |= 0x8; - return s_pPixelShaders[pshIndex]; - } -} - - -//----------------------------------------------------------------------------- -// Sets up hw morphing state for the vertex shader -//----------------------------------------------------------------------------- -void CBaseVSShader::SetHWMorphVertexShaderState( int nDimConst, int nSubrectConst, VertexTextureSampler_t morphSampler ) -{ -#ifndef _X360 - if ( !s_pShaderAPI->IsHWMorphingEnabled() ) - return; - - int nMorphWidth, nMorphHeight; - s_pShaderAPI->GetStandardTextureDimensions( &nMorphWidth, &nMorphHeight, TEXTURE_MORPH_ACCUMULATOR ); - - int nDim = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_4TUPLE_COUNT ); - float pMorphAccumSize[4] = { nMorphWidth, nMorphHeight, nDim, 0.0f }; - s_pShaderAPI->SetVertexShaderConstant( nDimConst, pMorphAccumSize ); - - int nXOffset = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_X_OFFSET ); - int nYOffset = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_Y_OFFSET ); - int nWidth = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_WIDTH ); - int nHeight = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_HEIGHT ); - float pMorphAccumSubrect[4] = { nXOffset, nYOffset, nWidth, nHeight }; - s_pShaderAPI->SetVertexShaderConstant( nSubrectConst, pMorphAccumSubrect ); - - s_pShaderAPI->BindStandardVertexTexture( morphSampler, TEXTURE_MORPH_ACCUMULATOR ); -#endif -} - - -//----------------------------------------------------------------------------- -// Vertex shader unlit generic pass -//----------------------------------------------------------------------------- -void CBaseVSShader::VertexShaderUnlitGenericPass( int baseTextureVar, int frameVar, - int baseTextureTransformVar, - int detailVar, int detailTransform, - bool bDetailTransformIsScale, - int envmapVar, int envMapFrameVar, - int envmapMaskVar, int envmapMaskFrameVar, - int envmapMaskScaleVar, int envmapTintVar, - int alphaTestReferenceVar, - int nDetailBlendModeVar, - int nOutlineVar, - int nOutlineColorVar, - int nOutlineStartVar, - int nOutlineEndVar, - int nSeparateDetailUVsVar ) -{ - IMaterialVar** params = s_ppParams; - - bool bBaseAlphaEnvmapMask = IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK); - bool bEnvmap = (envmapVar >= 0) && params[envmapVar]->IsTexture(); - bool bMask = false; - if (bEnvmap && (envmapMaskVar >= 0)) - { - bMask = params[envmapMaskVar]->IsTexture(); - } - bool bDetail = (detailVar >= 0) && params[detailVar]->IsTexture(); - bool bBaseTexture = (baseTextureVar >= 0) && params[baseTextureVar]->IsTexture(); - bool bVertexColor = IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR); - bool bEnvmapCameraSpace = IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE); - bool bEnvmapSphere = IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE); - - bool bDetailMultiply = ( nDetailBlendModeVar >= 0 ) && ( params[nDetailBlendModeVar]->GetIntValue() == 8 ); - bool bMaskBaseByDetailAlpha = ( nDetailBlendModeVar >= 0 ) && ( params[nDetailBlendModeVar]->GetIntValue() == 9 ); - bool bSeparateDetailUVs = ( nSeparateDetailUVsVar >= 0 ) && ( params[nSeparateDetailUVsVar]->GetIntValue() != 0 ); - - if (IsSnapshotting()) - { - // Alpha test - s_pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); - - if( alphaTestReferenceVar != -1 && params[alphaTestReferenceVar]->GetFloatValue() > 0.0f ) - { - s_pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[alphaTestReferenceVar]->GetFloatValue() ); - } - - // Base texture on stage 0 - if (bBaseTexture) - { - s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - } - - if (bDetail) - { - s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - } - - if (bEnvmap) - { - // envmap on stage 1 - s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - - // envmapmask on stage 2 - if (bMask || bBaseAlphaEnvmapMask ) - s_pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - } - - if (bBaseTexture) - SetDefaultBlendingShadowState( baseTextureVar, true ); - else if (bMask) - SetDefaultBlendingShadowState( envmapMaskVar, false ); - else - SetDefaultBlendingShadowState(); - - int fmt = VERTEX_POSITION; - if( bEnvmap ) - fmt |= VERTEX_NORMAL; - if ( bVertexColor ) - fmt |= VERTEX_COLOR; - - int numTexCoords = 1; - if( bSeparateDetailUVs ) - { - numTexCoords = 2; - } - - s_pShaderShadow->VertexShaderVertexFormat( fmt, numTexCoords, 0, 0 ); - const char *pshName = UnlitGeneric_ComputePixelShaderName( - bMask, - bEnvmap, - bBaseTexture, - bBaseAlphaEnvmapMask, - bDetail, - bDetailMultiply, - bMaskBaseByDetailAlpha ); - s_pShaderShadow->SetPixelShader( pshName ); - - // Compute the vertex shader index. - unlitgeneric_vs11_Static_Index vshIndex; - vshIndex.SetDETAIL( bDetail ); - vshIndex.SetENVMAP( bEnvmap ); - vshIndex.SetENVMAPCAMERASPACE( bEnvmap && bEnvmapCameraSpace ); - vshIndex.SetENVMAPSPHERE( bEnvmap && bEnvmapSphere ); - vshIndex.SetVERTEXCOLOR( bVertexColor ); - vshIndex.SetSEPARATEDETAILUVS( bSeparateDetailUVs ); - s_pShaderShadow->SetVertexShader( "unlitgeneric_vs11", vshIndex.GetIndex() ); - - DefaultFog(); - } - else - { - if ( s_pShaderAPI->InFlashlightMode() ) // Not snapshotting && flashlight pass - { - Draw( false ); - return; - } - - if (bBaseTexture) - { - BindTexture( SHADER_SAMPLER0, baseTextureVar, frameVar ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, baseTextureTransformVar ); - } - - if (bDetail) - { - BindTexture( SHADER_SAMPLER3, detailVar, frameVar ); - - if (bDetailTransformIsScale) - { - SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, baseTextureTransformVar, detailTransform ); - } - else - { - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, detailTransform ); - } - } - - if (bEnvmap) - { - BindTexture( SHADER_SAMPLER1, envmapVar, envMapFrameVar ); - - if (bMask || bBaseAlphaEnvmapMask) - { - if (bMask) - BindTexture( SHADER_SAMPLER2, envmapMaskVar, envmapMaskFrameVar ); - else - BindTexture( SHADER_SAMPLER2, baseTextureVar, frameVar ); - - SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, baseTextureTransformVar, envmapMaskScaleVar ); - } - - SetEnvMapTintPixelShaderDynamicState( 2, envmapTintVar, -1 ); - - if (bEnvmapSphere || IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE)) - { - LoadViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_VIEWMODEL ); - } - } - - SetModulationVertexShaderDynamicState(); - - float flConsts[12]={ 0, 0, 0, 1, // color - 0, 0, 0, 0, // max - 0, 0, 0, .5, // min - }; - - // set up outline pixel shader constants - if ( bDetailMultiply && ( nOutlineVar != -1 ) && ( params[nOutlineVar]->GetIntValue() ) ) - { - if ( nOutlineColorVar != -1 ) - params[nOutlineColorVar]->GetVecValue( flConsts, 3 ); - if ( nOutlineEndVar != -1 ) - flConsts[7] = params[nOutlineEndVar]->GetFloatValue(); - if ( nOutlineStartVar != -1 ) - flConsts[11] = params[nOutlineStartVar]->GetFloatValue(); - } - - s_pShaderAPI->SetPixelShaderConstant( 0, flConsts, 3 ); - - // Compute the vertex shader index. - unlitgeneric_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - vshIndex.SetSKINNING( s_pShaderAPI->GetCurrentNumBones() > 0 ); - s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - - Draw(); -} - - -void CBaseVSShader::DrawWorldBaseTexture( int baseTextureVar, int baseTextureTransformVar, - int frameVar, int colorVar, int alphaVar ) -{ - if( IsSnapshotting() ) - { - s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - s_pShaderShadow->VertexShaderVertexFormat( - VERTEX_POSITION, 1, 0, 0 ); - s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BaseTexture" ); - SetNormalBlendingShadowState(); - lightmappedgeneric_basetexture_Static_Index vshIndex; - s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BaseTexture", vshIndex.GetIndex() ); - - FogToOOOverbright(); - } - else - { - IMaterialVar** params = s_ppParams; - bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - if( bLightingOnly ) - { - s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); - } - else - { - BindTexture( SHADER_SAMPLER0, baseTextureVar, frameVar ); - } - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, baseTextureTransformVar ); - SetColorPixelShaderConstant( 0, colorVar, alphaVar ); - lightmappedgeneric_basetexture_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); -} - -void CBaseVSShader::DrawWorldBumpedDiffuseLighting( int bumpmapVar, int bumpFrameVar, - int bumpTransformVar, bool bMultiply, - bool bSSBump ) -{ - if( IsSnapshotting() ) - { - s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - if( bMultiply ) - { - s_pShaderShadow->EnableBlending( true ); - SingleTextureLightmapBlendMode(); - } - s_pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 3, 0, 0 ); - - lightmappedgeneric_bumpmappedlightmap_Static_Index vshIndex; - s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BumpmappedLightmap", vshIndex.GetIndex() ); - - if ( bSSBump ) - s_pShaderShadow->SetPixelShader( "LightmappedGeneric_SSBumpmappedLightmap" ); - else - s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BumpmappedLightmap" ); - FogToFogColor(); - } - else - { - if( !g_pConfig->m_bFastNoBump ) - { - BindTexture( SHADER_SAMPLER0, bumpmapVar, bumpFrameVar ); - } - else - { - s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_NORMALMAP_FLAT ); - } - LoadBumpLightmapCoordinateAxes_PixelShader( 0 ); - s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP_BUMPED ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, bumpTransformVar ); - SetModulationPixelShaderDynamicState( 3 ); - - lightmappedgeneric_bumpmappedlightmap_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); -} - -void CBaseVSShader::DrawWorldBumpedDiffuseLighting_Base_ps14( int bumpmapVar, int bumpFrameVar, - int bumpTransformVar, - int baseTextureVar, int baseTextureTransformVar, int frameVar ) -{ - if( IsSnapshotting() ) - { - s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); - s_pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 3, 0, 0 ); - - lightmappedgeneric_bumpmappedlightmap_base_ps14_Static_Index vshIndex; - s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BumpmappedLightmap_Base_ps14", vshIndex.GetIndex() ); - - s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BumpmappedLightmap_Base_ps14" ); - FogToFogColor(); - } - else - { - if( !g_pConfig->m_bFastNoBump ) - { - BindTexture( SHADER_SAMPLER0, bumpmapVar, bumpFrameVar ); - } - else - { - s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_NORMALMAP_FLAT ); - } - LoadBumpLightmapCoordinateAxes_PixelShader( 0 ); - s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP_BUMPED ); - BindTexture( SHADER_SAMPLER4, baseTextureVar, frameVar ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, bumpTransformVar ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, baseTextureTransformVar ); - SetModulationPixelShaderDynamicState( 3 ); - - lightmappedgeneric_bumpmappedlightmap_base_ps14_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); -} - -void CBaseVSShader::DrawWorldBumpedDiffuseLighting_Blend_ps14( int bumpmapVar, int bumpFrameVar, - int bumpTransformVar, - int baseTextureVar, int baseTextureTransformVar, - int baseTextureFrameVar, - int baseTexture2Var, int baseTextureTransform2Var, - int baseTextureFrame2Var) -{ - if( IsSnapshotting() ) - { - s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); - s_pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 3, 0, 0 ); - - lightmappedgeneric_bumpmappedlightmap_blend_ps14_Static_Index vshIndex; - s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BumpmappedLightmap_Blend_ps14", vshIndex.GetIndex() ); - - s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BumpmappedLightmap_Blend_ps14" ); - FogToFogColor(); - } - else - { - if( !g_pConfig->m_bFastNoBump ) - { - BindTexture( SHADER_SAMPLER0, bumpmapVar, bumpFrameVar ); - } - else - { - s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_NORMALMAP_FLAT ); - } - LoadBumpLightmapCoordinateAxes_PixelShader( 0 ); - s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP_BUMPED ); - BindTexture( SHADER_SAMPLER4, baseTextureVar, baseTextureFrameVar ); - BindTexture( SHADER_SAMPLER5, baseTexture2Var, baseTextureFrame2Var ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, bumpTransformVar ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, baseTextureTransformVar ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, baseTextureTransform2Var ); - SetModulationPixelShaderDynamicState( 3 ); - - lightmappedgeneric_bumpmappedlightmap_blend_ps14_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); -} - -//#define USE_DEST_ALPHA -#define USE_NORMALMAP_ALPHA - -void CBaseVSShader::DrawWorldBumpedSpecularLighting( int bumpmapVar, int envmapVar, - int bumpFrameVar, int envmapFrameVar, - int envmapTintVar, int alphaVar, - int envmapContrastVar, int envmapSaturationVar, - int bumpTransformVar, int fresnelReflectionVar, - bool bBlend, bool bNoWriteZ ) -{ - // + BUMPED CUBEMAP - if( IsSnapshotting() ) - { - SetInitialShadowState( ); - if ( bNoWriteZ ) - { - s_pShaderShadow->EnableDepthWrites( false ); - } - s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - if( g_pHardwareConfig->SupportsPixelShaders_1_4() ) - { - s_pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); - } - if( bBlend ) - { - s_pShaderShadow->EnableBlending( true ); - s_pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); - } - // FIXME: Remove the normal (needed for tangent space gen) - s_pShaderShadow->VertexShaderVertexFormat( - VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | - VERTEX_TANGENT_T, 1, 0, 0 ); - - IMaterialVar** params = s_ppParams; - bool bHasNormalMapAlphaEnvMapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); - - if( g_pHardwareConfig->SupportsPixelShaders_1_4() ) - { - lightmappedgeneric_bumpmappedenvmap_ps14_Static_Index vshIndex; - s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BumpmappedEnvmap_ps14", vshIndex.GetIndex() ); - - int nPshIndex = bHasNormalMapAlphaEnvMapMask ? 1 : 0; - s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BumpmappedEnvmap_ps14", nPshIndex ); - } - else - { - lightmappedgeneric_bumpmappedenvmap_Static_Index vshIndex; - s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BumpmappedEnvmap", vshIndex.GetIndex() ); - - int nPshIndex = bHasNormalMapAlphaEnvMapMask ? 1 : 0; - s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BumpmappedEnvmap", nPshIndex ); - } - FogToBlack(); - } - else - { - IMaterialVar** params = s_ppParams; - s_pShaderAPI->SetDefaultState(); - BindTexture( SHADER_SAMPLER0, bumpmapVar, bumpFrameVar ); - BindTexture( SHADER_SAMPLER3, envmapVar, envmapFrameVar ); - - if( g_pHardwareConfig->SupportsPixelShaders_1_4() ) - { - s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALIZATION_CUBEMAP ); - - lightmappedgeneric_bumpmappedenvmap_ps14_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - else - { - lightmappedgeneric_bumpmappedenvmap_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - - SetEnvMapTintPixelShaderDynamicState( 0, envmapTintVar, alphaVar ); - // GR - fudge consts a bit to fix const/lerp issues - SetPixelShaderConstantFudge( 1, envmapContrastVar ); - SetPixelShaderConstantFudge( 2, envmapSaturationVar ); - float greyWeights[4] = { 0.299f, 0.587f, 0.114f, 0.0f }; - s_pShaderAPI->SetPixelShaderConstant( 3, greyWeights ); - - // [ 0, 0 ,0, R(0) ] - float fresnel[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - fresnel[3] = params[fresnelReflectionVar]->GetFloatValue(); - s_pShaderAPI->SetPixelShaderConstant( 4, fresnel ); - // [ 0, 0 ,0, 1-R(0) ] - fresnel[3] = 1.0f - fresnel[3]; - s_pShaderAPI->SetPixelShaderConstant( 6, fresnel ); - - float one[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - s_pShaderAPI->SetPixelShaderConstant( 5, one ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, bumpTransformVar ); - } - Draw(); -} - -void CBaseVSShader::DrawModelBumpedSpecularLighting( int bumpMapVar, int bumpMapFrameVar, - int envMapVar, int envMapVarFrame, - int envMapTintVar, int alphaVar, - int envMapContrastVar, int envMapSaturationVar, - int bumpTransformVar, - bool bBlendSpecular, bool bNoWriteZ ) -{ - IMaterialVar** params = s_ppParams; - - if( IsSnapshotting() ) - { - SetInitialShadowState( ); - if ( bNoWriteZ ) - { - s_pShaderShadow->EnableDepthWrites( false ); - } - s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - if( g_pHardwareConfig->SupportsPixelShaders_1_4() ) - { - s_pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); - } - s_pShaderShadow->EnableAlphaTest( false ); - if( bBlendSpecular ) - { - s_pShaderShadow->EnableBlending( true ); - SetAdditiveBlendingShadowState( -1, false ); - } - else - { - s_pShaderShadow->EnableBlending( false ); - SetNormalBlendingShadowState( -1, false ); - } - - s_pShaderShadow->VertexShaderVertexFormat( - VERTEX_POSITION | VERTEX_NORMAL, 1, 0, 4 /* userDataSize */ ); - - bool bHasNormalMapAlphaEnvMapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); - - if( g_pHardwareConfig->SupportsPixelShaders_1_4() ) - { - vertexlitgeneric_envmappedbumpmap_nolighting_ps14_Static_Index vshIndex; - s_pShaderShadow->SetVertexShader( "VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14", vshIndex.GetIndex() ); - if( bHasNormalMapAlphaEnvMapMask ) - { - s_pShaderShadow->SetPixelShader( "VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha_ps14" ); - } - else - { - s_pShaderShadow->SetPixelShader( "VertexLitGeneric_EnvmappedBumpmapV2_ps14" ); - } - } - else - { - vertexlitgeneric_envmappedbumpmap_nolighting_Static_Index vshIndex; - s_pShaderShadow->SetVertexShader( "VertexLitGeneric_EnvmappedBumpmap_NoLighting", vshIndex.GetIndex() ); - // This version does not multiply by lighting - // NOTE: We don't support multiplying by lighting for bumped specular stuff. - if( bHasNormalMapAlphaEnvMapMask ) - { - s_pShaderShadow->SetPixelShader( "VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha" ); - } - else - { - s_pShaderShadow->SetPixelShader( "VertexLitGeneric_EnvmappedBumpmapV2" ); - } - } - FogToBlack(); - } - else - { - s_pShaderAPI->SetDefaultState(); - BindTexture( SHADER_SAMPLER0, bumpMapVar, bumpMapFrameVar ); - BindTexture( SHADER_SAMPLER3, envMapVar, envMapVarFrame ); - if( g_pHardwareConfig->SupportsPixelShaders_1_4() ) - { - s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALIZATION_CUBEMAP ); - } - - if( bBlendSpecular ) - { - SetEnvMapTintPixelShaderDynamicState( 0, envMapTintVar, -1 ); - } - else - { - SetEnvMapTintPixelShaderDynamicState( 0, envMapTintVar, alphaVar ); - } - // GR - fudge consts a bit to fix const/lerp issues - SetPixelShaderConstantFudge( 1, envMapContrastVar ); - SetPixelShaderConstantFudge( 2, envMapSaturationVar ); - float greyWeights[4] = { 0.299f, 0.587f, 0.114f, 0.0f }; - s_pShaderAPI->SetPixelShaderConstant( 3, greyWeights ); - - // handle scrolling of bump texture - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, bumpTransformVar ); - - if( g_pHardwareConfig->SupportsPixelShaders_1_4() ) - { - vertexlitgeneric_envmappedbumpmap_nolighting_ps14_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - vshIndex.SetSKINNING( s_pShaderAPI->GetCurrentNumBones() > 0 ); - s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - else - { - vertexlitgeneric_envmappedbumpmap_nolighting_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - vshIndex.SetSKINNING( s_pShaderAPI->GetCurrentNumBones() > 0 ); - s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - } - Draw(); -} - -void CBaseVSShader::DrawBaseTextureBlend( int baseTextureVar, int baseTextureTransformVar, - int baseTextureFrameVar, - int baseTexture2Var, int baseTextureTransform2Var, - int baseTextureFrame2Var, int colorVar, int alphaVar ) -{ - if( IsSnapshotting() ) - { - SetInitialShadowState(); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - s_pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - s_pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | - SHADER_DRAW_LIGHTMAP_TEXCOORD1 ); - // FIXME: Remove the normal (needed for tangent space gen) - s_pShaderShadow->VertexShaderVertexFormat( - VERTEX_POSITION, 2, 0, 0 ); - - lightmappedgeneric_basetextureblend_Static_Index vshIndex; - s_pShaderShadow->SetVertexShader( "lightmappedgeneric_basetextureblend", vshIndex.GetIndex() ); - - s_pShaderShadow->SetPixelShader( "lightmappedgeneric_basetextureblend", 0 ); - FogToOOOverbright(); - } - else - { - IMaterialVar** params = s_ppParams; - bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - - s_pShaderAPI->SetDefaultState(); - if( bLightingOnly ) - { - s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); - s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); - } - else - { - BindTexture( SHADER_SAMPLER0, baseTextureVar, baseTextureFrameVar ); - BindTexture( SHADER_SAMPLER1, baseTexture2Var, baseTextureFrame2Var ); - } - s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_LIGHTMAP ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, baseTextureTransformVar ); - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, baseTextureTransform2Var ); - SetColorPixelShaderConstant( 0, colorVar, alphaVar ); - lightmappedgeneric_basetextureblend_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - Draw(); -} - -void CBaseVSShader::DrawWorldBumpedUsingVertexShader( int baseTextureVar, int baseTextureTransformVar, - int bumpmapVar, int bumpFrameVar, - int bumpTransformVar, - int envmapMaskVar, int envmapMaskFrame, - int envmapVar, - int envmapFrameVar, - int envmapTintVar, int colorVar, int alphaVar, - int envmapContrastVar, int envmapSaturationVar, - int frameVar, int fresnelReflectionVar, - bool doBaseTexture2, - int baseTexture2Var, int baseTextureTransform2Var, - int baseTextureFrame2Var, - bool bSSBump - ) -{ - IMaterialVar** params = s_ppParams; - // Draw base texture - bool bMultiplyDiffuseLighting = false; - bool bBlendSpecular = false; - - // Draw base texture(s) - if( doBaseTexture2 && params[baseTexture2Var]->IsTexture() && params[baseTextureVar]->IsTexture() ) - { - DrawBaseTextureBlend( baseTextureVar, baseTextureTransformVar, frameVar, - baseTexture2Var, baseTextureTransform2Var, baseTextureFrame2Var, colorVar, alphaVar ); - bMultiplyDiffuseLighting = true; - bBlendSpecular = true; - } - else if( params[baseTextureVar]->IsTexture() ) - { - DrawWorldBaseTexture( baseTextureVar, baseTextureTransformVar, frameVar, colorVar, alphaVar ); - bMultiplyDiffuseLighting = true; - bBlendSpecular = true; - } - else - { - // Just use color here - } - - // Draw diffuse lighting - if( params[baseTextureVar]->IsTexture() || !params[envmapVar]->IsTexture() ) - { - DrawWorldBumpedDiffuseLighting( bumpmapVar, bumpFrameVar, bumpTransformVar, - bMultiplyDiffuseLighting, bSSBump ); - bBlendSpecular = true; - } - - // Add specular lighting - if( params[envmapVar]->IsTexture() ) - { - DrawWorldBumpedSpecularLighting( - bumpmapVar, envmapVar, - bumpFrameVar, envmapFrameVar, - envmapTintVar, alphaVar, - envmapContrastVar, envmapSaturationVar, - bumpTransformVar, fresnelReflectionVar, - bBlendSpecular ); - } -} -#endif // GAME_SHADER_DLL - - -//----------------------------------------------------------------------------- -// GR - translucency query -//----------------------------------------------------------------------------- -BlendType_t CBaseVSShader::EvaluateBlendRequirements( int textureVar, bool isBaseTexture, - int detailTextureVar ) -{ - // Either we've got a constant modulation - bool isTranslucent = IsAlphaModulating(); - - // Or we've got a vertex alpha - isTranslucent = isTranslucent || (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA); - - // Or we've got a texture alpha (for blending or alpha test) - isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) && - !(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) ); - - if ( ( detailTextureVar != -1 ) && ( ! isTranslucent ) ) - { - isTranslucent = TextureIsTranslucent( detailTextureVar, isBaseTexture ); - } - - if ( CurrentMaterialVarFlags() & MATERIAL_VAR_ADDITIVE ) - { - return isTranslucent ? BT_BLENDADD : BT_ADD; // Additive - } - else - { - return isTranslucent ? BT_BLEND : BT_NONE; // Normal blending - } -} - -#ifndef GAME_SHADER_DLL - -void CBaseVSShader::SetFlashlightVertexShaderConstants( bool bBump, int bumpTransformVar, bool bDetail, int detailScaleVar, bool bSetTextureTransforms ) -{ - Assert( !IsSnapshotting() ); - - VMatrix worldToTexture; - const FlashlightState_t &flashlightState = s_pShaderAPI->GetFlashlightState( worldToTexture ); - - // Set the flashlight origin - float pos[4]; - pos[0] = flashlightState.m_vecLightOrigin[0]; - pos[1] = flashlightState.m_vecLightOrigin[1]; - pos[2] = flashlightState.m_vecLightOrigin[2]; - pos[3] = 1.0f / ( ( 0.6f * flashlightState.m_FarZ ) - flashlightState.m_FarZ ); // DX8 needs this - - s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, pos, 1 ); - - s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, worldToTexture.Base(), 4 ); - - // Set the flashlight attenuation factors - float atten[4]; - atten[0] = flashlightState.m_fConstantAtten; - atten[1] = flashlightState.m_fLinearAtten; - atten[2] = flashlightState.m_fQuadraticAtten; - atten[3] = flashlightState.m_FarZ; - s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, atten, 1 ); - - if ( bDetail ) - { - SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, BASETEXTURETRANSFORM, detailScaleVar ); - } - - if( bSetTextureTransforms ) - { - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, BASETEXTURETRANSFORM ); - if( !bDetail && bBump && bumpTransformVar != -1 ) - { - SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, bumpTransformVar ); // aliased on top of detail transform - } - } -} - -#if SUPPORT_DX8 -void CBaseVSShader::DrawFlashlight_dx80( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bBump, - int bumpmapVar, int bumpmapFrame, int bumpTransform, int flashlightTextureVar, int flashlightTextureFrameVar, - bool bLightmappedGeneric, bool bWorldVertexTransition, int nWorldVertexTransitionPassID, int baseTexture2Var, - int baseTexture2FrameVar, bool bTeeth, int nTeethForwardVar, int nTeethIllumFactorVar ) -{ - // FLASHLIGHTFIXME: hack . . need to fix the vertex shader so that it can deal with and without bumps for vertexlitgeneric - if( !bLightmappedGeneric ) - { - bBump = false; - } - if( pShaderShadow ) - { - SetInitialShadowState(); - pShaderShadow->EnableDepthWrites( false ); - - // Be sure not to write to dest alpha - pShaderShadow->EnableAlphaWrites( false ); - - // Never alpha test the flashlight pass - pShaderShadow->EnableAlphaTest( false ); - - if ( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) ) - { - // use zfunc zequals since alpha isn't guaranteed to - // be the same on both the regular pass and the flashlight pass. - pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); - } - - // Alpha blend - if( bWorldVertexTransition ) - { - // use separate alpha blend to make sure that we aren't adding alpha from source - if( nWorldVertexTransitionPassID == 0 ) - { - EnableAlphaBlending( SHADER_BLEND_DST_ALPHA, SHADER_BLEND_ONE ); - } - else - { - EnableAlphaBlending( SHADER_BLEND_ONE_MINUS_DST_ALPHA, SHADER_BLEND_ONE ); - } - } - else - { - SetAdditiveBlendingShadowState( BASETEXTURE, true ); - } - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - - if( bLightmappedGeneric ) - { - bool bUsingVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); - lightmappedgeneric_flashlight_vs11_Static_Index vshIndex; - vshIndex.SetNORMALMAP( bBump ); - vshIndex.SetWORLDVERTEXTRANSITION( bWorldVertexTransition ); - vshIndex.SetVERTEXCOLOR( bUsingVertexColor ); - pShaderShadow->SetVertexShader( "lightmappedgeneric_flashlight_vs11", vshIndex.GetIndex() ); - - unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; - if( bBump ) - { - flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; - } - if ( bWorldVertexTransition || bUsingVertexColor ) - { - flags |= VERTEX_COLOR; - } - pShaderShadow->VertexShaderVertexFormat( flags, 1, 0, 0 ); - } - else - { - vertexlitgeneric_flashlight_vs11_Static_Index vshIndex; - vshIndex.SetTEETH( bTeeth ); - pShaderShadow->SetVertexShader( "vertexlitgeneric_flashlight_vs11", vshIndex.GetIndex() ); - - unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; - pShaderShadow->VertexShaderVertexFormat( flags, 1, 0, bBump ? 4 : 0 ); - } - - bool bNoCull = IS_FLAG_SET( MATERIAL_VAR_NOCULL ); - - flashlight_ps11_Static_Index pshIndex; - pshIndex.SetNORMALMAP( bBump ); - pshIndex.SetNOCULL( bNoCull ); - pShaderShadow->SetPixelShader( "flashlight_ps11", pshIndex.GetIndex() ); - - FogToBlack(); - } - else - { - // Specify that we have XYZ texcoords that need to be divided by W before the pixel shader. - // NOTE Tried to divide XY by Z, but doesn't work. - // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. - pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE0, 0, true ); - BindTexture( SHADER_SAMPLER0, flashlightTextureVar, flashlightTextureFrameVar ); - - if( bWorldVertexTransition && ( nWorldVertexTransitionPassID == 1 ) ) - { - BindTexture( SHADER_SAMPLER1, baseTexture2Var, baseTexture2FrameVar ); - } - else - { - if( params[BASETEXTURE]->IsTexture() ) - { - BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); - } - else - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); - } - } - pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP ); - if( bBump ) - { - BindTexture( SHADER_SAMPLER3, bumpmapVar, bumpmapFrame ); - } - else - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALIZATION_CUBEMAP ); - } - - if( bLightmappedGeneric ) - { - lightmappedgeneric_flashlight_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - else - { - vertexlitgeneric_flashlight_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - - if( bTeeth ) - { - Assert( nTeethForwardVar >= 0 ); - Assert( nTeethIllumFactorVar >= 0 ); - Vector4D lighting; - params[nTeethForwardVar]->GetVecValue( lighting.Base(), 3 ); - lighting[3] = params[nTeethIllumFactorVar]->GetFloatValue(); - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, lighting.Base() ); - } - - vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - } - - flashlight_ps11_Dynamic_Index pshIndex; - pShaderAPI->SetPixelShaderIndex( pshIndex.GetIndex() ); - - SetFlashlightVertexShaderConstants( bBump, bumpTransform, false, -1, true ); - } - Draw(); -} -#endif // support_dx8 - -#ifdef STDSHADER_DX9_DLL_EXPORT -void CBaseVSShader::DrawFlashlight_dx90( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, - IShaderShadow* pShaderShadow, DrawFlashlight_dx90_Vars_t &vars ) -{ - // FLASHLIGHTFIXME: hack . . need to fix the vertex shader so that it can deal with and without bumps for vertexlitgeneric - if( !vars.m_bLightmappedGeneric ) - { - vars.m_bBump = false; - } - bool bBump2 = vars.m_bWorldVertexTransition && vars.m_bBump && vars.m_nBumpmap2Var != -1 && params[vars.m_nBumpmap2Var]->IsTexture(); - bool bSeamless = vars.m_fSeamlessScale != 0.0; - bool bDetail = vars.m_bLightmappedGeneric && (vars.m_nDetailVar != -1) && params[vars.m_nDetailVar]->IsDefined() && (vars.m_nDetailScale != -1); - - int nDetailBlendMode = 0; - if ( bDetail ) - { - nDetailBlendMode = GetIntParam( vars.m_nDetailTextureCombineMode, params ); - nDetailBlendMode = nDetailBlendMode > 1 ? 1 : nDetailBlendMode; - } - - if( pShaderShadow ) - { - SetInitialShadowState(); - pShaderShadow->EnableDepthWrites( false ); - pShaderShadow->EnableAlphaWrites( false ); - - // Alpha blend - SetAdditiveBlendingShadowState( BASETEXTURE, true ); - - // Alpha test - pShaderShadow->EnableAlphaTest( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) ); - if ( vars.m_nAlphaTestReference != -1 && params[vars.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) - { - pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[vars.m_nAlphaTestReference]->GetFloatValue() ); - } - - // Spot sampler - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); - - // Base sampler - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); - - // Normalizing cubemap sampler - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - - // Normalizing cubemap sampler2 or normal map sampler - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - - // RandomRotation sampler - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); - - // Flashlight depth sampler - pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); - pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER7 ); - - if( vars.m_bWorldVertexTransition ) - { - // $basetexture2 - pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true ); - } - if( bBump2 ) - { - // Normalmap2 sampler - pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); - } - if( bDetail ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // detail sampler - if ( nDetailBlendMode != 0 ) //Not Mod2X - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, true ); - } - - pShaderShadow->EnableSRGBWrite( true ); - - if( vars.m_bLightmappedGeneric ) - { - lightmappedgeneric_flashlight_vs20_Static_Index vshIndex; - vshIndex.SetWORLDVERTEXTRANSITION( vars.m_bWorldVertexTransition ); - vshIndex.SetNORMALMAP( vars.m_bBump ); - vshIndex.SetSEAMLESS( bSeamless ); - vshIndex.SetDETAIL( bDetail ); - pShaderShadow->SetVertexShader( "lightmappedgeneric_flashlight_vs20", vshIndex.GetIndex() ); - - unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; - if( vars.m_bBump ) - { - flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; - } - int numTexCoords = 1; - if( vars.m_bWorldVertexTransition ) - { - flags |= VERTEX_COLOR; - numTexCoords = 2; // need lightmap texcoords to get alpha. - } - pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); - } - else - { - vertexlitgeneric_flashlight_vs11_Static_Index vshIndex; - vshIndex.SetTEETH( vars.m_bTeeth ); - pShaderShadow->SetVertexShader( "vertexlitgeneric_flashlight_vs11", vshIndex.GetIndex() ); - - unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; - int numTexCoords = 1; - pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, vars.m_bBump ? 4 : 0 ); - } - - int nBumpMapVariant = 0; - if ( vars.m_bBump ) - { - nBumpMapVariant = ( vars.m_bSSBump ) ? 2 : 1; - } - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - int nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); - - flashlight_ps20b_Static_Index pshIndex; - pshIndex.SetNORMALMAP( nBumpMapVariant ); - pshIndex.SetNORMALMAP2( bBump2 ); - pshIndex.SetWORLDVERTEXTRANSITION( vars.m_bWorldVertexTransition ); - pshIndex.SetSEAMLESS( bSeamless ); - pshIndex.SetDETAILTEXTURE( bDetail ); - pshIndex.SetDETAIL_BLEND_MODE( nDetailBlendMode ); - pshIndex.SetFLASHLIGHTDEPTHFILTERMODE( nShadowFilterMode ); - pShaderShadow->SetPixelShader( "flashlight_ps20b", pshIndex.GetIndex() ); - } - else - { - flashlight_ps20_Static_Index pshIndex; - pshIndex.SetNORMALMAP( nBumpMapVariant ); - pshIndex.SetNORMALMAP2( bBump2 ); - pshIndex.SetWORLDVERTEXTRANSITION( vars.m_bWorldVertexTransition ); - pshIndex.SetSEAMLESS( bSeamless ); - pshIndex.SetDETAILTEXTURE( bDetail ); - pshIndex.SetDETAIL_BLEND_MODE( nDetailBlendMode ); - pShaderShadow->SetPixelShader( "flashlight_ps20", pshIndex.GetIndex() ); - } - FogToBlack(); - } - else - { - VMatrix worldToTexture; - ITexture *pFlashlightDepthTexture; - FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); - - SetFlashLightColorFromState( flashlightState, pShaderAPI ); - - BindTexture( SHADER_SAMPLER0, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); - - if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows ) - { - BindTexture( SHADER_SAMPLER7, pFlashlightDepthTexture, 0 ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); - - // Tweaks associated with a given flashlight - float tweaks[4]; - 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 ); - - // Dimensions of screen, used for screen-space noise map sampling - float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; - int nWidth, nHeight; - pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); - vScreenScale[0] = (float) nWidth / 32.0f; - vScreenScale[1] = (float) nHeight / 32.0f; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); - } - - if( params[BASETEXTURE]->IsTexture() && mat_fullbright.GetInt() != 2 ) - { - BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); - } - else - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); - } - if( vars.m_bWorldVertexTransition ) - { - Assert( vars.m_nBaseTexture2Var >= 0 && vars.m_nBaseTexture2FrameVar >= 0 ); - BindTexture( SHADER_SAMPLER4, vars.m_nBaseTexture2Var, vars.m_nBaseTexture2FrameVar ); - } - pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP ); - if( vars.m_bBump ) - { - BindTexture( SHADER_SAMPLER3, vars.m_nBumpmapVar, vars.m_nBumpmapFrame ); - } - else - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALIZATION_CUBEMAP ); - } - - if( bDetail ) - { - BindTexture( SHADER_SAMPLER8, vars.m_nDetailVar ); - } - - if( vars.m_bWorldVertexTransition ) - { - if( bBump2 ) - { - BindTexture( SHADER_SAMPLER6, vars.m_nBumpmap2Var, vars.m_nBumpmap2Frame ); - } - } - - if( vars.m_bLightmappedGeneric ) - { - DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs20 ); - SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - SET_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs20 ); - if ( bSeamless ) - { - float const0[4]={ vars.m_fSeamlessScale,0,0,0}; - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, const0 ); - } - - if ( bDetail ) - { - float vDetailConstants[4] = {1,1,1,1}; - - if ( vars.m_nDetailTint != -1 ) - { - params[vars.m_nDetailTint]->GetVecValue( vDetailConstants, 3 ); - } - - if ( vars.m_nDetailTextureBlendFactor != -1 ) - { - vDetailConstants[3] = params[vars.m_nDetailTextureBlendFactor]->GetFloatValue(); - } - - pShaderAPI->SetPixelShaderConstant( 0, vDetailConstants, 1 ); - } - } - else - { - vertexlitgeneric_flashlight_vs11_Dynamic_Index vshIndex; - vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); - vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); - pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); - - if( vars.m_bTeeth ) - { - Assert( vars.m_nTeethForwardVar >= 0 ); - Assert( vars.m_nTeethIllumFactorVar >= 0 ); - Vector4D lighting; - params[vars.m_nTeethForwardVar]->GetVecValue( lighting.Base(), 3 ); - lighting[3] = params[vars.m_nTeethIllumFactorVar]->GetFloatValue(); - pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lighting.Base() ); - } - } - - pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); - - float vEyePos_SpecExponent[4]; - pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); - vEyePos_SpecExponent[3] = 0.0f; - pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); - - if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( flashlight_ps20b ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ) ); - SET_DYNAMIC_PIXEL_SHADER( flashlight_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( flashlight_ps20 ); - SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); - SET_DYNAMIC_PIXEL_SHADER( flashlight_ps20 ); - } - - float atten[4]; // 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; - s_pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); - - SetFlashlightVertexShaderConstants( vars.m_bBump, vars.m_nBumpTransform, bDetail, vars.m_nDetailScale, bSeamless ? false : true ); - } - Draw(); -} - -#endif - -void CBaseVSShader::InitParamsUnlitGeneric_DX8( - int baseTextureVar, - int detailScaleVar, - int envmapOptionalVar, - int envmapVar, - int envmapTintVar, - int envmapMaskScaleVar, - int nDetailBlendMode ) -{ - IMaterialVar** params = s_ppParams; - - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - - if( envmapTintVar >= 0 && !params[envmapTintVar]->IsDefined() ) - { - params[envmapTintVar]->SetVecValue( 1.0f, 1.0f, 1.0f ); - } - - if( envmapMaskScaleVar >= 0 && !params[envmapMaskScaleVar]->IsDefined() ) - { - params[envmapMaskScaleVar]->SetFloatValue( 1.0f ); - } - - if( detailScaleVar >= 0 && !params[detailScaleVar]->IsDefined() ) - { - params[detailScaleVar]->SetFloatValue( 4.0f ); - } - - // No texture means no self-illum or env mask in base alpha - if ( baseTextureVar >= 0 && !params[baseTextureVar]->IsDefined() ) - { - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - - // If in decal mode, no debug override... - if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) - { - SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); - } - - // Get rid of the envmap if it's optional for this dx level. - if( envmapOptionalVar >= 0 && params[envmapOptionalVar]->IsDefined() && params[envmapOptionalVar]->GetIntValue() ) - { - if (envmapVar >= 0) - { - params[envmapVar]->SetUndefined(); - } - } - - // If mat_specular 0, then get rid of envmap - if( envmapVar >= 0 && baseTextureVar >= 0 && !g_pConfig->UseSpecular() && params[envmapVar]->IsDefined() && params[baseTextureVar]->IsDefined() ) - { - params[envmapVar]->SetUndefined(); - } -} - -void CBaseVSShader::InitUnlitGeneric_DX8( - int baseTextureVar, - int detailVar, - int envmapVar, - int envmapMaskVar ) -{ - IMaterialVar** params = s_ppParams; - - if (baseTextureVar >= 0 && params[baseTextureVar]->IsDefined()) - { - LoadTexture( baseTextureVar ); - - if (!params[baseTextureVar]->GetTextureValue()->IsTranslucent()) - { - if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) - CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); - } - } - - // Don't alpha test if the alpha channel is used for other purposes - if ( IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) - CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); - - // the second texture (if there is one) - if (detailVar >= 0 && params[detailVar]->IsDefined()) - { - LoadTexture( detailVar ); - } - - if (envmapVar >= 0 && params[envmapVar]->IsDefined()) - { - if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) - LoadCubeMap( envmapVar ); - else - LoadTexture( envmapVar ); - - if( !g_pHardwareConfig->SupportsCubeMaps() ) - SET_FLAGS(MATERIAL_VAR_ENVMAPSPHERE); - - if (envmapMaskVar >= 0 && params[envmapMaskVar]->IsDefined()) - LoadTexture( envmapMaskVar ); - } -} -#endif // GAME_SHADER_DLL - -#endif // !_STATIC_LINKED || STDSHADER_DX8_DLL_EXPORT - - -// Take 0..1 seed and map to (u, v) coordinate to be used in shadow filter jittering... -void CBaseVSShader::HashShadow2DJitter( const float fJitterSeed, float *fU, float* fV ) -{ - const int nTexRes = 32; - int nSeed = fmod (fJitterSeed, 1.0f) * nTexRes * nTexRes; - - int nRow = nSeed / nTexRes; - int nCol = nSeed % nTexRes; - - // Div and mod to get an individual texel in the fTexRes x fTexRes grid - *fU = nRow / (float) nTexRes; // Row - *fV = nCol / (float) nTexRes; // Column -} - - -void CBaseVSShader::DrawEqualDepthToDestAlpha( void ) -{ -#ifdef STDSHADER_DX9_DLL_EXPORT - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - bool bMakeActualDrawCall = false; - if( s_pShaderShadow ) - { - s_pShaderShadow->EnableColorWrites( false ); - s_pShaderShadow->EnableAlphaWrites( true ); - s_pShaderShadow->EnableDepthWrites( false ); - s_pShaderShadow->EnableAlphaTest( false ); - s_pShaderShadow->EnableBlending( false ); - - s_pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); - - s_pShaderShadow->SetVertexShader( "depthtodestalpha_vs20", 0 ); - s_pShaderShadow->SetPixelShader( "depthtodestalpha_ps20b", 0 ); - } - if( s_pShaderAPI ) - { - s_pShaderAPI->SetVertexShaderIndex( 0 ); - s_pShaderAPI->SetPixelShaderIndex( 0 ); - - bMakeActualDrawCall = s_pShaderAPI->ShouldWriteDepthToDestAlpha(); - } - Draw( bMakeActualDrawCall ); - } -#else - Assert( 0 ); //probably just needs a shader update to the latest -#endif -} +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// This is what all vs/ps (dx8+) shaders inherit from. +//===========================================================================// +#if !defined(_STATIC_LINKED) || defined(STDSHADER_DX8_DLL_EXPORT) || defined(STDSHADER_DX9_DLL_EXPORT) + +#include "BaseVSShader.h" +#include "mathlib/vmatrix.h" +#include "mathlib/bumpvects.h" +#include "cpp_shader_constant_register_map.h" +#include "convar.h" + +#ifndef GAME_SHADER_DLL +#ifdef HDR +#include "vertexlit_and_unlit_generic_hdr_ps20.inc" +#include "vertexlit_and_unlit_generic_hdr_ps20b.inc" +#endif + +#if SUPPORT_DX8 +#include "lightmappedgeneric_flashlight_vs11.inc" +#include "flashlight_ps11.inc" +#endif + +#ifdef STDSHADER_DX9_DLL_EXPORT +#include "lightmappedgeneric_flashlight_vs20.inc" +#endif +#ifdef STDSHADER_DX9_DLL_EXPORT +#include "flashlight_ps20.inc" +#include "flashlight_ps20b.inc" +#endif +#include "unlitgeneric_vs11.inc" +#include "VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.inc" +#include "VertexLitGeneric_EnvmappedBumpmap_NoLighting.inc" +#include "vertexlitgeneric_flashlight_vs11.inc" +#include "LightmappedGeneric_BaseTexture.inc" +#include "LightmappedGeneric_BumpmappedLightmap_Base_ps14.inc" +#include "LightmappedGeneric_BumpmappedLightmap_Blend_ps14.inc" +#include "lightmappedgeneric_bumpmappedenvmap_ps14.inc" +#include "lightmappedgeneric_bumpmappedenvmap.inc" +#include "lightmappedgeneric_basetextureblend.inc" +#include "lightmappedgeneric_bumpmappedlightmap.inc" +#endif // GAME_SHADER_DLL + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); + +// These functions are to be called from the shaders. + +//----------------------------------------------------------------------------- +// Pixel and vertex shader constants.... +//----------------------------------------------------------------------------- +void CBaseVSShader::SetPixelShaderConstant( int pixelReg, int constantVar, int constantVar2 ) +{ + Assert( !IsSnapshotting() ); + if ((!s_ppParams) || (constantVar == -1) || (constantVar2 == -1)) + return; + + IMaterialVar* pPixelVar = s_ppParams[constantVar]; + Assert( pPixelVar ); + IMaterialVar* pPixelVar2 = s_ppParams[constantVar2]; + Assert( pPixelVar2 ); + + float val[4]; + if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + { + pPixelVar->GetVecValue( val, 3 ); + } + else + { + val[0] = val[1] = val[2] = pPixelVar->GetFloatValue(); + } + + val[3] = pPixelVar2->GetFloatValue(); + s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); +} + +void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar, int constantVar2 ) +{ + Assert( !IsSnapshotting() ); + if ((!s_ppParams) || (constantVar == -1) || (constantVar2 == -1)) + return; + + IMaterialVar* pPixelVar = s_ppParams[constantVar]; + Assert( pPixelVar ); + IMaterialVar* pPixelVar2 = s_ppParams[constantVar2]; + Assert( pPixelVar2 ); + + float val[4]; + if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + { + pPixelVar->GetVecValue( val, 3 ); + } + else + { + val[0] = val[1] = val[2] = pPixelVar->GetFloatValue(); + } + + val[3] = pPixelVar2->GetFloatValue(); + val[0] = val[0] > 1.0f ? val[0] : GammaToLinear( val[0] ); + val[1] = val[1] > 1.0f ? val[1] : GammaToLinear( val[1] ); + val[2] = val[2] > 1.0f ? val[2] : GammaToLinear( val[2] ); + + s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); +} + +void CBaseVSShader::SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue ) +{ + Assert( !IsSnapshotting() ); + if ((!s_ppParams) || (constantVar == -1)) + return; + + IMaterialVar* pPixelVar = s_ppParams[constantVar]; + Assert( pPixelVar ); + + float val[4]; + if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pPixelVar->GetVecValue( val, 4 ); + else + val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue(); + val[3]=fWValue; + s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); +} + +void CBaseVSShader::SetPixelShaderConstant( int pixelReg, int constantVar ) +{ + Assert( !IsSnapshotting() ); + if ((!s_ppParams) || (constantVar == -1)) + return; + + IMaterialVar* pPixelVar = s_ppParams[constantVar]; + Assert( pPixelVar ); + + float val[4]; + if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pPixelVar->GetVecValue( val, 4 ); + else + val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue(); + s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); +} + +void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar ) +{ + Assert( !IsSnapshotting() ); + if ((!s_ppParams) || (constantVar == -1)) + return; + + IMaterialVar* pPixelVar = s_ppParams[constantVar]; + Assert( pPixelVar ); + + float val[4]; + if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pPixelVar->GetVecValue( val, 4 ); + else + val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue(); + + val[0] = val[0] > 1.0f ? val[0] : GammaToLinear( val[0] ); + val[1] = val[1] > 1.0f ? val[1] : GammaToLinear( val[1] ); + val[2] = val[2] > 1.0f ? val[2] : GammaToLinear( val[2] ); + + s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); +} + +void CBaseVSShader::SetVertexShaderConstantGammaToLinear( int var, float const* pVec, int numConst, bool bForce ) +{ + int i; + for( i = 0; i < numConst; i++ ) + { + float vec[4]; + vec[0] = pVec[i*4+0] > 1.0f ? pVec[i*4+0] : GammaToLinear( pVec[i*4+0] ); + vec[1] = pVec[i*4+1] > 1.0f ? pVec[i*4+1] : GammaToLinear( pVec[i*4+1] ); + vec[2] = pVec[i*4+2] > 1.0f ? pVec[i*4+2] : GammaToLinear( pVec[i*4+2] ); + vec[3] = pVec[i*4+3]; + + s_pShaderAPI->SetVertexShaderConstant( var + i, vec, 1, bForce ); + } +} + +void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int var, float const* pVec, int numConst, bool bForce ) +{ + int i; + for( i = 0; i < numConst; i++ ) + { + float vec[4]; + vec[0] = pVec[i*4+0] > 1.0f ? pVec[i*4+0] : GammaToLinear( pVec[i*4+0] ); + vec[1] = pVec[i*4+1] > 1.0f ? pVec[i*4+1] : GammaToLinear( pVec[i*4+1] ); + vec[2] = pVec[i*4+2] > 1.0f ? pVec[i*4+2] : GammaToLinear( pVec[i*4+2] ); + + vec[3] = pVec[i*4+3]; + + s_pShaderAPI->SetPixelShaderConstant( var + i, vec, 1, bForce ); + } +} + +// GR - special version with fix for const/lerp issue +void CBaseVSShader::SetPixelShaderConstantFudge( int pixelReg, int constantVar ) +{ + Assert( !IsSnapshotting() ); + if ((!s_ppParams) || (constantVar == -1)) + return; + + IMaterialVar* pPixelVar = s_ppParams[constantVar]; + Assert( pPixelVar ); + + float val[4]; + if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + { + pPixelVar->GetVecValue( val, 4 ); + val[0] = val[0] * 0.992f + 0.0078f; + val[1] = val[1] * 0.992f + 0.0078f; + val[2] = val[2] * 0.992f + 0.0078f; + val[3] = val[3] * 0.992f + 0.0078f; + } + else + val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue() * 0.992f + 0.0078f; + s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); +} + +void CBaseVSShader::SetVertexShaderConstant( int vertexReg, int constantVar ) +{ + Assert( !IsSnapshotting() ); + if ((!s_ppParams) || (constantVar == -1)) + return; + + IMaterialVar* pVertexVar = s_ppParams[constantVar]; + Assert( pVertexVar ); + + float val[4]; + if (pVertexVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pVertexVar->GetVecValue( val, 4 ); + else + val[0] = val[1] = val[2] = val[3] = pVertexVar->GetFloatValue(); + s_pShaderAPI->SetVertexShaderConstant( vertexReg, val ); +} + +//----------------------------------------------------------------------------- +// Sets normalized light color for pixel shaders. +//----------------------------------------------------------------------------- +void CBaseVSShader::SetPixelShaderLightColors( int pixelReg ) +{ + int i; + int maxLights = s_pShaderAPI->GetMaxLights(); + for( i = 0; i < maxLights; i++ ) + { + const LightDesc_t & lightDesc = s_pShaderAPI->GetLight( i ); + if( lightDesc.m_Type != MATERIAL_LIGHT_DISABLE ) + { + Vector color( lightDesc.m_Color[0], lightDesc.m_Color[1], lightDesc.m_Color[2] ); + VectorNormalize( color ); + float val[4] = { color[0], color[1], color[2], 1.0f }; + s_pShaderAPI->SetPixelShaderConstant( pixelReg + i, val, 1 ); + } + else + { + float zero[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + s_pShaderAPI->SetPixelShaderConstant( pixelReg + i, zero, 1 ); + } + } +} + + +//----------------------------------------------------------------------------- +// Sets vertex shader texture transforms +//----------------------------------------------------------------------------- +void CBaseVSShader::SetVertexShaderTextureTranslation( int vertexReg, int translationVar ) +{ + float offset[2] = {0, 0}; + + IMaterialVar* pTranslationVar = s_ppParams[translationVar]; + if (pTranslationVar) + { + if (pTranslationVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pTranslationVar->GetVecValue( offset, 2 ); + else + offset[0] = offset[1] = pTranslationVar->GetFloatValue(); + } + + Vector4D translation[2]; + translation[0].Init( 1.0f, 0.0f, 0.0f, offset[0] ); + translation[1].Init( 0.0f, 1.0f, 0.0f, offset[1] ); + s_pShaderAPI->SetVertexShaderConstant( vertexReg, translation[0].Base(), 2 ); +} + +void CBaseVSShader::SetVertexShaderTextureScale( int vertexReg, int scaleVar ) +{ + float scale[2] = {1, 1}; + + IMaterialVar* pScaleVar = s_ppParams[scaleVar]; + if (pScaleVar) + { + if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pScaleVar->GetVecValue( scale, 2 ); + else if (pScaleVar->IsDefined()) + scale[0] = scale[1] = pScaleVar->GetFloatValue(); + } + + Vector4D scaleMatrix[2]; + scaleMatrix[0].Init( scale[0], 0.0f, 0.0f, 0.0f ); + scaleMatrix[1].Init( 0.0f, scale[1], 0.0f, 0.0f ); + s_pShaderAPI->SetVertexShaderConstant( vertexReg, scaleMatrix[0].Base(), 2 ); +} + +void CBaseVSShader::SetVertexShaderTextureTransform( int vertexReg, int transformVar ) +{ + Vector4D transformation[2]; + IMaterialVar* pTransformationVar = s_ppParams[transformVar]; + if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) + { + const VMatrix &mat = pTransformationVar->GetMatrixValue(); + transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); + transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); + } + else + { + transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); + transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); + } + s_pShaderAPI->SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 ); +} + +void CBaseVSShader::SetVertexShaderTextureScaledTransform( int vertexReg, int transformVar, int scaleVar ) +{ + Vector4D transformation[2]; + IMaterialVar* pTransformationVar = s_ppParams[transformVar]; + if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) + { + const VMatrix &mat = pTransformationVar->GetMatrixValue(); + transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); + transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); + } + else + { + transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); + transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); + } + + Vector2D scale( 1, 1 ); + IMaterialVar* pScaleVar = s_ppParams[scaleVar]; + if (pScaleVar) + { + if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pScaleVar->GetVecValue( scale.Base(), 2 ); + else if (pScaleVar->IsDefined()) + scale[0] = scale[1] = pScaleVar->GetFloatValue(); + } + + // Apply the scaling + transformation[0][0] *= scale[0]; + transformation[0][1] *= scale[1]; + transformation[1][0] *= scale[0]; + transformation[1][1] *= scale[1]; + transformation[0][3] *= scale[0]; + transformation[1][3] *= scale[1]; + s_pShaderAPI->SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 ); +} + + +//----------------------------------------------------------------------------- +// Sets pixel shader texture transforms +//----------------------------------------------------------------------------- +void CBaseVSShader::SetPixelShaderTextureTranslation( int pixelReg, int translationVar ) +{ + float offset[2] = {0, 0}; + + IMaterialVar* pTranslationVar = s_ppParams[translationVar]; + if (pTranslationVar) + { + if (pTranslationVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pTranslationVar->GetVecValue( offset, 2 ); + else + offset[0] = offset[1] = pTranslationVar->GetFloatValue(); + } + + Vector4D translation[2]; + translation[0].Init( 1.0f, 0.0f, 0.0f, offset[0] ); + translation[1].Init( 0.0f, 1.0f, 0.0f, offset[1] ); + s_pShaderAPI->SetPixelShaderConstant( pixelReg, translation[0].Base(), 2 ); +} + +void CBaseVSShader::SetPixelShaderTextureScale( int pixelReg, int scaleVar ) +{ + float scale[2] = {1, 1}; + + IMaterialVar* pScaleVar = s_ppParams[scaleVar]; + if (pScaleVar) + { + if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pScaleVar->GetVecValue( scale, 2 ); + else if (pScaleVar->IsDefined()) + scale[0] = scale[1] = pScaleVar->GetFloatValue(); + } + + Vector4D scaleMatrix[2]; + scaleMatrix[0].Init( scale[0], 0.0f, 0.0f, 0.0f ); + scaleMatrix[1].Init( 0.0f, scale[1], 0.0f, 0.0f ); + s_pShaderAPI->SetPixelShaderConstant( pixelReg, scaleMatrix[0].Base(), 2 ); +} + +void CBaseVSShader::SetPixelShaderTextureTransform( int pixelReg, int transformVar ) +{ + Vector4D transformation[2]; + IMaterialVar* pTransformationVar = s_ppParams[transformVar]; + if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) + { + const VMatrix &mat = pTransformationVar->GetMatrixValue(); + transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); + transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); + } + else + { + transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); + transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); + } + s_pShaderAPI->SetPixelShaderConstant( pixelReg, transformation[0].Base(), 2 ); +} + +void CBaseVSShader::SetPixelShaderTextureScaledTransform( int pixelReg, int transformVar, int scaleVar ) +{ + Vector4D transformation[2]; + IMaterialVar* pTransformationVar = s_ppParams[transformVar]; + if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) + { + const VMatrix &mat = pTransformationVar->GetMatrixValue(); + transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); + transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); + } + else + { + transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); + transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); + } + + Vector2D scale( 1, 1 ); + IMaterialVar* pScaleVar = s_ppParams[scaleVar]; + if (pScaleVar) + { + if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pScaleVar->GetVecValue( scale.Base(), 2 ); + else if (pScaleVar->IsDefined()) + scale[0] = scale[1] = pScaleVar->GetFloatValue(); + } + + // Apply the scaling + transformation[0][0] *= scale[0]; + transformation[0][1] *= scale[1]; + transformation[1][0] *= scale[0]; + transformation[1][1] *= scale[1]; + transformation[0][3] *= scale[0]; + transformation[1][3] *= scale[1]; + s_pShaderAPI->SetPixelShaderConstant( pixelReg, transformation[0].Base(), 2 ); +} + + +//----------------------------------------------------------------------------- +// Moves a matrix into vertex shader constants +//----------------------------------------------------------------------------- +void CBaseVSShader::SetVertexShaderMatrix3x4( int vertexReg, int matrixVar ) +{ + IMaterialVar* pTranslationVar = s_ppParams[matrixVar]; + if (pTranslationVar) + { + s_pShaderAPI->SetVertexShaderConstant( vertexReg, &pTranslationVar->GetMatrixValue( )[0][0], 3 ); + } + else + { + VMatrix matrix; + MatrixSetIdentity( matrix ); + s_pShaderAPI->SetVertexShaderConstant( vertexReg, &matrix[0][0], 3 ); + } +} + +void CBaseVSShader::SetVertexShaderMatrix4x4( int vertexReg, int matrixVar ) +{ + IMaterialVar* pTranslationVar = s_ppParams[matrixVar]; + if (pTranslationVar) + { + s_pShaderAPI->SetVertexShaderConstant( vertexReg, &pTranslationVar->GetMatrixValue( )[0][0], 4 ); + } + else + { + VMatrix matrix; + MatrixSetIdentity( matrix ); + s_pShaderAPI->SetVertexShaderConstant( vertexReg, &matrix[0][0], 4 ); + } +} + + +//----------------------------------------------------------------------------- +// Loads the view matrix into pixel shader constants +//----------------------------------------------------------------------------- +void CBaseVSShader::LoadViewMatrixIntoVertexShaderConstant( int vertexReg ) +{ + VMatrix mat, transpose; + s_pShaderAPI->GetMatrix( MATERIAL_VIEW, mat.m[0] ); + + MatrixTranspose( mat, transpose ); + s_pShaderAPI->SetVertexShaderConstant( vertexReg, transpose.m[0], 3 ); +} + + +//----------------------------------------------------------------------------- +// Loads the projection matrix into pixel shader constants +//----------------------------------------------------------------------------- +void CBaseVSShader::LoadProjectionMatrixIntoVertexShaderConstant( int vertexReg ) +{ + VMatrix mat, transpose; + s_pShaderAPI->GetMatrix( MATERIAL_PROJECTION, mat.m[0] ); + + MatrixTranspose( mat, transpose ); + s_pShaderAPI->SetVertexShaderConstant( vertexReg, transpose.m[0], 4 ); +} + + +//----------------------------------------------------------------------------- +// Loads the projection matrix into pixel shader constants +//----------------------------------------------------------------------------- +void CBaseVSShader::LoadModelViewMatrixIntoVertexShaderConstant( int vertexReg ) +{ + VMatrix view, model, modelView, transpose; + s_pShaderAPI->GetMatrix( MATERIAL_MODEL, model.m[0] ); + MatrixTranspose( model, model ); + s_pShaderAPI->GetMatrix( MATERIAL_VIEW, view.m[0] ); + MatrixTranspose( view, view ); + + MatrixMultiply( view, model, modelView ); + s_pShaderAPI->SetVertexShaderConstant( vertexReg, modelView.m[0], 3 ); +} + +//----------------------------------------------------------------------------- +// Loads a scale/offset version of the viewport transform into the specified constant. +//----------------------------------------------------------------------------- +void CBaseVSShader::LoadViewportTransformScaledIntoVertexShaderConstant( int vertexReg ) +{ + ShaderViewport_t viewport; + + s_pShaderAPI->GetViewports( &viewport, 1 ); + + int bbWidth = 0, + bbHeight = 0; + + s_pShaderAPI->GetBackBufferDimensions( bbWidth, bbHeight ); + + // (x, y, z, w) = (Width / bbWidth, Height / bbHeight, MinX / bbWidth, MinY / bbHeight) + Vector4D viewportTransform( + 1.0f * viewport.m_nWidth / bbWidth, + 1.0f * viewport.m_nHeight / bbHeight, + 1.0f * viewport.m_nTopLeftX / bbWidth, + 1.0f * viewport.m_nTopLeftY / bbHeight + ); + + s_pShaderAPI->SetVertexShaderConstant( vertexReg, viewportTransform.Base() ); +} + + + +//----------------------------------------------------------------------------- +// Loads bump lightmap coordinates into the pixel shader +//----------------------------------------------------------------------------- +void CBaseVSShader::LoadBumpLightmapCoordinateAxes_PixelShader( int pixelReg ) +{ + Vector4D basis[3]; + for (int i = 0; i < 3; ++i) + { + memcpy( &basis[i], &g_localBumpBasis[i], 3 * sizeof(float) ); + basis[i][3] = 0.0f; + } + s_pShaderAPI->SetPixelShaderConstant( pixelReg, (float*)basis, 3 ); +} + + +//----------------------------------------------------------------------------- +// Loads bump lightmap coordinates into the pixel shader +//----------------------------------------------------------------------------- +void CBaseVSShader::LoadBumpLightmapCoordinateAxes_VertexShader( int vertexReg ) +{ + Vector4D basis[3]; + + // transpose + int i; + for (i = 0; i < 3; ++i) + { + basis[i][0] = g_localBumpBasis[0][i]; + basis[i][1] = g_localBumpBasis[1][i]; + basis[i][2] = g_localBumpBasis[2][i]; + basis[i][3] = 0.0f; + } + s_pShaderAPI->SetVertexShaderConstant( vertexReg, (float*)basis, 3 ); + for (i = 0; i < 3; ++i) + { + memcpy( &basis[i], &g_localBumpBasis[i], 3 * sizeof(float) ); + basis[i][3] = 0.0f; + } + s_pShaderAPI->SetVertexShaderConstant( vertexReg + 3, (float*)basis, 3 ); +} + + +//----------------------------------------------------------------------------- +// Helper methods for pixel shader overbrighting +//----------------------------------------------------------------------------- +void CBaseVSShader::EnablePixelShaderOverbright( int reg, bool bEnable, bool bDivideByTwo ) +{ + // can't have other overbright values with pixel shaders as it stands. + float v[4]; + if( bEnable ) + { + v[0] = v[1] = v[2] = v[3] = bDivideByTwo ? OVERBRIGHT / 2.0f : OVERBRIGHT; + } + else + { + v[0] = v[1] = v[2] = v[3] = bDivideByTwo ? 1.0f / 2.0f : 1.0f; + } + s_pShaderAPI->SetPixelShaderConstant( reg, v, 1 ); +} + + +//----------------------------------------------------------------------------- +// Helper for dealing with modulation +//----------------------------------------------------------------------------- +void CBaseVSShader::SetModulationVertexShaderDynamicState() +{ + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + ComputeModulationColor( color ); + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); +} + +void CBaseVSShader::SetModulationPixelShaderDynamicState( int modulationVar ) +{ + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + ComputeModulationColor( color ); + s_pShaderAPI->SetPixelShaderConstant( modulationVar, color ); +} + +void CBaseVSShader::SetModulationPixelShaderDynamicState_LinearColorSpace( int modulationVar ) +{ + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + ComputeModulationColor( color ); + color[0] = color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ); + color[1] = color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ); + color[2] = color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ); + + s_pShaderAPI->SetPixelShaderConstant( modulationVar, color ); +} + +void CBaseVSShader::SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( int modulationVar, float flScale ) +{ + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + ComputeModulationColor( color ); + color[0] = ( color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ) ) * flScale; + color[1] = ( color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ) ) * flScale; + color[2] = ( color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ) ) * flScale; + + s_pShaderAPI->SetPixelShaderConstant( modulationVar, color ); +} + + +//----------------------------------------------------------------------------- +// Converts a color + alpha into a vector4 +//----------------------------------------------------------------------------- +void CBaseVSShader::ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color ) +{ + color.Init( 1.0, 1.0, 1.0, 1.0 ); + if ( colorVar != -1 ) + { + IMaterialVar* pColorVar = s_ppParams[colorVar]; + if ( pColorVar->GetType() == MATERIAL_VAR_TYPE_VECTOR ) + { + pColorVar->GetVecValue( color.Base(), 3 ); + } + else + { + color[0] = color[1] = color[2] = pColorVar->GetFloatValue(); + } + } + if ( alphaVar != -1 ) + { + float flAlpha = s_ppParams[alphaVar]->GetFloatValue(); + color[3] = clamp( flAlpha, 0.0f, 1.0f ); + } +} + + +//----------------------------------------------------------------------------- +// Sets a color + alpha into shader constants +//----------------------------------------------------------------------------- +void CBaseVSShader::SetColorVertexShaderConstant( int nVertexReg, int colorVar, int alphaVar ) +{ + Vector4D color; + ColorVarsToVector( colorVar, alphaVar, color ); + s_pShaderAPI->SetVertexShaderConstant( nVertexReg, color.Base() ); +} + +void CBaseVSShader::SetColorPixelShaderConstant( int nPixelReg, int colorVar, int alphaVar ) +{ + Vector4D color; + ColorVarsToVector( colorVar, alphaVar, color ); + s_pShaderAPI->SetPixelShaderConstant( nPixelReg, color.Base() ); +} + +#ifdef _DEBUG +ConVar mat_envmaptintoverride( "mat_envmaptintoverride", "-1" ); +ConVar mat_envmaptintscale( "mat_envmaptintscale", "-1" ); +#endif + +//----------------------------------------------------------------------------- +// Helpers for dealing with envmap tint +//----------------------------------------------------------------------------- +// set alphaVar to -1 to ignore it. +void CBaseVSShader::SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear ) +{ + float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + if( g_pConfig->bShowSpecular && mat_fullbright.GetInt() != 2 ) + { + IMaterialVar* pAlphaVar = NULL; + if( alphaVar >= 0 ) + { + pAlphaVar = s_ppParams[alphaVar]; + } + if( pAlphaVar ) + { + color[3] = pAlphaVar->GetFloatValue(); + } + + IMaterialVar* pTintVar = s_ppParams[tintVar]; +#ifdef _DEBUG + pTintVar->GetVecValue( color, 3 ); + + float envmapTintOverride = mat_envmaptintoverride.GetFloat(); + float envmapTintScaleOverride = mat_envmaptintscale.GetFloat(); + + if( envmapTintOverride != -1.0f ) + { + color[0] = color[1] = color[2] = envmapTintOverride; + } + if( envmapTintScaleOverride != -1.0f ) + { + color[0] *= envmapTintScaleOverride; + color[1] *= envmapTintScaleOverride; + color[2] *= envmapTintScaleOverride; + } + + if( bConvertFromGammaToLinear ) + { + color[0] = color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ); + color[1] = color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ); + color[2] = color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ); + } +#else + if( bConvertFromGammaToLinear ) + { + pTintVar->GetLinearVecValue( color, 3 ); + } + else + { + pTintVar->GetVecValue( color, 3 ); + } +#endif + } + else + { + color[0] = color[1] = color[2] = color[3] = 0.0f; + } + s_pShaderAPI->SetPixelShaderConstant( pixelReg, color, 1 ); +} + +void CBaseVSShader::SetAmbientCubeDynamicStateVertexShader( ) +{ + s_pShaderAPI->SetVertexShaderStateAmbientLightCube(); +} + +float CBaseVSShader::GetAmbientLightCubeLuminance( ) +{ + return s_pShaderAPI->GetAmbientLightCubeLuminance(); +} + +#ifndef GAME_SHADER_DLL +const char *CBaseVSShader::UnlitGeneric_ComputePixelShaderName( bool bMask, + bool bEnvmap, + bool bBaseTexture, + bool bBaseAlphaEnvmapMask, + bool bDetail, + bool bDetailMultiplyMode, + bool bMaskBaseByDetailAlpha ) +{ + static char const* s_pPixelShaders[] = + { + "UnlitGeneric_NoTexture", + "UnlitGeneric", + "UnlitGeneric_EnvMapNoTexture", + "UnlitGeneric_EnvMap", + "UnlitGeneric_NoTexture", + "UnlitGeneric", + "UnlitGeneric_EnvMapMaskNoTexture", + "UnlitGeneric_EnvMapMask", + + // Detail texture + // The other commented-out versions are used if we want to + // apply the detail *after* the environment map is added + "UnlitGeneric_DetailNoTexture", + "UnlitGeneric_Detail", + "UnlitGeneric_EnvMapNoTexture", //"UnlitGeneric_DetailEnvMapNoTexture", + "UnlitGeneric_DetailEnvMap", + "UnlitGeneric_DetailNoTexture", + "UnlitGeneric_Detail", + "UnlitGeneric_EnvMapMaskNoTexture", //"UnlitGeneric_DetailEnvMapMaskNoTexture", + "UnlitGeneric_DetailEnvMapMask", + }; + + // handle hud elements + if ( bDetail & bDetailMultiplyMode ) + return "alphadist_ps11"; + + if ( bDetail & bMaskBaseByDetailAlpha ) + return "UnlitGeneric_MaskBaseByDetailAlpha_ps11"; + + if (!bMask && bEnvmap && bBaseTexture && bBaseAlphaEnvmapMask) + { + if (!bDetail) + return "UnlitGeneric_BaseAlphaMaskedEnvMap"; + else + return "UnlitGeneric_DetailBaseAlphaMaskedEnvMap"; + } + else + { + int pshIndex = 0; + if (bBaseTexture) + pshIndex |= 0x1; + if (bEnvmap) + pshIndex |= 0x2; + if (bMask) + pshIndex |= 0x4; + if (bDetail) + pshIndex |= 0x8; + return s_pPixelShaders[pshIndex]; + } +} + + +//----------------------------------------------------------------------------- +// Sets up hw morphing state for the vertex shader +//----------------------------------------------------------------------------- +void CBaseVSShader::SetHWMorphVertexShaderState( int nDimConst, int nSubrectConst, VertexTextureSampler_t morphSampler ) +{ +#ifndef _X360 + if ( !s_pShaderAPI->IsHWMorphingEnabled() ) + return; + + int nMorphWidth, nMorphHeight; + s_pShaderAPI->GetStandardTextureDimensions( &nMorphWidth, &nMorphHeight, TEXTURE_MORPH_ACCUMULATOR ); + + int nDim = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_4TUPLE_COUNT ); + float pMorphAccumSize[4] = { nMorphWidth, nMorphHeight, nDim, 0.0f }; + s_pShaderAPI->SetVertexShaderConstant( nDimConst, pMorphAccumSize ); + + int nXOffset = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_X_OFFSET ); + int nYOffset = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_Y_OFFSET ); + int nWidth = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_WIDTH ); + int nHeight = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_HEIGHT ); + float pMorphAccumSubrect[4] = { nXOffset, nYOffset, nWidth, nHeight }; + s_pShaderAPI->SetVertexShaderConstant( nSubrectConst, pMorphAccumSubrect ); + + s_pShaderAPI->BindStandardVertexTexture( morphSampler, TEXTURE_MORPH_ACCUMULATOR ); +#endif +} + + +//----------------------------------------------------------------------------- +// Vertex shader unlit generic pass +//----------------------------------------------------------------------------- +void CBaseVSShader::VertexShaderUnlitGenericPass( int baseTextureVar, int frameVar, + int baseTextureTransformVar, + int detailVar, int detailTransform, + bool bDetailTransformIsScale, + int envmapVar, int envMapFrameVar, + int envmapMaskVar, int envmapMaskFrameVar, + int envmapMaskScaleVar, int envmapTintVar, + int alphaTestReferenceVar, + int nDetailBlendModeVar, + int nOutlineVar, + int nOutlineColorVar, + int nOutlineStartVar, + int nOutlineEndVar, + int nSeparateDetailUVsVar ) +{ + IMaterialVar** params = s_ppParams; + + bool bBaseAlphaEnvmapMask = IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK); + bool bEnvmap = (envmapVar >= 0) && params[envmapVar]->IsTexture(); + bool bMask = false; + if (bEnvmap && (envmapMaskVar >= 0)) + { + bMask = params[envmapMaskVar]->IsTexture(); + } + bool bDetail = (detailVar >= 0) && params[detailVar]->IsTexture(); + bool bBaseTexture = (baseTextureVar >= 0) && params[baseTextureVar]->IsTexture(); + bool bVertexColor = IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR); + bool bEnvmapCameraSpace = IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE); + bool bEnvmapSphere = IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE); + + bool bDetailMultiply = ( nDetailBlendModeVar >= 0 ) && ( params[nDetailBlendModeVar]->GetIntValue() == 8 ); + bool bMaskBaseByDetailAlpha = ( nDetailBlendModeVar >= 0 ) && ( params[nDetailBlendModeVar]->GetIntValue() == 9 ); + bool bSeparateDetailUVs = ( nSeparateDetailUVsVar >= 0 ) && ( params[nSeparateDetailUVsVar]->GetIntValue() != 0 ); + + if (IsSnapshotting()) + { + // Alpha test + s_pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + if( alphaTestReferenceVar != -1 && params[alphaTestReferenceVar]->GetFloatValue() > 0.0f ) + { + s_pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[alphaTestReferenceVar]->GetFloatValue() ); + } + + // Base texture on stage 0 + if (bBaseTexture) + { + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + } + + if (bDetail) + { + s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + } + + if (bEnvmap) + { + // envmap on stage 1 + s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + // envmapmask on stage 2 + if (bMask || bBaseAlphaEnvmapMask ) + s_pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + } + + if (bBaseTexture) + SetDefaultBlendingShadowState( baseTextureVar, true ); + else if (bMask) + SetDefaultBlendingShadowState( envmapMaskVar, false ); + else + SetDefaultBlendingShadowState(); + + int fmt = VERTEX_POSITION; + if( bEnvmap ) + fmt |= VERTEX_NORMAL; + if ( bVertexColor ) + fmt |= VERTEX_COLOR; + + int numTexCoords = 1; + if( bSeparateDetailUVs ) + { + numTexCoords = 2; + } + + s_pShaderShadow->VertexShaderVertexFormat( fmt, numTexCoords, 0, 0 ); + const char *pshName = UnlitGeneric_ComputePixelShaderName( + bMask, + bEnvmap, + bBaseTexture, + bBaseAlphaEnvmapMask, + bDetail, + bDetailMultiply, + bMaskBaseByDetailAlpha ); + s_pShaderShadow->SetPixelShader( pshName ); + + // Compute the vertex shader index. + unlitgeneric_vs11_Static_Index vshIndex; + vshIndex.SetDETAIL( bDetail ); + vshIndex.SetENVMAP( bEnvmap ); + vshIndex.SetENVMAPCAMERASPACE( bEnvmap && bEnvmapCameraSpace ); + vshIndex.SetENVMAPSPHERE( bEnvmap && bEnvmapSphere ); + vshIndex.SetVERTEXCOLOR( bVertexColor ); + vshIndex.SetSEPARATEDETAILUVS( bSeparateDetailUVs ); + s_pShaderShadow->SetVertexShader( "unlitgeneric_vs11", vshIndex.GetIndex() ); + + DefaultFog(); + } + else + { + if ( s_pShaderAPI->InFlashlightMode() ) // Not snapshotting && flashlight pass + { + Draw( false ); + return; + } + + if (bBaseTexture) + { + BindTexture( SHADER_SAMPLER0, baseTextureVar, frameVar ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, baseTextureTransformVar ); + } + + if (bDetail) + { + BindTexture( SHADER_SAMPLER3, detailVar, frameVar ); + + if (bDetailTransformIsScale) + { + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, baseTextureTransformVar, detailTransform ); + } + else + { + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, detailTransform ); + } + } + + if (bEnvmap) + { + BindTexture( SHADER_SAMPLER1, envmapVar, envMapFrameVar ); + + if (bMask || bBaseAlphaEnvmapMask) + { + if (bMask) + BindTexture( SHADER_SAMPLER2, envmapMaskVar, envmapMaskFrameVar ); + else + BindTexture( SHADER_SAMPLER2, baseTextureVar, frameVar ); + + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, baseTextureTransformVar, envmapMaskScaleVar ); + } + + SetEnvMapTintPixelShaderDynamicState( 2, envmapTintVar, -1 ); + + if (bEnvmapSphere || IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE)) + { + LoadViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_VIEWMODEL ); + } + } + + SetModulationVertexShaderDynamicState(); + + float flConsts[12]={ 0, 0, 0, 1, // color + 0, 0, 0, 0, // max + 0, 0, 0, .5, // min + }; + + // set up outline pixel shader constants + if ( bDetailMultiply && ( nOutlineVar != -1 ) && ( params[nOutlineVar]->GetIntValue() ) ) + { + if ( nOutlineColorVar != -1 ) + params[nOutlineColorVar]->GetVecValue( flConsts, 3 ); + if ( nOutlineEndVar != -1 ) + flConsts[7] = params[nOutlineEndVar]->GetFloatValue(); + if ( nOutlineStartVar != -1 ) + flConsts[11] = params[nOutlineStartVar]->GetFloatValue(); + } + + s_pShaderAPI->SetPixelShaderConstant( 0, flConsts, 3 ); + + // Compute the vertex shader index. + unlitgeneric_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( s_pShaderAPI->GetCurrentNumBones() > 0 ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + + Draw(); +} + + +void CBaseVSShader::DrawWorldBaseTexture( int baseTextureVar, int baseTextureTransformVar, + int frameVar, int colorVar, int alphaVar ) +{ + if( IsSnapshotting() ) + { + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + s_pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION, 1, 0, 0 ); + s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BaseTexture" ); + SetNormalBlendingShadowState(); + lightmappedgeneric_basetexture_Static_Index vshIndex; + s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BaseTexture", vshIndex.GetIndex() ); + + FogToOOOverbright(); + } + else + { + IMaterialVar** params = s_ppParams; + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + if( bLightingOnly ) + { + s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); + } + else + { + BindTexture( SHADER_SAMPLER0, baseTextureVar, frameVar ); + } + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, baseTextureTransformVar ); + SetColorPixelShaderConstant( 0, colorVar, alphaVar ); + lightmappedgeneric_basetexture_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); +} + +void CBaseVSShader::DrawWorldBumpedDiffuseLighting( int bumpmapVar, int bumpFrameVar, + int bumpTransformVar, bool bMultiply, + bool bSSBump ) +{ + if( IsSnapshotting() ) + { + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + if( bMultiply ) + { + s_pShaderShadow->EnableBlending( true ); + SingleTextureLightmapBlendMode(); + } + s_pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 3, 0, 0 ); + + lightmappedgeneric_bumpmappedlightmap_Static_Index vshIndex; + s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BumpmappedLightmap", vshIndex.GetIndex() ); + + if ( bSSBump ) + s_pShaderShadow->SetPixelShader( "LightmappedGeneric_SSBumpmappedLightmap" ); + else + s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BumpmappedLightmap" ); + FogToFogColor(); + } + else + { + if( !g_pConfig->m_bFastNoBump ) + { + BindTexture( SHADER_SAMPLER0, bumpmapVar, bumpFrameVar ); + } + else + { + s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_NORMALMAP_FLAT ); + } + LoadBumpLightmapCoordinateAxes_PixelShader( 0 ); + s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP_BUMPED ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, bumpTransformVar ); + SetModulationPixelShaderDynamicState( 3 ); + + lightmappedgeneric_bumpmappedlightmap_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); +} + +void CBaseVSShader::DrawWorldBumpedDiffuseLighting_Base_ps14( int bumpmapVar, int bumpFrameVar, + int bumpTransformVar, + int baseTextureVar, int baseTextureTransformVar, int frameVar ) +{ + if( IsSnapshotting() ) + { + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + s_pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 3, 0, 0 ); + + lightmappedgeneric_bumpmappedlightmap_base_ps14_Static_Index vshIndex; + s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BumpmappedLightmap_Base_ps14", vshIndex.GetIndex() ); + + s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BumpmappedLightmap_Base_ps14" ); + FogToFogColor(); + } + else + { + if( !g_pConfig->m_bFastNoBump ) + { + BindTexture( SHADER_SAMPLER0, bumpmapVar, bumpFrameVar ); + } + else + { + s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_NORMALMAP_FLAT ); + } + LoadBumpLightmapCoordinateAxes_PixelShader( 0 ); + s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP_BUMPED ); + BindTexture( SHADER_SAMPLER4, baseTextureVar, frameVar ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, bumpTransformVar ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, baseTextureTransformVar ); + SetModulationPixelShaderDynamicState( 3 ); + + lightmappedgeneric_bumpmappedlightmap_base_ps14_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); +} + +void CBaseVSShader::DrawWorldBumpedDiffuseLighting_Blend_ps14( int bumpmapVar, int bumpFrameVar, + int bumpTransformVar, + int baseTextureVar, int baseTextureTransformVar, + int baseTextureFrameVar, + int baseTexture2Var, int baseTextureTransform2Var, + int baseTextureFrame2Var) +{ + if( IsSnapshotting() ) + { + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + s_pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 3, 0, 0 ); + + lightmappedgeneric_bumpmappedlightmap_blend_ps14_Static_Index vshIndex; + s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BumpmappedLightmap_Blend_ps14", vshIndex.GetIndex() ); + + s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BumpmappedLightmap_Blend_ps14" ); + FogToFogColor(); + } + else + { + if( !g_pConfig->m_bFastNoBump ) + { + BindTexture( SHADER_SAMPLER0, bumpmapVar, bumpFrameVar ); + } + else + { + s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_NORMALMAP_FLAT ); + } + LoadBumpLightmapCoordinateAxes_PixelShader( 0 ); + s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP_BUMPED ); + BindTexture( SHADER_SAMPLER4, baseTextureVar, baseTextureFrameVar ); + BindTexture( SHADER_SAMPLER5, baseTexture2Var, baseTextureFrame2Var ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, bumpTransformVar ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, baseTextureTransformVar ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, baseTextureTransform2Var ); + SetModulationPixelShaderDynamicState( 3 ); + + lightmappedgeneric_bumpmappedlightmap_blend_ps14_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); +} + +//#define USE_DEST_ALPHA +#define USE_NORMALMAP_ALPHA + +void CBaseVSShader::DrawWorldBumpedSpecularLighting( int bumpmapVar, int envmapVar, + int bumpFrameVar, int envmapFrameVar, + int envmapTintVar, int alphaVar, + int envmapContrastVar, int envmapSaturationVar, + int bumpTransformVar, int fresnelReflectionVar, + bool bBlend, bool bNoWriteZ ) +{ + // + BUMPED CUBEMAP + if( IsSnapshotting() ) + { + SetInitialShadowState( ); + if ( bNoWriteZ ) + { + s_pShaderShadow->EnableDepthWrites( false ); + } + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + if( g_pHardwareConfig->SupportsPixelShaders_1_4() ) + { + s_pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + } + if( bBlend ) + { + s_pShaderShadow->EnableBlending( true ); + s_pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + } + // FIXME: Remove the normal (needed for tangent space gen) + s_pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | + VERTEX_TANGENT_T, 1, 0, 0 ); + + IMaterialVar** params = s_ppParams; + bool bHasNormalMapAlphaEnvMapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + + if( g_pHardwareConfig->SupportsPixelShaders_1_4() ) + { + lightmappedgeneric_bumpmappedenvmap_ps14_Static_Index vshIndex; + s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BumpmappedEnvmap_ps14", vshIndex.GetIndex() ); + + int nPshIndex = bHasNormalMapAlphaEnvMapMask ? 1 : 0; + s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BumpmappedEnvmap_ps14", nPshIndex ); + } + else + { + lightmappedgeneric_bumpmappedenvmap_Static_Index vshIndex; + s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BumpmappedEnvmap", vshIndex.GetIndex() ); + + int nPshIndex = bHasNormalMapAlphaEnvMapMask ? 1 : 0; + s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BumpmappedEnvmap", nPshIndex ); + } + FogToBlack(); + } + else + { + IMaterialVar** params = s_ppParams; + s_pShaderAPI->SetDefaultState(); + BindTexture( SHADER_SAMPLER0, bumpmapVar, bumpFrameVar ); + BindTexture( SHADER_SAMPLER3, envmapVar, envmapFrameVar ); + + if( g_pHardwareConfig->SupportsPixelShaders_1_4() ) + { + s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALIZATION_CUBEMAP ); + + lightmappedgeneric_bumpmappedenvmap_ps14_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + else + { + lightmappedgeneric_bumpmappedenvmap_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + + SetEnvMapTintPixelShaderDynamicState( 0, envmapTintVar, alphaVar ); + // GR - fudge consts a bit to fix const/lerp issues + SetPixelShaderConstantFudge( 1, envmapContrastVar ); + SetPixelShaderConstantFudge( 2, envmapSaturationVar ); + float greyWeights[4] = { 0.299f, 0.587f, 0.114f, 0.0f }; + s_pShaderAPI->SetPixelShaderConstant( 3, greyWeights ); + + // [ 0, 0 ,0, R(0) ] + float fresnel[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + fresnel[3] = params[fresnelReflectionVar]->GetFloatValue(); + s_pShaderAPI->SetPixelShaderConstant( 4, fresnel ); + // [ 0, 0 ,0, 1-R(0) ] + fresnel[3] = 1.0f - fresnel[3]; + s_pShaderAPI->SetPixelShaderConstant( 6, fresnel ); + + float one[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + s_pShaderAPI->SetPixelShaderConstant( 5, one ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, bumpTransformVar ); + } + Draw(); +} + +void CBaseVSShader::DrawModelBumpedSpecularLighting( int bumpMapVar, int bumpMapFrameVar, + int envMapVar, int envMapVarFrame, + int envMapTintVar, int alphaVar, + int envMapContrastVar, int envMapSaturationVar, + int bumpTransformVar, + bool bBlendSpecular, bool bNoWriteZ ) +{ + IMaterialVar** params = s_ppParams; + + if( IsSnapshotting() ) + { + SetInitialShadowState( ); + if ( bNoWriteZ ) + { + s_pShaderShadow->EnableDepthWrites( false ); + } + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + if( g_pHardwareConfig->SupportsPixelShaders_1_4() ) + { + s_pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + } + s_pShaderShadow->EnableAlphaTest( false ); + if( bBlendSpecular ) + { + s_pShaderShadow->EnableBlending( true ); + SetAdditiveBlendingShadowState( -1, false ); + } + else + { + s_pShaderShadow->EnableBlending( false ); + SetNormalBlendingShadowState( -1, false ); + } + + s_pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION | VERTEX_NORMAL, 1, 0, 4 /* userDataSize */ ); + + bool bHasNormalMapAlphaEnvMapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + + if( g_pHardwareConfig->SupportsPixelShaders_1_4() ) + { + vertexlitgeneric_envmappedbumpmap_nolighting_ps14_Static_Index vshIndex; + s_pShaderShadow->SetVertexShader( "VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14", vshIndex.GetIndex() ); + if( bHasNormalMapAlphaEnvMapMask ) + { + s_pShaderShadow->SetPixelShader( "VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha_ps14" ); + } + else + { + s_pShaderShadow->SetPixelShader( "VertexLitGeneric_EnvmappedBumpmapV2_ps14" ); + } + } + else + { + vertexlitgeneric_envmappedbumpmap_nolighting_Static_Index vshIndex; + s_pShaderShadow->SetVertexShader( "VertexLitGeneric_EnvmappedBumpmap_NoLighting", vshIndex.GetIndex() ); + // This version does not multiply by lighting + // NOTE: We don't support multiplying by lighting for bumped specular stuff. + if( bHasNormalMapAlphaEnvMapMask ) + { + s_pShaderShadow->SetPixelShader( "VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha" ); + } + else + { + s_pShaderShadow->SetPixelShader( "VertexLitGeneric_EnvmappedBumpmapV2" ); + } + } + FogToBlack(); + } + else + { + s_pShaderAPI->SetDefaultState(); + BindTexture( SHADER_SAMPLER0, bumpMapVar, bumpMapFrameVar ); + BindTexture( SHADER_SAMPLER3, envMapVar, envMapVarFrame ); + if( g_pHardwareConfig->SupportsPixelShaders_1_4() ) + { + s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALIZATION_CUBEMAP ); + } + + if( bBlendSpecular ) + { + SetEnvMapTintPixelShaderDynamicState( 0, envMapTintVar, -1 ); + } + else + { + SetEnvMapTintPixelShaderDynamicState( 0, envMapTintVar, alphaVar ); + } + // GR - fudge consts a bit to fix const/lerp issues + SetPixelShaderConstantFudge( 1, envMapContrastVar ); + SetPixelShaderConstantFudge( 2, envMapSaturationVar ); + float greyWeights[4] = { 0.299f, 0.587f, 0.114f, 0.0f }; + s_pShaderAPI->SetPixelShaderConstant( 3, greyWeights ); + + // handle scrolling of bump texture + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, bumpTransformVar ); + + if( g_pHardwareConfig->SupportsPixelShaders_1_4() ) + { + vertexlitgeneric_envmappedbumpmap_nolighting_ps14_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( s_pShaderAPI->GetCurrentNumBones() > 0 ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + else + { + vertexlitgeneric_envmappedbumpmap_nolighting_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( s_pShaderAPI->GetCurrentNumBones() > 0 ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + } + Draw(); +} + +void CBaseVSShader::DrawBaseTextureBlend( int baseTextureVar, int baseTextureTransformVar, + int baseTextureFrameVar, + int baseTexture2Var, int baseTextureTransform2Var, + int baseTextureFrame2Var, int colorVar, int alphaVar ) +{ + if( IsSnapshotting() ) + { + SetInitialShadowState(); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + s_pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | + SHADER_DRAW_LIGHTMAP_TEXCOORD1 ); + // FIXME: Remove the normal (needed for tangent space gen) + s_pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION, 2, 0, 0 ); + + lightmappedgeneric_basetextureblend_Static_Index vshIndex; + s_pShaderShadow->SetVertexShader( "lightmappedgeneric_basetextureblend", vshIndex.GetIndex() ); + + s_pShaderShadow->SetPixelShader( "lightmappedgeneric_basetextureblend", 0 ); + FogToOOOverbright(); + } + else + { + IMaterialVar** params = s_ppParams; + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + + s_pShaderAPI->SetDefaultState(); + if( bLightingOnly ) + { + s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); + } + else + { + BindTexture( SHADER_SAMPLER0, baseTextureVar, baseTextureFrameVar ); + BindTexture( SHADER_SAMPLER1, baseTexture2Var, baseTextureFrame2Var ); + } + s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_LIGHTMAP ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, baseTextureTransformVar ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, baseTextureTransform2Var ); + SetColorPixelShaderConstant( 0, colorVar, alphaVar ); + lightmappedgeneric_basetextureblend_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); +} + +void CBaseVSShader::DrawWorldBumpedUsingVertexShader( int baseTextureVar, int baseTextureTransformVar, + int bumpmapVar, int bumpFrameVar, + int bumpTransformVar, + int envmapMaskVar, int envmapMaskFrame, + int envmapVar, + int envmapFrameVar, + int envmapTintVar, int colorVar, int alphaVar, + int envmapContrastVar, int envmapSaturationVar, + int frameVar, int fresnelReflectionVar, + bool doBaseTexture2, + int baseTexture2Var, int baseTextureTransform2Var, + int baseTextureFrame2Var, + bool bSSBump + ) +{ + IMaterialVar** params = s_ppParams; + // Draw base texture + bool bMultiplyDiffuseLighting = false; + bool bBlendSpecular = false; + + // Draw base texture(s) + if( doBaseTexture2 && params[baseTexture2Var]->IsTexture() && params[baseTextureVar]->IsTexture() ) + { + DrawBaseTextureBlend( baseTextureVar, baseTextureTransformVar, frameVar, + baseTexture2Var, baseTextureTransform2Var, baseTextureFrame2Var, colorVar, alphaVar ); + bMultiplyDiffuseLighting = true; + bBlendSpecular = true; + } + else if( params[baseTextureVar]->IsTexture() ) + { + DrawWorldBaseTexture( baseTextureVar, baseTextureTransformVar, frameVar, colorVar, alphaVar ); + bMultiplyDiffuseLighting = true; + bBlendSpecular = true; + } + else + { + // Just use color here + } + + // Draw diffuse lighting + if( params[baseTextureVar]->IsTexture() || !params[envmapVar]->IsTexture() ) + { + DrawWorldBumpedDiffuseLighting( bumpmapVar, bumpFrameVar, bumpTransformVar, + bMultiplyDiffuseLighting, bSSBump ); + bBlendSpecular = true; + } + + // Add specular lighting + if( params[envmapVar]->IsTexture() ) + { + DrawWorldBumpedSpecularLighting( + bumpmapVar, envmapVar, + bumpFrameVar, envmapFrameVar, + envmapTintVar, alphaVar, + envmapContrastVar, envmapSaturationVar, + bumpTransformVar, fresnelReflectionVar, + bBlendSpecular ); + } +} +#endif // GAME_SHADER_DLL + + +//----------------------------------------------------------------------------- +// GR - translucency query +//----------------------------------------------------------------------------- +BlendType_t CBaseVSShader::EvaluateBlendRequirements( int textureVar, bool isBaseTexture, + int detailTextureVar ) +{ + // Either we've got a constant modulation + bool isTranslucent = IsAlphaModulating(); + + // Or we've got a vertex alpha + isTranslucent = isTranslucent || (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA); + + // Or we've got a texture alpha (for blending or alpha test) + isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) && + !(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) ); + + if ( ( detailTextureVar != -1 ) && ( ! isTranslucent ) ) + { + isTranslucent = TextureIsTranslucent( detailTextureVar, isBaseTexture ); + } + + if ( CurrentMaterialVarFlags() & MATERIAL_VAR_ADDITIVE ) + { + return isTranslucent ? BT_BLENDADD : BT_ADD; // Additive + } + else + { + return isTranslucent ? BT_BLEND : BT_NONE; // Normal blending + } +} + +#ifndef GAME_SHADER_DLL + +void CBaseVSShader::SetFlashlightVertexShaderConstants( bool bBump, int bumpTransformVar, bool bDetail, int detailScaleVar, bool bSetTextureTransforms ) +{ + Assert( !IsSnapshotting() ); + + VMatrix worldToTexture; + const FlashlightState_t &flashlightState = s_pShaderAPI->GetFlashlightState( worldToTexture ); + + // Set the flashlight origin + float pos[4]; + pos[0] = flashlightState.m_vecLightOrigin[0]; + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + pos[3] = 1.0f / ( ( 0.6f * flashlightState.m_FarZ ) - flashlightState.m_FarZ ); // DX8 needs this + + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, pos, 1 ); + + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, worldToTexture.Base(), 4 ); + + // Set the flashlight attenuation factors + float atten[4]; + atten[0] = flashlightState.m_fConstantAtten; + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, atten, 1 ); + + if ( bDetail ) + { + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, BASETEXTURETRANSFORM, detailScaleVar ); + } + + if( bSetTextureTransforms ) + { + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, BASETEXTURETRANSFORM ); + if( !bDetail && bBump && bumpTransformVar != -1 ) + { + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, bumpTransformVar ); // aliased on top of detail transform + } + } +} + +#if SUPPORT_DX8 +void CBaseVSShader::DrawFlashlight_dx80( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bBump, + int bumpmapVar, int bumpmapFrame, int bumpTransform, int flashlightTextureVar, int flashlightTextureFrameVar, + bool bLightmappedGeneric, bool bWorldVertexTransition, int nWorldVertexTransitionPassID, int baseTexture2Var, + int baseTexture2FrameVar, bool bTeeth, int nTeethForwardVar, int nTeethIllumFactorVar ) +{ + // FLASHLIGHTFIXME: hack . . need to fix the vertex shader so that it can deal with and without bumps for vertexlitgeneric + if( !bLightmappedGeneric ) + { + bBump = false; + } + if( pShaderShadow ) + { + SetInitialShadowState(); + pShaderShadow->EnableDepthWrites( false ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + // Never alpha test the flashlight pass + pShaderShadow->EnableAlphaTest( false ); + + if ( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) ) + { + // use zfunc zequals since alpha isn't guaranteed to + // be the same on both the regular pass and the flashlight pass. + pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); + } + + // Alpha blend + if( bWorldVertexTransition ) + { + // use separate alpha blend to make sure that we aren't adding alpha from source + if( nWorldVertexTransitionPassID == 0 ) + { + EnableAlphaBlending( SHADER_BLEND_DST_ALPHA, SHADER_BLEND_ONE ); + } + else + { + EnableAlphaBlending( SHADER_BLEND_ONE_MINUS_DST_ALPHA, SHADER_BLEND_ONE ); + } + } + else + { + SetAdditiveBlendingShadowState( BASETEXTURE, true ); + } + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + if( bLightmappedGeneric ) + { + bool bUsingVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); + lightmappedgeneric_flashlight_vs11_Static_Index vshIndex; + vshIndex.SetNORMALMAP( bBump ); + vshIndex.SetWORLDVERTEXTRANSITION( bWorldVertexTransition ); + vshIndex.SetVERTEXCOLOR( bUsingVertexColor ); + pShaderShadow->SetVertexShader( "lightmappedgeneric_flashlight_vs11", vshIndex.GetIndex() ); + + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; + if( bBump ) + { + flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; + } + if ( bWorldVertexTransition || bUsingVertexColor ) + { + flags |= VERTEX_COLOR; + } + pShaderShadow->VertexShaderVertexFormat( flags, 1, 0, 0 ); + } + else + { + vertexlitgeneric_flashlight_vs11_Static_Index vshIndex; + vshIndex.SetTEETH( bTeeth ); + pShaderShadow->SetVertexShader( "vertexlitgeneric_flashlight_vs11", vshIndex.GetIndex() ); + + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; + pShaderShadow->VertexShaderVertexFormat( flags, 1, 0, bBump ? 4 : 0 ); + } + + bool bNoCull = IS_FLAG_SET( MATERIAL_VAR_NOCULL ); + + flashlight_ps11_Static_Index pshIndex; + pshIndex.SetNORMALMAP( bBump ); + pshIndex.SetNOCULL( bNoCull ); + pShaderShadow->SetPixelShader( "flashlight_ps11", pshIndex.GetIndex() ); + + FogToBlack(); + } + else + { + // Specify that we have XYZ texcoords that need to be divided by W before the pixel shader. + // NOTE Tried to divide XY by Z, but doesn't work. + // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. + pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE0, 0, true ); + BindTexture( SHADER_SAMPLER0, flashlightTextureVar, flashlightTextureFrameVar ); + + if( bWorldVertexTransition && ( nWorldVertexTransitionPassID == 1 ) ) + { + BindTexture( SHADER_SAMPLER1, baseTexture2Var, baseTexture2FrameVar ); + } + else + { + if( params[BASETEXTURE]->IsTexture() ) + { + BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); + } + } + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP ); + if( bBump ) + { + BindTexture( SHADER_SAMPLER3, bumpmapVar, bumpmapFrame ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALIZATION_CUBEMAP ); + } + + if( bLightmappedGeneric ) + { + lightmappedgeneric_flashlight_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + else + { + vertexlitgeneric_flashlight_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + + if( bTeeth ) + { + Assert( nTeethForwardVar >= 0 ); + Assert( nTeethIllumFactorVar >= 0 ); + Vector4D lighting; + params[nTeethForwardVar]->GetVecValue( lighting.Base(), 3 ); + lighting[3] = params[nTeethIllumFactorVar]->GetFloatValue(); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, lighting.Base() ); + } + + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + + flashlight_ps11_Dynamic_Index pshIndex; + pShaderAPI->SetPixelShaderIndex( pshIndex.GetIndex() ); + + SetFlashlightVertexShaderConstants( bBump, bumpTransform, false, -1, true ); + } + Draw(); +} +#endif // support_dx8 + +#ifdef STDSHADER_DX9_DLL_EXPORT +void CBaseVSShader::DrawFlashlight_dx90( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, DrawFlashlight_dx90_Vars_t &vars ) +{ + // FLASHLIGHTFIXME: hack . . need to fix the vertex shader so that it can deal with and without bumps for vertexlitgeneric + if( !vars.m_bLightmappedGeneric ) + { + vars.m_bBump = false; + } + bool bBump2 = vars.m_bWorldVertexTransition && vars.m_bBump && vars.m_nBumpmap2Var != -1 && params[vars.m_nBumpmap2Var]->IsTexture(); + bool bSeamless = vars.m_fSeamlessScale != 0.0; + bool bDetail = vars.m_bLightmappedGeneric && (vars.m_nDetailVar != -1) && params[vars.m_nDetailVar]->IsDefined() && (vars.m_nDetailScale != -1); + + int nDetailBlendMode = 0; + if ( bDetail ) + { + nDetailBlendMode = GetIntParam( vars.m_nDetailTextureCombineMode, params ); + nDetailBlendMode = nDetailBlendMode > 1 ? 1 : nDetailBlendMode; + } + + if( pShaderShadow ) + { + SetInitialShadowState(); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( false ); + + // Alpha blend + SetAdditiveBlendingShadowState( BASETEXTURE, true ); + + // Alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) ); + if ( vars.m_nAlphaTestReference != -1 && params[vars.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[vars.m_nAlphaTestReference]->GetFloatValue() ); + } + + // Spot sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + // Base sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + + // Normalizing cubemap sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + // Normalizing cubemap sampler2 or normal map sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + // RandomRotation sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + + // Flashlight depth sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER7 ); + + if( vars.m_bWorldVertexTransition ) + { + // $basetexture2 + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true ); + } + if( bBump2 ) + { + // Normalmap2 sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + } + if( bDetail ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // detail sampler + if ( nDetailBlendMode != 0 ) //Not Mod2X + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, true ); + } + + pShaderShadow->EnableSRGBWrite( true ); + + if( vars.m_bLightmappedGeneric ) + { + lightmappedgeneric_flashlight_vs20_Static_Index vshIndex; + vshIndex.SetWORLDVERTEXTRANSITION( vars.m_bWorldVertexTransition ); + vshIndex.SetNORMALMAP( vars.m_bBump ); + vshIndex.SetSEAMLESS( bSeamless ); + vshIndex.SetDETAIL( bDetail ); + pShaderShadow->SetVertexShader( "lightmappedgeneric_flashlight_vs20", vshIndex.GetIndex() ); + + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; + if( vars.m_bBump ) + { + flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; + } + int numTexCoords = 1; + if( vars.m_bWorldVertexTransition ) + { + flags |= VERTEX_COLOR; + numTexCoords = 2; // need lightmap texcoords to get alpha. + } + pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); + } + else + { + vertexlitgeneric_flashlight_vs11_Static_Index vshIndex; + vshIndex.SetTEETH( vars.m_bTeeth ); + pShaderShadow->SetVertexShader( "vertexlitgeneric_flashlight_vs11", vshIndex.GetIndex() ); + + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; + int numTexCoords = 1; + pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, vars.m_bBump ? 4 : 0 ); + } + + int nBumpMapVariant = 0; + if ( vars.m_bBump ) + { + nBumpMapVariant = ( vars.m_bSSBump ) ? 2 : 1; + } + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + int nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); + + flashlight_ps20b_Static_Index pshIndex; + pshIndex.SetNORMALMAP( nBumpMapVariant ); + pshIndex.SetNORMALMAP2( bBump2 ); + pshIndex.SetWORLDVERTEXTRANSITION( vars.m_bWorldVertexTransition ); + pshIndex.SetSEAMLESS( bSeamless ); + pshIndex.SetDETAILTEXTURE( bDetail ); + pshIndex.SetDETAIL_BLEND_MODE( nDetailBlendMode ); + pshIndex.SetFLASHLIGHTDEPTHFILTERMODE( nShadowFilterMode ); + pShaderShadow->SetPixelShader( "flashlight_ps20b", pshIndex.GetIndex() ); + } + else + { + flashlight_ps20_Static_Index pshIndex; + pshIndex.SetNORMALMAP( nBumpMapVariant ); + pshIndex.SetNORMALMAP2( bBump2 ); + pshIndex.SetWORLDVERTEXTRANSITION( vars.m_bWorldVertexTransition ); + pshIndex.SetSEAMLESS( bSeamless ); + pshIndex.SetDETAILTEXTURE( bDetail ); + pshIndex.SetDETAIL_BLEND_MODE( nDetailBlendMode ); + pShaderShadow->SetPixelShader( "flashlight_ps20", pshIndex.GetIndex() ); + } + FogToBlack(); + } + else + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + + SetFlashLightColorFromState( flashlightState, pShaderAPI ); + + BindTexture( SHADER_SAMPLER0, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows ) + { + BindTexture( SHADER_SAMPLER7, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); + + // Tweaks associated with a given flashlight + float tweaks[4]; + 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 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); + } + + if( params[BASETEXTURE]->IsTexture() && mat_fullbright.GetInt() != 2 ) + { + BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); + } + if( vars.m_bWorldVertexTransition ) + { + Assert( vars.m_nBaseTexture2Var >= 0 && vars.m_nBaseTexture2FrameVar >= 0 ); + BindTexture( SHADER_SAMPLER4, vars.m_nBaseTexture2Var, vars.m_nBaseTexture2FrameVar ); + } + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP ); + if( vars.m_bBump ) + { + BindTexture( SHADER_SAMPLER3, vars.m_nBumpmapVar, vars.m_nBumpmapFrame ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALIZATION_CUBEMAP ); + } + + if( bDetail ) + { + BindTexture( SHADER_SAMPLER8, vars.m_nDetailVar ); + } + + if( vars.m_bWorldVertexTransition ) + { + if( bBump2 ) + { + BindTexture( SHADER_SAMPLER6, vars.m_nBumpmap2Var, vars.m_nBumpmap2Frame ); + } + } + + if( vars.m_bLightmappedGeneric ) + { + DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs20 ); + if ( bSeamless ) + { + float const0[4]={ vars.m_fSeamlessScale,0,0,0}; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, const0 ); + } + + if ( bDetail ) + { + float vDetailConstants[4] = {1,1,1,1}; + + if ( vars.m_nDetailTint != -1 ) + { + params[vars.m_nDetailTint]->GetVecValue( vDetailConstants, 3 ); + } + + if ( vars.m_nDetailTextureBlendFactor != -1 ) + { + vDetailConstants[3] = params[vars.m_nDetailTextureBlendFactor]->GetFloatValue(); + } + + pShaderAPI->SetPixelShaderConstant( 0, vDetailConstants, 1 ); + } + } + else + { + vertexlitgeneric_flashlight_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + if( vars.m_bTeeth ) + { + Assert( vars.m_nTeethForwardVar >= 0 ); + Assert( vars.m_nTeethIllumFactorVar >= 0 ); + Vector4D lighting; + params[vars.m_nTeethForwardVar]->GetVecValue( lighting.Base(), 3 ); + lighting[3] = params[vars.m_nTeethIllumFactorVar]->GetFloatValue(); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lighting.Base() ); + } + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( flashlight_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ) ); + SET_DYNAMIC_PIXEL_SHADER( flashlight_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( flashlight_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( flashlight_ps20 ); + } + + float atten[4]; // 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; + s_pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); + + SetFlashlightVertexShaderConstants( vars.m_bBump, vars.m_nBumpTransform, bDetail, vars.m_nDetailScale, bSeamless ? false : true ); + } + Draw(); +} + +#endif + +void CBaseVSShader::InitParamsUnlitGeneric_DX8( + int baseTextureVar, + int detailScaleVar, + int envmapOptionalVar, + int envmapVar, + int envmapTintVar, + int envmapMaskScaleVar, + int nDetailBlendMode ) +{ + IMaterialVar** params = s_ppParams; + + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + if( envmapTintVar >= 0 && !params[envmapTintVar]->IsDefined() ) + { + params[envmapTintVar]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if( envmapMaskScaleVar >= 0 && !params[envmapMaskScaleVar]->IsDefined() ) + { + params[envmapMaskScaleVar]->SetFloatValue( 1.0f ); + } + + if( detailScaleVar >= 0 && !params[detailScaleVar]->IsDefined() ) + { + params[detailScaleVar]->SetFloatValue( 4.0f ); + } + + // No texture means no self-illum or env mask in base alpha + if ( baseTextureVar >= 0 && !params[baseTextureVar]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + // Get rid of the envmap if it's optional for this dx level. + if( envmapOptionalVar >= 0 && params[envmapOptionalVar]->IsDefined() && params[envmapOptionalVar]->GetIntValue() ) + { + if (envmapVar >= 0) + { + params[envmapVar]->SetUndefined(); + } + } + + // If mat_specular 0, then get rid of envmap + if( envmapVar >= 0 && baseTextureVar >= 0 && !g_pConfig->UseSpecular() && params[envmapVar]->IsDefined() && params[baseTextureVar]->IsDefined() ) + { + params[envmapVar]->SetUndefined(); + } +} + +void CBaseVSShader::InitUnlitGeneric_DX8( + int baseTextureVar, + int detailVar, + int envmapVar, + int envmapMaskVar ) +{ + IMaterialVar** params = s_ppParams; + + if (baseTextureVar >= 0 && params[baseTextureVar]->IsDefined()) + { + LoadTexture( baseTextureVar ); + + if (!params[baseTextureVar]->GetTextureValue()->IsTranslucent()) + { + if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + // Don't alpha test if the alpha channel is used for other purposes + if ( IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + + // the second texture (if there is one) + if (detailVar >= 0 && params[detailVar]->IsDefined()) + { + LoadTexture( detailVar ); + } + + if (envmapVar >= 0 && params[envmapVar]->IsDefined()) + { + if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + LoadCubeMap( envmapVar ); + else + LoadTexture( envmapVar ); + + if( !g_pHardwareConfig->SupportsCubeMaps() ) + SET_FLAGS(MATERIAL_VAR_ENVMAPSPHERE); + + if (envmapMaskVar >= 0 && params[envmapMaskVar]->IsDefined()) + LoadTexture( envmapMaskVar ); + } +} +#endif // GAME_SHADER_DLL + +#endif // !_STATIC_LINKED || STDSHADER_DX8_DLL_EXPORT + + +// Take 0..1 seed and map to (u, v) coordinate to be used in shadow filter jittering... +void CBaseVSShader::HashShadow2DJitter( const float fJitterSeed, float *fU, float* fV ) +{ + const int nTexRes = 32; + int nSeed = fmod (fJitterSeed, 1.0f) * nTexRes * nTexRes; + + int nRow = nSeed / nTexRes; + int nCol = nSeed % nTexRes; + + // Div and mod to get an individual texel in the fTexRes x fTexRes grid + *fU = nRow / (float) nTexRes; // Row + *fV = nCol / (float) nTexRes; // Column +} + + +void CBaseVSShader::DrawEqualDepthToDestAlpha( void ) +{ +#ifdef STDSHADER_DX9_DLL_EXPORT + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + bool bMakeActualDrawCall = false; + if( s_pShaderShadow ) + { + s_pShaderShadow->EnableColorWrites( false ); + s_pShaderShadow->EnableAlphaWrites( true ); + s_pShaderShadow->EnableDepthWrites( false ); + s_pShaderShadow->EnableAlphaTest( false ); + s_pShaderShadow->EnableBlending( false ); + + s_pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); + + s_pShaderShadow->SetVertexShader( "depthtodestalpha_vs20", 0 ); + s_pShaderShadow->SetPixelShader( "depthtodestalpha_ps20b", 0 ); + } + if( s_pShaderAPI ) + { + s_pShaderAPI->SetVertexShaderIndex( 0 ); + s_pShaderAPI->SetPixelShaderIndex( 0 ); + + bMakeActualDrawCall = s_pShaderAPI->ShouldWriteDepthToDestAlpha(); + } + Draw( bMakeActualDrawCall ); + } +#else + Assert( 0 ); //probably just needs a shader update to the latest +#endif +} diff --git a/mp/src/materialsystem/stdshaders/BaseVSShader.h b/mp/src/materialsystem/stdshaders/BaseVSShader.h index 2a38afb1..1ba6cc43 100644 --- a/mp/src/materialsystem/stdshaders/BaseVSShader.h +++ b/mp/src/materialsystem/stdshaders/BaseVSShader.h @@ -1,439 +1,439 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// This is what all vs/ps (dx8+) shaders inherit from. -//===========================================================================// - -#ifndef BASEVSSHADER_H -#define BASEVSSHADER_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "shaderlib/cshader.h" -#include "shaderlib/BaseShader.h" -#include "convar.h" -#include - -#ifdef _X360 -#define SUPPORT_DX8 0 -#define SUPPORT_DX7 0 -#else -#define SUPPORT_DX8 1 -#define SUPPORT_DX7 1 -#endif -//----------------------------------------------------------------------------- -// Helper macro for vertex shaders -//----------------------------------------------------------------------------- -#define BEGIN_VS_SHADER_FLAGS(_name, _help, _flags) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, _flags ) -#define BEGIN_VS_SHADER(_name,_help) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, 0 ) - - -// useful parameter initialization macro -#define INIT_FLOAT_PARM( parm, value ) \ - if ( !params[(parm)]->IsDefined() ) \ - { \ - params[(parm)]->SetFloatValue( (value) ); \ - } - -// useful pixel shader declaration macro for ps20/20b c++ code -#define SET_STATIC_PS2X_PIXEL_SHADER_NO_COMBOS( basename ) \ - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) \ - { \ - DECLARE_STATIC_PIXEL_SHADER( basename##_ps20b ); \ - SET_STATIC_PIXEL_SHADER( basename##_ps20b ); \ - } \ - else \ - { \ - DECLARE_STATIC_PIXEL_SHADER( basename##_ps20 ); \ - SET_STATIC_PIXEL_SHADER( basename##_ps20 ); \ - } - -#define SET_DYNAMIC_PS2X_PIXEL_SHADER_NO_COMBOS( basename ) \ - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) \ - { \ - DECLARE_DYNAMIC_PIXEL_SHADER( basename##_ps20b ); \ - SET_DYNAMIC_PIXEL_SHADER( basename##_ps20b ); \ - } \ - else \ - { \ - DECLARE_DYNAMIC_PIXEL_SHADER( basename##_ps20 ); \ - SET_DYNAMIC_PIXEL_SHADER( basename##_ps20 ); \ - } - - -//----------------------------------------------------------------------------- -// Base class for shaders, contains helper methods. -//----------------------------------------------------------------------------- -class CBaseVSShader : public CBaseShader -{ -public: - - // Loads bump lightmap coordinates into the pixel shader - void LoadBumpLightmapCoordinateAxes_PixelShader( int pixelReg ); - - // Loads bump lightmap coordinates into the vertex shader - void LoadBumpLightmapCoordinateAxes_VertexShader( int vertexReg ); - - // Pixel and vertex shader constants.... - void SetPixelShaderConstant( int pixelReg, int constantVar ); - - // Pixel and vertex shader constants.... - void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar ); - - // This version will put constantVar into x,y,z, and constantVar2 into the w - void SetPixelShaderConstant( int pixelReg, int constantVar, int constantVar2 ); - void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar, int constantVar2 ); - - // Helpers for setting constants that need to be converted to linear space (from gamma space). - void SetVertexShaderConstantGammaToLinear( int var, float const* pVec, int numConst = 1, bool bForce = false ); - void SetPixelShaderConstantGammaToLinear( int var, float const* pVec, int numConst = 1, bool bForce = false ); - - void SetVertexShaderConstant( int vertexReg, int constantVar ); - - // set rgb components of constant from a color parm and give an explicit w value - void SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue ); - - // GR - fix for const/lerp issues - void SetPixelShaderConstantFudge( int pixelReg, int constantVar ); - - // Sets light direction for pixel shaders. - void SetPixelShaderLightColors( int pixelReg ); - - // Sets vertex shader texture transforms - void SetVertexShaderTextureTranslation( int vertexReg, int translationVar ); - void SetVertexShaderTextureScale( int vertexReg, int scaleVar ); - void SetVertexShaderTextureTransform( int vertexReg, int transformVar ); - void SetVertexShaderTextureScaledTransform( int vertexReg, - int transformVar, int scaleVar ); - - // Set pixel shader texture transforms - void SetPixelShaderTextureTranslation( int pixelReg, int translationVar ); - void SetPixelShaderTextureScale( int pixelReg, int scaleVar ); - void SetPixelShaderTextureTransform( int pixelReg, int transformVar ); - void SetPixelShaderTextureScaledTransform( int pixelReg, - int transformVar, int scaleVar ); - - // Moves a matrix into vertex shader constants - void SetVertexShaderMatrix3x4( int vertexReg, int matrixVar ); - void SetVertexShaderMatrix4x4( int vertexReg, int matrixVar ); - - // Loads the view matrix into vertex shader constants - void LoadViewMatrixIntoVertexShaderConstant( int vertexReg ); - - // Loads the projection matrix into vertex shader constants - void LoadProjectionMatrixIntoVertexShaderConstant( int vertexReg ); - - // Loads the model->view matrix into vertex shader constants - void LoadModelViewMatrixIntoVertexShaderConstant( int vertexReg ); - - // Loads a scale/offset version of the viewport transform into the specified constant. - void LoadViewportTransformScaledIntoVertexShaderConstant( int vertexReg ); - - // Sets up ambient light cube... - void SetAmbientCubeDynamicStateVertexShader( ); - float GetAmbientLightCubeLuminance( ); - - // Helpers for dealing with envmaptint - void SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear = false ); - - // Helper methods for pixel shader overbrighting - void EnablePixelShaderOverbright( int reg, bool bEnable, bool bDivideByTwo ); - - // Helper for dealing with modulation - void SetModulationVertexShaderDynamicState(); - void SetModulationPixelShaderDynamicState( int modulationVar ); - void SetModulationPixelShaderDynamicState_LinearColorSpace( int modulationVar ); - void SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( int modulationVar, float flScale ); - - // Sets a color + alpha into shader constants - void SetColorVertexShaderConstant( int nVertexReg, int colorVar, int alphaVar ); - void SetColorPixelShaderConstant( int nPixelReg, int colorVar, int alphaVar ); - - -#ifndef GAME_SHADER_DLL - // - // Standard shader passes! - // - - void InitParamsUnlitGeneric_DX8( - int baseTextureVar, - int detailScaleVar, - int envmapOptionalVar, - int envmapVar, - int envmapTintVar, - int envmapMaskScaleVar, - int nDetailBlendMode ); - - void InitUnlitGeneric_DX8( - int baseTextureVar, - int detailVar, - int envmapVar, - int envmapMaskVar ); - - // Dx8 Unlit Generic pass - void VertexShaderUnlitGenericPass( int baseTextureVar, int frameVar, - int baseTextureTransformVar, - int detailVar, int detailTransform, bool bDetailTransformIsScale, - int envmapVar, int envMapFrameVar, int envmapMaskVar, - int envmapMaskFrameVar, int envmapMaskScaleVar, int envmapTintVar, - int alphaTestReferenceVar, - int nDetailBlendModeVar, - int nOutlineVar, - int nOutlineColorVar, - int nOutlineStartVar, - int nOutlineEndVar, - int nSeparateDetailUVsVar - ); - - // Helpers for drawing world bump mapped stuff. - void DrawModelBumpedSpecularLighting( int bumpMapVar, int bumpMapFrameVar, - int envMapVar, int envMapVarFrame, - int envMapTintVar, int alphaVar, - int envMapContrastVar, int envMapSaturationVar, - int bumpTransformVar, - bool bBlendSpecular, bool bNoWriteZ = false ); - void DrawWorldBumpedSpecularLighting( int bumpmapVar, int envmapVar, - int bumpFrameVar, int envmapFrameVar, - int envmapTintVar, int alphaVar, - int envmapContrastVar, int envmapSaturationVar, - int bumpTransformVar, int fresnelReflectionVar, - bool bBlend, bool bNoWriteZ = false ); - - const char *UnlitGeneric_ComputeVertexShaderName( bool bMask, - bool bEnvmap, - bool bBaseTexture, - bool bBaseAlphaEnvmapMask, - bool bDetail, - bool bVertexColor, - bool bEnvmapCameraSpace, - bool bEnvmapSphere ); - - const char *UnlitGeneric_ComputePixelShaderName( bool bMask, - bool bEnvmap, - bool bBaseTexture, - bool bBaseAlphaEnvmapMask, - bool bDetail, - bool bMultiplyDetail, - bool bMaskBaseByDetailAlpha ); - - void DrawWorldBaseTexture( int baseTextureVar, int baseTextureTransformVar, int frameVar, int colorVar, int alphaVar ); - void DrawWorldBumpedDiffuseLighting( int bumpmapVar, int bumpFrameVar, - int bumpTransformVar, bool bMultiply, bool bSSBump ); - void DrawWorldBumpedSpecularLighting( int envmapMaskVar, int envmapMaskFrame, - int bumpmapVar, int envmapVar, - int bumpFrameVar, int envmapFrameVar, - int envmapTintVar, int alphaVar, - int envmapContrastVar, int envmapSaturationVar, - int bumpTransformVar, int fresnelReflectionVar, - bool bBlend ); - void DrawBaseTextureBlend( int baseTextureVar, int baseTextureTransformVar, - int baseTextureFrameVar, - int baseTexture2Var, int baseTextureTransform2Var, - int baseTextureFrame2Var, int colorVar, int alphaVar ); - void DrawWorldBumpedDiffuseLighting_Base_ps14( int bumpmapVar, int bumpFrameVar, - int bumpTransformVar, int baseTextureVar, int baseTextureTransformVar, int frameVar ); - void DrawWorldBumpedDiffuseLighting_Blend_ps14( int bumpmapVar, int bumpFrameVar, int bumpTransformVar, - int baseTextureVar, int baseTextureTransformVar, int baseTextureFrameVar, - int baseTexture2Var, int baseTextureTransform2Var, int baseTextureFrame2Var); - void DrawWorldBumpedUsingVertexShader( int baseTextureVar, int baseTextureTransformVar, - int bumpmapVar, int bumpFrameVar, - int bumpTransformVar, - int envmapMaskVar, int envmapMaskFrame, - int envmapVar, - int envmapFrameVar, - int envmapTintVar, int colorVar, int alphaVar, - int envmapContrastVar, int envmapSaturationVar, int frameVar, int fresnelReflectionVar, - bool doBaseTexture2, - int baseTexture2Var, - int baseTextureTransform2Var, - int baseTextureFrame2Var, - bool bSSBump - ); - - // Sets up hw morphing state for the vertex shader - void SetHWMorphVertexShaderState( int nDimConst, int nSubrectConst, VertexTextureSampler_t morphSampler ); - - // Computes the shader index for vertex lit materials - int ComputeVertexLitShaderIndex( bool bVertexLitGeneric, bool hasBump, bool hasEnvmap, bool hasVertexColor, bool bHasNormal ) const; - - // Helper for setting up flashlight constants - void SetFlashlightVertexShaderConstants( bool bBump, int bumpTransformVar, bool bDetail, int detailScaleVar, bool bSetTextureTransforms ); - -#if SUPPORT_DX8 - void DrawFlashlight_dx80( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, - bool bBump, int bumpmapVar, int bumpmapFrame, int bumpTransform, int flashlightTextureVar, - int flashlightTextureFrameVar, bool bLightmappedGeneric, bool bWorldVertexTransition, - int nWorldVertexTransitionPassID, int baseTexture2Var, int baseTexture2FrameVar, - bool bTeeth=false, int nTeethForwardVar=0, int nTeethIllumFactorVar=0 ); -#endif - - struct DrawFlashlight_dx90_Vars_t - { - DrawFlashlight_dx90_Vars_t() - { - // set all ints to -1 - memset( this, 0xFF, sizeof(DrawFlashlight_dx90_Vars_t) ); - // set all bools to a default value. - m_bBump = false; - m_bLightmappedGeneric = false; - m_bWorldVertexTransition = false; - m_bTeeth = false; - m_bSSBump = false; - m_fSeamlessScale = 0.0; - } - bool m_bBump; - bool m_bLightmappedGeneric; - bool m_bWorldVertexTransition; - bool m_bTeeth; - int m_nBumpmapVar; - int m_nBumpmapFrame; - int m_nBumpTransform; - int m_nFlashlightTextureVar; - int m_nFlashlightTextureFrameVar; - int m_nBaseTexture2Var; - int m_nBaseTexture2FrameVar; - int m_nBumpmap2Var; - int m_nBumpmap2Frame; - int m_nBump2Transform; - int m_nDetailVar; - int m_nDetailScale; - int m_nDetailTextureCombineMode; - int m_nDetailTextureBlendFactor; - int m_nDetailTint; - int m_nTeethForwardVar; - int m_nTeethIllumFactorVar; - int m_nAlphaTestReference; - bool m_bSSBump; - float m_fSeamlessScale; // 0.0 = not seamless - }; - void DrawFlashlight_dx90( IMaterialVar** params, - IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, DrawFlashlight_dx90_Vars_t &vars ); -#endif // GAME_SHADER_DLL - - BlendType_t EvaluateBlendRequirements( int textureVar, bool isBaseTexture, int detailTextureVar = -1 ); - - void HashShadow2DJitter( const float fJitterSeed, float *fU, float* fV ); - - //Alpha tested materials can end up leaving garbage in the dest alpha buffer if they write depth. - //This pass fills in the areas that passed the alpha test with depth in dest alpha - //by writing only equal depth pixels and only if we should be writing depth to dest alpha - void DrawEqualDepthToDestAlpha( void ); - -private: - // Helper methods for VertexLitGenericPass -// void UnlitGenericShadowState( int baseTextureVar, int detailVar, int envmapVar, int envmapMaskVar, bool doSkin ); - void UnlitGenericDynamicState( int baseTextureVar, int frameVar, int baseTextureTransformVar, - int detailVar, int detailTransform, bool bDetailTransformIsScale, int envmapVar, - int envMapFrameVar, int envmapMaskVar, int envmapMaskFrameVar, - int envmapMaskScaleVar, int envmapTintVar ); - - // Converts a color + alpha into a vector4 - void ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color ); - -}; - -FORCEINLINE void SetFlashLightColorFromState( FlashlightState_t const &state, IShaderDynamicAPI *pShaderAPI, int nPSRegister=28, bool bFlashlightNoLambert=false ) -{ - // Old code - //float flToneMapScale = ( pShaderAPI->GetToneMappingScaleLinear() ).x; - //float flFlashlightScale = 1.0f / flToneMapScale; - - // Fix to old code to keep flashlight from ever getting brighter than 1.0 - //float flToneMapScale = ( pShaderAPI->GetToneMappingScaleLinear() ).x; - //if ( flToneMapScale < 1.0f ) - // flToneMapScale = 1.0f; - //float flFlashlightScale = 1.0f / flToneMapScale; - - // Force flashlight to 25% bright always - float flFlashlightScale = 0.25f; - - if ( !g_pHardwareConfig->GetHDREnabled() ) - { - // Non-HDR path requires 2.0 flashlight - flFlashlightScale = 2.0f; - } - - // DX10 requires some hackery due to sRGB/blend ordering change from DX9 - if ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) - { - flFlashlightScale *= 2.5f; // Magic number that works well on the NVIDIA 8800 - } - - // Generate pixel shader constant - float const *pFlashlightColor = state.m_Color; - float vPsConst[4] = { flFlashlightScale * pFlashlightColor[0], flFlashlightScale * pFlashlightColor[1], flFlashlightScale * pFlashlightColor[2], pFlashlightColor[3] }; - vPsConst[3] = bFlashlightNoLambert ? 2.0f : 0.0f; // This will be added to N.L before saturate to force a 1.0 N.L term - - // Red flashlight for testing - //vPsConst[0] = 0.5f; vPsConst[1] = 0.0f; vPsConst[2] = 0.0f; - - pShaderAPI->SetPixelShaderConstant( nPSRegister, ( float * )vPsConst ); -} - -FORCEINLINE float ShadowAttenFromState( FlashlightState_t const &state ) -{ - // DX10 requires some hackery due to sRGB/blend ordering change from DX9, which makes the shadows too light - if ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) - return state.m_flShadowAtten * 0.1f; // magic number - - return state.m_flShadowAtten; -} - -FORCEINLINE float ShadowFilterFromState( FlashlightState_t const &state ) -{ - // We developed shadow maps at 1024, so we expect the penumbra size to have been tuned relative to that - return state.m_flShadowFilterSize / 1024.0f; -} - - -// convenient material variable access functions for helpers to use. -FORCEINLINE bool IsTextureSet( int nVar, IMaterialVar **params ) -{ - return ( nVar != -1 ) && ( params[nVar]->IsTexture() ); -} - -FORCEINLINE bool IsBoolSet( int nVar, IMaterialVar **params ) -{ - return ( nVar != -1 ) && ( params[nVar]->GetIntValue() ); -} - -FORCEINLINE int GetIntParam( int nVar, IMaterialVar **params, int nDefaultValue = 0 ) -{ - return ( nVar != -1 ) ? ( params[nVar]->GetIntValue() ) : nDefaultValue; -} - -FORCEINLINE float GetFloatParam( int nVar, IMaterialVar **params, float flDefaultValue = 0.0 ) -{ - return ( nVar != -1 ) ? ( params[nVar]->GetFloatValue() ) : flDefaultValue; -} - -FORCEINLINE void InitFloatParam( int nIndex, IMaterialVar **params, float flValue ) -{ - if ( (nIndex != -1) && !params[nIndex]->IsDefined() ) - { - params[nIndex]->SetFloatValue( flValue ); - } -} - -FORCEINLINE void InitIntParam( int nIndex, IMaterialVar **params, int nValue ) -{ - if ( (nIndex != -1) && !params[nIndex]->IsDefined() ) - { - params[nIndex]->SetIntValue( nValue ); - } -} - - -class ConVar; - -#ifdef _DEBUG -extern ConVar mat_envmaptintoverride; -extern ConVar mat_envmaptintscale; -#endif - - -#endif // BASEVSSHADER_H +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// This is what all vs/ps (dx8+) shaders inherit from. +//===========================================================================// + +#ifndef BASEVSSHADER_H +#define BASEVSSHADER_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "shaderlib/cshader.h" +#include "shaderlib/BaseShader.h" +#include "convar.h" +#include + +#ifdef _X360 +#define SUPPORT_DX8 0 +#define SUPPORT_DX7 0 +#else +#define SUPPORT_DX8 1 +#define SUPPORT_DX7 1 +#endif +//----------------------------------------------------------------------------- +// Helper macro for vertex shaders +//----------------------------------------------------------------------------- +#define BEGIN_VS_SHADER_FLAGS(_name, _help, _flags) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, _flags ) +#define BEGIN_VS_SHADER(_name,_help) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, 0 ) + + +// useful parameter initialization macro +#define INIT_FLOAT_PARM( parm, value ) \ + if ( !params[(parm)]->IsDefined() ) \ + { \ + params[(parm)]->SetFloatValue( (value) ); \ + } + +// useful pixel shader declaration macro for ps20/20b c++ code +#define SET_STATIC_PS2X_PIXEL_SHADER_NO_COMBOS( basename ) \ + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) \ + { \ + DECLARE_STATIC_PIXEL_SHADER( basename##_ps20b ); \ + SET_STATIC_PIXEL_SHADER( basename##_ps20b ); \ + } \ + else \ + { \ + DECLARE_STATIC_PIXEL_SHADER( basename##_ps20 ); \ + SET_STATIC_PIXEL_SHADER( basename##_ps20 ); \ + } + +#define SET_DYNAMIC_PS2X_PIXEL_SHADER_NO_COMBOS( basename ) \ + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) \ + { \ + DECLARE_DYNAMIC_PIXEL_SHADER( basename##_ps20b ); \ + SET_DYNAMIC_PIXEL_SHADER( basename##_ps20b ); \ + } \ + else \ + { \ + DECLARE_DYNAMIC_PIXEL_SHADER( basename##_ps20 ); \ + SET_DYNAMIC_PIXEL_SHADER( basename##_ps20 ); \ + } + + +//----------------------------------------------------------------------------- +// Base class for shaders, contains helper methods. +//----------------------------------------------------------------------------- +class CBaseVSShader : public CBaseShader +{ +public: + + // Loads bump lightmap coordinates into the pixel shader + void LoadBumpLightmapCoordinateAxes_PixelShader( int pixelReg ); + + // Loads bump lightmap coordinates into the vertex shader + void LoadBumpLightmapCoordinateAxes_VertexShader( int vertexReg ); + + // Pixel and vertex shader constants.... + void SetPixelShaderConstant( int pixelReg, int constantVar ); + + // Pixel and vertex shader constants.... + void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar ); + + // This version will put constantVar into x,y,z, and constantVar2 into the w + void SetPixelShaderConstant( int pixelReg, int constantVar, int constantVar2 ); + void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar, int constantVar2 ); + + // Helpers for setting constants that need to be converted to linear space (from gamma space). + void SetVertexShaderConstantGammaToLinear( int var, float const* pVec, int numConst = 1, bool bForce = false ); + void SetPixelShaderConstantGammaToLinear( int var, float const* pVec, int numConst = 1, bool bForce = false ); + + void SetVertexShaderConstant( int vertexReg, int constantVar ); + + // set rgb components of constant from a color parm and give an explicit w value + void SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue ); + + // GR - fix for const/lerp issues + void SetPixelShaderConstantFudge( int pixelReg, int constantVar ); + + // Sets light direction for pixel shaders. + void SetPixelShaderLightColors( int pixelReg ); + + // Sets vertex shader texture transforms + void SetVertexShaderTextureTranslation( int vertexReg, int translationVar ); + void SetVertexShaderTextureScale( int vertexReg, int scaleVar ); + void SetVertexShaderTextureTransform( int vertexReg, int transformVar ); + void SetVertexShaderTextureScaledTransform( int vertexReg, + int transformVar, int scaleVar ); + + // Set pixel shader texture transforms + void SetPixelShaderTextureTranslation( int pixelReg, int translationVar ); + void SetPixelShaderTextureScale( int pixelReg, int scaleVar ); + void SetPixelShaderTextureTransform( int pixelReg, int transformVar ); + void SetPixelShaderTextureScaledTransform( int pixelReg, + int transformVar, int scaleVar ); + + // Moves a matrix into vertex shader constants + void SetVertexShaderMatrix3x4( int vertexReg, int matrixVar ); + void SetVertexShaderMatrix4x4( int vertexReg, int matrixVar ); + + // Loads the view matrix into vertex shader constants + void LoadViewMatrixIntoVertexShaderConstant( int vertexReg ); + + // Loads the projection matrix into vertex shader constants + void LoadProjectionMatrixIntoVertexShaderConstant( int vertexReg ); + + // Loads the model->view matrix into vertex shader constants + void LoadModelViewMatrixIntoVertexShaderConstant( int vertexReg ); + + // Loads a scale/offset version of the viewport transform into the specified constant. + void LoadViewportTransformScaledIntoVertexShaderConstant( int vertexReg ); + + // Sets up ambient light cube... + void SetAmbientCubeDynamicStateVertexShader( ); + float GetAmbientLightCubeLuminance( ); + + // Helpers for dealing with envmaptint + void SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear = false ); + + // Helper methods for pixel shader overbrighting + void EnablePixelShaderOverbright( int reg, bool bEnable, bool bDivideByTwo ); + + // Helper for dealing with modulation + void SetModulationVertexShaderDynamicState(); + void SetModulationPixelShaderDynamicState( int modulationVar ); + void SetModulationPixelShaderDynamicState_LinearColorSpace( int modulationVar ); + void SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( int modulationVar, float flScale ); + + // Sets a color + alpha into shader constants + void SetColorVertexShaderConstant( int nVertexReg, int colorVar, int alphaVar ); + void SetColorPixelShaderConstant( int nPixelReg, int colorVar, int alphaVar ); + + +#ifndef GAME_SHADER_DLL + // + // Standard shader passes! + // + + void InitParamsUnlitGeneric_DX8( + int baseTextureVar, + int detailScaleVar, + int envmapOptionalVar, + int envmapVar, + int envmapTintVar, + int envmapMaskScaleVar, + int nDetailBlendMode ); + + void InitUnlitGeneric_DX8( + int baseTextureVar, + int detailVar, + int envmapVar, + int envmapMaskVar ); + + // Dx8 Unlit Generic pass + void VertexShaderUnlitGenericPass( int baseTextureVar, int frameVar, + int baseTextureTransformVar, + int detailVar, int detailTransform, bool bDetailTransformIsScale, + int envmapVar, int envMapFrameVar, int envmapMaskVar, + int envmapMaskFrameVar, int envmapMaskScaleVar, int envmapTintVar, + int alphaTestReferenceVar, + int nDetailBlendModeVar, + int nOutlineVar, + int nOutlineColorVar, + int nOutlineStartVar, + int nOutlineEndVar, + int nSeparateDetailUVsVar + ); + + // Helpers for drawing world bump mapped stuff. + void DrawModelBumpedSpecularLighting( int bumpMapVar, int bumpMapFrameVar, + int envMapVar, int envMapVarFrame, + int envMapTintVar, int alphaVar, + int envMapContrastVar, int envMapSaturationVar, + int bumpTransformVar, + bool bBlendSpecular, bool bNoWriteZ = false ); + void DrawWorldBumpedSpecularLighting( int bumpmapVar, int envmapVar, + int bumpFrameVar, int envmapFrameVar, + int envmapTintVar, int alphaVar, + int envmapContrastVar, int envmapSaturationVar, + int bumpTransformVar, int fresnelReflectionVar, + bool bBlend, bool bNoWriteZ = false ); + + const char *UnlitGeneric_ComputeVertexShaderName( bool bMask, + bool bEnvmap, + bool bBaseTexture, + bool bBaseAlphaEnvmapMask, + bool bDetail, + bool bVertexColor, + bool bEnvmapCameraSpace, + bool bEnvmapSphere ); + + const char *UnlitGeneric_ComputePixelShaderName( bool bMask, + bool bEnvmap, + bool bBaseTexture, + bool bBaseAlphaEnvmapMask, + bool bDetail, + bool bMultiplyDetail, + bool bMaskBaseByDetailAlpha ); + + void DrawWorldBaseTexture( int baseTextureVar, int baseTextureTransformVar, int frameVar, int colorVar, int alphaVar ); + void DrawWorldBumpedDiffuseLighting( int bumpmapVar, int bumpFrameVar, + int bumpTransformVar, bool bMultiply, bool bSSBump ); + void DrawWorldBumpedSpecularLighting( int envmapMaskVar, int envmapMaskFrame, + int bumpmapVar, int envmapVar, + int bumpFrameVar, int envmapFrameVar, + int envmapTintVar, int alphaVar, + int envmapContrastVar, int envmapSaturationVar, + int bumpTransformVar, int fresnelReflectionVar, + bool bBlend ); + void DrawBaseTextureBlend( int baseTextureVar, int baseTextureTransformVar, + int baseTextureFrameVar, + int baseTexture2Var, int baseTextureTransform2Var, + int baseTextureFrame2Var, int colorVar, int alphaVar ); + void DrawWorldBumpedDiffuseLighting_Base_ps14( int bumpmapVar, int bumpFrameVar, + int bumpTransformVar, int baseTextureVar, int baseTextureTransformVar, int frameVar ); + void DrawWorldBumpedDiffuseLighting_Blend_ps14( int bumpmapVar, int bumpFrameVar, int bumpTransformVar, + int baseTextureVar, int baseTextureTransformVar, int baseTextureFrameVar, + int baseTexture2Var, int baseTextureTransform2Var, int baseTextureFrame2Var); + void DrawWorldBumpedUsingVertexShader( int baseTextureVar, int baseTextureTransformVar, + int bumpmapVar, int bumpFrameVar, + int bumpTransformVar, + int envmapMaskVar, int envmapMaskFrame, + int envmapVar, + int envmapFrameVar, + int envmapTintVar, int colorVar, int alphaVar, + int envmapContrastVar, int envmapSaturationVar, int frameVar, int fresnelReflectionVar, + bool doBaseTexture2, + int baseTexture2Var, + int baseTextureTransform2Var, + int baseTextureFrame2Var, + bool bSSBump + ); + + // Sets up hw morphing state for the vertex shader + void SetHWMorphVertexShaderState( int nDimConst, int nSubrectConst, VertexTextureSampler_t morphSampler ); + + // Computes the shader index for vertex lit materials + int ComputeVertexLitShaderIndex( bool bVertexLitGeneric, bool hasBump, bool hasEnvmap, bool hasVertexColor, bool bHasNormal ) const; + + // Helper for setting up flashlight constants + void SetFlashlightVertexShaderConstants( bool bBump, int bumpTransformVar, bool bDetail, int detailScaleVar, bool bSetTextureTransforms ); + +#if SUPPORT_DX8 + void DrawFlashlight_dx80( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + bool bBump, int bumpmapVar, int bumpmapFrame, int bumpTransform, int flashlightTextureVar, + int flashlightTextureFrameVar, bool bLightmappedGeneric, bool bWorldVertexTransition, + int nWorldVertexTransitionPassID, int baseTexture2Var, int baseTexture2FrameVar, + bool bTeeth=false, int nTeethForwardVar=0, int nTeethIllumFactorVar=0 ); +#endif + + struct DrawFlashlight_dx90_Vars_t + { + DrawFlashlight_dx90_Vars_t() + { + // set all ints to -1 + memset( this, 0xFF, sizeof(DrawFlashlight_dx90_Vars_t) ); + // set all bools to a default value. + m_bBump = false; + m_bLightmappedGeneric = false; + m_bWorldVertexTransition = false; + m_bTeeth = false; + m_bSSBump = false; + m_fSeamlessScale = 0.0; + } + bool m_bBump; + bool m_bLightmappedGeneric; + bool m_bWorldVertexTransition; + bool m_bTeeth; + int m_nBumpmapVar; + int m_nBumpmapFrame; + int m_nBumpTransform; + int m_nFlashlightTextureVar; + int m_nFlashlightTextureFrameVar; + int m_nBaseTexture2Var; + int m_nBaseTexture2FrameVar; + int m_nBumpmap2Var; + int m_nBumpmap2Frame; + int m_nBump2Transform; + int m_nDetailVar; + int m_nDetailScale; + int m_nDetailTextureCombineMode; + int m_nDetailTextureBlendFactor; + int m_nDetailTint; + int m_nTeethForwardVar; + int m_nTeethIllumFactorVar; + int m_nAlphaTestReference; + bool m_bSSBump; + float m_fSeamlessScale; // 0.0 = not seamless + }; + void DrawFlashlight_dx90( IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, DrawFlashlight_dx90_Vars_t &vars ); +#endif // GAME_SHADER_DLL + + BlendType_t EvaluateBlendRequirements( int textureVar, bool isBaseTexture, int detailTextureVar = -1 ); + + void HashShadow2DJitter( const float fJitterSeed, float *fU, float* fV ); + + //Alpha tested materials can end up leaving garbage in the dest alpha buffer if they write depth. + //This pass fills in the areas that passed the alpha test with depth in dest alpha + //by writing only equal depth pixels and only if we should be writing depth to dest alpha + void DrawEqualDepthToDestAlpha( void ); + +private: + // Helper methods for VertexLitGenericPass +// void UnlitGenericShadowState( int baseTextureVar, int detailVar, int envmapVar, int envmapMaskVar, bool doSkin ); + void UnlitGenericDynamicState( int baseTextureVar, int frameVar, int baseTextureTransformVar, + int detailVar, int detailTransform, bool bDetailTransformIsScale, int envmapVar, + int envMapFrameVar, int envmapMaskVar, int envmapMaskFrameVar, + int envmapMaskScaleVar, int envmapTintVar ); + + // Converts a color + alpha into a vector4 + void ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color ); + +}; + +FORCEINLINE void SetFlashLightColorFromState( FlashlightState_t const &state, IShaderDynamicAPI *pShaderAPI, int nPSRegister=28, bool bFlashlightNoLambert=false ) +{ + // Old code + //float flToneMapScale = ( pShaderAPI->GetToneMappingScaleLinear() ).x; + //float flFlashlightScale = 1.0f / flToneMapScale; + + // Fix to old code to keep flashlight from ever getting brighter than 1.0 + //float flToneMapScale = ( pShaderAPI->GetToneMappingScaleLinear() ).x; + //if ( flToneMapScale < 1.0f ) + // flToneMapScale = 1.0f; + //float flFlashlightScale = 1.0f / flToneMapScale; + + // Force flashlight to 25% bright always + float flFlashlightScale = 0.25f; + + if ( !g_pHardwareConfig->GetHDREnabled() ) + { + // Non-HDR path requires 2.0 flashlight + flFlashlightScale = 2.0f; + } + + // DX10 requires some hackery due to sRGB/blend ordering change from DX9 + if ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) + { + flFlashlightScale *= 2.5f; // Magic number that works well on the NVIDIA 8800 + } + + // Generate pixel shader constant + float const *pFlashlightColor = state.m_Color; + float vPsConst[4] = { flFlashlightScale * pFlashlightColor[0], flFlashlightScale * pFlashlightColor[1], flFlashlightScale * pFlashlightColor[2], pFlashlightColor[3] }; + vPsConst[3] = bFlashlightNoLambert ? 2.0f : 0.0f; // This will be added to N.L before saturate to force a 1.0 N.L term + + // Red flashlight for testing + //vPsConst[0] = 0.5f; vPsConst[1] = 0.0f; vPsConst[2] = 0.0f; + + pShaderAPI->SetPixelShaderConstant( nPSRegister, ( float * )vPsConst ); +} + +FORCEINLINE float ShadowAttenFromState( FlashlightState_t const &state ) +{ + // DX10 requires some hackery due to sRGB/blend ordering change from DX9, which makes the shadows too light + if ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) + return state.m_flShadowAtten * 0.1f; // magic number + + return state.m_flShadowAtten; +} + +FORCEINLINE float ShadowFilterFromState( FlashlightState_t const &state ) +{ + // We developed shadow maps at 1024, so we expect the penumbra size to have been tuned relative to that + return state.m_flShadowFilterSize / 1024.0f; +} + + +// convenient material variable access functions for helpers to use. +FORCEINLINE bool IsTextureSet( int nVar, IMaterialVar **params ) +{ + return ( nVar != -1 ) && ( params[nVar]->IsTexture() ); +} + +FORCEINLINE bool IsBoolSet( int nVar, IMaterialVar **params ) +{ + return ( nVar != -1 ) && ( params[nVar]->GetIntValue() ); +} + +FORCEINLINE int GetIntParam( int nVar, IMaterialVar **params, int nDefaultValue = 0 ) +{ + return ( nVar != -1 ) ? ( params[nVar]->GetIntValue() ) : nDefaultValue; +} + +FORCEINLINE float GetFloatParam( int nVar, IMaterialVar **params, float flDefaultValue = 0.0 ) +{ + return ( nVar != -1 ) ? ( params[nVar]->GetFloatValue() ) : flDefaultValue; +} + +FORCEINLINE void InitFloatParam( int nIndex, IMaterialVar **params, float flValue ) +{ + if ( (nIndex != -1) && !params[nIndex]->IsDefined() ) + { + params[nIndex]->SetFloatValue( flValue ); + } +} + +FORCEINLINE void InitIntParam( int nIndex, IMaterialVar **params, int nValue ) +{ + if ( (nIndex != -1) && !params[nIndex]->IsDefined() ) + { + params[nIndex]->SetIntValue( nValue ); + } +} + + +class ConVar; + +#ifdef _DEBUG +extern ConVar mat_envmaptintoverride; +extern ConVar mat_envmaptintscale; +#endif + + +#endif // BASEVSSHADER_H diff --git a/mp/src/materialsystem/stdshaders/Bloom.cpp b/mp/src/materialsystem/stdshaders/Bloom.cpp index 620a6edb..c2635fbe 100644 --- a/mp/src/materialsystem/stdshaders/Bloom.cpp +++ b/mp/src/materialsystem/stdshaders/Bloom.cpp @@ -1,90 +1,90 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// -// -// Purpose: -// -// $NoKeywords: $ -//===========================================================================// - -#include "BaseVSShader.h" - -#include "SDK_screenspaceeffect_vs20.inc" -#include "SDK_Bloom_ps20.inc" -#include "SDK_Bloom_ps20b.inc" - -BEGIN_VS_SHADER_FLAGS( SDK_Bloom, "Help for Bloom", SHADER_NOT_EDITABLE ) - BEGIN_SHADER_PARAMS - SHADER_PARAM( FBTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_FullFrameFB", "" ) - SHADER_PARAM( BLURTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallHDR0", "" ) - END_SHADER_PARAMS - - SHADER_INIT - { - if( params[FBTEXTURE]->IsDefined() ) - { - LoadTexture( FBTEXTURE ); - } - if( params[BLURTEXTURE]->IsDefined() ) - { - LoadTexture( BLURTEXTURE ); - } - } - - SHADER_FALLBACK - { - // Requires DX9 + above - if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { - Assert( 0 ); - return "Wireframe"; - } - return 0; - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - int fmt = VERTEX_POSITION; - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); - - // Pre-cache shaders - DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); - SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_STATIC_PIXEL_SHADER( sdk_bloom_ps20b ); - SET_STATIC_PIXEL_SHADER( sdk_bloom_ps20b ); - } - else - { - DECLARE_STATIC_PIXEL_SHADER( sdk_bloom_ps20 ); - SET_STATIC_PIXEL_SHADER( sdk_bloom_ps20 ); - } - } - - DYNAMIC_STATE - { - BindTexture( SHADER_SAMPLER0, FBTEXTURE, -1 ); - BindTexture( SHADER_SAMPLER1, BLURTEXTURE, -1 ); - DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); - SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - DECLARE_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps20b ); - SET_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps20b ); - } - else - { - DECLARE_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps20 ); - SET_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps20 ); - } - } - Draw(); - } -END_SHADER +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" + +#include "SDK_screenspaceeffect_vs20.inc" +#include "SDK_Bloom_ps20.inc" +#include "SDK_Bloom_ps20b.inc" + +BEGIN_VS_SHADER_FLAGS( SDK_Bloom, "Help for Bloom", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( FBTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_FullFrameFB", "" ) + SHADER_PARAM( BLURTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallHDR0", "" ) + END_SHADER_PARAMS + + SHADER_INIT + { + if( params[FBTEXTURE]->IsDefined() ) + { + LoadTexture( FBTEXTURE ); + } + if( params[BLURTEXTURE]->IsDefined() ) + { + LoadTexture( BLURTEXTURE ); + } + } + + SHADER_FALLBACK + { + // Requires DX9 + above + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + Assert( 0 ); + return "Wireframe"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + // Pre-cache shaders + DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sdk_bloom_ps20b ); + SET_STATIC_PIXEL_SHADER( sdk_bloom_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sdk_bloom_ps20 ); + SET_STATIC_PIXEL_SHADER( sdk_bloom_ps20 ); + } + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, FBTEXTURE, -1 ); + BindTexture( SHADER_SAMPLER1, BLURTEXTURE, -1 ); + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( sdk_bloom_ps20 ); + } + } + Draw(); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/commandbuilder.h b/mp/src/materialsystem/stdshaders/commandbuilder.h index 13a68ede..278f2dce 100644 --- a/mp/src/materialsystem/stdshaders/commandbuilder.h +++ b/mp/src/materialsystem/stdshaders/commandbuilder.h @@ -1,407 +1,407 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// Utility class for building command buffers into memory -//===========================================================================// - -#ifndef COMMANDBUILDER_H -#define COMMANDBUILDER_H - -#ifndef COMMANDBUFFER_H -#include "shaderapi/commandbuffer.h" -#endif - -#include "BaseVSShader.h" -#include "shaderapi/ishaderapi.h" - -#ifdef _WIN32 -#pragma once -#endif - -extern ConVar my_mat_fullbright; - -template class CFixedCommandStorageBuffer -{ -public: - uint8 m_Data[N]; - - uint8 *m_pDataOut; -#ifdef DBGFLAG_ASSERT - size_t m_nNumBytesRemaining; -#endif - - FORCEINLINE CFixedCommandStorageBuffer( void ) - { - m_pDataOut = m_Data; -#ifdef DBGFLAG_ASSERT - m_nNumBytesRemaining = N; -#endif - - } - - FORCEINLINE void EnsureCapacity( size_t sz ) - { - Assert( m_nNumBytesRemaining >= sz ); - } - - template FORCEINLINE void Put( T const &nValue ) - { - EnsureCapacity( sizeof( T ) ); - *( reinterpret_cast( m_pDataOut ) ) = nValue; - m_pDataOut += sizeof( nValue ); -#ifdef DBGFLAG_ASSERT - m_nNumBytesRemaining -= sizeof( nValue ); -#endif - } - - FORCEINLINE void PutInt( int nValue ) - { - Put( nValue ); - } - - FORCEINLINE void PutFloat( float nValue ) - { - Put( nValue ); - } - - FORCEINLINE void PutPtr( void * pPtr ) - { - Put( pPtr ); - } - - FORCEINLINE void PutMemory( const void *pMemory, size_t nBytes ) - { - EnsureCapacity( nBytes ); - memcpy( m_pDataOut, pMemory, nBytes ); - m_pDataOut += nBytes; - } - - FORCEINLINE uint8 *Base( void ) - { - return m_Data; - } - - FORCEINLINE void Reset( void ) - { - m_pDataOut = m_Data; -#ifdef DBGFLAG_ASSERT - m_nNumBytesRemaining = N; -#endif - } - - FORCEINLINE size_t Size( void ) const - { - return m_pDataOut - m_Data; - } - -}; - -template class CCommandBufferBuilder -{ -public: - S m_Storage; - - FORCEINLINE void End( void ) - { - m_Storage.PutInt( CBCMD_END ); - } - - - FORCEINLINE IMaterialVar *Param( int nVar ) const - { - return CBaseShader::s_ppParams[nVar]; - } - - FORCEINLINE void SetPixelShaderConstants( int nFirstConstant, int nConstants ) - { - m_Storage.PutInt( CBCMD_SET_PIXEL_SHADER_FLOAT_CONST ); - m_Storage.PutInt( nFirstConstant ); - m_Storage.PutInt( nConstants ); - } - - FORCEINLINE void OutputConstantData( float const *pSrcData ) - { - m_Storage.PutFloat( pSrcData[0] ); - m_Storage.PutFloat( pSrcData[1] ); - m_Storage.PutFloat( pSrcData[2] ); - m_Storage.PutFloat( pSrcData[3] ); - } - - FORCEINLINE void OutputConstantData4( float flVal0, float flVal1, float flVal2, float flVal3 ) - { - m_Storage.PutFloat( flVal0 ); - m_Storage.PutFloat( flVal1 ); - m_Storage.PutFloat( flVal2 ); - m_Storage.PutFloat( flVal3 ); - } - - FORCEINLINE void SetPixelShaderConstant( int nFirstConstant, float const *pSrcData, int nNumConstantsToSet ) - { - SetPixelShaderConstants( nFirstConstant, nNumConstantsToSet ); - m_Storage.PutMemory( pSrcData, 4 * sizeof( float ) * nNumConstantsToSet ); - } - - FORCEINLINE void SetPixelShaderConstant( int nFirstConstant, int nVar ) - { - SetPixelShaderConstant( nFirstConstant, Param( nVar )->GetVecValue() ); - } - - void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar ) - { - float val[4]; - Param(constantVar)->GetVecValue( val, 3 ); - val[0] = val[0] > 1.0f ? val[0] : GammaToLinear( val[0] ); - val[1] = val[1] > 1.0f ? val[1] : GammaToLinear( val[1] ); - val[2] = val[2] > 1.0f ? val[2] : GammaToLinear( val[2] ); - val[3] = 1.0; - SetPixelShaderConstant( pixelReg, val ); - } - - FORCEINLINE void SetPixelShaderConstant( int nFirstConstant, float const *pSrcData ) - { - SetPixelShaderConstants( nFirstConstant, 1 ); - OutputConstantData( pSrcData ); - } - - FORCEINLINE void SetPixelShaderConstant4( int nFirstConstant, float flVal0, float flVal1, float flVal2, float flVal3 ) - { - SetPixelShaderConstants( nFirstConstant, 1 ); - OutputConstantData4( flVal0, flVal1, flVal2, flVal3 ); - } - - FORCEINLINE void SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue ) - { - if ( constantVar != -1 ) - { - float val[3]; - Param(constantVar)->GetVecValue( val, 3); - SetPixelShaderConstant4( pixelReg, val[0], val[1], val[2], fWValue ); - } - } - - FORCEINLINE void SetVertexShaderConstant( int nFirstConstant, float const *pSrcData ) - { - m_Storage.PutInt( CBCMD_SET_VERTEX_SHADER_FLOAT_CONST ); - m_Storage.PutInt( nFirstConstant ); - m_Storage.PutInt( 1 ); - OutputConstantData( pSrcData ); - } - - FORCEINLINE void SetVertexShaderConstant( int nFirstConstant, float const *pSrcData, int nConsts ) - { - m_Storage.PutInt( CBCMD_SET_VERTEX_SHADER_FLOAT_CONST ); - m_Storage.PutInt( nFirstConstant ); - m_Storage.PutInt( nConsts ); - m_Storage.PutMemory( pSrcData, 4 * nConsts * sizeof( float ) ); - } - - - FORCEINLINE void SetVertexShaderConstant4( int nFirstConstant, float flVal0, float flVal1, float flVal2, float flVal3 ) - { - m_Storage.PutInt( CBCMD_SET_VERTEX_SHADER_FLOAT_CONST ); - m_Storage.PutInt( nFirstConstant ); - m_Storage.PutInt( 1 ); - m_Storage.PutFloat( flVal0 ); - m_Storage.PutFloat( flVal1 ); - m_Storage.PutFloat( flVal2 ); - m_Storage.PutFloat( flVal3 ); - } - - void SetVertexShaderTextureTransform( int vertexReg, int transformVar ) - { - Vector4D transformation[2]; - IMaterialVar* pTransformationVar = Param( transformVar ); - if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) - { - const VMatrix &mat = pTransformationVar->GetMatrixValue(); - transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); - transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); - } - else - { - transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); - transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); - } - SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 ); - } - - - void SetVertexShaderTextureScaledTransform( int vertexReg, int transformVar, int scaleVar ) - { - Vector4D transformation[2]; - IMaterialVar* pTransformationVar = Param( transformVar ); - if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) - { - const VMatrix &mat = pTransformationVar->GetMatrixValue(); - transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); - transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); - } - else - { - transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); - transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); - } - - Vector2D scale( 1, 1 ); - IMaterialVar* pScaleVar = Param( scaleVar ); - if (pScaleVar) - { - if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) - pScaleVar->GetVecValue( scale.Base(), 2 ); - else if (pScaleVar->IsDefined()) - scale[0] = scale[1] = pScaleVar->GetFloatValue(); - } - - // Apply the scaling - transformation[0][0] *= scale[0]; - transformation[0][1] *= scale[1]; - transformation[1][0] *= scale[0]; - transformation[1][1] *= scale[1]; - transformation[0][3] *= scale[0]; - transformation[1][3] *= scale[1]; - SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 ); - } - - FORCEINLINE void SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar ) - { - if( g_pConfig->bShowSpecular && my_mat_fullbright.GetInt() != 2 ) - { - SetPixelShaderConstant( pixelReg, Param( tintVar)->GetVecValue() ); - } - else - { - SetPixelShaderConstant4( pixelReg, 0.0, 0.0, 0.0, 0.0 ); - } - } - - FORCEINLINE void SetEnvMapTintPixelShaderDynamicStateGammaToLinear( int pixelReg, int tintVar, float flAlphaValue = 1.0 ) - { - if( ( tintVar != -1 ) && g_pConfig->bShowSpecular && my_mat_fullbright.GetInt() != 2 ) - { - float color[4]; - color[3] = flAlphaValue; - Param( tintVar)->GetLinearVecValue( color, 3 ); - SetPixelShaderConstant( pixelReg, color ); - } - else - { - SetPixelShaderConstant4( pixelReg, 0.0, 0.0, 0.0, flAlphaValue ); - } - } - - FORCEINLINE void StoreEyePosInPixelShaderConstant( int nConst ) - { - m_Storage.PutInt( CBCMD_STORE_EYE_POS_IN_PSCONST ); - m_Storage.PutInt( nConst ); - } - - FORCEINLINE void CommitPixelShaderLighting( int nConst ) - { - m_Storage.PutInt( CBCMD_COMMITPIXELSHADERLIGHTING ); - m_Storage.PutInt( nConst ); - } - - FORCEINLINE void SetPixelShaderStateAmbientLightCube( int nConst ) - { - m_Storage.PutInt( CBCMD_SETPIXELSHADERSTATEAMBIENTLIGHTCUBE ); - m_Storage.PutInt( nConst ); - } - - FORCEINLINE void SetAmbientCubeDynamicStateVertexShader( void ) - { - m_Storage.PutInt( CBCMD_SETAMBIENTCUBEDYNAMICSTATEVERTEXSHADER ); - } - - FORCEINLINE void SetPixelShaderFogParams( int nReg ) - { - m_Storage.PutInt( CBCMD_SETPIXELSHADERFOGPARAMS ); - m_Storage.PutInt( nReg ); - } - - FORCEINLINE void BindStandardTexture( Sampler_t nSampler, StandardTextureId_t nTextureId ) - { - m_Storage.PutInt( CBCMD_BIND_STANDARD_TEXTURE ); - m_Storage.PutInt( nSampler ); - m_Storage.PutInt( nTextureId ); - } - - - FORCEINLINE void BindTexture( Sampler_t nSampler, ShaderAPITextureHandle_t hTexture ) - { - Assert( hTexture != INVALID_SHADERAPI_TEXTURE_HANDLE ); - if ( hTexture != INVALID_SHADERAPI_TEXTURE_HANDLE ) - { - m_Storage.PutInt( CBCMD_BIND_SHADERAPI_TEXTURE_HANDLE ); - m_Storage.PutInt( nSampler ); - m_Storage.PutInt( hTexture ); - } - } - - FORCEINLINE void BindTexture( CBaseVSShader *pShader, Sampler_t nSampler, int nTextureVar, int nFrameVar ) - { - ShaderAPITextureHandle_t hTexture = pShader->GetShaderAPITextureBindHandle( nTextureVar, nFrameVar ); - BindTexture( nSampler, hTexture ); - } - - FORCEINLINE void BindMultiTexture( CBaseVSShader *pShader, Sampler_t nSampler1, Sampler_t nSampler2, int nTextureVar, int nFrameVar ) - { - ShaderAPITextureHandle_t hTexture = pShader->GetShaderAPITextureBindHandle( nTextureVar, nFrameVar, 0 ); - BindTexture( nSampler1, hTexture ); - hTexture = pShader->GetShaderAPITextureBindHandle( nTextureVar, nFrameVar, 1 ); - BindTexture( nSampler2, hTexture ); - } - - FORCEINLINE void SetPixelShaderIndex( int nIndex ) - { - m_Storage.PutInt( CBCMD_SET_PSHINDEX ); - m_Storage.PutInt( nIndex ); - } - - FORCEINLINE void SetVertexShaderIndex( int nIndex ) - { - m_Storage.PutInt( CBCMD_SET_VSHINDEX ); - m_Storage.PutInt( nIndex ); - } - - FORCEINLINE void SetDepthFeatheringPixelShaderConstant( int iConstant, float fDepthBlendScale ) - { - m_Storage.PutInt( CBCMD_SET_DEPTH_FEATHERING_CONST ); - m_Storage.PutInt( iConstant ); - m_Storage.PutFloat( fDepthBlendScale ); - } - - FORCEINLINE void Goto( uint8 *pCmdBuf ) - { - m_Storage.PutInt( CBCMD_JUMP ); - m_Storage.PutPtr( pCmdBuf ); - } - - FORCEINLINE void Call( uint8 *pCmdBuf ) - { - m_Storage.PutInt( CBCMD_JSR ); - m_Storage.PutPtr( pCmdBuf ); - } - - FORCEINLINE void Reset( void ) - { - m_Storage.Reset(); - } - - FORCEINLINE size_t Size( void ) const - { - return m_Storage.Size(); - } - - FORCEINLINE uint8 *Base( void ) - { - return m_Storage.Base(); - } - - - -}; - - -#endif // commandbuilder_h +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// Utility class for building command buffers into memory +//===========================================================================// + +#ifndef COMMANDBUILDER_H +#define COMMANDBUILDER_H + +#ifndef COMMANDBUFFER_H +#include "shaderapi/commandbuffer.h" +#endif + +#include "BaseVSShader.h" +#include "shaderapi/ishaderapi.h" + +#ifdef _WIN32 +#pragma once +#endif + +extern ConVar my_mat_fullbright; + +template class CFixedCommandStorageBuffer +{ +public: + uint8 m_Data[N]; + + uint8 *m_pDataOut; +#ifdef DBGFLAG_ASSERT + size_t m_nNumBytesRemaining; +#endif + + FORCEINLINE CFixedCommandStorageBuffer( void ) + { + m_pDataOut = m_Data; +#ifdef DBGFLAG_ASSERT + m_nNumBytesRemaining = N; +#endif + + } + + FORCEINLINE void EnsureCapacity( size_t sz ) + { + Assert( m_nNumBytesRemaining >= sz ); + } + + template FORCEINLINE void Put( T const &nValue ) + { + EnsureCapacity( sizeof( T ) ); + *( reinterpret_cast( m_pDataOut ) ) = nValue; + m_pDataOut += sizeof( nValue ); +#ifdef DBGFLAG_ASSERT + m_nNumBytesRemaining -= sizeof( nValue ); +#endif + } + + FORCEINLINE void PutInt( int nValue ) + { + Put( nValue ); + } + + FORCEINLINE void PutFloat( float nValue ) + { + Put( nValue ); + } + + FORCEINLINE void PutPtr( void * pPtr ) + { + Put( pPtr ); + } + + FORCEINLINE void PutMemory( const void *pMemory, size_t nBytes ) + { + EnsureCapacity( nBytes ); + memcpy( m_pDataOut, pMemory, nBytes ); + m_pDataOut += nBytes; + } + + FORCEINLINE uint8 *Base( void ) + { + return m_Data; + } + + FORCEINLINE void Reset( void ) + { + m_pDataOut = m_Data; +#ifdef DBGFLAG_ASSERT + m_nNumBytesRemaining = N; +#endif + } + + FORCEINLINE size_t Size( void ) const + { + return m_pDataOut - m_Data; + } + +}; + +template class CCommandBufferBuilder +{ +public: + S m_Storage; + + FORCEINLINE void End( void ) + { + m_Storage.PutInt( CBCMD_END ); + } + + + FORCEINLINE IMaterialVar *Param( int nVar ) const + { + return CBaseShader::s_ppParams[nVar]; + } + + FORCEINLINE void SetPixelShaderConstants( int nFirstConstant, int nConstants ) + { + m_Storage.PutInt( CBCMD_SET_PIXEL_SHADER_FLOAT_CONST ); + m_Storage.PutInt( nFirstConstant ); + m_Storage.PutInt( nConstants ); + } + + FORCEINLINE void OutputConstantData( float const *pSrcData ) + { + m_Storage.PutFloat( pSrcData[0] ); + m_Storage.PutFloat( pSrcData[1] ); + m_Storage.PutFloat( pSrcData[2] ); + m_Storage.PutFloat( pSrcData[3] ); + } + + FORCEINLINE void OutputConstantData4( float flVal0, float flVal1, float flVal2, float flVal3 ) + { + m_Storage.PutFloat( flVal0 ); + m_Storage.PutFloat( flVal1 ); + m_Storage.PutFloat( flVal2 ); + m_Storage.PutFloat( flVal3 ); + } + + FORCEINLINE void SetPixelShaderConstant( int nFirstConstant, float const *pSrcData, int nNumConstantsToSet ) + { + SetPixelShaderConstants( nFirstConstant, nNumConstantsToSet ); + m_Storage.PutMemory( pSrcData, 4 * sizeof( float ) * nNumConstantsToSet ); + } + + FORCEINLINE void SetPixelShaderConstant( int nFirstConstant, int nVar ) + { + SetPixelShaderConstant( nFirstConstant, Param( nVar )->GetVecValue() ); + } + + void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar ) + { + float val[4]; + Param(constantVar)->GetVecValue( val, 3 ); + val[0] = val[0] > 1.0f ? val[0] : GammaToLinear( val[0] ); + val[1] = val[1] > 1.0f ? val[1] : GammaToLinear( val[1] ); + val[2] = val[2] > 1.0f ? val[2] : GammaToLinear( val[2] ); + val[3] = 1.0; + SetPixelShaderConstant( pixelReg, val ); + } + + FORCEINLINE void SetPixelShaderConstant( int nFirstConstant, float const *pSrcData ) + { + SetPixelShaderConstants( nFirstConstant, 1 ); + OutputConstantData( pSrcData ); + } + + FORCEINLINE void SetPixelShaderConstant4( int nFirstConstant, float flVal0, float flVal1, float flVal2, float flVal3 ) + { + SetPixelShaderConstants( nFirstConstant, 1 ); + OutputConstantData4( flVal0, flVal1, flVal2, flVal3 ); + } + + FORCEINLINE void SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue ) + { + if ( constantVar != -1 ) + { + float val[3]; + Param(constantVar)->GetVecValue( val, 3); + SetPixelShaderConstant4( pixelReg, val[0], val[1], val[2], fWValue ); + } + } + + FORCEINLINE void SetVertexShaderConstant( int nFirstConstant, float const *pSrcData ) + { + m_Storage.PutInt( CBCMD_SET_VERTEX_SHADER_FLOAT_CONST ); + m_Storage.PutInt( nFirstConstant ); + m_Storage.PutInt( 1 ); + OutputConstantData( pSrcData ); + } + + FORCEINLINE void SetVertexShaderConstant( int nFirstConstant, float const *pSrcData, int nConsts ) + { + m_Storage.PutInt( CBCMD_SET_VERTEX_SHADER_FLOAT_CONST ); + m_Storage.PutInt( nFirstConstant ); + m_Storage.PutInt( nConsts ); + m_Storage.PutMemory( pSrcData, 4 * nConsts * sizeof( float ) ); + } + + + FORCEINLINE void SetVertexShaderConstant4( int nFirstConstant, float flVal0, float flVal1, float flVal2, float flVal3 ) + { + m_Storage.PutInt( CBCMD_SET_VERTEX_SHADER_FLOAT_CONST ); + m_Storage.PutInt( nFirstConstant ); + m_Storage.PutInt( 1 ); + m_Storage.PutFloat( flVal0 ); + m_Storage.PutFloat( flVal1 ); + m_Storage.PutFloat( flVal2 ); + m_Storage.PutFloat( flVal3 ); + } + + void SetVertexShaderTextureTransform( int vertexReg, int transformVar ) + { + Vector4D transformation[2]; + IMaterialVar* pTransformationVar = Param( transformVar ); + if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) + { + const VMatrix &mat = pTransformationVar->GetMatrixValue(); + transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); + transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); + } + else + { + transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); + transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); + } + SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 ); + } + + + void SetVertexShaderTextureScaledTransform( int vertexReg, int transformVar, int scaleVar ) + { + Vector4D transformation[2]; + IMaterialVar* pTransformationVar = Param( transformVar ); + if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) + { + const VMatrix &mat = pTransformationVar->GetMatrixValue(); + transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] ); + transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] ); + } + else + { + transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f ); + transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f ); + } + + Vector2D scale( 1, 1 ); + IMaterialVar* pScaleVar = Param( scaleVar ); + if (pScaleVar) + { + if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pScaleVar->GetVecValue( scale.Base(), 2 ); + else if (pScaleVar->IsDefined()) + scale[0] = scale[1] = pScaleVar->GetFloatValue(); + } + + // Apply the scaling + transformation[0][0] *= scale[0]; + transformation[0][1] *= scale[1]; + transformation[1][0] *= scale[0]; + transformation[1][1] *= scale[1]; + transformation[0][3] *= scale[0]; + transformation[1][3] *= scale[1]; + SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 ); + } + + FORCEINLINE void SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar ) + { + if( g_pConfig->bShowSpecular && my_mat_fullbright.GetInt() != 2 ) + { + SetPixelShaderConstant( pixelReg, Param( tintVar)->GetVecValue() ); + } + else + { + SetPixelShaderConstant4( pixelReg, 0.0, 0.0, 0.0, 0.0 ); + } + } + + FORCEINLINE void SetEnvMapTintPixelShaderDynamicStateGammaToLinear( int pixelReg, int tintVar, float flAlphaValue = 1.0 ) + { + if( ( tintVar != -1 ) && g_pConfig->bShowSpecular && my_mat_fullbright.GetInt() != 2 ) + { + float color[4]; + color[3] = flAlphaValue; + Param( tintVar)->GetLinearVecValue( color, 3 ); + SetPixelShaderConstant( pixelReg, color ); + } + else + { + SetPixelShaderConstant4( pixelReg, 0.0, 0.0, 0.0, flAlphaValue ); + } + } + + FORCEINLINE void StoreEyePosInPixelShaderConstant( int nConst ) + { + m_Storage.PutInt( CBCMD_STORE_EYE_POS_IN_PSCONST ); + m_Storage.PutInt( nConst ); + } + + FORCEINLINE void CommitPixelShaderLighting( int nConst ) + { + m_Storage.PutInt( CBCMD_COMMITPIXELSHADERLIGHTING ); + m_Storage.PutInt( nConst ); + } + + FORCEINLINE void SetPixelShaderStateAmbientLightCube( int nConst ) + { + m_Storage.PutInt( CBCMD_SETPIXELSHADERSTATEAMBIENTLIGHTCUBE ); + m_Storage.PutInt( nConst ); + } + + FORCEINLINE void SetAmbientCubeDynamicStateVertexShader( void ) + { + m_Storage.PutInt( CBCMD_SETAMBIENTCUBEDYNAMICSTATEVERTEXSHADER ); + } + + FORCEINLINE void SetPixelShaderFogParams( int nReg ) + { + m_Storage.PutInt( CBCMD_SETPIXELSHADERFOGPARAMS ); + m_Storage.PutInt( nReg ); + } + + FORCEINLINE void BindStandardTexture( Sampler_t nSampler, StandardTextureId_t nTextureId ) + { + m_Storage.PutInt( CBCMD_BIND_STANDARD_TEXTURE ); + m_Storage.PutInt( nSampler ); + m_Storage.PutInt( nTextureId ); + } + + + FORCEINLINE void BindTexture( Sampler_t nSampler, ShaderAPITextureHandle_t hTexture ) + { + Assert( hTexture != INVALID_SHADERAPI_TEXTURE_HANDLE ); + if ( hTexture != INVALID_SHADERAPI_TEXTURE_HANDLE ) + { + m_Storage.PutInt( CBCMD_BIND_SHADERAPI_TEXTURE_HANDLE ); + m_Storage.PutInt( nSampler ); + m_Storage.PutInt( hTexture ); + } + } + + FORCEINLINE void BindTexture( CBaseVSShader *pShader, Sampler_t nSampler, int nTextureVar, int nFrameVar ) + { + ShaderAPITextureHandle_t hTexture = pShader->GetShaderAPITextureBindHandle( nTextureVar, nFrameVar ); + BindTexture( nSampler, hTexture ); + } + + FORCEINLINE void BindMultiTexture( CBaseVSShader *pShader, Sampler_t nSampler1, Sampler_t nSampler2, int nTextureVar, int nFrameVar ) + { + ShaderAPITextureHandle_t hTexture = pShader->GetShaderAPITextureBindHandle( nTextureVar, nFrameVar, 0 ); + BindTexture( nSampler1, hTexture ); + hTexture = pShader->GetShaderAPITextureBindHandle( nTextureVar, nFrameVar, 1 ); + BindTexture( nSampler2, hTexture ); + } + + FORCEINLINE void SetPixelShaderIndex( int nIndex ) + { + m_Storage.PutInt( CBCMD_SET_PSHINDEX ); + m_Storage.PutInt( nIndex ); + } + + FORCEINLINE void SetVertexShaderIndex( int nIndex ) + { + m_Storage.PutInt( CBCMD_SET_VSHINDEX ); + m_Storage.PutInt( nIndex ); + } + + FORCEINLINE void SetDepthFeatheringPixelShaderConstant( int iConstant, float fDepthBlendScale ) + { + m_Storage.PutInt( CBCMD_SET_DEPTH_FEATHERING_CONST ); + m_Storage.PutInt( iConstant ); + m_Storage.PutFloat( fDepthBlendScale ); + } + + FORCEINLINE void Goto( uint8 *pCmdBuf ) + { + m_Storage.PutInt( CBCMD_JUMP ); + m_Storage.PutPtr( pCmdBuf ); + } + + FORCEINLINE void Call( uint8 *pCmdBuf ) + { + m_Storage.PutInt( CBCMD_JSR ); + m_Storage.PutPtr( pCmdBuf ); + } + + FORCEINLINE void Reset( void ) + { + m_Storage.Reset(); + } + + FORCEINLINE size_t Size( void ) const + { + return m_Storage.Size(); + } + + FORCEINLINE uint8 *Base( void ) + { + return m_Storage.Base(); + } + + + +}; + + +#endif // commandbuilder_h diff --git a/mp/src/materialsystem/stdshaders/common_flashlight_fxc.h b/mp/src/materialsystem/stdshaders/common_flashlight_fxc.h index f9256a59..098f1848 100644 --- a/mp/src/materialsystem/stdshaders/common_flashlight_fxc.h +++ b/mp/src/materialsystem/stdshaders/common_flashlight_fxc.h @@ -1,821 +1,821 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Common pixel shader code specific to flashlights -// -// $NoKeywords: $ -// -//=============================================================================// -#ifndef COMMON_FLASHLIGHT_FXC_H_ -#define COMMON_FLASHLIGHT_FXC_H_ - -#include "common_ps_fxc.h" - - -// JasonM - TODO: remove this simpleton version -float DoShadow( sampler DepthSampler, float4 texCoord ) -{ - const float g_flShadowBias = 0.0005f; - float2 uoffset = float2( 0.5f/512.f, 0.0f ); - float2 voffset = float2( 0.0f, 0.5f/512.f ); - float3 projTexCoord = texCoord.xyz / texCoord.w; - float4 flashlightDepth = float4( tex2D( DepthSampler, projTexCoord + uoffset + voffset ).x, - tex2D( DepthSampler, projTexCoord + uoffset - voffset ).x, - tex2D( DepthSampler, projTexCoord - uoffset + voffset ).x, - tex2D( DepthSampler, projTexCoord - uoffset - voffset ).x ); - -# if ( defined( REVERSE_DEPTH_ON_X360 ) ) - { - flashlightDepth = 1.0f - flashlightDepth; - } -# endif - - float shadowed = 0.0f; - float z = texCoord.z/texCoord.w; - float4 dz = float4(z,z,z,z) - (flashlightDepth + float4( g_flShadowBias, g_flShadowBias, g_flShadowBias, g_flShadowBias)); - float4 shadow = float4(0.25f,0.25f,0.25f,0.25f); - - if( dz.x <= 0.0f ) - shadowed += shadow.x; - if( dz.y <= 0.0f ) - shadowed += shadow.y; - if( dz.z <= 0.0f ) - shadowed += shadow.z; - if( dz.w <= 0.0f ) - shadowed += shadow.w; - - return shadowed; -} - - -float DoShadowNvidiaRAWZOneTap( sampler DepthSampler, const float4 shadowMapPos ) -{ - float ooW = 1.0f / shadowMapPos.w; // 1 / w - float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once - - float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter - float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space - - float fDepth = dot(tex2D(DepthSampler, shadowMapCenter).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); - - return fDepth > objDepth; -} - - -float DoShadowNvidiaRAWZ( sampler DepthSampler, const float4 shadowMapPos ) -{ - float fE = 1.0f / 512.0f; // Epsilon - - float ooW = 1.0f / shadowMapPos.w; // 1 / w - float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once - - float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter - float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space - - float4 vDepths; - vDepths.x = dot(tex2D(DepthSampler, shadowMapCenter + float2( fE, fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); - vDepths.y = dot(tex2D(DepthSampler, shadowMapCenter + float2( -fE, fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); - vDepths.z = dot(tex2D(DepthSampler, shadowMapCenter + float2( fE, -fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); - vDepths.w = dot(tex2D(DepthSampler, shadowMapCenter + float2( -fE, -fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); - - return dot(vDepths > objDepth.xxxx, float4(0.25, 0.25, 0.25, 0.25)); -} - - -float DoShadowNvidiaCheap( sampler DepthSampler, const float4 shadowMapPos ) -{ - float fTexelEpsilon = 1.0f / 1024.0f; - - float ooW = 1.0f / shadowMapPos.w; // 1 / w - float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once - - float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter - float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space - - float4 vTaps; - vTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, fTexelEpsilon), objDepth, 1 ) ).x; - vTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, fTexelEpsilon), objDepth, 1 ) ).x; - vTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, -fTexelEpsilon), objDepth, 1 ) ).x; - vTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, -fTexelEpsilon), objDepth, 1 ) ).x; - - return dot(vTaps, float4(0.25, 0.25, 0.25, 0.25)); -} - -float DoShadowNvidiaPCF3x3Box( sampler DepthSampler, const float4 shadowMapPos ) -{ - float fTexelEpsilon = 1.0f / 1024.0f; - - float ooW = 1.0f / shadowMapPos.w; // 1 / w - float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once - - float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter - float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space - - float4 vOneTaps; - vOneTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, fTexelEpsilon ), objDepth, 1 ) ).x; - vOneTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, fTexelEpsilon ), objDepth, 1 ) ).x; - vOneTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, -fTexelEpsilon ), objDepth, 1 ) ).x; - vOneTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, -fTexelEpsilon ), objDepth, 1 ) ).x; - float flOneTaps = dot( vOneTaps, float4(1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f)); - - float4 vTwoTaps; - vTwoTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, 0 ), objDepth, 1 ) ).x; - vTwoTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, 0 ), objDepth, 1 ) ).x; - vTwoTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTexelEpsilon ), objDepth, 1 ) ).x; - vTwoTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTexelEpsilon ), objDepth, 1 ) ).x; - float flTwoTaps = dot( vTwoTaps, float4(1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f)); - - float flCenterTap = tex2Dproj( DepthSampler, float4( shadowMapCenter, objDepth, 1 ) ).x * (1.0f / 9.0f); - - // Sum all 9 Taps - return flOneTaps + flTwoTaps + flCenterTap; -} - - -// -// 1 4 7 4 1 -// 4 20 33 20 4 -// 7 33 55 33 7 -// 4 20 33 20 4 -// 1 4 7 4 1 -// -float DoShadowNvidiaPCF5x5Gaussian( sampler DepthSampler, const float4 shadowMapPos ) -{ - float fEpsilon = 1.0f / 512.0f; - float fTwoEpsilon = 2.0f * fEpsilon; - - float ooW = 1.0f / shadowMapPos.w; // 1 / w - float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once - - float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter - float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space - - float4 vOneTaps; - vOneTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x; - vOneTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x; - vOneTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x; - vOneTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x; - float flOneTaps = dot( vOneTaps, float4(1.0f / 331.0f, 1.0f / 331.0f, 1.0f / 331.0f, 1.0f / 331.0f)); - - float4 vSevenTaps; - vSevenTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, 0 ), objDepth, 1 ) ).x; - vSevenTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, 0 ), objDepth, 1 ) ).x; - vSevenTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTwoEpsilon ), objDepth, 1 ) ).x; - vSevenTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTwoEpsilon ), objDepth, 1 ) ).x; - float flSevenTaps = dot( vSevenTaps, float4( 7.0f / 331.0f, 7.0f / 331.0f, 7.0f / 331.0f, 7.0f / 331.0f ) ); - - float4 vFourTapsA, vFourTapsB; - vFourTapsA.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, fEpsilon ), objDepth, 1 ) ).x; - vFourTapsA.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x; - vFourTapsA.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x; - vFourTapsA.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, fEpsilon ), objDepth, 1 ) ).x; - vFourTapsB.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, -fEpsilon ), objDepth, 1 ) ).x; - vFourTapsB.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x; - vFourTapsB.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x; - vFourTapsB.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, -fEpsilon ), objDepth, 1 ) ).x; - float flFourTapsA = dot( vFourTapsA, float4( 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f ) ); - float flFourTapsB = dot( vFourTapsB, float4( 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f ) ); - - float4 v20Taps; - v20Taps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, fEpsilon ), objDepth, 1 ) ).x; - v20Taps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, fEpsilon ), objDepth, 1 ) ).x; - v20Taps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, -fEpsilon ), objDepth, 1 ) ).x; - v20Taps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, -fEpsilon ), objDepth, 1 ) ).x; - float fl20Taps = dot( v20Taps, float4(20.0f / 331.0f, 20.0f / 331.0f, 20.0f / 331.0f, 20.0f / 331.0f)); - - float4 v33Taps; - v33Taps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, 0 ), objDepth, 1 ) ).x; - v33Taps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, 0 ), objDepth, 1 ) ).x; - v33Taps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fEpsilon ), objDepth, 1 ) ).x; - v33Taps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fEpsilon ), objDepth, 1 ) ).x; - float fl33Taps = dot( v33Taps, float4(33.0f / 331.0f, 33.0f / 331.0f, 33.0f / 331.0f, 33.0f / 331.0f)); - - float flCenterTap = tex2Dproj( DepthSampler, float4( shadowMapCenter, objDepth, 1 ) ).x * (55.0f / 331.0f); - - // Sum all 25 Taps - return flOneTaps + flSevenTaps + +flFourTapsA + flFourTapsB + fl20Taps + fl33Taps + flCenterTap; -} - - -float DoShadowATICheap( sampler DepthSampler, const float4 shadowMapPos ) -{ - float2 shadowMapCenter = shadowMapPos.xy/shadowMapPos.w; - float objDepth = shadowMapPos.z / shadowMapPos.w; - float fSampleDepth = tex2D( DepthSampler, shadowMapCenter ).x; - - objDepth = min( objDepth, 0.99999 ); //HACKHACK: On 360, surfaces at or past the far flashlight plane have an abrupt cutoff. This is temp until a smooth falloff is implemented - - return fSampleDepth > objDepth; -} - - -// Poisson disc, randomly rotated at different UVs -float DoShadowPoisson16Sample( sampler DepthSampler, sampler RandomRotationSampler, const float3 vProjCoords, const float2 vScreenPos, const float4 vShadowTweaks, bool bNvidiaHardwarePCF, bool bFetch4 ) -{ - float2 vPoissonOffset[8] = { float2( 0.3475f, 0.0042f ), - float2( 0.8806f, 0.3430f ), - float2( -0.0041f, -0.6197f ), - float2( 0.0472f, 0.4964f ), - float2( -0.3730f, 0.0874f ), - float2( -0.9217f, -0.3177f ), - float2( -0.6289f, 0.7388f ), - float2( 0.5744f, -0.7741f ) }; - - float flScaleOverMapSize = vShadowTweaks.x * 2; // Tweak parameters to shader - float2 vNoiseOffset = vShadowTweaks.zw; - float4 vLightDepths = 0, accum = 0.0f; - float2 rotOffset = 0; - - float2 shadowMapCenter = vProjCoords.xy; // Center of shadow filter - float objDepth = min( vProjCoords.z, 0.99999 ); // Object depth in shadow space - - // 2D Rotation Matrix setup - float3 RMatTop = 0, RMatBottom = 0; -#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) - RMatTop.xy = tex2D( RandomRotationSampler, cFlashlightScreenScale.xy * (vScreenPos * 0.5 + 0.5) + vNoiseOffset) * 2.0 - 1.0; - RMatBottom.xy = float2(-1.0, 1.0) * RMatTop.yx; // 2x2 rotation matrix in 4-tuple -#endif - - RMatTop *= flScaleOverMapSize; // Scale up kernel while accounting for texture resolution - RMatBottom *= flScaleOverMapSize; - - RMatTop.z = shadowMapCenter.x; // To be added in d2adds generated below - RMatBottom.z = shadowMapCenter.y; - - float fResult = 0.0f; - - if ( bNvidiaHardwarePCF ) - { - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[0].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[0].xy) + RMatBottom.z; - vLightDepths.x += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[1].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[1].xy) + RMatBottom.z; - vLightDepths.y += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[2].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[2].xy) + RMatBottom.z; - vLightDepths.z += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[3].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[3].xy) + RMatBottom.z; - vLightDepths.w += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4].xy) + RMatBottom.z; - vLightDepths.x += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[5].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[5].xy) + RMatBottom.z; - vLightDepths.y += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[6].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[6].xy) + RMatBottom.z; - vLightDepths.z += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[7].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[7].xy) + RMatBottom.z; - vLightDepths.w += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; - - fResult = dot( vLightDepths, float4( 0.25, 0.25, 0.25, 0.25) ); - } - else if ( bFetch4 ) - { -/* - -TODO: Fix this contact hardening stuff - - float flNumCloserSamples = 1; - float flAccumulatedCloserSamples = objDepth; - float4 vBlockerDepths; - - // First, search for blockers - for( int j=0; j<8; j++ ) - { - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[j].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[j].xy) + RMatBottom.z; - vBlockerDepths = tex2D( DepthSampler, rotOffset.xy ); - - // Which samples are closer than the pixel we're rendering? - float4 vCloserSamples = (vBlockerDepths < objDepth.xxxx ); // Binary comparison results - flNumCloserSamples += dot( vCloserSamples, float4(1, 1, 1, 1) ); // How many samples are closer than receiver? - flAccumulatedCloserSamples += dot (vCloserSamples, vBlockerDepths ); // Total depths from samples closer than receiver - } - - float flBlockerDepth = flAccumulatedCloserSamples / flNumCloserSamples; - float flContactHardeningScale = (objDepth - flBlockerDepth) / flBlockerDepth; - - // Scale the kernel - RMatTop.xy *= flContactHardeningScale; - RMatBottom.xy *= flContactHardeningScale; -*/ - - for( int i=0; i<8; i++ ) - { - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[i].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[i].xy) + RMatBottom.z; - vLightDepths = tex2D( DepthSampler, rotOffset.xy ); - accum += (vLightDepths > objDepth.xxxx); - } - - fResult = dot( accum, float4( 1.0f/32.0f, 1.0f/32.0f, 1.0f/32.0f, 1.0f/32.0f) ); - } - else // ATI vanilla hardware shadow mapping - { - for( int i=0; i<2; i++ ) - { - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+0].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+0].xy) + RMatBottom.z; - vLightDepths.x = tex2D( DepthSampler, rotOffset.xy ).x; - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+1].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+1].xy) + RMatBottom.z; - vLightDepths.y = tex2D( DepthSampler, rotOffset.xy ).x; - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+2].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+2].xy) + RMatBottom.z; - vLightDepths.z = tex2D( DepthSampler, rotOffset.xy ).x; - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+3].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+3].xy) + RMatBottom.z; - vLightDepths.w = tex2D( DepthSampler, rotOffset.xy ).x; - - accum += (vLightDepths > objDepth.xxxx); - } - - fResult = dot( accum, float4( 0.125, 0.125, 0.125, 0.125) ); - } - - return fResult; -} - -#if defined( _X360 ) - -// Poisson disc, randomly rotated at different UVs -float DoShadow360Simple( sampler DepthSampler, const float3 vProjCoords ) -{ - float fLOD; - float2 shadowMapCenter = vProjCoords.xy; // Center of shadow filter - float objDepth = min( vProjCoords.z, 0.99999 ); // Object depth in shadow space - -#if defined( REVERSE_DEPTH_ON_X360 ) - objDepth = 1.0f - objDepth; -#endif - - float4 vSampledDepths, vWeights; - - asm { - getCompTexLOD2D fLOD.x, shadowMapCenter.xy, DepthSampler, AnisoFilter=max16to1 - setTexLOD fLOD.x - - tfetch2D vSampledDepths.x___, shadowMapCenter, DepthSampler, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - tfetch2D vSampledDepths._x__, shadowMapCenter, DepthSampler, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - tfetch2D vSampledDepths.__x_, shadowMapCenter, DepthSampler, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - tfetch2D vSampledDepths.___x, shadowMapCenter, DepthSampler, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - - getWeights2D vWeights, shadowMapCenter.xy, DepthSampler, MagFilter=linear, MinFilter=linear, UseComputedLOD=false, UseRegisterLOD=true - }; - - vWeights = float4( (1-vWeights.x)*(1-vWeights.y), vWeights.x*(1-vWeights.y), (1-vWeights.x)*vWeights.y, vWeights.x*vWeights.y ); - -#if defined( REVERSE_DEPTH_ON_X360 ) - float4 vCompare = (vSampledDepths < objDepth.xxxx); -#else - float4 vCompare = (vSampledDepths > objDepth.xxxx); -#endif - - return dot( vCompare, vWeights ); -} - - -float Do360PCFFetch( sampler DepthSampler, float2 tc, float objDepth ) -{ - float fLOD; - float4 vSampledDepths, vWeights; - - asm { - getCompTexLOD2D fLOD.x, tc.xy, DepthSampler, AnisoFilter=max16to1 - setTexLOD fLOD.x - - tfetch2D vSampledDepths.x___, tc, DepthSampler, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - tfetch2D vSampledDepths._x__, tc, DepthSampler, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - tfetch2D vSampledDepths.__x_, tc, DepthSampler, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - tfetch2D vSampledDepths.___x, tc, DepthSampler, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - - getWeights2D vWeights, tc.xy, DepthSampler, MagFilter=linear, MinFilter=linear, UseComputedLOD=false, UseRegisterLOD=true - }; - - vWeights = float4( (1-vWeights.x)*(1-vWeights.y), vWeights.x*(1-vWeights.y), (1-vWeights.x)*vWeights.y, vWeights.x*vWeights.y ); - -#if defined( REVERSE_DEPTH_ON_X360 ) - float4 vCompare = (vSampledDepths < objDepth.xxxx); -#else - float4 vCompare = (vSampledDepths > objDepth.xxxx); -#endif - - return dot( vCompare, vWeights ); -} - - - -float Do360NearestFetch( sampler DepthSampler, float2 tc, float objDepth ) -{ - float fLOD; - float4 vSampledDepth; - - asm { - getCompTexLOD2D fLOD.x, tc.xy, DepthSampler, AnisoFilter=max16to1 - setTexLOD fLOD.x - - tfetch2D vSampledDepth.x___, tc, DepthSampler, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - }; - -#if defined( REVERSE_DEPTH_ON_X360 ) - return (vSampledDepth.x < objDepth.x); -#else - return (vSampledDepth.x > objDepth.x); -#endif - -} - - -float AmountShadowed_8Tap_360( sampler DepthSampler, float2 tc, float objDepth ) -{ - float fLOD; - float4 vSampledDepthsA, vSampledDepthsB; - - // Optimal 8 rooks pattern to get an idea about whether we're at a penumbra or not - // From [Kallio07] "Scanline Edge-Flag Algorithm for Antialiasing" - // - // +---+---+---+---+---+---+---+---+ - // | | | | | | o | | | - // +---+---+---+---+---+---+---+---+ - // | o | | | | | | | | - // +---+---+---+---+---+---+---+---+ - // | | | | o | | | | | - // +---+---+---+---+---+---+---+---+ - // | | | | | | | o | | - // +---+---+---+---+---+---+---+---+ - // | | o | | | | | | | - // +---+---+---+---+---+---+---+---+ - // | | | | | o | | | | - // +---+---+---+---+---+---+---+---+ - // | | | | | | | | o | - // +---+---+---+---+---+---+---+---+ - // | | | o | | | | | | - // +---+---+---+---+---+---+---+---+ - // - asm { - getCompTexLOD2D fLOD.x, tc.xy, DepthSampler, AnisoFilter=max16to1 - setTexLOD fLOD.x - - tfetch2D vSampledDepthsA.x___, tc, DepthSampler, OffsetX = -2.0, OffsetY = -1.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - tfetch2D vSampledDepthsA._x__, tc, DepthSampler, OffsetX = -1.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - tfetch2D vSampledDepthsA.__x_, tc, DepthSampler, OffsetX = -1.0, OffsetY = 2.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - tfetch2D vSampledDepthsA.___x, tc, DepthSampler, OffsetX = -0.5, OffsetY = -1.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - - tfetch2D vSampledDepthsB.x___, tc, DepthSampler, OffsetX = 0.5, OffsetY = 1.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - tfetch2D vSampledDepthsB._x__, tc, DepthSampler, OffsetX = 1.0, OffsetY = -2.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - tfetch2D vSampledDepthsB.__x_, tc, DepthSampler, OffsetX = 1.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - tfetch2D vSampledDepthsB.___x, tc, DepthSampler, OffsetX = 2.0, OffsetY = 1.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - }; - -#if defined( REVERSE_DEPTH_ON_X360 ) - float4 vCompareA = (vSampledDepthsA < objDepth.xxxx); - float4 vCompareB = (vSampledDepthsB < objDepth.xxxx); -#else - float4 vCompareA = (vSampledDepthsA > objDepth.xxxx); - float4 vCompareB = (vSampledDepthsB > objDepth.xxxx); -#endif - - return dot( vCompareA, float4(0.125,0.125,0.125,0.125) ) + dot( vCompareB, float4(0.125,0.125,0.125,0.125) ); -} - - -float AmountShadowed_4Tap_360( sampler DepthSampler, float2 tc, float objDepth ) -{ - float fLOD; - float4 vSampledDepths; - - // Rotated grid pattern to get an idea about whether we're at a penumbra or not - asm { - getCompTexLOD2D fLOD.x, tc.xy, DepthSampler, AnisoFilter=max16to1 - setTexLOD fLOD.x - - tfetch2D vSampledDepths.x___, tc, DepthSampler, OffsetX = -1.0, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - tfetch2D vSampledDepths._x__, tc, DepthSampler, OffsetX = -0.5, OffsetY = -1.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - tfetch2D vSampledDepths.__x_, tc, DepthSampler, OffsetX = 0.5, OffsetY = 1.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - tfetch2D vSampledDepths.___x, tc, DepthSampler, OffsetX = 1.0, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point - }; - -#if defined( REVERSE_DEPTH_ON_X360 ) - float4 vCompare = (vSampledDepths < objDepth.xxxx); -#else - float4 vCompare = (vSampledDepths > objDepth.xxxx); -#endif - - return dot( vCompare, float4(0.25,0.25,0.25,0.25) ); -} - -// Poisson disc, randomly rotated at different UVs -float DoShadowPoisson360( sampler DepthSampler, sampler RandomRotationSampler, const float3 vProjCoords, const float2 vScreenPos, const float4 vShadowTweaks ) -{ - float2 vPoissonOffset[8] = { float2( 0.3475f, 0.0042f ), float2( 0.8806f, 0.3430f ), - float2( -0.0041f, -0.6197f ), float2( 0.0472f, 0.4964f ), - float2( -0.3730f, 0.0874f ), float2( -0.9217f, -0.3177f ), - float2( -0.6289f, 0.7388f ), float2( 0.5744f, -0.7741f ) }; - - float2 shadowMapCenter = vProjCoords.xy; // Center of shadow filter - float objDepth = min( vProjCoords.z, 0.99999 ); // Object depth in shadow space - -#if defined( REVERSE_DEPTH_ON_X360 ) - objDepth = 1.0f - objDepth; -#endif - - float fAmountShadowed = AmountShadowed_4Tap_360( DepthSampler, shadowMapCenter, objDepth ); - - if ( fAmountShadowed >= 1.0f ) // Fully in light - { - return 1.0f; - } - else // Do the expensive filtering since we're at least partially shadowed - { - float flScaleOverMapSize = 1.7f / 512.0f; // Tweak parameters to shader - - // 2D Rotation Matrix setup - float3 RMatTop = 0, RMatBottom = 0; -#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) - RMatTop.xy = tex2D( RandomRotationSampler, cFlashlightScreenScale.xy * (vScreenPos * 0.5 + 0.5)) * 2.0 - 1.0; - RMatBottom.xy = float2(-1.0, 1.0) * RMatTop.yx; // 2x2 rotation matrix in 4-tuple -#endif - - RMatTop *= flScaleOverMapSize; // Scale up kernel while accounting for texture resolution - RMatBottom *= flScaleOverMapSize; - RMatTop.z = shadowMapCenter.x; // To be added in d2adds generated below - RMatBottom.z = shadowMapCenter.y; - float2 rotOffset = float2(0,0); - float4 vAccum = 0; - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[0].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[0].xy) + RMatBottom.z; - vAccum.x = Do360NearestFetch( DepthSampler, rotOffset, objDepth ); - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[1].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[1].xy) + RMatBottom.z; - vAccum.y = Do360NearestFetch( DepthSampler, rotOffset, objDepth ); - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[2].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[2].xy) + RMatBottom.z; - vAccum.z = Do360NearestFetch( DepthSampler, rotOffset, objDepth ); - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[3].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[3].xy) + RMatBottom.z; - vAccum.w = Do360NearestFetch( DepthSampler, rotOffset, objDepth ); - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4].xy) + RMatBottom.z; - vAccum.x += Do360NearestFetch( DepthSampler, rotOffset, objDepth ); - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[5].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[5].xy) + RMatBottom.z; - vAccum.y += Do360NearestFetch( DepthSampler, rotOffset, objDepth ); - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[6].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[6].xy) + RMatBottom.z; - vAccum.z += Do360NearestFetch( DepthSampler, rotOffset, objDepth ); - - rotOffset.x = dot (RMatTop.xy, vPoissonOffset[7].xy) + RMatTop.z; - rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[7].xy) + RMatBottom.z; - vAccum.w += Do360NearestFetch( DepthSampler, rotOffset, objDepth ); - - return dot( vAccum, float4( 0.25, 0.25, 0.25, 0.25) ); - } -} - -#endif // _X360 - - -float DoFlashlightShadow( sampler DepthSampler, sampler RandomRotationSampler, float3 vProjCoords, float2 vScreenPos, int nShadowLevel, float4 vShadowTweaks, bool bAllowHighQuality ) -{ - float flShadow = 1.0f; - -#if !defined( _X360 ) //PC - if( nShadowLevel == NVIDIA_PCF_POISSON ) - flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, true, false ); - else if( nShadowLevel == ATI_NOPCF ) - flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, false, false ); - else if( nShadowLevel == ATI_NO_PCF_FETCH4 ) - flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, false, true ); - - return flShadow; -#else - - // Compile-time switch for shaders which allow high quality modes on 360 - if ( bAllowHighQuality ) - { - // Static control flow switch for shadow quality. Some non-interactive sequences use the high quality path - if ( g_bHighQualityShadows ) - { - flShadow = DoShadowPoisson360( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks ); - } - else - { - flShadow = DoShadow360Simple( DepthSampler, vProjCoords ); - } - } - else - { - flShadow = DoShadow360Simple( DepthSampler, vProjCoords ); - } - - return flShadow; - -#endif -} - -float3 SpecularLight( const float3 vWorldNormal, const float3 vLightDir, const float fSpecularExponent, - const float3 vEyeDir, const bool bDoSpecularWarp, in sampler specularWarpSampler, float fFresnel ) -{ - float3 result = float3(0.0f, 0.0f, 0.0f); - - //float3 vReflect = reflect( -vEyeDir, vWorldNormal ); - float3 vReflect = 2 * vWorldNormal * dot( vWorldNormal , vEyeDir ) - vEyeDir; // Reflect view through normal - float3 vSpecular = saturate(dot( vReflect, vLightDir )); // L.R (use half-angle instead?) - vSpecular = pow( vSpecular.x, fSpecularExponent ); // Raise to specular power - - // Optionally warp as function of scalar specular and fresnel - if ( bDoSpecularWarp ) - vSpecular *= tex2D( specularWarpSampler, float2(vSpecular.x, fFresnel) ); // Sample at { (L.R)^k, fresnel } - - return vSpecular; -} - -void DoSpecularFlashlight( float3 flashlightPos, float3 worldPos, float4 flashlightSpacePosition, float3 worldNormal, - float3 attenuationFactors, float farZ, sampler FlashlightSampler, sampler FlashlightDepthSampler, sampler RandomRotationSampler, - int nShadowLevel, bool bDoShadows, bool bAllowHighQuality, const float2 vScreenPos, const float fSpecularExponent, const float3 vEyeDir, - const bool bDoSpecularWarp, sampler specularWarpSampler, float fFresnel, float4 vShadowTweaks, - - // Outputs of this shader...separate shadowed diffuse and specular from the flashlight - out float3 diffuseLighting, out float3 specularLighting ) -{ - float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; - float3 flashlightColor = float3(1,1,1); - -#if ( defined( _X360 ) ) - - float3 ltz = vProjCoords.xyz < float3( 0.0f, 0.0f, 0.0f ); - float3 gto = vProjCoords.xyz > float3( 1.0f, 1.0f, 1.0f ); - - [branch] - if ( dot(ltz + gto, float3(1,1,1)) > 0 ) - { - clip(-1); - diffuseLighting = specularLighting = float3(0,0,0); - return; - } - else - { - flashlightColor = tex2D( FlashlightSampler, vProjCoords ); - - [branch] - if ( dot(flashlightColor.xyz, float3(1,1,1)) <= 0 ) - { - clip(-1); - diffuseLighting = specularLighting = float3(0,0,0); - return; - } - } -#else - flashlightColor = tex2D( FlashlightSampler, vProjCoords ); -#endif - - -#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) - flashlightColor *= cFlashlightColor.xyz; // Flashlight color -#endif - - float3 delta = flashlightPos - worldPos; - float3 L = normalize( delta ); - float distSquared = dot( delta, delta ); - float dist = sqrt( distSquared ); - - float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); - - // Attenuation for light and to fade out shadow over distance - float fAtten = saturate( dot( attenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); - - // Shadowing and coloring terms -#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) - if ( bDoShadows ) - { - float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, nShadowLevel, vShadowTweaks, bAllowHighQuality ); - float flAttenuated = lerp( flShadow, 1.0f, vShadowTweaks.y ); // Blend between fully attenuated and not attenuated - flShadow = saturate( lerp( flAttenuated, flShadow, fAtten ) ); // Blend between shadow and above, according to light attenuation - flashlightColor *= flShadow; // Shadow term - } -#endif - - diffuseLighting = fAtten; -#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) - diffuseLighting *= saturate( dot( L.xyz, worldNormal.xyz ) + flFlashlightNoLambertValue ); // Lambertian term -#else - diffuseLighting *= saturate( dot( L.xyz, worldNormal.xyz ) ); // Lambertian (not Half-Lambert) term -#endif - diffuseLighting *= flashlightColor; - diffuseLighting *= endFalloffFactor; - - // Specular term (masked by diffuse) - specularLighting = diffuseLighting * SpecularLight ( worldNormal, L, fSpecularExponent, vEyeDir, bDoSpecularWarp, specularWarpSampler, fFresnel ); -} - -// Diffuse only version -float3 DoFlashlight( float3 flashlightPos, float3 worldPos, float4 flashlightSpacePosition, float3 worldNormal, - float3 attenuationFactors, float farZ, sampler FlashlightSampler, sampler FlashlightDepthSampler, - sampler RandomRotationSampler, int nShadowLevel, bool bDoShadows, bool bAllowHighQuality, - const float2 vScreenPos, bool bClip, float4 vShadowTweaks = float4(3/1024.0f, 0.0005f, 0.0f, 0.0f), bool bHasNormal = true ) -{ - float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; - float3 flashlightColor = float3(1,1,1); - -#if ( defined( _X360 ) ) - - float3 ltz = vProjCoords.xyz < float3( 0.0f, 0.0f, 0.0f ); - float3 gto = vProjCoords.xyz > float3( 1.0f, 1.0f, 1.0f ); - - [branch] - if ( dot(ltz + gto, float3(1,1,1)) > 0 ) - { - if ( bClip ) - { - clip(-1); - } - return float3(0,0,0); - } - else - { - flashlightColor = tex2D( FlashlightSampler, vProjCoords ); - - [branch] - if ( dot(flashlightColor.xyz, float3(1,1,1)) <= 0 ) - { - if ( bClip ) - { - clip(-1); - } - return float3(0,0,0); - } - } -#else - flashlightColor = tex2D( FlashlightSampler, vProjCoords ); -#endif - -#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) - flashlightColor *= cFlashlightColor.xyz; // Flashlight color -#endif - - float3 delta = flashlightPos - worldPos; - float3 L = normalize( delta ); - float distSquared = dot( delta, delta ); - float dist = sqrt( distSquared ); - - float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); - - // Attenuation for light and to fade out shadow over distance - float fAtten = saturate( dot( attenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); - - // Shadowing and coloring terms -#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) - if ( bDoShadows ) - { - float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, nShadowLevel, vShadowTweaks, bAllowHighQuality ); - float flAttenuated = lerp( flShadow, 1.0f, vShadowTweaks.y ); // Blend between fully attenuated and not attenuated - flShadow = saturate( lerp( flAttenuated, flShadow, fAtten ) ); // Blend between shadow and above, according to light attenuation - flashlightColor *= flShadow; // Shadow term - } -#endif - - float3 diffuseLighting = fAtten; - - float flLDotWorldNormal; - if ( bHasNormal ) - { - flLDotWorldNormal = dot( L.xyz, worldNormal.xyz ); - } - else - { - flLDotWorldNormal = 1.0f; - } - -#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) - diffuseLighting *= saturate( flLDotWorldNormal + flFlashlightNoLambertValue ); // Lambertian term -#else - diffuseLighting *= saturate( flLDotWorldNormal ); // Lambertian (not Half-Lambert) term -#endif - - diffuseLighting *= flashlightColor; - diffuseLighting *= endFalloffFactor; - - return diffuseLighting; -} - -#endif //#ifndef COMMON_FLASHLIGHT_FXC_H_ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Common pixel shader code specific to flashlights +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_FLASHLIGHT_FXC_H_ +#define COMMON_FLASHLIGHT_FXC_H_ + +#include "common_ps_fxc.h" + + +// JasonM - TODO: remove this simpleton version +float DoShadow( sampler DepthSampler, float4 texCoord ) +{ + const float g_flShadowBias = 0.0005f; + float2 uoffset = float2( 0.5f/512.f, 0.0f ); + float2 voffset = float2( 0.0f, 0.5f/512.f ); + float3 projTexCoord = texCoord.xyz / texCoord.w; + float4 flashlightDepth = float4( tex2D( DepthSampler, projTexCoord + uoffset + voffset ).x, + tex2D( DepthSampler, projTexCoord + uoffset - voffset ).x, + tex2D( DepthSampler, projTexCoord - uoffset + voffset ).x, + tex2D( DepthSampler, projTexCoord - uoffset - voffset ).x ); + +# if ( defined( REVERSE_DEPTH_ON_X360 ) ) + { + flashlightDepth = 1.0f - flashlightDepth; + } +# endif + + float shadowed = 0.0f; + float z = texCoord.z/texCoord.w; + float4 dz = float4(z,z,z,z) - (flashlightDepth + float4( g_flShadowBias, g_flShadowBias, g_flShadowBias, g_flShadowBias)); + float4 shadow = float4(0.25f,0.25f,0.25f,0.25f); + + if( dz.x <= 0.0f ) + shadowed += shadow.x; + if( dz.y <= 0.0f ) + shadowed += shadow.y; + if( dz.z <= 0.0f ) + shadowed += shadow.z; + if( dz.w <= 0.0f ) + shadowed += shadow.w; + + return shadowed; +} + + +float DoShadowNvidiaRAWZOneTap( sampler DepthSampler, const float4 shadowMapPos ) +{ + float ooW = 1.0f / shadowMapPos.w; // 1 / w + float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once + + float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter + float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space + + float fDepth = dot(tex2D(DepthSampler, shadowMapCenter).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); + + return fDepth > objDepth; +} + + +float DoShadowNvidiaRAWZ( sampler DepthSampler, const float4 shadowMapPos ) +{ + float fE = 1.0f / 512.0f; // Epsilon + + float ooW = 1.0f / shadowMapPos.w; // 1 / w + float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once + + float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter + float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space + + float4 vDepths; + vDepths.x = dot(tex2D(DepthSampler, shadowMapCenter + float2( fE, fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); + vDepths.y = dot(tex2D(DepthSampler, shadowMapCenter + float2( -fE, fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); + vDepths.z = dot(tex2D(DepthSampler, shadowMapCenter + float2( fE, -fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); + vDepths.w = dot(tex2D(DepthSampler, shadowMapCenter + float2( -fE, -fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); + + return dot(vDepths > objDepth.xxxx, float4(0.25, 0.25, 0.25, 0.25)); +} + + +float DoShadowNvidiaCheap( sampler DepthSampler, const float4 shadowMapPos ) +{ + float fTexelEpsilon = 1.0f / 1024.0f; + + float ooW = 1.0f / shadowMapPos.w; // 1 / w + float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once + + float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter + float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space + + float4 vTaps; + vTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, fTexelEpsilon), objDepth, 1 ) ).x; + vTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, fTexelEpsilon), objDepth, 1 ) ).x; + vTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, -fTexelEpsilon), objDepth, 1 ) ).x; + vTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, -fTexelEpsilon), objDepth, 1 ) ).x; + + return dot(vTaps, float4(0.25, 0.25, 0.25, 0.25)); +} + +float DoShadowNvidiaPCF3x3Box( sampler DepthSampler, const float4 shadowMapPos ) +{ + float fTexelEpsilon = 1.0f / 1024.0f; + + float ooW = 1.0f / shadowMapPos.w; // 1 / w + float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once + + float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter + float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space + + float4 vOneTaps; + vOneTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, fTexelEpsilon ), objDepth, 1 ) ).x; + vOneTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, fTexelEpsilon ), objDepth, 1 ) ).x; + vOneTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, -fTexelEpsilon ), objDepth, 1 ) ).x; + vOneTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, -fTexelEpsilon ), objDepth, 1 ) ).x; + float flOneTaps = dot( vOneTaps, float4(1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f)); + + float4 vTwoTaps; + vTwoTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, 0 ), objDepth, 1 ) ).x; + vTwoTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, 0 ), objDepth, 1 ) ).x; + vTwoTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTexelEpsilon ), objDepth, 1 ) ).x; + vTwoTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTexelEpsilon ), objDepth, 1 ) ).x; + float flTwoTaps = dot( vTwoTaps, float4(1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f)); + + float flCenterTap = tex2Dproj( DepthSampler, float4( shadowMapCenter, objDepth, 1 ) ).x * (1.0f / 9.0f); + + // Sum all 9 Taps + return flOneTaps + flTwoTaps + flCenterTap; +} + + +// +// 1 4 7 4 1 +// 4 20 33 20 4 +// 7 33 55 33 7 +// 4 20 33 20 4 +// 1 4 7 4 1 +// +float DoShadowNvidiaPCF5x5Gaussian( sampler DepthSampler, const float4 shadowMapPos ) +{ + float fEpsilon = 1.0f / 512.0f; + float fTwoEpsilon = 2.0f * fEpsilon; + + float ooW = 1.0f / shadowMapPos.w; // 1 / w + float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once + + float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter + float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space + + float4 vOneTaps; + vOneTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x; + vOneTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x; + vOneTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x; + vOneTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x; + float flOneTaps = dot( vOneTaps, float4(1.0f / 331.0f, 1.0f / 331.0f, 1.0f / 331.0f, 1.0f / 331.0f)); + + float4 vSevenTaps; + vSevenTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, 0 ), objDepth, 1 ) ).x; + vSevenTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, 0 ), objDepth, 1 ) ).x; + vSevenTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTwoEpsilon ), objDepth, 1 ) ).x; + vSevenTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTwoEpsilon ), objDepth, 1 ) ).x; + float flSevenTaps = dot( vSevenTaps, float4( 7.0f / 331.0f, 7.0f / 331.0f, 7.0f / 331.0f, 7.0f / 331.0f ) ); + + float4 vFourTapsA, vFourTapsB; + vFourTapsA.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, fEpsilon ), objDepth, 1 ) ).x; + vFourTapsA.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x; + vFourTapsA.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x; + vFourTapsA.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, fEpsilon ), objDepth, 1 ) ).x; + vFourTapsB.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, -fEpsilon ), objDepth, 1 ) ).x; + vFourTapsB.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x; + vFourTapsB.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x; + vFourTapsB.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, -fEpsilon ), objDepth, 1 ) ).x; + float flFourTapsA = dot( vFourTapsA, float4( 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f ) ); + float flFourTapsB = dot( vFourTapsB, float4( 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f ) ); + + float4 v20Taps; + v20Taps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, fEpsilon ), objDepth, 1 ) ).x; + v20Taps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, fEpsilon ), objDepth, 1 ) ).x; + v20Taps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, -fEpsilon ), objDepth, 1 ) ).x; + v20Taps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, -fEpsilon ), objDepth, 1 ) ).x; + float fl20Taps = dot( v20Taps, float4(20.0f / 331.0f, 20.0f / 331.0f, 20.0f / 331.0f, 20.0f / 331.0f)); + + float4 v33Taps; + v33Taps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, 0 ), objDepth, 1 ) ).x; + v33Taps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, 0 ), objDepth, 1 ) ).x; + v33Taps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fEpsilon ), objDepth, 1 ) ).x; + v33Taps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fEpsilon ), objDepth, 1 ) ).x; + float fl33Taps = dot( v33Taps, float4(33.0f / 331.0f, 33.0f / 331.0f, 33.0f / 331.0f, 33.0f / 331.0f)); + + float flCenterTap = tex2Dproj( DepthSampler, float4( shadowMapCenter, objDepth, 1 ) ).x * (55.0f / 331.0f); + + // Sum all 25 Taps + return flOneTaps + flSevenTaps + +flFourTapsA + flFourTapsB + fl20Taps + fl33Taps + flCenterTap; +} + + +float DoShadowATICheap( sampler DepthSampler, const float4 shadowMapPos ) +{ + float2 shadowMapCenter = shadowMapPos.xy/shadowMapPos.w; + float objDepth = shadowMapPos.z / shadowMapPos.w; + float fSampleDepth = tex2D( DepthSampler, shadowMapCenter ).x; + + objDepth = min( objDepth, 0.99999 ); //HACKHACK: On 360, surfaces at or past the far flashlight plane have an abrupt cutoff. This is temp until a smooth falloff is implemented + + return fSampleDepth > objDepth; +} + + +// Poisson disc, randomly rotated at different UVs +float DoShadowPoisson16Sample( sampler DepthSampler, sampler RandomRotationSampler, const float3 vProjCoords, const float2 vScreenPos, const float4 vShadowTweaks, bool bNvidiaHardwarePCF, bool bFetch4 ) +{ + float2 vPoissonOffset[8] = { float2( 0.3475f, 0.0042f ), + float2( 0.8806f, 0.3430f ), + float2( -0.0041f, -0.6197f ), + float2( 0.0472f, 0.4964f ), + float2( -0.3730f, 0.0874f ), + float2( -0.9217f, -0.3177f ), + float2( -0.6289f, 0.7388f ), + float2( 0.5744f, -0.7741f ) }; + + float flScaleOverMapSize = vShadowTweaks.x * 2; // Tweak parameters to shader + float2 vNoiseOffset = vShadowTweaks.zw; + float4 vLightDepths = 0, accum = 0.0f; + float2 rotOffset = 0; + + float2 shadowMapCenter = vProjCoords.xy; // Center of shadow filter + float objDepth = min( vProjCoords.z, 0.99999 ); // Object depth in shadow space + + // 2D Rotation Matrix setup + float3 RMatTop = 0, RMatBottom = 0; +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + RMatTop.xy = tex2D( RandomRotationSampler, cFlashlightScreenScale.xy * (vScreenPos * 0.5 + 0.5) + vNoiseOffset) * 2.0 - 1.0; + RMatBottom.xy = float2(-1.0, 1.0) * RMatTop.yx; // 2x2 rotation matrix in 4-tuple +#endif + + RMatTop *= flScaleOverMapSize; // Scale up kernel while accounting for texture resolution + RMatBottom *= flScaleOverMapSize; + + RMatTop.z = shadowMapCenter.x; // To be added in d2adds generated below + RMatBottom.z = shadowMapCenter.y; + + float fResult = 0.0f; + + if ( bNvidiaHardwarePCF ) + { + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[0].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[0].xy) + RMatBottom.z; + vLightDepths.x += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[1].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[1].xy) + RMatBottom.z; + vLightDepths.y += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[2].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[2].xy) + RMatBottom.z; + vLightDepths.z += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[3].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[3].xy) + RMatBottom.z; + vLightDepths.w += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4].xy) + RMatBottom.z; + vLightDepths.x += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[5].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[5].xy) + RMatBottom.z; + vLightDepths.y += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[6].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[6].xy) + RMatBottom.z; + vLightDepths.z += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[7].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[7].xy) + RMatBottom.z; + vLightDepths.w += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; + + fResult = dot( vLightDepths, float4( 0.25, 0.25, 0.25, 0.25) ); + } + else if ( bFetch4 ) + { +/* + +TODO: Fix this contact hardening stuff + + float flNumCloserSamples = 1; + float flAccumulatedCloserSamples = objDepth; + float4 vBlockerDepths; + + // First, search for blockers + for( int j=0; j<8; j++ ) + { + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[j].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[j].xy) + RMatBottom.z; + vBlockerDepths = tex2D( DepthSampler, rotOffset.xy ); + + // Which samples are closer than the pixel we're rendering? + float4 vCloserSamples = (vBlockerDepths < objDepth.xxxx ); // Binary comparison results + flNumCloserSamples += dot( vCloserSamples, float4(1, 1, 1, 1) ); // How many samples are closer than receiver? + flAccumulatedCloserSamples += dot (vCloserSamples, vBlockerDepths ); // Total depths from samples closer than receiver + } + + float flBlockerDepth = flAccumulatedCloserSamples / flNumCloserSamples; + float flContactHardeningScale = (objDepth - flBlockerDepth) / flBlockerDepth; + + // Scale the kernel + RMatTop.xy *= flContactHardeningScale; + RMatBottom.xy *= flContactHardeningScale; +*/ + + for( int i=0; i<8; i++ ) + { + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[i].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[i].xy) + RMatBottom.z; + vLightDepths = tex2D( DepthSampler, rotOffset.xy ); + accum += (vLightDepths > objDepth.xxxx); + } + + fResult = dot( accum, float4( 1.0f/32.0f, 1.0f/32.0f, 1.0f/32.0f, 1.0f/32.0f) ); + } + else // ATI vanilla hardware shadow mapping + { + for( int i=0; i<2; i++ ) + { + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+0].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+0].xy) + RMatBottom.z; + vLightDepths.x = tex2D( DepthSampler, rotOffset.xy ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+1].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+1].xy) + RMatBottom.z; + vLightDepths.y = tex2D( DepthSampler, rotOffset.xy ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+2].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+2].xy) + RMatBottom.z; + vLightDepths.z = tex2D( DepthSampler, rotOffset.xy ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+3].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+3].xy) + RMatBottom.z; + vLightDepths.w = tex2D( DepthSampler, rotOffset.xy ).x; + + accum += (vLightDepths > objDepth.xxxx); + } + + fResult = dot( accum, float4( 0.125, 0.125, 0.125, 0.125) ); + } + + return fResult; +} + +#if defined( _X360 ) + +// Poisson disc, randomly rotated at different UVs +float DoShadow360Simple( sampler DepthSampler, const float3 vProjCoords ) +{ + float fLOD; + float2 shadowMapCenter = vProjCoords.xy; // Center of shadow filter + float objDepth = min( vProjCoords.z, 0.99999 ); // Object depth in shadow space + +#if defined( REVERSE_DEPTH_ON_X360 ) + objDepth = 1.0f - objDepth; +#endif + + float4 vSampledDepths, vWeights; + + asm { + getCompTexLOD2D fLOD.x, shadowMapCenter.xy, DepthSampler, AnisoFilter=max16to1 + setTexLOD fLOD.x + + tfetch2D vSampledDepths.x___, shadowMapCenter, DepthSampler, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths._x__, shadowMapCenter, DepthSampler, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths.__x_, shadowMapCenter, DepthSampler, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths.___x, shadowMapCenter, DepthSampler, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + + getWeights2D vWeights, shadowMapCenter.xy, DepthSampler, MagFilter=linear, MinFilter=linear, UseComputedLOD=false, UseRegisterLOD=true + }; + + vWeights = float4( (1-vWeights.x)*(1-vWeights.y), vWeights.x*(1-vWeights.y), (1-vWeights.x)*vWeights.y, vWeights.x*vWeights.y ); + +#if defined( REVERSE_DEPTH_ON_X360 ) + float4 vCompare = (vSampledDepths < objDepth.xxxx); +#else + float4 vCompare = (vSampledDepths > objDepth.xxxx); +#endif + + return dot( vCompare, vWeights ); +} + + +float Do360PCFFetch( sampler DepthSampler, float2 tc, float objDepth ) +{ + float fLOD; + float4 vSampledDepths, vWeights; + + asm { + getCompTexLOD2D fLOD.x, tc.xy, DepthSampler, AnisoFilter=max16to1 + setTexLOD fLOD.x + + tfetch2D vSampledDepths.x___, tc, DepthSampler, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths._x__, tc, DepthSampler, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths.__x_, tc, DepthSampler, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths.___x, tc, DepthSampler, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + + getWeights2D vWeights, tc.xy, DepthSampler, MagFilter=linear, MinFilter=linear, UseComputedLOD=false, UseRegisterLOD=true + }; + + vWeights = float4( (1-vWeights.x)*(1-vWeights.y), vWeights.x*(1-vWeights.y), (1-vWeights.x)*vWeights.y, vWeights.x*vWeights.y ); + +#if defined( REVERSE_DEPTH_ON_X360 ) + float4 vCompare = (vSampledDepths < objDepth.xxxx); +#else + float4 vCompare = (vSampledDepths > objDepth.xxxx); +#endif + + return dot( vCompare, vWeights ); +} + + + +float Do360NearestFetch( sampler DepthSampler, float2 tc, float objDepth ) +{ + float fLOD; + float4 vSampledDepth; + + asm { + getCompTexLOD2D fLOD.x, tc.xy, DepthSampler, AnisoFilter=max16to1 + setTexLOD fLOD.x + + tfetch2D vSampledDepth.x___, tc, DepthSampler, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + }; + +#if defined( REVERSE_DEPTH_ON_X360 ) + return (vSampledDepth.x < objDepth.x); +#else + return (vSampledDepth.x > objDepth.x); +#endif + +} + + +float AmountShadowed_8Tap_360( sampler DepthSampler, float2 tc, float objDepth ) +{ + float fLOD; + float4 vSampledDepthsA, vSampledDepthsB; + + // Optimal 8 rooks pattern to get an idea about whether we're at a penumbra or not + // From [Kallio07] "Scanline Edge-Flag Algorithm for Antialiasing" + // + // +---+---+---+---+---+---+---+---+ + // | | | | | | o | | | + // +---+---+---+---+---+---+---+---+ + // | o | | | | | | | | + // +---+---+---+---+---+---+---+---+ + // | | | | o | | | | | + // +---+---+---+---+---+---+---+---+ + // | | | | | | | o | | + // +---+---+---+---+---+---+---+---+ + // | | o | | | | | | | + // +---+---+---+---+---+---+---+---+ + // | | | | | o | | | | + // +---+---+---+---+---+---+---+---+ + // | | | | | | | | o | + // +---+---+---+---+---+---+---+---+ + // | | | o | | | | | | + // +---+---+---+---+---+---+---+---+ + // + asm { + getCompTexLOD2D fLOD.x, tc.xy, DepthSampler, AnisoFilter=max16to1 + setTexLOD fLOD.x + + tfetch2D vSampledDepthsA.x___, tc, DepthSampler, OffsetX = -2.0, OffsetY = -1.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepthsA._x__, tc, DepthSampler, OffsetX = -1.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepthsA.__x_, tc, DepthSampler, OffsetX = -1.0, OffsetY = 2.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepthsA.___x, tc, DepthSampler, OffsetX = -0.5, OffsetY = -1.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + + tfetch2D vSampledDepthsB.x___, tc, DepthSampler, OffsetX = 0.5, OffsetY = 1.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepthsB._x__, tc, DepthSampler, OffsetX = 1.0, OffsetY = -2.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepthsB.__x_, tc, DepthSampler, OffsetX = 1.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepthsB.___x, tc, DepthSampler, OffsetX = 2.0, OffsetY = 1.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + }; + +#if defined( REVERSE_DEPTH_ON_X360 ) + float4 vCompareA = (vSampledDepthsA < objDepth.xxxx); + float4 vCompareB = (vSampledDepthsB < objDepth.xxxx); +#else + float4 vCompareA = (vSampledDepthsA > objDepth.xxxx); + float4 vCompareB = (vSampledDepthsB > objDepth.xxxx); +#endif + + return dot( vCompareA, float4(0.125,0.125,0.125,0.125) ) + dot( vCompareB, float4(0.125,0.125,0.125,0.125) ); +} + + +float AmountShadowed_4Tap_360( sampler DepthSampler, float2 tc, float objDepth ) +{ + float fLOD; + float4 vSampledDepths; + + // Rotated grid pattern to get an idea about whether we're at a penumbra or not + asm { + getCompTexLOD2D fLOD.x, tc.xy, DepthSampler, AnisoFilter=max16to1 + setTexLOD fLOD.x + + tfetch2D vSampledDepths.x___, tc, DepthSampler, OffsetX = -1.0, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths._x__, tc, DepthSampler, OffsetX = -0.5, OffsetY = -1.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths.__x_, tc, DepthSampler, OffsetX = 0.5, OffsetY = 1.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths.___x, tc, DepthSampler, OffsetX = 1.0, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + }; + +#if defined( REVERSE_DEPTH_ON_X360 ) + float4 vCompare = (vSampledDepths < objDepth.xxxx); +#else + float4 vCompare = (vSampledDepths > objDepth.xxxx); +#endif + + return dot( vCompare, float4(0.25,0.25,0.25,0.25) ); +} + +// Poisson disc, randomly rotated at different UVs +float DoShadowPoisson360( sampler DepthSampler, sampler RandomRotationSampler, const float3 vProjCoords, const float2 vScreenPos, const float4 vShadowTweaks ) +{ + float2 vPoissonOffset[8] = { float2( 0.3475f, 0.0042f ), float2( 0.8806f, 0.3430f ), + float2( -0.0041f, -0.6197f ), float2( 0.0472f, 0.4964f ), + float2( -0.3730f, 0.0874f ), float2( -0.9217f, -0.3177f ), + float2( -0.6289f, 0.7388f ), float2( 0.5744f, -0.7741f ) }; + + float2 shadowMapCenter = vProjCoords.xy; // Center of shadow filter + float objDepth = min( vProjCoords.z, 0.99999 ); // Object depth in shadow space + +#if defined( REVERSE_DEPTH_ON_X360 ) + objDepth = 1.0f - objDepth; +#endif + + float fAmountShadowed = AmountShadowed_4Tap_360( DepthSampler, shadowMapCenter, objDepth ); + + if ( fAmountShadowed >= 1.0f ) // Fully in light + { + return 1.0f; + } + else // Do the expensive filtering since we're at least partially shadowed + { + float flScaleOverMapSize = 1.7f / 512.0f; // Tweak parameters to shader + + // 2D Rotation Matrix setup + float3 RMatTop = 0, RMatBottom = 0; +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + RMatTop.xy = tex2D( RandomRotationSampler, cFlashlightScreenScale.xy * (vScreenPos * 0.5 + 0.5)) * 2.0 - 1.0; + RMatBottom.xy = float2(-1.0, 1.0) * RMatTop.yx; // 2x2 rotation matrix in 4-tuple +#endif + + RMatTop *= flScaleOverMapSize; // Scale up kernel while accounting for texture resolution + RMatBottom *= flScaleOverMapSize; + RMatTop.z = shadowMapCenter.x; // To be added in d2adds generated below + RMatBottom.z = shadowMapCenter.y; + float2 rotOffset = float2(0,0); + float4 vAccum = 0; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[0].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[0].xy) + RMatBottom.z; + vAccum.x = Do360NearestFetch( DepthSampler, rotOffset, objDepth ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[1].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[1].xy) + RMatBottom.z; + vAccum.y = Do360NearestFetch( DepthSampler, rotOffset, objDepth ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[2].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[2].xy) + RMatBottom.z; + vAccum.z = Do360NearestFetch( DepthSampler, rotOffset, objDepth ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[3].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[3].xy) + RMatBottom.z; + vAccum.w = Do360NearestFetch( DepthSampler, rotOffset, objDepth ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4].xy) + RMatBottom.z; + vAccum.x += Do360NearestFetch( DepthSampler, rotOffset, objDepth ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[5].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[5].xy) + RMatBottom.z; + vAccum.y += Do360NearestFetch( DepthSampler, rotOffset, objDepth ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[6].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[6].xy) + RMatBottom.z; + vAccum.z += Do360NearestFetch( DepthSampler, rotOffset, objDepth ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[7].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[7].xy) + RMatBottom.z; + vAccum.w += Do360NearestFetch( DepthSampler, rotOffset, objDepth ); + + return dot( vAccum, float4( 0.25, 0.25, 0.25, 0.25) ); + } +} + +#endif // _X360 + + +float DoFlashlightShadow( sampler DepthSampler, sampler RandomRotationSampler, float3 vProjCoords, float2 vScreenPos, int nShadowLevel, float4 vShadowTweaks, bool bAllowHighQuality ) +{ + float flShadow = 1.0f; + +#if !defined( _X360 ) //PC + if( nShadowLevel == NVIDIA_PCF_POISSON ) + flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, true, false ); + else if( nShadowLevel == ATI_NOPCF ) + flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, false, false ); + else if( nShadowLevel == ATI_NO_PCF_FETCH4 ) + flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, false, true ); + + return flShadow; +#else + + // Compile-time switch for shaders which allow high quality modes on 360 + if ( bAllowHighQuality ) + { + // Static control flow switch for shadow quality. Some non-interactive sequences use the high quality path + if ( g_bHighQualityShadows ) + { + flShadow = DoShadowPoisson360( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks ); + } + else + { + flShadow = DoShadow360Simple( DepthSampler, vProjCoords ); + } + } + else + { + flShadow = DoShadow360Simple( DepthSampler, vProjCoords ); + } + + return flShadow; + +#endif +} + +float3 SpecularLight( const float3 vWorldNormal, const float3 vLightDir, const float fSpecularExponent, + const float3 vEyeDir, const bool bDoSpecularWarp, in sampler specularWarpSampler, float fFresnel ) +{ + float3 result = float3(0.0f, 0.0f, 0.0f); + + //float3 vReflect = reflect( -vEyeDir, vWorldNormal ); + float3 vReflect = 2 * vWorldNormal * dot( vWorldNormal , vEyeDir ) - vEyeDir; // Reflect view through normal + float3 vSpecular = saturate(dot( vReflect, vLightDir )); // L.R (use half-angle instead?) + vSpecular = pow( vSpecular.x, fSpecularExponent ); // Raise to specular power + + // Optionally warp as function of scalar specular and fresnel + if ( bDoSpecularWarp ) + vSpecular *= tex2D( specularWarpSampler, float2(vSpecular.x, fFresnel) ); // Sample at { (L.R)^k, fresnel } + + return vSpecular; +} + +void DoSpecularFlashlight( float3 flashlightPos, float3 worldPos, float4 flashlightSpacePosition, float3 worldNormal, + float3 attenuationFactors, float farZ, sampler FlashlightSampler, sampler FlashlightDepthSampler, sampler RandomRotationSampler, + int nShadowLevel, bool bDoShadows, bool bAllowHighQuality, const float2 vScreenPos, const float fSpecularExponent, const float3 vEyeDir, + const bool bDoSpecularWarp, sampler specularWarpSampler, float fFresnel, float4 vShadowTweaks, + + // Outputs of this shader...separate shadowed diffuse and specular from the flashlight + out float3 diffuseLighting, out float3 specularLighting ) +{ + float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; + float3 flashlightColor = float3(1,1,1); + +#if ( defined( _X360 ) ) + + float3 ltz = vProjCoords.xyz < float3( 0.0f, 0.0f, 0.0f ); + float3 gto = vProjCoords.xyz > float3( 1.0f, 1.0f, 1.0f ); + + [branch] + if ( dot(ltz + gto, float3(1,1,1)) > 0 ) + { + clip(-1); + diffuseLighting = specularLighting = float3(0,0,0); + return; + } + else + { + flashlightColor = tex2D( FlashlightSampler, vProjCoords ); + + [branch] + if ( dot(flashlightColor.xyz, float3(1,1,1)) <= 0 ) + { + clip(-1); + diffuseLighting = specularLighting = float3(0,0,0); + return; + } + } +#else + flashlightColor = tex2D( FlashlightSampler, vProjCoords ); +#endif + + +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + flashlightColor *= cFlashlightColor.xyz; // Flashlight color +#endif + + float3 delta = flashlightPos - worldPos; + float3 L = normalize( delta ); + float distSquared = dot( delta, delta ); + float dist = sqrt( distSquared ); + + float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); + + // Attenuation for light and to fade out shadow over distance + float fAtten = saturate( dot( attenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); + + // Shadowing and coloring terms +#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) + if ( bDoShadows ) + { + float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, nShadowLevel, vShadowTweaks, bAllowHighQuality ); + float flAttenuated = lerp( flShadow, 1.0f, vShadowTweaks.y ); // Blend between fully attenuated and not attenuated + flShadow = saturate( lerp( flAttenuated, flShadow, fAtten ) ); // Blend between shadow and above, according to light attenuation + flashlightColor *= flShadow; // Shadow term + } +#endif + + diffuseLighting = fAtten; +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + diffuseLighting *= saturate( dot( L.xyz, worldNormal.xyz ) + flFlashlightNoLambertValue ); // Lambertian term +#else + diffuseLighting *= saturate( dot( L.xyz, worldNormal.xyz ) ); // Lambertian (not Half-Lambert) term +#endif + diffuseLighting *= flashlightColor; + diffuseLighting *= endFalloffFactor; + + // Specular term (masked by diffuse) + specularLighting = diffuseLighting * SpecularLight ( worldNormal, L, fSpecularExponent, vEyeDir, bDoSpecularWarp, specularWarpSampler, fFresnel ); +} + +// Diffuse only version +float3 DoFlashlight( float3 flashlightPos, float3 worldPos, float4 flashlightSpacePosition, float3 worldNormal, + float3 attenuationFactors, float farZ, sampler FlashlightSampler, sampler FlashlightDepthSampler, + sampler RandomRotationSampler, int nShadowLevel, bool bDoShadows, bool bAllowHighQuality, + const float2 vScreenPos, bool bClip, float4 vShadowTweaks = float4(3/1024.0f, 0.0005f, 0.0f, 0.0f), bool bHasNormal = true ) +{ + float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; + float3 flashlightColor = float3(1,1,1); + +#if ( defined( _X360 ) ) + + float3 ltz = vProjCoords.xyz < float3( 0.0f, 0.0f, 0.0f ); + float3 gto = vProjCoords.xyz > float3( 1.0f, 1.0f, 1.0f ); + + [branch] + if ( dot(ltz + gto, float3(1,1,1)) > 0 ) + { + if ( bClip ) + { + clip(-1); + } + return float3(0,0,0); + } + else + { + flashlightColor = tex2D( FlashlightSampler, vProjCoords ); + + [branch] + if ( dot(flashlightColor.xyz, float3(1,1,1)) <= 0 ) + { + if ( bClip ) + { + clip(-1); + } + return float3(0,0,0); + } + } +#else + flashlightColor = tex2D( FlashlightSampler, vProjCoords ); +#endif + +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + flashlightColor *= cFlashlightColor.xyz; // Flashlight color +#endif + + float3 delta = flashlightPos - worldPos; + float3 L = normalize( delta ); + float distSquared = dot( delta, delta ); + float dist = sqrt( distSquared ); + + float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); + + // Attenuation for light and to fade out shadow over distance + float fAtten = saturate( dot( attenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); + + // Shadowing and coloring terms +#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) + if ( bDoShadows ) + { + float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, nShadowLevel, vShadowTweaks, bAllowHighQuality ); + float flAttenuated = lerp( flShadow, 1.0f, vShadowTweaks.y ); // Blend between fully attenuated and not attenuated + flShadow = saturate( lerp( flAttenuated, flShadow, fAtten ) ); // Blend between shadow and above, according to light attenuation + flashlightColor *= flShadow; // Shadow term + } +#endif + + float3 diffuseLighting = fAtten; + + float flLDotWorldNormal; + if ( bHasNormal ) + { + flLDotWorldNormal = dot( L.xyz, worldNormal.xyz ); + } + else + { + flLDotWorldNormal = 1.0f; + } + +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + diffuseLighting *= saturate( flLDotWorldNormal + flFlashlightNoLambertValue ); // Lambertian term +#else + diffuseLighting *= saturate( flLDotWorldNormal ); // Lambertian (not Half-Lambert) term +#endif + + diffuseLighting *= flashlightColor; + diffuseLighting *= endFalloffFactor; + + return diffuseLighting; +} + +#endif //#ifndef COMMON_FLASHLIGHT_FXC_H_ diff --git a/mp/src/materialsystem/stdshaders/common_fxc.h b/mp/src/materialsystem/stdshaders/common_fxc.h index b81c9a46..2103b3f9 100644 --- a/mp/src/materialsystem/stdshaders/common_fxc.h +++ b/mp/src/materialsystem/stdshaders/common_fxc.h @@ -1,326 +1,326 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -#ifndef COMMON_FXC_H_ -#define COMMON_FXC_H_ - -#include "common_pragmas.h" -#include "common_hlsl_cpp_consts.h" - -#ifdef NV3X -# define HALF half -# define HALF2 half2 -# define HALF3 half3 -# define HALF4 half4 -# define HALF3x3 half3x3 -# define HALF3x4 half3x4 -# define HALF4x3 half4x3 -# define HALF_CONSTANT( _constant ) ((HALF)_constant) -#else -# define HALF float -# define HALF2 float2 -# define HALF3 float3 -# define HALF4 float4 -# define HALF3x3 float3x3 -# define HALF3x4 float3x4 -# define HALF4x3 float4x3 -# define HALF_CONSTANT( _constant ) _constant -#endif - -// This is where all common code for both vertex and pixel shaders. -#define OO_SQRT_3 0.57735025882720947f -static const HALF3 bumpBasis[3] = { - HALF3( 0.81649661064147949f, 0.0f, OO_SQRT_3 ), - HALF3( -0.40824833512306213f, 0.70710676908493042f, OO_SQRT_3 ), - HALF3( -0.40824821591377258f, -0.7071068286895752f, OO_SQRT_3 ) -}; -static const HALF3 bumpBasisTranspose[3] = { - HALF3( 0.81649661064147949f, -0.40824833512306213f, -0.40824833512306213f ), - HALF3( 0.0f, 0.70710676908493042f, -0.7071068286895752f ), - HALF3( OO_SQRT_3, OO_SQRT_3, OO_SQRT_3 ) -}; - -#if defined( _X360 ) -#define REVERSE_DEPTH_ON_X360 //uncomment to use D3DFMT_D24FS8 with an inverted depth viewport for better performance. Keep this in sync with the same named #define in public/shaderapi/shareddefs.h -//Note that the reversal happens in the viewport. So ONLY reading back from a depth texture should be affected. Projected math is unaffected. -#endif - -HALF3 CalcReflectionVectorNormalized( HALF3 normal, HALF3 eyeVector ) -{ - // FIXME: might be better of normalizing with a normalizing cube map and - // get rid of the dot( normal, normal ) - // compute reflection vector r = 2 * ((n dot v)/(n dot n)) n - v - return 2.0 * ( dot( normal, eyeVector ) / dot( normal, normal ) ) * normal - eyeVector; -} - -HALF3 CalcReflectionVectorUnnormalized( HALF3 normal, HALF3 eyeVector ) -{ - // FIXME: might be better of normalizing with a normalizing cube map and - // get rid of the dot( normal, normal ) - // compute reflection vector r = 2 * ((n dot v)/(n dot n)) n - v - // multiply all values through by N.N. uniformly scaling reflection vector won't affect result - // since it is used in a cubemap lookup - return (2.0*(dot( normal, eyeVector ))*normal) - (dot( normal, normal )*eyeVector); -} - -float3 HuePreservingColorClamp( float3 c ) -{ - // Get the max of all of the color components and a specified maximum amount - float maximum = max( max( c.x, c.y ), max( c.z, 1.0f ) ); - - return (c / maximum); -} - -HALF3 HuePreservingColorClamp( HALF3 c, HALF maxVal ) -{ - // Get the max of all of the color components and a specified maximum amount - float maximum = max( max( c.x, c.y ), max( c.z, maxVal ) ); - return (c * ( maxVal / maximum ) ); -} - -#if (AA_CLAMP==1) -HALF2 ComputeLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord ) -{ - HALF2 result = saturate(Lightmap1and2Coord.xy) * Lightmap1and2Coord.wz * 0.99; - result += Lightmap3Coord; - return result; -} - -void ComputeBumpedLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord, - out HALF2 bumpCoord1, - out HALF2 bumpCoord2, - out HALF2 bumpCoord3 ) -{ - HALF2 result = saturate(Lightmap1and2Coord.xy) * Lightmap1and2Coord.wz * 0.99; - result += Lightmap3Coord; - bumpCoord1 = result + HALF2(Lightmap1and2Coord.z, 0); - bumpCoord2 = result + 2*HALF2(Lightmap1and2Coord.z, 0); - bumpCoord3 = result + 3*HALF2(Lightmap1and2Coord.z, 0); -} -#else -HALF2 ComputeLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord ) -{ - return Lightmap1and2Coord.xy; -} - -void ComputeBumpedLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord, - out HALF2 bumpCoord1, - out HALF2 bumpCoord2, - out HALF2 bumpCoord3 ) -{ - bumpCoord1 = Lightmap1and2Coord.xy; - bumpCoord2 = Lightmap1and2Coord.wz; // reversed order!!! - bumpCoord3 = Lightmap3Coord.xy; -} -#endif - -// Versions of matrix multiply functions which force HLSL compiler to explictly use DOTs, -// not giving it the option of using MAD expansion. In a perfect world, the compiler would -// always pick the best strategy, and these shouldn't be needed.. but.. well.. umm.. -// -// lorenmcq - -float3 mul3x3(float3 v, float3x3 m) -{ -#if !defined( _X360 ) - return float3(dot(v, transpose(m)[0]), dot(v, transpose(m)[1]), dot(v, transpose(m)[2])); -#else - // xbox360 fxc.exe (new back end) borks with transposes, generates bad code - return mul( v, m ); -#endif -} - -float3 mul4x3(float4 v, float4x3 m) -{ -#if !defined( _X360 ) - return float3(dot(v, transpose(m)[0]), dot(v, transpose(m)[1]), dot(v, transpose(m)[2])); -#else - // xbox360 fxc.exe (new back end) borks with transposes, generates bad code - return mul( v, m ); -#endif -} - -float3 DecompressHDR( float4 input ) -{ - return input.rgb * input.a * MAX_HDR_OVERBRIGHT; -} - -float4 CompressHDR( float3 input ) -{ - // FIXME: want to use min so that we clamp to white, but what happens if we - // have an albedo component that's less than 1/MAX_HDR_OVERBRIGHT? - // float fMax = max( max( color.r, color.g ), color.b ); - float4 output; - float fMax = min( min( input.r, input.g ), input.b ); - if( fMax > 1.0f ) - { - float oofMax = 1.0f / fMax; - output.rgb = oofMax * input.rgb; - output.a = min( fMax / MAX_HDR_OVERBRIGHT, 1.0f ); - } - else - { - output.rgb = input.rgb; - output.a = 0.0f; - } - return output; -} - - -float3 LinearToGamma( const float3 f3linear ) -{ - return pow( f3linear, 1.0f / 2.2f ); -} - -float4 LinearToGamma( const float4 f4linear ) -{ - return float4( pow( f4linear.xyz, 1.0f / 2.2f ), f4linear.w ); -} - -float LinearToGamma( const float f1linear ) -{ - return pow( f1linear, 1.0f / 2.2f ); -} - -float3 GammaToLinear( const float3 gamma ) -{ - return pow( gamma, 2.2f ); -} - -float4 GammaToLinear( const float4 gamma ) -{ - return float4( pow( gamma.xyz, 2.2f ), gamma.w ); -} - -float GammaToLinear( const float gamma ) -{ - return pow( gamma, 2.2f ); -} - -// These two functions use the actual sRGB math -float SrgbGammaToLinear( float flSrgbGammaValue ) -{ - float x = saturate( flSrgbGammaValue ); - return ( x <= 0.04045f ) ? ( x / 12.92f ) : ( pow( ( x + 0.055f ) / 1.055f, 2.4f ) ); -} - -float SrgbLinearToGamma( float flLinearValue ) -{ - float x = saturate( flLinearValue ); - return ( x <= 0.0031308f ) ? ( x * 12.92f ) : ( 1.055f * pow( x, ( 1.0f / 2.4f ) ) ) - 0.055f; -} - -// These twofunctions use the XBox 360's exact piecewise linear algorithm -float X360GammaToLinear( float fl360GammaValue ) -{ - float flLinearValue; - - fl360GammaValue = saturate( fl360GammaValue ); - if ( fl360GammaValue < ( 96.0f / 255.0f ) ) - { - if ( fl360GammaValue < ( 64.0f / 255.0f ) ) - { - flLinearValue = fl360GammaValue * 255.0f; - } - else - { - flLinearValue = fl360GammaValue * ( 255.0f * 2.0f ) - 64.0f; - flLinearValue += floor( flLinearValue * ( 1.0f / 512.0f ) ); - } - } - else - { - if( fl360GammaValue < ( 192.0f / 255.0f ) ) - { - flLinearValue = fl360GammaValue * ( 255.0f * 4.0f ) - 256.0f; - flLinearValue += floor( flLinearValue * ( 1.0f / 256.0f ) ); - } - else - { - flLinearValue = fl360GammaValue * ( 255.0f * 8.0f ) - 1024.0f; - flLinearValue += floor( flLinearValue * ( 1.0f / 128.0f ) ); - } - } - - flLinearValue *= 1.0f / 1023.0f; - - flLinearValue = saturate( flLinearValue ); - return flLinearValue; -} - -float X360LinearToGamma( float flLinearValue ) -{ - float fl360GammaValue; - - flLinearValue = saturate( flLinearValue ); - if ( flLinearValue < ( 128.0f / 1023.0f ) ) - { - if ( flLinearValue < ( 64.0f / 1023.0f ) ) - { - fl360GammaValue = flLinearValue * ( 1023.0f * ( 1.0f / 255.0f ) ); - } - else - { - fl360GammaValue = flLinearValue * ( ( 1023.0f / 2.0f ) * ( 1.0f / 255.0f ) ) + ( 32.0f / 255.0f ); - } - } - else - { - if ( flLinearValue < ( 512.0f / 1023.0f ) ) - { - fl360GammaValue = flLinearValue * ( ( 1023.0f / 4.0f ) * ( 1.0f / 255.0f ) ) + ( 64.0f / 255.0f ); - } - else - { - fl360GammaValue = flLinearValue * ( ( 1023.0f /8.0f ) * ( 1.0f / 255.0f ) ) + ( 128.0f /255.0f ); // 1.0 -> 1.0034313725490196078431372549016 - if ( fl360GammaValue > 1.0f ) - { - fl360GammaValue = 1.0f; - } - } - } - - fl360GammaValue = saturate( fl360GammaValue ); - return fl360GammaValue; -} - -float SrgbGammaTo360Gamma( float flSrgbGammaValue ) -{ - float flLinearValue = SrgbGammaToLinear( flSrgbGammaValue ); - float fl360GammaValue = X360LinearToGamma( flLinearValue ); - return fl360GammaValue; -} - -float3 Vec3WorldToTangent( float3 iWorldVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal ) -{ - float3 vTangentVector; - vTangentVector.x = dot( iWorldVector.xyz, iWorldTangent.xyz ); - vTangentVector.y = dot( iWorldVector.xyz, iWorldBinormal.xyz ); - vTangentVector.z = dot( iWorldVector.xyz, iWorldNormal.xyz ); - return vTangentVector.xyz; // Return without normalizing -} - -float3 Vec3WorldToTangentNormalized( float3 iWorldVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal ) -{ - return normalize( Vec3WorldToTangent( iWorldVector, iWorldNormal, iWorldTangent, iWorldBinormal ) ); -} - -float3 Vec3TangentToWorld( float3 iTangentVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal ) -{ - float3 vWorldVector; - vWorldVector.xyz = iTangentVector.x * iWorldTangent.xyz; - vWorldVector.xyz += iTangentVector.y * iWorldBinormal.xyz; - vWorldVector.xyz += iTangentVector.z * iWorldNormal.xyz; - return vWorldVector.xyz; // Return without normalizing -} - -float3 Vec3TangentToWorldNormalized( float3 iTangentVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal ) -{ - return normalize( Vec3TangentToWorld( iTangentVector, iWorldNormal, iWorldTangent, iWorldBinormal ) ); -} - -#endif //#ifndef COMMON_FXC_H_ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_FXC_H_ +#define COMMON_FXC_H_ + +#include "common_pragmas.h" +#include "common_hlsl_cpp_consts.h" + +#ifdef NV3X +# define HALF half +# define HALF2 half2 +# define HALF3 half3 +# define HALF4 half4 +# define HALF3x3 half3x3 +# define HALF3x4 half3x4 +# define HALF4x3 half4x3 +# define HALF_CONSTANT( _constant ) ((HALF)_constant) +#else +# define HALF float +# define HALF2 float2 +# define HALF3 float3 +# define HALF4 float4 +# define HALF3x3 float3x3 +# define HALF3x4 float3x4 +# define HALF4x3 float4x3 +# define HALF_CONSTANT( _constant ) _constant +#endif + +// This is where all common code for both vertex and pixel shaders. +#define OO_SQRT_3 0.57735025882720947f +static const HALF3 bumpBasis[3] = { + HALF3( 0.81649661064147949f, 0.0f, OO_SQRT_3 ), + HALF3( -0.40824833512306213f, 0.70710676908493042f, OO_SQRT_3 ), + HALF3( -0.40824821591377258f, -0.7071068286895752f, OO_SQRT_3 ) +}; +static const HALF3 bumpBasisTranspose[3] = { + HALF3( 0.81649661064147949f, -0.40824833512306213f, -0.40824833512306213f ), + HALF3( 0.0f, 0.70710676908493042f, -0.7071068286895752f ), + HALF3( OO_SQRT_3, OO_SQRT_3, OO_SQRT_3 ) +}; + +#if defined( _X360 ) +#define REVERSE_DEPTH_ON_X360 //uncomment to use D3DFMT_D24FS8 with an inverted depth viewport for better performance. Keep this in sync with the same named #define in public/shaderapi/shareddefs.h +//Note that the reversal happens in the viewport. So ONLY reading back from a depth texture should be affected. Projected math is unaffected. +#endif + +HALF3 CalcReflectionVectorNormalized( HALF3 normal, HALF3 eyeVector ) +{ + // FIXME: might be better of normalizing with a normalizing cube map and + // get rid of the dot( normal, normal ) + // compute reflection vector r = 2 * ((n dot v)/(n dot n)) n - v + return 2.0 * ( dot( normal, eyeVector ) / dot( normal, normal ) ) * normal - eyeVector; +} + +HALF3 CalcReflectionVectorUnnormalized( HALF3 normal, HALF3 eyeVector ) +{ + // FIXME: might be better of normalizing with a normalizing cube map and + // get rid of the dot( normal, normal ) + // compute reflection vector r = 2 * ((n dot v)/(n dot n)) n - v + // multiply all values through by N.N. uniformly scaling reflection vector won't affect result + // since it is used in a cubemap lookup + return (2.0*(dot( normal, eyeVector ))*normal) - (dot( normal, normal )*eyeVector); +} + +float3 HuePreservingColorClamp( float3 c ) +{ + // Get the max of all of the color components and a specified maximum amount + float maximum = max( max( c.x, c.y ), max( c.z, 1.0f ) ); + + return (c / maximum); +} + +HALF3 HuePreservingColorClamp( HALF3 c, HALF maxVal ) +{ + // Get the max of all of the color components and a specified maximum amount + float maximum = max( max( c.x, c.y ), max( c.z, maxVal ) ); + return (c * ( maxVal / maximum ) ); +} + +#if (AA_CLAMP==1) +HALF2 ComputeLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord ) +{ + HALF2 result = saturate(Lightmap1and2Coord.xy) * Lightmap1and2Coord.wz * 0.99; + result += Lightmap3Coord; + return result; +} + +void ComputeBumpedLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord, + out HALF2 bumpCoord1, + out HALF2 bumpCoord2, + out HALF2 bumpCoord3 ) +{ + HALF2 result = saturate(Lightmap1and2Coord.xy) * Lightmap1and2Coord.wz * 0.99; + result += Lightmap3Coord; + bumpCoord1 = result + HALF2(Lightmap1and2Coord.z, 0); + bumpCoord2 = result + 2*HALF2(Lightmap1and2Coord.z, 0); + bumpCoord3 = result + 3*HALF2(Lightmap1and2Coord.z, 0); +} +#else +HALF2 ComputeLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord ) +{ + return Lightmap1and2Coord.xy; +} + +void ComputeBumpedLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord, + out HALF2 bumpCoord1, + out HALF2 bumpCoord2, + out HALF2 bumpCoord3 ) +{ + bumpCoord1 = Lightmap1and2Coord.xy; + bumpCoord2 = Lightmap1and2Coord.wz; // reversed order!!! + bumpCoord3 = Lightmap3Coord.xy; +} +#endif + +// Versions of matrix multiply functions which force HLSL compiler to explictly use DOTs, +// not giving it the option of using MAD expansion. In a perfect world, the compiler would +// always pick the best strategy, and these shouldn't be needed.. but.. well.. umm.. +// +// lorenmcq + +float3 mul3x3(float3 v, float3x3 m) +{ +#if !defined( _X360 ) + return float3(dot(v, transpose(m)[0]), dot(v, transpose(m)[1]), dot(v, transpose(m)[2])); +#else + // xbox360 fxc.exe (new back end) borks with transposes, generates bad code + return mul( v, m ); +#endif +} + +float3 mul4x3(float4 v, float4x3 m) +{ +#if !defined( _X360 ) + return float3(dot(v, transpose(m)[0]), dot(v, transpose(m)[1]), dot(v, transpose(m)[2])); +#else + // xbox360 fxc.exe (new back end) borks with transposes, generates bad code + return mul( v, m ); +#endif +} + +float3 DecompressHDR( float4 input ) +{ + return input.rgb * input.a * MAX_HDR_OVERBRIGHT; +} + +float4 CompressHDR( float3 input ) +{ + // FIXME: want to use min so that we clamp to white, but what happens if we + // have an albedo component that's less than 1/MAX_HDR_OVERBRIGHT? + // float fMax = max( max( color.r, color.g ), color.b ); + float4 output; + float fMax = min( min( input.r, input.g ), input.b ); + if( fMax > 1.0f ) + { + float oofMax = 1.0f / fMax; + output.rgb = oofMax * input.rgb; + output.a = min( fMax / MAX_HDR_OVERBRIGHT, 1.0f ); + } + else + { + output.rgb = input.rgb; + output.a = 0.0f; + } + return output; +} + + +float3 LinearToGamma( const float3 f3linear ) +{ + return pow( f3linear, 1.0f / 2.2f ); +} + +float4 LinearToGamma( const float4 f4linear ) +{ + return float4( pow( f4linear.xyz, 1.0f / 2.2f ), f4linear.w ); +} + +float LinearToGamma( const float f1linear ) +{ + return pow( f1linear, 1.0f / 2.2f ); +} + +float3 GammaToLinear( const float3 gamma ) +{ + return pow( gamma, 2.2f ); +} + +float4 GammaToLinear( const float4 gamma ) +{ + return float4( pow( gamma.xyz, 2.2f ), gamma.w ); +} + +float GammaToLinear( const float gamma ) +{ + return pow( gamma, 2.2f ); +} + +// These two functions use the actual sRGB math +float SrgbGammaToLinear( float flSrgbGammaValue ) +{ + float x = saturate( flSrgbGammaValue ); + return ( x <= 0.04045f ) ? ( x / 12.92f ) : ( pow( ( x + 0.055f ) / 1.055f, 2.4f ) ); +} + +float SrgbLinearToGamma( float flLinearValue ) +{ + float x = saturate( flLinearValue ); + return ( x <= 0.0031308f ) ? ( x * 12.92f ) : ( 1.055f * pow( x, ( 1.0f / 2.4f ) ) ) - 0.055f; +} + +// These twofunctions use the XBox 360's exact piecewise linear algorithm +float X360GammaToLinear( float fl360GammaValue ) +{ + float flLinearValue; + + fl360GammaValue = saturate( fl360GammaValue ); + if ( fl360GammaValue < ( 96.0f / 255.0f ) ) + { + if ( fl360GammaValue < ( 64.0f / 255.0f ) ) + { + flLinearValue = fl360GammaValue * 255.0f; + } + else + { + flLinearValue = fl360GammaValue * ( 255.0f * 2.0f ) - 64.0f; + flLinearValue += floor( flLinearValue * ( 1.0f / 512.0f ) ); + } + } + else + { + if( fl360GammaValue < ( 192.0f / 255.0f ) ) + { + flLinearValue = fl360GammaValue * ( 255.0f * 4.0f ) - 256.0f; + flLinearValue += floor( flLinearValue * ( 1.0f / 256.0f ) ); + } + else + { + flLinearValue = fl360GammaValue * ( 255.0f * 8.0f ) - 1024.0f; + flLinearValue += floor( flLinearValue * ( 1.0f / 128.0f ) ); + } + } + + flLinearValue *= 1.0f / 1023.0f; + + flLinearValue = saturate( flLinearValue ); + return flLinearValue; +} + +float X360LinearToGamma( float flLinearValue ) +{ + float fl360GammaValue; + + flLinearValue = saturate( flLinearValue ); + if ( flLinearValue < ( 128.0f / 1023.0f ) ) + { + if ( flLinearValue < ( 64.0f / 1023.0f ) ) + { + fl360GammaValue = flLinearValue * ( 1023.0f * ( 1.0f / 255.0f ) ); + } + else + { + fl360GammaValue = flLinearValue * ( ( 1023.0f / 2.0f ) * ( 1.0f / 255.0f ) ) + ( 32.0f / 255.0f ); + } + } + else + { + if ( flLinearValue < ( 512.0f / 1023.0f ) ) + { + fl360GammaValue = flLinearValue * ( ( 1023.0f / 4.0f ) * ( 1.0f / 255.0f ) ) + ( 64.0f / 255.0f ); + } + else + { + fl360GammaValue = flLinearValue * ( ( 1023.0f /8.0f ) * ( 1.0f / 255.0f ) ) + ( 128.0f /255.0f ); // 1.0 -> 1.0034313725490196078431372549016 + if ( fl360GammaValue > 1.0f ) + { + fl360GammaValue = 1.0f; + } + } + } + + fl360GammaValue = saturate( fl360GammaValue ); + return fl360GammaValue; +} + +float SrgbGammaTo360Gamma( float flSrgbGammaValue ) +{ + float flLinearValue = SrgbGammaToLinear( flSrgbGammaValue ); + float fl360GammaValue = X360LinearToGamma( flLinearValue ); + return fl360GammaValue; +} + +float3 Vec3WorldToTangent( float3 iWorldVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal ) +{ + float3 vTangentVector; + vTangentVector.x = dot( iWorldVector.xyz, iWorldTangent.xyz ); + vTangentVector.y = dot( iWorldVector.xyz, iWorldBinormal.xyz ); + vTangentVector.z = dot( iWorldVector.xyz, iWorldNormal.xyz ); + return vTangentVector.xyz; // Return without normalizing +} + +float3 Vec3WorldToTangentNormalized( float3 iWorldVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal ) +{ + return normalize( Vec3WorldToTangent( iWorldVector, iWorldNormal, iWorldTangent, iWorldBinormal ) ); +} + +float3 Vec3TangentToWorld( float3 iTangentVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal ) +{ + float3 vWorldVector; + vWorldVector.xyz = iTangentVector.x * iWorldTangent.xyz; + vWorldVector.xyz += iTangentVector.y * iWorldBinormal.xyz; + vWorldVector.xyz += iTangentVector.z * iWorldNormal.xyz; + return vWorldVector.xyz; // Return without normalizing +} + +float3 Vec3TangentToWorldNormalized( float3 iTangentVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal ) +{ + return normalize( Vec3TangentToWorld( iTangentVector, iWorldNormal, iWorldTangent, iWorldBinormal ) ); +} + +#endif //#ifndef COMMON_FXC_H_ diff --git a/mp/src/materialsystem/stdshaders/common_fxc2.h b/mp/src/materialsystem/stdshaders/common_fxc2.h index 7ee8b48c..33a25aa0 100644 --- a/mp/src/materialsystem/stdshaders/common_fxc2.h +++ b/mp/src/materialsystem/stdshaders/common_fxc2.h @@ -1,19 +1,19 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -#ifndef COMMON_FXC2_H_ -#define COMMON_FXC2_H_ - -// This file is here so you can add new utility functions without -// changing common_fxc.h and causing a recompile of the entire universe. - -float LinearToMonochrome ( float3 r ) -{ - return dot( r, float3( 0.299f, 0.587f, 0.114f ) ); -} - -#endif //#ifndef COMMON_FXC2_H_ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_FXC2_H_ +#define COMMON_FXC2_H_ + +// This file is here so you can add new utility functions without +// changing common_fxc.h and causing a recompile of the entire universe. + +float LinearToMonochrome ( float3 r ) +{ + return dot( r, float3( 0.299f, 0.587f, 0.114f ) ); +} + +#endif //#ifndef COMMON_FXC2_H_ diff --git a/mp/src/materialsystem/stdshaders/common_hlsl_cpp_consts.h b/mp/src/materialsystem/stdshaders/common_hlsl_cpp_consts.h index 523feee4..41bc7153 100644 --- a/mp/src/materialsystem/stdshaders/common_hlsl_cpp_consts.h +++ b/mp/src/materialsystem/stdshaders/common_hlsl_cpp_consts.h @@ -1,27 +1,27 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -#ifndef COMMON_HLSL_CONSTS_H_ -#define COMMON_HLSL_CONSTS_H_ - -#ifdef NV3X - #define PSHADER_VECT_SCALE 20.0 - #define VSHADER_VECT_SCALE (1.0 / (PSHADER_VECT_SCALE) ) -#else - #define PSHADER_VECT_SCALE 1.0 - #define VSHADER_VECT_SCALE 1.0 -#endif - -// GR - HDR luminance maps to 0..n range -// IMPORTANT: Keep the same value as in materialsystem_global.h -// HDRFIXME: Make this a pixel shader constant? -#define MAX_HDR_OVERBRIGHT 16.0f - -#define LINEAR_FOG_COLOR 29 -#define TONE_MAPPING_SCALE_PSH_CONSTANT 30 - -#endif //#ifndef COMMON_HLSL_CONSTS_H_ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_HLSL_CONSTS_H_ +#define COMMON_HLSL_CONSTS_H_ + +#ifdef NV3X + #define PSHADER_VECT_SCALE 20.0 + #define VSHADER_VECT_SCALE (1.0 / (PSHADER_VECT_SCALE) ) +#else + #define PSHADER_VECT_SCALE 1.0 + #define VSHADER_VECT_SCALE 1.0 +#endif + +// GR - HDR luminance maps to 0..n range +// IMPORTANT: Keep the same value as in materialsystem_global.h +// HDRFIXME: Make this a pixel shader constant? +#define MAX_HDR_OVERBRIGHT 16.0f + +#define LINEAR_FOG_COLOR 29 +#define TONE_MAPPING_SCALE_PSH_CONSTANT 30 + +#endif //#ifndef COMMON_HLSL_CONSTS_H_ diff --git a/mp/src/materialsystem/stdshaders/common_lightmappedgeneric_fxc.h b/mp/src/materialsystem/stdshaders/common_lightmappedgeneric_fxc.h index e82bdf65..aa670746 100644 --- a/mp/src/materialsystem/stdshaders/common_lightmappedgeneric_fxc.h +++ b/mp/src/materialsystem/stdshaders/common_lightmappedgeneric_fxc.h @@ -1,202 +1,202 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// - - -#if defined( _X360 ) - -void GetBaseTextureAndNormal( sampler base, sampler base2, sampler bump, bool bBase2, bool bBump, float3 coords, float3 vWeights, - out float4 vResultBase, out float4 vResultBase2, out float4 vResultBump ) -{ - vResultBase = 0; - vResultBase2 = 0; - vResultBump = 0; - - if ( !bBump ) - { - vResultBump = float4(0, 0, 1, 1); - } - -#if SEAMLESS - - vWeights = max( vWeights - 0.3, 0 ); - - vWeights *= 1.0f / dot( vWeights, float3(1,1,1) ); - - [branch] - if (vWeights.x > 0) - { - vResultBase += vWeights.x * tex2D( base, coords.zy ); - - if ( bBase2 ) - { - vResultBase2 += vWeights.x * tex2D( base2, coords.zy ); - } - - if ( bBump ) - { - vResultBump += vWeights.x * tex2D( bump, coords.zy ); - } - } - - [branch] - if (vWeights.y > 0) - { - vResultBase += vWeights.y * tex2D( base, coords.xz ); - - if ( bBase2 ) - { - vResultBase2 += vWeights.y * tex2D( base2, coords.xz ); - } - if ( bBump ) - { - vResultBump += vWeights.y * tex2D( bump, coords.xz ); - } - } - - [branch] - if (vWeights.z > 0) - { - vResultBase += vWeights.z * tex2D( base, coords.xy ); - if ( bBase2 ) - { - vResultBase2 += vWeights.z * tex2D( base2, coords.xy ); - } - - if ( bBump ) - { - vResultBump += vWeights.z * tex2D( bump, coords.xy ); - } - } - -#else // not seamless - - vResultBase = tex2D( base, coords.xy ); - - if ( bBase2 ) - { - vResultBase2 = tex2D( base2, coords.xy ); - } - - if ( bBump ) - { - vResultBump = tex2D( bump, coords.xy ); - } - -#endif - - -} - -#else // PC - -void GetBaseTextureAndNormal( sampler base, sampler base2, sampler bump, bool bBase2, bool bBump, float3 coords, float3 vWeights, - out float4 vResultBase, out float4 vResultBase2, out float4 vResultBump ) -{ - vResultBase = 0; - vResultBase2 = 0; - vResultBump = 0; - - if ( !bBump ) - { - vResultBump = float4(0, 0, 1, 1); - } - -#if SEAMLESS - - vResultBase += vWeights.x * tex2D( base, coords.zy ); - if ( bBase2 ) - { - vResultBase2 += vWeights.x * tex2D( base2, coords.zy ); - } - if ( bBump ) - { - vResultBump += vWeights.x * tex2D( bump, coords.zy ); - } - - vResultBase += vWeights.y * tex2D( base, coords.xz ); - if ( bBase2 ) - { - vResultBase2 += vWeights.y * tex2D( base2, coords.xz ); - } - if ( bBump ) - { - vResultBump += vWeights.y * tex2D( bump, coords.xz ); - } - - vResultBase += vWeights.z * tex2D( base, coords.xy ); - if ( bBase2 ) - { - vResultBase2 += vWeights.z * tex2D( base2, coords.xy ); - } - if ( bBump ) - { - vResultBump += vWeights.z * tex2D( bump, coords.xy ); - } - -#else // not seamless - - vResultBase = tex2D( base, coords.xy ); - if ( bBase2 ) - { - vResultBase2 = tex2D( base2, coords.xy ); - } - if ( bBump ) - { - vResultBump = tex2D( bump, coords.xy ); - } -#endif - -} - -#endif - - - - -float3 LightMapSample( sampler LightmapSampler, float2 vTexCoord ) -{ -# if ( !defined( _X360 ) || !defined( USE_32BIT_LIGHTMAPS_ON_360 ) ) - { - float3 sample = tex2D( LightmapSampler, vTexCoord ); - - return sample; - } -# else - { -# if 0 //1 for cheap sampling, 0 for accurate scaling from the individual samples - { - float4 sample = tex2D( LightmapSampler, vTexCoord ); - - return sample.rgb * sample.a; - } -# else - { - float4 Weights; - float4 samples_0; //no arrays allowed in inline assembly - float4 samples_1; - float4 samples_2; - float4 samples_3; - - asm { - tfetch2D samples_0, vTexCoord.xy, LightmapSampler, OffsetX = -0.5, OffsetY = -0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false - tfetch2D samples_1, vTexCoord.xy, LightmapSampler, OffsetX = 0.5, OffsetY = -0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false - tfetch2D samples_2, vTexCoord.xy, LightmapSampler, OffsetX = -0.5, OffsetY = 0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false - tfetch2D samples_3, vTexCoord.xy, LightmapSampler, OffsetX = 0.5, OffsetY = 0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false - - getWeights2D Weights, vTexCoord.xy, LightmapSampler - }; - - Weights = float4( (1-Weights.x)*(1-Weights.y), Weights.x*(1-Weights.y), (1-Weights.x)*Weights.y, Weights.x*Weights.y ); - - float3 result; - result.rgb = samples_0.rgb * (samples_0.a * Weights.x); - result.rgb += samples_1.rgb * (samples_1.a * Weights.y); - result.rgb += samples_2.rgb * (samples_2.a * Weights.z); - result.rgb += samples_3.rgb * (samples_3.a * Weights.w); - - return result; - } -# endif - } -# endif -} - +//========= Copyright Valve Corporation, All rights reserved. ============// + + +#if defined( _X360 ) + +void GetBaseTextureAndNormal( sampler base, sampler base2, sampler bump, bool bBase2, bool bBump, float3 coords, float3 vWeights, + out float4 vResultBase, out float4 vResultBase2, out float4 vResultBump ) +{ + vResultBase = 0; + vResultBase2 = 0; + vResultBump = 0; + + if ( !bBump ) + { + vResultBump = float4(0, 0, 1, 1); + } + +#if SEAMLESS + + vWeights = max( vWeights - 0.3, 0 ); + + vWeights *= 1.0f / dot( vWeights, float3(1,1,1) ); + + [branch] + if (vWeights.x > 0) + { + vResultBase += vWeights.x * tex2D( base, coords.zy ); + + if ( bBase2 ) + { + vResultBase2 += vWeights.x * tex2D( base2, coords.zy ); + } + + if ( bBump ) + { + vResultBump += vWeights.x * tex2D( bump, coords.zy ); + } + } + + [branch] + if (vWeights.y > 0) + { + vResultBase += vWeights.y * tex2D( base, coords.xz ); + + if ( bBase2 ) + { + vResultBase2 += vWeights.y * tex2D( base2, coords.xz ); + } + if ( bBump ) + { + vResultBump += vWeights.y * tex2D( bump, coords.xz ); + } + } + + [branch] + if (vWeights.z > 0) + { + vResultBase += vWeights.z * tex2D( base, coords.xy ); + if ( bBase2 ) + { + vResultBase2 += vWeights.z * tex2D( base2, coords.xy ); + } + + if ( bBump ) + { + vResultBump += vWeights.z * tex2D( bump, coords.xy ); + } + } + +#else // not seamless + + vResultBase = tex2D( base, coords.xy ); + + if ( bBase2 ) + { + vResultBase2 = tex2D( base2, coords.xy ); + } + + if ( bBump ) + { + vResultBump = tex2D( bump, coords.xy ); + } + +#endif + + +} + +#else // PC + +void GetBaseTextureAndNormal( sampler base, sampler base2, sampler bump, bool bBase2, bool bBump, float3 coords, float3 vWeights, + out float4 vResultBase, out float4 vResultBase2, out float4 vResultBump ) +{ + vResultBase = 0; + vResultBase2 = 0; + vResultBump = 0; + + if ( !bBump ) + { + vResultBump = float4(0, 0, 1, 1); + } + +#if SEAMLESS + + vResultBase += vWeights.x * tex2D( base, coords.zy ); + if ( bBase2 ) + { + vResultBase2 += vWeights.x * tex2D( base2, coords.zy ); + } + if ( bBump ) + { + vResultBump += vWeights.x * tex2D( bump, coords.zy ); + } + + vResultBase += vWeights.y * tex2D( base, coords.xz ); + if ( bBase2 ) + { + vResultBase2 += vWeights.y * tex2D( base2, coords.xz ); + } + if ( bBump ) + { + vResultBump += vWeights.y * tex2D( bump, coords.xz ); + } + + vResultBase += vWeights.z * tex2D( base, coords.xy ); + if ( bBase2 ) + { + vResultBase2 += vWeights.z * tex2D( base2, coords.xy ); + } + if ( bBump ) + { + vResultBump += vWeights.z * tex2D( bump, coords.xy ); + } + +#else // not seamless + + vResultBase = tex2D( base, coords.xy ); + if ( bBase2 ) + { + vResultBase2 = tex2D( base2, coords.xy ); + } + if ( bBump ) + { + vResultBump = tex2D( bump, coords.xy ); + } +#endif + +} + +#endif + + + + +float3 LightMapSample( sampler LightmapSampler, float2 vTexCoord ) +{ +# if ( !defined( _X360 ) || !defined( USE_32BIT_LIGHTMAPS_ON_360 ) ) + { + float3 sample = tex2D( LightmapSampler, vTexCoord ); + + return sample; + } +# else + { +# if 0 //1 for cheap sampling, 0 for accurate scaling from the individual samples + { + float4 sample = tex2D( LightmapSampler, vTexCoord ); + + return sample.rgb * sample.a; + } +# else + { + float4 Weights; + float4 samples_0; //no arrays allowed in inline assembly + float4 samples_1; + float4 samples_2; + float4 samples_3; + + asm { + tfetch2D samples_0, vTexCoord.xy, LightmapSampler, OffsetX = -0.5, OffsetY = -0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false + tfetch2D samples_1, vTexCoord.xy, LightmapSampler, OffsetX = 0.5, OffsetY = -0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false + tfetch2D samples_2, vTexCoord.xy, LightmapSampler, OffsetX = -0.5, OffsetY = 0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false + tfetch2D samples_3, vTexCoord.xy, LightmapSampler, OffsetX = 0.5, OffsetY = 0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false + + getWeights2D Weights, vTexCoord.xy, LightmapSampler + }; + + Weights = float4( (1-Weights.x)*(1-Weights.y), Weights.x*(1-Weights.y), (1-Weights.x)*Weights.y, Weights.x*Weights.y ); + + float3 result; + result.rgb = samples_0.rgb * (samples_0.a * Weights.x); + result.rgb += samples_1.rgb * (samples_1.a * Weights.y); + result.rgb += samples_2.rgb * (samples_2.a * Weights.z); + result.rgb += samples_3.rgb * (samples_3.a * Weights.w); + + return result; + } +# endif + } +# endif +} + diff --git a/mp/src/materialsystem/stdshaders/common_pragmas.h b/mp/src/materialsystem/stdshaders/common_pragmas.h index 50b61ff0..c22a76b1 100644 --- a/mp/src/materialsystem/stdshaders/common_pragmas.h +++ b/mp/src/materialsystem/stdshaders/common_pragmas.h @@ -1,38 +1,38 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Common shader compiler pragmas -// -// $NoKeywords: $ -// -//=============================================================================// -#ifndef COMMON_PRAGMAS_H_ -#define COMMON_PRAGMAS_H_ - -// -// Validated shader models: -// -// SHADER_MODEL_VS_1_1 -// SHADER_MODEL_VS_2_0 -// SHADER_MODEL_VS_3_0 -// -// SHADER_MODEL_PS_1_1 -// SHADER_MODEL_PS_1_4 -// SHADER_MODEL_PS_2_0 -// SHADER_MODEL_PS_2_B -// SHADER_MODEL_PS_3_0 -// -// -// -// Platforms: -// -// PC -// _X360 -// - -// Special pragmas silencing common warnings -#pragma warning ( disable : 3557 ) // warning X3557: Loop only executes for N iteration(s), forcing loop to unroll -#pragma warning ( disable : 3595 ) // warning X3595: Microcode Compiler possible performance issue: pixel shader input semantic ___ is unused -#pragma warning ( disable : 3596 ) // warning X3596: Microcode Compiler possible performance issue: pixel shader input semantic ___ is unused -#pragma warning ( disable : 4702 ) // warning X4702: complement opportunity missed because input result WAS clamped from 0 to 1 - -#endif //#ifndef COMMON_PRAGMAS_H_ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Common shader compiler pragmas +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_PRAGMAS_H_ +#define COMMON_PRAGMAS_H_ + +// +// Validated shader models: +// +// SHADER_MODEL_VS_1_1 +// SHADER_MODEL_VS_2_0 +// SHADER_MODEL_VS_3_0 +// +// SHADER_MODEL_PS_1_1 +// SHADER_MODEL_PS_1_4 +// SHADER_MODEL_PS_2_0 +// SHADER_MODEL_PS_2_B +// SHADER_MODEL_PS_3_0 +// +// +// +// Platforms: +// +// PC +// _X360 +// + +// Special pragmas silencing common warnings +#pragma warning ( disable : 3557 ) // warning X3557: Loop only executes for N iteration(s), forcing loop to unroll +#pragma warning ( disable : 3595 ) // warning X3595: Microcode Compiler possible performance issue: pixel shader input semantic ___ is unused +#pragma warning ( disable : 3596 ) // warning X3596: Microcode Compiler possible performance issue: pixel shader input semantic ___ is unused +#pragma warning ( disable : 4702 ) // warning X4702: complement opportunity missed because input result WAS clamped from 0 to 1 + +#endif //#ifndef COMMON_PRAGMAS_H_ diff --git a/mp/src/materialsystem/stdshaders/common_ps_fxc.h b/mp/src/materialsystem/stdshaders/common_ps_fxc.h index d4a47ea5..fca6511f 100644 --- a/mp/src/materialsystem/stdshaders/common_ps_fxc.h +++ b/mp/src/materialsystem/stdshaders/common_ps_fxc.h @@ -1,804 +1,804 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Common pixel shader code -// -// $NoKeywords: $ -// -//=============================================================================// -#ifndef COMMON_PS_FXC_H_ -#define COMMON_PS_FXC_H_ - -#include "common_fxc.h" - -// Put global skip commands here. . make sure and check that the appropriate vars are defined -// so these aren't used on the wrong shaders! - -// -------------------------------------------------------------------------------- -// HDR should never be enabled if we don't aren't running in float or integer HDR mode. -// SKIP: defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED -// -------------------------------------------------------------------------------- -// We don't ever write water fog to dest alpha if we aren't doing water fog. -// SKIP: defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA -// -------------------------------------------------------------------------------- -// We don't need fog in the pixel shader if we aren't in float fog mode2 -// NOSKIP: defined $HDRTYPE && defined $HDRENABLED && defined $PIXELFOGTYPE && $HDRTYPE != HDR_TYPE_FLOAT && $FOGTYPE != 0 -// -------------------------------------------------------------------------------- -// We don't do HDR and LIGHTING_PREVIEW at the same time since it's running LDR in hammer. -// SKIP: defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 -// -------------------------------------------------------------------------------- -// Ditch all fastpath attempts if we are doing LIGHTING_PREVIEW. -// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT -// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST -// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH -// -------------------------------------------------------------------------------- -// Ditch flashlight depth when flashlight is disabled -// SKIP: ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW -// -------------------------------------------------------------------------------- - -// System defined pixel shader constants - -#if defined( _X360 ) -const bool g_bHighQualityShadows : register( b0 ); -#endif - -// NOTE: w == 1.0f / (Dest alpha compressed depth range). -const float4 g_LinearFogColor : register( c29 ); -#define OO_DESTALPHA_DEPTH_RANGE (g_LinearFogColor.w) - -// Linear and gamma light scale values -const float4 cLightScale : register( c30 ); -#define LINEAR_LIGHT_SCALE (cLightScale.x) -#define LIGHT_MAP_SCALE (cLightScale.y) -#define ENV_MAP_SCALE (cLightScale.z) -#define GAMMA_LIGHT_SCALE (cLightScale.w) - -// Flashlight constants -#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) - const float4 cFlashlightColor : register( c28 ); - const float4 cFlashlightScreenScale : register( c31 ); // .zw are currently unused - #define flFlashlightNoLambertValue cFlashlightColor.w // This is either 0.0 or 2.0 -#endif - -#define HDR_INPUT_MAP_SCALE 16.0f - -#define TONEMAP_SCALE_NONE 0 -#define TONEMAP_SCALE_LINEAR 1 -#define TONEMAP_SCALE_GAMMA 2 - -#define PIXEL_FOG_TYPE_NONE -1 //MATERIAL_FOG_NONE is handled by PIXEL_FOG_TYPE_RANGE, this is for explicitly disabling fog in the shader -#define PIXEL_FOG_TYPE_RANGE 0 //range+none packed together in ps2b. Simply none in ps20 (instruction limits) -#define PIXEL_FOG_TYPE_HEIGHT 1 - -// If you change these, make the corresponding change in hardwareconfig.cpp -#define NVIDIA_PCF_POISSON 0 -#define ATI_NOPCF 1 -#define ATI_NO_PCF_FETCH4 2 - -struct LPREVIEW_PS_OUT -{ - float4 color : COLOR0; - float4 normal : COLOR1; - float4 position : COLOR2; - float4 flags : COLOR3; -}; - -/* -// unused -HALF Luminance( HALF3 color ) -{ - return dot( color, HALF3( HALF_CONSTANT(0.30f), HALF_CONSTANT(0.59f), HALF_CONSTANT(0.11f) ) ); -} -*/ - -/* -// unused -HALF LuminanceScaled( HALF3 color ) -{ - return dot( color, HALF3( HALF_CONSTANT(0.30f) / MAX_HDR_OVERBRIGHT, HALF_CONSTANT(0.59f) / MAX_HDR_OVERBRIGHT, HALF_CONSTANT(0.11f) / MAX_HDR_OVERBRIGHT ) ); -} -*/ - -/* -// unused -HALF AvgColor( HALF3 color ) -{ - return dot( color, HALF3( HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f) ) ); -} -*/ - -/* -// unused -HALF4 DiffuseBump( sampler lightmapSampler, - float2 lightmapTexCoord1, - float2 lightmapTexCoord2, - float2 lightmapTexCoord3, - HALF3 normal ) -{ - HALF3 lightmapColor1 = tex2D( lightmapSampler, lightmapTexCoord1 ); - HALF3 lightmapColor2 = tex2D( lightmapSampler, lightmapTexCoord2 ); - HALF3 lightmapColor3 = tex2D( lightmapSampler, lightmapTexCoord3 ); - - HALF3 diffuseLighting; - diffuseLighting = saturate( dot( normal, bumpBasis[0] ) ) * lightmapColor1 + - saturate( dot( normal, bumpBasis[1] ) ) * lightmapColor2 + - saturate( dot( normal, bumpBasis[2] ) ) * lightmapColor3; - - return HALF4( diffuseLighting, LuminanceScaled( diffuseLighting ) ); -} -*/ - - -/* -// unused -HALF Fresnel( HALF3 normal, - HALF3 eye, - HALF2 scaleBias ) -{ - HALF fresnel = HALF_CONSTANT(1.0f) - dot( normal, eye ); - fresnel = pow( fresnel, HALF_CONSTANT(5.0f) ); - - return fresnel * scaleBias.x + scaleBias.y; -} -*/ - -/* -// unused -HALF4 GetNormal( sampler normalSampler, - float2 normalTexCoord ) -{ - HALF4 normal = tex2D( normalSampler, normalTexCoord ); - normal.rgb = HALF_CONSTANT(2.0f) * normal.rgb - HALF_CONSTANT(1.0f); - - return normal; -} -*/ - -// Needs to match NormalDecodeMode_t enum in imaterialsystem.h -#define NORM_DECODE_NONE 0 -#define NORM_DECODE_ATI2N 1 -#define NORM_DECODE_ATI2N_ALPHA 2 - -float4 DecompressNormal( sampler NormalSampler, float2 tc, int nDecompressionMode, sampler AlphaSampler ) -{ - float4 normalTexel = tex2D( NormalSampler, tc ); - float4 result; - - if ( nDecompressionMode == NORM_DECODE_NONE ) - { - result = float4(normalTexel.xyz * 2.0f - 1.0f, normalTexel.a ); - } - else if ( nDecompressionMode == NORM_DECODE_ATI2N ) - { - result.xy = normalTexel.xy * 2.0f - 1.0f; - result.z = sqrt( 1.0f - dot(result.xy, result.xy) ); - result.a = 1.0f; - } - else // ATI2N plus ATI1N for alpha - { - result.xy = normalTexel.xy * 2.0f - 1.0f; - result.z = sqrt( 1.0f - dot(result.xy, result.xy) ); - result.a = tex2D( AlphaSampler, tc ).x; // Note that this comes in on the X channel - } - - return result; -} - -float4 DecompressNormal( sampler NormalSampler, float2 tc, int nDecompressionMode ) -{ - return DecompressNormal( NormalSampler, tc, nDecompressionMode, NormalSampler ); -} - - -HALF3 NormalizeWithCubemap( sampler normalizeSampler, HALF3 input ) -{ -// return texCUBE( normalizeSampler, input ) * 2.0f - 1.0f; - return texCUBE( normalizeSampler, input ); -} - -/* -HALF4 EnvReflect( sampler envmapSampler, - sampler normalizeSampler, - HALF3 normal, - float3 eye, - HALF2 fresnelScaleBias ) -{ - HALF3 normEye = NormalizeWithCubemap( normalizeSampler, eye ); - HALF fresnel = Fresnel( normal, normEye, fresnelScaleBias ); - HALF3 reflect = CalcReflectionVectorUnnormalized( normal, eye ); - return texCUBE( envmapSampler, reflect ); -} -*/ - -float CalcWaterFogAlpha( const float flWaterZ, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ, const float flFogOORange ) -{ -// float flDepthFromWater = flWaterZ - flWorldPosZ + 2.0f; // hackity hack . .this is for the DF_FUDGE_UP in view_scene.cpp - float flDepthFromWater = flWaterZ - flWorldPosZ; - - // if flDepthFromWater < 0, then set it to 0 - // This is the equivalent of moving the vert to the water surface if it's above the water surface - // We'll do this with the saturate at the end instead. -// flDepthFromWater = max( 0.0f, flDepthFromWater ); - - // Calculate the ratio of water fog to regular fog (ie. how much of the distance from the viewer - // to the vert is actually underwater. - float flDepthFromEye = flEyePosZ - flWorldPosZ; - float f = saturate(flDepthFromWater * (1.0/flDepthFromEye)); - - // $tmp.w is now the distance that we see through water. - return saturate(f * flProjPosZ * flFogOORange); -} - -float CalcRangeFog( const float flProjPosZ, const float flFogStartOverRange, const float flFogMaxDensity, const float flFogOORange ) -{ -#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b - return saturate( min( flFogMaxDensity, (flProjPosZ * flFogOORange) - flFogStartOverRange ) ); -#else - return 0.0f; //ps20 shaders will never have range fog enabled because too many ran out of slots. -#endif -} - -float CalcPixelFogFactor( int iPIXELFOGTYPE, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) -{ - float retVal; - if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_NONE ) - { - retVal = 0.0f; - } - if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE ) //range fog, or no fog depending on fog parameters - { - retVal = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.z, fogParams.w ); - } - else if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) //height fog - { - retVal = CalcWaterFogAlpha( fogParams.y, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.w ); - } - - return retVal; -} - -//g_FogParams not defined by default, but this is the same layout for every shader that does define it -#define g_FogEndOverRange g_FogParams.x -#define g_WaterZ g_FogParams.y -#define g_FogMaxDensity g_FogParams.z -#define g_FogOORange g_FogParams.w - -float3 BlendPixelFog( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, const int iPIXELFOGTYPE ) -{ - if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE ) //either range fog or no fog depending on fog parameters and whether this is ps20 or ps2b - { -# if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b - pixelFogFactor = saturate( pixelFogFactor ); - return lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog -# else - return vShaderColor; -# endif - } - else if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) - { - return lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); - } - else if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_NONE ) - { - return vShaderColor; - } -} - - -#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) && ( CONVERT_TO_SRGB != 0 ) ) -sampler1D GammaTableSampler : register( s15 ); - -float3 SRGBOutput( const float3 vShaderColor ) -{ - //On ps2b capable hardware we always have the linear->gamma conversion table texture in sampler s15. - float3 result; - result.r = tex1D( GammaTableSampler, vShaderColor.r ).r; - result.g = tex1D( GammaTableSampler, vShaderColor.g ).r; - result.b = tex1D( GammaTableSampler, vShaderColor.b ).r; - return result; -} - -#else - -float3 SRGBOutput( const float3 vShaderColor ) -{ - return vShaderColor; //ps 1.1, 1.4, and 2.0 never do srgb conversion in the pixel shader -} - -#endif - - -float SoftParticleDepth( float flDepth ) -{ - return flDepth * OO_DESTALPHA_DEPTH_RANGE; -} - - -float DepthToDestAlpha( const float flProjZ ) -{ -#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b - return SoftParticleDepth( flProjZ ); -#else - return 1.0f; -#endif -} - - -float4 FinalOutput( const float4 vShaderColor, float pixelFogFactor, const int iPIXELFOGTYPE, const int iTONEMAP_SCALE_TYPE, const bool bWriteDepthToDestAlpha = false, const float flProjZ = 1.0f ) -{ - float4 result; - if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) - { - result.rgb = vShaderColor.rgb * LINEAR_LIGHT_SCALE; - } - else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) - { - result.rgb = vShaderColor.rgb * GAMMA_LIGHT_SCALE; - } - else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_NONE ) - { - result.rgb = vShaderColor.rgb; - } - - if( bWriteDepthToDestAlpha ) - result.a = DepthToDestAlpha( flProjZ ); - else - result.a = vShaderColor.a; - - result.rgb = BlendPixelFog( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, iPIXELFOGTYPE ); - -#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b - result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion -#endif - - return result; -} - -LPREVIEW_PS_OUT FinalOutput( const LPREVIEW_PS_OUT vShaderColor, float pixelFogFactor, const int iPIXELFOGTYPE, const int iTONEMAP_SCALE_TYPE ) -{ - LPREVIEW_PS_OUT result; - result.color = FinalOutput( vShaderColor.color, pixelFogFactor, iPIXELFOGTYPE, iTONEMAP_SCALE_TYPE ); - result.normal.rgb = SRGBOutput( vShaderColor.normal.rgb ); - result.normal.a = vShaderColor.normal.a; - - result.position.rgb = SRGBOutput( vShaderColor.position.rgb ); - result.position.a = vShaderColor.position.a; - - result.flags.rgb = SRGBOutput( vShaderColor.flags.rgb ); - result.flags.a = vShaderColor.flags.a; - - return result; -} - - - - -float RemapValClamped( float val, float A, float B, float C, float D) -{ - float cVal = (val - A) / (B - A); - cVal = saturate( cVal ); - - return C + (D - C) * cVal; -} - - -//===================================================================================// -// This is based on Natasha Tatarchuk's Parallax Occlusion Mapping (ATI) -//===================================================================================// -// INPUT: -// inTexCoord: -// the texcoord for the height/displacement map before parallaxing -// -// vParallax: -// Compute initial parallax displacement direction: -// float2 vParallaxDirection = normalize( vViewTS.xy ); -// float fLength = length( vViewTS ); -// float fParallaxLength = sqrt( fLength * fLength - vViewTS.z * vViewTS.z ) / vViewTS.z; -// Out.vParallax = vParallaxDirection * fParallaxLength * fProjectedBumpHeight; -// -// vNormal: -// tangent space normal -// -// vViewW: -// float3 vViewW = /*normalize*/(mul( matViewInverse, float4( 0, 0, 0, 1)) - inPosition ); -// -// OUTPUT: -// the new texcoord after parallaxing -float2 CalcParallaxedTexCoord( float2 inTexCoord, float2 vParallax, float3 vNormal, - float3 vViewW, sampler HeightMapSampler ) -{ - const int nMinSamples = 8; - const int nMaxSamples = 50; - - // Normalize the incoming view vector to avoid artifacts: -// vView = normalize( vView ); - vViewW = normalize( vViewW ); -// vLight = normalize( vLight ); - - // Change the number of samples per ray depending on the viewing angle - // for the surface. Oblique angles require smaller step sizes to achieve - // more accurate precision - int nNumSteps = (int) lerp( nMaxSamples, nMinSamples, dot( vViewW, vNormal ) ); - - float4 cResultColor = float4( 0, 0, 0, 1 ); - - //===============================================// - // Parallax occlusion mapping offset computation // - //===============================================// - 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 dx = ddx( inTexCoord ); - float2 dy = ddy( inTexCoord ); - - float2 vTexOffsetPerStep = fStepSize * vParallax; - - float2 vTexCurrentOffset = inTexCoord; - float fCurrentBound = 1.0; - - float x = 0; - float y = 0; - float xh = 0; - float yh = 0; - - float2 texOffset2 = 0; - - bool bCondition = true; - while ( bCondition == true && nStepIndex < nNumSteps ) - { - vTexCurrentOffset -= vTexOffsetPerStep; - - fCurrHeight = tex2Dgrad( HeightMapSampler, vTexCurrentOffset, dx, dy ).r; - - fCurrentBound -= fStepSize; - - if ( fCurrHeight > fCurrentBound ) - { - x = fCurrentBound; - y = fCurrentBound + fStepSize; - xh = fCurrHeight; - yh = fPrevHeight; - - texOffset2 = vTexCurrentOffset - vTexOffsetPerStep; - - bCondition = false; - } - else - { - nStepIndex++; - fPrevHeight = fCurrHeight; - } - - } // End of while ( bCondition == true && nStepIndex > -1 )#else - - fCurrentBound -= fStepSize; - - float fParallaxAmount; - float numerator = (x * (y - yh) - y * (x - xh)); - float denomenator = ((y - yh) - (x - xh)); - // avoid NaN generation - if( ( numerator == 0.0f ) && ( denomenator == 0.0f ) ) - { - fParallaxAmount = 0.0f; - } - else - { - fParallaxAmount = numerator / denomenator; - } - - float2 vParallaxOffset = vParallax * (1 - fParallaxAmount ); - - // Sample the height at the next possible step: - fNextHeight = tex2Dgrad( HeightMapSampler, texOffset2, dx, dy ).r; - - // Original offset: - float2 texSampleBase = inTexCoord - vParallaxOffset; - - return texSampleBase; - -#if 0 - cResultColor.rgb = ComputeDiffuseColor( texSampleBase, vLight ); - - float fBound = 1.0 - fStepSize * nStepIndex; - if ( fNextHeight < fCurrentBound ) -// if( 0 ) - { - //void DoIteration( in float2 vParallaxJittered, in float3 vLight, inout float4 cResultColor ) - //cResultColor.rgb = float3(1,0,0); - DoIteration( vParallax + vPixelSize, vLight, fStepSize, inTexCoord, nStepIndex, dx, dy, fBound, cResultColor ); - DoIteration( vParallax - vPixelSize, vLight, fStepSize, inTexCoord, nStepIndex, dx, dy, fBound, cResultColor ); - DoIteration( vParallax + float2( -vPixelSize.x, vPixelSize.y ), vLight, fStepSize, inTexCoord, nStepIndex, dx, dy, fBound, cResultColor ); - DoIteration( vParallax + float2( vPixelSize.x, -vPixelSize.y ), vLight, fStepSize, inTexCoord, nStepIndex, dx, dy, fBound, cResultColor ); - - cResultColor.rgb /= 5; -// cResultColor.rgb = float3( 1.0f, 0.0f, 0.0f ); - } // End of if ( fNextHeight < fCurrentBound ) - -#if DOSHADOWS - { - //============================================// - // Soft shadow and self-occlusion computation // - //============================================// - // Compute the blurry shadows (note that this computation takes into - // account self-occlusion for shadow computation): - float sh0 = tex2D( sNormalMap, texSampleBase).w; - float shA = (tex2D( sNormalMap, texSampleBase + inXY * 0.88 ).w - sh0 - 0.88 ) * 1 * fShadowSoftening; - float sh9 = (tex2D( sNormalMap, texSampleBase + inXY * 0.77 ).w - sh0 - 0.77 ) * 2 * fShadowSoftening; - float sh8 = (tex2D( sNormalMap, texSampleBase + inXY * 0.66 ).w - sh0 - 0.66 ) * 4 * fShadowSoftening; - float sh7 = (tex2D( sNormalMap, texSampleBase + inXY * 0.55 ).w - sh0 - 0.55 ) * 6 * fShadowSoftening; - float sh6 = (tex2D( sNormalMap, texSampleBase + inXY * 0.44 ).w - sh0 - 0.44 ) * 8 * fShadowSoftening; - float sh5 = (tex2D( sNormalMap, texSampleBase + inXY * 0.33 ).w - sh0 - 0.33 ) * 10 * fShadowSoftening; - float sh4 = (tex2D( sNormalMap, texSampleBase + inXY * 0.22 ).w - sh0 - 0.22 ) * 12 * fShadowSoftening; - - // Compute the actual shadow strength: - float fShadow = 1 - max( max( max( max( max( max( shA, sh9 ), sh8 ), sh7 ), sh6 ), sh5 ), sh4 ); - - cResultColor.rgb *= fShadow * 0.6 + 0.4; - } -#endif - - return cResultColor; -#endif -} - - -//======================================// -// HSL Color space conversion routines // -//======================================// - -#define HUE 0 -#define SATURATION 1 -#define LIGHTNESS 2 - -// Convert from RGB to HSL color space -float4 RGBtoHSL( float4 inColor ) -{ - float h, s; - float flMax = max( inColor.r, max( inColor.g, inColor.b ) ); - float flMin = min( inColor.r, min( inColor.g, inColor.b ) ); - - float l = (flMax + flMin) / 2.0f; - - if (flMax == flMin) // achromatic case - { - s = h = 0; - } - else // chromatic case - { - // Next, calculate the hue - float delta = flMax - flMin; - - // First, calculate the saturation - if (l < 0.5f) // If we're in the lower hexcone - { - s = delta/(flMax + flMin); - } - else - { - s = delta/(2 - flMax - flMin); - } - - if ( inColor.r == flMax ) - { - h = (inColor.g - inColor.b)/delta; // color between yellow and magenta - } - else if ( inColor.g == flMax ) - { - h = 2 + (inColor.b - inColor.r)/delta; // color between cyan and yellow - } - else // blue must be max - { - h = 4 + (inColor.r - inColor.g)/delta; // color between magenta and cyan - } - - h *= 60.0f; - - if (h < 0.0f) - { - h += 360.0f; - } - - h /= 360.0f; - } - - return float4 (h, s, l, 1.0f); -} - -float HueToRGB( float v1, float v2, float vH ) -{ - float fResult = v1; - - vH = fmod (vH + 1.0f, 1.0f); - - if ( ( 6.0f * vH ) < 1.0f ) - { - fResult = ( v1 + ( v2 - v1 ) * 6.0f * vH ); - } - else if ( ( 2.0f * vH ) < 1.0f ) - { - fResult = ( v2 ); - } - else if ( ( 3.0f * vH ) < 2.0f ) - { - fResult = ( v1 + ( v2 - v1 ) * ( ( 2.0f / 3.0f ) - vH ) * 6.0f ); - } - - return fResult; -} - -// Convert from HSL to RGB color space -float4 HSLtoRGB( float4 hsl ) -{ - float r, g, b; - float h = hsl[HUE]; - float s = hsl[SATURATION]; - float l = hsl[LIGHTNESS]; - - if ( s == 0 ) - { - r = g = b = l; - } - else - { - float v1, v2; - - if ( l < 0.5f ) - v2 = l * ( 1.0f + s ); - else - v2 = ( l + s ) - ( s * l ); - - v1 = 2 * l - v2; - - r = HueToRGB( v1, v2, h + ( 1.0f / 3.0f ) ); - g = HueToRGB( v1, v2, h ); - b = HueToRGB( v1, v2, h - ( 1.0f / 3.0f ) ); - } - - return float4( r, g, b, 1.0f ); -} - - -// texture combining modes for combining base and detail/basetexture2 -#define TCOMBINE_RGB_EQUALS_BASE_x_DETAILx2 0 // original mode -#define TCOMBINE_RGB_ADDITIVE 1 // base.rgb+detail.rgb*fblend -#define TCOMBINE_DETAIL_OVER_BASE 2 -#define TCOMBINE_FADE 3 // straight fade between base and detail. -#define TCOMBINE_BASE_OVER_DETAIL 4 // use base alpha for blend over detail -#define TCOMBINE_RGB_ADDITIVE_SELFILLUM 5 // add detail color post lighting -#define TCOMBINE_RGB_ADDITIVE_SELFILLUM_THRESHOLD_FADE 6 -#define TCOMBINE_MOD2X_SELECT_TWO_PATTERNS 7 // use alpha channel of base to select between mod2x channels in r+a of detail -#define TCOMBINE_MULTIPLY 8 -#define TCOMBINE_MASK_BASE_BY_DETAIL_ALPHA 9 // use alpha channel of detail to mask base -#define TCOMBINE_SSBUMP_BUMP 10 // use detail to modulate lighting as an ssbump -#define TCOMBINE_SSBUMP_NOBUMP 11 // detail is an ssbump but use it as an albedo. shader does the magic here - no user needs to specify mode 11 - -float4 TextureCombine( float4 baseColor, float4 detailColor, int combine_mode, - float fBlendFactor ) -{ - if ( combine_mode == TCOMBINE_MOD2X_SELECT_TWO_PATTERNS) - { - float3 dc=lerp(detailColor.r,detailColor.a, baseColor.a); - baseColor.rgb*=lerp(float3(1,1,1),2.0*dc,fBlendFactor); - } - if ( combine_mode == TCOMBINE_RGB_EQUALS_BASE_x_DETAILx2) - baseColor.rgb*=lerp(float3(1,1,1),2.0*detailColor.rgb,fBlendFactor); - if ( combine_mode == TCOMBINE_RGB_ADDITIVE ) - baseColor.rgb += fBlendFactor * detailColor.rgb; - if ( combine_mode == TCOMBINE_DETAIL_OVER_BASE ) - { - float fblend=fBlendFactor * detailColor.a; - baseColor.rgb = lerp( baseColor.rgb, detailColor.rgb, fblend); - } - if ( combine_mode == TCOMBINE_FADE ) - { - baseColor = lerp( baseColor, detailColor, fBlendFactor); - } - if ( combine_mode == TCOMBINE_BASE_OVER_DETAIL ) - { - float fblend=fBlendFactor * (1-baseColor.a); - baseColor.rgb = lerp( baseColor.rgb, detailColor.rgb, fblend ); - baseColor.a = detailColor.a; - } - if ( combine_mode == TCOMBINE_MULTIPLY ) - { - baseColor = lerp( baseColor, baseColor*detailColor, fBlendFactor); - } - - if (combine_mode == TCOMBINE_MASK_BASE_BY_DETAIL_ALPHA ) - { - baseColor.a = lerp( baseColor.a, baseColor.a*detailColor.a, fBlendFactor ); - } - if ( combine_mode == TCOMBINE_SSBUMP_NOBUMP ) - { - baseColor.rgb = baseColor.rgb * dot( detailColor.rgb, 2.0/3.0 ); - } - return baseColor; -} - -float3 lerp5(float3 f1, float3 f2, float i1, float i2, float x) -{ - return f1+(f2-f1)*(x-i1)/(i2-i1); -} - -float3 TextureCombinePostLighting( float3 lit_baseColor, float4 detailColor, int combine_mode, - float fBlendFactor ) -{ - if ( combine_mode == TCOMBINE_RGB_ADDITIVE_SELFILLUM ) - lit_baseColor += fBlendFactor * detailColor.rgb; - if ( combine_mode == TCOMBINE_RGB_ADDITIVE_SELFILLUM_THRESHOLD_FADE ) - { - // fade in an unusual way - instead of fading out color, remap an increasing band of it from - // 0..1 - //if (fBlendFactor > 0.5) - // lit_baseColor += min(1, (1.0/fBlendFactor)*max(0, detailColor.rgb-(1-fBlendFactor) ) ); - //else - // lit_baseColor += 2*fBlendFactor*2*max(0, detailColor.rgb-.5); - - float f = fBlendFactor - 0.5; - float fMult = (f >= 0) ? 1.0/fBlendFactor : 4*fBlendFactor; - float fAdd = (f >= 0) ? 1.0-fMult : -0.5*fMult; - lit_baseColor += saturate(fMult * detailColor.rgb + fAdd); - } - return lit_baseColor; -} - -//NOTE: On X360. fProjZ is expected to be pre-reversed for cheaper math here in the pixel shader -float DepthFeathering( sampler DepthSampler, const float2 vScreenPos, float fProjZ, float fProjW, float4 vDepthBlendConstants ) -{ -# if ( !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) ) //minimum requirement of ps2b - { - float flFeatheredAlpha; - float2 flDepths; -#define flSceneDepth flDepths.x -#define flSpriteDepth flDepths.y - -# if ( defined( _X360 ) ) - { - //Get depth from the depth texture. Need to sample with the offset of (0.5, 0.5) to fix rounding errors - asm { - tfetch2D flDepths.x___, vScreenPos, DepthSampler, OffsetX=0.5, OffsetY=0.5, MinFilter=point, MagFilter=point, MipFilter=point - }; - -# if( !defined( REVERSE_DEPTH_ON_X360 ) ) - flSceneDepth = 1.0f - flSceneDepth; -# endif - - //get the sprite depth into the same range as the texture depth - flSpriteDepth = fProjZ / fProjW; - - //unproject to get at the pre-projection z. This value is much more linear than depth - flDepths = vDepthBlendConstants.z / flDepths; - flDepths = vDepthBlendConstants.y - flDepths; - - flFeatheredAlpha = flSceneDepth - flSpriteDepth; - flFeatheredAlpha *= vDepthBlendConstants.x; - flFeatheredAlpha = saturate( flFeatheredAlpha ); - } -# else - { - flSceneDepth = tex2D( DepthSampler, vScreenPos ).a; // PC uses dest alpha of the frame buffer - flSpriteDepth = SoftParticleDepth( fProjZ ); - - flFeatheredAlpha = abs(flSceneDepth - flSpriteDepth) * vDepthBlendConstants.x; - flFeatheredAlpha = max( smoothstep( 0.75f, 1.0f, flSceneDepth ), flFeatheredAlpha ); //as the sprite approaches the edge of our compressed depth space, the math stops working. So as the sprite approaches the far depth, smoothly remove feathering. - flFeatheredAlpha = saturate( flFeatheredAlpha ); - } -# endif - -#undef flSceneDepth -#undef flSpriteDepth - - return flFeatheredAlpha; - } -# else - { - return 1.0f; - } -# endif -} - -#endif //#ifndef COMMON_PS_FXC_H_ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Common pixel shader code +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_PS_FXC_H_ +#define COMMON_PS_FXC_H_ + +#include "common_fxc.h" + +// Put global skip commands here. . make sure and check that the appropriate vars are defined +// so these aren't used on the wrong shaders! + +// -------------------------------------------------------------------------------- +// HDR should never be enabled if we don't aren't running in float or integer HDR mode. +// SKIP: defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// -------------------------------------------------------------------------------- +// We don't ever write water fog to dest alpha if we aren't doing water fog. +// SKIP: defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// -------------------------------------------------------------------------------- +// We don't need fog in the pixel shader if we aren't in float fog mode2 +// NOSKIP: defined $HDRTYPE && defined $HDRENABLED && defined $PIXELFOGTYPE && $HDRTYPE != HDR_TYPE_FLOAT && $FOGTYPE != 0 +// -------------------------------------------------------------------------------- +// We don't do HDR and LIGHTING_PREVIEW at the same time since it's running LDR in hammer. +// SKIP: defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// -------------------------------------------------------------------------------- +// Ditch all fastpath attempts if we are doing LIGHTING_PREVIEW. +// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// -------------------------------------------------------------------------------- +// Ditch flashlight depth when flashlight is disabled +// SKIP: ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// -------------------------------------------------------------------------------- + +// System defined pixel shader constants + +#if defined( _X360 ) +const bool g_bHighQualityShadows : register( b0 ); +#endif + +// NOTE: w == 1.0f / (Dest alpha compressed depth range). +const float4 g_LinearFogColor : register( c29 ); +#define OO_DESTALPHA_DEPTH_RANGE (g_LinearFogColor.w) + +// Linear and gamma light scale values +const float4 cLightScale : register( c30 ); +#define LINEAR_LIGHT_SCALE (cLightScale.x) +#define LIGHT_MAP_SCALE (cLightScale.y) +#define ENV_MAP_SCALE (cLightScale.z) +#define GAMMA_LIGHT_SCALE (cLightScale.w) + +// Flashlight constants +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + const float4 cFlashlightColor : register( c28 ); + const float4 cFlashlightScreenScale : register( c31 ); // .zw are currently unused + #define flFlashlightNoLambertValue cFlashlightColor.w // This is either 0.0 or 2.0 +#endif + +#define HDR_INPUT_MAP_SCALE 16.0f + +#define TONEMAP_SCALE_NONE 0 +#define TONEMAP_SCALE_LINEAR 1 +#define TONEMAP_SCALE_GAMMA 2 + +#define PIXEL_FOG_TYPE_NONE -1 //MATERIAL_FOG_NONE is handled by PIXEL_FOG_TYPE_RANGE, this is for explicitly disabling fog in the shader +#define PIXEL_FOG_TYPE_RANGE 0 //range+none packed together in ps2b. Simply none in ps20 (instruction limits) +#define PIXEL_FOG_TYPE_HEIGHT 1 + +// If you change these, make the corresponding change in hardwareconfig.cpp +#define NVIDIA_PCF_POISSON 0 +#define ATI_NOPCF 1 +#define ATI_NO_PCF_FETCH4 2 + +struct LPREVIEW_PS_OUT +{ + float4 color : COLOR0; + float4 normal : COLOR1; + float4 position : COLOR2; + float4 flags : COLOR3; +}; + +/* +// unused +HALF Luminance( HALF3 color ) +{ + return dot( color, HALF3( HALF_CONSTANT(0.30f), HALF_CONSTANT(0.59f), HALF_CONSTANT(0.11f) ) ); +} +*/ + +/* +// unused +HALF LuminanceScaled( HALF3 color ) +{ + return dot( color, HALF3( HALF_CONSTANT(0.30f) / MAX_HDR_OVERBRIGHT, HALF_CONSTANT(0.59f) / MAX_HDR_OVERBRIGHT, HALF_CONSTANT(0.11f) / MAX_HDR_OVERBRIGHT ) ); +} +*/ + +/* +// unused +HALF AvgColor( HALF3 color ) +{ + return dot( color, HALF3( HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f) ) ); +} +*/ + +/* +// unused +HALF4 DiffuseBump( sampler lightmapSampler, + float2 lightmapTexCoord1, + float2 lightmapTexCoord2, + float2 lightmapTexCoord3, + HALF3 normal ) +{ + HALF3 lightmapColor1 = tex2D( lightmapSampler, lightmapTexCoord1 ); + HALF3 lightmapColor2 = tex2D( lightmapSampler, lightmapTexCoord2 ); + HALF3 lightmapColor3 = tex2D( lightmapSampler, lightmapTexCoord3 ); + + HALF3 diffuseLighting; + diffuseLighting = saturate( dot( normal, bumpBasis[0] ) ) * lightmapColor1 + + saturate( dot( normal, bumpBasis[1] ) ) * lightmapColor2 + + saturate( dot( normal, bumpBasis[2] ) ) * lightmapColor3; + + return HALF4( diffuseLighting, LuminanceScaled( diffuseLighting ) ); +} +*/ + + +/* +// unused +HALF Fresnel( HALF3 normal, + HALF3 eye, + HALF2 scaleBias ) +{ + HALF fresnel = HALF_CONSTANT(1.0f) - dot( normal, eye ); + fresnel = pow( fresnel, HALF_CONSTANT(5.0f) ); + + return fresnel * scaleBias.x + scaleBias.y; +} +*/ + +/* +// unused +HALF4 GetNormal( sampler normalSampler, + float2 normalTexCoord ) +{ + HALF4 normal = tex2D( normalSampler, normalTexCoord ); + normal.rgb = HALF_CONSTANT(2.0f) * normal.rgb - HALF_CONSTANT(1.0f); + + return normal; +} +*/ + +// Needs to match NormalDecodeMode_t enum in imaterialsystem.h +#define NORM_DECODE_NONE 0 +#define NORM_DECODE_ATI2N 1 +#define NORM_DECODE_ATI2N_ALPHA 2 + +float4 DecompressNormal( sampler NormalSampler, float2 tc, int nDecompressionMode, sampler AlphaSampler ) +{ + float4 normalTexel = tex2D( NormalSampler, tc ); + float4 result; + + if ( nDecompressionMode == NORM_DECODE_NONE ) + { + result = float4(normalTexel.xyz * 2.0f - 1.0f, normalTexel.a ); + } + else if ( nDecompressionMode == NORM_DECODE_ATI2N ) + { + result.xy = normalTexel.xy * 2.0f - 1.0f; + result.z = sqrt( 1.0f - dot(result.xy, result.xy) ); + result.a = 1.0f; + } + else // ATI2N plus ATI1N for alpha + { + result.xy = normalTexel.xy * 2.0f - 1.0f; + result.z = sqrt( 1.0f - dot(result.xy, result.xy) ); + result.a = tex2D( AlphaSampler, tc ).x; // Note that this comes in on the X channel + } + + return result; +} + +float4 DecompressNormal( sampler NormalSampler, float2 tc, int nDecompressionMode ) +{ + return DecompressNormal( NormalSampler, tc, nDecompressionMode, NormalSampler ); +} + + +HALF3 NormalizeWithCubemap( sampler normalizeSampler, HALF3 input ) +{ +// return texCUBE( normalizeSampler, input ) * 2.0f - 1.0f; + return texCUBE( normalizeSampler, input ); +} + +/* +HALF4 EnvReflect( sampler envmapSampler, + sampler normalizeSampler, + HALF3 normal, + float3 eye, + HALF2 fresnelScaleBias ) +{ + HALF3 normEye = NormalizeWithCubemap( normalizeSampler, eye ); + HALF fresnel = Fresnel( normal, normEye, fresnelScaleBias ); + HALF3 reflect = CalcReflectionVectorUnnormalized( normal, eye ); + return texCUBE( envmapSampler, reflect ); +} +*/ + +float CalcWaterFogAlpha( const float flWaterZ, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ, const float flFogOORange ) +{ +// float flDepthFromWater = flWaterZ - flWorldPosZ + 2.0f; // hackity hack . .this is for the DF_FUDGE_UP in view_scene.cpp + float flDepthFromWater = flWaterZ - flWorldPosZ; + + // if flDepthFromWater < 0, then set it to 0 + // This is the equivalent of moving the vert to the water surface if it's above the water surface + // We'll do this with the saturate at the end instead. +// flDepthFromWater = max( 0.0f, flDepthFromWater ); + + // Calculate the ratio of water fog to regular fog (ie. how much of the distance from the viewer + // to the vert is actually underwater. + float flDepthFromEye = flEyePosZ - flWorldPosZ; + float f = saturate(flDepthFromWater * (1.0/flDepthFromEye)); + + // $tmp.w is now the distance that we see through water. + return saturate(f * flProjPosZ * flFogOORange); +} + +float CalcRangeFog( const float flProjPosZ, const float flFogStartOverRange, const float flFogMaxDensity, const float flFogOORange ) +{ +#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b + return saturate( min( flFogMaxDensity, (flProjPosZ * flFogOORange) - flFogStartOverRange ) ); +#else + return 0.0f; //ps20 shaders will never have range fog enabled because too many ran out of slots. +#endif +} + +float CalcPixelFogFactor( int iPIXELFOGTYPE, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) +{ + float retVal; + if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_NONE ) + { + retVal = 0.0f; + } + if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE ) //range fog, or no fog depending on fog parameters + { + retVal = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.z, fogParams.w ); + } + else if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) //height fog + { + retVal = CalcWaterFogAlpha( fogParams.y, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.w ); + } + + return retVal; +} + +//g_FogParams not defined by default, but this is the same layout for every shader that does define it +#define g_FogEndOverRange g_FogParams.x +#define g_WaterZ g_FogParams.y +#define g_FogMaxDensity g_FogParams.z +#define g_FogOORange g_FogParams.w + +float3 BlendPixelFog( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, const int iPIXELFOGTYPE ) +{ + if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE ) //either range fog or no fog depending on fog parameters and whether this is ps20 or ps2b + { +# if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b + pixelFogFactor = saturate( pixelFogFactor ); + return lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog +# else + return vShaderColor; +# endif + } + else if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) + { + return lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); + } + else if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_NONE ) + { + return vShaderColor; + } +} + + +#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) && ( CONVERT_TO_SRGB != 0 ) ) +sampler1D GammaTableSampler : register( s15 ); + +float3 SRGBOutput( const float3 vShaderColor ) +{ + //On ps2b capable hardware we always have the linear->gamma conversion table texture in sampler s15. + float3 result; + result.r = tex1D( GammaTableSampler, vShaderColor.r ).r; + result.g = tex1D( GammaTableSampler, vShaderColor.g ).r; + result.b = tex1D( GammaTableSampler, vShaderColor.b ).r; + return result; +} + +#else + +float3 SRGBOutput( const float3 vShaderColor ) +{ + return vShaderColor; //ps 1.1, 1.4, and 2.0 never do srgb conversion in the pixel shader +} + +#endif + + +float SoftParticleDepth( float flDepth ) +{ + return flDepth * OO_DESTALPHA_DEPTH_RANGE; +} + + +float DepthToDestAlpha( const float flProjZ ) +{ +#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b + return SoftParticleDepth( flProjZ ); +#else + return 1.0f; +#endif +} + + +float4 FinalOutput( const float4 vShaderColor, float pixelFogFactor, const int iPIXELFOGTYPE, const int iTONEMAP_SCALE_TYPE, const bool bWriteDepthToDestAlpha = false, const float flProjZ = 1.0f ) +{ + float4 result; + if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) + { + result.rgb = vShaderColor.rgb * LINEAR_LIGHT_SCALE; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) + { + result.rgb = vShaderColor.rgb * GAMMA_LIGHT_SCALE; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_NONE ) + { + result.rgb = vShaderColor.rgb; + } + + if( bWriteDepthToDestAlpha ) + result.a = DepthToDestAlpha( flProjZ ); + else + result.a = vShaderColor.a; + + result.rgb = BlendPixelFog( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, iPIXELFOGTYPE ); + +#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b + result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion +#endif + + return result; +} + +LPREVIEW_PS_OUT FinalOutput( const LPREVIEW_PS_OUT vShaderColor, float pixelFogFactor, const int iPIXELFOGTYPE, const int iTONEMAP_SCALE_TYPE ) +{ + LPREVIEW_PS_OUT result; + result.color = FinalOutput( vShaderColor.color, pixelFogFactor, iPIXELFOGTYPE, iTONEMAP_SCALE_TYPE ); + result.normal.rgb = SRGBOutput( vShaderColor.normal.rgb ); + result.normal.a = vShaderColor.normal.a; + + result.position.rgb = SRGBOutput( vShaderColor.position.rgb ); + result.position.a = vShaderColor.position.a; + + result.flags.rgb = SRGBOutput( vShaderColor.flags.rgb ); + result.flags.a = vShaderColor.flags.a; + + return result; +} + + + + +float RemapValClamped( float val, float A, float B, float C, float D) +{ + float cVal = (val - A) / (B - A); + cVal = saturate( cVal ); + + return C + (D - C) * cVal; +} + + +//===================================================================================// +// This is based on Natasha Tatarchuk's Parallax Occlusion Mapping (ATI) +//===================================================================================// +// INPUT: +// inTexCoord: +// the texcoord for the height/displacement map before parallaxing +// +// vParallax: +// Compute initial parallax displacement direction: +// float2 vParallaxDirection = normalize( vViewTS.xy ); +// float fLength = length( vViewTS ); +// float fParallaxLength = sqrt( fLength * fLength - vViewTS.z * vViewTS.z ) / vViewTS.z; +// Out.vParallax = vParallaxDirection * fParallaxLength * fProjectedBumpHeight; +// +// vNormal: +// tangent space normal +// +// vViewW: +// float3 vViewW = /*normalize*/(mul( matViewInverse, float4( 0, 0, 0, 1)) - inPosition ); +// +// OUTPUT: +// the new texcoord after parallaxing +float2 CalcParallaxedTexCoord( float2 inTexCoord, float2 vParallax, float3 vNormal, + float3 vViewW, sampler HeightMapSampler ) +{ + const int nMinSamples = 8; + const int nMaxSamples = 50; + + // Normalize the incoming view vector to avoid artifacts: +// vView = normalize( vView ); + vViewW = normalize( vViewW ); +// vLight = normalize( vLight ); + + // Change the number of samples per ray depending on the viewing angle + // for the surface. Oblique angles require smaller step sizes to achieve + // more accurate precision + int nNumSteps = (int) lerp( nMaxSamples, nMinSamples, dot( vViewW, vNormal ) ); + + float4 cResultColor = float4( 0, 0, 0, 1 ); + + //===============================================// + // Parallax occlusion mapping offset computation // + //===============================================// + 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 dx = ddx( inTexCoord ); + float2 dy = ddy( inTexCoord ); + + float2 vTexOffsetPerStep = fStepSize * vParallax; + + float2 vTexCurrentOffset = inTexCoord; + float fCurrentBound = 1.0; + + float x = 0; + float y = 0; + float xh = 0; + float yh = 0; + + float2 texOffset2 = 0; + + bool bCondition = true; + while ( bCondition == true && nStepIndex < nNumSteps ) + { + vTexCurrentOffset -= vTexOffsetPerStep; + + fCurrHeight = tex2Dgrad( HeightMapSampler, vTexCurrentOffset, dx, dy ).r; + + fCurrentBound -= fStepSize; + + if ( fCurrHeight > fCurrentBound ) + { + x = fCurrentBound; + y = fCurrentBound + fStepSize; + xh = fCurrHeight; + yh = fPrevHeight; + + texOffset2 = vTexCurrentOffset - vTexOffsetPerStep; + + bCondition = false; + } + else + { + nStepIndex++; + fPrevHeight = fCurrHeight; + } + + } // End of while ( bCondition == true && nStepIndex > -1 )#else + + fCurrentBound -= fStepSize; + + float fParallaxAmount; + float numerator = (x * (y - yh) - y * (x - xh)); + float denomenator = ((y - yh) - (x - xh)); + // avoid NaN generation + if( ( numerator == 0.0f ) && ( denomenator == 0.0f ) ) + { + fParallaxAmount = 0.0f; + } + else + { + fParallaxAmount = numerator / denomenator; + } + + float2 vParallaxOffset = vParallax * (1 - fParallaxAmount ); + + // Sample the height at the next possible step: + fNextHeight = tex2Dgrad( HeightMapSampler, texOffset2, dx, dy ).r; + + // Original offset: + float2 texSampleBase = inTexCoord - vParallaxOffset; + + return texSampleBase; + +#if 0 + cResultColor.rgb = ComputeDiffuseColor( texSampleBase, vLight ); + + float fBound = 1.0 - fStepSize * nStepIndex; + if ( fNextHeight < fCurrentBound ) +// if( 0 ) + { + //void DoIteration( in float2 vParallaxJittered, in float3 vLight, inout float4 cResultColor ) + //cResultColor.rgb = float3(1,0,0); + DoIteration( vParallax + vPixelSize, vLight, fStepSize, inTexCoord, nStepIndex, dx, dy, fBound, cResultColor ); + DoIteration( vParallax - vPixelSize, vLight, fStepSize, inTexCoord, nStepIndex, dx, dy, fBound, cResultColor ); + DoIteration( vParallax + float2( -vPixelSize.x, vPixelSize.y ), vLight, fStepSize, inTexCoord, nStepIndex, dx, dy, fBound, cResultColor ); + DoIteration( vParallax + float2( vPixelSize.x, -vPixelSize.y ), vLight, fStepSize, inTexCoord, nStepIndex, dx, dy, fBound, cResultColor ); + + cResultColor.rgb /= 5; +// cResultColor.rgb = float3( 1.0f, 0.0f, 0.0f ); + } // End of if ( fNextHeight < fCurrentBound ) + +#if DOSHADOWS + { + //============================================// + // Soft shadow and self-occlusion computation // + //============================================// + // Compute the blurry shadows (note that this computation takes into + // account self-occlusion for shadow computation): + float sh0 = tex2D( sNormalMap, texSampleBase).w; + float shA = (tex2D( sNormalMap, texSampleBase + inXY * 0.88 ).w - sh0 - 0.88 ) * 1 * fShadowSoftening; + float sh9 = (tex2D( sNormalMap, texSampleBase + inXY * 0.77 ).w - sh0 - 0.77 ) * 2 * fShadowSoftening; + float sh8 = (tex2D( sNormalMap, texSampleBase + inXY * 0.66 ).w - sh0 - 0.66 ) * 4 * fShadowSoftening; + float sh7 = (tex2D( sNormalMap, texSampleBase + inXY * 0.55 ).w - sh0 - 0.55 ) * 6 * fShadowSoftening; + float sh6 = (tex2D( sNormalMap, texSampleBase + inXY * 0.44 ).w - sh0 - 0.44 ) * 8 * fShadowSoftening; + float sh5 = (tex2D( sNormalMap, texSampleBase + inXY * 0.33 ).w - sh0 - 0.33 ) * 10 * fShadowSoftening; + float sh4 = (tex2D( sNormalMap, texSampleBase + inXY * 0.22 ).w - sh0 - 0.22 ) * 12 * fShadowSoftening; + + // Compute the actual shadow strength: + float fShadow = 1 - max( max( max( max( max( max( shA, sh9 ), sh8 ), sh7 ), sh6 ), sh5 ), sh4 ); + + cResultColor.rgb *= fShadow * 0.6 + 0.4; + } +#endif + + return cResultColor; +#endif +} + + +//======================================// +// HSL Color space conversion routines // +//======================================// + +#define HUE 0 +#define SATURATION 1 +#define LIGHTNESS 2 + +// Convert from RGB to HSL color space +float4 RGBtoHSL( float4 inColor ) +{ + float h, s; + float flMax = max( inColor.r, max( inColor.g, inColor.b ) ); + float flMin = min( inColor.r, min( inColor.g, inColor.b ) ); + + float l = (flMax + flMin) / 2.0f; + + if (flMax == flMin) // achromatic case + { + s = h = 0; + } + else // chromatic case + { + // Next, calculate the hue + float delta = flMax - flMin; + + // First, calculate the saturation + if (l < 0.5f) // If we're in the lower hexcone + { + s = delta/(flMax + flMin); + } + else + { + s = delta/(2 - flMax - flMin); + } + + if ( inColor.r == flMax ) + { + h = (inColor.g - inColor.b)/delta; // color between yellow and magenta + } + else if ( inColor.g == flMax ) + { + h = 2 + (inColor.b - inColor.r)/delta; // color between cyan and yellow + } + else // blue must be max + { + h = 4 + (inColor.r - inColor.g)/delta; // color between magenta and cyan + } + + h *= 60.0f; + + if (h < 0.0f) + { + h += 360.0f; + } + + h /= 360.0f; + } + + return float4 (h, s, l, 1.0f); +} + +float HueToRGB( float v1, float v2, float vH ) +{ + float fResult = v1; + + vH = fmod (vH + 1.0f, 1.0f); + + if ( ( 6.0f * vH ) < 1.0f ) + { + fResult = ( v1 + ( v2 - v1 ) * 6.0f * vH ); + } + else if ( ( 2.0f * vH ) < 1.0f ) + { + fResult = ( v2 ); + } + else if ( ( 3.0f * vH ) < 2.0f ) + { + fResult = ( v1 + ( v2 - v1 ) * ( ( 2.0f / 3.0f ) - vH ) * 6.0f ); + } + + return fResult; +} + +// Convert from HSL to RGB color space +float4 HSLtoRGB( float4 hsl ) +{ + float r, g, b; + float h = hsl[HUE]; + float s = hsl[SATURATION]; + float l = hsl[LIGHTNESS]; + + if ( s == 0 ) + { + r = g = b = l; + } + else + { + float v1, v2; + + if ( l < 0.5f ) + v2 = l * ( 1.0f + s ); + else + v2 = ( l + s ) - ( s * l ); + + v1 = 2 * l - v2; + + r = HueToRGB( v1, v2, h + ( 1.0f / 3.0f ) ); + g = HueToRGB( v1, v2, h ); + b = HueToRGB( v1, v2, h - ( 1.0f / 3.0f ) ); + } + + return float4( r, g, b, 1.0f ); +} + + +// texture combining modes for combining base and detail/basetexture2 +#define TCOMBINE_RGB_EQUALS_BASE_x_DETAILx2 0 // original mode +#define TCOMBINE_RGB_ADDITIVE 1 // base.rgb+detail.rgb*fblend +#define TCOMBINE_DETAIL_OVER_BASE 2 +#define TCOMBINE_FADE 3 // straight fade between base and detail. +#define TCOMBINE_BASE_OVER_DETAIL 4 // use base alpha for blend over detail +#define TCOMBINE_RGB_ADDITIVE_SELFILLUM 5 // add detail color post lighting +#define TCOMBINE_RGB_ADDITIVE_SELFILLUM_THRESHOLD_FADE 6 +#define TCOMBINE_MOD2X_SELECT_TWO_PATTERNS 7 // use alpha channel of base to select between mod2x channels in r+a of detail +#define TCOMBINE_MULTIPLY 8 +#define TCOMBINE_MASK_BASE_BY_DETAIL_ALPHA 9 // use alpha channel of detail to mask base +#define TCOMBINE_SSBUMP_BUMP 10 // use detail to modulate lighting as an ssbump +#define TCOMBINE_SSBUMP_NOBUMP 11 // detail is an ssbump but use it as an albedo. shader does the magic here - no user needs to specify mode 11 + +float4 TextureCombine( float4 baseColor, float4 detailColor, int combine_mode, + float fBlendFactor ) +{ + if ( combine_mode == TCOMBINE_MOD2X_SELECT_TWO_PATTERNS) + { + float3 dc=lerp(detailColor.r,detailColor.a, baseColor.a); + baseColor.rgb*=lerp(float3(1,1,1),2.0*dc,fBlendFactor); + } + if ( combine_mode == TCOMBINE_RGB_EQUALS_BASE_x_DETAILx2) + baseColor.rgb*=lerp(float3(1,1,1),2.0*detailColor.rgb,fBlendFactor); + if ( combine_mode == TCOMBINE_RGB_ADDITIVE ) + baseColor.rgb += fBlendFactor * detailColor.rgb; + if ( combine_mode == TCOMBINE_DETAIL_OVER_BASE ) + { + float fblend=fBlendFactor * detailColor.a; + baseColor.rgb = lerp( baseColor.rgb, detailColor.rgb, fblend); + } + if ( combine_mode == TCOMBINE_FADE ) + { + baseColor = lerp( baseColor, detailColor, fBlendFactor); + } + if ( combine_mode == TCOMBINE_BASE_OVER_DETAIL ) + { + float fblend=fBlendFactor * (1-baseColor.a); + baseColor.rgb = lerp( baseColor.rgb, detailColor.rgb, fblend ); + baseColor.a = detailColor.a; + } + if ( combine_mode == TCOMBINE_MULTIPLY ) + { + baseColor = lerp( baseColor, baseColor*detailColor, fBlendFactor); + } + + if (combine_mode == TCOMBINE_MASK_BASE_BY_DETAIL_ALPHA ) + { + baseColor.a = lerp( baseColor.a, baseColor.a*detailColor.a, fBlendFactor ); + } + if ( combine_mode == TCOMBINE_SSBUMP_NOBUMP ) + { + baseColor.rgb = baseColor.rgb * dot( detailColor.rgb, 2.0/3.0 ); + } + return baseColor; +} + +float3 lerp5(float3 f1, float3 f2, float i1, float i2, float x) +{ + return f1+(f2-f1)*(x-i1)/(i2-i1); +} + +float3 TextureCombinePostLighting( float3 lit_baseColor, float4 detailColor, int combine_mode, + float fBlendFactor ) +{ + if ( combine_mode == TCOMBINE_RGB_ADDITIVE_SELFILLUM ) + lit_baseColor += fBlendFactor * detailColor.rgb; + if ( combine_mode == TCOMBINE_RGB_ADDITIVE_SELFILLUM_THRESHOLD_FADE ) + { + // fade in an unusual way - instead of fading out color, remap an increasing band of it from + // 0..1 + //if (fBlendFactor > 0.5) + // lit_baseColor += min(1, (1.0/fBlendFactor)*max(0, detailColor.rgb-(1-fBlendFactor) ) ); + //else + // lit_baseColor += 2*fBlendFactor*2*max(0, detailColor.rgb-.5); + + float f = fBlendFactor - 0.5; + float fMult = (f >= 0) ? 1.0/fBlendFactor : 4*fBlendFactor; + float fAdd = (f >= 0) ? 1.0-fMult : -0.5*fMult; + lit_baseColor += saturate(fMult * detailColor.rgb + fAdd); + } + return lit_baseColor; +} + +//NOTE: On X360. fProjZ is expected to be pre-reversed for cheaper math here in the pixel shader +float DepthFeathering( sampler DepthSampler, const float2 vScreenPos, float fProjZ, float fProjW, float4 vDepthBlendConstants ) +{ +# if ( !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) ) //minimum requirement of ps2b + { + float flFeatheredAlpha; + float2 flDepths; +#define flSceneDepth flDepths.x +#define flSpriteDepth flDepths.y + +# if ( defined( _X360 ) ) + { + //Get depth from the depth texture. Need to sample with the offset of (0.5, 0.5) to fix rounding errors + asm { + tfetch2D flDepths.x___, vScreenPos, DepthSampler, OffsetX=0.5, OffsetY=0.5, MinFilter=point, MagFilter=point, MipFilter=point + }; + +# if( !defined( REVERSE_DEPTH_ON_X360 ) ) + flSceneDepth = 1.0f - flSceneDepth; +# endif + + //get the sprite depth into the same range as the texture depth + flSpriteDepth = fProjZ / fProjW; + + //unproject to get at the pre-projection z. This value is much more linear than depth + flDepths = vDepthBlendConstants.z / flDepths; + flDepths = vDepthBlendConstants.y - flDepths; + + flFeatheredAlpha = flSceneDepth - flSpriteDepth; + flFeatheredAlpha *= vDepthBlendConstants.x; + flFeatheredAlpha = saturate( flFeatheredAlpha ); + } +# else + { + flSceneDepth = tex2D( DepthSampler, vScreenPos ).a; // PC uses dest alpha of the frame buffer + flSpriteDepth = SoftParticleDepth( fProjZ ); + + flFeatheredAlpha = abs(flSceneDepth - flSpriteDepth) * vDepthBlendConstants.x; + flFeatheredAlpha = max( smoothstep( 0.75f, 1.0f, flSceneDepth ), flFeatheredAlpha ); //as the sprite approaches the edge of our compressed depth space, the math stops working. So as the sprite approaches the far depth, smoothly remove feathering. + flFeatheredAlpha = saturate( flFeatheredAlpha ); + } +# endif + +#undef flSceneDepth +#undef flSpriteDepth + + return flFeatheredAlpha; + } +# else + { + return 1.0f; + } +# endif +} + +#endif //#ifndef COMMON_PS_FXC_H_ diff --git a/mp/src/materialsystem/stdshaders/common_vertexlitgeneric_dx9.h b/mp/src/materialsystem/stdshaders/common_vertexlitgeneric_dx9.h index 66cc642a..2eb7bb3c 100644 --- a/mp/src/materialsystem/stdshaders/common_vertexlitgeneric_dx9.h +++ b/mp/src/materialsystem/stdshaders/common_vertexlitgeneric_dx9.h @@ -1,423 +1,423 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -#ifndef COMMON_VERTEXLITGENERIC_DX9_H_ -#define COMMON_VERTEXLITGENERIC_DX9_H_ - -#include "common_ps_fxc.h" - -// We store four light colors and positions in an -// array of three of these structures like so: -// -// x y z w -// +------+------+------+------+ -// | L0.rgb | | -// +------+------+------+ | -// | L0.pos | L3 | -// +------+------+------+ rgb | -// | L1.rgb | | -// +------+------+------+------+ -// | L1.pos | | -// +------+------+------+ | -// | L2.rgb | L3 | -// +------+------+------+ pos | -// | L2.pos | | -// +------+------+------+------+ -// -struct PixelShaderLightInfo -{ - float4 color; - float4 pos; -}; - -#define cOverbright 2.0f -#define cOOOverbright 0.5f - -#define LIGHTTYPE_NONE 0 -#define LIGHTTYPE_SPOT 1 -#define LIGHTTYPE_POINT 2 -#define LIGHTTYPE_DIRECTIONAL 3 - -// Better suited to Pixel shader models, 11 instructions in pixel shader -// ... actually, now only 9: mul, cmp, cmp, mul, mad, mad, mad, mad, mad -float3 PixelShaderAmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) -{ - float3 linearColor, nSquared = worldNormal * worldNormal; - float3 isNegative = ( worldNormal >= 0.0 ) ? 0 : nSquared; - float3 isPositive = ( worldNormal >= 0.0 ) ? nSquared : 0; - linearColor = isPositive.x * cAmbientCube[0] + isNegative.x * cAmbientCube[1] + - isPositive.y * cAmbientCube[2] + isNegative.y * cAmbientCube[3] + - isPositive.z * cAmbientCube[4] + isNegative.z * cAmbientCube[5]; - return linearColor; -} - -// Better suited to Vertex shader models -// Six VS instructions due to use of constant indexing (slt, mova, mul, mul, mad, mad) -float3 VertexShaderAmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) -{ - float3 nSquared = worldNormal * worldNormal; - int3 isNegative = ( worldNormal < 0.0 ); - float3 linearColor; - linearColor = nSquared.x * cAmbientCube[isNegative.x] + - nSquared.y * cAmbientCube[isNegative.y+2] + - nSquared.z * cAmbientCube[isNegative.z+4]; - return linearColor; -} - -float3 AmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) -{ - // Vertex shader cases -#ifdef SHADER_MODEL_VS_1_0 - return VertexShaderAmbientLight( worldNormal, cAmbientCube ); -#elif SHADER_MODEL_VS_1_1 - return VertexShaderAmbientLight( worldNormal, cAmbientCube ); -#elif SHADER_MODEL_VS_2_0 - return VertexShaderAmbientLight( worldNormal, cAmbientCube ); -#elif SHADER_MODEL_VS_3_0 - return VertexShaderAmbientLight( worldNormal, cAmbientCube ); -#else - // Pixel shader case - return PixelShaderAmbientLight( worldNormal, cAmbientCube ); -#endif -} - -//----------------------------------------------------------------------------- -// Purpose: Compute scalar diffuse term with various optional tweaks such as -// Half Lambert and ambient occlusion -//----------------------------------------------------------------------------- -float3 DiffuseTerm(const bool bHalfLambert, const float3 worldNormal, const float3 lightDir, - const bool bDoAmbientOcclusion, const float fAmbientOcclusion, - const bool bDoLightingWarp, in sampler lightWarpSampler ) -{ - float fResult; - - float NDotL = dot( worldNormal, lightDir ); // Unsaturated dot (-1 to 1 range) - - if ( bHalfLambert ) - { - fResult = saturate(NDotL * 0.5 + 0.5); // Scale and bias to 0 to 1 range - - if ( !bDoLightingWarp ) - { - fResult *= fResult; // Square - } - } - else - { - fResult = saturate( NDotL ); // Saturate pure Lambertian term - } - - if ( bDoAmbientOcclusion ) - { - // Raise to higher powers for darker AO values -// float fAOPower = lerp( 4.0f, 1.0f, fAmbientOcclusion ); -// result *= pow( NDotL * 0.5 + 0.5, fAOPower ); - fResult *= fAmbientOcclusion; - } - - float3 fOut = float3( fResult, fResult, fResult ); - if ( bDoLightingWarp ) - { - fOut = 2.0f * tex1D( lightWarpSampler, fResult ); - } - - return fOut; -} - -float3 PixelShaderDoGeneralDiffuseLight( const float fAtten, const float3 worldPos, const float3 worldNormal, - in sampler NormalizeSampler, - const float3 vPosition, const float3 vColor, const bool bHalfLambert, - const bool bDoAmbientOcclusion, const float fAmbientOcclusion, - const bool bDoLightingWarp, in sampler lightWarpSampler ) -{ -#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) - float3 lightDir = normalize( vPosition - worldPos ); -#else - float3 lightDir = NormalizeWithCubemap( NormalizeSampler, vPosition - worldPos ); -#endif - return vColor * fAtten * DiffuseTerm( bHalfLambert, worldNormal, lightDir, bDoAmbientOcclusion, fAmbientOcclusion, bDoLightingWarp, lightWarpSampler ); -} - -float3 PixelShaderGetLightVector( const float3 worldPos, PixelShaderLightInfo cLightInfo[3], int nLightIndex ) -{ - if ( nLightIndex == 3 ) - { - // Unpack light 3 from w components... - float3 vLight3Pos = float3( cLightInfo[1].pos.w, cLightInfo[2].color.w, cLightInfo[2].pos.w ); - return normalize( vLight3Pos - worldPos ); - } - else - { - return normalize( cLightInfo[nLightIndex].pos - worldPos ); - } -} - -float3 PixelShaderGetLightColor( PixelShaderLightInfo cLightInfo[3], int nLightIndex ) -{ - if ( nLightIndex == 3 ) - { - // Unpack light 3 from w components... - return float3( cLightInfo[0].color.w, cLightInfo[0].pos.w, cLightInfo[1].color.w ); - } - else - { - return cLightInfo[nLightIndex].color.rgb; - } -} - - -void SpecularAndRimTerms( const float3 vWorldNormal, const float3 vLightDir, const float fSpecularExponent, - const float3 vEyeDir, const bool bDoAmbientOcclusion, const float fAmbientOcclusion, - const bool bDoSpecularWarp, in sampler specularWarpSampler, const float fFresnel, - const float3 color, const bool bDoRimLighting, const float fRimExponent, - - // Outputs - out float3 specularLighting, out float3 rimLighting ) -{ - rimLighting = float3(0.0f, 0.0f, 0.0f); - - //float3 vReflect = reflect( -vEyeDir, vWorldNormal ); // Reflect view through normal - float3 vReflect = 2 * vWorldNormal * dot( vWorldNormal , vEyeDir ) - vEyeDir; // Reflect view through normal - float LdotR = saturate(dot( vReflect, vLightDir )); // L.R (use half-angle instead?) - specularLighting = pow( LdotR, fSpecularExponent ); // Raise to specular exponent - - // Optionally warp as function of scalar specular and fresnel - if ( bDoSpecularWarp ) - specularLighting *= tex2D( specularWarpSampler, float2(specularLighting.x, fFresnel) ); // Sample at { (L.R)^k, fresnel } - - specularLighting *= saturate(dot( vWorldNormal, vLightDir )); // Mask with N.L - specularLighting *= color; // Modulate with light color - - if ( bDoAmbientOcclusion ) // Optionally modulate with ambient occlusion - specularLighting *= fAmbientOcclusion; - - if ( bDoRimLighting ) // Optionally do rim lighting - { - rimLighting = pow( LdotR, fRimExponent ); // Raise to rim exponent - rimLighting *= saturate(dot( vWorldNormal, vLightDir )); // Mask with N.L - rimLighting *= color; // Modulate with light color - } -} - -// Traditional fresnel term approximation -float Fresnel( const float3 vNormal, const float3 vEyeDir ) -{ - float fresnel = saturate( 1 - dot( vNormal, vEyeDir ) ); // 1-(N.V) for Fresnel term - return fresnel * fresnel; // Square for a more subtle look -} - -// Traditional fresnel term approximation which uses 4th power (square twice) -float Fresnel4( const float3 vNormal, const float3 vEyeDir ) -{ - float fresnel = saturate( 1 - dot( vNormal, vEyeDir ) ); // 1-(N.V) for Fresnel term - fresnel = fresnel * fresnel; // Square - return fresnel * fresnel; // Square again for a more subtle look -} - - -// -// Custom Fresnel with low, mid and high parameters defining a piecewise continuous function -// with traditional fresnel (0 to 1 range) as input. The 0 to 0.5 range blends between -// low and mid while the 0.5 to 1 range blends between mid and high -// -// | -// | . M . . . H -// | . -// L -// | -// +---------------- -// 0 1 -// -float Fresnel( const float3 vNormal, const float3 vEyeDir, float3 vRanges ) -{ - //float result, f = Fresnel( vNormal, vEyeDir ); // Traditional Fresnel - //if ( f > 0.5f ) - // result = lerp( vRanges.y, vRanges.z, (2*f)-1 ); // Blend between mid and high values - //else - // result = lerp( vRanges.x, vRanges.y, 2*f ); // Blend between low and mid values - - // note: vRanges is now encoded as ((mid-min)*2, mid, (max-mid)*2) to optimize math - float f = saturate( 1 - dot( vNormal, vEyeDir ) ); - f = f*f - 0.5; - return vRanges.y + (f >= 0.0 ? vRanges.z : vRanges.x) * f; -} - -void PixelShaderDoSpecularLight( const float3 vWorldPos, const float3 vWorldNormal, const float fSpecularExponent, const float3 vEyeDir, - const float fAtten, const float3 vLightColor, const float3 vLightDir, - const bool bDoAmbientOcclusion, const float fAmbientOcclusion, - const bool bDoSpecularWarp, in sampler specularWarpSampler, float fFresnel, - const bool bDoRimLighting, const float fRimExponent, - - // Outputs - out float3 specularLighting, out float3 rimLighting ) -{ - // Compute Specular and rim terms - SpecularAndRimTerms( vWorldNormal, vLightDir, fSpecularExponent, - vEyeDir, bDoAmbientOcclusion, fAmbientOcclusion, - bDoSpecularWarp, specularWarpSampler, fFresnel, vLightColor * fAtten, - bDoRimLighting, fRimExponent, specularLighting, rimLighting ); -} - -float3 PixelShaderDoLightingLinear( const float3 worldPos, const float3 worldNormal, - const float3 staticLightingColor, const bool bStaticLight, - const bool bAmbientLight, const float4 lightAtten, const float3 cAmbientCube[6], - in sampler NormalizeSampler, const int nNumLights, PixelShaderLightInfo cLightInfo[3], - const bool bHalfLambert, const bool bDoAmbientOcclusion, const float fAmbientOcclusion, - const bool bDoLightingWarp, in sampler lightWarpSampler ) -{ - float3 linearColor = 0.0f; - - if ( bStaticLight ) - { - // The static lighting comes in in gamma space and has also been premultiplied by $cOOOverbright - // need to get it into - // linear space so that we can do adds. - linearColor += GammaToLinear( staticLightingColor * cOverbright ); - } - - if ( bAmbientLight ) - { - float3 ambient = AmbientLight( worldNormal, cAmbientCube ); - - if ( bDoAmbientOcclusion ) - ambient *= fAmbientOcclusion * fAmbientOcclusion; // Note squaring... - - linearColor += ambient; - } - - if ( nNumLights > 0 ) - { - linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.x, worldPos, worldNormal, NormalizeSampler, - cLightInfo[0].pos, cLightInfo[0].color, bHalfLambert, - bDoAmbientOcclusion, fAmbientOcclusion, - bDoLightingWarp, lightWarpSampler ); - if ( nNumLights > 1 ) - { - linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.y, worldPos, worldNormal, NormalizeSampler, - cLightInfo[1].pos, cLightInfo[1].color, bHalfLambert, - bDoAmbientOcclusion, fAmbientOcclusion, - bDoLightingWarp, lightWarpSampler ); - if ( nNumLights > 2 ) - { - linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.z, worldPos, worldNormal, NormalizeSampler, - cLightInfo[2].pos, cLightInfo[2].color, bHalfLambert, - bDoAmbientOcclusion, fAmbientOcclusion, - bDoLightingWarp, lightWarpSampler ); - if ( nNumLights > 3 ) - { - // Unpack the 4th light's data from tight constant packing - float3 vLight3Color = float3( cLightInfo[0].color.w, cLightInfo[0].pos.w, cLightInfo[1].color.w ); - float3 vLight3Pos = float3( cLightInfo[1].pos.w, cLightInfo[2].color.w, cLightInfo[2].pos.w ); - linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.w, worldPos, worldNormal, NormalizeSampler, - vLight3Pos, vLight3Color, bHalfLambert, - bDoAmbientOcclusion, fAmbientOcclusion, - bDoLightingWarp, lightWarpSampler ); - } - } - } - } - - return linearColor; -} - -void PixelShaderDoSpecularLighting( const float3 worldPos, const float3 worldNormal, const float fSpecularExponent, const float3 vEyeDir, - const float4 lightAtten, const int nNumLights, PixelShaderLightInfo cLightInfo[3], - const bool bDoAmbientOcclusion, const float fAmbientOcclusion, - const bool bDoSpecularWarp, in sampler specularWarpSampler, float fFresnel, - const bool bDoRimLighting, const float fRimExponent, - - // Outputs - out float3 specularLighting, out float3 rimLighting ) -{ - specularLighting = rimLighting = float3( 0.0f, 0.0f, 0.0f ); - float3 localSpecularTerm, localRimTerm; - - if( nNumLights > 0 ) - { - PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, - lightAtten.x, PixelShaderGetLightColor( cLightInfo, 0 ), - PixelShaderGetLightVector( worldPos, cLightInfo, 0 ), - bDoAmbientOcclusion, fAmbientOcclusion, - bDoSpecularWarp, specularWarpSampler, fFresnel, - bDoRimLighting, fRimExponent, - localSpecularTerm, localRimTerm ); - - specularLighting += localSpecularTerm; // Accumulate specular and rim terms - rimLighting += localRimTerm; - } - - if( nNumLights > 1 ) - { - PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, - lightAtten.y, PixelShaderGetLightColor( cLightInfo, 1 ), - PixelShaderGetLightVector( worldPos, cLightInfo, 1 ), - bDoAmbientOcclusion, fAmbientOcclusion, - bDoSpecularWarp, specularWarpSampler, fFresnel, - bDoRimLighting, fRimExponent, - localSpecularTerm, localRimTerm ); - - specularLighting += localSpecularTerm; // Accumulate specular and rim terms - rimLighting += localRimTerm; - } - - - if( nNumLights > 2 ) - { - PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, - lightAtten.z, PixelShaderGetLightColor( cLightInfo, 2 ), - PixelShaderGetLightVector( worldPos, cLightInfo, 2 ), - bDoAmbientOcclusion, fAmbientOcclusion, - bDoSpecularWarp, specularWarpSampler, fFresnel, - bDoRimLighting, fRimExponent, - localSpecularTerm, localRimTerm ); - - specularLighting += localSpecularTerm; // Accumulate specular and rim terms - rimLighting += localRimTerm; - } - - if( nNumLights > 3 ) - { - PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, - lightAtten.w, PixelShaderGetLightColor( cLightInfo, 3 ), - PixelShaderGetLightVector( worldPos, cLightInfo, 3 ), - bDoAmbientOcclusion, fAmbientOcclusion, - bDoSpecularWarp, specularWarpSampler, fFresnel, - bDoRimLighting, fRimExponent, - localSpecularTerm, localRimTerm ); - - specularLighting += localSpecularTerm; // Accumulate specular and rim terms - rimLighting += localRimTerm; - } - -} - -float3 PixelShaderDoRimLighting( const float3 worldNormal, const float3 vEyeDir, const float3 cAmbientCube[6], float fFresnel ) -{ - float3 vReflect = reflect( -vEyeDir, worldNormal ); // Reflect view through normal - - return fFresnel * PixelShaderAmbientLight( vEyeDir, cAmbientCube ); -} - -// Called directly by newer shaders or through the following wrapper for older shaders -float3 PixelShaderDoLighting( const float3 worldPos, const float3 worldNormal, - const float3 staticLightingColor, const bool bStaticLight, - const bool bAmbientLight, const float4 lightAtten, const float3 cAmbientCube[6], - in sampler NormalizeSampler, const int nNumLights, PixelShaderLightInfo cLightInfo[3], - const bool bHalfLambert, - - // New optional/experimental parameters - const bool bDoAmbientOcclusion, const float fAmbientOcclusion, - const bool bDoLightingWarp, in sampler lightWarpSampler ) -{ - float3 linearColor = PixelShaderDoLightingLinear( worldPos, worldNormal, staticLightingColor, - bStaticLight, bAmbientLight, lightAtten, - cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, bHalfLambert, - bDoAmbientOcclusion, fAmbientOcclusion, - bDoLightingWarp, lightWarpSampler ); - - // go ahead and clamp to the linear space equivalent of overbright 2 so that we match - // everything else. -// linearColor = HuePreservingColorClamp( linearColor, pow( 2.0f, 2.2 ) ); - - return linearColor; -} - -#endif //#ifndef COMMON_VERTEXLITGENERIC_DX9_H_ +//========= Copyright Valve Corporation, All rights reserved. ============// +#ifndef COMMON_VERTEXLITGENERIC_DX9_H_ +#define COMMON_VERTEXLITGENERIC_DX9_H_ + +#include "common_ps_fxc.h" + +// We store four light colors and positions in an +// array of three of these structures like so: +// +// x y z w +// +------+------+------+------+ +// | L0.rgb | | +// +------+------+------+ | +// | L0.pos | L3 | +// +------+------+------+ rgb | +// | L1.rgb | | +// +------+------+------+------+ +// | L1.pos | | +// +------+------+------+ | +// | L2.rgb | L3 | +// +------+------+------+ pos | +// | L2.pos | | +// +------+------+------+------+ +// +struct PixelShaderLightInfo +{ + float4 color; + float4 pos; +}; + +#define cOverbright 2.0f +#define cOOOverbright 0.5f + +#define LIGHTTYPE_NONE 0 +#define LIGHTTYPE_SPOT 1 +#define LIGHTTYPE_POINT 2 +#define LIGHTTYPE_DIRECTIONAL 3 + +// Better suited to Pixel shader models, 11 instructions in pixel shader +// ... actually, now only 9: mul, cmp, cmp, mul, mad, mad, mad, mad, mad +float3 PixelShaderAmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) +{ + float3 linearColor, nSquared = worldNormal * worldNormal; + float3 isNegative = ( worldNormal >= 0.0 ) ? 0 : nSquared; + float3 isPositive = ( worldNormal >= 0.0 ) ? nSquared : 0; + linearColor = isPositive.x * cAmbientCube[0] + isNegative.x * cAmbientCube[1] + + isPositive.y * cAmbientCube[2] + isNegative.y * cAmbientCube[3] + + isPositive.z * cAmbientCube[4] + isNegative.z * cAmbientCube[5]; + return linearColor; +} + +// Better suited to Vertex shader models +// Six VS instructions due to use of constant indexing (slt, mova, mul, mul, mad, mad) +float3 VertexShaderAmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) +{ + float3 nSquared = worldNormal * worldNormal; + int3 isNegative = ( worldNormal < 0.0 ); + float3 linearColor; + linearColor = nSquared.x * cAmbientCube[isNegative.x] + + nSquared.y * cAmbientCube[isNegative.y+2] + + nSquared.z * cAmbientCube[isNegative.z+4]; + return linearColor; +} + +float3 AmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) +{ + // Vertex shader cases +#ifdef SHADER_MODEL_VS_1_0 + return VertexShaderAmbientLight( worldNormal, cAmbientCube ); +#elif SHADER_MODEL_VS_1_1 + return VertexShaderAmbientLight( worldNormal, cAmbientCube ); +#elif SHADER_MODEL_VS_2_0 + return VertexShaderAmbientLight( worldNormal, cAmbientCube ); +#elif SHADER_MODEL_VS_3_0 + return VertexShaderAmbientLight( worldNormal, cAmbientCube ); +#else + // Pixel shader case + return PixelShaderAmbientLight( worldNormal, cAmbientCube ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: Compute scalar diffuse term with various optional tweaks such as +// Half Lambert and ambient occlusion +//----------------------------------------------------------------------------- +float3 DiffuseTerm(const bool bHalfLambert, const float3 worldNormal, const float3 lightDir, + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoLightingWarp, in sampler lightWarpSampler ) +{ + float fResult; + + float NDotL = dot( worldNormal, lightDir ); // Unsaturated dot (-1 to 1 range) + + if ( bHalfLambert ) + { + fResult = saturate(NDotL * 0.5 + 0.5); // Scale and bias to 0 to 1 range + + if ( !bDoLightingWarp ) + { + fResult *= fResult; // Square + } + } + else + { + fResult = saturate( NDotL ); // Saturate pure Lambertian term + } + + if ( bDoAmbientOcclusion ) + { + // Raise to higher powers for darker AO values +// float fAOPower = lerp( 4.0f, 1.0f, fAmbientOcclusion ); +// result *= pow( NDotL * 0.5 + 0.5, fAOPower ); + fResult *= fAmbientOcclusion; + } + + float3 fOut = float3( fResult, fResult, fResult ); + if ( bDoLightingWarp ) + { + fOut = 2.0f * tex1D( lightWarpSampler, fResult ); + } + + return fOut; +} + +float3 PixelShaderDoGeneralDiffuseLight( const float fAtten, const float3 worldPos, const float3 worldNormal, + in sampler NormalizeSampler, + const float3 vPosition, const float3 vColor, const bool bHalfLambert, + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoLightingWarp, in sampler lightWarpSampler ) +{ +#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) + float3 lightDir = normalize( vPosition - worldPos ); +#else + float3 lightDir = NormalizeWithCubemap( NormalizeSampler, vPosition - worldPos ); +#endif + return vColor * fAtten * DiffuseTerm( bHalfLambert, worldNormal, lightDir, bDoAmbientOcclusion, fAmbientOcclusion, bDoLightingWarp, lightWarpSampler ); +} + +float3 PixelShaderGetLightVector( const float3 worldPos, PixelShaderLightInfo cLightInfo[3], int nLightIndex ) +{ + if ( nLightIndex == 3 ) + { + // Unpack light 3 from w components... + float3 vLight3Pos = float3( cLightInfo[1].pos.w, cLightInfo[2].color.w, cLightInfo[2].pos.w ); + return normalize( vLight3Pos - worldPos ); + } + else + { + return normalize( cLightInfo[nLightIndex].pos - worldPos ); + } +} + +float3 PixelShaderGetLightColor( PixelShaderLightInfo cLightInfo[3], int nLightIndex ) +{ + if ( nLightIndex == 3 ) + { + // Unpack light 3 from w components... + return float3( cLightInfo[0].color.w, cLightInfo[0].pos.w, cLightInfo[1].color.w ); + } + else + { + return cLightInfo[nLightIndex].color.rgb; + } +} + + +void SpecularAndRimTerms( const float3 vWorldNormal, const float3 vLightDir, const float fSpecularExponent, + const float3 vEyeDir, const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoSpecularWarp, in sampler specularWarpSampler, const float fFresnel, + const float3 color, const bool bDoRimLighting, const float fRimExponent, + + // Outputs + out float3 specularLighting, out float3 rimLighting ) +{ + rimLighting = float3(0.0f, 0.0f, 0.0f); + + //float3 vReflect = reflect( -vEyeDir, vWorldNormal ); // Reflect view through normal + float3 vReflect = 2 * vWorldNormal * dot( vWorldNormal , vEyeDir ) - vEyeDir; // Reflect view through normal + float LdotR = saturate(dot( vReflect, vLightDir )); // L.R (use half-angle instead?) + specularLighting = pow( LdotR, fSpecularExponent ); // Raise to specular exponent + + // Optionally warp as function of scalar specular and fresnel + if ( bDoSpecularWarp ) + specularLighting *= tex2D( specularWarpSampler, float2(specularLighting.x, fFresnel) ); // Sample at { (L.R)^k, fresnel } + + specularLighting *= saturate(dot( vWorldNormal, vLightDir )); // Mask with N.L + specularLighting *= color; // Modulate with light color + + if ( bDoAmbientOcclusion ) // Optionally modulate with ambient occlusion + specularLighting *= fAmbientOcclusion; + + if ( bDoRimLighting ) // Optionally do rim lighting + { + rimLighting = pow( LdotR, fRimExponent ); // Raise to rim exponent + rimLighting *= saturate(dot( vWorldNormal, vLightDir )); // Mask with N.L + rimLighting *= color; // Modulate with light color + } +} + +// Traditional fresnel term approximation +float Fresnel( const float3 vNormal, const float3 vEyeDir ) +{ + float fresnel = saturate( 1 - dot( vNormal, vEyeDir ) ); // 1-(N.V) for Fresnel term + return fresnel * fresnel; // Square for a more subtle look +} + +// Traditional fresnel term approximation which uses 4th power (square twice) +float Fresnel4( const float3 vNormal, const float3 vEyeDir ) +{ + float fresnel = saturate( 1 - dot( vNormal, vEyeDir ) ); // 1-(N.V) for Fresnel term + fresnel = fresnel * fresnel; // Square + return fresnel * fresnel; // Square again for a more subtle look +} + + +// +// Custom Fresnel with low, mid and high parameters defining a piecewise continuous function +// with traditional fresnel (0 to 1 range) as input. The 0 to 0.5 range blends between +// low and mid while the 0.5 to 1 range blends between mid and high +// +// | +// | . M . . . H +// | . +// L +// | +// +---------------- +// 0 1 +// +float Fresnel( const float3 vNormal, const float3 vEyeDir, float3 vRanges ) +{ + //float result, f = Fresnel( vNormal, vEyeDir ); // Traditional Fresnel + //if ( f > 0.5f ) + // result = lerp( vRanges.y, vRanges.z, (2*f)-1 ); // Blend between mid and high values + //else + // result = lerp( vRanges.x, vRanges.y, 2*f ); // Blend between low and mid values + + // note: vRanges is now encoded as ((mid-min)*2, mid, (max-mid)*2) to optimize math + float f = saturate( 1 - dot( vNormal, vEyeDir ) ); + f = f*f - 0.5; + return vRanges.y + (f >= 0.0 ? vRanges.z : vRanges.x) * f; +} + +void PixelShaderDoSpecularLight( const float3 vWorldPos, const float3 vWorldNormal, const float fSpecularExponent, const float3 vEyeDir, + const float fAtten, const float3 vLightColor, const float3 vLightDir, + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoSpecularWarp, in sampler specularWarpSampler, float fFresnel, + const bool bDoRimLighting, const float fRimExponent, + + // Outputs + out float3 specularLighting, out float3 rimLighting ) +{ + // Compute Specular and rim terms + SpecularAndRimTerms( vWorldNormal, vLightDir, fSpecularExponent, + vEyeDir, bDoAmbientOcclusion, fAmbientOcclusion, + bDoSpecularWarp, specularWarpSampler, fFresnel, vLightColor * fAtten, + bDoRimLighting, fRimExponent, specularLighting, rimLighting ); +} + +float3 PixelShaderDoLightingLinear( const float3 worldPos, const float3 worldNormal, + const float3 staticLightingColor, const bool bStaticLight, + const bool bAmbientLight, const float4 lightAtten, const float3 cAmbientCube[6], + in sampler NormalizeSampler, const int nNumLights, PixelShaderLightInfo cLightInfo[3], + const bool bHalfLambert, const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoLightingWarp, in sampler lightWarpSampler ) +{ + float3 linearColor = 0.0f; + + if ( bStaticLight ) + { + // The static lighting comes in in gamma space and has also been premultiplied by $cOOOverbright + // need to get it into + // linear space so that we can do adds. + linearColor += GammaToLinear( staticLightingColor * cOverbright ); + } + + if ( bAmbientLight ) + { + float3 ambient = AmbientLight( worldNormal, cAmbientCube ); + + if ( bDoAmbientOcclusion ) + ambient *= fAmbientOcclusion * fAmbientOcclusion; // Note squaring... + + linearColor += ambient; + } + + if ( nNumLights > 0 ) + { + linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.x, worldPos, worldNormal, NormalizeSampler, + cLightInfo[0].pos, cLightInfo[0].color, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion, + bDoLightingWarp, lightWarpSampler ); + if ( nNumLights > 1 ) + { + linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.y, worldPos, worldNormal, NormalizeSampler, + cLightInfo[1].pos, cLightInfo[1].color, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion, + bDoLightingWarp, lightWarpSampler ); + if ( nNumLights > 2 ) + { + linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.z, worldPos, worldNormal, NormalizeSampler, + cLightInfo[2].pos, cLightInfo[2].color, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion, + bDoLightingWarp, lightWarpSampler ); + if ( nNumLights > 3 ) + { + // Unpack the 4th light's data from tight constant packing + float3 vLight3Color = float3( cLightInfo[0].color.w, cLightInfo[0].pos.w, cLightInfo[1].color.w ); + float3 vLight3Pos = float3( cLightInfo[1].pos.w, cLightInfo[2].color.w, cLightInfo[2].pos.w ); + linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.w, worldPos, worldNormal, NormalizeSampler, + vLight3Pos, vLight3Color, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion, + bDoLightingWarp, lightWarpSampler ); + } + } + } + } + + return linearColor; +} + +void PixelShaderDoSpecularLighting( const float3 worldPos, const float3 worldNormal, const float fSpecularExponent, const float3 vEyeDir, + const float4 lightAtten, const int nNumLights, PixelShaderLightInfo cLightInfo[3], + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoSpecularWarp, in sampler specularWarpSampler, float fFresnel, + const bool bDoRimLighting, const float fRimExponent, + + // Outputs + out float3 specularLighting, out float3 rimLighting ) +{ + specularLighting = rimLighting = float3( 0.0f, 0.0f, 0.0f ); + float3 localSpecularTerm, localRimTerm; + + if( nNumLights > 0 ) + { + PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, + lightAtten.x, PixelShaderGetLightColor( cLightInfo, 0 ), + PixelShaderGetLightVector( worldPos, cLightInfo, 0 ), + bDoAmbientOcclusion, fAmbientOcclusion, + bDoSpecularWarp, specularWarpSampler, fFresnel, + bDoRimLighting, fRimExponent, + localSpecularTerm, localRimTerm ); + + specularLighting += localSpecularTerm; // Accumulate specular and rim terms + rimLighting += localRimTerm; + } + + if( nNumLights > 1 ) + { + PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, + lightAtten.y, PixelShaderGetLightColor( cLightInfo, 1 ), + PixelShaderGetLightVector( worldPos, cLightInfo, 1 ), + bDoAmbientOcclusion, fAmbientOcclusion, + bDoSpecularWarp, specularWarpSampler, fFresnel, + bDoRimLighting, fRimExponent, + localSpecularTerm, localRimTerm ); + + specularLighting += localSpecularTerm; // Accumulate specular and rim terms + rimLighting += localRimTerm; + } + + + if( nNumLights > 2 ) + { + PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, + lightAtten.z, PixelShaderGetLightColor( cLightInfo, 2 ), + PixelShaderGetLightVector( worldPos, cLightInfo, 2 ), + bDoAmbientOcclusion, fAmbientOcclusion, + bDoSpecularWarp, specularWarpSampler, fFresnel, + bDoRimLighting, fRimExponent, + localSpecularTerm, localRimTerm ); + + specularLighting += localSpecularTerm; // Accumulate specular and rim terms + rimLighting += localRimTerm; + } + + if( nNumLights > 3 ) + { + PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, + lightAtten.w, PixelShaderGetLightColor( cLightInfo, 3 ), + PixelShaderGetLightVector( worldPos, cLightInfo, 3 ), + bDoAmbientOcclusion, fAmbientOcclusion, + bDoSpecularWarp, specularWarpSampler, fFresnel, + bDoRimLighting, fRimExponent, + localSpecularTerm, localRimTerm ); + + specularLighting += localSpecularTerm; // Accumulate specular and rim terms + rimLighting += localRimTerm; + } + +} + +float3 PixelShaderDoRimLighting( const float3 worldNormal, const float3 vEyeDir, const float3 cAmbientCube[6], float fFresnel ) +{ + float3 vReflect = reflect( -vEyeDir, worldNormal ); // Reflect view through normal + + return fFresnel * PixelShaderAmbientLight( vEyeDir, cAmbientCube ); +} + +// Called directly by newer shaders or through the following wrapper for older shaders +float3 PixelShaderDoLighting( const float3 worldPos, const float3 worldNormal, + const float3 staticLightingColor, const bool bStaticLight, + const bool bAmbientLight, const float4 lightAtten, const float3 cAmbientCube[6], + in sampler NormalizeSampler, const int nNumLights, PixelShaderLightInfo cLightInfo[3], + const bool bHalfLambert, + + // New optional/experimental parameters + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + const bool bDoLightingWarp, in sampler lightWarpSampler ) +{ + float3 linearColor = PixelShaderDoLightingLinear( worldPos, worldNormal, staticLightingColor, + bStaticLight, bAmbientLight, lightAtten, + cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion, + bDoLightingWarp, lightWarpSampler ); + + // go ahead and clamp to the linear space equivalent of overbright 2 so that we match + // everything else. +// linearColor = HuePreservingColorClamp( linearColor, pow( 2.0f, 2.2 ) ); + + return linearColor; +} + +#endif //#ifndef COMMON_VERTEXLITGENERIC_DX9_H_ diff --git a/mp/src/materialsystem/stdshaders/common_vs_fxc.h b/mp/src/materialsystem/stdshaders/common_vs_fxc.h index fe2e117a..ac966b68 100644 --- a/mp/src/materialsystem/stdshaders/common_vs_fxc.h +++ b/mp/src/materialsystem/stdshaders/common_vs_fxc.h @@ -1,955 +1,955 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: This is where all common code for vertex shaders go. -// -// $NoKeywords: $ -// -//===========================================================================// - - - -#ifndef COMMON_VS_FXC_H_ -#define COMMON_VS_FXC_H_ - -#include "common_fxc.h" - -// Put global skip commands here. . make sure and check that the appropriate vars are defined -// so these aren't used on the wrong shaders! -// -------------------------------------------------------------------------------- -// Ditch all fastpath attemps if we are doing LIGHTING_PREVIEW. -// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH -// -------------------------------------------------------------------------------- - - -#ifndef COMPRESSED_VERTS -// Default to no vertex compression -#define COMPRESSED_VERTS 0 -#endif - -#if ( !defined( SHADER_MODEL_VS_2_0 ) && !defined( SHADER_MODEL_VS_3_0 ) ) -#if COMPRESSED_VERTS == 1 -#error "Vertex compression is only for DX9 and up!" -#endif -#endif - -// We're testing 2 normal compression methods -// One compressed normals+tangents into a SHORT2 each (8 bytes total) -// The other compresses them together, into a single UBYTE4 (4 bytes total) -// FIXME: pick one or the other, compare lighting quality in important cases -#define COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 0 -#define COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 1 -//#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 -#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 - - -#define FOGTYPE_RANGE 0 -#define FOGTYPE_HEIGHT 1 - -#define COMPILE_ERROR ( 1/0; ) - -// ------------------------- -// CONSTANTS -// ------------------------- - -#pragma def ( vs, c0, 0.0f, 1.0f, 2.0f, 0.5f ) - -const float4 cConstants1 : register(c1); -#define cOOGamma cConstants1.x -#define cOverbright 2.0f -#define cOneThird cConstants1.z -#define cOOOverbright ( 1.0f / 2.0f ) - - -// The g_bLightEnabled registers and g_nLightCountRegister hold the same information regarding -// enabling lights, but callers internal to this file tend to use the loops, while external -// callers will end up using the booleans -const bool g_bLightEnabled[4] : register(b0); - // through b3 - -const int g_nLightCountRegister : register(i0); - - -#define g_nLightCount g_nLightCountRegister.x - -const float4 cEyePosWaterZ : register(c2); -#define cEyePos cEyePosWaterZ.xyz - -// Only cFlexScale.x is used -// It is a binary value used to switch on/off the addition of the flex delta stream -const float4 cFlexScale : register( c3 ); - -const float4x4 cModelViewProj : register(c4); -const float4x4 cViewProj : register(c8); - -// Used to compute projPosZ in shaders without skinning -// Using cModelViewProj with FastClip generates incorrect results -// This is just row two of the non-FastClip cModelViewProj matrix -const float4 cModelViewProjZ : register(c12); - -// More constants working back from the top... -const float4 cViewProjZ : register(c13); - -const float4 cFogParams : register(c16); -#define cFogEndOverFogRange cFogParams.x -#define cFogOne cFogParams.y -#define cFogMaxDensity cFogParams.z -#define cOOFogRange cFogParams.w - -const float4x4 cViewModel : register(c17); - -const float3 cAmbientCubeX [ 2 ] : register ( c21 ) ; -const float3 cAmbientCubeY [ 2 ] : register ( c23 ) ; -const float3 cAmbientCubeZ [ 2 ] : register ( c25 ) ; - -#if defined ( SHADER_MODEL_VS_3_0 ) -const float4 cFlexWeights [ 512 ] : register ( c1024 ) ; -#endif - -struct LightInfo -{ - float4 color; // {xyz} is color w is light type code (see comment below) - float4 dir; // {xyz} is dir w is light type code - float4 pos; - float4 spotParams; - float4 atten; -}; - -// w components of color and dir indicate light type: -// 1x - directional -// 01 - spot -// 00 - point - -// Four lights x 5 constants each = 20 constants -LightInfo cLightInfo[4] : register(c27); -#define LIGHT_0_POSITION_REG c29 - -#ifdef SHADER_MODEL_VS_1_1 - -const float4 cModulationColor : register(c37); - -#define SHADER_SPECIFIC_CONST_0 c38 -#define SHADER_SPECIFIC_CONST_1 c39 -#define SHADER_SPECIFIC_CONST_2 c40 -#define SHADER_SPECIFIC_CONST_3 c41 -#define SHADER_SPECIFIC_CONST_4 c42 -#define SHADER_SPECIFIC_CONST_5 c43 -#define SHADER_SPECIFIC_CONST_6 c44 -#define SHADER_SPECIFIC_CONST_7 c45 -#define SHADER_SPECIFIC_CONST_8 c46 -#define SHADER_SPECIFIC_CONST_9 c47 -#define SHADER_SPECIFIC_CONST_10 c14 -#define SHADER_SPECIFIC_CONST_11 c15 - -static const int cModel0Index = 48; -const float4x3 cModel[16] : register(c48); -// last cmodel is c105 for dx80, c214 for dx90 - -#else // DX9 shaders (vs20 and beyond) - -const float4 cModulationColor : register( c47 ); - -#define SHADER_SPECIFIC_CONST_0 c48 -#define SHADER_SPECIFIC_CONST_1 c49 -#define SHADER_SPECIFIC_CONST_2 c50 -#define SHADER_SPECIFIC_CONST_3 c51 -#define SHADER_SPECIFIC_CONST_4 c52 -#define SHADER_SPECIFIC_CONST_5 c53 -#define SHADER_SPECIFIC_CONST_6 c54 -#define SHADER_SPECIFIC_CONST_7 c55 -#define SHADER_SPECIFIC_CONST_8 c56 -#define SHADER_SPECIFIC_CONST_9 c57 -#define SHADER_SPECIFIC_CONST_10 c14 -#define SHADER_SPECIFIC_CONST_11 c15 - -static const int cModel0Index = 58; -const float4x3 cModel[53] : register( c58 ); -// last cmodel is c105 for dx80, c216 for dx90 - - -#define SHADER_SPECIFIC_BOOL_CONST_0 b4 -#define SHADER_SPECIFIC_BOOL_CONST_1 b5 -#define SHADER_SPECIFIC_BOOL_CONST_2 b6 -#define SHADER_SPECIFIC_BOOL_CONST_3 b7 -#define SHADER_SPECIFIC_BOOL_CONST_4 b8 -#define SHADER_SPECIFIC_BOOL_CONST_5 b9 -#define SHADER_SPECIFIC_BOOL_CONST_6 b10 -#define SHADER_SPECIFIC_BOOL_CONST_7 b11 -#endif // vertex shader model constant packing changes - - -//======================================================================================= -// Methods to decompress vertex normals -//======================================================================================= - -//----------------------------------------------------------------------------------- -// Decompress a normal from two-component compressed format -// We expect this data to come from a signed SHORT2 stream in the range of -32768..32767 -// -// -32678 and 0 are invalid encodings -// w contains the sign to use in the cross product when generating a binormal -void _DecompressShort2Tangent( float2 inputTangent, out float4 outputTangent ) -{ - float2 ztSigns = sign( inputTangent ); // sign bits for z and tangent (+1 or -1) - float2 xyAbs = abs( inputTangent ); // 1..32767 - outputTangent.xy = (xyAbs - 16384.0f) / 16384.0f; // x and y - outputTangent.z = ztSigns.x * sqrt( saturate( 1.0f - dot( outputTangent.xy, outputTangent.xy ) ) ); - outputTangent.w = ztSigns.y; -} - -//----------------------------------------------------------------------------------- -// Same code as _DecompressShort2Tangent, just one returns a float4, one a float3 -void _DecompressShort2Normal( float2 inputNormal, out float3 outputNormal ) -{ - float4 result; - _DecompressShort2Tangent( inputNormal, result ); - outputNormal = result.xyz; -} - -//----------------------------------------------------------------------------------- -// Decompress normal+tangent together -void _DecompressShort2NormalTangent( float2 inputNormal, float2 inputTangent, out float3 outputNormal, out float4 outputTangent ) -{ - // FIXME: if we end up sticking with the SHORT2 format, pack the normal and tangent into a single SHORT4 element - // (that would make unpacking normal+tangent here together much cheaper than the sum of their parts) - _DecompressShort2Normal( inputNormal, outputNormal ); - _DecompressShort2Tangent( inputTangent, outputTangent ); -} - -//======================================================================================= -// Decompress a normal and tangent from four-component compressed format -// We expect this data to come from an unsigned UBYTE4 stream in the range of 0..255 -// The final vTangent.w contains the sign to use in the cross product when generating a binormal -void _DecompressUByte4NormalTangent( float4 inputNormal, - out float3 outputNormal, // {nX, nY, nZ} - out float4 outputTangent ) // {tX, tY, tZ, sign of binormal} -{ - float fOne = 1.0f; - - float4 ztztSignBits = ( inputNormal - 128.0f ) < 0; // sign bits for zs and binormal (1 or 0) set-less-than (slt) asm instruction - float4 xyxyAbs = abs( inputNormal - 128.0f ) - ztztSignBits; // 0..127 - float4 xyxySignBits = ( xyxyAbs - 64.0f ) < 0; // sign bits for xs and ys (1 or 0) - float4 normTan = (abs( xyxyAbs - 64.0f ) - xyxySignBits) / 63.0f; // abs({nX, nY, tX, tY}) - outputNormal.xy = normTan.xy; // abs({nX, nY, __, __}) - outputTangent.xy = normTan.zw; // abs({tX, tY, __, __}) - - float4 xyxySigns = 1 - 2*xyxySignBits; // Convert sign bits to signs - float4 ztztSigns = 1 - 2*ztztSignBits; // ( [1,0] -> [-1,+1] ) - - outputNormal.z = 1.0f - outputNormal.x - outputNormal.y; // Project onto x+y+z=1 - outputNormal.xyz = normalize( outputNormal.xyz ); // Normalize onto unit sphere - outputNormal.xy *= xyxySigns.xy; // Restore x and y signs - outputNormal.z *= ztztSigns.x; // Restore z sign - - outputTangent.z = 1.0f - outputTangent.x - outputTangent.y; // Project onto x+y+z=1 - outputTangent.xyz = normalize( outputTangent.xyz ); // Normalize onto unit sphere - outputTangent.xy *= xyxySigns.zw; // Restore x and y signs - outputTangent.z *= ztztSigns.z; // Restore z sign - outputTangent.w = ztztSigns.w; // Binormal sign -} - - -//----------------------------------------------------------------------------------- -// Decompress just a normal from four-component compressed format (same as above) -// We expect this data to come from an unsigned UBYTE4 stream in the range of 0..255 -// [ When compiled, this works out to approximately 17 asm instructions ] -void _DecompressUByte4Normal( float4 inputNormal, - out float3 outputNormal) // {nX, nY, nZ} -{ - float fOne = 1.0f; - - float2 ztSigns = ( inputNormal.xy - 128.0f ) < 0; // sign bits for zs and binormal (1 or 0) set-less-than (slt) asm instruction - float2 xyAbs = abs( inputNormal.xy - 128.0f ) - ztSigns; // 0..127 - float2 xySigns = ( xyAbs - 64.0f ) < 0; // sign bits for xs and ys (1 or 0) - outputNormal.xy = ( abs( xyAbs - 64.0f ) - xySigns ) / 63.0f; // abs({nX, nY}) - - outputNormal.z = 1.0f - outputNormal.x - outputNormal.y; // Project onto x+y+z=1 - outputNormal.xyz = normalize( outputNormal.xyz ); // Normalize onto unit sphere - - outputNormal.xy *= lerp( fOne.xx, -fOne.xx, xySigns ); // Restore x and y signs - outputNormal.z *= lerp( fOne.x, -fOne.x, ztSigns.x ); // Restore z sign -} - - -void DecompressVertex_Normal( float4 inputNormal, out float3 outputNormal ) -{ - if ( COMPRESSED_VERTS == 1 ) - { - if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 ) - { - _DecompressShort2Normal( inputNormal.xy, outputNormal ); - } - else // ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) - { - _DecompressUByte4Normal( inputNormal, outputNormal ); - } - } - else - { - outputNormal = inputNormal.xyz; - } -} - -void DecompressVertex_NormalTangent( float4 inputNormal, float4 inputTangent, out float3 outputNormal, out float4 outputTangent ) -{ - if ( COMPRESSED_VERTS == 1 ) - { - if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 ) - { - _DecompressShort2NormalTangent( inputNormal.xy, inputTangent.xy, outputNormal, outputTangent ); - } - else // ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) - { - _DecompressUByte4NormalTangent( inputNormal, outputNormal, outputTangent ); - } - } - else - { - outputNormal = inputNormal.xyz; - outputTangent = inputTangent; - } -} - - -#ifdef SHADER_MODEL_VS_3_0 - -//----------------------------------------------------------------------------- -// Methods to sample morph data from a vertex texture -// NOTE: vMorphTargetTextureDim.x = width, cVertexTextureDim.y = height, cVertexTextureDim.z = # of float4 fields per vertex -// For position + normal morph for example, there will be 2 fields. -//----------------------------------------------------------------------------- -float4 SampleMorphDelta( sampler2D vt, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, const float flVertexID, const float flField ) -{ - float flColumn = floor( flVertexID / vMorphSubrect.w ); - - float4 t; - t.x = vMorphSubrect.x + vMorphTargetTextureDim.z * flColumn + flField + 0.5f; - t.y = vMorphSubrect.y + flVertexID - flColumn * vMorphSubrect.w + 0.5f; - t.xy /= vMorphTargetTextureDim.xy; - t.z = t.w = 0.f; - - return tex2Dlod( vt, t ); -} - -// Optimized version which reads 2 deltas -void SampleMorphDelta2( sampler2D vt, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, const float flVertexID, out float4 delta1, out float4 delta2 ) -{ - float flColumn = floor( flVertexID / vMorphSubrect.w ); - - float4 t; - t.x = vMorphSubrect.x + vMorphTargetTextureDim.z * flColumn + 0.5f; - t.y = vMorphSubrect.y + flVertexID - flColumn * vMorphSubrect.w + 0.5f; - t.xy /= vMorphTargetTextureDim.xy; - t.z = t.w = 0.f; - - delta1 = tex2Dlod( vt, t ); - t.x += 1.0f / vMorphTargetTextureDim.x; - delta2 = tex2Dlod( vt, t ); -} - -#endif // SHADER_MODEL_VS_3_0 - - -#if ( defined( SHADER_MODEL_VS_2_0 ) || defined( SHADER_MODEL_VS_3_0 ) ) - -//----------------------------------------------------------------------------- -// Method to apply morphs -//----------------------------------------------------------------------------- -bool ApplyMorph( float3 vPosFlex, inout float3 vPosition ) -{ - // Flexes coming in from a separate stream - float3 vPosDelta = vPosFlex.xyz * cFlexScale.x; - vPosition.xyz += vPosDelta; - return true; -} - -bool ApplyMorph( float3 vPosFlex, float3 vNormalFlex, inout float3 vPosition, inout float3 vNormal ) -{ - // Flexes coming in from a separate stream - float3 vPosDelta = vPosFlex.xyz * cFlexScale.x; - float3 vNormalDelta = vNormalFlex.xyz * cFlexScale.x; - vPosition.xyz += vPosDelta; - vNormal += vNormalDelta; - return true; -} - -bool ApplyMorph( float3 vPosFlex, float3 vNormalFlex, - inout float3 vPosition, inout float3 vNormal, inout float3 vTangent ) -{ - // Flexes coming in from a separate stream - float3 vPosDelta = vPosFlex.xyz * cFlexScale.x; - float3 vNormalDelta = vNormalFlex.xyz * cFlexScale.x; - vPosition.xyz += vPosDelta; - vNormal += vNormalDelta; - vTangent.xyz += vNormalDelta; - return true; -} - -bool ApplyMorph( float4 vPosFlex, float3 vNormalFlex, - inout float3 vPosition, inout float3 vNormal, inout float3 vTangent, out float flWrinkle ) -{ - // Flexes coming in from a separate stream - float3 vPosDelta = vPosFlex.xyz * cFlexScale.x; - float3 vNormalDelta = vNormalFlex.xyz * cFlexScale.x; - flWrinkle = vPosFlex.w * cFlexScale.y; - vPosition.xyz += vPosDelta; - vNormal += vNormalDelta; - vTangent.xyz += vNormalDelta; - return true; -} - -#endif // defined( SHADER_MODEL_VS_2_0 ) || defined( SHADER_MODEL_VS_3_0 ) - - -#ifdef SHADER_MODEL_VS_3_0 - -bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, - const float flVertexID, const float3 vMorphTexCoord, - inout float3 vPosition ) -{ -#if MORPHING - -#if !DECAL - // Flexes coming in from a separate stream - float4 vPosDelta = SampleMorphDelta( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, 0 ); - vPosition += vPosDelta.xyz; -#else - float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); - float3 vPosDelta = tex2Dlod( morphSampler, t ); - vPosition += vPosDelta.xyz * vMorphTexCoord.z; -#endif // DECAL - - return true; - -#else // !MORPHING - return false; -#endif -} - -bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, - const float flVertexID, const float3 vMorphTexCoord, - inout float3 vPosition, inout float3 vNormal ) -{ -#if MORPHING - -#if !DECAL - float4 vPosDelta, vNormalDelta; - SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); - vPosition += vPosDelta.xyz; - vNormal += vNormalDelta.xyz; -#else - float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); - float3 vPosDelta = tex2Dlod( morphSampler, t ); - t.x += 1.0f / vMorphTargetTextureDim.x; - float3 vNormalDelta = tex2Dlod( morphSampler, t ); - vPosition += vPosDelta.xyz * vMorphTexCoord.z; - vNormal += vNormalDelta.xyz * vMorphTexCoord.z; -#endif // DECAL - - return true; - -#else // !MORPHING - return false; -#endif -} - -bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, - const float flVertexID, const float3 vMorphTexCoord, - inout float3 vPosition, inout float3 vNormal, inout float3 vTangent ) -{ -#if MORPHING - -#if !DECAL - float4 vPosDelta, vNormalDelta; - SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); - vPosition += vPosDelta.xyz; - vNormal += vNormalDelta.xyz; - vTangent += vNormalDelta.xyz; -#else - float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); - float3 vPosDelta = tex2Dlod( morphSampler, t ); - t.x += 1.0f / vMorphTargetTextureDim.x; - float3 vNormalDelta = tex2Dlod( morphSampler, t ); - vPosition += vPosDelta.xyz * vMorphTexCoord.z; - vNormal += vNormalDelta.xyz * vMorphTexCoord.z; - vTangent += vNormalDelta.xyz * vMorphTexCoord.z; -#endif // DECAL - - return true; - -#else // MORPHING - - return false; -#endif -} - -bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, - const float flVertexID, const float3 vMorphTexCoord, - inout float3 vPosition, inout float3 vNormal, inout float3 vTangent, out float flWrinkle ) -{ -#if MORPHING - -#if !DECAL - float4 vPosDelta, vNormalDelta; - SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); - vPosition += vPosDelta.xyz; - vNormal += vNormalDelta.xyz; - vTangent += vNormalDelta.xyz; - flWrinkle = vPosDelta.w; -#else - float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); - float4 vPosDelta = tex2Dlod( morphSampler, t ); - t.x += 1.0f / vMorphTargetTextureDim.x; - float3 vNormalDelta = tex2Dlod( morphSampler, t ); - - vPosition += vPosDelta.xyz * vMorphTexCoord.z; - vNormal += vNormalDelta.xyz * vMorphTexCoord.z; - vTangent += vNormalDelta.xyz * vMorphTexCoord.z; - flWrinkle = vPosDelta.w * vMorphTexCoord.z; -#endif // DECAL - - return true; - -#else // MORPHING - - flWrinkle = 0.0f; - return false; - -#endif -} - -#endif // SHADER_MODEL_VS_3_0 - - -float RangeFog( const float3 projPos ) -{ - return max( cFogMaxDensity, ( -projPos.z * cOOFogRange + cFogEndOverFogRange ) ); -} - -float WaterFog( const float3 worldPos, const float3 projPos ) -{ - float4 tmp; - - tmp.xy = cEyePosWaterZ.wz - worldPos.z; - - // tmp.x is the distance from the water surface to the vert - // tmp.y is the distance from the eye position to the vert - - // if $tmp.x < 0, then set it to 0 - // This is the equivalent of moving the vert to the water surface if it's above the water surface - - tmp.x = max( 0.0f, tmp.x ); - - // $tmp.w = $tmp.x / $tmp.y - tmp.w = tmp.x / tmp.y; - - tmp.w *= projPos.z; - - // $tmp.w is now the distance that we see through water. - - return max( cFogMaxDensity, ( -tmp.w * cOOFogRange + cFogOne ) ); -} - -float CalcFog( const float3 worldPos, const float3 projPos, const int fogType ) -{ -#if defined( _X360 ) - // 360 only does pixel fog - return 1.0f; -#endif - - if( fogType == FOGTYPE_RANGE ) - { - return RangeFog( projPos ); - } - else - { -#if SHADERMODEL_VS_2_0 == 1 - // We do this work in the pixel shader in dx9, so don't do any fog here. - return 1.0f; -#else - return WaterFog( worldPos, projPos ); -#endif - } -} - -float CalcFog( const float3 worldPos, const float3 projPos, const bool bWaterFog ) -{ -#if defined( _X360 ) - // 360 only does pixel fog - return 1.0f; -#endif - - float flFog; - if( !bWaterFog ) - { - flFog = RangeFog( projPos ); - } - else - { -#if SHADERMODEL_VS_2_0 == 1 - // We do this work in the pixel shader in dx9, so don't do any fog here. - flFog = 1.0f; -#else - flFog = WaterFog( worldPos, projPos ); -#endif - } - - return flFog; -} - -float4 DecompressBoneWeights( const float4 weights ) -{ - float4 result = weights; - - if ( COMPRESSED_VERTS ) - { - // Decompress from SHORT2 to float. In our case, [-1, +32767] -> [0, +1] - // NOTE: we add 1 here so we can divide by 32768 - which is exact (divide by 32767 is not). - // This avoids cracking between meshes with different numbers of bone weights. - // We use SHORT2 instead of SHORT2N for a similar reason - the GPU's conversion - // from [-32768,+32767] to [-1,+1] is imprecise in the same way. - result += 1; - result /= 32768; - } - - return result; -} - -void SkinPosition( bool bSkinning, const float4 modelPos, - const float4 boneWeights, float4 fBoneIndices, - out float3 worldPos ) -{ -#if !defined( _X360 ) - int3 boneIndices = D3DCOLORtoUBYTE4( fBoneIndices ); -#else - int3 boneIndices = fBoneIndices; -#endif - - // Needed for invariance issues caused by multipass rendering -#if defined( _X360 ) - [isolate] -#endif - { - if ( !bSkinning ) - { - worldPos = mul4x3( modelPos, cModel[0] ); - } - else // skinning - always three bones - { - float4x3 mat1 = cModel[boneIndices[0]]; - float4x3 mat2 = cModel[boneIndices[1]]; - float4x3 mat3 = cModel[boneIndices[2]]; - - float3 weights = DecompressBoneWeights( boneWeights ).xyz; - weights[2] = 1 - (weights[0] + weights[1]); - - float4x3 blendMatrix = mat1 * weights[0] + mat2 * weights[1] + mat3 * weights[2]; - worldPos = mul4x3( modelPos, blendMatrix ); - } - } -} - -void SkinPositionAndNormal( bool bSkinning, const float4 modelPos, const float3 modelNormal, - const float4 boneWeights, float4 fBoneIndices, - out float3 worldPos, out float3 worldNormal ) -{ - // Needed for invariance issues caused by multipass rendering -#if defined( _X360 ) - [isolate] -#endif - { - -#if !defined( _X360 ) - int3 boneIndices = D3DCOLORtoUBYTE4( fBoneIndices ); -#else - int3 boneIndices = fBoneIndices; -#endif - - if ( !bSkinning ) - { - worldPos = mul4x3( modelPos, cModel[0] ); - worldNormal = mul3x3( modelNormal, ( const float3x3 )cModel[0] ); - } - else // skinning - always three bones - { - float4x3 mat1 = cModel[boneIndices[0]]; - float4x3 mat2 = cModel[boneIndices[1]]; - float4x3 mat3 = cModel[boneIndices[2]]; - - float3 weights = DecompressBoneWeights( boneWeights ).xyz; - weights[2] = 1 - (weights[0] + weights[1]); - - float4x3 blendMatrix = mat1 * weights[0] + mat2 * weights[1] + mat3 * weights[2]; - worldPos = mul4x3( modelPos, blendMatrix ); - worldNormal = mul3x3( modelNormal, ( float3x3 )blendMatrix ); - } - - } // end [isolate] -} - -// Is it worth keeping SkinPosition and SkinPositionAndNormal around since the optimizer -// gets rid of anything that isn't used? -void SkinPositionNormalAndTangentSpace( - bool bSkinning, - const float4 modelPos, const float3 modelNormal, - const float4 modelTangentS, - const float4 boneWeights, float4 fBoneIndices, - out float3 worldPos, out float3 worldNormal, - out float3 worldTangentS, out float3 worldTangentT ) -{ -#if !defined( _X360 ) - int3 boneIndices = D3DCOLORtoUBYTE4( fBoneIndices ); -#else - int3 boneIndices = fBoneIndices; -#endif - - // Needed for invariance issues caused by multipass rendering -#if defined( _X360 ) - [isolate] -#endif - { - if ( !bSkinning ) - { - worldPos = mul4x3( modelPos, cModel[0] ); - worldNormal = mul3x3( modelNormal, ( const float3x3 )cModel[0] ); - worldTangentS = mul3x3( ( float3 )modelTangentS, ( const float3x3 )cModel[0] ); - } - else // skinning - always three bones - { - float4x3 mat1 = cModel[boneIndices[0]]; - float4x3 mat2 = cModel[boneIndices[1]]; - float4x3 mat3 = cModel[boneIndices[2]]; - - float3 weights = DecompressBoneWeights( boneWeights ).xyz; - weights[2] = 1 - (weights[0] + weights[1]); - - float4x3 blendMatrix = mat1 * weights[0] + mat2 * weights[1] + mat3 * weights[2]; - worldPos = mul4x3( modelPos, blendMatrix ); - worldNormal = mul3x3( modelNormal, ( const float3x3 )blendMatrix ); - worldTangentS = mul3x3( ( float3 )modelTangentS, ( const float3x3 )blendMatrix ); - } - worldTangentT = cross( worldNormal, worldTangentS ) * modelTangentS.w; - } -} - - -//----------------------------------------------------------------------------- -// Lighting helper functions -//----------------------------------------------------------------------------- - -float3 AmbientLight( const float3 worldNormal ) -{ - float3 nSquared = worldNormal * worldNormal; - int3 isNegative = ( worldNormal < 0.0 ); - float3 linearColor; - linearColor = nSquared.x * cAmbientCubeX[isNegative.x] + - nSquared.y * cAmbientCubeY[isNegative.y] + - nSquared.z * cAmbientCubeZ[isNegative.z]; - return linearColor; -} - -// The following "internal" routines are called "privately" by other routines in this file which -// handle the particular flavor of vs20 control flow appropriate to the original caller -float VertexAttenInternal( const float3 worldPos, int lightNum ) -{ - float result = 0.0f; - - // Get light direction - float3 lightDir = cLightInfo[lightNum].pos - worldPos; - - // Get light distance squared. - float lightDistSquared = dot( lightDir, lightDir ); - - // Get 1/lightDistance - float ooLightDist = rsqrt( lightDistSquared ); - - // Normalize light direction - lightDir *= ooLightDist; - - float3 vDist; -# if defined( _X360 ) - { - //X360 dynamic compile hits an internal compiler error using dst(), this is the breakdown of how dst() works from the 360 docs. - vDist.x = 1; - vDist.y = lightDistSquared * ooLightDist; - vDist.z = lightDistSquared; - //flDist.w = ooLightDist; - } -# else - { - vDist = dst( lightDistSquared, ooLightDist ); - } -# endif - - float flDistanceAtten = 1.0f / dot( cLightInfo[lightNum].atten.xyz, vDist ); - - // Spot attenuation - float flCosTheta = dot( cLightInfo[lightNum].dir.xyz, -lightDir ); - float flSpotAtten = (flCosTheta - cLightInfo[lightNum].spotParams.z) * cLightInfo[lightNum].spotParams.w; - flSpotAtten = max( 0.0001f, flSpotAtten ); - flSpotAtten = pow( flSpotAtten, cLightInfo[lightNum].spotParams.x ); - flSpotAtten = saturate( flSpotAtten ); - - // Select between point and spot - float flAtten = lerp( flDistanceAtten, flDistanceAtten * flSpotAtten, cLightInfo[lightNum].dir.w ); - - // Select between above and directional (no attenuation) - result = lerp( flAtten, 1.0f, cLightInfo[lightNum].color.w ); - - return result; -} - -float CosineTermInternal( const float3 worldPos, const float3 worldNormal, int lightNum, bool bHalfLambert ) -{ - // Calculate light direction assuming this is a point or spot - float3 lightDir = normalize( cLightInfo[lightNum].pos - worldPos ); - - // Select the above direction or the one in the structure, based upon light type - lightDir = lerp( lightDir, -cLightInfo[lightNum].dir, cLightInfo[lightNum].color.w ); - - // compute N dot L - float NDotL = dot( worldNormal, lightDir ); - - if ( !bHalfLambert ) - { - NDotL = max( 0.0f, NDotL ); - } - else // Half-Lambert - { - NDotL = NDotL * 0.5 + 0.5; - NDotL = NDotL * NDotL; - } - return NDotL; -} - -// This routine uses booleans to do early-outs and is meant to be called by routines OUTSIDE of this file -float GetVertexAttenForLight( const float3 worldPos, int lightNum, bool bUseStaticControlFlow ) -{ - float result = 0.0f; - - // Direct3D uses static control flow but OpenGL currently does not - if ( bUseStaticControlFlow ) - { - if ( g_bLightEnabled[lightNum] ) - { - result = VertexAttenInternal( worldPos, lightNum ); - } - } - else // OpenGL non-static-control-flow path - { - result = VertexAttenInternal( worldPos, lightNum ); - } - - return result; -} - -float3 DoLightInternal( const float3 worldPos, const float3 worldNormal, int lightNum, bool bHalfLambert ) -{ - return cLightInfo[lightNum].color * - CosineTermInternal( worldPos, worldNormal, lightNum, bHalfLambert ) * - VertexAttenInternal( worldPos, lightNum ); -} - -float3 DoLighting( const float3 worldPos, const float3 worldNormal, - const float3 staticLightingColor, const bool bStaticLight, - const bool bDynamicLight, bool bHalfLambert ) -{ - float3 linearColor = float3( 0.0f, 0.0f, 0.0f ); - - if( bStaticLight ) // Static light - { - float3 col = staticLightingColor * cOverbright; -#if defined ( _X360 ) - linearColor += col * col; -#else - linearColor += GammaToLinear( col ); -#endif - } - - if( bDynamicLight ) // Dynamic light - { - for (int i = 0; i < g_nLightCount; i++) - { - linearColor += DoLightInternal( worldPos, worldNormal, i, bHalfLambert ); - } - } - - if( bDynamicLight ) - { - linearColor += AmbientLight( worldNormal ); //ambient light is already remapped - } - - return linearColor; -} - -float3 DoLightingUnrolled( const float3 worldPos, const float3 worldNormal, - const float3 staticLightingColor, const bool bStaticLight, - const bool bDynamicLight, bool bHalfLambert, const int nNumLights ) -{ - float3 linearColor = float3( 0.0f, 0.0f, 0.0f ); - - if( bStaticLight ) // Static light - { - linearColor += GammaToLinear( staticLightingColor * cOverbright ); - } - - if( bDynamicLight ) // Ambient light - { - if ( nNumLights >= 1 ) - linearColor += DoLightInternal( worldPos, worldNormal, 0, bHalfLambert ); - if ( nNumLights >= 2 ) - linearColor += DoLightInternal( worldPos, worldNormal, 1, bHalfLambert ); - if ( nNumLights >= 3 ) - linearColor += DoLightInternal( worldPos, worldNormal, 2, bHalfLambert ); - if ( nNumLights >= 4 ) - linearColor += DoLightInternal( worldPos, worldNormal, 3, bHalfLambert ); - } - - if( bDynamicLight ) - { - linearColor += AmbientLight( worldNormal ); //ambient light is already remapped - } - - return linearColor; -} - -int4 FloatToInt( in float4 floats ) -{ - return D3DCOLORtoUBYTE4( floats.zyxw / 255.001953125 ); -} - -float2 ComputeSphereMapTexCoords( in float3 reflectionVector ) -{ - // transform reflection vector into view space - reflectionVector = mul( reflectionVector, ( float3x3 )cViewModel ); - - // generate - float3 tmp = float3( reflectionVector.x, reflectionVector.y, reflectionVector.z + 1.0f ); - - // find 1 / len - float ooLen = dot( tmp, tmp ); - ooLen = 1.0f / sqrt( ooLen ); - - // tmp = tmp/|tmp| + 1 - tmp.xy = ooLen * tmp.xy + 1.0f; - - return tmp.xy * 0.5f; -} - - -#define DEFORMATION_CLAMP_TO_BOX_IN_WORLDSPACE 1 - // minxyz.minsoftness / maxxyz.maxsoftness -float3 ApplyDeformation( float3 worldpos, int deftype, float4 defparms0, float4 defparms1, - float4 defparms2, float4 defparms3 ) -{ - float3 ret = worldpos; - if ( deftype == DEFORMATION_CLAMP_TO_BOX_IN_WORLDSPACE ) - { - ret=max( ret, defparms2.xyz ); - ret=min( ret, defparms3.xyz ); - } - - return ret; -} - - -#endif //#ifndef COMMON_VS_FXC_H_ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: This is where all common code for vertex shaders go. +// +// $NoKeywords: $ +// +//===========================================================================// + + + +#ifndef COMMON_VS_FXC_H_ +#define COMMON_VS_FXC_H_ + +#include "common_fxc.h" + +// Put global skip commands here. . make sure and check that the appropriate vars are defined +// so these aren't used on the wrong shaders! +// -------------------------------------------------------------------------------- +// Ditch all fastpath attemps if we are doing LIGHTING_PREVIEW. +// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// -------------------------------------------------------------------------------- + + +#ifndef COMPRESSED_VERTS +// Default to no vertex compression +#define COMPRESSED_VERTS 0 +#endif + +#if ( !defined( SHADER_MODEL_VS_2_0 ) && !defined( SHADER_MODEL_VS_3_0 ) ) +#if COMPRESSED_VERTS == 1 +#error "Vertex compression is only for DX9 and up!" +#endif +#endif + +// We're testing 2 normal compression methods +// One compressed normals+tangents into a SHORT2 each (8 bytes total) +// The other compresses them together, into a single UBYTE4 (4 bytes total) +// FIXME: pick one or the other, compare lighting quality in important cases +#define COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 0 +#define COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 1 +//#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 +#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 + + +#define FOGTYPE_RANGE 0 +#define FOGTYPE_HEIGHT 1 + +#define COMPILE_ERROR ( 1/0; ) + +// ------------------------- +// CONSTANTS +// ------------------------- + +#pragma def ( vs, c0, 0.0f, 1.0f, 2.0f, 0.5f ) + +const float4 cConstants1 : register(c1); +#define cOOGamma cConstants1.x +#define cOverbright 2.0f +#define cOneThird cConstants1.z +#define cOOOverbright ( 1.0f / 2.0f ) + + +// The g_bLightEnabled registers and g_nLightCountRegister hold the same information regarding +// enabling lights, but callers internal to this file tend to use the loops, while external +// callers will end up using the booleans +const bool g_bLightEnabled[4] : register(b0); + // through b3 + +const int g_nLightCountRegister : register(i0); + + +#define g_nLightCount g_nLightCountRegister.x + +const float4 cEyePosWaterZ : register(c2); +#define cEyePos cEyePosWaterZ.xyz + +// Only cFlexScale.x is used +// It is a binary value used to switch on/off the addition of the flex delta stream +const float4 cFlexScale : register( c3 ); + +const float4x4 cModelViewProj : register(c4); +const float4x4 cViewProj : register(c8); + +// Used to compute projPosZ in shaders without skinning +// Using cModelViewProj with FastClip generates incorrect results +// This is just row two of the non-FastClip cModelViewProj matrix +const float4 cModelViewProjZ : register(c12); + +// More constants working back from the top... +const float4 cViewProjZ : register(c13); + +const float4 cFogParams : register(c16); +#define cFogEndOverFogRange cFogParams.x +#define cFogOne cFogParams.y +#define cFogMaxDensity cFogParams.z +#define cOOFogRange cFogParams.w + +const float4x4 cViewModel : register(c17); + +const float3 cAmbientCubeX [ 2 ] : register ( c21 ) ; +const float3 cAmbientCubeY [ 2 ] : register ( c23 ) ; +const float3 cAmbientCubeZ [ 2 ] : register ( c25 ) ; + +#if defined ( SHADER_MODEL_VS_3_0 ) +const float4 cFlexWeights [ 512 ] : register ( c1024 ) ; +#endif + +struct LightInfo +{ + float4 color; // {xyz} is color w is light type code (see comment below) + float4 dir; // {xyz} is dir w is light type code + float4 pos; + float4 spotParams; + float4 atten; +}; + +// w components of color and dir indicate light type: +// 1x - directional +// 01 - spot +// 00 - point + +// Four lights x 5 constants each = 20 constants +LightInfo cLightInfo[4] : register(c27); +#define LIGHT_0_POSITION_REG c29 + +#ifdef SHADER_MODEL_VS_1_1 + +const float4 cModulationColor : register(c37); + +#define SHADER_SPECIFIC_CONST_0 c38 +#define SHADER_SPECIFIC_CONST_1 c39 +#define SHADER_SPECIFIC_CONST_2 c40 +#define SHADER_SPECIFIC_CONST_3 c41 +#define SHADER_SPECIFIC_CONST_4 c42 +#define SHADER_SPECIFIC_CONST_5 c43 +#define SHADER_SPECIFIC_CONST_6 c44 +#define SHADER_SPECIFIC_CONST_7 c45 +#define SHADER_SPECIFIC_CONST_8 c46 +#define SHADER_SPECIFIC_CONST_9 c47 +#define SHADER_SPECIFIC_CONST_10 c14 +#define SHADER_SPECIFIC_CONST_11 c15 + +static const int cModel0Index = 48; +const float4x3 cModel[16] : register(c48); +// last cmodel is c105 for dx80, c214 for dx90 + +#else // DX9 shaders (vs20 and beyond) + +const float4 cModulationColor : register( c47 ); + +#define SHADER_SPECIFIC_CONST_0 c48 +#define SHADER_SPECIFIC_CONST_1 c49 +#define SHADER_SPECIFIC_CONST_2 c50 +#define SHADER_SPECIFIC_CONST_3 c51 +#define SHADER_SPECIFIC_CONST_4 c52 +#define SHADER_SPECIFIC_CONST_5 c53 +#define SHADER_SPECIFIC_CONST_6 c54 +#define SHADER_SPECIFIC_CONST_7 c55 +#define SHADER_SPECIFIC_CONST_8 c56 +#define SHADER_SPECIFIC_CONST_9 c57 +#define SHADER_SPECIFIC_CONST_10 c14 +#define SHADER_SPECIFIC_CONST_11 c15 + +static const int cModel0Index = 58; +const float4x3 cModel[53] : register( c58 ); +// last cmodel is c105 for dx80, c216 for dx90 + + +#define SHADER_SPECIFIC_BOOL_CONST_0 b4 +#define SHADER_SPECIFIC_BOOL_CONST_1 b5 +#define SHADER_SPECIFIC_BOOL_CONST_2 b6 +#define SHADER_SPECIFIC_BOOL_CONST_3 b7 +#define SHADER_SPECIFIC_BOOL_CONST_4 b8 +#define SHADER_SPECIFIC_BOOL_CONST_5 b9 +#define SHADER_SPECIFIC_BOOL_CONST_6 b10 +#define SHADER_SPECIFIC_BOOL_CONST_7 b11 +#endif // vertex shader model constant packing changes + + +//======================================================================================= +// Methods to decompress vertex normals +//======================================================================================= + +//----------------------------------------------------------------------------------- +// Decompress a normal from two-component compressed format +// We expect this data to come from a signed SHORT2 stream in the range of -32768..32767 +// +// -32678 and 0 are invalid encodings +// w contains the sign to use in the cross product when generating a binormal +void _DecompressShort2Tangent( float2 inputTangent, out float4 outputTangent ) +{ + float2 ztSigns = sign( inputTangent ); // sign bits for z and tangent (+1 or -1) + float2 xyAbs = abs( inputTangent ); // 1..32767 + outputTangent.xy = (xyAbs - 16384.0f) / 16384.0f; // x and y + outputTangent.z = ztSigns.x * sqrt( saturate( 1.0f - dot( outputTangent.xy, outputTangent.xy ) ) ); + outputTangent.w = ztSigns.y; +} + +//----------------------------------------------------------------------------------- +// Same code as _DecompressShort2Tangent, just one returns a float4, one a float3 +void _DecompressShort2Normal( float2 inputNormal, out float3 outputNormal ) +{ + float4 result; + _DecompressShort2Tangent( inputNormal, result ); + outputNormal = result.xyz; +} + +//----------------------------------------------------------------------------------- +// Decompress normal+tangent together +void _DecompressShort2NormalTangent( float2 inputNormal, float2 inputTangent, out float3 outputNormal, out float4 outputTangent ) +{ + // FIXME: if we end up sticking with the SHORT2 format, pack the normal and tangent into a single SHORT4 element + // (that would make unpacking normal+tangent here together much cheaper than the sum of their parts) + _DecompressShort2Normal( inputNormal, outputNormal ); + _DecompressShort2Tangent( inputTangent, outputTangent ); +} + +//======================================================================================= +// Decompress a normal and tangent from four-component compressed format +// We expect this data to come from an unsigned UBYTE4 stream in the range of 0..255 +// The final vTangent.w contains the sign to use in the cross product when generating a binormal +void _DecompressUByte4NormalTangent( float4 inputNormal, + out float3 outputNormal, // {nX, nY, nZ} + out float4 outputTangent ) // {tX, tY, tZ, sign of binormal} +{ + float fOne = 1.0f; + + float4 ztztSignBits = ( inputNormal - 128.0f ) < 0; // sign bits for zs and binormal (1 or 0) set-less-than (slt) asm instruction + float4 xyxyAbs = abs( inputNormal - 128.0f ) - ztztSignBits; // 0..127 + float4 xyxySignBits = ( xyxyAbs - 64.0f ) < 0; // sign bits for xs and ys (1 or 0) + float4 normTan = (abs( xyxyAbs - 64.0f ) - xyxySignBits) / 63.0f; // abs({nX, nY, tX, tY}) + outputNormal.xy = normTan.xy; // abs({nX, nY, __, __}) + outputTangent.xy = normTan.zw; // abs({tX, tY, __, __}) + + float4 xyxySigns = 1 - 2*xyxySignBits; // Convert sign bits to signs + float4 ztztSigns = 1 - 2*ztztSignBits; // ( [1,0] -> [-1,+1] ) + + outputNormal.z = 1.0f - outputNormal.x - outputNormal.y; // Project onto x+y+z=1 + outputNormal.xyz = normalize( outputNormal.xyz ); // Normalize onto unit sphere + outputNormal.xy *= xyxySigns.xy; // Restore x and y signs + outputNormal.z *= ztztSigns.x; // Restore z sign + + outputTangent.z = 1.0f - outputTangent.x - outputTangent.y; // Project onto x+y+z=1 + outputTangent.xyz = normalize( outputTangent.xyz ); // Normalize onto unit sphere + outputTangent.xy *= xyxySigns.zw; // Restore x and y signs + outputTangent.z *= ztztSigns.z; // Restore z sign + outputTangent.w = ztztSigns.w; // Binormal sign +} + + +//----------------------------------------------------------------------------------- +// Decompress just a normal from four-component compressed format (same as above) +// We expect this data to come from an unsigned UBYTE4 stream in the range of 0..255 +// [ When compiled, this works out to approximately 17 asm instructions ] +void _DecompressUByte4Normal( float4 inputNormal, + out float3 outputNormal) // {nX, nY, nZ} +{ + float fOne = 1.0f; + + float2 ztSigns = ( inputNormal.xy - 128.0f ) < 0; // sign bits for zs and binormal (1 or 0) set-less-than (slt) asm instruction + float2 xyAbs = abs( inputNormal.xy - 128.0f ) - ztSigns; // 0..127 + float2 xySigns = ( xyAbs - 64.0f ) < 0; // sign bits for xs and ys (1 or 0) + outputNormal.xy = ( abs( xyAbs - 64.0f ) - xySigns ) / 63.0f; // abs({nX, nY}) + + outputNormal.z = 1.0f - outputNormal.x - outputNormal.y; // Project onto x+y+z=1 + outputNormal.xyz = normalize( outputNormal.xyz ); // Normalize onto unit sphere + + outputNormal.xy *= lerp( fOne.xx, -fOne.xx, xySigns ); // Restore x and y signs + outputNormal.z *= lerp( fOne.x, -fOne.x, ztSigns.x ); // Restore z sign +} + + +void DecompressVertex_Normal( float4 inputNormal, out float3 outputNormal ) +{ + if ( COMPRESSED_VERTS == 1 ) + { + if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 ) + { + _DecompressShort2Normal( inputNormal.xy, outputNormal ); + } + else // ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) + { + _DecompressUByte4Normal( inputNormal, outputNormal ); + } + } + else + { + outputNormal = inputNormal.xyz; + } +} + +void DecompressVertex_NormalTangent( float4 inputNormal, float4 inputTangent, out float3 outputNormal, out float4 outputTangent ) +{ + if ( COMPRESSED_VERTS == 1 ) + { + if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 ) + { + _DecompressShort2NormalTangent( inputNormal.xy, inputTangent.xy, outputNormal, outputTangent ); + } + else // ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) + { + _DecompressUByte4NormalTangent( inputNormal, outputNormal, outputTangent ); + } + } + else + { + outputNormal = inputNormal.xyz; + outputTangent = inputTangent; + } +} + + +#ifdef SHADER_MODEL_VS_3_0 + +//----------------------------------------------------------------------------- +// Methods to sample morph data from a vertex texture +// NOTE: vMorphTargetTextureDim.x = width, cVertexTextureDim.y = height, cVertexTextureDim.z = # of float4 fields per vertex +// For position + normal morph for example, there will be 2 fields. +//----------------------------------------------------------------------------- +float4 SampleMorphDelta( sampler2D vt, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, const float flVertexID, const float flField ) +{ + float flColumn = floor( flVertexID / vMorphSubrect.w ); + + float4 t; + t.x = vMorphSubrect.x + vMorphTargetTextureDim.z * flColumn + flField + 0.5f; + t.y = vMorphSubrect.y + flVertexID - flColumn * vMorphSubrect.w + 0.5f; + t.xy /= vMorphTargetTextureDim.xy; + t.z = t.w = 0.f; + + return tex2Dlod( vt, t ); +} + +// Optimized version which reads 2 deltas +void SampleMorphDelta2( sampler2D vt, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, const float flVertexID, out float4 delta1, out float4 delta2 ) +{ + float flColumn = floor( flVertexID / vMorphSubrect.w ); + + float4 t; + t.x = vMorphSubrect.x + vMorphTargetTextureDim.z * flColumn + 0.5f; + t.y = vMorphSubrect.y + flVertexID - flColumn * vMorphSubrect.w + 0.5f; + t.xy /= vMorphTargetTextureDim.xy; + t.z = t.w = 0.f; + + delta1 = tex2Dlod( vt, t ); + t.x += 1.0f / vMorphTargetTextureDim.x; + delta2 = tex2Dlod( vt, t ); +} + +#endif // SHADER_MODEL_VS_3_0 + + +#if ( defined( SHADER_MODEL_VS_2_0 ) || defined( SHADER_MODEL_VS_3_0 ) ) + +//----------------------------------------------------------------------------- +// Method to apply morphs +//----------------------------------------------------------------------------- +bool ApplyMorph( float3 vPosFlex, inout float3 vPosition ) +{ + // Flexes coming in from a separate stream + float3 vPosDelta = vPosFlex.xyz * cFlexScale.x; + vPosition.xyz += vPosDelta; + return true; +} + +bool ApplyMorph( float3 vPosFlex, float3 vNormalFlex, inout float3 vPosition, inout float3 vNormal ) +{ + // Flexes coming in from a separate stream + float3 vPosDelta = vPosFlex.xyz * cFlexScale.x; + float3 vNormalDelta = vNormalFlex.xyz * cFlexScale.x; + vPosition.xyz += vPosDelta; + vNormal += vNormalDelta; + return true; +} + +bool ApplyMorph( float3 vPosFlex, float3 vNormalFlex, + inout float3 vPosition, inout float3 vNormal, inout float3 vTangent ) +{ + // Flexes coming in from a separate stream + float3 vPosDelta = vPosFlex.xyz * cFlexScale.x; + float3 vNormalDelta = vNormalFlex.xyz * cFlexScale.x; + vPosition.xyz += vPosDelta; + vNormal += vNormalDelta; + vTangent.xyz += vNormalDelta; + return true; +} + +bool ApplyMorph( float4 vPosFlex, float3 vNormalFlex, + inout float3 vPosition, inout float3 vNormal, inout float3 vTangent, out float flWrinkle ) +{ + // Flexes coming in from a separate stream + float3 vPosDelta = vPosFlex.xyz * cFlexScale.x; + float3 vNormalDelta = vNormalFlex.xyz * cFlexScale.x; + flWrinkle = vPosFlex.w * cFlexScale.y; + vPosition.xyz += vPosDelta; + vNormal += vNormalDelta; + vTangent.xyz += vNormalDelta; + return true; +} + +#endif // defined( SHADER_MODEL_VS_2_0 ) || defined( SHADER_MODEL_VS_3_0 ) + + +#ifdef SHADER_MODEL_VS_3_0 + +bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, + const float flVertexID, const float3 vMorphTexCoord, + inout float3 vPosition ) +{ +#if MORPHING + +#if !DECAL + // Flexes coming in from a separate stream + float4 vPosDelta = SampleMorphDelta( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, 0 ); + vPosition += vPosDelta.xyz; +#else + float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); + float3 vPosDelta = tex2Dlod( morphSampler, t ); + vPosition += vPosDelta.xyz * vMorphTexCoord.z; +#endif // DECAL + + return true; + +#else // !MORPHING + return false; +#endif +} + +bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, + const float flVertexID, const float3 vMorphTexCoord, + inout float3 vPosition, inout float3 vNormal ) +{ +#if MORPHING + +#if !DECAL + float4 vPosDelta, vNormalDelta; + SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); + vPosition += vPosDelta.xyz; + vNormal += vNormalDelta.xyz; +#else + float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); + float3 vPosDelta = tex2Dlod( morphSampler, t ); + t.x += 1.0f / vMorphTargetTextureDim.x; + float3 vNormalDelta = tex2Dlod( morphSampler, t ); + vPosition += vPosDelta.xyz * vMorphTexCoord.z; + vNormal += vNormalDelta.xyz * vMorphTexCoord.z; +#endif // DECAL + + return true; + +#else // !MORPHING + return false; +#endif +} + +bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, + const float flVertexID, const float3 vMorphTexCoord, + inout float3 vPosition, inout float3 vNormal, inout float3 vTangent ) +{ +#if MORPHING + +#if !DECAL + float4 vPosDelta, vNormalDelta; + SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); + vPosition += vPosDelta.xyz; + vNormal += vNormalDelta.xyz; + vTangent += vNormalDelta.xyz; +#else + float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); + float3 vPosDelta = tex2Dlod( morphSampler, t ); + t.x += 1.0f / vMorphTargetTextureDim.x; + float3 vNormalDelta = tex2Dlod( morphSampler, t ); + vPosition += vPosDelta.xyz * vMorphTexCoord.z; + vNormal += vNormalDelta.xyz * vMorphTexCoord.z; + vTangent += vNormalDelta.xyz * vMorphTexCoord.z; +#endif // DECAL + + return true; + +#else // MORPHING + + return false; +#endif +} + +bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, + const float flVertexID, const float3 vMorphTexCoord, + inout float3 vPosition, inout float3 vNormal, inout float3 vTangent, out float flWrinkle ) +{ +#if MORPHING + +#if !DECAL + float4 vPosDelta, vNormalDelta; + SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); + vPosition += vPosDelta.xyz; + vNormal += vNormalDelta.xyz; + vTangent += vNormalDelta.xyz; + flWrinkle = vPosDelta.w; +#else + float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); + float4 vPosDelta = tex2Dlod( morphSampler, t ); + t.x += 1.0f / vMorphTargetTextureDim.x; + float3 vNormalDelta = tex2Dlod( morphSampler, t ); + + vPosition += vPosDelta.xyz * vMorphTexCoord.z; + vNormal += vNormalDelta.xyz * vMorphTexCoord.z; + vTangent += vNormalDelta.xyz * vMorphTexCoord.z; + flWrinkle = vPosDelta.w * vMorphTexCoord.z; +#endif // DECAL + + return true; + +#else // MORPHING + + flWrinkle = 0.0f; + return false; + +#endif +} + +#endif // SHADER_MODEL_VS_3_0 + + +float RangeFog( const float3 projPos ) +{ + return max( cFogMaxDensity, ( -projPos.z * cOOFogRange + cFogEndOverFogRange ) ); +} + +float WaterFog( const float3 worldPos, const float3 projPos ) +{ + float4 tmp; + + tmp.xy = cEyePosWaterZ.wz - worldPos.z; + + // tmp.x is the distance from the water surface to the vert + // tmp.y is the distance from the eye position to the vert + + // if $tmp.x < 0, then set it to 0 + // This is the equivalent of moving the vert to the water surface if it's above the water surface + + tmp.x = max( 0.0f, tmp.x ); + + // $tmp.w = $tmp.x / $tmp.y + tmp.w = tmp.x / tmp.y; + + tmp.w *= projPos.z; + + // $tmp.w is now the distance that we see through water. + + return max( cFogMaxDensity, ( -tmp.w * cOOFogRange + cFogOne ) ); +} + +float CalcFog( const float3 worldPos, const float3 projPos, const int fogType ) +{ +#if defined( _X360 ) + // 360 only does pixel fog + return 1.0f; +#endif + + if( fogType == FOGTYPE_RANGE ) + { + return RangeFog( projPos ); + } + else + { +#if SHADERMODEL_VS_2_0 == 1 + // We do this work in the pixel shader in dx9, so don't do any fog here. + return 1.0f; +#else + return WaterFog( worldPos, projPos ); +#endif + } +} + +float CalcFog( const float3 worldPos, const float3 projPos, const bool bWaterFog ) +{ +#if defined( _X360 ) + // 360 only does pixel fog + return 1.0f; +#endif + + float flFog; + if( !bWaterFog ) + { + flFog = RangeFog( projPos ); + } + else + { +#if SHADERMODEL_VS_2_0 == 1 + // We do this work in the pixel shader in dx9, so don't do any fog here. + flFog = 1.0f; +#else + flFog = WaterFog( worldPos, projPos ); +#endif + } + + return flFog; +} + +float4 DecompressBoneWeights( const float4 weights ) +{ + float4 result = weights; + + if ( COMPRESSED_VERTS ) + { + // Decompress from SHORT2 to float. In our case, [-1, +32767] -> [0, +1] + // NOTE: we add 1 here so we can divide by 32768 - which is exact (divide by 32767 is not). + // This avoids cracking between meshes with different numbers of bone weights. + // We use SHORT2 instead of SHORT2N for a similar reason - the GPU's conversion + // from [-32768,+32767] to [-1,+1] is imprecise in the same way. + result += 1; + result /= 32768; + } + + return result; +} + +void SkinPosition( bool bSkinning, const float4 modelPos, + const float4 boneWeights, float4 fBoneIndices, + out float3 worldPos ) +{ +#if !defined( _X360 ) + int3 boneIndices = D3DCOLORtoUBYTE4( fBoneIndices ); +#else + int3 boneIndices = fBoneIndices; +#endif + + // Needed for invariance issues caused by multipass rendering +#if defined( _X360 ) + [isolate] +#endif + { + if ( !bSkinning ) + { + worldPos = mul4x3( modelPos, cModel[0] ); + } + else // skinning - always three bones + { + float4x3 mat1 = cModel[boneIndices[0]]; + float4x3 mat2 = cModel[boneIndices[1]]; + float4x3 mat3 = cModel[boneIndices[2]]; + + float3 weights = DecompressBoneWeights( boneWeights ).xyz; + weights[2] = 1 - (weights[0] + weights[1]); + + float4x3 blendMatrix = mat1 * weights[0] + mat2 * weights[1] + mat3 * weights[2]; + worldPos = mul4x3( modelPos, blendMatrix ); + } + } +} + +void SkinPositionAndNormal( bool bSkinning, const float4 modelPos, const float3 modelNormal, + const float4 boneWeights, float4 fBoneIndices, + out float3 worldPos, out float3 worldNormal ) +{ + // Needed for invariance issues caused by multipass rendering +#if defined( _X360 ) + [isolate] +#endif + { + +#if !defined( _X360 ) + int3 boneIndices = D3DCOLORtoUBYTE4( fBoneIndices ); +#else + int3 boneIndices = fBoneIndices; +#endif + + if ( !bSkinning ) + { + worldPos = mul4x3( modelPos, cModel[0] ); + worldNormal = mul3x3( modelNormal, ( const float3x3 )cModel[0] ); + } + else // skinning - always three bones + { + float4x3 mat1 = cModel[boneIndices[0]]; + float4x3 mat2 = cModel[boneIndices[1]]; + float4x3 mat3 = cModel[boneIndices[2]]; + + float3 weights = DecompressBoneWeights( boneWeights ).xyz; + weights[2] = 1 - (weights[0] + weights[1]); + + float4x3 blendMatrix = mat1 * weights[0] + mat2 * weights[1] + mat3 * weights[2]; + worldPos = mul4x3( modelPos, blendMatrix ); + worldNormal = mul3x3( modelNormal, ( float3x3 )blendMatrix ); + } + + } // end [isolate] +} + +// Is it worth keeping SkinPosition and SkinPositionAndNormal around since the optimizer +// gets rid of anything that isn't used? +void SkinPositionNormalAndTangentSpace( + bool bSkinning, + const float4 modelPos, const float3 modelNormal, + const float4 modelTangentS, + const float4 boneWeights, float4 fBoneIndices, + out float3 worldPos, out float3 worldNormal, + out float3 worldTangentS, out float3 worldTangentT ) +{ +#if !defined( _X360 ) + int3 boneIndices = D3DCOLORtoUBYTE4( fBoneIndices ); +#else + int3 boneIndices = fBoneIndices; +#endif + + // Needed for invariance issues caused by multipass rendering +#if defined( _X360 ) + [isolate] +#endif + { + if ( !bSkinning ) + { + worldPos = mul4x3( modelPos, cModel[0] ); + worldNormal = mul3x3( modelNormal, ( const float3x3 )cModel[0] ); + worldTangentS = mul3x3( ( float3 )modelTangentS, ( const float3x3 )cModel[0] ); + } + else // skinning - always three bones + { + float4x3 mat1 = cModel[boneIndices[0]]; + float4x3 mat2 = cModel[boneIndices[1]]; + float4x3 mat3 = cModel[boneIndices[2]]; + + float3 weights = DecompressBoneWeights( boneWeights ).xyz; + weights[2] = 1 - (weights[0] + weights[1]); + + float4x3 blendMatrix = mat1 * weights[0] + mat2 * weights[1] + mat3 * weights[2]; + worldPos = mul4x3( modelPos, blendMatrix ); + worldNormal = mul3x3( modelNormal, ( const float3x3 )blendMatrix ); + worldTangentS = mul3x3( ( float3 )modelTangentS, ( const float3x3 )blendMatrix ); + } + worldTangentT = cross( worldNormal, worldTangentS ) * modelTangentS.w; + } +} + + +//----------------------------------------------------------------------------- +// Lighting helper functions +//----------------------------------------------------------------------------- + +float3 AmbientLight( const float3 worldNormal ) +{ + float3 nSquared = worldNormal * worldNormal; + int3 isNegative = ( worldNormal < 0.0 ); + float3 linearColor; + linearColor = nSquared.x * cAmbientCubeX[isNegative.x] + + nSquared.y * cAmbientCubeY[isNegative.y] + + nSquared.z * cAmbientCubeZ[isNegative.z]; + return linearColor; +} + +// The following "internal" routines are called "privately" by other routines in this file which +// handle the particular flavor of vs20 control flow appropriate to the original caller +float VertexAttenInternal( const float3 worldPos, int lightNum ) +{ + float result = 0.0f; + + // Get light direction + float3 lightDir = cLightInfo[lightNum].pos - worldPos; + + // Get light distance squared. + float lightDistSquared = dot( lightDir, lightDir ); + + // Get 1/lightDistance + float ooLightDist = rsqrt( lightDistSquared ); + + // Normalize light direction + lightDir *= ooLightDist; + + float3 vDist; +# if defined( _X360 ) + { + //X360 dynamic compile hits an internal compiler error using dst(), this is the breakdown of how dst() works from the 360 docs. + vDist.x = 1; + vDist.y = lightDistSquared * ooLightDist; + vDist.z = lightDistSquared; + //flDist.w = ooLightDist; + } +# else + { + vDist = dst( lightDistSquared, ooLightDist ); + } +# endif + + float flDistanceAtten = 1.0f / dot( cLightInfo[lightNum].atten.xyz, vDist ); + + // Spot attenuation + float flCosTheta = dot( cLightInfo[lightNum].dir.xyz, -lightDir ); + float flSpotAtten = (flCosTheta - cLightInfo[lightNum].spotParams.z) * cLightInfo[lightNum].spotParams.w; + flSpotAtten = max( 0.0001f, flSpotAtten ); + flSpotAtten = pow( flSpotAtten, cLightInfo[lightNum].spotParams.x ); + flSpotAtten = saturate( flSpotAtten ); + + // Select between point and spot + float flAtten = lerp( flDistanceAtten, flDistanceAtten * flSpotAtten, cLightInfo[lightNum].dir.w ); + + // Select between above and directional (no attenuation) + result = lerp( flAtten, 1.0f, cLightInfo[lightNum].color.w ); + + return result; +} + +float CosineTermInternal( const float3 worldPos, const float3 worldNormal, int lightNum, bool bHalfLambert ) +{ + // Calculate light direction assuming this is a point or spot + float3 lightDir = normalize( cLightInfo[lightNum].pos - worldPos ); + + // Select the above direction or the one in the structure, based upon light type + lightDir = lerp( lightDir, -cLightInfo[lightNum].dir, cLightInfo[lightNum].color.w ); + + // compute N dot L + float NDotL = dot( worldNormal, lightDir ); + + if ( !bHalfLambert ) + { + NDotL = max( 0.0f, NDotL ); + } + else // Half-Lambert + { + NDotL = NDotL * 0.5 + 0.5; + NDotL = NDotL * NDotL; + } + return NDotL; +} + +// This routine uses booleans to do early-outs and is meant to be called by routines OUTSIDE of this file +float GetVertexAttenForLight( const float3 worldPos, int lightNum, bool bUseStaticControlFlow ) +{ + float result = 0.0f; + + // Direct3D uses static control flow but OpenGL currently does not + if ( bUseStaticControlFlow ) + { + if ( g_bLightEnabled[lightNum] ) + { + result = VertexAttenInternal( worldPos, lightNum ); + } + } + else // OpenGL non-static-control-flow path + { + result = VertexAttenInternal( worldPos, lightNum ); + } + + return result; +} + +float3 DoLightInternal( const float3 worldPos, const float3 worldNormal, int lightNum, bool bHalfLambert ) +{ + return cLightInfo[lightNum].color * + CosineTermInternal( worldPos, worldNormal, lightNum, bHalfLambert ) * + VertexAttenInternal( worldPos, lightNum ); +} + +float3 DoLighting( const float3 worldPos, const float3 worldNormal, + const float3 staticLightingColor, const bool bStaticLight, + const bool bDynamicLight, bool bHalfLambert ) +{ + float3 linearColor = float3( 0.0f, 0.0f, 0.0f ); + + if( bStaticLight ) // Static light + { + float3 col = staticLightingColor * cOverbright; +#if defined ( _X360 ) + linearColor += col * col; +#else + linearColor += GammaToLinear( col ); +#endif + } + + if( bDynamicLight ) // Dynamic light + { + for (int i = 0; i < g_nLightCount; i++) + { + linearColor += DoLightInternal( worldPos, worldNormal, i, bHalfLambert ); + } + } + + if( bDynamicLight ) + { + linearColor += AmbientLight( worldNormal ); //ambient light is already remapped + } + + return linearColor; +} + +float3 DoLightingUnrolled( const float3 worldPos, const float3 worldNormal, + const float3 staticLightingColor, const bool bStaticLight, + const bool bDynamicLight, bool bHalfLambert, const int nNumLights ) +{ + float3 linearColor = float3( 0.0f, 0.0f, 0.0f ); + + if( bStaticLight ) // Static light + { + linearColor += GammaToLinear( staticLightingColor * cOverbright ); + } + + if( bDynamicLight ) // Ambient light + { + if ( nNumLights >= 1 ) + linearColor += DoLightInternal( worldPos, worldNormal, 0, bHalfLambert ); + if ( nNumLights >= 2 ) + linearColor += DoLightInternal( worldPos, worldNormal, 1, bHalfLambert ); + if ( nNumLights >= 3 ) + linearColor += DoLightInternal( worldPos, worldNormal, 2, bHalfLambert ); + if ( nNumLights >= 4 ) + linearColor += DoLightInternal( worldPos, worldNormal, 3, bHalfLambert ); + } + + if( bDynamicLight ) + { + linearColor += AmbientLight( worldNormal ); //ambient light is already remapped + } + + return linearColor; +} + +int4 FloatToInt( in float4 floats ) +{ + return D3DCOLORtoUBYTE4( floats.zyxw / 255.001953125 ); +} + +float2 ComputeSphereMapTexCoords( in float3 reflectionVector ) +{ + // transform reflection vector into view space + reflectionVector = mul( reflectionVector, ( float3x3 )cViewModel ); + + // generate + float3 tmp = float3( reflectionVector.x, reflectionVector.y, reflectionVector.z + 1.0f ); + + // find 1 / len + float ooLen = dot( tmp, tmp ); + ooLen = 1.0f / sqrt( ooLen ); + + // tmp = tmp/|tmp| + 1 + tmp.xy = ooLen * tmp.xy + 1.0f; + + return tmp.xy * 0.5f; +} + + +#define DEFORMATION_CLAMP_TO_BOX_IN_WORLDSPACE 1 + // minxyz.minsoftness / maxxyz.maxsoftness +float3 ApplyDeformation( float3 worldpos, int deftype, float4 defparms0, float4 defparms1, + float4 defparms2, float4 defparms3 ) +{ + float3 ret = worldpos; + if ( deftype == DEFORMATION_CLAMP_TO_BOX_IN_WORLDSPACE ) + { + ret=max( ret, defparms2.xyz ); + ret=min( ret, defparms3.xyz ); + } + + return ret; +} + + +#endif //#ifndef COMMON_VS_FXC_H_ diff --git a/mp/src/materialsystem/stdshaders/cpp_shader_constant_register_map.h b/mp/src/materialsystem/stdshaders/cpp_shader_constant_register_map.h index b448b048..a89e8eae 100644 --- a/mp/src/materialsystem/stdshaders/cpp_shader_constant_register_map.h +++ b/mp/src/materialsystem/stdshaders/cpp_shader_constant_register_map.h @@ -1,45 +1,45 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Provide convenient mapping for shader constants -// -// $NoKeywords: $ -//============================================================================= - -#define C_CODE_HACK -#include "shader_constant_register_map.h" -#undef C_CODE_HACK - -// For the C code, map the above file's defines back to integers... -#define PSREG_CONSTANT_00 0 -#define PSREG_CONSTANT_01 1 -#define PSREG_CONSTANT_02 2 -#define PSREG_CONSTANT_03 3 -#define PSREG_CONSTANT_04 4 -#define PSREG_CONSTANT_05 5 -#define PSREG_CONSTANT_06 6 -#define PSREG_CONSTANT_07 7 -#define PSREG_CONSTANT_08 8 -#define PSREG_CONSTANT_09 9 -#define PSREG_CONSTANT_10 10 -#define PSREG_CONSTANT_11 11 -#define PSREG_CONSTANT_12 12 -#define PSREG_CONSTANT_13 13 -#define PSREG_CONSTANT_14 14 -#define PSREG_CONSTANT_15 15 -#define PSREG_CONSTANT_16 16 -#define PSREG_CONSTANT_17 17 -#define PSREG_CONSTANT_18 18 -#define PSREG_CONSTANT_19 19 -#define PSREG_CONSTANT_20 20 -#define PSREG_CONSTANT_21 21 -#define PSREG_CONSTANT_22 22 -#define PSREG_CONSTANT_23 23 -#define PSREG_CONSTANT_24 24 -#define PSREG_CONSTANT_25 25 -#define PSREG_CONSTANT_26 26 -#define PSREG_CONSTANT_27 27 -#define PSREG_CONSTANT_28 28 -#define PSREG_CONSTANT_29 29 -#define PSREG_CONSTANT_30 30 -#define PSREG_CONSTANT_31 31 - +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Provide convenient mapping for shader constants +// +// $NoKeywords: $ +//============================================================================= + +#define C_CODE_HACK +#include "shader_constant_register_map.h" +#undef C_CODE_HACK + +// For the C code, map the above file's defines back to integers... +#define PSREG_CONSTANT_00 0 +#define PSREG_CONSTANT_01 1 +#define PSREG_CONSTANT_02 2 +#define PSREG_CONSTANT_03 3 +#define PSREG_CONSTANT_04 4 +#define PSREG_CONSTANT_05 5 +#define PSREG_CONSTANT_06 6 +#define PSREG_CONSTANT_07 7 +#define PSREG_CONSTANT_08 8 +#define PSREG_CONSTANT_09 9 +#define PSREG_CONSTANT_10 10 +#define PSREG_CONSTANT_11 11 +#define PSREG_CONSTANT_12 12 +#define PSREG_CONSTANT_13 13 +#define PSREG_CONSTANT_14 14 +#define PSREG_CONSTANT_15 15 +#define PSREG_CONSTANT_16 16 +#define PSREG_CONSTANT_17 17 +#define PSREG_CONSTANT_18 18 +#define PSREG_CONSTANT_19 19 +#define PSREG_CONSTANT_20 20 +#define PSREG_CONSTANT_21 21 +#define PSREG_CONSTANT_22 22 +#define PSREG_CONSTANT_23 23 +#define PSREG_CONSTANT_24 24 +#define PSREG_CONSTANT_25 25 +#define PSREG_CONSTANT_26 26 +#define PSREG_CONSTANT_27 27 +#define PSREG_CONSTANT_28 28 +#define PSREG_CONSTANT_29 29 +#define PSREG_CONSTANT_30 30 +#define PSREG_CONSTANT_31 31 + diff --git a/mp/src/materialsystem/stdshaders/dx8fallbacks.cpp b/mp/src/materialsystem/stdshaders/dx8fallbacks.cpp index 9ee2659c..a847ef38 100644 --- a/mp/src/materialsystem/stdshaders/dx8fallbacks.cpp +++ b/mp/src/materialsystem/stdshaders/dx8fallbacks.cpp @@ -1,11 +1,11 @@ -#include "BaseVSShader.h" - -// This one isn't supported on dx8 -DEFINE_FALLBACK_SHADER( SDK_DepthWrite, Wireframe ) - -DEFINE_FALLBACK_SHADER( SDK_EyeRefract, Eyes_dx8 ) -DEFINE_FALLBACK_SHADER( SDK_VolumeClouds, UnlitGeneric_DX8 ) - -// FIXME: These aren't supported on dx8, but need to be. -DEFINE_FALLBACK_SHADER( SDK_EyeGlint, EyeGlint ) -DEFINE_FALLBACK_SHADER( SDK_AfterShock, AfterShock ) +#include "BaseVSShader.h" + +// This one isn't supported on dx8 +DEFINE_FALLBACK_SHADER( SDK_DepthWrite, Wireframe ) + +DEFINE_FALLBACK_SHADER( SDK_EyeRefract, Eyes_dx8 ) +DEFINE_FALLBACK_SHADER( SDK_VolumeClouds, UnlitGeneric_DX8 ) + +// FIXME: These aren't supported on dx8, but need to be. +DEFINE_FALLBACK_SHADER( SDK_EyeGlint, EyeGlint ) +DEFINE_FALLBACK_SHADER( SDK_AfterShock, AfterShock ) diff --git a/mp/src/materialsystem/stdshaders/example_model_dx9.cpp b/mp/src/materialsystem/stdshaders/example_model_dx9.cpp index 87e012e3..12b6ee11 100644 --- a/mp/src/materialsystem/stdshaders/example_model_dx9.cpp +++ b/mp/src/materialsystem/stdshaders/example_model_dx9.cpp @@ -1,60 +1,60 @@ -//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== -// -// Example shader that can be applied to models -// -//================================================================================================== - -#include "BaseVSShader.h" -#include "convar.h" -#include "example_model_dx9_helper.h" - -#ifdef GAME_SHADER_DLL -DEFINE_FALLBACK_SHADER( Mod_Example_Model, Mod_Example_Model_DX9 ) -BEGIN_VS_SHADER( Mod_Example_Model_DX9, "Help for Example Model Shader" ) -#else -DEFINE_FALLBACK_SHADER( Example_Model, Example_Model_DX9 ) -BEGIN_VS_SHADER( Example_Model_DX9, "Help for Example Model Shader" ) -#endif - - BEGIN_SHADER_PARAMS - SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) - END_SHADER_PARAMS - - void SetupVars( ExampleModel_DX9_Vars_t& info ) - { - info.m_nBaseTexture = BASETEXTURE; - info.m_nBaseTextureFrame = FRAME; - info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; - info.m_nAlphaTestReference = ALPHATESTREFERENCE; - info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; - info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; - } - - SHADER_INIT_PARAMS() - { - ExampleModel_DX9_Vars_t info; - SetupVars( info ); - InitParamsExampleModel_DX9( this, params, pMaterialName, info ); - } - - SHADER_FALLBACK - { - return 0; - } - - SHADER_INIT - { - ExampleModel_DX9_Vars_t info; - SetupVars( info ); - InitExampleModel_DX9( this, params, info ); - } - - SHADER_DRAW - { - ExampleModel_DX9_Vars_t info; - SetupVars( info ); - DrawExampleModel_DX9( this, params, pShaderAPI, pShaderShadow, info, vertexCompression, pContextDataPtr ); - } - -END_SHADER - +//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== +// +// Example shader that can be applied to models +// +//================================================================================================== + +#include "BaseVSShader.h" +#include "convar.h" +#include "example_model_dx9_helper.h" + +#ifdef GAME_SHADER_DLL +DEFINE_FALLBACK_SHADER( Mod_Example_Model, Mod_Example_Model_DX9 ) +BEGIN_VS_SHADER( Mod_Example_Model_DX9, "Help for Example Model Shader" ) +#else +DEFINE_FALLBACK_SHADER( Example_Model, Example_Model_DX9 ) +BEGIN_VS_SHADER( Example_Model_DX9, "Help for Example Model Shader" ) +#endif + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + END_SHADER_PARAMS + + void SetupVars( ExampleModel_DX9_Vars_t& info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlphaTestReference = ALPHATESTREFERENCE; + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + } + + SHADER_INIT_PARAMS() + { + ExampleModel_DX9_Vars_t info; + SetupVars( info ); + InitParamsExampleModel_DX9( this, params, pMaterialName, info ); + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + ExampleModel_DX9_Vars_t info; + SetupVars( info ); + InitExampleModel_DX9( this, params, info ); + } + + SHADER_DRAW + { + ExampleModel_DX9_Vars_t info; + SetupVars( info ); + DrawExampleModel_DX9( this, params, pShaderAPI, pShaderShadow, info, vertexCompression, pContextDataPtr ); + } + +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/example_model_dx9_helper.cpp b/mp/src/materialsystem/stdshaders/example_model_dx9_helper.cpp index 471b9f80..82b8d466 100644 --- a/mp/src/materialsystem/stdshaders/example_model_dx9_helper.cpp +++ b/mp/src/materialsystem/stdshaders/example_model_dx9_helper.cpp @@ -1,341 +1,341 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//===========================================================================// -#include "BaseVSShader.h" -#include "example_model_dx9_helper.h" -#include "convar.h" -#include "cpp_shader_constant_register_map.h" -#include "example_model_vs20.inc" -#include "example_model_ps20b.inc" -#include "commandbuilder.h" - - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -static ConVar mat_fullbright( "mat_fullbright", "0", FCVAR_CHEAT ); -static ConVar r_lightwarpidentity( "r_lightwarpidentity", "0", FCVAR_CHEAT ); -static ConVar r_rimlight( "r_rimlight", "1", FCVAR_CHEAT ); - -// Textures may be bound to the following samplers: -// SHADER_SAMPLER0 Base (Albedo) / Gloss in alpha -// SHADER_SAMPLER4 Flashlight Shadow Depth Map -// SHADER_SAMPLER5 Normalization cube map -// SHADER_SAMPLER6 Flashlight Cookie - - -//----------------------------------------------------------------------------- -// Initialize shader parameters -//----------------------------------------------------------------------------- -void InitParamsExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, ExampleModel_DX9_Vars_t &info ) -{ - // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture - Assert( info.m_nFlashlightTexture >= 0 ); - - if ( g_pHardwareConfig->SupportsBorderColor() ) - { - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); - } - else - { - params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); - } - - // This shader can be used with hw skinning - SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); - SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); -} - -//----------------------------------------------------------------------------- -// Initialize shader -//----------------------------------------------------------------------------- -void InitExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, ExampleModel_DX9_Vars_t &info ) -{ - Assert( info.m_nFlashlightTexture >= 0 ); - pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB ); - - bool bIsBaseTextureTranslucent = false; - if ( params[info.m_nBaseTexture]->IsDefined() ) - { - pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); - - if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) - { - bIsBaseTextureTranslucent = true; - } - } -} - -class CExampleModel_DX9_Context : public CBasePerMaterialContextData -{ -public: - CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut; - bool m_bFastPath; - -}; - -//----------------------------------------------------------------------------- -// Draws the shader -//----------------------------------------------------------------------------- -void DrawExampleModel_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, - bool bHasFlashlight, ExampleModel_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, - CBasePerMaterialContextData **pContextDataPtr ) -{ - bool bHasBaseTexture = (info.m_nBaseTexture != -1) && params[info.m_nBaseTexture]->IsTexture(); - bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; - - BlendType_t nBlendType= pShader->EvaluateBlendRequirements( info.m_nBaseTexture, true ); - bool bFullyOpaque = ( nBlendType != BT_BLENDADD ) && ( nBlendType != BT_BLEND ) && !bIsAlphaTested && !bHasFlashlight; - - CExampleModel_DX9_Context *pContextData = reinterpret_cast< CExampleModel_DX9_Context *> ( *pContextDataPtr ); - if ( !pContextData ) - { - pContextData = new CExampleModel_DX9_Context; - *pContextDataPtr = pContextData; - } - - if( pShader->IsSnapshotting() ) - { - pShaderShadow->EnableAlphaTest( bIsAlphaTested ); - - if( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) - { - pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); - } - - int nShadowFilterMode = 0; - if( bHasFlashlight ) - { - if (params[info.m_nBaseTexture]->IsTexture()) - { - pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); - } - - if( bIsAlphaTested ) - { - // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to - // be the same on both the regular pass and the flashlight pass. - pShaderShadow->EnableAlphaTest( false ); - pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); - } - pShaderShadow->EnableBlending( true ); - pShaderShadow->EnableDepthWrites( false ); - - // Be sure not to write to dest alpha - pShaderShadow->EnableAlphaWrites( false ); - - nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats - } - else // not flashlight pass - { - if (params[info.m_nBaseTexture]->IsTexture()) - { - pShader->SetDefaultBlendingShadowState( info.m_nBaseTexture, true ); - } - } - - unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; - int userDataSize = 0; - - // Always enable...will bind white if nothing specified... - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base (albedo) map - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); - - if( bHasFlashlight ) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map - pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 ); - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false ); - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Noise map - pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Flashlight cookie - pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, true ); - userDataSize = 4; // tangent S - } - - // Always enable, since flat normal will be bound - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Normal map - userDataSize = 4; // tangent S - pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Normalizing cube map - pShaderShadow->EnableSRGBWrite( true ); - - // texcoord0 : base texcoord, texcoord2 : decal hw morph delta - int pTexCoordDim[3] = { 2, 0, 3 }; - int nTexCoordCount = 1; - - // This shader supports compressed vertices, so OR in that flag: - flags |= VERTEX_FORMAT_COMPRESSED; - - pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize ); - - DECLARE_STATIC_VERTEX_SHADER( example_model_vs20 ); - SET_STATIC_VERTEX_SHADER( example_model_vs20 ); - - // Assume we're only going to get in here if we support 2b - DECLARE_STATIC_PIXEL_SHADER( example_model_ps20b ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); - SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); - SET_STATIC_PIXEL_SHADER_COMBO( CONVERT_TO_SRGB, 0 ); - SET_STATIC_PIXEL_SHADER( example_model_ps20b ); - - if( bHasFlashlight ) - { - pShader->FogToBlack(); - } - else - { - pShader->DefaultFog(); - } - - // 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 ); - - if( bHasBaseTexture ) - { - pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); - } - else - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); - } - - LightState_t lightState = { 0, false, false }; - bool bFlashlightShadows = false; - if( bHasFlashlight ) - { - Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); - pShader->BindTexture( SHADER_SAMPLER6, info.m_nFlashlightTexture, info.m_nFlashlightTextureFrame ); - 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 ) - { - pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 ); - pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); - } - } - else // no flashlight - { - pShaderAPI->GetDX9LightState( &lightState ); - } - - MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); - int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; - int numBones = pShaderAPI->GetCurrentNumBones(); - - 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." ); - } - - DECLARE_DYNAMIC_VERTEX_SHADER( example_model_vs20 ); - 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( example_model_vs20 ); - - DECLARE_DYNAMIC_PIXEL_SHADER( example_model_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( example_model_ps20b ); - - pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); - pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); - pShader->SetAmbientCubeDynamicStateVertexShader(); - - if( !bHasFlashlight ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); - } - - pShaderAPI->SetPixelShaderStateAmbientLightCube( PSREG_AMBIENT_CUBE, !lightState.m_bAmbientLight ); // Force to black if not bAmbientLight - pShaderAPI->CommitPixelShaderLighting( PSREG_LIGHT_INFO_ARRAY ); - - // handle mat_fullbright 2 (diffuse lighting only) - if( bLightingOnly ) - { - pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); - } - - pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); - - if( bHasFlashlight ) - { - VMatrix worldToTexture; - float atten[4], pos[4], tweaks[4]; - - const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); - SetFlashLightColorFromState( flashlightState, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); - - pShader->BindTexture( SHADER_SAMPLER6, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); - - atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors - atten[1] = flashlightState.m_fLinearAtten; - atten[2] = flashlightState.m_fQuadraticAtten; - atten[3] = flashlightState.m_FarZ; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); - - pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin - 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 ); - pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); - pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); - - // Dimensions of screen, used for screen-space noise map sampling - float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; - int nWidth, nHeight; - pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); - vScreenScale[0] = (float) nWidth / 32.0f; - vScreenScale[1] = (float) nHeight / 32.0f; - pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); - } - } - pShader->Draw(); -} - - -//----------------------------------------------------------------------------- -// Draws the shader -//----------------------------------------------------------------------------- -void DrawExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, - ExampleModel_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr ) - -{ - bool bHasFlashlight = pShader->UsingFlashlight( params ); - if ( bHasFlashlight ) - { - DrawExampleModel_DX9_Internal( pShader, params, pShaderAPI, pShaderShadow, false, info, vertexCompression, pContextDataPtr++ ); - if ( pShaderShadow ) - { - pShader->SetInitialShadowState( ); - } - } - DrawExampleModel_DX9_Internal( pShader, params, pShaderAPI, pShaderShadow, bHasFlashlight, info, vertexCompression, pContextDataPtr ); -} +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#include "BaseVSShader.h" +#include "example_model_dx9_helper.h" +#include "convar.h" +#include "cpp_shader_constant_register_map.h" +#include "example_model_vs20.inc" +#include "example_model_ps20b.inc" +#include "commandbuilder.h" + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_fullbright( "mat_fullbright", "0", FCVAR_CHEAT ); +static ConVar r_lightwarpidentity( "r_lightwarpidentity", "0", FCVAR_CHEAT ); +static ConVar r_rimlight( "r_rimlight", "1", FCVAR_CHEAT ); + +// Textures may be bound to the following samplers: +// SHADER_SAMPLER0 Base (Albedo) / Gloss in alpha +// SHADER_SAMPLER4 Flashlight Shadow Depth Map +// SHADER_SAMPLER5 Normalization cube map +// SHADER_SAMPLER6 Flashlight Cookie + + +//----------------------------------------------------------------------------- +// Initialize shader parameters +//----------------------------------------------------------------------------- +void InitParamsExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, ExampleModel_DX9_Vars_t &info ) +{ + // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture + Assert( info.m_nFlashlightTexture >= 0 ); + + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + // This shader can be used with hw skinning + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); +} + +//----------------------------------------------------------------------------- +// Initialize shader +//----------------------------------------------------------------------------- +void InitExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, ExampleModel_DX9_Vars_t &info ) +{ + Assert( info.m_nFlashlightTexture >= 0 ); + pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB ); + + bool bIsBaseTextureTranslucent = false; + if ( params[info.m_nBaseTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); + + if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) + { + bIsBaseTextureTranslucent = true; + } + } +} + +class CExampleModel_DX9_Context : public CBasePerMaterialContextData +{ +public: + CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut; + bool m_bFastPath; + +}; + +//----------------------------------------------------------------------------- +// Draws the shader +//----------------------------------------------------------------------------- +void DrawExampleModel_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + bool bHasFlashlight, ExampleModel_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ) +{ + bool bHasBaseTexture = (info.m_nBaseTexture != -1) && params[info.m_nBaseTexture]->IsTexture(); + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + + BlendType_t nBlendType= pShader->EvaluateBlendRequirements( info.m_nBaseTexture, true ); + bool bFullyOpaque = ( nBlendType != BT_BLENDADD ) && ( nBlendType != BT_BLEND ) && !bIsAlphaTested && !bHasFlashlight; + + CExampleModel_DX9_Context *pContextData = reinterpret_cast< CExampleModel_DX9_Context *> ( *pContextDataPtr ); + if ( !pContextData ) + { + pContextData = new CExampleModel_DX9_Context; + *pContextDataPtr = pContextData; + } + + if( pShader->IsSnapshotting() ) + { + pShaderShadow->EnableAlphaTest( bIsAlphaTested ); + + if( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); + } + + int nShadowFilterMode = 0; + if( bHasFlashlight ) + { + if (params[info.m_nBaseTexture]->IsTexture()) + { + pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); + } + + if( bIsAlphaTested ) + { + // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to + // be the same on both the regular pass and the flashlight pass. + pShaderShadow->EnableAlphaTest( false ); + pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); + } + pShaderShadow->EnableBlending( true ); + pShaderShadow->EnableDepthWrites( false ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + } + else // not flashlight pass + { + if (params[info.m_nBaseTexture]->IsTexture()) + { + pShader->SetDefaultBlendingShadowState( info.m_nBaseTexture, true ); + } + } + + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; + int userDataSize = 0; + + // Always enable...will bind white if nothing specified... + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base (albedo) map + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + if( bHasFlashlight ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false ); + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Noise map + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Flashlight cookie + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, true ); + userDataSize = 4; // tangent S + } + + // Always enable, since flat normal will be bound + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Normal map + userDataSize = 4; // tangent S + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Normalizing cube map + pShaderShadow->EnableSRGBWrite( true ); + + // texcoord0 : base texcoord, texcoord2 : decal hw morph delta + int pTexCoordDim[3] = { 2, 0, 3 }; + int nTexCoordCount = 1; + + // This shader supports compressed vertices, so OR in that flag: + flags |= VERTEX_FORMAT_COMPRESSED; + + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize ); + + DECLARE_STATIC_VERTEX_SHADER( example_model_vs20 ); + SET_STATIC_VERTEX_SHADER( example_model_vs20 ); + + // Assume we're only going to get in here if we support 2b + DECLARE_STATIC_PIXEL_SHADER( example_model_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( CONVERT_TO_SRGB, 0 ); + SET_STATIC_PIXEL_SHADER( example_model_ps20b ); + + if( bHasFlashlight ) + { + pShader->FogToBlack(); + } + else + { + pShader->DefaultFog(); + } + + // 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 ); + + if( bHasBaseTexture ) + { + pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); + } + + LightState_t lightState = { 0, false, false }; + bool bFlashlightShadows = false; + if( bHasFlashlight ) + { + Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); + pShader->BindTexture( SHADER_SAMPLER6, info.m_nFlashlightTexture, info.m_nFlashlightTextureFrame ); + 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 ) + { + pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); + } + } + else // no flashlight + { + pShaderAPI->GetDX9LightState( &lightState ); + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + int numBones = pShaderAPI->GetCurrentNumBones(); + + 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." ); + } + + DECLARE_DYNAMIC_VERTEX_SHADER( example_model_vs20 ); + 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( example_model_vs20 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( example_model_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( example_model_ps20b ); + + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); + pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); + pShader->SetAmbientCubeDynamicStateVertexShader(); + + if( !bHasFlashlight ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + } + + pShaderAPI->SetPixelShaderStateAmbientLightCube( PSREG_AMBIENT_CUBE, !lightState.m_bAmbientLight ); // Force to black if not bAmbientLight + pShaderAPI->CommitPixelShaderLighting( PSREG_LIGHT_INFO_ARRAY ); + + // handle mat_fullbright 2 (diffuse lighting only) + if( bLightingOnly ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + if( bHasFlashlight ) + { + VMatrix worldToTexture; + float atten[4], pos[4], tweaks[4]; + + const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); + SetFlashLightColorFromState( flashlightState, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); + + pShader->BindTexture( SHADER_SAMPLER6, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); + + pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + 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 ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); + } + } + pShader->Draw(); +} + + +//----------------------------------------------------------------------------- +// Draws the shader +//----------------------------------------------------------------------------- +void DrawExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + ExampleModel_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr ) + +{ + bool bHasFlashlight = pShader->UsingFlashlight( params ); + if ( bHasFlashlight ) + { + DrawExampleModel_DX9_Internal( pShader, params, pShaderAPI, pShaderShadow, false, info, vertexCompression, pContextDataPtr++ ); + if ( pShaderShadow ) + { + pShader->SetInitialShadowState( ); + } + } + DrawExampleModel_DX9_Internal( pShader, params, pShaderAPI, pShaderShadow, bHasFlashlight, info, vertexCompression, pContextDataPtr ); +} diff --git a/mp/src/materialsystem/stdshaders/example_model_dx9_helper.h b/mp/src/materialsystem/stdshaders/example_model_dx9_helper.h index 3b82e71f..dfe2579c 100644 --- a/mp/src/materialsystem/stdshaders/example_model_dx9_helper.h +++ b/mp/src/materialsystem/stdshaders/example_model_dx9_helper.h @@ -1,46 +1,46 @@ -//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== -// -// Example shader that can be applied to models -// -//================================================================================================== - -#ifndef EXAMPLE_MODEL_DX9_HELPER_H -#define EXAMPLE_MODEL_DX9_HELPER_H - -#include - -//----------------------------------------------------------------------------- -// Forward declarations -//----------------------------------------------------------------------------- -class CBaseVSShader; -class IMaterialVar; -class IShaderDynamicAPI; -class IShaderShadow; - -//----------------------------------------------------------------------------- -// Init params/ init/ draw methods -//----------------------------------------------------------------------------- -struct ExampleModel_DX9_Vars_t -{ - ExampleModel_DX9_Vars_t() { memset( this, 0xFF, sizeof(*this) ); } - - int m_nBaseTexture; - int m_nBaseTextureFrame; - int m_nBaseTextureTransform; - int m_nAlphaTestReference; - int m_nFlashlightTexture; - int m_nFlashlightTextureFrame; -}; - -void InitParamsExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, - const char *pMaterialName, ExampleModel_DX9_Vars_t &info ); - -void InitExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, - ExampleModel_DX9_Vars_t &info ); - -void DrawExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, - IShaderShadow* pShaderShadow, - ExampleModel_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, - CBasePerMaterialContextData **pContextDataPtr ); - -#endif // EXAMPLE_MODEL_DX9_HELPER_H +//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== +// +// Example shader that can be applied to models +// +//================================================================================================== + +#ifndef EXAMPLE_MODEL_DX9_HELPER_H +#define EXAMPLE_MODEL_DX9_HELPER_H + +#include + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct ExampleModel_DX9_Vars_t +{ + ExampleModel_DX9_Vars_t() { memset( this, 0xFF, sizeof(*this) ); } + + int m_nBaseTexture; + int m_nBaseTextureFrame; + int m_nBaseTextureTransform; + int m_nAlphaTestReference; + int m_nFlashlightTexture; + int m_nFlashlightTextureFrame; +}; + +void InitParamsExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, + const char *pMaterialName, ExampleModel_DX9_Vars_t &info ); + +void InitExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, + ExampleModel_DX9_Vars_t &info ); + +void DrawExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, + ExampleModel_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ); + +#endif // EXAMPLE_MODEL_DX9_HELPER_H diff --git a/mp/src/materialsystem/stdshaders/game_shader_dx9_base.vpc b/mp/src/materialsystem/stdshaders/game_shader_dx9_base.vpc index 8ba932d3..b89578e8 100644 --- a/mp/src/materialsystem/stdshaders/game_shader_dx9_base.vpc +++ b/mp/src/materialsystem/stdshaders/game_shader_dx9_base.vpc @@ -1,90 +1,90 @@ -//----------------------------------------------------------------------------- -// game_shader_dx9.vpc -// -// Project Script for mods to use an an example of how to override shaders -//----------------------------------------------------------------------------- - -$Macro OUTBINDIR "$SRCDIR\..\game\$GAMENAME\bin" - -$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc" - -$Configuration "Debug" -{ - $General - { - $OutputDirectory "Debug_dx9_$GAMENAME" [$WIN32] - $IntermediateDirectory "Debug_dx9_$GAMENAME" [$WIN32] - } -} - -$Configuration "Release" -{ - $General - { - $OutputDirectory "Release_dx9_$GAMENAME" [$WIN32] - $IntermediateDirectory "Release_dx9_$GAMENAME" [$WIN32] - } -} - -// Common Configuration -$Configuration -{ - $Compiler - { - $AdditionalIncludeDirectories "$BASE;fxctmp9;vshtmp9;" [$WIN32||$POSIX] -// $AdditionalIncludeDirectories "$BASE;..\..\dx9sdk\include" [$WIN32] - $AdditionalIncludeDirectories "$BASE;fxctmp9_360;vshtmp9_360" [$X360] - $PreprocessorDefinitions "$BASE;STDSHADER_DX9_DLL_EXPORT;FAST_MATERIALVAR_ACCESS;GAME_SHADER_DLL" - $PreprocessorDefinitions "$BASE;USE_ACTUAL_DX" [($WIN32||$X360) && !$GL] - } - - $Linker - { - $AdditionalDependencies "$BASE version.lib winmm.lib" [$WIN32] - $SystemLibraries "iconv" [$OSXALL] - } -} - -$Project -{ - $Folder "Source Files" - { - $File "BaseVSShader.cpp" - - $File "example_model_dx9.cpp" - $File "example_model_dx9_helper.cpp" - - $File "Bloom.cpp" - $File "screenspace_general.cpp" - } - - $Folder "Header Files" - { - $File "BaseVSShader.h" - $File "common_fxc.h" - $File "common_hlsl_cpp_consts.h" - $File "common_ps_fxc.h" - $File "common_vertexlitgeneric_dx9.h" - $File "common_vs_fxc.h" - $File "shader_constant_register_map.h" - - $File "example_model_dx9_helper.h" - } - - $Folder "Link Libraries" [$WIN32] - { -// $File "$SRCDIR\dx9sdk\lib\d3dx9.lib" - } - - $Folder "Link Libraries" - { - $Lib mathlib - $Lib shaderlib - } - - $File "buildsdkshaders.bat" - $File "buildshaders.bat" - - $Shaders "stdshader_dx9_20b.txt" - $Shaders "stdshader_dx9_30.txt" -} +//----------------------------------------------------------------------------- +// game_shader_dx9.vpc +// +// Project Script for mods to use an an example of how to override shaders +//----------------------------------------------------------------------------- + +$Macro OUTBINDIR "$SRCDIR\..\game\$GAMENAME\bin" + +$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc" + +$Configuration "Debug" +{ + $General + { + $OutputDirectory "Debug_dx9_$GAMENAME" [$WIN32] + $IntermediateDirectory "Debug_dx9_$GAMENAME" [$WIN32] + } +} + +$Configuration "Release" +{ + $General + { + $OutputDirectory "Release_dx9_$GAMENAME" [$WIN32] + $IntermediateDirectory "Release_dx9_$GAMENAME" [$WIN32] + } +} + +// Common Configuration +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE;fxctmp9;vshtmp9;" [$WIN32||$POSIX] +// $AdditionalIncludeDirectories "$BASE;..\..\dx9sdk\include" [$WIN32] + $AdditionalIncludeDirectories "$BASE;fxctmp9_360;vshtmp9_360" [$X360] + $PreprocessorDefinitions "$BASE;STDSHADER_DX9_DLL_EXPORT;FAST_MATERIALVAR_ACCESS;GAME_SHADER_DLL" + $PreprocessorDefinitions "$BASE;USE_ACTUAL_DX" [($WIN32||$X360) && !$GL] + } + + $Linker + { + $AdditionalDependencies "$BASE version.lib winmm.lib" [$WIN32] + $SystemLibraries "iconv" [$OSXALL] + } +} + +$Project +{ + $Folder "Source Files" + { + $File "BaseVSShader.cpp" + + $File "example_model_dx9.cpp" + $File "example_model_dx9_helper.cpp" + + $File "Bloom.cpp" + $File "screenspace_general.cpp" + } + + $Folder "Header Files" + { + $File "BaseVSShader.h" + $File "common_fxc.h" + $File "common_hlsl_cpp_consts.h" + $File "common_ps_fxc.h" + $File "common_vertexlitgeneric_dx9.h" + $File "common_vs_fxc.h" + $File "shader_constant_register_map.h" + + $File "example_model_dx9_helper.h" + } + + $Folder "Link Libraries" [$WIN32] + { +// $File "$SRCDIR\dx9sdk\lib\d3dx9.lib" + } + + $Folder "Link Libraries" + { + $Lib mathlib + $Lib shaderlib + } + + $File "buildsdkshaders.bat" + $File "buildshaders.bat" + + $Shaders "stdshader_dx9_20b.txt" + $Shaders "stdshader_dx9_30.txt" +} diff --git a/mp/src/materialsystem/stdshaders/game_shader_dx9_hl2mp.vpc b/mp/src/materialsystem/stdshaders/game_shader_dx9_hl2mp.vpc index 7f5339b7..dee82199 100644 --- a/mp/src/materialsystem/stdshaders/game_shader_dx9_hl2mp.vpc +++ b/mp/src/materialsystem/stdshaders/game_shader_dx9_hl2mp.vpc @@ -1,13 +1,13 @@ -//----------------------------------------------------------------------------- -// game_shader_dx9.vpc -// -// Project Script for mods to use an an example of how to override shaders -//----------------------------------------------------------------------------- - -$Macro SRCDIR "..\.." -$Macro GAMENAME "mod_hl2mp" -$Include "$SRCDIR\materialsystem\stdshaders\game_shader_dx9_base.vpc" - -$Project "Shaders (HL2MP)" -{ +//----------------------------------------------------------------------------- +// game_shader_dx9.vpc +// +// Project Script for mods to use an an example of how to override shaders +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\.." +$Macro GAMENAME "mod_hl2mp" +$Include "$SRCDIR\materialsystem\stdshaders\game_shader_dx9_base.vpc" + +$Project "Shaders (HL2MP)" +{ } \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/genwaterloop.pl b/mp/src/materialsystem/stdshaders/genwaterloop.pl index 0a4701ce..64ad0658 100644 --- a/mp/src/materialsystem/stdshaders/genwaterloop.pl +++ b/mp/src/materialsystem/stdshaders/genwaterloop.pl @@ -1,9 +1,9 @@ -for($ix=-2;$ix<=2;$ix++) -{ - for($iy=-2;$iy<=2;$iy++) - { - print "vRefractColor += tex2D( RefractSampler, vRefractTexCoord + $ix * ddx1 + $iy * ddy1 );\n"; - $sumweights+=1; - } -} -print "float sumweights = $sumweights;\n"; +for($ix=-2;$ix<=2;$ix++) +{ + for($iy=-2;$iy<=2;$iy++) + { + print "vRefractColor += tex2D( RefractSampler, vRefractTexCoord + $ix * ddx1 + $iy * ddy1 );\n"; + $sumweights+=1; + } +} +print "float sumweights = $sumweights;\n"; diff --git a/mp/src/materialsystem/stdshaders/screenspace_general.cpp b/mp/src/materialsystem/stdshaders/screenspace_general.cpp index 0a2bf03e..4d2ad67f 100644 --- a/mp/src/materialsystem/stdshaders/screenspace_general.cpp +++ b/mp/src/materialsystem/stdshaders/screenspace_general.cpp @@ -1,232 +1,232 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#include "BaseVSShader.h" - -#include "SDK_screenspaceeffect_vs20.inc" - -DEFINE_FALLBACK_SHADER( SDK_screenspace_general, SDK_screenspace_general_dx9 ) -BEGIN_VS_SHADER_FLAGS( SDK_screenspace_general_dx9, "Help for screenspace_general", SHADER_NOT_EDITABLE ) - BEGIN_SHADER_PARAMS - SHADER_PARAM( C0_X,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( C0_Y,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( C0_Z,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( C0_W,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( C1_X,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( C1_Y,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( C1_Z,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( C1_W,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( C2_X,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( C2_Y,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( C2_Z,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( C2_W,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( C3_X,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( C3_Y,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( C3_Z,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( C3_W,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( PIXSHADER, SHADER_PARAM_TYPE_STRING, "", "Name of the pixel shader to use" ) - SHADER_PARAM( DISABLE_COLOR_WRITES,SHADER_PARAM_TYPE_INTEGER,"0","") - SHADER_PARAM( ALPHATESTED,SHADER_PARAM_TYPE_FLOAT,"0","") - SHADER_PARAM( TEXTURE1, SHADER_PARAM_TYPE_TEXTURE, "", "" ) - SHADER_PARAM( TEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "", "" ) - SHADER_PARAM( TEXTURE3, SHADER_PARAM_TYPE_TEXTURE, "", "" ) - SHADER_PARAM( LINEARREAD_BASETEXTURE, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( LINEARREAD_TEXTURE1, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( LINEARREAD_TEXTURE2, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( LINEARREAD_TEXTURE3, SHADER_PARAM_TYPE_INTEGER, "0", "" ) - SHADER_PARAM( LINEARWRITE,SHADER_PARAM_TYPE_INTEGER,"0","") - SHADER_PARAM( X360APPCHOOSER, SHADER_PARAM_TYPE_INTEGER, "0", "Needed for movies in 360 launcher" ) - END_SHADER_PARAMS - - SHADER_INIT - { - if ( params[BASETEXTURE]->IsDefined() ) - { - LoadTexture( BASETEXTURE ); - } - if ( params[TEXTURE1]->IsDefined() ) - { - LoadTexture( TEXTURE1 ); - } - if ( params[TEXTURE2]->IsDefined() ) - { - LoadTexture( TEXTURE2 ); - } - if ( params[TEXTURE3]->IsDefined() ) - { - LoadTexture( TEXTURE3 ); - } - } - - SHADER_FALLBACK - { - if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) - { - return "screenspace_general_dx8"; - } - - return 0; - } - - SHADER_DRAW - { - SHADOW_STATE - { - pShaderShadow->EnableDepthWrites( false ); - - if (params[BASETEXTURE]->IsDefined()) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); - ITexture *txtr=params[BASETEXTURE]->GetTextureValue(); - ImageFormat fmt=txtr->GetImageFormat(); - if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); - else - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0, !params[LINEARREAD_BASETEXTURE]->IsDefined() || !params[LINEARREAD_BASETEXTURE]->GetIntValue() ); - } - if (params[TEXTURE1]->IsDefined()) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); - ITexture *txtr=params[TEXTURE1]->GetTextureValue(); - ImageFormat fmt=txtr->GetImageFormat(); - if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER1,false); - else - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER1, !params[LINEARREAD_TEXTURE1]->IsDefined() || !params[LINEARREAD_TEXTURE1]->GetIntValue() ); - } - if (params[TEXTURE2]->IsDefined()) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); - ITexture *txtr=params[TEXTURE2]->GetTextureValue(); - ImageFormat fmt=txtr->GetImageFormat(); - if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER2,false); - else - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER2, !params[LINEARREAD_TEXTURE2]->IsDefined() || !params[LINEARREAD_TEXTURE2]->GetIntValue() ); - } - if (params[TEXTURE3]->IsDefined()) - { - pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); - ITexture *txtr=params[TEXTURE3]->GetTextureValue(); - ImageFormat fmt=txtr->GetImageFormat(); - if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER3,false); - else - pShaderShadow->EnableSRGBRead(SHADER_SAMPLER3, !params[LINEARREAD_TEXTURE3]->IsDefined() || !params[LINEARREAD_TEXTURE3]->GetIntValue() ); - } - int fmt = VERTEX_POSITION; - - if ( IS_PARAM_DEFINED( X360APPCHOOSER ) && ( params[X360APPCHOOSER]->GetIntValue() ) ) - { - fmt |= VERTEX_COLOR; - EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); - } - pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); - - // maybe convert from linear to gamma on write. - bool srgb_write=true; - if (params[LINEARWRITE]->GetFloatValue()) - srgb_write=false; - pShaderShadow->EnableSRGBWrite( srgb_write ); - - // Pre-cache shaders - DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); - SET_STATIC_VERTEX_SHADER_COMBO( X360APPCHOOSER, IS_PARAM_DEFINED( X360APPCHOOSER ) ? params[X360APPCHOOSER]->GetIntValue() : 0 ); - vsh_forgot_to_set_static_X360APPCHOOSER = 0; // This is a dirty workaround to the shortcut [= 0] in the fxc - SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); - - if (params[DISABLE_COLOR_WRITES]->GetIntValue()) - { - pShaderShadow->EnableColorWrites(false); - } -// if (params[ALPHATESTED]->GetFloatValue()) - { - pShaderShadow->EnableAlphaTest(true); - pShaderShadow->AlphaFunc(SHADER_ALPHAFUNC_GREATER,0.0); - } - if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) ) - { - EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); - } - - if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) - { - const char *szPixelShader = params[PIXSHADER]->GetStringValue(); - size_t iLength = Q_strlen( szPixelShader ); - - if( (iLength > 5) && (Q_stricmp( &szPixelShader[iLength - 5], "_ps20" ) == 0) ) //detect if it's trying to load a ps20 shader - { - //replace it with the ps20b shader - char *szNewName = (char *)stackalloc( sizeof( char ) * (iLength + 2) ); - memcpy( szNewName, szPixelShader, sizeof( char ) * iLength ); - szNewName[iLength] = 'b'; - szNewName[iLength + 1] = '\0'; - pShaderShadow->SetPixelShader( szNewName, 0 ); - } - else - { - pShaderShadow->SetPixelShader( params[PIXSHADER]->GetStringValue(), 0 ); - } - } - else - { - pShaderShadow->SetPixelShader( params[PIXSHADER]->GetStringValue(), 0 ); - } - } - - DYNAMIC_STATE - { - if (params[BASETEXTURE]->IsDefined()) - { - BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); - } - if (params[TEXTURE1]->IsDefined()) - { - BindTexture( SHADER_SAMPLER1, TEXTURE1, -1 ); - } - if (params[TEXTURE2]->IsDefined()) - { - BindTexture( SHADER_SAMPLER2, TEXTURE2, -1 ); - } - if (params[TEXTURE3]->IsDefined()) - { - BindTexture( SHADER_SAMPLER3, TEXTURE3, -1 ); - } - float c0[]={ - params[C0_X]->GetFloatValue(), - params[C0_Y]->GetFloatValue(), - params[C0_Z]->GetFloatValue(), - params[C0_W]->GetFloatValue(), - params[C1_X]->GetFloatValue(), - params[C1_Y]->GetFloatValue(), - params[C1_Z]->GetFloatValue(), - params[C1_W]->GetFloatValue(), - params[C2_X]->GetFloatValue(), - params[C2_Y]->GetFloatValue(), - params[C2_Z]->GetFloatValue(), - params[C2_W]->GetFloatValue(), - params[C3_X]->GetFloatValue(), - params[C3_Y]->GetFloatValue(), - params[C3_Z]->GetFloatValue(), - params[C3_W]->GetFloatValue() - }; - - pShaderAPI->SetPixelShaderConstant( 0, c0, ARRAYSIZE(c0)/4 ); - - float eyePos[4]; - pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); - pShaderAPI->SetPixelShaderConstant( 10, eyePos, 1 ); - - pShaderAPI->SetVertexShaderIndex( 0 ); - pShaderAPI->SetPixelShaderIndex( 0 ); - - DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); - SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); - } - Draw(); - } -END_SHADER +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +#include "SDK_screenspaceeffect_vs20.inc" + +DEFINE_FALLBACK_SHADER( SDK_screenspace_general, SDK_screenspace_general_dx9 ) +BEGIN_VS_SHADER_FLAGS( SDK_screenspace_general_dx9, "Help for screenspace_general", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( C0_X,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( C0_Y,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( C0_Z,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( C0_W,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( C1_X,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( C1_Y,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( C1_Z,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( C1_W,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( C2_X,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( C2_Y,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( C2_Z,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( C2_W,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( C3_X,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( C3_Y,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( C3_Z,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( C3_W,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( PIXSHADER, SHADER_PARAM_TYPE_STRING, "", "Name of the pixel shader to use" ) + SHADER_PARAM( DISABLE_COLOR_WRITES,SHADER_PARAM_TYPE_INTEGER,"0","") + SHADER_PARAM( ALPHATESTED,SHADER_PARAM_TYPE_FLOAT,"0","") + SHADER_PARAM( TEXTURE1, SHADER_PARAM_TYPE_TEXTURE, "", "" ) + SHADER_PARAM( TEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "", "" ) + SHADER_PARAM( TEXTURE3, SHADER_PARAM_TYPE_TEXTURE, "", "" ) + SHADER_PARAM( LINEARREAD_BASETEXTURE, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( LINEARREAD_TEXTURE1, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( LINEARREAD_TEXTURE2, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( LINEARREAD_TEXTURE3, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( LINEARWRITE,SHADER_PARAM_TYPE_INTEGER,"0","") + SHADER_PARAM( X360APPCHOOSER, SHADER_PARAM_TYPE_INTEGER, "0", "Needed for movies in 360 launcher" ) + END_SHADER_PARAMS + + SHADER_INIT + { + if ( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + if ( params[TEXTURE1]->IsDefined() ) + { + LoadTexture( TEXTURE1 ); + } + if ( params[TEXTURE2]->IsDefined() ) + { + LoadTexture( TEXTURE2 ); + } + if ( params[TEXTURE3]->IsDefined() ) + { + LoadTexture( TEXTURE3 ); + } + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "screenspace_general_dx8"; + } + + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + + if (params[BASETEXTURE]->IsDefined()) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + ITexture *txtr=params[BASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); + else + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0, !params[LINEARREAD_BASETEXTURE]->IsDefined() || !params[LINEARREAD_BASETEXTURE]->GetIntValue() ); + } + if (params[TEXTURE1]->IsDefined()) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + ITexture *txtr=params[TEXTURE1]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER1,false); + else + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER1, !params[LINEARREAD_TEXTURE1]->IsDefined() || !params[LINEARREAD_TEXTURE1]->GetIntValue() ); + } + if (params[TEXTURE2]->IsDefined()) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + ITexture *txtr=params[TEXTURE2]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER2,false); + else + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER2, !params[LINEARREAD_TEXTURE2]->IsDefined() || !params[LINEARREAD_TEXTURE2]->GetIntValue() ); + } + if (params[TEXTURE3]->IsDefined()) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + ITexture *txtr=params[TEXTURE3]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER3,false); + else + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER3, !params[LINEARREAD_TEXTURE3]->IsDefined() || !params[LINEARREAD_TEXTURE3]->GetIntValue() ); + } + int fmt = VERTEX_POSITION; + + if ( IS_PARAM_DEFINED( X360APPCHOOSER ) && ( params[X360APPCHOOSER]->GetIntValue() ) ) + { + fmt |= VERTEX_COLOR; + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + // maybe convert from linear to gamma on write. + bool srgb_write=true; + if (params[LINEARWRITE]->GetFloatValue()) + srgb_write=false; + pShaderShadow->EnableSRGBWrite( srgb_write ); + + // Pre-cache shaders + DECLARE_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( X360APPCHOOSER, IS_PARAM_DEFINED( X360APPCHOOSER ) ? params[X360APPCHOOSER]->GetIntValue() : 0 ); + vsh_forgot_to_set_static_X360APPCHOOSER = 0; // This is a dirty workaround to the shortcut [= 0] in the fxc + SET_STATIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); + + if (params[DISABLE_COLOR_WRITES]->GetIntValue()) + { + pShaderShadow->EnableColorWrites(false); + } +// if (params[ALPHATESTED]->GetFloatValue()) + { + pShaderShadow->EnableAlphaTest(true); + pShaderShadow->AlphaFunc(SHADER_ALPHAFUNC_GREATER,0.0); + } + if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) ) + { + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + const char *szPixelShader = params[PIXSHADER]->GetStringValue(); + size_t iLength = Q_strlen( szPixelShader ); + + if( (iLength > 5) && (Q_stricmp( &szPixelShader[iLength - 5], "_ps20" ) == 0) ) //detect if it's trying to load a ps20 shader + { + //replace it with the ps20b shader + char *szNewName = (char *)stackalloc( sizeof( char ) * (iLength + 2) ); + memcpy( szNewName, szPixelShader, sizeof( char ) * iLength ); + szNewName[iLength] = 'b'; + szNewName[iLength + 1] = '\0'; + pShaderShadow->SetPixelShader( szNewName, 0 ); + } + else + { + pShaderShadow->SetPixelShader( params[PIXSHADER]->GetStringValue(), 0 ); + } + } + else + { + pShaderShadow->SetPixelShader( params[PIXSHADER]->GetStringValue(), 0 ); + } + } + + DYNAMIC_STATE + { + if (params[BASETEXTURE]->IsDefined()) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); + } + if (params[TEXTURE1]->IsDefined()) + { + BindTexture( SHADER_SAMPLER1, TEXTURE1, -1 ); + } + if (params[TEXTURE2]->IsDefined()) + { + BindTexture( SHADER_SAMPLER2, TEXTURE2, -1 ); + } + if (params[TEXTURE3]->IsDefined()) + { + BindTexture( SHADER_SAMPLER3, TEXTURE3, -1 ); + } + float c0[]={ + params[C0_X]->GetFloatValue(), + params[C0_Y]->GetFloatValue(), + params[C0_Z]->GetFloatValue(), + params[C0_W]->GetFloatValue(), + params[C1_X]->GetFloatValue(), + params[C1_Y]->GetFloatValue(), + params[C1_Z]->GetFloatValue(), + params[C1_W]->GetFloatValue(), + params[C2_X]->GetFloatValue(), + params[C2_Y]->GetFloatValue(), + params[C2_Z]->GetFloatValue(), + params[C2_W]->GetFloatValue(), + params[C3_X]->GetFloatValue(), + params[C3_Y]->GetFloatValue(), + params[C3_Z]->GetFloatValue(), + params[C3_W]->GetFloatValue() + }; + + pShaderAPI->SetPixelShaderConstant( 0, c0, ARRAYSIZE(c0)/4 ); + + float eyePos[4]; + pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); + pShaderAPI->SetPixelShaderConstant( 10, eyePos, 1 ); + + pShaderAPI->SetVertexShaderIndex( 0 ); + pShaderAPI->SetPixelShaderIndex( 0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( sdk_screenspaceeffect_vs20 ); + } + Draw(); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/shader_constant_register_map.h b/mp/src/materialsystem/stdshaders/shader_constant_register_map.h index 485bb7c4..ef1d9df7 100644 --- a/mp/src/materialsystem/stdshaders/shader_constant_register_map.h +++ b/mp/src/materialsystem/stdshaders/shader_constant_register_map.h @@ -1,81 +1,81 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Provide convenient mapping for shader constants -// -// $NoKeywords: $ -//============================================================================= - -#ifndef C_CODE_HACK -#include "common_vertexlitgeneric_dx9.h" -#endif - -#define PSREG_SELFILLUMTINT PSREG_CONSTANT_00 -#define PSREG_DIFFUSE_MODULATION PSREG_CONSTANT_01 -#define PSREG_ENVMAP_TINT__SHADOW_TWEAKS PSREG_CONSTANT_02 -#define PSREG_SELFILLUM_SCALE_BIAS_EXP PSREG_CONSTANT_03 -#define PSREG_AMBIENT_CUBE PSREG_CONSTANT_04 -// PSREG_AMBIENT_CUBE PSREG_CONSTANT_05 -// PSREG_AMBIENT_CUBE PSREG_CONSTANT_06 -// PSREG_AMBIENT_CUBE PSREG_CONSTANT_07 -// PSREG_AMBIENT_CUBE PSREG_CONSTANT_08 -// PSREG_AMBIENT_CUBE PSREG_CONSTANT_09 -#define PSREG_ENVMAP_FRESNEL__SELFILLUMMASK PSREG_CONSTANT_10 -#define PSREG_EYEPOS_SPEC_EXPONENT PSREG_CONSTANT_11 -#define PSREG_FOG_PARAMS PSREG_CONSTANT_12 -#define PSREG_FLASHLIGHT_ATTENUATION PSREG_CONSTANT_13 -#define PSREG_FLASHLIGHT_POSITION_RIM_BOOST PSREG_CONSTANT_14 -#define PSREG_FLASHLIGHT_TO_WORLD_TEXTURE PSREG_CONSTANT_15 -// PSREG_FLASHLIGHT_TO_WORLD_TEXTURE PSREG_CONSTANT_16 -// PSREG_FLASHLIGHT_TO_WORLD_TEXTURE PSREG_CONSTANT_17 -// PSREG_FLASHLIGHT_TO_WORLD_TEXTURE PSREG_CONSTANT_18 -#define PSREG_FRESNEL_SPEC_PARAMS PSREG_CONSTANT_19 -#define PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_20 -// PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_21 -// PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_22 -// PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_23 -// PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_24 -// PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_25 -#define PSREG_SPEC_RIM_PARAMS PSREG_CONSTANT_26 -// #define **free** PSREG_CONSTANT_27 //actually using this often blows constant limits, since literals have to get stuffed somewhere... -#define PSREG_FLASHLIGHT_COLOR PSREG_CONSTANT_28 -#define PSREG_LINEAR_FOG_COLOR PSREG_CONSTANT_29 -#define PSREG_LIGHT_SCALE PSREG_CONSTANT_30 -#define PSREG_FLASHLIGHT_SCREEN_SCALE PSREG_CONSTANT_31 -// --- End of ps_2_0 and ps_2_b constants --- - - -#ifndef C_CODE_HACK -//for fxc code, map the constants to register names. -#define PSREG_CONSTANT_00 c0 -#define PSREG_CONSTANT_01 c1 -#define PSREG_CONSTANT_02 c2 -#define PSREG_CONSTANT_03 c3 -#define PSREG_CONSTANT_04 c4 -#define PSREG_CONSTANT_05 c5 -#define PSREG_CONSTANT_06 c6 -#define PSREG_CONSTANT_07 c7 -#define PSREG_CONSTANT_08 c8 -#define PSREG_CONSTANT_09 c9 -#define PSREG_CONSTANT_10 c10 -#define PSREG_CONSTANT_11 c11 -#define PSREG_CONSTANT_12 c12 -#define PSREG_CONSTANT_13 c13 -#define PSREG_CONSTANT_14 c14 -#define PSREG_CONSTANT_15 c15 -#define PSREG_CONSTANT_16 c16 -#define PSREG_CONSTANT_17 c17 -#define PSREG_CONSTANT_18 c18 -#define PSREG_CONSTANT_19 c19 -#define PSREG_CONSTANT_20 c20 -#define PSREG_CONSTANT_21 c21 -#define PSREG_CONSTANT_22 c22 -#define PSREG_CONSTANT_23 c23 -#define PSREG_CONSTANT_24 c24 -#define PSREG_CONSTANT_25 c25 -#define PSREG_CONSTANT_26 c26 -#define PSREG_CONSTANT_27 c27 -#define PSREG_CONSTANT_28 c28 -#define PSREG_CONSTANT_29 c29 -#define PSREG_CONSTANT_30 c30 -#define PSREG_CONSTANT_31 c31 -#endif +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Provide convenient mapping for shader constants +// +// $NoKeywords: $ +//============================================================================= + +#ifndef C_CODE_HACK +#include "common_vertexlitgeneric_dx9.h" +#endif + +#define PSREG_SELFILLUMTINT PSREG_CONSTANT_00 +#define PSREG_DIFFUSE_MODULATION PSREG_CONSTANT_01 +#define PSREG_ENVMAP_TINT__SHADOW_TWEAKS PSREG_CONSTANT_02 +#define PSREG_SELFILLUM_SCALE_BIAS_EXP PSREG_CONSTANT_03 +#define PSREG_AMBIENT_CUBE PSREG_CONSTANT_04 +// PSREG_AMBIENT_CUBE PSREG_CONSTANT_05 +// PSREG_AMBIENT_CUBE PSREG_CONSTANT_06 +// PSREG_AMBIENT_CUBE PSREG_CONSTANT_07 +// PSREG_AMBIENT_CUBE PSREG_CONSTANT_08 +// PSREG_AMBIENT_CUBE PSREG_CONSTANT_09 +#define PSREG_ENVMAP_FRESNEL__SELFILLUMMASK PSREG_CONSTANT_10 +#define PSREG_EYEPOS_SPEC_EXPONENT PSREG_CONSTANT_11 +#define PSREG_FOG_PARAMS PSREG_CONSTANT_12 +#define PSREG_FLASHLIGHT_ATTENUATION PSREG_CONSTANT_13 +#define PSREG_FLASHLIGHT_POSITION_RIM_BOOST PSREG_CONSTANT_14 +#define PSREG_FLASHLIGHT_TO_WORLD_TEXTURE PSREG_CONSTANT_15 +// PSREG_FLASHLIGHT_TO_WORLD_TEXTURE PSREG_CONSTANT_16 +// PSREG_FLASHLIGHT_TO_WORLD_TEXTURE PSREG_CONSTANT_17 +// PSREG_FLASHLIGHT_TO_WORLD_TEXTURE PSREG_CONSTANT_18 +#define PSREG_FRESNEL_SPEC_PARAMS PSREG_CONSTANT_19 +#define PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_20 +// PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_21 +// PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_22 +// PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_23 +// PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_24 +// PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_25 +#define PSREG_SPEC_RIM_PARAMS PSREG_CONSTANT_26 +// #define **free** PSREG_CONSTANT_27 //actually using this often blows constant limits, since literals have to get stuffed somewhere... +#define PSREG_FLASHLIGHT_COLOR PSREG_CONSTANT_28 +#define PSREG_LINEAR_FOG_COLOR PSREG_CONSTANT_29 +#define PSREG_LIGHT_SCALE PSREG_CONSTANT_30 +#define PSREG_FLASHLIGHT_SCREEN_SCALE PSREG_CONSTANT_31 +// --- End of ps_2_0 and ps_2_b constants --- + + +#ifndef C_CODE_HACK +//for fxc code, map the constants to register names. +#define PSREG_CONSTANT_00 c0 +#define PSREG_CONSTANT_01 c1 +#define PSREG_CONSTANT_02 c2 +#define PSREG_CONSTANT_03 c3 +#define PSREG_CONSTANT_04 c4 +#define PSREG_CONSTANT_05 c5 +#define PSREG_CONSTANT_06 c6 +#define PSREG_CONSTANT_07 c7 +#define PSREG_CONSTANT_08 c8 +#define PSREG_CONSTANT_09 c9 +#define PSREG_CONSTANT_10 c10 +#define PSREG_CONSTANT_11 c11 +#define PSREG_CONSTANT_12 c12 +#define PSREG_CONSTANT_13 c13 +#define PSREG_CONSTANT_14 c14 +#define PSREG_CONSTANT_15 c15 +#define PSREG_CONSTANT_16 c16 +#define PSREG_CONSTANT_17 c17 +#define PSREG_CONSTANT_18 c18 +#define PSREG_CONSTANT_19 c19 +#define PSREG_CONSTANT_20 c20 +#define PSREG_CONSTANT_21 c21 +#define PSREG_CONSTANT_22 c22 +#define PSREG_CONSTANT_23 c23 +#define PSREG_CONSTANT_24 c24 +#define PSREG_CONSTANT_25 c25 +#define PSREG_CONSTANT_26 c26 +#define PSREG_CONSTANT_27 c27 +#define PSREG_CONSTANT_28 c28 +#define PSREG_CONSTANT_29 c29 +#define PSREG_CONSTANT_30 c30 +#define PSREG_CONSTANT_31 c31 +#endif -- cgit v1.2.3