aboutsummaryrefslogtreecommitdiff
path: root/mp/src/materialsystem
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/materialsystem
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/materialsystem')
-rw-r--r--mp/src/materialsystem/shaderapidx9/locald3dtypes.h382
-rw-r--r--mp/src/materialsystem/stdshaders/BaseVSShader.cpp4468
-rw-r--r--mp/src/materialsystem/stdshaders/BaseVSShader.h878
-rw-r--r--mp/src/materialsystem/stdshaders/Bloom.cpp180
-rw-r--r--mp/src/materialsystem/stdshaders/commandbuilder.h814
-rw-r--r--mp/src/materialsystem/stdshaders/common_flashlight_fxc.h1642
-rw-r--r--mp/src/materialsystem/stdshaders/common_fxc.h652
-rw-r--r--mp/src/materialsystem/stdshaders/common_fxc2.h38
-rw-r--r--mp/src/materialsystem/stdshaders/common_hlsl_cpp_consts.h54
-rw-r--r--mp/src/materialsystem/stdshaders/common_lightmappedgeneric_fxc.h404
-rw-r--r--mp/src/materialsystem/stdshaders/common_pragmas.h76
-rw-r--r--mp/src/materialsystem/stdshaders/common_ps_fxc.h1608
-rw-r--r--mp/src/materialsystem/stdshaders/common_vertexlitgeneric_dx9.h846
-rw-r--r--mp/src/materialsystem/stdshaders/common_vs_fxc.h1910
-rw-r--r--mp/src/materialsystem/stdshaders/cpp_shader_constant_register_map.h90
-rw-r--r--mp/src/materialsystem/stdshaders/dx8fallbacks.cpp22
-rw-r--r--mp/src/materialsystem/stdshaders/example_model_dx9.cpp120
-rw-r--r--mp/src/materialsystem/stdshaders/example_model_dx9_helper.cpp682
-rw-r--r--mp/src/materialsystem/stdshaders/example_model_dx9_helper.h92
-rw-r--r--mp/src/materialsystem/stdshaders/game_shader_dx9_base.vpc180
-rw-r--r--mp/src/materialsystem/stdshaders/game_shader_dx9_hl2mp.vpc24
-rw-r--r--mp/src/materialsystem/stdshaders/genwaterloop.pl18
-rw-r--r--mp/src/materialsystem/stdshaders/screenspace_general.cpp464
-rw-r--r--mp/src/materialsystem/stdshaders/shader_constant_register_map.h162
24 files changed, 7903 insertions, 7903 deletions
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 <d3d10.h>
-#include <d3dx10.h>
-
-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 <d3d10.h>
+#include <d3dx10.h>
+
+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 <renderparm.h>
-
-#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 <renderparm.h>
+
+#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<int N> 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<class T> FORCEINLINE void Put( T const &nValue )
- {
- EnsureCapacity( sizeof( T ) );
- *( reinterpret_cast<T *>( 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 S> 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<int N> 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<class T> FORCEINLINE void Put( T const &nValue )
+ {
+ EnsureCapacity( sizeof( T ) );
+ *( reinterpret_cast<T *>( 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 S> 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 <rx ry rz+1>
- 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 <rx ry rz+1>
+ 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 <string.h>
-
-//-----------------------------------------------------------------------------
-// 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 <string.h>
+
+//-----------------------------------------------------------------------------
+// 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