1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2025-09-19 12:06:07 +08:00

SDK sync.

This commit is contained in:
Scott Ehlert
2012-07-06 20:35:59 -05:00
parent 4fb33274fb
commit fdd0bbf277
413 changed files with 67257 additions and 4 deletions

View File

@ -0,0 +1,115 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $Header: $
// $NoKeywords: $
// An interface that should not ever be accessed directly from shaders
// but instead is visible only to shaderlib.
//===========================================================================//
#ifndef ISHADERSYSTEM_H
#define ISHADERSYSTEM_H
#ifdef _WIN32
#pragma once
#endif
#include "interface.h"
#include <materialsystem/IShader.h>
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
enum Sampler_t;
class ITexture;
class IShader;
//-----------------------------------------------------------------------------
// The Shader system interface version
//-----------------------------------------------------------------------------
#define SHADERSYSTEM_INTERFACE_VERSION "ShaderSystem002"
//-----------------------------------------------------------------------------
// Modulation flags
//-----------------------------------------------------------------------------
enum
{
SHADER_USING_ALPHA_MODULATION = 0x1,
SHADER_USING_FLASHLIGHT = 0x2,
SHADER_USING_FIXED_FUNCTION_BAKED_LIGHTING = 0x4,
SHADER_USING_EDITOR = 0x8,
// the BUFFER0 and GBUFFER1 bits provide 3 g-buffermodes plus the normal modes.
// the modes are:
// Normal rendering = ( gbuffer1 = 0, gbuffer0 = 0 )
// Output pos, normal, albedo via mrts = (0,1)
// output fixed lighted single image = (1,0)
// output the normal = (1,1)
SHADER_USING_GBUFFER0 = 0x10,
SHADER_USING_GBUFFER1 = 0x20,
};
//-----------------------------------------------------------------------------
// The shader system (a singleton)
//-----------------------------------------------------------------------------
abstract_class IShaderSystem
{
public:
virtual ShaderAPITextureHandle_t GetShaderAPITextureBindHandle( ITexture *pTexture, int nFrameVar, int nTextureChannel = 0 ) =0;
// Binds a texture
virtual void BindTexture( Sampler_t sampler1, ITexture *pTexture, int nFrameVar = 0 ) = 0;
virtual void BindTexture( Sampler_t sampler1, Sampler_t sampler2, ITexture *pTexture, int nFrameVar = 0 ) = 0;
// Takes a snapshot
virtual void TakeSnapshot( ) = 0;
// Draws a snapshot
virtual void DrawSnapshot( const unsigned char *pInstanceCommandBuffer, bool bMakeActualDrawCall = true ) = 0;
// Are we using graphics?
virtual bool IsUsingGraphics() const = 0;
// Are editor materials enabled?
virtual bool CanUseEditorMaterials() const = 0;
// Bind vertex texture
virtual void BindVertexTexture( VertexTextureSampler_t vtSampler, ITexture *pTexture, int nFrameVar = 0 ) = 0;
};
//-----------------------------------------------------------------------------
// The Shader plug-in DLL interface version
//-----------------------------------------------------------------------------
#define SHADER_DLL_INTERFACE_VERSION "ShaderDLL004"
//-----------------------------------------------------------------------------
// The Shader interface versions
//-----------------------------------------------------------------------------
abstract_class IShaderDLLInternal
{
public:
// Here's where the app systems get to learn about each other
virtual bool Connect( CreateInterfaceFn factory, bool bIsMaterialSystem ) = 0;
virtual void Disconnect( bool bIsMaterialSystem ) = 0;
// Returns the number of shaders defined in this DLL
virtual int ShaderCount() const = 0;
// Returns information about each shader defined in this DLL
virtual IShader *GetShader( int nShader ) = 0;
};
//-----------------------------------------------------------------------------
// Singleton interface
//-----------------------------------------------------------------------------
IShaderDLLInternal *GetShaderDLLInternal();
#endif // ISHADERSYSTEM_H

View File

@ -0,0 +1,176 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef IMATERIALINTERNAL_H
#define IMATERIALINTERNAL_H
#ifdef _WIN32
#pragma once
#endif
// identifier was truncated to '255' characters in the debug information
#pragma warning(disable: 4786)
#include "materialsystem/imaterialsystem.h"
#include "materialsystem/imaterial.h"
#include "shaderapi/ishaderapi.h"
#include "filesystem.h"
//-----------------------------------------------------------------------------
// forward declarations
//-----------------------------------------------------------------------------
enum MaterialPrimitiveType_t;
class IShader;
class IMesh;
class IVertexBuffer;
class IIndexBuffer;
struct Shader_VertexArrayData_t;
struct ShaderRenderState_t;
class KeyValues;
struct tokencache_t
{
unsigned short symbol;
unsigned char varIndex;
unsigned char cached : 1;
unsigned char subrect : 1;
};
//-----------------------------------------------------------------------------
// Interface for materials used only within the material system
//-----------------------------------------------------------------------------
abstract_class IMaterialInternal : public IMaterial
{
public:
// class factory methods
static IMaterialInternal* CreateMaterial( char const* pMaterialName, const char *pTextureGroupName, KeyValues *pKeyValues = NULL );
static void DestroyMaterial( IMaterialInternal* pMaterial );
// If supplied, pKeyValues and pPatchKeyValues should come from LoadVMTFile()
static IMaterialInternal* CreateMaterialSubRect( char const* pMaterialName, const char *pTextureGroupName,
KeyValues *pKeyValues = NULL, KeyValues *pPatchKeyValues = NULL, bool bAssumeCreateFromFile = false );
static void DestroyMaterialSubRect( IMaterialInternal* pMaterial );
// refcount
virtual int GetReferenceCount( ) const = 0;
// enumeration id
virtual void SetEnumerationID( int id ) = 0;
// White lightmap methods
virtual void SetNeedsWhiteLightmap( bool val ) = 0;
virtual bool GetNeedsWhiteLightmap( ) const = 0;
// load/unload
virtual void Uncache( bool bPreserveVars = false ) = 0;
virtual void Precache() = 0;
// If supplied, pKeyValues and pPatchKeyValues should come from LoadVMTFile()
virtual bool PrecacheVars( KeyValues *pKeyValues = NULL, KeyValues *pPatchKeyValues = NULL, CUtlVector<FileNameHandle_t> *pIncludes = NULL ) = 0;
// reload all textures used by this materals
virtual void ReloadTextures() = 0;
// lightmap pages associated with this material
virtual void SetMinLightmapPageID( int pageID ) = 0;
virtual void SetMaxLightmapPageID( int pageID ) = 0;;
virtual int GetMinLightmapPageID( ) const = 0;
virtual int GetMaxLightmapPageID( ) const = 0;
virtual IShader *GetShader() const = 0;
// Can we use it?
virtual bool IsPrecached( ) const = 0;
virtual bool IsPrecachedVars() const = 0;
// main draw method
virtual void DrawMesh( VertexCompressionType_t vertexCompression, bool bIsAlphaModulating, bool bUsingPreTessPatches ) = 0;
// Gets the vertex format
virtual VertexFormat_t GetVertexFormat() const = 0;
virtual VertexFormat_t GetVertexUsage() const = 0;
// Performs a debug trace on this material
virtual bool PerformDebugTrace() const = 0;
// Can we override this material in debug?
virtual bool NoDebugOverride() const = 0;
// Should we draw?
virtual void ToggleSuppression() = 0;
// Are we suppressed?
virtual bool IsSuppressed() const = 0;
// Should we debug?
virtual void ToggleDebugTrace() = 0;
// Do we use fog?
virtual bool UseFog() const = 0;
// Adds a material variable to the material
virtual void AddMaterialVar( IMaterialVar *pMaterialVar ) = 0;
// Gets the renderstate
virtual ShaderRenderState_t *GetRenderState() = 0;
// Was this manually created (not read from a file?)
virtual bool IsManuallyCreated() const = 0;
virtual bool NeedsFixedFunctionFlashlight() const = 0;
virtual bool IsUsingVertexID() const = 0;
// Identifies a material mounted through the preload path
virtual void MarkAsPreloaded( bool bSet ) = 0;
virtual bool IsPreloaded() const = 0;
// Conditonally increments the refcount
virtual void ArtificialAddRef( void ) = 0;
virtual void ArtificialRelease( void ) = 0;
virtual void ReportVarChanged( IMaterialVar *pVar ) = 0;
virtual uint32 GetChangeID() const = 0;
virtual bool IsTranslucentInternal( float fAlphaModulation ) const = 0;
//Is this the queue friendly or realtime version of the material?
virtual bool IsRealTimeVersion( void ) const = 0;
virtual void ClearContextData( void )
{
}
//easy swapping between the queue friendly and realtime versions of the material
virtual IMaterialInternal *GetRealTimeVersion( void ) = 0;
virtual IMaterialInternal *GetQueueFriendlyVersion( void ) = 0;
virtual void PrecacheMappingDimensions( void ) = 0;
virtual void FindRepresentativeTexture( void ) = 0;
// These are used when a new whitelist is passed in. First materials to be reloaded are flagged, then they are reloaded.
virtual void DecideShouldReloadFromWhitelist( IFileList *pFileList ) = 0;
virtual void ReloadFromWhitelistIfMarked() = 0;
virtual void CompactMaterialVars() = 0;
};
extern void InsertKeyValues( KeyValues& dst, KeyValues& src, bool bCheckForExistence );
extern void WriteKeyValuesToFile( const char *pFileName, KeyValues& keyValues );
extern void ExpandPatchFile( KeyValues& keyValues, KeyValues &patchKeyValues );
// patchKeyValues accumulates keys applied by VMT patch files (this is necessary to make $fallbackmaterial
// work properly - the patch keys need to be reapplied when the fallback VMT is loaded). It may contain
// previously accumulated patch keys on entry, and may contain more encountered patch keys on exit.
extern bool LoadVMTFile( KeyValues &vmtKeyValues, KeyValues &patchKeyValues, const char *pMaterialName, bool bUsesUNCFilename, CUtlVector<FileNameHandle_t> *pIncludes );
extern void CompactMaterialVars( IMaterialVar **ppMaterialVars, int nVars );
extern void CompactMaterialVarHeap();
#endif // IMATERIALINTERNAL_H

View File

@ -0,0 +1,229 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef IMATERIALSYSTEMINTERNAL_H
#define IMATERIALSYSTEMINTERNAL_H
#ifdef _WIN32
#pragma once
#endif
#include "materialsystem/imaterialsystem.h"
#include "tier1/callqueue.h"
#include "tier1/memstack.h"
class IMaterialInternal;
//-----------------------------------------------------------------------------
// Special call queue that knows (a) single threaded access, and (b) all
// functions called after last function added
//-----------------------------------------------------------------------------
class CMatCallQueue
{
public:
CMatCallQueue()
{
MEM_ALLOC_CREDIT_( "CMatCallQueue.m_Allocator" );
#ifdef SWDS
m_Allocator.Init( 2*1024, 0, 0, 4 );
#else
m_Allocator.Init( IsX360() ? 2*1024*1024 : 8*1024*1024, 64*1024, 256*1024, 4 );
#endif
m_FunctorFactory.SetAllocator( &m_Allocator );
m_pHead = m_pTail = NULL;
}
size_t GetMemoryUsed()
{
return m_Allocator.GetUsed();
}
int Count()
{
int i = 0;
Elem_t *pCurrent = m_pHead;
while ( pCurrent )
{
i++;
pCurrent = pCurrent->pNext;
}
return i;
}
void CallQueued()
{
if ( !m_pHead )
{
return;
}
CFunctor *pFunctor;
Elem_t *pCurrent = m_pHead;
while ( pCurrent )
{
pFunctor = pCurrent->pFunctor;
#ifdef _DEBUG
if ( pFunctor->m_nUserID == m_nBreakSerialNumber)
{
m_nBreakSerialNumber = (unsigned)-1;
}
#endif
(*pFunctor)();
pFunctor->Release();
pCurrent = pCurrent->pNext;
}
#ifdef DEBUG_MATCALLQUEUE
static int prevHigh = 0;
if ( m_Allocator.GetUsed() > prevHigh )
{
Msg( "***%d\n", m_Allocator.GetUsed() );
prevHigh = m_Allocator.GetUsed();
}
#endif
m_Allocator.FreeAll( false );
m_pHead = m_pTail = NULL;
}
void QueueFunctor( CFunctor *pFunctor )
{
Assert( pFunctor );
QueueFunctorInternal( RetAddRef( pFunctor ) );
}
void Flush()
{
if ( !m_pHead )
{
return;
}
CFunctor *pFunctor;
Elem_t *pCurrent = m_pHead;
while ( pCurrent )
{
pFunctor = pCurrent->pFunctor;
pFunctor->Release();
pCurrent = pCurrent->pNext;
}
m_Allocator.FreeAll( false );
m_pHead = m_pTail = NULL;
}
#define DEFINE_MATCALLQUEUE_NONMEMBER_QUEUE_CALL(N) \
template <typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
void QueueCall(FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
QueueFunctorInternal( m_FunctorFactory.CreateFunctor( pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \
}
//-------------------------------------
#define DEFINE_MATCALLQUEUE_MEMBER_QUEUE_CALL(N) \
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
void QueueCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
QueueFunctorInternal( m_FunctorFactory.CreateFunctor( pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \
}
//-------------------------------------
#define DEFINE_MATCALLQUEUE_CONST_MEMBER_QUEUE_CALL(N) \
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
void QueueCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
QueueFunctorInternal( m_FunctorFactory.CreateFunctor( pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \
}
//-------------------------------------
FUNC_GENERATE_ALL( DEFINE_MATCALLQUEUE_NONMEMBER_QUEUE_CALL );
FUNC_GENERATE_ALL( DEFINE_MATCALLQUEUE_MEMBER_QUEUE_CALL );
FUNC_GENERATE_ALL( DEFINE_MATCALLQUEUE_CONST_MEMBER_QUEUE_CALL );
private:
void QueueFunctorInternal( CFunctor *pFunctor )
{
#ifdef _DEBUG
pFunctor->m_nUserID = m_nCurSerialNumber++;
#endif
MEM_ALLOC_CREDIT_( "CMatCallQueue.m_Allocator" );
Elem_t *pNew = (Elem_t *)m_Allocator.Alloc( sizeof(Elem_t) );
if ( m_pTail )
{
m_pTail->pNext = pNew;
m_pTail = pNew;
}
else
{
m_pHead = m_pTail = pNew;
}
pNew->pNext = NULL;
pNew->pFunctor = pFunctor;
}
struct Elem_t
{
Elem_t *pNext;
CFunctor *pFunctor;
};
Elem_t *m_pHead;
Elem_t *m_pTail;
CMemoryStack m_Allocator;
CCustomizedFunctorFactory<CMemoryStack, CRefCounted1<CFunctor, CRefCountServiceDestruct< CRefST > > > m_FunctorFactory;
unsigned m_nCurSerialNumber;
unsigned m_nBreakSerialNumber;
};
#define MATCONFIG_FLAGS_SUPPORT_EDITOR ( 1 << 0 )
#define MATCONFIG_FLAGS_SUPPORT_GBUFFER ( 1 << 1 )
//-----------------------------------------------------------------------------
// Additional interfaces used internally to the library
//-----------------------------------------------------------------------------
abstract_class IMaterialSystemInternal : public IMaterialSystem
{
public:
// Returns the current material
virtual IMaterial* GetCurrentMaterial() = 0;
virtual int GetLightmapPage( void ) = 0;
// Gets the maximum lightmap page size...
virtual int GetLightmapWidth( int lightmap ) const = 0;
virtual int GetLightmapHeight( int lightmap ) const = 0;
virtual ITexture *GetLocalCubemap( void ) = 0;
// virtual bool RenderZOnlyWithHeightClipEnabled( void ) = 0;
virtual void ForceDepthFuncEquals( bool bEnable ) = 0;
virtual enum MaterialHeightClipMode_t GetHeightClipMode( void ) = 0;
// FIXME: Remove? Here for debugging shaders in CShaderSystem
virtual void AddMaterialToMaterialList( IMaterialInternal *pMaterial ) = 0;
virtual void RemoveMaterial( IMaterialInternal *pMaterial ) = 0;
virtual void RemoveMaterialSubRect( IMaterialInternal *pMaterial ) = 0;
virtual bool InFlashlightMode() const = 0;
// Can we use editor materials?
virtual bool CanUseEditorMaterials() const = 0;
virtual int GetConfigurationFlags( void ) const = 0;
virtual const char *GetForcedTextureLoadPathID() = 0;
virtual CMatCallQueue *GetRenderCallQueue() = 0;
virtual void UnbindMaterial( IMaterial *pMaterial ) = 0;
virtual uint GetRenderThreadId() const = 0 ;
};
#endif // IMATERIALSYSTEMINTERNAL_H

View File

@ -0,0 +1,21 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=====================================================================================//
#include "materialsystem_global.h"
#include "shaderapi/ishaderapi.h"
#include "shadersystem.h"
#include <malloc.h>
#include "filesystem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
int g_FrameNum;
IShaderAPI *g_pShaderAPI = 0;
IShaderDeviceMgr* g_pShaderDeviceMgr = 0;
IShaderDevice *g_pShaderDevice = 0;
IShaderShadow* g_pShaderShadow = 0;
IClientMaterialSystem *g_pClientMaterialSystem = 0;

View File

@ -0,0 +1,112 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Header: $
// $NoKeywords: $
//
//=============================================================================//
#ifndef MATERIALSYSTEM_GLOBAL_H
#define MATERIALSYSTEM_GLOBAL_H
#ifdef _WIN32
#pragma once
#endif
#include "imaterialsysteminternal.h"
#include "tier0/dbg.h"
#include "tier2/tier2.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class ITextureInternal;
class IShaderAPI;
class IHardwareConfigInternal;
class IShaderUtil;
class IShaderShadow;
class IShaderDeviceMgr;
class IShaderDevice;
class IShaderSystemInternal;
class IMaterialInternal;
class IColorCorrectionSystem;
class IMaterialVar;
class IClientMaterialSystem;
//-----------------------------------------------------------------------------
// Constants used by the system
//-----------------------------------------------------------------------------
#define MATERIAL_MAX_PATH 256
// GR - limits for blured image (HDR stuff)
#define MAX_BLUR_IMAGE_WIDTH 256
#define MAX_BLUR_IMAGE_HEIGHT 192
#define CLAMP_BLUR_IMAGE_WIDTH( _w ) ( ( _w < MAX_BLUR_IMAGE_WIDTH ) ? _w : MAX_BLUR_IMAGE_WIDTH )
#define CLAMP_BLUR_IMAGE_HEIGHT( _h ) ( ( _h < MAX_BLUR_IMAGE_HEIGHT ) ? _h : MAX_BLUR_IMAGE_HEIGHT )
//-----------------------------------------------------------------------------
// Global structures
//-----------------------------------------------------------------------------
extern MaterialSystem_Config_t g_config;
extern uint32 g_nDebugVarsSignature;
//extern MaterialSystem_ErrorFunc_t Error;
//extern MaterialSystem_WarningFunc_t Warning;
extern int g_FrameNum;
extern IShaderAPI* g_pShaderAPI;
extern IShaderDeviceMgr* g_pShaderDeviceMgr;
extern IShaderDevice* g_pShaderDevice;
extern IShaderShadow* g_pShaderShadow;
extern IClientMaterialSystem *g_pClientMaterialSystem;
extern IMaterialInternal *g_pErrorMaterial;
IShaderSystemInternal* ShaderSystem();
inline IShaderSystemInternal* ShaderSystem()
{
extern IShaderSystemInternal *g_pShaderSystem;
return g_pShaderSystem;
}
inline IHardwareConfigInternal *HardwareConfig()
{
extern IHardwareConfigInternal* g_pHWConfig;
return g_pHWConfig;
}
//-----------------------------------------------------------------------------
// Accessor to get at the material system
//-----------------------------------------------------------------------------
inline IMaterialSystemInternal* MaterialSystem()
{
extern IMaterialSystemInternal *g_pInternalMaterialSystem;
return g_pInternalMaterialSystem;
}
inline IShaderUtil* ShaderUtil()
{
extern IShaderUtil *g_pShaderUtil;
return g_pShaderUtil;
}
extern IColorCorrectionSystem *g_pColorCorrectionSystem;
inline IColorCorrectionSystem *ColorCorrectionSystem()
{
return g_pColorCorrectionSystem;
}
//-----------------------------------------------------------------------------
// Global methods related to material vars
//-----------------------------------------------------------------------------
void EnableThreadedMaterialVarAccess( bool bEnable, IMaterialVar **ppParams, int nVarCount );
#endif // MATERIALSYSTEM_GLOBAL_H

View File

@ -0,0 +1,191 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef LOCALD3DTYPES_H
#define LOCALD3DTYPES_H
#ifdef _WIN32
#pragma once
#endif
#if defined( DX10 ) && !defined( POSIX )
#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( POSIX )
#if !defined( _X360 ) && !defined( POSIX )
#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 "dxabstract.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

View File

@ -0,0 +1,985 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
//===========================================================================//
#include "shaderlib/BaseShader.h"
#include "shaderlib/ShaderDLL.h"
#include "tier0/dbg.h"
#include "shaderDLL_Global.h"
#include "../IShaderSystem.h"
#include "materialsystem/imaterial.h"
#include "materialsystem/itexture.h"
#include "materialsystem/ishaderapi.h"
#include "materialsystem/materialsystem_config.h"
#include "shaderlib/cshader.h"
#include "shaderlib/commandbuilder.h"
#include "renderparm.h"
#include "mathlib/vmatrix.h"
#include "tier1/strtools.h"
#include "convar.h"
#include "tier0/vprof.h"
// NOTE: This must be the last include file in a .cpp file!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Storage buffer used for instance command buffers
//-----------------------------------------------------------------------------
class CPerInstanceContextData : public CBasePerInstanceContextData
{
public:
CPerInstanceContextData() : m_pCommandBuffer( NULL ), m_nSize( 0 ) {}
virtual ~CPerInstanceContextData()
{
if ( m_pCommandBuffer )
{
delete m_pCommandBuffer;
}
}
unsigned char *m_pCommandBuffer;
int m_nSize;
};
//-----------------------------------------------------------------------------
// Globals
//-----------------------------------------------------------------------------
const char *CBaseShader::s_pTextureGroupName = NULL;
IMaterialVar **CBaseShader::s_ppParams;
IShaderShadow *CBaseShader::s_pShaderShadow;
IShaderDynamicAPI *CBaseShader::s_pShaderAPI;
IShaderInit *CBaseShader::s_pShaderInit;
int CBaseShader::s_nModulationFlags;
int CBaseShader::s_nPassCount = 0;
CPerInstanceContextData** CBaseShader::s_pInstanceDataPtr = NULL;
static bool s_bBuildingInstanceCommandBuffer = false;
static CInstanceCommandBufferBuilder< CFixedCommandStorageBuffer< 512 > > s_InstanceCommandBuffer;
bool g_shaderConfigDumpEnable = false; //true; //DO NOT CHECK IN ENABLED FIXME
static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT );
//-----------------------------------------------------------------------------
// constructor
//-----------------------------------------------------------------------------
CBaseShader::CBaseShader()
{
GetShaderDLL()->InsertShader( this );
}
//-----------------------------------------------------------------------------
// Shader parameter info
//-----------------------------------------------------------------------------
// Look in BaseShader.h for the enumeration for these.
// Update there if you update here.
static ShaderParamInfo_t s_StandardParams[NUM_SHADER_MATERIAL_VARS] =
{
{ "$flags", "flags", SHADER_PARAM_TYPE_INTEGER, "0", SHADER_PARAM_NOT_EDITABLE },
{ "$flags_defined", "flags_defined", SHADER_PARAM_TYPE_INTEGER, "0", SHADER_PARAM_NOT_EDITABLE },
{ "$flags2", "flags2", SHADER_PARAM_TYPE_INTEGER, "0", SHADER_PARAM_NOT_EDITABLE },
{ "$flags_defined2", "flags2_defined", SHADER_PARAM_TYPE_INTEGER, "0", SHADER_PARAM_NOT_EDITABLE },
{ "$color", "color", SHADER_PARAM_TYPE_COLOR, "[1 1 1]", 0 },
{ "$alpha", "alpha", SHADER_PARAM_TYPE_FLOAT, "1.0", 0 },
{ "$basetexture", "Base Texture with lighting built in", SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", 0 },
{ "$frame", "Animation Frame", SHADER_PARAM_TYPE_INTEGER, "0", 0 },
{ "$basetexturetransform", "Base Texture Texcoord Transform",SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", 0 },
{ "$flashlighttexture", "flashlight spotlight shape texture", SHADER_PARAM_TYPE_TEXTURE, "effects/flashlight001", SHADER_PARAM_NOT_EDITABLE },
{ "$flashlighttextureframe", "Animation Frame for $flashlight", SHADER_PARAM_TYPE_INTEGER, "0", SHADER_PARAM_NOT_EDITABLE },
{ "$color2", "color2", SHADER_PARAM_TYPE_COLOR, "[1 1 1]", 0 },
{ "$srgbtint", "tint value to be applied when running on new-style srgb parts", SHADER_PARAM_TYPE_COLOR, "[1 1 1]", 0 },
};
//-----------------------------------------------------------------------------
// Gets the standard shader parameter names
// FIXME: Turn this into one function?
//-----------------------------------------------------------------------------
int CBaseShader::GetParamCount( ) const
{
return NUM_SHADER_MATERIAL_VARS;
}
const ShaderParamInfo_t &CBaseShader::GetParamInfo( int nParamIndex ) const
{
Assert( nParamIndex < NUM_SHADER_MATERIAL_VARS );
return s_StandardParams[nParamIndex];
}
//-----------------------------------------------------------------------------
// Necessary to snag ahold of some important data for the helper methods
//-----------------------------------------------------------------------------
void CBaseShader::InitShaderParams( IMaterialVar** ppParams, const char *pMaterialName )
{
// Re-entrancy check
Assert( !s_ppParams );
s_ppParams = ppParams;
OnInitShaderParams( ppParams, pMaterialName );
s_ppParams = NULL;
}
void CBaseShader::InitShaderInstance( IMaterialVar** ppParams, IShaderInit *pShaderInit, const char *pMaterialName, const char *pTextureGroupName )
{
// Re-entrancy check
Assert( !s_ppParams );
s_ppParams = ppParams;
s_pShaderInit = pShaderInit;
s_pTextureGroupName = pTextureGroupName;
OnInitShaderInstance( ppParams, pShaderInit, pMaterialName );
s_pTextureGroupName = NULL;
s_ppParams = NULL;
s_pShaderInit = NULL;
}
void CBaseShader::DrawElements( IMaterialVar **ppParams, int nModulationFlags,
IShaderShadow* pShaderShadow, IShaderDynamicAPI* pShaderAPI, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr, CBasePerInstanceContextData** pInstanceDataPtr )
{
VPROF("CBaseShader::DrawElements");
// Re-entrancy check
Assert( !s_ppParams );
s_ppParams = ppParams;
s_pShaderAPI = pShaderAPI;
s_pShaderShadow = pShaderShadow;
s_nModulationFlags = nModulationFlags;
s_pInstanceDataPtr = (CPerInstanceContextData**)( pInstanceDataPtr );
s_nPassCount = 0;
if ( IsSnapshotting() )
{
// Set up the shadow state
SetInitialShadowState( );
}
OnDrawElements( ppParams, pShaderShadow, pShaderAPI, vertexCompression, pContextDataPtr );
s_pInstanceDataPtr = NULL;
s_nPassCount = 0;
s_nModulationFlags = 0;
s_ppParams = NULL;
s_pShaderAPI = NULL;
s_pShaderShadow = NULL;
}
//-----------------------------------------------------------------------------
// Sets the default shadow state
//-----------------------------------------------------------------------------
void CBaseShader::SetInitialShadowState( )
{
// Set the default state
s_pShaderShadow->SetDefaultState();
// Init the standard states...
int flags = s_ppParams[FLAGS]->GetIntValue();
if (flags & MATERIAL_VAR_IGNOREZ)
{
s_pShaderShadow->EnableDepthTest( false );
s_pShaderShadow->EnableDepthWrites( false );
}
if (flags & MATERIAL_VAR_DECAL)
{
s_pShaderShadow->EnablePolyOffset( SHADER_POLYOFFSET_DECAL );
s_pShaderShadow->EnableDepthWrites( false );
}
if (flags & MATERIAL_VAR_NOCULL)
{
s_pShaderShadow->EnableCulling( false );
}
if (flags & MATERIAL_VAR_ZNEARER)
{
s_pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_NEARER );
}
if (flags & MATERIAL_VAR_WIREFRAME)
{
s_pShaderShadow->PolyMode( SHADER_POLYMODEFACE_FRONT_AND_BACK, SHADER_POLYMODE_LINE );
}
// Set alpha to coverage
if (flags & MATERIAL_VAR_ALLOWALPHATOCOVERAGE)
{
// Force the bit on and then check against alpha blend and test states in CShaderShadowDX8::ComputeAggregateShadowState()
s_pShaderShadow->EnableAlphaToCoverage( true );
}
}
//-----------------------------------------------------------------------------
// Draws a snapshot
//-----------------------------------------------------------------------------
void CBaseShader::Draw( bool bMakeActualDrawCall )
{
// You forgot to call PI_EndCommandBuffer
Assert( !s_bBuildingInstanceCommandBuffer );
if ( IsSnapshotting() )
{
// Turn off transparency if we're asked to....
if (g_pConfig->bNoTransparency &&
((s_ppParams[FLAGS]->GetIntValue() & MATERIAL_VAR_NO_DEBUG_OVERRIDE) == 0))
{
s_pShaderShadow->EnableDepthWrites( true );
s_pShaderShadow->EnableBlending( false );
}
GetShaderSystem()->TakeSnapshot();
// Automagically add skinning + vertex lighting
if ( !s_pInstanceDataPtr[s_nPassCount] )
{
bool bIsSkinning = CShader_IsFlag2Set( s_ppParams, MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
bool bIsVertexLit = CShader_IsFlag2Set( s_ppParams, MATERIAL_VAR2_LIGHTING_VERTEX_LIT );
if ( bIsSkinning || bIsVertexLit )
{
PI_BeginCommandBuffer();
// NOTE: EndCommandBuffer will insert the appropriate commands
PI_EndCommandBuffer();
}
}
}
else
{
GetShaderSystem()->DrawSnapshot( s_pInstanceDataPtr[s_nPassCount] ?
s_pInstanceDataPtr[s_nPassCount]->m_pCommandBuffer : NULL, bMakeActualDrawCall );
}
++s_nPassCount;
}
//-----------------------------------------------------------------------------
// Methods related to building per-instance command buffers
//-----------------------------------------------------------------------------
void CBaseShader::PI_BeginCommandBuffer()
{
// NOTE: This assertion is here because the memory allocation strategy
// is perhaps not the best if this is used in dynamic states; we should
// rethink in that case.
Assert( IsSnapshotting() );
Assert( !s_bBuildingInstanceCommandBuffer );
s_bBuildingInstanceCommandBuffer = true;
s_InstanceCommandBuffer.Reset();
}
void CBaseShader::PI_EndCommandBuffer()
{
Assert( s_bBuildingInstanceCommandBuffer );
// Automagically add skinning
if ( CShader_IsFlag2Set( s_ppParams, MATERIAL_VAR2_SUPPORTS_HW_SKINNING ) )
{
PI_SetSkinningMatrices();
}
if ( CShader_IsFlag2Set( s_ppParams, MATERIAL_VAR2_LIGHTING_VERTEX_LIT ) )
{
PI_SetVertexShaderLocalLighting();
}
s_bBuildingInstanceCommandBuffer = false;
s_InstanceCommandBuffer.End();
int nSize = s_InstanceCommandBuffer.Size();
if ( nSize > 0 )
{
CPerInstanceContextData *pContextData = s_pInstanceDataPtr[ s_nPassCount ];
if ( !pContextData )
{
pContextData = new CPerInstanceContextData;
s_pInstanceDataPtr[ s_nPassCount ] = pContextData;
}
unsigned char *pBuf = pContextData->m_pCommandBuffer;
if ( pContextData->m_nSize < nSize )
{
if ( pContextData->m_pCommandBuffer )
{
delete pContextData->m_pCommandBuffer;
}
pBuf = new unsigned char[nSize];
pContextData->m_pCommandBuffer = pBuf;
pContextData->m_nSize = nSize;
}
memcpy( pBuf, s_InstanceCommandBuffer.Base(), nSize );
}
}
//-----------------------------------------------------------------------------
// Queues commands onto the instance command buffer
//-----------------------------------------------------------------------------
void CBaseShader::PI_SetPixelShaderAmbientLightCube( int nFirstRegister )
{
Assert( s_bBuildingInstanceCommandBuffer );
s_InstanceCommandBuffer.SetPixelShaderAmbientLightCube( nFirstRegister );
}
void CBaseShader::PI_SetPixelShaderLocalLighting( int nFirstRegister )
{
Assert( s_bBuildingInstanceCommandBuffer );
s_InstanceCommandBuffer.SetPixelShaderLocalLighting( nFirstRegister );
}
void CBaseShader::PI_SetVertexShaderAmbientLightCube( /*int nFirstRegister*/ )
{
Assert( s_bBuildingInstanceCommandBuffer );
s_InstanceCommandBuffer.SetVertexShaderAmbientLightCube( /*nFirstRegister*/ );
}
void CBaseShader::PI_SetVertexShaderLocalLighting()
{
Assert( s_bBuildingInstanceCommandBuffer );
s_InstanceCommandBuffer.SetVertexShaderLocalLighting( );
}
void CBaseShader::PI_SetSkinningMatrices()
{
Assert( s_bBuildingInstanceCommandBuffer );
s_InstanceCommandBuffer.SetSkinningMatrices();
}
void CBaseShader::PI_SetPixelShaderAmbientLightCubeLuminance( int nFirstRegister )
{
Assert( s_bBuildingInstanceCommandBuffer );
s_InstanceCommandBuffer.SetPixelShaderAmbientLightCubeLuminance( nFirstRegister );
}
void CBaseShader::PI_SetPixelShaderGlintDamping( int nFirstRegister )
{
Assert( s_bBuildingInstanceCommandBuffer );
s_InstanceCommandBuffer.SetPixelShaderGlintDamping( nFirstRegister );
}
void CBaseShader::PI_SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( int nRegister, float scale )
{
Assert( s_bBuildingInstanceCommandBuffer );
Vector color2( 1.0f, 1.0f, 1.0f );
ApplyColor2Factor( color2.Base() );
s_InstanceCommandBuffer.SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( nRegister, color2, scale );
}
void CBaseShader::PI_SetModulationPixelShaderDynamicState_LinearScale( int nRegister, float scale )
{
Assert( s_bBuildingInstanceCommandBuffer );
Vector color2( 1.0f, 1.0f, 1.0f );
ApplyColor2Factor( color2.Base() );
s_InstanceCommandBuffer.SetModulationPixelShaderDynamicState_LinearScale( nRegister, color2, scale );
}
void CBaseShader::PI_SetModulationPixelShaderDynamicState_LinearScale_ScaleInW( int nRegister, float scale )
{
Assert( s_bBuildingInstanceCommandBuffer );
Vector color2( 1.0f, 1.0f, 1.0f );
ApplyColor2Factor( color2.Base() );
s_InstanceCommandBuffer.SetModulationPixelShaderDynamicState_LinearScale_ScaleInW( nRegister, color2, scale );
}
void CBaseShader::PI_SetModulationPixelShaderDynamicState_LinearColorSpace( int nRegister )
{
Assert( s_bBuildingInstanceCommandBuffer );
Vector color2( 1.0f, 1.0f, 1.0f );
ApplyColor2Factor( color2.Base() );
s_InstanceCommandBuffer.SetModulationPixelShaderDynamicState_LinearColorSpace( nRegister, color2 );
}
void CBaseShader::PI_SetModulationPixelShaderDynamicState( int nRegister )
{
Assert( s_bBuildingInstanceCommandBuffer );
Vector color2( 1.0f, 1.0f, 1.0f );
ApplyColor2Factor( color2.Base() );
s_InstanceCommandBuffer.SetModulationPixelShaderDynamicState( nRegister, color2 );
}
void CBaseShader::PI_SetModulationVertexShaderDynamicState()
{
Assert( s_bBuildingInstanceCommandBuffer );
Vector color2( 1.0f, 1.0f, 1.0f );
ApplyColor2Factor( color2.Base() );
s_InstanceCommandBuffer.SetModulationVertexShaderDynamicState( VERTEX_SHADER_MODULATION_COLOR, color2 );
}
void CBaseShader::PI_SetModulationVertexShaderDynamicState_LinearScale( float flScale )
{
Assert( s_bBuildingInstanceCommandBuffer );
Vector color2( 1.0f, 1.0f, 1.0f );
ApplyColor2Factor( color2.Base() );
s_InstanceCommandBuffer.SetModulationVertexShaderDynamicState_LinearScale( VERTEX_SHADER_MODULATION_COLOR, color2, flScale );
}
void CBaseShader::PI_SetModulationPixelShaderDynamicState_Identity( int nRegister )
{
Assert( s_bBuildingInstanceCommandBuffer );
s_InstanceCommandBuffer.SetModulationPixelShaderDynamicState_Identity( nRegister );
}
//-----------------------------------------------------------------------------
// Finds a particular parameter (works because the lowest parameters match the shader)
//-----------------------------------------------------------------------------
int CBaseShader::FindParamIndex( const char *pName ) const
{
int numParams = GetParamCount();
for( int i = 0; i < numParams; i++ )
{
if( Q_strnicmp( GetParamInfo( i ).m_pName, pName, 64 ) == 0 )
{
return i;
}
}
return -1;
}
//-----------------------------------------------------------------------------
// Are we using graphics?
//-----------------------------------------------------------------------------
bool CBaseShader::IsUsingGraphics()
{
return GetShaderSystem()->IsUsingGraphics();
}
//-----------------------------------------------------------------------------
// Are we using graphics?
//-----------------------------------------------------------------------------
bool CBaseShader::CanUseEditorMaterials() const
{
return GetShaderSystem()->CanUseEditorMaterials();
}
//-----------------------------------------------------------------------------
// Loads a texture
//-----------------------------------------------------------------------------
void CBaseShader::LoadTexture( int nTextureVar )
{
if ((!s_ppParams) || (nTextureVar == -1))
return;
IMaterialVar* pNameVar = s_ppParams[nTextureVar];
if( pNameVar && pNameVar->IsDefined() )
{
s_pShaderInit->LoadTexture( pNameVar, s_pTextureGroupName );
}
}
//-----------------------------------------------------------------------------
// Loads a bumpmap
//-----------------------------------------------------------------------------
void CBaseShader::LoadBumpMap( int nTextureVar )
{
if ((!s_ppParams) || (nTextureVar == -1))
return;
IMaterialVar* pNameVar = s_ppParams[nTextureVar];
if( pNameVar && pNameVar->IsDefined() )
{
s_pShaderInit->LoadBumpMap( pNameVar, s_pTextureGroupName );
}
}
//-----------------------------------------------------------------------------
// Loads a cubemap
//-----------------------------------------------------------------------------
void CBaseShader::LoadCubeMap( int nTextureVar )
{
if ((!s_ppParams) || (nTextureVar == -1))
return;
IMaterialVar* pNameVar = s_ppParams[nTextureVar];
if( pNameVar && pNameVar->IsDefined() )
{
s_pShaderInit->LoadCubeMap( s_ppParams, pNameVar );
}
}
ShaderAPITextureHandle_t CBaseShader::GetShaderAPITextureBindHandle( int nTextureVar, int nFrameVar, int nTextureChannel )
{
Assert( !IsSnapshotting() );
Assert( nTextureVar != -1 );
Assert ( s_ppParams );
IMaterialVar* pTextureVar = s_ppParams[nTextureVar];
IMaterialVar* pFrameVar = (nFrameVar != -1) ? s_ppParams[nFrameVar] : NULL;
int nFrame = pFrameVar ? pFrameVar->GetIntValue() : 0;
return GetShaderSystem()->GetShaderAPITextureBindHandle( pTextureVar->GetTextureValue(), nFrame, nTextureChannel );
}
void CBaseShader::BindVertexTexture( VertexTextureSampler_t vtSampler, int nTextureVar, int nFrame /* = 0 */)
{
Assert( !IsSnapshotting() );
IMaterialVar* pTextureVar = s_ppParams[nTextureVar];
if ( !pTextureVar )
return;
GetShaderSystem()->BindVertexTexture( vtSampler, pTextureVar->GetTextureValue() );
}
ShaderAPITextureHandle_t CBaseShader::GetShaderAPITextureBindHandle( ITexture *pTexture, int nFrame, int nTextureChannel )
{
return GetShaderSystem()->GetShaderAPITextureBindHandle( pTexture, nFrame, nTextureChannel );
}
//-----------------------------------------------------------------------------
// Four different flavors of BindTexture(), handling the two-sampler
// case as well as ITexture* versus textureVar forms
//-----------------------------------------------------------------------------
void CBaseShader::BindTexture( Sampler_t sampler1, int nTextureVar, int nFrameVar /* = -1 */ )
{
BindTexture( sampler1, (Sampler_t) -1, nTextureVar, nFrameVar );
}
void CBaseShader::BindTexture( Sampler_t sampler1, Sampler_t sampler2, int nTextureVar, int nFrameVar /* = -1 */ )
{
Assert( !IsSnapshotting() );
Assert( nTextureVar != -1 );
Assert ( s_ppParams );
IMaterialVar* pTextureVar = s_ppParams[nTextureVar];
IMaterialVar* pFrameVar = (nFrameVar != -1) ? s_ppParams[nFrameVar] : NULL;
if (pTextureVar)
{
int nFrame = pFrameVar ? pFrameVar->GetIntValue() : 0;
if ( sampler2 == -1 )
{
GetShaderSystem()->BindTexture( sampler1, pTextureVar->GetTextureValue(), nFrame );
}
else
{
GetShaderSystem()->BindTexture( sampler1, sampler2, pTextureVar->GetTextureValue(), nFrame );
}
}
}
void CBaseShader::BindTexture( Sampler_t sampler1, ITexture *pTexture, int nFrame /* = 0 */ )
{
BindTexture( sampler1, (Sampler_t) -1, pTexture, nFrame );
}
void CBaseShader::BindTexture( Sampler_t sampler1, Sampler_t sampler2, ITexture *pTexture, int nFrame /* = 0 */ )
{
Assert( !IsSnapshotting() );
if ( sampler2 == -1 )
{
GetShaderSystem()->BindTexture( sampler1, pTexture, nFrame );
}
else
{
GetShaderSystem()->BindTexture( sampler1, sampler2, pTexture, nFrame );
}
}
//-----------------------------------------------------------------------------
// Does the texture store translucency in its alpha channel?
//-----------------------------------------------------------------------------
bool CBaseShader::TextureIsTranslucent( int textureVar, bool isBaseTexture )
{
if (textureVar < 0)
return false;
IMaterialVar** params = s_ppParams;
if (params[textureVar]->GetType() == MATERIAL_VAR_TYPE_TEXTURE)
{
if (!isBaseTexture)
{
return params[textureVar]->GetTextureValue()->IsTranslucent();
}
else
{
// Override translucency settings if this flag is set.
if (IS_FLAG_SET(MATERIAL_VAR_OPAQUETEXTURE))
return false;
bool bHasSelfIllum = ( ( CurrentMaterialVarFlags() & MATERIAL_VAR_SELFILLUM ) != 0 );
bool bHasSelfIllumMask = ( ( CurrentMaterialVarFlags2() & MATERIAL_VAR2_SELFILLUMMASK ) != 0 );
bool bHasBaseAlphaEnvmapMask = ( ( CurrentMaterialVarFlags() & MATERIAL_VAR_BASEALPHAENVMAPMASK ) != 0 );
bool bUsingBaseTextureAlphaForSelfIllum = bHasSelfIllum && !bHasSelfIllumMask;
// Check if we are using base texture alpha for something other than translucency.
if ( !bUsingBaseTextureAlphaForSelfIllum && !bHasBaseAlphaEnvmapMask )
{
// We aren't using base alpha for anything other than trancluceny.
// check if the material is marked as translucent or alpha test.
if ((CurrentMaterialVarFlags() & MATERIAL_VAR_TRANSLUCENT) ||
(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST))
{
// Make sure the texture has an alpha channel.
return params[textureVar]->GetTextureValue()->IsTranslucent();
}
}
}
}
return false;
}
//-----------------------------------------------------------------------------
//
// Helper methods for color modulation
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Are we alpha or color modulating?
//-----------------------------------------------------------------------------
bool CBaseShader::IsAlphaModulating()
{
return (s_nModulationFlags & SHADER_USING_ALPHA_MODULATION) != 0;
}
// FIXME: Figure out a better way to do this?
//-----------------------------------------------------------------------------
int CBaseShader::ComputeModulationFlags( IMaterialVar** params, IShaderDynamicAPI* pShaderAPI )
{
s_pShaderAPI = pShaderAPI;
int mod = 0;
if( UsingFlashlight(params) )
{
mod |= SHADER_USING_FLASHLIGHT;
}
if ( UsingEditor(params) )
{
mod |= SHADER_USING_EDITOR;
}
if( IS_FLAG2_SET( MATERIAL_VAR2_USE_FIXED_FUNCTION_BAKED_LIGHTING ) )
{
AssertOnce( IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_BAKED_LIGHTING_SNAPSHOTS ) );
if( IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_BAKED_LIGHTING_SNAPSHOTS ) )
{
mod |= SHADER_USING_FIXED_FUNCTION_BAKED_LIGHTING;
}
}
if ( IsSnapshotting() )
{
if ( IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER0 ) )
mod |= SHADER_USING_GBUFFER0;
if ( IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER1 ) )
mod |= SHADER_USING_GBUFFER1;
}
else
{
int nFixedLightingMode = pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING );
if ( nFixedLightingMode & 1 )
mod |= SHADER_USING_GBUFFER0;
if ( nFixedLightingMode & 2 )
mod |= SHADER_USING_GBUFFER1;
}
s_pShaderAPI = NULL;
return mod;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
bool CBaseShader::NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const
{
return CShader_IsFlag2Set( params, MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
bool CBaseShader::NeedsFullFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const
{
return CShader_IsFlag2Set( params, MATERIAL_VAR2_NEEDS_FULL_FRAME_BUFFER_TEXTURE );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
bool CBaseShader::IsTranslucent( IMaterialVar **params ) const
{
return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT );
}
//-----------------------------------------------------------------------------
// Returns the translucency...
//-----------------------------------------------------------------------------
void CBaseShader::ApplyColor2Factor( float *pColorOut ) const // (*pColorOut) *= COLOR2
{
if ( !g_pConfig->bShowDiffuse )
{
pColorOut[0] = pColorOut[1] = pColorOut[2] = 0.0f;
return;
}
IMaterialVar* pColor2Var = s_ppParams[COLOR2];
if ( pColor2Var->GetType() == MATERIAL_VAR_TYPE_VECTOR )
{
float flColor2[3];
pColor2Var->GetVecValue( flColor2, 3 );
pColorOut[0] *= flColor2[0];
pColorOut[1] *= flColor2[1];
pColorOut[2] *= flColor2[2];
}
if ( g_pHardwareConfig->UsesSRGBCorrectBlending() )
{
IMaterialVar* pSRGBVar = s_ppParams[SRGBTINT];
if (pSRGBVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
{
float flSRGB[3];
pSRGBVar->GetVecValue( flSRGB, 3 );
pColorOut[0] *= flSRGB[0];
pColorOut[1] *= flSRGB[1];
pColorOut[2] *= flSRGB[2];
}
}
}
//-----------------------------------------------------------------------------
//
// Helper methods for alpha blending....
//
//-----------------------------------------------------------------------------
void CBaseShader::EnableAlphaBlending( ShaderBlendFactor_t src, ShaderBlendFactor_t dst )
{
Assert( IsSnapshotting() );
s_pShaderShadow->EnableBlending( true );
s_pShaderShadow->BlendFunc( src, dst );
s_pShaderShadow->EnableDepthWrites(false);
}
void CBaseShader::DisableAlphaBlending()
{
Assert( IsSnapshotting() );
s_pShaderShadow->EnableBlending( false );
}
void CBaseShader::SetNormalBlendingShadowState( int textureVar, bool isBaseTexture )
{
Assert( IsSnapshotting() );
// 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
isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) &&
!(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) );
if (isTranslucent)
{
EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
}
else
{
DisableAlphaBlending();
}
}
//ConVar mat_debug_flashlight_only( "mat_debug_flashlight_only", "0" );
void CBaseShader::SetAdditiveBlendingShadowState( int textureVar, bool isBaseTexture )
{
Assert( IsSnapshotting() );
// 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
isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) &&
!(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) );
/*
if ( mat_debug_flashlight_only.GetBool() )
{
if (isTranslucent)
{
EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA);
//s_pShaderShadow->EnableAlphaTest( true );
//s_pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.99f );
}
else
{
EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ZERO);
}
}
else
*/
{
if (isTranslucent)
{
EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE );
}
else
{
EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE );
}
}
}
void CBaseShader::SetDefaultBlendingShadowState( int textureVar, bool isBaseTexture )
{
if ( CurrentMaterialVarFlags() & MATERIAL_VAR_ADDITIVE )
{
SetAdditiveBlendingShadowState( textureVar, isBaseTexture );
}
else
{
SetNormalBlendingShadowState( textureVar, isBaseTexture );
}
}
void CBaseShader::SetBlendingShadowState( BlendType_t nMode )
{
switch ( nMode )
{
case BT_NONE:
DisableAlphaBlending();
break;
case BT_BLEND:
EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
break;
case BT_ADD:
EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE );
break;
case BT_BLENDADD:
EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE );
break;
}
}
//-----------------------------------------------------------------------------
// Sets lightmap blending mode for single texturing
//-----------------------------------------------------------------------------
void CBaseShader::SingleTextureLightmapBlendMode( )
{
Assert( IsSnapshotting() );
s_pShaderShadow->EnableBlending( true );
s_pShaderShadow->BlendFunc( SHADER_BLEND_DST_COLOR, SHADER_BLEND_SRC_COLOR );
}
FORCEINLINE void CBaseShader::SetFogMode( ShaderFogMode_t fogMode )
{
if (( CurrentMaterialVarFlags() & MATERIAL_VAR_NOFOG ) == 0)
{
bool bVertexFog = ( ( CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXFOG ) != 0 );
s_pShaderShadow->FogMode( fogMode, bVertexFog );
}
else
{
s_pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED, false );
}
}
//-----------------------------------------------------------------------------
//
// Helper methods for fog
//
//-----------------------------------------------------------------------------
void CBaseShader::FogToOOOverbright( void )
{
Assert( IsSnapshotting() );
SetFogMode( SHADER_FOGMODE_OO_OVERBRIGHT );
}
void CBaseShader::FogToWhite( void )
{
Assert( IsSnapshotting() );
SetFogMode( SHADER_FOGMODE_WHITE );
}
void CBaseShader::FogToBlack( void )
{
Assert( IsSnapshotting() );
SetFogMode( SHADER_FOGMODE_BLACK );
}
void CBaseShader::FogToGrey( void )
{
Assert( IsSnapshotting() );
SetFogMode( SHADER_FOGMODE_GREY );
}
void CBaseShader::FogToFogColor( void )
{
Assert( IsSnapshotting() );
SetFogMode( SHADER_FOGMODE_FOGCOLOR );
}
void CBaseShader::DisableFog( void )
{
Assert( IsSnapshotting() );
s_pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED, false );
}
void CBaseShader::DefaultFog( void )
{
if ( CurrentMaterialVarFlags() & MATERIAL_VAR_ADDITIVE )
{
FogToBlack();
}
else
{
FogToFogColor();
}
}
bool CBaseShader::UsingFlashlight( IMaterialVar **params ) const
{
if( IsSnapshotting() )
{
return CShader_IsFlag2Set( params, MATERIAL_VAR2_USE_FLASHLIGHT );
}
else
{
return s_pShaderAPI->InFlashlightMode();
}
}
bool CBaseShader::UsingEditor( IMaterialVar **params ) const
{
if( IsSnapshotting() )
{
return CShader_IsFlag2Set( params, MATERIAL_VAR2_USE_EDITOR );
}
else
{
return s_pShaderAPI->InEditorMode();
}
}
bool CBaseShader::IsHDREnabled( void )
{
// HDRFIXME! Need to fix this for vgui materials
HDRType_t hdr_mode = g_pHardwareConfig->GetHDRType();
return ( hdr_mode == HDR_TYPE_INTEGER ) || ( hdr_mode == HDR_TYPE_FLOAT );
}

View File

@ -0,0 +1,169 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
//===========================================================================//
#include "shaderlib/ShaderDLL.h"
#include "materialsystem/IShader.h"
#include "tier1/utlvector.h"
#include "tier0/dbg.h"
#include "materialsystem/imaterialsystemhardwareconfig.h"
#include "materialsystem/materialsystem_config.h"
#include "IShaderSystem.h"
#include "materialsystem/ishaderapi.h"
#include "shaderlib_cvar.h"
#include "mathlib/mathlib.h"
#include "tier2/tier2.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// The standard implementation of CShaderDLL
//-----------------------------------------------------------------------------
class CShaderDLL : public IShaderDLLInternal, public IShaderDLL
{
public:
CShaderDLL();
// methods of IShaderDLL
virtual bool Connect( CreateInterfaceFn factory );
virtual void Disconnect();
virtual int ShaderCount() const;
virtual IShader *GetShader( int nShader );
// methods of IShaderDLLInternal
virtual bool Connect( CreateInterfaceFn factory, bool bIsMaterialSystem );
virtual void Disconnect( bool bIsMaterialSystem );
virtual void InsertShader( IShader *pShader );
private:
CUtlVector< IShader * > m_ShaderList;
};
//-----------------------------------------------------------------------------
// Global interfaces/structures
//-----------------------------------------------------------------------------
IMaterialSystemHardwareConfig* g_pHardwareConfig;
const MaterialSystem_Config_t *g_pConfig;
//-----------------------------------------------------------------------------
// Interfaces/structures local to shaderlib
//-----------------------------------------------------------------------------
IShaderSystem* g_pSLShaderSystem;
// Pattern necessary because shaders register themselves in global constructors
static CShaderDLL *s_pShaderDLL;
//-----------------------------------------------------------------------------
// Global accessor
//-----------------------------------------------------------------------------
IShaderDLL *GetShaderDLL()
{
// Pattern necessary because shaders register themselves in global constructors
if ( !s_pShaderDLL )
{
s_pShaderDLL = new CShaderDLL;
}
return s_pShaderDLL;
}
IShaderDLLInternal *GetShaderDLLInternal()
{
// Pattern necessary because shaders register themselves in global constructors
if ( !s_pShaderDLL )
{
s_pShaderDLL = new CShaderDLL;
}
return static_cast<IShaderDLLInternal*>( s_pShaderDLL );
}
//-----------------------------------------------------------------------------
// Singleton interface
//-----------------------------------------------------------------------------
EXPOSE_INTERFACE_FN( (InstantiateInterfaceFn)GetShaderDLLInternal, IShaderDLLInternal, SHADER_DLL_INTERFACE_VERSION );
//-----------------------------------------------------------------------------
// Connect, disconnect...
//-----------------------------------------------------------------------------
CShaderDLL::CShaderDLL()
{
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f );
}
//-----------------------------------------------------------------------------
// Connect, disconnect...
//-----------------------------------------------------------------------------
bool CShaderDLL::Connect( CreateInterfaceFn factory, bool bIsMaterialSystem )
{
g_pHardwareConfig = (IMaterialSystemHardwareConfig*)factory( MATERIALSYSTEM_HARDWARECONFIG_INTERFACE_VERSION, NULL );
g_pConfig = (const MaterialSystem_Config_t*)factory( MATERIALSYSTEM_CONFIG_VERSION, NULL );
g_pSLShaderSystem = (IShaderSystem*)factory( SHADERSYSTEM_INTERFACE_VERSION, NULL );
if ( !bIsMaterialSystem )
{
ConnectTier1Libraries( &factory, 1 );
InitShaderLibCVars( factory );
}
return ( g_pConfig != NULL ) && (g_pHardwareConfig != NULL) && ( g_pSLShaderSystem != NULL );
}
void CShaderDLL::Disconnect( bool bIsMaterialSystem )
{
if ( !bIsMaterialSystem )
{
ConVar_Unregister();
DisconnectTier1Libraries();
}
g_pHardwareConfig = NULL;
g_pConfig = NULL;
g_pSLShaderSystem = NULL;
}
bool CShaderDLL::Connect( CreateInterfaceFn factory )
{
return Connect( factory, false );
}
void CShaderDLL::Disconnect()
{
Disconnect( false );
}
//-----------------------------------------------------------------------------
// Iterates over all shaders
//-----------------------------------------------------------------------------
int CShaderDLL::ShaderCount() const
{
return m_ShaderList.Count();
}
IShader *CShaderDLL::GetShader( int nShader )
{
if ( ( nShader < 0 ) || ( nShader >= m_ShaderList.Count() ) )
return NULL;
return m_ShaderList[nShader];
}
//-----------------------------------------------------------------------------
// Adds to the shader lists
//-----------------------------------------------------------------------------
void CShaderDLL::InsertShader( IShader *pShader )
{
Assert( pShader );
m_ShaderList.AddToTail( pShader );
}

View File

@ -0,0 +1,33 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Header: $
// $NoKeywords: $
//=============================================================================//
#ifndef SHADERDLL_GLOBAL_H
#define SHADERDLL_GLOBAL_H
#ifdef _WIN32
#pragma once
#endif
//-----------------------------------------------------------------------------
// forward declarations
//-----------------------------------------------------------------------------
class IShaderSystem;
//-----------------------------------------------------------------------------
// forward declarations
//-----------------------------------------------------------------------------
inline IShaderSystem *GetShaderSystem()
{
extern IShaderSystem* g_pSLShaderSystem;
return g_pSLShaderSystem;
}
#endif // SHADERDLL_GLOBAL_H

View File

@ -0,0 +1,42 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
//===========================================================================//
#include "icvar.h"
#include "tier1/tier1.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// ------------------------------------------------------------------------------------------- //
// ConVar stuff.
// ------------------------------------------------------------------------------------------- //
class CShaderLibConVarAccessor : public IConCommandBaseAccessor
{
public:
virtual bool RegisterConCommandBase( ConCommandBase *pCommand )
{
// Link to engine's list instead
g_pCVar->RegisterConCommand( pCommand );
char const *pValue = g_pCVar->GetCommandLineValue( pCommand->GetName() );
if( pValue && !pCommand->IsCommand() )
{
( ( ConVar * )pCommand )->SetValue( pValue );
}
return true;
}
};
CShaderLibConVarAccessor g_ConVarAccessor;
void InitShaderLibCVars( CreateInterfaceFn cvarFactory )
{
if ( g_pCVar )
{
ConVar_Register( FCVAR_MATERIAL_SYSTEM_THREAD, &g_ConVarAccessor );
}
}

View File

@ -0,0 +1,20 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef SHADERLIB_CVAR_H
#define SHADERLIB_CVAR_H
#ifdef _WIN32
#pragma once
#endif
#include "interface.h"
void InitShaderLibCVars( CreateInterfaceFn cvarFactory );
#endif // SHADERLIB_CVAR_H

View File

@ -0,0 +1,423 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="shaderlib"
ProjectGUID="{1A1149D9-CB1B-BF85-19CA-C9C2996BFDE8}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug\."
IntermediateDirectory=".\Debug\."
ConfigurationType="4"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
CommandLine=""
ExcludedFromBuild="false"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
UseUnicodeResponseFiles="false"
AdditionalOptions="/MP"
Optimization="0"
AdditionalIncludeDirectories="..\..\common;..\..\public;..\..\public\tier0;..\..\public\tier1;..\"
PreprocessorDefinitions="WIN32;_WIN32;_DEBUG;DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;VPCGAME=swarm;VPCGAMECAPS=SWARM;_DLL_EXT=.dll;COMPILER_MSVC32;VPCGAME=swarm;VPCGAMECAPS=SWARM;_DLL_EXT=.dll;COMPILER_MSVC;_DLL_EXT=.dll;VPCGAME=swarm;VPCGAMECAPS=SWARM;_DLL_EXT=.dll;LIBNAME=shaderlib;VPCGAME=swarm;VPCGAMECAPS=SWARM;_DLL_EXT=.dll;FAST_MATERIALVAR_ACCESS;VPCGAME=swarm;VPCGAMECAPS=SWARM;_DLL_EXT=.dll"
StringPooling="true"
MinimalRebuild="true"
ExceptionHandling="0"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
BufferSecurityCheck="false"
EnableEnhancedInstructionSet="2"
FloatingPointModel="2"
TreatWChar_tAsBuiltInType="true"
ForceConformanceInForLoopScope="true"
RuntimeTypeInfo="true"
OpenMP="false"
UsePrecompiledHeader="0"
ExpandAttributedSource="false"
AssemblerOutput="0"
AssemblerListingLocation="$(IntDir)/"
ObjectFile="$(IntDir)/"
ProgramDataBaseFileName="$(IntDir)/"
GenerateXMLDocumentationFiles="false"
BrowseInformation="0"
BrowseInformationFile="$(IntDir)/"
WarningLevel="4"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
CompileAs="2"
ErrorReporting="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
CommandLine="if exist ..\..\lib\public\shaderlib.lib attrib -r ..\..\lib\public\shaderlib.lib"
ExcludedFromBuild="false"
/>
<Tool
Name="VCLibrarianTool"
UseUnicodeResponseFiles="false"
OutputFile="..\..\lib\public\.\shaderlib.lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
SuppressStartupBanner="true"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile="$(OutDir)/shaderlib.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
ExcludedFromBuild="false"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release\."
IntermediateDirectory=".\Release\."
ConfigurationType="4"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
CommandLine=""
ExcludedFromBuild="false"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
UseUnicodeResponseFiles="false"
AdditionalOptions="/MP"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
AdditionalIncludeDirectories="..\..\common;..\..\public;..\..\public\tier0;..\..\public\tier1;..\"
PreprocessorDefinitions="WIN32;_WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;VPCGAME=swarm;VPCGAMECAPS=SWARM;_DLL_EXT=.dll;COMPILER_MSVC32;VPCGAME=swarm;VPCGAMECAPS=SWARM;_DLL_EXT=.dll;COMPILER_MSVC;_DLL_EXT=.dll;VPCGAME=swarm;VPCGAMECAPS=SWARM;_DLL_EXT=.dll;LIBNAME=shaderlib;VPCGAME=swarm;VPCGAMECAPS=SWARM;_DLL_EXT=.dll;FAST_MATERIALVAR_ACCESS;VPCGAME=swarm;VPCGAMECAPS=SWARM;_DLL_EXT=.dll"
StringPooling="true"
ExceptionHandling="0"
RuntimeLibrary="0"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="2"
FloatingPointModel="2"
TreatWChar_tAsBuiltInType="true"
ForceConformanceInForLoopScope="true"
RuntimeTypeInfo="true"
OpenMP="false"
UsePrecompiledHeader="0"
ExpandAttributedSource="false"
AssemblerOutput="0"
AssemblerListingLocation="$(IntDir)/"
ObjectFile="$(IntDir)/"
ProgramDataBaseFileName="$(IntDir)/"
GenerateXMLDocumentationFiles="false"
BrowseInformation="0"
BrowseInformationFile="$(IntDir)/"
WarningLevel="4"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="1"
CompileAs="2"
ErrorReporting="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
CommandLine="if exist ..\..\lib\public\shaderlib.lib attrib -r ..\..\lib\public\shaderlib.lib"
ExcludedFromBuild="false"
/>
<Tool
Name="VCLibrarianTool"
UseUnicodeResponseFiles="false"
OutputFile="..\..\lib\public\.\shaderlib.lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
SuppressStartupBanner="true"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile="$(OutDir)/shaderlib.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
ExcludedFromBuild="false"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="VPC Scripts"
>
<File
RelativePath=".\shaderlib.vpc"
>
</File>
<File
RelativePath="..\..\vpc_scripts\source_lib_base.vpc"
>
</File>
<File
RelativePath="..\..\vpc_scripts\source_lib_win32_base.vpc"
>
</File>
<File
RelativePath="..\..\vpc_scripts\source_lib_win32_debug.vpc"
>
</File>
<File
RelativePath="..\..\vpc_scripts\source_lib_win32_release.vpc"
>
</File>
<File
RelativePath="..\..\vpc_scripts\version.vpc"
>
</File>
</Filter>
<Filter
Name="Source Files"
>
<File
RelativePath=".\BaseShader.cpp"
>
</File>
<File
RelativePath=".\ShaderDLL.cpp"
>
</File>
<File
RelativePath=".\shaderlib_cvar.cpp"
>
</File>
</Filter>
<Filter
Name="External Header Files"
>
<File
RelativePath="..\..\public\tier0\basetypes.h"
>
</File>
<File
RelativePath="..\..\public\commonmacros.h"
>
</File>
<File
RelativePath="..\..\public\tier0\dbg.h"
>
</File>
<File
RelativePath="..\..\public\tier0\fasttimer.h"
>
</File>
<File
RelativePath="..\..\public\appframework\IAppSystem.h"
>
</File>
<File
RelativePath="..\..\public\tier0\icommandline.h"
>
</File>
<File
RelativePath="..\..\public\icvar.h"
>
</File>
<File
RelativePath="..\..\public\ImageLoader.h"
>
</File>
<File
RelativePath="..\..\public\materialsystem\imaterial.h"
>
</File>
<File
RelativePath="..\..\public\materialsystem\imaterialsystem.h"
>
</File>
<File
RelativePath="..\..\public\materialsystem\imaterialsystemhardwareconfig.h"
>
</File>
<File
RelativePath="..\..\public\materialsystem\imaterialvar.h"
>
</File>
<File
RelativePath="..\..\public\materialsystem\imesh.h"
>
</File>
<File
RelativePath="..\..\public\materialsystem\IShader.h"
>
</File>
<File
RelativePath="..\..\public\materialsystem\ishaderapi.h"
>
</File>
<File
RelativePath="..\IShaderSystem.h"
>
</File>
<File
RelativePath="..\..\public\materialsystem\itexture.h"
>
</File>
<File
RelativePath="..\..\public\materialsystem\materialsystem_config.h"
>
</File>
<File
RelativePath="..\..\public\MATHLIB.H"
>
</File>
<File
RelativePath="..\..\public\tier0\memdbgoff.h"
>
</File>
<File
RelativePath="..\..\public\tier0\memdbgon.h"
>
</File>
<File
RelativePath="..\..\public\tier0\platform.h"
>
</File>
<File
RelativePath="..\..\public\protected_things.h"
>
</File>
<File
RelativePath="..\..\public\string_t.h"
>
</File>
<File
RelativePath="..\..\public\tier1\strtools.h"
>
</File>
<File
RelativePath="..\..\public\tier1\utlmemory.h"
>
</File>
<File
RelativePath="..\..\public\tier1\utlvector.h"
>
</File>
<File
RelativePath="..\..\public\vector.h"
>
</File>
<File
RelativePath="..\..\public\vector2d.h"
>
</File>
<File
RelativePath="..\..\public\vector4d.h"
>
</File>
<File
RelativePath="..\..\public\vmatrix.h"
>
</File>
<File
RelativePath="..\..\public\vplane.h"
>
</File>
<File
RelativePath="..\..\public\vstdlib\vstdlib.h"
>
</File>
</Filter>
<Filter
Name="Header Files"
>
<File
RelativePath="..\..\public\shaderlib\BaseShader.h"
>
</File>
<File
RelativePath="..\..\public\shaderlib\commandbuilder.h"
>
</File>
<File
RelativePath="..\..\public\shaderlib\cshader.h"
>
</File>
<File
RelativePath="..\..\public\shaderlib\ShaderDLL.h"
>
</File>
<File
RelativePath=".\shaderDLL_Global.h"
>
</File>
<File
RelativePath=".\shaderlib_cvar.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,372 @@
//===== Copyright <20> 1996-2005, 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 "cpp_shader_constant_register_map.h"
#include "shaderlib/cshader.h"
#include "shaderlib/baseshader.h"
#include "ConVar.h"
#include <renderparm.h>
//-----------------------------------------------------------------------------
// 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 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 );
// 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 );
// Sets up hw morphing state for the vertex shader
void SetHWMorphVertexShaderState( int nDimConst, int nSubrectConst, VertexTextureSampler_t morphSampler );
BlendType_t EvaluateBlendRequirements( int textureVar, bool isBaseTexture, int detailTextureVar = -1 );
// Helper for setting up flashlight constants
void SetFlashlightVertexShaderConstants( bool bBump, int bumpTransformVar, bool bDetail, int detailScaleVar, bool bSetTextureTransforms );
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 );
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:
// Converts a color + alpha into a vector4
void ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color );
};
FORCEINLINE char * GetFlashlightTextureFilename()
{
//if ( !IsX360() && ( g_pHardwareConfig->SupportsBorderColor() ) )
//{
// return "effects/flashlight001_border";
//}
//else
{
return "effects/flashlight001";
}
}
extern ConVar r_flashlightbrightness;
FORCEINLINE void SetFlashLightColorFromState( FlashlightState_t const &state, IShaderDynamicAPI *pShaderAPI, bool bSinglePassFlashlight, 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;
float flFlashlightScale = r_flashlightbrightness.GetFloat();
if ( !g_pHardwareConfig->GetHDREnabled() )
{
// Non-HDR path requires 2.0 flashlight
flFlashlightScale = 2.0f;
}
// DX10 hardware and single pass flashlight require a hack scalar since the flashlight is added in linear space
if ( ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) || ( bSinglePassFlashlight ) )
{
flFlashlightScale *= 2.5f; // Magic number that works well on the 360 and NVIDIA 8800
}
flFlashlightScale *= state.m_fBrightnessScale;
// 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;
}
FORCEINLINE void SetupUberlightFromState( IShaderDynamicAPI *pShaderAPI, FlashlightState_t const &state )
{
// Bail if we can't do ps30 or we don't even want an uberlight
if ( !g_pHardwareConfig->HasFastVertexTextures() || !state.m_bUberlight || !pShaderAPI )
return;
UberlightState_t u = state.m_uberlightState;
// Set uberlight shader parameters as function of user controls from UberlightState_t
Vector4D vSmoothEdge0 = Vector4D( 0.0f, u.m_fCutOn - u.m_fNearEdge, u.m_fCutOff, 0.0f );
Vector4D vSmoothEdge1 = Vector4D( 0.0f, u.m_fCutOn, u.m_fCutOff + u.m_fFarEdge, 0.0f );
Vector4D vSmoothOneOverW = Vector4D( 0.0f, 1.0f / u.m_fNearEdge, 1.0f / u.m_fFarEdge, 0.0f );
Vector4D vShearRound = Vector4D( u.m_fShearx, u.m_fSheary, 2.0f / u.m_fRoundness, -u.m_fRoundness / 2.0f );
Vector4D vaAbB = Vector4D( u.m_fWidth, u.m_fWidth + u.m_fWedge, u.m_fHeight, u.m_fHeight + u.m_fHedge );
pShaderAPI->SetPixelShaderConstant( PSREG_UBERLIGHT_SMOOTH_EDGE_0, vSmoothEdge0.Base(), 1 );
pShaderAPI->SetPixelShaderConstant( PSREG_UBERLIGHT_SMOOTH_EDGE_1, vSmoothEdge1.Base(), 1 );
pShaderAPI->SetPixelShaderConstant( PSREG_UBERLIGHT_SMOOTH_EDGE_OOW, vSmoothOneOverW.Base(), 1 );
pShaderAPI->SetPixelShaderConstant( PSREG_UBERLIGHT_SHEAR_ROUND, vShearRound.Base(), 1 );
pShaderAPI->SetPixelShaderConstant( PSREG_UBERLIGHT_AABB, vaAbB.Base(), 1 );
QAngle angles;
QuaternionAngles( state.m_quatOrientation, angles );
// World to Light's View matrix
matrix3x4_t viewMatrix, viewMatrixInverse;
AngleMatrix( angles, state.m_vecLightOrigin, viewMatrixInverse );
MatrixInvert( viewMatrixInverse, viewMatrix );
pShaderAPI->SetPixelShaderConstant( PSREG_UBERLIGHT_WORLD_TO_LIGHT, viewMatrix.Base(), 4 );
}
// 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 );
}
}
FORCEINLINE void InitVecParam( int nIndex, IMaterialVar **params, float x, float y )
{
if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
{
params[nIndex]->SetVecValue( x, y );
}
}
FORCEINLINE void InitVecParam( int nIndex, IMaterialVar **params, float x, float y, float z )
{
if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
{
params[nIndex]->SetVecValue( x, y, z );
}
}
FORCEINLINE void InitVecParam( int nIndex, IMaterialVar **params, float x, float y, float z, float w )
{
if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
{
params[nIndex]->SetVecValue( x, y, z, w );
}
}
// Did we launch with -tools
bool ToolsEnabled();
class ConVar;
#ifdef _DEBUG
extern ConVar mat_envmaptintoverride;
extern ConVar mat_envmaptintscale;
#endif
extern ConVar r_emulategl;
FORCEINLINE bool IsOpenGL( void )
{
return IsPosix() || r_emulategl.GetBool();
}
#endif // BASEVSSHADER_H

View File

@ -0,0 +1,88 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#include "BaseVSShader.h"
#include "screenspaceeffect_vs20.inc"
#include "bloom_ps20.inc"
#include "bloom_ps20b.inc"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
BEGIN_VS_SHADER_FLAGS( 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
{
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( screenspaceeffect_vs20 );
SET_STATIC_VERTEX_SHADER( screenspaceeffect_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( bloom_ps20b );
SET_STATIC_PIXEL_SHADER( bloom_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( bloom_ps20 );
SET_STATIC_PIXEL_SHADER( bloom_ps20 );
}
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, FBTEXTURE, -1 );
BindTexture( SHADER_SAMPLER1, BLURTEXTURE, -1 );
DECLARE_DYNAMIC_VERTEX_SHADER( screenspaceeffect_vs20 );
SET_DYNAMIC_VERTEX_SHADER( screenspaceeffect_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( bloom_ps20b );
SET_DYNAMIC_PIXEL_SHADER( bloom_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( bloom_ps20 );
SET_DYNAMIC_PIXEL_SHADER( bloom_ps20 );
}
}
Draw();
}
END_SHADER

View File

@ -0,0 +1,19 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
#include "common_ps_fxc.h"
sampler FBSampler : register( s0 );
sampler BlurSampler : register( s1 );
struct PS_INPUT
{
float2 texCoord : TEXCOORD0;
};
float4 main( PS_INPUT i ) : COLOR
{
float4 fbSample = tex2D( FBSampler, i.texCoord );
float4 blurSample = tex2D( BlurSampler, i.texCoord );
return FinalOutput( float4( fbSample + blurSample.rgb * blurSample.a * MAX_HDR_OVERBRIGHT, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
}

View File

@ -0,0 +1,131 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#include "BaseVSShader.h"
#include "blurfilter_vs20.inc"
#include "blurfilter_ps20.inc"
#include "blurfilter_ps20b.inc"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
BEGIN_VS_SHADER_FLAGS( BlurFilterX, "Help for BlurFilterX", SHADER_NOT_EDITABLE )
BEGIN_SHADER_PARAMS
SHADER_PARAM( KERNEL, SHADER_PARAM_TYPE_INTEGER, "0", "Kernel type" )
END_SHADER_PARAMS
SHADER_INIT
{
if( params[BASETEXTURE]->IsDefined() )
{
LoadTexture( BASETEXTURE );
}
if ( !( params[ KERNEL ]->IsDefined() ) )
{
params[ KERNEL ]->SetIntValue( 0 );
}
}
SHADER_FALLBACK
{
return 0;
}
SHADER_DRAW
{
SHADOW_STATE
{
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableAlphaWrites( true );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false );
pShaderShadow->EnableSRGBWrite( false );
DECLARE_STATIC_VERTEX_SHADER( blurfilter_vs20 );
SET_STATIC_VERTEX_SHADER_COMBO( KERNEL, params[ KERNEL ]->GetIntValue() ? 1 : 0 );
SET_STATIC_VERTEX_SHADER( blurfilter_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20b );
SET_STATIC_PIXEL_SHADER_COMBO( KERNEL, params[ KERNEL ]->GetIntValue() );
SET_STATIC_PIXEL_SHADER_COMBO( CLEAR_COLOR, false );
SET_STATIC_PIXEL_SHADER( blurfilter_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20 );
SET_STATIC_PIXEL_SHADER_COMBO( KERNEL, params[ KERNEL ]->GetIntValue() );
SET_STATIC_PIXEL_SHADER_COMBO( CLEAR_COLOR, false );
SET_STATIC_PIXEL_SHADER( blurfilter_ps20 );
}
if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) )
EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE );
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 );
float v[4];
// The temp buffer is 1/4 back buffer size
ITexture *src_texture = params[BASETEXTURE]->GetTextureValue();
int width = src_texture->GetActualWidth();
float dX = 1.0f / width;
// Tap offsets
v[0] = 1.3366f * dX;
v[1] = 0.0f;
v[2] = 0;
v[3] = 0;
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, v, 1 );
v[0] = 3.4295f * dX;
v[1] = 0.0f;
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, v, 1 );
v[0] = 5.4264f * dX;
v[1] = 0.0f;
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, v, 1 );
v[0] = 7.4359f * dX;
v[1] = 0.0f;
pShaderAPI->SetPixelShaderConstant( 0, v, 1 );
v[0] = 9.4436f * dX;
v[1] = 0.0f;
pShaderAPI->SetPixelShaderConstant( 1, v, 1 );
v[0] = 11.4401f * dX;
v[1] = 0.0f;
pShaderAPI->SetPixelShaderConstant( 2, v, 1 );
v[0] = v[1] = v[2] = v[3] = 1.0;
pShaderAPI->SetPixelShaderConstant( 3, v, 1 );
v[0] = v[1] = v[2] = v[3] = 0.0;
v[0] = dX;
pShaderAPI->SetPixelShaderConstant( 4, v, 1 );
DECLARE_DYNAMIC_VERTEX_SHADER( blurfilter_ps20 );
SET_DYNAMIC_VERTEX_SHADER( blurfilter_ps20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b );
SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 );
SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 );
}
}
Draw();
}
END_SHADER

View File

@ -0,0 +1,154 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
//===========================================================================//
#include "BaseVSShader.h"
#include "blurfilter_vs20.inc"
#include "blurfilter_ps20.inc"
#include "blurfilter_ps20b.inc"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
BEGIN_VS_SHADER_FLAGS( BlurFilterY, "Help for BlurFilterY", SHADER_NOT_EDITABLE )
BEGIN_SHADER_PARAMS
SHADER_PARAM( BLOOMAMOUNT, SHADER_PARAM_TYPE_FLOAT, "1.0", "" )
SHADER_PARAM( FRAMETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallHDR0", "" )
SHADER_PARAM( KERNEL, SHADER_PARAM_TYPE_INTEGER, "0", "Kernel type" )
SHADER_PARAM( ENABLECLEARCOLOR, SHADER_PARAM_TYPE_BOOL, "0", "clear RGB channels to a solid color" )
SHADER_PARAM( CLEARCOLOR, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "clear color" )
END_SHADER_PARAMS
SHADER_INIT
{
if ( params[BASETEXTURE]->IsDefined() )
{
LoadTexture( BASETEXTURE );
}
if ( !( params[BLOOMAMOUNT]->IsDefined() ) )
{
params[BLOOMAMOUNT]->SetFloatValue(1.0);
}
if ( !( params[ KERNEL ]->IsDefined() ) )
{
params[ KERNEL ]->SetIntValue( 0 );
}
if ( !( params[ ENABLECLEARCOLOR ]->IsDefined() ) )
{
params[ ENABLECLEARCOLOR ]->SetIntValue( 0 );
}
if ( !( params[ CLEARCOLOR ]->IsDefined() ) )
{
params[ CLEARCOLOR ]->SetVecValue( 0.0f, 0.0f, 0.0f );
}
}
SHADER_FALLBACK
{
return 0;
}
SHADER_DRAW
{
SHADOW_STATE
{
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableAlphaWrites( true );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 );
//avoid srgb conversions to alleviate some of the srgb texture lookup problems
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false );
pShaderShadow->EnableSRGBWrite( false );
DECLARE_STATIC_VERTEX_SHADER( blurfilter_vs20 );
SET_STATIC_VERTEX_SHADER_COMBO( KERNEL, params[ KERNEL ]->GetIntValue() ? 1 : 0 );
SET_STATIC_VERTEX_SHADER( blurfilter_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20b );
SET_STATIC_PIXEL_SHADER_COMBO( KERNEL, params[ KERNEL ]->GetIntValue() );
SET_STATIC_PIXEL_SHADER_COMBO( CLEAR_COLOR, params[ ENABLECLEARCOLOR ]->GetIntValue() );
SET_STATIC_PIXEL_SHADER( blurfilter_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20 );
SET_STATIC_PIXEL_SHADER_COMBO( KERNEL, params[ KERNEL ]->GetIntValue() );
SET_STATIC_PIXEL_SHADER_COMBO( CLEAR_COLOR, params[ ENABLECLEARCOLOR ]->GetIntValue() );
SET_STATIC_PIXEL_SHADER( blurfilter_ps20 );
}
if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) )
EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE );
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 );
// The temp buffer is 1/4 back buffer size
ITexture *src_texture = params[BASETEXTURE]->GetTextureValue();
int height = src_texture->GetActualHeight();
float dY = 1.0f / height;
// dY *= 0.4;
float v[4];
// Tap offsets
v[0] = 0.0f;
v[1] = 1.3366f * dY;
v[2] = 0;
v[3] = 0;
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, v, 1 );
v[0] = 0.0f;
v[1] = 3.4295f * dY;
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, v, 1 );
v[0] = 0.0f;
v[1] = 5.4264f * dY;
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, v, 1 );
v[0] = 0.0f;
v[1] = 7.4359f * dY;
pShaderAPI->SetPixelShaderConstant( 0, v, 1 );
v[0] = 0.0f;
v[1] = 9.4436f * dY;
pShaderAPI->SetPixelShaderConstant( 1, v, 1 );
v[0] = 0.0f;
v[1] = 11.4401f * dY;
pShaderAPI->SetPixelShaderConstant( 2, v, 1 );
v[0] = v[1] = v[2] = params[BLOOMAMOUNT]->GetFloatValue();
pShaderAPI->SetPixelShaderConstant( 3, v, 1 );
v[0] = v[1] = v[2] = v[3] = 0.0;
v[1] = dY;
pShaderAPI->SetPixelShaderConstant( 4, v, 1 );
params[CLEARCOLOR]->GetVecValue( v, 3 );
v[3] = 0.0f;
pShaderAPI->SetPixelShaderConstant( 5, v, 1 );
DECLARE_DYNAMIC_VERTEX_SHADER( blurfilter_ps20 );
SET_DYNAMIC_VERTEX_SHADER( blurfilter_ps20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b );
SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 );
SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 );
}
}
Draw();
}
END_SHADER

View File

@ -0,0 +1,128 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// STATIC: "KERNEL" "0..4"
// STATIC: "CLEAR_COLOR" "0..1"
#include "common_ps_fxc.h"
sampler TexSampler : register( s0 );
struct PS_INPUT
{
float2 coordTap0 : TEXCOORD0;
#if ( KERNEL == 0 ) // Original kernel that has a '+' plus shape
float2 coordTap1 : TEXCOORD1;
float2 coordTap2 : TEXCOORD2;
float2 coordTap3 : TEXCOORD3;
float2 coordTap1Neg : TEXCOORD4;
float2 coordTap2Neg : TEXCOORD5;
float2 coordTap3Neg : TEXCOORD6;
#endif
};
float2 g_vPsTapOffset[3] : register( c0 );
float3 g_vScaleFactor : register( c3 );
float2 g_vUvOffsetToNeighborPixel : register( c4 );
float3 g_vClearColor : register( c5 );
float4 main( PS_INPUT i ) : COLOR
{
#if ( KERNEL == 0 ) // Original kernel that has a '+' plus shape (used for bloom?)
{
float4 s0, s1, s2, s3, s4, s5, s6, color;
// Sample taps with coordinates from VS
s0 = saturate( tex2D( TexSampler, i.coordTap0 ) );
s1 = saturate( tex2D( TexSampler, i.coordTap1 ) );
s2 = saturate( tex2D( TexSampler, i.coordTap2 ) );
s3 = saturate( tex2D( TexSampler, i.coordTap3 ) );
s4 = saturate( tex2D( TexSampler, i.coordTap1Neg ) );
s5 = saturate( tex2D( TexSampler, i.coordTap2Neg ) );
s6 = saturate( tex2D( TexSampler, i.coordTap3Neg ) );
color = s0 * 0.2013f;
color += ( s1 + s4 ) * 0.2185f;
color += ( s2 + s5 ) * 0.0821f;
color += ( s3 + s6 ) * 0.0461f;
// Compute tex coords for other taps
float2 coordTap4 = i.coordTap0 + g_vPsTapOffset[0];
float2 coordTap5 = i.coordTap0 + g_vPsTapOffset[1];
float2 coordTap6 = i.coordTap0 + g_vPsTapOffset[2];
float2 coordTap4Neg = i.coordTap0 - g_vPsTapOffset[0];
float2 coordTap5Neg = i.coordTap0 - g_vPsTapOffset[1];
float2 coordTap6Neg = i.coordTap0 - g_vPsTapOffset[2];
// Sample the taps
s1 = saturate( tex2D( TexSampler, coordTap4 ) );
s2 = saturate( tex2D( TexSampler, coordTap5 ) );
s3 = saturate( tex2D( TexSampler, coordTap6 ) );
s4 = saturate( tex2D( TexSampler, coordTap4Neg ) );
s5 = saturate( tex2D( TexSampler, coordTap5Neg ) );
s6 = saturate( tex2D( TexSampler, coordTap6Neg ) );
color += ( s1 + s4 ) * 0.0262f;
color += ( s2 + s5 ) * 0.0162f;
color += ( s3 + s6 ) * 0.0102f;
#if CLEAR_COLOR == 1
{
color.rgb = g_vClearColor.rgb;
}
#else
{
color.xyz *= g_vScaleFactor.xyz;
}
#endif
return color;
}
#else // Gaussian kernel
{
#if ( KERNEL == 1 )
// Gaussian kernel 7 pixels wide
int kNumSamples = 5;
float vKernel[5] = { 0.004433f, 0.296042f, 0.399050f, 0.296042f, 0.004433f };
float vUvOffset[5] = { -3.000000f, -1.182425f, 0.000000f, 1.182425f, 3.000000f };
#elif ( KERNEL == 2 )
// Gaussian kernel 9 pixels wide
int kNumSamples = 5;
float vKernel[5] = { 0.019827f, 0.320561f, 0.319224f, 0.320561f, 0.019827f };
float vUvOffset[5] = { -3.096215f, -1.276878f, 0.000000f, 1.276878f, 3.096215f };
#elif ( KERNEL == 3 )
// Gaussian kernel 13 pixels wide
int kNumSamples = 7;
float vKernel[7] = { 0.004487f, 0.069185f, 0.312325f, 0.228005f, 0.312325f, 0.069185f, 0.004487f };
float vUvOffset[7] = { -5.142349f, -3.241796f, -1.379942f, 0.000000f, 1.379942f, 3.241796f, 5.142349f };
#elif ( KERNEL == 4 )
// Gaussian kernel 25 pixels wide
int kNumSamples = 13;
float vKernel[13] = { 0.000534f, 0.003733f, 0.018004f, 0.059928f, 0.137740f, 0.218677f, 0.122765f, 0.218677f, 0.137740f, 0.059928f, 0.018004f, 0.003733f, 0.000534f };
float vUvOffset[13] = { -11.251852f, -9.289172f, -7.329586f, -5.372686f, -3.417910f, -1.464557f, 0.000000f, 1.464557f, 3.417910f, 5.372686f, 7.329586f, 9.289172f, 11.251852f };
#endif
float2 vStartUv = i.coordTap0.xy;
float4 cColor = { 0.0f, 0.0f, 0.0f, 0.0f };
for ( int j = 0; j < kNumSamples; j++ )
{
// Calculate uv
float2 vUvTmp = vStartUv.xy + ( vUvOffset[j].xx * g_vUvOffsetToNeighborPixel.xy );
// Sample pixel
cColor.rgba += vKernel[j] * tex2D( TexSampler, vUvTmp.xy );
}
#if CLEAR_COLOR == 1
{
cColor.rgb = g_vClearColor.rgb;
}
#else
{
cColor.rgb = cColor.rgb * g_vScaleFactor.rgb;
}
#endif
return cColor.rgba;
}
#endif
}

View File

@ -0,0 +1,45 @@
#include "common_vs_fxc.h"
// STATIC: "KERNEL" "0..1"
struct VS_INPUT
{
float3 vPos : POSITION;
float2 vBaseTexCoord : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 projPos : POSITION;
float2 coordTap0 : TEXCOORD0;
#if ( KERNEL == 0 ) // Original kernel that has a '+' plus shape
float2 coordTap1 : TEXCOORD1;
float2 coordTap2 : TEXCOORD2;
float2 coordTap3 : TEXCOORD3;
float2 coordTap1Neg : TEXCOORD4;
float2 coordTap2Neg : TEXCOORD5;
float2 coordTap3Neg : TEXCOORD6;
#endif
};
float2 vsTapOffs[3] : register ( SHADER_SPECIFIC_CONST_0 );
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
o.projPos = float4( v.vPos, 1.0f );
o.coordTap0.xy = v.vBaseTexCoord.xy;
#if ( KERNEL == 0 ) // Original kernel
o.coordTap1 = v.vBaseTexCoord + vsTapOffs[0];
o.coordTap2 = v.vBaseTexCoord + vsTapOffs[1];
o.coordTap3 = v.vBaseTexCoord + vsTapOffs[2];
o.coordTap1Neg = v.vBaseTexCoord - vsTapOffs[0];
o.coordTap2Neg = v.vBaseTexCoord - vsTapOffs[1];
o.coordTap3Neg = v.vBaseTexCoord - vsTapOffs[2];
#endif
return o;
}

View File

@ -0,0 +1,105 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Clears color/depth, but obeys stencil while doing so
//
//=============================================================================//
#include "BaseVSShader.h"
#include "bufferclearobeystencil_vs20.inc"
#include "bufferclearobeystencil_ps20.inc"
#include "bufferclearobeystencil_ps20b.inc"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
DEFINE_FALLBACK_SHADER( BufferClearObeyStencil, BufferClearObeyStencil_DX9 )
BEGIN_VS_SHADER_FLAGS( BufferClearObeyStencil_DX9, "", SHADER_NOT_EDITABLE )
BEGIN_SHADER_PARAMS
SHADER_PARAM( CLEARCOLOR, SHADER_PARAM_TYPE_INTEGER, "1", "activates clearing of color" )
SHADER_PARAM( CLEARALPHA, SHADER_PARAM_TYPE_INTEGER, "-1", "activates clearing of alpha. -1 == copy CLEARCOLOR setting" )
SHADER_PARAM( CLEARDEPTH, SHADER_PARAM_TYPE_INTEGER, "1", "activates clearing of depth" )
END_SHADER_PARAMS
SHADER_INIT_PARAMS()
{
}
SHADER_FALLBACK
{
return 0;
}
SHADER_INIT
{
if ( !params[CLEARALPHA]->IsDefined() )
{
params[CLEARALPHA]->SetIntValue( -1 );
}
}
SHADER_DRAW
{
bool bEnableColorWrites = params[CLEARCOLOR]->GetIntValue() != 0;
bool bEnableAlphaWrites = (params[CLEARALPHA]->GetIntValue() >= 0) ? (params[CLEARALPHA]->GetIntValue() != 0) : bEnableColorWrites;
bool bUsesColor = bEnableColorWrites || bEnableAlphaWrites;
SHADOW_STATE
{
pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_ALWAYS );
bool bEnableDepthWrites = params[CLEARDEPTH]->GetIntValue() != 0;
pShaderShadow->EnableDepthWrites( bEnableDepthWrites );
pShaderShadow->EnableColorWrites( bEnableColorWrites );
pShaderShadow->EnableAlphaWrites( bEnableAlphaWrites );
pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION|VERTEX_COLOR, 1, NULL, 0 );
DECLARE_STATIC_VERTEX_SHADER( bufferclearobeystencil_vs20 );
SET_STATIC_VERTEX_SHADER_COMBO( USESCOLOR, bUsesColor );
SET_STATIC_VERTEX_SHADER( bufferclearobeystencil_vs20 );
//avoid setting a pixel shader when only doing depth/stencil operations, as recommended by PIX
if( bUsesColor )
{
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( bufferclearobeystencil_ps20b );
SET_STATIC_PIXEL_SHADER( bufferclearobeystencil_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( bufferclearobeystencil_ps20 );
SET_STATIC_PIXEL_SHADER( bufferclearobeystencil_ps20 );
}
}
}
DYNAMIC_STATE
{
DECLARE_DYNAMIC_VERTEX_SHADER( bufferclearobeystencil_vs20 );
SET_DYNAMIC_VERTEX_SHADER( bufferclearobeystencil_vs20 );
//avoid setting a pixel shader when only doing depth/stencil operations, as recommended by PIX
if( bUsesColor )
{
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( bufferclearobeystencil_ps20b );
SET_DYNAMIC_PIXEL_SHADER( bufferclearobeystencil_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( bufferclearobeystencil_ps20 );
SET_DYNAMIC_PIXEL_SHADER( bufferclearobeystencil_ps20 );
}
}
}
Draw( );
}
END_SHADER

View File

@ -0,0 +1,21 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
#include "common_ps_fxc.h"
struct PS_INPUT
{
float4 projPos : POSITION;
float3 zValue : TEXCOORD0;
};
const float3 g_ZFilter : register( c1 );
const float3 g_ModulationColor : register( c2 );
float4 main( PS_INPUT i ) : COLOR
{
float z = dot( i.zValue, g_ZFilter );
z = saturate( z );
float4 color = float4( z, z, z, 1.0f );
color.rgb *= g_ModulationColor;
return FinalOutput( color, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
}

View File

@ -0,0 +1,38 @@
// DYNAMIC: "COMPRESSED_VERTS" "0..1"
// DYNAMIC: "SKINNING" "0..1"
#include "common_vs_fxc.h"
static const bool g_bSkinning = SKINNING ? true : false;
const float2 cDepthFactor : register( SHADER_SPECIFIC_CONST_0 );
struct VS_INPUT
{
float4 vPos : POSITION;
float4 vBoneWeights : BLENDWEIGHT;
float4 vBoneIndices : BLENDINDICES;
};
struct VS_OUTPUT
{
float4 projPos : POSITION;
float2 zValue : TEXCOORD0;
};
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
float3 worldPos;
SkinPosition( g_bSkinning, v.vPos, v.vBoneWeights, v.vBoneIndices, worldPos );
float4 projPos = mul( float4( worldPos, 1 ), cViewProj );
o.projPos = projPos;
o.zValue.x = (o.projPos.z - cDepthFactor.y) / cDepthFactor.x;
o.zValue.y = (o.projPos.w - cDepthFactor.y) / cDepthFactor.x;
return o;
}

View File

@ -0,0 +1,89 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
//===========================================================================//
#include "BaseVSShader.h"
#include "debugdrawenvmapmask_vs20.inc"
#include "debugdrawenvmapmask_ps20.inc"
#include "debugdrawenvmapmask_ps20b.inc"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
BEGIN_VS_SHADER_FLAGS( DebugDrawEnvmapMask, "Help for DebugDrawEnvmapMask", SHADER_NOT_EDITABLE )
BEGIN_SHADER_PARAMS
SHADER_PARAM( SHOWALPHA, SHADER_PARAM_TYPE_INTEGER, "0", "" )
END_SHADER_PARAMS
SHADER_INIT_PARAMS()
{
SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
}
SHADER_INIT
{
}
SHADER_FALLBACK
{
return 0;
}
SHADER_DRAW
{
SHADOW_STATE
{
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
// Set stream format (note that this shader supports compression)
unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED;
int nTexCoordCount = 1;
int userDataSize = 0;
pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize );
DECLARE_STATIC_VERTEX_SHADER( debugdrawenvmapmask_vs20 );
SET_STATIC_VERTEX_SHADER( debugdrawenvmapmask_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( debugdrawenvmapmask_ps20b );
SET_STATIC_PIXEL_SHADER( debugdrawenvmapmask_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( debugdrawenvmapmask_ps20 );
SET_STATIC_PIXEL_SHADER( debugdrawenvmapmask_ps20 );
}
}
DYNAMIC_STATE
{
int numBones = s_pShaderAPI->GetCurrentNumBones();
DECLARE_DYNAMIC_VERTEX_SHADER( debugdrawenvmapmask_vs20 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
SET_DYNAMIC_VERTEX_SHADER( debugdrawenvmapmask_vs20 );
bool bShowAlpha = params[SHOWALPHA]->GetIntValue() ? true : false;
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( debugdrawenvmapmask_ps20b );
SET_DYNAMIC_PIXEL_SHADER_COMBO( SHOWALPHA, bShowAlpha );
SET_DYNAMIC_PIXEL_SHADER( debugdrawenvmapmask_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( debugdrawenvmapmask_ps20 );
SET_DYNAMIC_PIXEL_SHADER_COMBO( SHOWALPHA, bShowAlpha );
SET_DYNAMIC_PIXEL_SHADER( debugdrawenvmapmask_ps20 );
}
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM );
}
Draw();
}
END_SHADER

View File

@ -0,0 +1,24 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// DYNAMIC: "SHOWALPHA" "0..1"
#include "common_ps_fxc.h"
sampler BaseTextureSampler : register( s0 );
struct PS_INPUT
{
float4 projPos : POSITION;
float2 baseTexCoord : TEXCOORD0;
};
float4 main( PS_INPUT i ) : COLOR
{
float4 baseColor = tex2D( BaseTextureSampler, i.baseTexCoord );
#if SHOWALPHA
float4 result = float4( baseColor.a, baseColor.a, baseColor.a, 1.0f );
#else
float4 result = float4( baseColor.rgb, 1.0f );
#endif
return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
}

View File

@ -0,0 +1,39 @@
// DYNAMIC: "COMPRESSED_VERTS" "0..1"
// DYNAMIC: "SKINNING" "0..1"
#include "common_vs_fxc.h"
static const bool g_bSkinning = SKINNING ? true : false;
const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 );
struct VS_INPUT
{
float4 vPos : POSITION;
float4 vBoneWeights : BLENDWEIGHT;
float4 vBoneIndices : BLENDINDICES;
float4 vTexCoord0 : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 projPos : POSITION;
float2 baseTexCoord : TEXCOORD0;
};
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
float3 worldPos;
SkinPosition( g_bSkinning, v.vPos, v.vBoneWeights, v.vBoneIndices, worldPos );
float4 projPos = mul( float4( worldPos, 1 ), cViewProj );
o.projPos = projPos;
o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] );
o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] );
return o;
}

View File

@ -0,0 +1,104 @@
//========= Copyright <20> 1996-2007, Valve Corporation, All rights reserved. ============//
#include "BaseVSShader.h"
#include "shaderlib/CShader.h"
#include "debugtextureview_vs20.inc"
#include "debugtextureview_ps20.inc"
#include "debugtextureview_ps20b.inc"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
DEFINE_FALLBACK_SHADER( DebugTextureView, DebugTextureView_dx9 )
BEGIN_VS_SHADER( DebugTextureView_dx9, "Help for DebugTextureView" )
BEGIN_SHADER_PARAMS
SHADER_PARAM( SHOWALPHA, SHADER_PARAM_TYPE_BOOL, "0", "" )
END_SHADER_PARAMS
SHADER_INIT
{
if ( params[BASETEXTURE]->IsDefined() )
{
LoadTexture( BASETEXTURE );
}
}
SHADER_FALLBACK
{
return 0;
}
SHADER_DRAW
{
SHADOW_STATE
{
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableAlphaTest( true );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
// Set stream format (note that this shader supports compression)
unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED;
int nTexCoordCount = 1;
int userDataSize = 0;
pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize );
DECLARE_STATIC_VERTEX_SHADER( debugtextureview_vs20 );
SET_STATIC_VERTEX_SHADER( debugtextureview_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( debugtextureview_ps20b );
SET_STATIC_PIXEL_SHADER_COMBO( SHOWALPHA, params[SHOWALPHA]->GetIntValue() != 0 );
SET_STATIC_PIXEL_SHADER( debugtextureview_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( debugtextureview_ps20 );
SET_STATIC_PIXEL_SHADER_COMBO( SHOWALPHA, params[SHOWALPHA]->GetIntValue() != 0 );
SET_STATIC_PIXEL_SHADER( debugtextureview_ps20 );
}
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
//pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP );
ITexture *pTexture = params[BASETEXTURE]->GetTextureValue();
float cPsConst0[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
if ( ( pTexture->GetImageFormat() == IMAGE_FORMAT_RGBA16161616F ) ||
( pTexture->GetImageFormat() == IMAGE_FORMAT_RGBA16161616 ) ||
( pTexture->GetImageFormat() == IMAGE_FORMAT_RGB323232F ) ||
( pTexture->GetImageFormat() == IMAGE_FORMAT_RGBA32323232F ) )
{
if ( pTexture->IsCubeMap() )
cPsConst0[0] = 1.0f;
else
cPsConst0[1] = 1.0f;
}
pShaderAPI->SetPixelShaderConstant( 0, cPsConst0 );
DECLARE_DYNAMIC_VERTEX_SHADER( debugtextureview_vs20 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
SET_DYNAMIC_VERTEX_SHADER( debugtextureview_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( debugtextureview_ps20b );
SET_DYNAMIC_PIXEL_SHADER_COMBO( ISCUBEMAP, pTexture->IsCubeMap() );
SET_DYNAMIC_PIXEL_SHADER( debugtextureview_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( debugtextureview_ps20 );
SET_DYNAMIC_PIXEL_SHADER_COMBO( ISCUBEMAP, pTexture->IsCubeMap() );
SET_DYNAMIC_PIXEL_SHADER( debugtextureview_ps20 );
}
}
Draw();
}
END_SHADER

View File

@ -0,0 +1,80 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// STATIC: "SHOWALPHA" "0..1"
// DYNAMIC: "ISCUBEMAP" "0..1"
#include "common_ps_fxc.h"
sampler g_tSampler : register( s0 );
struct PS_INPUT
{
float2 texCoord : TEXCOORD0;
};
const float3 g_vConst0 : register( c0 );
#define g_flIsHdrCube g_vConst0.x
#define g_flIsHdr2D g_vConst0.y
float4 main( PS_INPUT i ) : COLOR
{
float4 sample = tex2D( g_tSampler, i.texCoord );
float4 result = { 0.0f, 0.0f, 0.0f, 1.0f };
result.rgb = sample.rgb;
#if SHOWALPHA
result.rgb = sample.a;
#endif
if ( g_flIsHdr2D )
result.rgb *= MAX_HDR_OVERBRIGHT;
#if ISCUBEMAP
bool bNoDataForThisPixel = false;
float3 vec = float3( 0, 0, 0 );
float x = i.texCoord.x;
float y = i.texCoord.y;
float x2 = frac( ( i.texCoord.x ) * 3.0f ) * 2.0f - 1.0f;
float y2 = frac( ( i.texCoord.y ) * 4.0f ) * 2.0f - 1.0f;
if ( ( x >= 0.3333f ) && ( x <= 0.6666f ) ) //Center row
{
if ( y >= 0.75f )
vec = float3( x2, 1.0, y2 );
else if ( y >= 0.5f )
vec = float3( x2, y2, -1.0 );
else if ( y >= 0.25f )
vec = float3( x2, -1.0, -y2 );
else if ( y >= 0.0f )
vec = float3( x2, -y2, 1.0 );
}
else if ( ( y >= 0.25f ) && ( y <= 0.5f ) )
{
if ( x <= 0.3333f )
vec = float3( -1.0f, -x2, -y2 );
else if (x >= 0.6666f)
vec = float3( 1.0f, x2, -y2 );
else
bNoDataForThisPixel = true;
}
else
{
bNoDataForThisPixel = true;
}
float4 cBase = texCUBE( g_tSampler, vec );
#if SHOWALPHA
cBase.rgb = cBase.a;
#endif
if ( g_flIsHdrCube )
cBase.rgb *= ENV_MAP_SCALE;
if ( bNoDataForThisPixel == true )
cBase.rgb = float3( 0.9f, 0.4f, 0.15f );
result.rgb = cBase.rgb;
result.a = 1.0f; // - bNoDataForThisPixel;
#endif
return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
}

View File

@ -0,0 +1,23 @@
// DYNAMIC: "COMPRESSED_VERTS" "0..1"
#include "common_vs_fxc.h"
struct VS_INPUT
{
float4 vPos : POSITION;
float4 vTexCoord0 : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 vProjPos : POSITION;
float2 vUv0 : TEXCOORD0;
};
VS_OUTPUT main( const VS_INPUT i )
{
VS_OUTPUT o;
o.vProjPos.xyzw = mul( i.vPos.xyzw, cModelViewProj );
o.vUv0.xy = i.vTexCoord0.xy;
return o;
}

View File

@ -0,0 +1,227 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $Header: $
// $NoKeywords: $
//===========================================================================//
#include "BaseVSShader.h"
#include "cpp_shader_constant_register_map.h"
#include "decalmodulate_vs20.inc"
#include "decalmodulate_ps20.inc"
#include "decalmodulate_ps20b.inc"
#ifndef _X360
#include "decalmodulate_vs30.inc"
#include "decalmodulate_ps30.inc"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
DEFINE_FALLBACK_SHADER( DecalModulate, DecalModulate_DX9 )
BEGIN_VS_SHADER( DecalModulate_dx9,
"Help for DecalModulate_dx9" )
BEGIN_SHADER_PARAMS
SHADER_PARAM( FOGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "0.4", "exponent to tweak fog fade" )
SHADER_PARAM( FOGSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "scale to tweak fog fade" )
END_SHADER_PARAMS
SHADER_FALLBACK
{
return 0;
}
SHADER_INIT_PARAMS()
{
if( !params[ FOGEXPONENT ]->IsDefined() )
{
params[ FOGEXPONENT ]->SetFloatValue( 0.4f );
}
if( !params[ FOGSCALE ]->IsDefined() )
{
params[ FOGSCALE ]->SetFloatValue( 1.0f );
}
SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
#ifndef _X360
if ( g_pHardwareConfig->HasFastVertexTextures() )
{
// The vertex shader uses the vertex id stream
SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID );
SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
}
#endif
}
SHADER_INIT
{
LoadTexture( BASETEXTURE );
}
SHADER_DRAW
{
SHADOW_STATE
{
pShaderShadow->EnableAlphaTest( true );
pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.0f );
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnablePolyOffset( SHADER_POLYOFFSET_DECAL );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
// Be sure not to write to dest alpha
pShaderShadow->EnableAlphaWrites( false );
//SRGB conversions hose the blend on some hardware, so keep everything in gamma space.
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false );
pShaderShadow->EnableSRGBWrite( false );
pShaderShadow->EnableBlending( true );
pShaderShadow->BlendFunc( SHADER_BLEND_DST_COLOR, SHADER_BLEND_SRC_COLOR );
pShaderShadow->DisableFogGammaCorrection( true ); //fog should stay exactly middle grey
FogToGrey();
int nLightingPreviewMode = IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER0 ) + 2 * IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER1 );
bool bHasVertexAlpha = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) && IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA );
#ifndef _X360
if ( !g_pHardwareConfig->HasFastVertexTextures() )
#endif
{
DECLARE_STATIC_VERTEX_SHADER( decalmodulate_vs20 );
SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bHasVertexAlpha );
SET_STATIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, nLightingPreviewMode != 0 );
SET_STATIC_VERTEX_SHADER( decalmodulate_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( decalmodulate_ps20b );
SET_STATIC_PIXEL_SHADER_COMBO( VERTEXALPHA, bHasVertexAlpha );
SET_STATIC_PIXEL_SHADER( decalmodulate_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( decalmodulate_ps20 );
SET_STATIC_PIXEL_SHADER_COMBO( VERTEXALPHA, bHasVertexAlpha );
SET_STATIC_PIXEL_SHADER( decalmodulate_ps20 );
}
}
#ifndef _X360
else
{
DECLARE_STATIC_VERTEX_SHADER( decalmodulate_vs30 );
SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bHasVertexAlpha );
SET_STATIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, nLightingPreviewMode != 0 );
SET_STATIC_VERTEX_SHADER( decalmodulate_vs30 );
DECLARE_STATIC_PIXEL_SHADER( decalmodulate_ps30 );
SET_STATIC_PIXEL_SHADER_COMBO( VERTEXALPHA, bHasVertexAlpha );
SET_STATIC_PIXEL_SHADER( decalmodulate_ps30 );
}
#endif
// Set stream format (note that this shader supports compression)
unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED;
if ( bHasVertexAlpha )
{
flags |= VERTEX_COLOR;
}
#ifndef _X360
// The VS30 shader offsets decals along the normal (for morphed geom)
flags |= g_pHardwareConfig->HasFastVertexTextures() ? VERTEX_NORMAL : 0;
#endif
int pTexCoordDim[3] = { 2, 0, 3 };
int nTexCoordCount = 1;
int userDataSize = 0;
#ifndef _X360
if ( g_pHardwareConfig->HasFastVertexTextures() )
{
nTexCoordCount = 3;
}
#endif
pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize );
}
DYNAMIC_STATE
{
if ( pShaderAPI->InFlashlightMode() && !IsX360() )
{
// Don't draw anything for the flashlight pass
Draw( false );
return;
}
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
// Set an identity base texture transformation
Vector4D transformation[2];
transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f );
transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f );
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, transformation[0].Base(), 2 );
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 );
// fog tweaks
float fConsts[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
fConsts[0] = params[ FOGEXPONENT ]->GetFloatValue();
fConsts[1] = params[ FOGSCALE ]->GetFloatValue();
pShaderAPI->SetPixelShaderConstant( 0, fConsts );
#ifndef _X360
if ( !g_pHardwareConfig->HasFastVertexTextures() )
#endif
{
DECLARE_DYNAMIC_VERTEX_SHADER( decalmodulate_vs20 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, 0 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
// SET_DYNAMIC_VERTEX_SHADER_COMBO( TESSELLATION, 0 ); // JasonM TODO: set this appropriately when we care about decals on subds
SET_DYNAMIC_VERTEX_SHADER( decalmodulate_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( decalmodulate_ps20b );
SET_DYNAMIC_PIXEL_SHADER( decalmodulate_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( decalmodulate_ps20 );
SET_DYNAMIC_PIXEL_SHADER( decalmodulate_ps20 );
}
}
#ifndef _X360
else
{
SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 );
DECLARE_DYNAMIC_VERTEX_SHADER( decalmodulate_vs30 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
// SET_DYNAMIC_VERTEX_SHADER_COMBO( TESSELLATION, 0 ); // JasonM TODO: set this appropriately when we care about decals on subds
SET_DYNAMIC_VERTEX_SHADER( decalmodulate_vs30 );
DECLARE_DYNAMIC_PIXEL_SHADER( decalmodulate_ps30 );
SET_DYNAMIC_PIXEL_SHADER( decalmodulate_ps30 );
bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() };
pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords );
}
#endif
}
Draw( );
}
END_SHADER

View File

@ -0,0 +1,280 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: Depth of field material
//
//===========================================================================//
#include "BaseVSShader.h"
#include "depth_of_field_vs20.inc"
#include "depth_of_field_ps20b.inc"
#include "convar.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
ConVar mat_dof_max_blur_radius( "mat_dof_max_blur_radius", "10" );
ConVar mat_dof_quality( "mat_dof_quality", "0" );
// 8 samples
static const float s_flPoissonConstsQuality0[16] = {
0.0, 0.0,
0.527837, -0.085868,
-0.040088, 0.536087,
-0.670445, -0.179949,
-0.419418, -0.616039,
0.440453, -0.639399,
-0.757088, 0.349334,
0.574619, 0.685879
};
// 16 samples
static const float s_flPoissonConstsQuality1[32] = {
0.0747, -0.8341,
-0.9138, 0.3251,
0.8667, -0.3029,
-0.4642, 0.2187,
-0.1505, 0.7320,
0.7310, -0.6786,
0.2859, -0.3254,
-0.1311, -0.2292,
0.3518, 0.6470,
-0.7485, -0.6307,
0.1687, 0.1873,
-0.3604, -0.7483,
-0.5658, -0.1521,
0.7102, 0.0536,
-0.6056, 0.7747,
0.7793, 0.6194
};
// 32 samples
static const float s_flPoissonConstsQuality2[64] = {
0.0854f, -0.0644f,
0.8744f, 0.1665f,
0.2329f, 0.3995f,
-0.7804f, 0.5482f,
-0.4577f, 0.7647f,
-0.1936f, 0.5564f,
0.4205f, -0.5768f,
-0.0304f, -0.9050f,
-0.5215f, 0.1854f,
0.3161f, -0.2954f,
0.0666f, -0.5564f,
-0.2137f, -0.0072f,
-0.4112f, -0.3311f,
0.6438f, -0.2484f,
-0.9055f, -0.0360f,
0.8323f, 0.5268f,
0.5592f, 0.3459f,
-0.6797f, -0.5201f,
-0.4325f, -0.8857f,
0.8768f, -0.4197f,
0.3090f, -0.8646f,
0.5034f, 0.8603f,
0.3752f, 0.0627f,
-0.0161f, 0.2627f,
0.0969f, 0.7054f,
-0.2291f, -0.6595f,
-0.5887f, -0.1100f,
0.7048f, -0.6528f,
-0.8438f, 0.2706f,
-0.5061f, 0.4653f,
-0.1245f, -0.3302f,
-0.1801f, 0.8486f
};
DEFINE_FALLBACK_SHADER( DepthOfField, DepthOfField_dx9 )
BEGIN_VS_SHADER_FLAGS( DepthOfField_dx9, "Depth of Field", SHADER_NOT_EDITABLE )
BEGIN_SHADER_PARAMS
SHADER_PARAM( SMALLFB, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallFB1", "Downsampled backbuffer" )
SHADER_PARAM( NEARPLANE, SHADER_PARAM_TYPE_FLOAT, "0", "Near plane depth" )
SHADER_PARAM( FARPLANE, SHADER_PARAM_TYPE_FLOAT, "0", "Far plane depth" )
SHADER_PARAM( NEARBLURDEPTH, SHADER_PARAM_TYPE_FLOAT, "0", "Near blur plane depth" )
SHADER_PARAM( NEARFOCUSDEPTH, SHADER_PARAM_TYPE_FLOAT, "0", "Near focus plane depth" )
SHADER_PARAM( FARFOCUSDEPTH, SHADER_PARAM_TYPE_FLOAT, "0", "Far focus plane depth" )
SHADER_PARAM( FARBLURDEPTH, SHADER_PARAM_TYPE_FLOAT, "0", "Far blur plane depth" )
SHADER_PARAM( NEARBLURRADIUS, SHADER_PARAM_TYPE_FLOAT, "0", "Max near blur radius" )
SHADER_PARAM( FARBLURRADIUS, SHADER_PARAM_TYPE_FLOAT, "0", "Max far blur radius" )
SHADER_PARAM( QUALITY, SHADER_PARAM_TYPE_INTEGER, "0", "Quality level. Selects different algorithms." )
END_SHADER_PARAMS
SHADER_INIT_PARAMS()
{
SET_PARAM_STRING_IF_NOT_DEFINED( SMALLFB, "_rt_SmallFB1" );
SET_PARAM_FLOAT_IF_NOT_DEFINED( NEARPLANE, 0.0f );
SET_PARAM_FLOAT_IF_NOT_DEFINED( FARPLANE, 0.0f );
SET_PARAM_FLOAT_IF_NOT_DEFINED( NEARBLURDEPTH, 0.0f );
SET_PARAM_FLOAT_IF_NOT_DEFINED( NEARFOCUSDEPTH, 0.0f );
SET_PARAM_FLOAT_IF_NOT_DEFINED( FARFOCUSDEPTH, 0.0f );
SET_PARAM_FLOAT_IF_NOT_DEFINED( FARBLURDEPTH, 0.0f );
SET_PARAM_FLOAT_IF_NOT_DEFINED( NEARBLURRADIUS, 0.0f );
SET_PARAM_FLOAT_IF_NOT_DEFINED( FARBLURRADIUS, 0.0f );
SET_PARAM_INT_IF_NOT_DEFINED( QUALITY, 0 );
}
SHADER_FALLBACK
{
if ( g_pHardwareConfig->GetDXSupportLevel() < 92 )
{
return "Wireframe";
}
return 0;
}
SHADER_INIT
{
if ( params[BASETEXTURE]->IsDefined() )
{
LoadTexture( BASETEXTURE );
}
if ( params[SMALLFB]->IsDefined() )
{
LoadTexture( SMALLFB );
}
}
SHADER_DRAW
{
SHADOW_STATE
{
pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false );
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false );
pShaderShadow->EnableSRGBWrite( false );
DECLARE_STATIC_VERTEX_SHADER( depth_of_field_vs20 );
SET_STATIC_VERTEX_SHADER( depth_of_field_vs20 );
if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( depth_of_field_ps20b );
SET_STATIC_PIXEL_SHADER( depth_of_field_ps20b );
}
else
{
Assert( !"No ps_2_b. This shouldn't be happening" );
}
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableAlphaWrites( false );
}
DYNAMIC_STATE
{
DECLARE_DYNAMIC_VERTEX_SHADER( depth_of_field_vs20 );
SET_DYNAMIC_VERTEX_SHADER( depth_of_field_vs20 );
// Bind textures
BindTexture( SHADER_SAMPLER0, BASETEXTURE );
BindTexture( SHADER_SAMPLER1, SMALLFB );
// near blur = blur of stuff in front of focus range
// far blur = blur of stuff behind focus range
// C0: set near/far blur and focus distances
// x = near blur distance
// y = near focus distance
// z = far focus distance
// w = far blur distance
// C1:
// x = blur radius for near blur (in pixels)
// y = blur radius for far blur (in pixels)
// TODO: Specifying this stuff in pixels makes blurs look smaller on high backbuffer resolutions.
// This might be a problem for tweaking these values.
float vConst[16] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
vConst[0] = params[NEARBLURDEPTH]->GetFloatValue();
vConst[1] = params[NEARFOCUSDEPTH]->GetFloatValue();
vConst[2] = params[FARFOCUSDEPTH]->GetFloatValue();
vConst[3] = params[FARBLURDEPTH]->GetFloatValue();;
// max blur radius will need to be set based on qulity level and screen res
vConst[4] = mat_dof_max_blur_radius.GetFloat();
vConst[5] = MIN( params[NEARBLURRADIUS]->GetFloatValue(), vConst[4] ) / vConst[4]; // near and far blur radius as fraction of max radius
vConst[6] = MIN( params[FARBLURRADIUS]->GetFloatValue(), vConst[4] ) / vConst[4];
vConst[8] = params[NEARPLANE]->GetFloatValue();
vConst[9] = params[FARPLANE]->GetFloatValue();
// 8192 is the magic number for HDR mode 3 (see FLOAT_RENDERPARM_DEST_ALPHA_DEPTH_SCALE in shaderapidx8.cpp)
vConst[10] = 8192.0f * ( vConst[9] - vConst[8] ) / vConst[9];
vConst[12] = vConst[10] / ( vConst[0] - vConst[1] );
vConst[13] = ( vConst[8] - vConst[1] ) / ( vConst[0] - vConst[1] );
vConst[14] = vConst[10] / ( vConst[3] - vConst[2] );
vConst[15] = ( vConst[8] - vConst[2] ) / ( vConst[3] - vConst[2] );
pShaderAPI->SetPixelShaderConstant( 0, vConst, 4 );
// set up poisson sample location constants pre-divided by screen res
int nNumPoissonSamples = 0;
const float *pPoissonSrc = NULL;
switch ( params[QUALITY]->GetIntValue() )
{
case 0:
// NOTE: These must match the shader
nNumPoissonSamples = 8;
pPoissonSrc = s_flPoissonConstsQuality0;
break;
case 1:
case 2:
nNumPoissonSamples = 16;
pPoissonSrc = s_flPoissonConstsQuality1;
break;
case 3:
nNumPoissonSamples = 32;
pPoissonSrc = s_flPoissonConstsQuality2;
break;
default:
Warning( "Invalid mat_dof_quality value. Resetting to 0.\n" );
mat_dof_quality.SetValue( 0 );
nNumPoissonSamples = 8;
pPoissonSrc = s_flPoissonConstsQuality0;
break;
}
float vPoissonConst[64]; // temp table
// Get texture dimensions
ITexture *pTex = params[BASETEXTURE]->GetTextureValue();
Assert( pTex );
float flInvTexWidth = 1.0f / static_cast<float>( pTex->GetActualWidth() );
float flInvTexHeight = 1.0f / static_cast<float>( pTex->GetActualHeight() );
for ( int i = 0; i < nNumPoissonSamples; i++ )
{
vPoissonConst[ 2*i ] = pPoissonSrc[ 2*i ] * flInvTexWidth;
vPoissonConst[ 2*i+1 ] = pPoissonSrc[ 2*i+1 ] * flInvTexHeight;
}
// swizzle every other 2-tuple so that I can use the free .wz swizzle in the shader
for ( int i = 1; i < nNumPoissonSamples; i += 2)
{
float t = vPoissonConst[ 2*i ];
vPoissonConst[ 2*i ] = vPoissonConst[ 2*i+1 ];
vPoissonConst[ 2*i+1 ] = t;
}
pShaderAPI->SetPixelShaderConstant( 4, vPoissonConst, nNumPoissonSamples / 2 );
if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( depth_of_field_ps20b );
SET_DYNAMIC_PIXEL_SHADER_COMBO( QUALITY, params[QUALITY]->GetIntValue() );
SET_DYNAMIC_PIXEL_SHADER( depth_of_field_ps20b );
}
else
{
Assert( !"No ps_2_b. This shouldn't be happening" );
}
}
Draw();
}
END_SHADER

View File

@ -0,0 +1,105 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#include "BaseVSShader.h"
#include "common_hlsl_cpp_consts.h"
#include "downsample_ps20.inc"
#include "downsample_ps20b.inc"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
BEGIN_VS_SHADER_FLAGS( Downsample, "Help for Downsample", SHADER_NOT_EDITABLE )
BEGIN_SHADER_PARAMS
END_SHADER_PARAMS
SHADER_INIT
{
LoadTexture( BASETEXTURE );
}
SHADER_FALLBACK
{
return 0;
}
SHADER_DRAW
{
SHADOW_STATE
{
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableAlphaWrites( true );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false );
pShaderShadow->EnableSRGBWrite( false );
int fmt = VERTEX_POSITION;
pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 );
pShaderShadow->SetVertexShader( "Downsample_vs20", 0 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( downsample_ps20b );
SET_STATIC_PIXEL_SHADER( downsample_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( downsample_ps20 );
SET_STATIC_PIXEL_SHADER( downsample_ps20 );
}
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 );
int width, height;
pShaderAPI->GetBackBufferDimensions( width, height );
float v[4];
float dX = 1.0f / width;
float dY = 1.0f / height;
v[0] = -dX;
v[1] = -dY;
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, v, 1 );
v[0] = -dX;
v[1] = dY;
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, v, 1 );
v[0] = dX;
v[1] = -dY;
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, v, 1 );
v[0] = dX;
v[1] = dY;
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, v, 1 );
// Setup luminance threshold (all values are scaled down by max luminance)
// v[0] = 1.0f / MAX_HDR_OVERBRIGHT;
v[0] = 0.0f;
pShaderAPI->SetPixelShaderConstant( 0, v, 1 );
pShaderAPI->SetVertexShaderIndex( 0 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( downsample_ps20b );
SET_DYNAMIC_PIXEL_SHADER( downsample_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( downsample_ps20 );
SET_DYNAMIC_PIXEL_SHADER( downsample_ps20 );
}
}
Draw();
}
END_SHADER

View File

@ -0,0 +1,78 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// STATIC: "BLOOMTYPE" "0..1"
// DYNAMIC: "FLOAT_BACK_BUFFER" "0..1" [ps20b] [ps30] [PC]
// DYNAMIC: "FLOAT_BACK_BUFFER" "0..0" [ps20b] [XBOX]
#include "common_ps_fxc.h"
sampler TexSampler : register( s0 );
float4 params : register( c0 );
float4 params2 : register( c1 );
#define g_flBloomExp params2.x
#define g_flBloomSaturation params2.y
struct PS_INPUT
{
float2 coordTap0 : TEXCOORD0;
float2 coordTap1 : TEXCOORD1;
float2 coordTap2 : TEXCOORD2;
float2 coordTap3 : TEXCOORD3;
};
float4 Shape( float4 cColor )
{
#if ( BLOOMTYPE == 0 )
{
float flLum = dot( cColor.xyz, params.xyz );
cColor.rgb = pow( cColor.xyz, params.w ) * flLum;
}
#endif
#if ( BLOOMTYPE == 1 )
{
float flScale = 1.55f; // Color scale
float flBias = -0.09f; // Color bias
float flBrightnessClamp = 0.59f; // After scale and bias, clamp RGB values brighter than this
float flExp = g_flBloomExp;
cColor.rgb = pow( saturate( min( flBrightnessClamp, ( cColor.rgb * flScale ) + flBias ) ), flExp );
}
#endif
return cColor;
}
float4 main( PS_INPUT i ) : COLOR
{
float4 s0, s1, s2, s3;
// Sample 4 taps
s0 = tex2D( TexSampler, i.coordTap0 );
s1 = tex2D( TexSampler, i.coordTap1 );
s2 = tex2D( TexSampler, i.coordTap2 );
s3 = tex2D( TexSampler, i.coordTap3 );
#if ( FLOAT_BACK_BUFFER == 1 )
{
// for float HDR mode, match the color space of the int render pass, to get identical bloom results
s0.rgb = SrgbLinearToGamma( saturate( s0.rgb ) );
s1.rgb = SrgbLinearToGamma( saturate( s1.rgb ) );
s2.rgb = SrgbLinearToGamma( saturate( s2.rgb ) );
s3.rgb = SrgbLinearToGamma( saturate( s3.rgb ) );
}
#endif
float4 avgColor = ( s0 + s1 + s2 + s3 ) * 0.25f;
float fAvgLuminance = dot( avgColor.rgb, float3( 0.299, 0.587, 0.114 ) );
avgColor = Shape( avgColor );
// Saturation
#if ( BLOOMTYPE == 1 )
{
avgColor.rgb = lerp( dot( params.rgb, avgColor.rgb ), avgColor.rgb, g_flBloomSaturation );
}
#endif
avgColor.a = fAvgLuminance;
return FinalOutput( avgColor, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
}

View File

@ -0,0 +1,30 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
#include "common_ps_fxc.h"
sampler TexSampler : register( s0 );
struct PS_INPUT
{
float2 coordTap0 : TEXCOORD0;
float2 coordTap1 : TEXCOORD1;
float2 coordTap2 : TEXCOORD2;
float2 coordTap3 : TEXCOORD3;
};
float4 main( PS_INPUT i ) : COLOR
{
float4 s0, s1, s2, s3;
// Sample 4 taps
s0 = tex2D( TexSampler, i.coordTap0 );
s1 = tex2D( TexSampler, i.coordTap1 );
s2 = tex2D( TexSampler, i.coordTap2 );
s3 = tex2D( TexSampler, i.coordTap3 );
// store grayscale version of buffer in alpha
float4 vResult = ( s0 + s1 + s2 + s3 ) * 0.25f;
vResult.a = dot( float3( 0.3f, 0.59f, 0.11f ), vResult.rgb );
return vResult;
}

View File

@ -0,0 +1,34 @@
#include "common_vs_fxc.h"
struct VS_INPUT
{
float3 vPos : POSITION;
float2 vBaseTexCoord : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 projPos : POSITION;
float2 coordTap0 : TEXCOORD0;
float2 coordTap1 : TEXCOORD1;
float2 coordTap2 : TEXCOORD2;
float2 coordTap3 : TEXCOORD3;
};
float2 vsTapOffs[4] : register ( SHADER_SPECIFIC_CONST_0 );
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
o.projPos = float4( v.vPos, 1.0f );
o.coordTap0 = v.vBaseTexCoord + vsTapOffs[0];
o.coordTap1 = v.vBaseTexCoord + vsTapOffs[1];
o.coordTap2 = v.vBaseTexCoord + vsTapOffs[2];
o.coordTap3 = v.vBaseTexCoord + vsTapOffs[3];
return o;
}

View File

@ -0,0 +1,658 @@
//========= Copyright <20> 1996-2007, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "basevsshader.h"
#include "screenspaceeffect_vs20.inc"
#include "Engine_Post_ps20.inc"
#include "Engine_Post_ps20b.inc"
#include "..\materialsystem_global.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
ConVar mat_screen_blur_override( "mat_screen_blur_override", "-1.0" );
ConVar mat_depth_blur_focal_distance_override( "mat_depth_blur_focal_distance_override", "-1.0" );
ConVar mat_depth_blur_strength_override( "mat_depth_blur_strength_override", "-1.0" );
ConVar mat_grain_scale_override( "mat_grain_scale_override", "-1.0" );
ConVar mat_local_contrast_scale_override( "mat_local_contrast_scale_override", "0.0" );
ConVar mat_local_contrast_midtone_mask_override( "mat_local_contrast_midtone_mask_override", "-1.0" );
ConVar mat_local_contrast_vignette_start_override( "mat_local_contrast_vignette_start_override", "-1.0" );
ConVar mat_local_contrast_vignette_end_override( "mat_local_contrast_vignette_end_override", "-1.0" );
ConVar mat_local_contrast_edge_scale_override( "mat_local_contrast_edge_scale_override", "-1000.0" );
DEFINE_FALLBACK_SHADER( Engine_Post, Engine_Post_dx9 )
BEGIN_VS_SHADER_FLAGS( Engine_Post_dx9, "Engine post-processing effects (software anti-aliasing, bloom, color-correction", SHADER_NOT_EDITABLE )
BEGIN_SHADER_PARAMS
SHADER_PARAM( FBTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_FullFrameFB", "Full framebuffer texture" )
SHADER_PARAM( AAENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable software anti-aliasing" )
SHADER_PARAM( AAINTERNAL1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0]", "Internal anti-aliasing values set via material proxy" )
SHADER_PARAM( AAINTERNAL2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0]", "Internal anti-aliasing values set via material proxy" )
SHADER_PARAM( AAINTERNAL3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0]", "Internal anti-aliasing values set via material proxy" )
SHADER_PARAM( BLOOMENABLE, SHADER_PARAM_TYPE_BOOL, "1", "Enable bloom" )
SHADER_PARAM( BLOOMAMOUNT, SHADER_PARAM_TYPE_FLOAT, "1.0", "Bloom scale factor" )
SHADER_PARAM( SCREENEFFECTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "used for paint or vomit screen effect" )
SHADER_PARAM( DEPTHBLURENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Inexpensive depth-of-field substitute" )
SHADER_PARAM( ALLOWVIGNETTE, SHADER_PARAM_TYPE_BOOL, "0", "Allow vignette" )
SHADER_PARAM( VIGNETTEENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable vignette" )
SHADER_PARAM( INTERNAL_VIGNETTETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "dev/vignette", "" )
SHADER_PARAM( ALLOWNOISE, SHADER_PARAM_TYPE_BOOL, "0", "Allow noise" )
SHADER_PARAM( NOISEENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable noise" )
SHADER_PARAM( NOISESCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Noise scale" )
SHADER_PARAM( NOISETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Noise texture" )
SHADER_PARAM( ALLOWLOCALCONTRAST, SHADER_PARAM_TYPE_BOOL, "0", "Enable local contrast enhancement" )
SHADER_PARAM( LOCALCONTRASTENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable local contrast enhancement" )
SHADER_PARAM( LOCALCONTRASTSCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Local contrast scale" )
SHADER_PARAM( LOCALCONTRASTMIDTONEMASK, SHADER_PARAM_TYPE_FLOAT, "0", "Local contrast midtone mask" )
SHADER_PARAM( LOCALCONTRASTVIGNETTESTART, SHADER_PARAM_TYPE_BOOL, "0", "Enable local contrast enhancement" )
SHADER_PARAM( LOCALCONTRASTVIGNETTEEND, SHADER_PARAM_TYPE_FLOAT, "0", "Local contrast scale" )
SHADER_PARAM( LOCALCONTRASTEDGESCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Local contrast midtone mask" )
SHADER_PARAM( BLURREDVIGNETTEENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable blurred vignette" )
SHADER_PARAM( BLURREDVIGNETTESCALE, SHADER_PARAM_TYPE_FLOAT, "0", "blurred vignette strength" )
SHADER_PARAM( FADETOBLACKSCALE, SHADER_PARAM_TYPE_FLOAT, "0", "fade strength" )
SHADER_PARAM( DEPTHBLURFOCALDISTANCE, SHADER_PARAM_TYPE_FLOAT, "0", "Distance in dest-alpha space [0,1] of focal plane." )
SHADER_PARAM( DEPTHBLURSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "0", "Strength of depth-blur effect" )
SHADER_PARAM( SCREENBLURSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "0", "Full-screen blur factor" )
SHADER_PARAM( VOMITCOLOR1, SHADER_PARAM_TYPE_VEC3, "[0 0 0 0]", "1st vomit blend color" )
SHADER_PARAM( VOMITCOLOR2, SHADER_PARAM_TYPE_VEC3, "[0 0 0 0]", "2st vomit blend color" )
SHADER_PARAM( VOMITREFRACTSCALE, SHADER_PARAM_TYPE_FLOAT, "0.15", "vomit refract strength" )
SHADER_PARAM( VOMITENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable vomit refract" )
SHADER_PARAM( FADECOLOR, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0]", "viewfade color" )
SHADER_PARAM( FADE, SHADER_PARAM_TYPE_INTEGER, "0", "fade type. 0 = off, 1 = lerp, 2 = modulate" )
SHADER_PARAM( TV_GAMMA, SHADER_PARAM_TYPE_INTEGER, "0", "0 default, 1 used for laying off 360 movies" )
SHADER_PARAM( DESATURATEENABLE, SHADER_PARAM_TYPE_INTEGER, "0", "Desaturate with math, turns off color correction" )
SHADER_PARAM( DESATURATION, SHADER_PARAM_TYPE_FLOAT, "0", "Desaturation Amount" )
// Tool color correction setup
SHADER_PARAM( TOOLMODE, SHADER_PARAM_TYPE_BOOL, "1", "tool mode" )
SHADER_PARAM( TOOLCOLORCORRECTION, SHADER_PARAM_TYPE_FLOAT, "1", "tool color correction override" )
SHADER_PARAM( WEIGHT_DEFAULT, SHADER_PARAM_TYPE_FLOAT, "1", "weight default" )
SHADER_PARAM( WEIGHT0, SHADER_PARAM_TYPE_FLOAT, "1", "weight0" )
SHADER_PARAM( WEIGHT1, SHADER_PARAM_TYPE_FLOAT, "1", "weight1" )
SHADER_PARAM( WEIGHT2, SHADER_PARAM_TYPE_FLOAT, "1", "weight2" )
SHADER_PARAM( WEIGHT3, SHADER_PARAM_TYPE_FLOAT, "1", "weight3" )
SHADER_PARAM( NUM_LOOKUPS, SHADER_PARAM_TYPE_FLOAT, "0", "num_lookups" )
SHADER_PARAM( TOOLTIME, SHADER_PARAM_TYPE_FLOAT, "0", "tooltime" )
END_SHADER_PARAMS
SHADER_INIT_PARAMS()
{
if ( !params[ INTERNAL_VIGNETTETEXTURE ]->IsDefined() )
{
params[ INTERNAL_VIGNETTETEXTURE ]->SetStringValue( "dev/vignette" );
}
if ( !params[ AAENABLE ]->IsDefined() )
{
params[ AAENABLE ]->SetIntValue( 0 );
}
if ( !params[ AAINTERNAL1 ]->IsDefined() )
{
params[ AAINTERNAL1 ]->SetVecValue( 0, 0, 0, 0 );
}
if ( !params[ AAINTERNAL2 ]->IsDefined() )
{
params[ AAINTERNAL2 ]->SetVecValue( 0, 0, 0, 0 );
}
if ( !params[ AAINTERNAL3 ]->IsDefined() )
{
params[ AAINTERNAL3 ]->SetVecValue( 0, 0, 0, 0 );
}
if ( !params[ BLOOMENABLE ]->IsDefined() )
{
params[ BLOOMENABLE ]->SetIntValue( 1 );
}
if ( !params[ BLOOMAMOUNT ]->IsDefined() )
{
params[ BLOOMAMOUNT ]->SetFloatValue( 1.0f );
}
if ( !params[ DEPTHBLURENABLE ]->IsDefined() )
{
params[ DEPTHBLURENABLE ]->SetIntValue( 0 );
}
if ( !params[ ALLOWNOISE ]->IsDefined() )
{
params[ ALLOWNOISE ]->SetIntValue( 1 );
}
if ( !params[ NOISESCALE ]->IsDefined() )
{
params[ NOISESCALE ]->SetFloatValue( 1.0f );
}
if ( !params[ NOISEENABLE ]->IsDefined() )
{
params[ NOISEENABLE ]->SetIntValue( 0 );
}
if ( !params[ ALLOWVIGNETTE ]->IsDefined() )
{
params[ ALLOWVIGNETTE ]->SetIntValue( 1 );
}
if ( !params[ VIGNETTEENABLE ]->IsDefined() )
{
params[ VIGNETTEENABLE ]->SetIntValue( 0 );
}
if ( !params[ ALLOWLOCALCONTRAST ]->IsDefined() )
{
params[ ALLOWLOCALCONTRAST ]->SetIntValue( 1 );
}
if ( !params[ LOCALCONTRASTSCALE ]->IsDefined() )
{
params[ LOCALCONTRASTSCALE ]->SetFloatValue( 1.0f );
}
if ( !params[ LOCALCONTRASTMIDTONEMASK ]->IsDefined() )
{
params[ LOCALCONTRASTMIDTONEMASK ]->SetFloatValue( 1000.0f );
}
if ( !params[ LOCALCONTRASTENABLE ]->IsDefined() )
{
params[ LOCALCONTRASTENABLE ]->SetIntValue( 0 );
}
if ( !params[ LOCALCONTRASTVIGNETTESTART ]->IsDefined() )
{
params[ LOCALCONTRASTVIGNETTESTART ]->SetFloatValue( 0.7f );
}
if ( !params[ LOCALCONTRASTVIGNETTEEND ]->IsDefined() )
{
params[ LOCALCONTRASTVIGNETTEEND ]->SetFloatValue( 1.0f );
}
if ( !params[ LOCALCONTRASTEDGESCALE ]->IsDefined() )
{
params[ LOCALCONTRASTEDGESCALE ]->SetFloatValue( 0.0f );
}
if ( !params[ BLURREDVIGNETTEENABLE ]->IsDefined() )
{
params[ BLURREDVIGNETTEENABLE ]->SetIntValue( 0 );
}
if ( !params[ BLURREDVIGNETTESCALE ]->IsDefined() )
{
params[ BLURREDVIGNETTESCALE ]->SetFloatValue( 0.0f );
}
if ( !params[ FADETOBLACKSCALE ]->IsDefined() )
{
params[ FADETOBLACKSCALE ]->SetFloatValue( 0.0f );
}
if ( !params[ DEPTHBLURFOCALDISTANCE ]->IsDefined() )
{
params[ DEPTHBLURFOCALDISTANCE ]->SetFloatValue( 0.0f );
}
if ( !params[ DEPTHBLURSTRENGTH ]->IsDefined() )
{
params[ DEPTHBLURSTRENGTH ]->SetFloatValue( 0.0f );
}
if ( !params[ SCREENBLURSTRENGTH ]->IsDefined() )
{
params[ SCREENBLURSTRENGTH ]->SetFloatValue( 0.0f );
}
if ( !params[ TOOLMODE ]->IsDefined() )
{
params[ TOOLMODE ]->SetIntValue( 0 );
}
if ( !params[ TOOLCOLORCORRECTION ]->IsDefined() )
{
params[ TOOLCOLORCORRECTION ]->SetFloatValue( 0.0f );
}
if ( !params[ VOMITENABLE ]->IsDefined() )
{
params[ VOMITENABLE ]->SetIntValue( 0 );
}
if ( !params[ VOMITREFRACTSCALE ]->IsDefined() )
{
params[ VOMITREFRACTSCALE ]->SetFloatValue( 0.15f );
}
if ( !params[ VOMITCOLOR1 ]->IsDefined() )
{
params[ VOMITCOLOR1 ]->SetVecValue( 1.0, 1.0, 0.0 );
}
if ( !params[ VOMITCOLOR2 ]->IsDefined() )
{
params[ VOMITCOLOR2 ]->SetVecValue( 0.0, 1.0, 0.0 );
}
if ( !params[ FADE ]->IsDefined() )
{
params[ FADE ]->SetIntValue( 0 );
}
if ( !params[ FADECOLOR ]->IsDefined() )
{
params[ FADECOLOR ]->SetVecValue( 0.0f, 0.0f, 0.0f, 0.0f );
}
if ( !params[ TV_GAMMA ]->IsDefined() )
{
params[ TV_GAMMA ]->SetIntValue( 0 );
}
if ( !params[ DESATURATEENABLE ]->IsDefined() )
{
params[ DESATURATEENABLE ]->SetIntValue( 0 );
}
if ( !params[ DESATURATION ]->IsDefined() )
{
params[ DESATURATION ]->SetFloatValue( 0.0f );
}
SET_FLAGS2( MATERIAL_VAR2_NEEDS_FULL_FRAME_BUFFER_TEXTURE );
}
SHADER_FALLBACK
{
// This shader should not be *used* unless we're >= DX9 (bloomadd.vmt/screenspace_general_dx8 should be used for DX8)
return 0;
}
SHADER_INIT
{
if ( params[BASETEXTURE]->IsDefined() )
{
LoadTexture( BASETEXTURE );
}
if ( params[FBTEXTURE]->IsDefined() )
{
LoadTexture( FBTEXTURE );
}
if ( params[SCREENEFFECTTEXTURE]->IsDefined() )
{
LoadTexture( SCREENEFFECTTEXTURE );
}
if ( params[NOISETEXTURE]->IsDefined() )
{
LoadTexture( NOISETEXTURE );
}
if ( params[INTERNAL_VIGNETTETEXTURE]->IsDefined() )
{
LoadTexture( INTERNAL_VIGNETTETEXTURE );
}
}
SHADER_DRAW
{
bool bToolMode = params[TOOLMODE]->GetIntValue() != 0;
bool bDepthBlurEnable = params[ DEPTHBLURENABLE ]->GetIntValue() != 0;
SHADOW_STATE
{
// This shader uses opaque blending, but needs to match the behaviour of bloom_add/screen_spacegeneral,
// which uses additive blending (and is used when bloom is enabled but col-correction and AA are not).
// BUT!
// Hardware sRGB blending is incorrect (on pre-DX10 cards, sRGB values are added directly).
// SO...
// When doing the bloom addition in the pixel shader, we need to emulate that incorrect
// behaviour - by turning sRGB read OFF for the FB texture and by turning sRGB write OFF
// (which is fine, since the AA process works better on an sRGB framebuffer than a linear
// one; gamma colours more closely match luminance perception. The color-correction process
// has always taken gamma-space values as input anyway).
pShaderShadow->EnableBlending( false );
// The (sRGB) bloom texture is bound to sampler 0
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false );
pShaderShadow->EnableSRGBWrite( false );
// The (sRGB) full framebuffer texture is bound to sampler 1:
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false );
// Up to 4 (sRGB) color-correction lookup textures are bound to samplers 2-5:
pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER4, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER5, true );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, false );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, false );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, false );
// Noise
pShaderShadow->EnableTexture( SHADER_SAMPLER6, true );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, false );
// Vignette
pShaderShadow->EnableTexture( SHADER_SAMPLER7, true );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER7, false );
// Screen effect texture
pShaderShadow->EnableTexture( SHADER_SAMPLER8, true );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, false );
pShaderShadow->EnableSRGBWrite( false );
int format = VERTEX_POSITION;
int numTexCoords = 1;
int * pTexCoordDimensions = NULL;
int userDataSize = 0;
pShaderShadow->VertexShaderVertexFormat( format, numTexCoords, pTexCoordDimensions, userDataSize );
DECLARE_STATIC_VERTEX_SHADER( screenspaceeffect_vs20 );
SET_STATIC_VERTEX_SHADER( screenspaceeffect_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( engine_post_ps20b );
SET_STATIC_PIXEL_SHADER_COMBO( TOOL_MODE, bToolMode );
SET_STATIC_PIXEL_SHADER_COMBO( DEPTH_BLUR_ENABLE, bDepthBlurEnable );
SET_STATIC_PIXEL_SHADER( engine_post_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( engine_post_ps20 );
SET_STATIC_PIXEL_SHADER_COMBO( TOOL_MODE, bToolMode );
SET_STATIC_PIXEL_SHADER_COMBO( DEPTH_BLUR_ENABLE, false );
SET_STATIC_PIXEL_SHADER( engine_post_ps20 );
}
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 );
// FIXME: need to set FBTEXTURE to be point-sampled (will speed up this shader significantly on 360)
// and assert that it's set to SHADER_TEXWRAPMODE_CLAMP (since the shader will sample offscreen)
BindTexture( SHADER_SAMPLER1, FBTEXTURE, -1 );
ShaderColorCorrectionInfo_t ccInfo = { false, 0, 1.0f, { 1.0f, 1.0f, 1.0f, 1.0f } };
float flTime;
if ( bToolMode )
{
flTime = params[TOOLTIME]->GetFloatValue();
}
else
{
flTime = pShaderAPI->CurrentTime();
}
// PC, ps20b has a desaturation control that overrides color correction
bool bDesaturateEnable = bToolMode && ( params[DESATURATEENABLE]->GetIntValue() != 0 ) && g_pHardwareConfig->SupportsPixelShaders_2_b() && IsPC();
float vPsConst16[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
vPsConst16[0] = params[ DESATURATION ]->GetFloatValue();
vPsConst16[1] = ( params[FADE]->GetIntValue() == 2 ) ? 1.0f : 0.0f; // Enable lerping to ( color * fadecolor ) for FADE_COLOR=2
pShaderAPI->SetPixelShaderConstant( 16, vPsConst16, 1 );
if ( params[FADE]->GetIntValue() == 0 )
{
// Not fading, so set the constant to cause nothing to change about the pixel color
float vConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
pShaderAPI->SetPixelShaderConstant( 15, vConst );
}
else
{
pShaderAPI->SetPixelShaderConstant( 15, params[ FADECOLOR ]->GetVecValue(), 1 );
}
if ( !bDesaturateEnable ) // set up color correction
{
bool bToolColorCorrection = params[TOOLCOLORCORRECTION]->GetIntValue() != 0;
if ( bToolColorCorrection )
{
ccInfo.m_bIsEnabled = true;
ccInfo.m_nLookupCount = (int) params[NUM_LOOKUPS]->GetFloatValue();
ccInfo.m_flDefaultWeight = params[WEIGHT_DEFAULT]->GetFloatValue();
ccInfo.m_pLookupWeights[0] = params[WEIGHT0]->GetFloatValue();
ccInfo.m_pLookupWeights[1] = params[WEIGHT1]->GetFloatValue();
ccInfo.m_pLookupWeights[2] = params[WEIGHT2]->GetFloatValue();
ccInfo.m_pLookupWeights[3] = params[WEIGHT3]->GetFloatValue();
}
else
{
pShaderAPI->GetCurrentColorCorrection( &ccInfo );
}
}
int colCorrectNumLookups = MIN( ccInfo.m_nLookupCount, 3 );
for ( int i = 0; i < colCorrectNumLookups; i++ )
{
pShaderAPI->BindStandardTexture( (Sampler_t)(SHADER_SAMPLER2 + i), (StandardTextureId_t)(TEXTURE_COLOR_CORRECTION_VOLUME_0 + i) );
}
// Upload 1-pixel X&Y offsets [ (+dX,0,+dY,-dX) is chosen to work with the allowed ps20 swizzles ]
// The shader will sample in a cross (up/down/left/right from the current sample), for 5-tap
// (quality 0) mode and add another 4 samples in a diagonal cross, for 9-tap (quality 1) mode
ITexture * pTarget = params[FBTEXTURE]->GetTextureValue();
int width = pTarget->GetActualWidth();
int height = pTarget->GetActualHeight();
float dX = 1.0f / width;
float dY = 1.0f / height;
float offsets[4] = { +dX, 0, +dY, -dX };
pShaderAPI->SetPixelShaderConstant( 0, &offsets[0], 1 );
// Upload AA tweakables:
// x - strength (this can be used to toggle the AA off, or to weaken it where pathological cases are showing)
// y - reduction of 1-pixel-line blurring (blurring of 1-pixel lines causes issues, so it's tunable)
// z - edge threshold multiplier (default 1.0, < 1.0 => more edges softened, > 1.0 => fewer edges softened)
// w - tap offset multiplier (default 1.0, < 1.0 => sharper image, > 1.0 => blurrier image)
float tweakables[4] = { params[ AAINTERNAL1 ]->GetVecValue()[0],
params[ AAINTERNAL1 ]->GetVecValue()[1],
params[ AAINTERNAL3 ]->GetVecValue()[0],
params[ AAINTERNAL3 ]->GetVecValue()[1] };
pShaderAPI->SetPixelShaderConstant( 1, &tweakables[0], 1 );
// Upload AA UV transform (converts bloom texture UVs to framebuffer texture UVs)
// NOTE: we swap the order of the z and w components since 'wz' is an allowed ps20 swizzle, but 'zw' is not:
float uvTrans[4] = { params[ AAINTERNAL2 ]->GetVecValue()[0],
params[ AAINTERNAL2 ]->GetVecValue()[1],
params[ AAINTERNAL2 ]->GetVecValue()[3],
params[ AAINTERNAL2 ]->GetVecValue()[2] };
pShaderAPI->SetPixelShaderConstant( 2, &uvTrans[0], 1 );
// Upload color-correction weights:
pShaderAPI->SetPixelShaderConstant( 3, &ccInfo.m_flDefaultWeight );
pShaderAPI->SetPixelShaderConstant( 4, ccInfo.m_pLookupWeights );
int aaEnabled = ( IsX360() && ( params[ AAINTERNAL1 ]->GetVecValue()[0] != 0.0f ) ) ? 1 : 0;
int bloomEnabled = ( params[ BLOOMENABLE ]->GetIntValue() == 0 ) ? 0 : 1;
int colCorrectEnabled = ccInfo.m_bIsEnabled;
float flBloomFactor = bloomEnabled ? 1.0f : 0.0f;
flBloomFactor *= params[BLOOMAMOUNT]->GetFloatValue();
float bloomConstant[4] =
{
flBloomFactor,
params[ SCREENBLURSTRENGTH ]->GetFloatValue(),
params[ DEPTHBLURFOCALDISTANCE ]->GetFloatValue(),
params[ DEPTHBLURSTRENGTH ]->GetFloatValue()
};
if ( mat_screen_blur_override.GetFloat() >= 0.0f )
{
bloomConstant[1] = mat_screen_blur_override.GetFloat();
}
if ( mat_depth_blur_focal_distance_override.GetFloat() >= 0.0f )
{
bloomConstant[2] = mat_depth_blur_focal_distance_override.GetFloat();
}
#ifdef _X360
bloomConstant[3] = 0.0f; // Depth blur is currently broken on X360 because we're not writing out the depth scale properly
#else // !_X360
if ( mat_depth_blur_strength_override.GetFloat() >= 0.0f )
{
bloomConstant[3] = mat_depth_blur_strength_override.GetFloat();
}
#endif // _X360
pShaderAPI->SetPixelShaderConstant( 5, bloomConstant );
// Vignette
bool bVignetteEnable = ( params[ VIGNETTEENABLE ]->GetIntValue() != 0 ) && ( params[ ALLOWVIGNETTE ]->GetIntValue() != 0 );
if ( bVignetteEnable )
{
BindTexture( SHADER_SAMPLER7, INTERNAL_VIGNETTETEXTURE );
}
// Noise
bool bNoiseEnable = ( params[ NOISEENABLE ]->GetIntValue() != 0 ) && ( params[ ALLOWNOISE ]->GetIntValue() != 0 );
int nFbTextureHeight = params[FBTEXTURE]->GetTextureValue()->GetActualHeight();
if ( nFbTextureHeight < 720 )
{
// Disable noise at low resolutions
bNoiseEnable = false;
}
if ( bNoiseEnable )
{
BindTexture( SHADER_SAMPLER6, NOISETEXTURE );
// Noise scale
float vPsConst6[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
vPsConst6[0] = params[ NOISESCALE ]->GetFloatValue();
if ( mat_grain_scale_override.GetFloat() != -1.0f )
{
vPsConst6[0] = mat_grain_scale_override.GetFloat();
}
if ( IsX360() )
{
vPsConst6[0] *= 0.15f;
}
if ( vPsConst6[0] <= 0.0f )
{
bNoiseEnable = false;
}
pShaderAPI->SetPixelShaderConstant( 6, vPsConst6 );
// Time % 1000 for scrolling
float vPsConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
vPsConst[0] = flTime;
vPsConst[0] -= (float)( (int)( vPsConst[0] / 1000.0f ) ) * 1000.0f;
pShaderAPI->SetPixelShaderConstant( 7, vPsConst, 1 );
}
// Local Contrast
bool bLocalContrastEnable = ( params[ LOCALCONTRASTENABLE ]->GetIntValue() != 0 ) && ( params[ ALLOWLOCALCONTRAST ]->GetIntValue() != 0 );
bool bBlurredVignetteEnable = ( bLocalContrastEnable ) && ( params[ BLURREDVIGNETTEENABLE ]->GetIntValue() != 0 );
if ( bLocalContrastEnable )
{
// Contrast scale
float vPsConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
vPsConst[0] = params[ LOCALCONTRASTSCALE ]->GetFloatValue();
if ( mat_local_contrast_scale_override.GetFloat() != 0.0f )
{
vPsConst[0] = mat_local_contrast_scale_override.GetFloat();
}
vPsConst[1] = params[ LOCALCONTRASTMIDTONEMASK ]->GetFloatValue();
if ( mat_local_contrast_midtone_mask_override.GetFloat() >= 0.0f )
{
vPsConst[1] = mat_local_contrast_midtone_mask_override.GetFloat();
}
vPsConst[2] = params[ BLURREDVIGNETTESCALE ]->GetFloatValue();
pShaderAPI->SetPixelShaderConstant( 8, vPsConst, 1 );
vPsConst[0] = params[ LOCALCONTRASTVIGNETTESTART ]->GetFloatValue();
if ( mat_local_contrast_vignette_start_override.GetFloat() >= 0.0f )
{
vPsConst[0] = mat_local_contrast_vignette_start_override.GetFloat();
}
vPsConst[1] = params[ LOCALCONTRASTVIGNETTEEND ]->GetFloatValue();
if ( mat_local_contrast_vignette_end_override.GetFloat() >= 0.0f )
{
vPsConst[1] = mat_local_contrast_vignette_end_override.GetFloat();
}
vPsConst[2] = params[ LOCALCONTRASTEDGESCALE ]->GetFloatValue();
if ( mat_local_contrast_edge_scale_override.GetFloat() >= -1.0f )
{
vPsConst[2] = mat_local_contrast_edge_scale_override.GetFloat();
}
pShaderAPI->SetPixelShaderConstant( 9, vPsConst, 1 );
}
// fade to black
float vPsConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
vPsConst[0] = params[ FADETOBLACKSCALE ]->GetFloatValue();
pShaderAPI->SetPixelShaderConstant( 10, vPsConst, 1 );
bool bVomitEnable = ( params[ VOMITENABLE ]->GetIntValue() != 0 );
if ( bVomitEnable )
{
BindTexture( SHADER_SAMPLER8, SCREENEFFECTTEXTURE );
params[ VOMITCOLOR1 ]->GetVecValue( vPsConst, 3 );
vPsConst[3] = params[ VOMITREFRACTSCALE ]->GetFloatValue();
pShaderAPI->SetPixelShaderConstant( 11, vPsConst, 1 );
params[ VOMITCOLOR2 ]->GetVecValue( vPsConst, 3 );
vPsConst[3] = 0.0f;
pShaderAPI->SetPixelShaderConstant( 12, vPsConst, 1 );
// Get viewport and render target dimensions and set shader constant to do a 2D mad
int nViewportX, nViewportY, nViewportWidth, nViewportHeight;
pShaderAPI->GetCurrentViewport( nViewportX, nViewportY, nViewportWidth, nViewportHeight );
int nRtWidth, nRtHeight;
pShaderAPI->GetCurrentRenderTargetDimensions( nRtWidth, nRtHeight );
float vViewportMad[4];
// screen->viewport transform
vViewportMad[0] = ( float )nRtWidth / ( float )nViewportWidth;
vViewportMad[1] = ( float )nRtHeight / ( float )nViewportHeight;
vViewportMad[2] = -( float )nViewportX / ( float )nViewportWidth;
vViewportMad[3] = -( float )nViewportY / ( float )nViewportHeight;
pShaderAPI->SetPixelShaderConstant( 13, vViewportMad, 1 );
// viewport->screen transform
vViewportMad[0] = ( float )nViewportWidth / ( float )nRtWidth;
vViewportMad[1] = ( float )nViewportHeight / ( float )nRtHeight;
vViewportMad[2] = ( float )nViewportX / ( float )nRtWidth;
vViewportMad[3] = ( float )nViewportY / ( float )nRtHeight;
pShaderAPI->SetPixelShaderConstant( 14, vViewportMad, 1 );
}
if ( !colCorrectEnabled )
{
colCorrectNumLookups = 0;
}
bool bConvertFromLinear = ( g_pHardwareConfig->GetHDRType() == HDR_TYPE_FLOAT );
// JasonM - double check this if the SFM needs to use the engine post FX clip in main
bool bConvertToLinear = bToolMode && bConvertFromLinear && ( g_pHardwareConfig->GetHDRType() == HDR_TYPE_FLOAT );
if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( engine_post_ps20b );
SET_DYNAMIC_PIXEL_SHADER_COMBO( AA_ENABLE, aaEnabled );
SET_DYNAMIC_PIXEL_SHADER_COMBO( COL_CORRECT_NUM_LOOKUPS, colCorrectNumLookups );
SET_DYNAMIC_PIXEL_SHADER_COMBO( CONVERT_FROM_LINEAR, bConvertFromLinear );
SET_DYNAMIC_PIXEL_SHADER_COMBO( CONVERT_TO_LINEAR, bConvertToLinear );
SET_DYNAMIC_PIXEL_SHADER_COMBO( NOISE_ENABLE, bNoiseEnable );
SET_DYNAMIC_PIXEL_SHADER_COMBO( VIGNETTE_ENABLE, bVignetteEnable );
SET_DYNAMIC_PIXEL_SHADER_COMBO( LOCAL_CONTRAST_ENABLE, bLocalContrastEnable );
SET_DYNAMIC_PIXEL_SHADER_COMBO( BLURRED_VIGNETTE_ENABLE, bBlurredVignetteEnable );
SET_DYNAMIC_PIXEL_SHADER_COMBO( VOMIT_ENABLE, bVomitEnable );
#ifndef _X360
SET_DYNAMIC_PIXEL_SHADER_COMBO( TV_GAMMA, params[TV_GAMMA]->GetIntValue() && bToolMode ? 1 : 0 );
SET_DYNAMIC_PIXEL_SHADER_COMBO( DESATURATEENABLE, bDesaturateEnable );
#endif
SET_DYNAMIC_PIXEL_SHADER( engine_post_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( engine_post_ps20 );
SET_DYNAMIC_PIXEL_SHADER_COMBO( AA_ENABLE, aaEnabled );
SET_DYNAMIC_PIXEL_SHADER_COMBO( COL_CORRECT_NUM_LOOKUPS, colCorrectNumLookups );
SET_DYNAMIC_PIXEL_SHADER_COMBO( VOMIT_ENABLE, bVomitEnable );
SET_DYNAMIC_PIXEL_SHADER( engine_post_ps20 );
}
DECLARE_DYNAMIC_VERTEX_SHADER( screenspaceeffect_vs20 );
SET_DYNAMIC_VERTEX_SHADER( screenspaceeffect_vs20 );
}
Draw();
}
END_SHADER

View File

@ -0,0 +1,440 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// FIXMEL4DTOMAINMERGE
// Need to re-enable bloom and disable other L4D-only features in here and the cpp file.
// STATIC: "TOOL_MODE" "0..1"
// STATIC: "DEPTH_BLUR_ENABLE" "0..1"
// DYNAMIC: "AA_ENABLE" "0..0" [PC]
// DYNAMIC: "AA_ENABLE" "0..1" [XBOX]
// DYNAMIC: "COL_CORRECT_NUM_LOOKUPS" "0..3"
// DYNAMIC: "CONVERT_FROM_LINEAR" "0..1" [ps20b] [ps30] [PC]
// DYNAMIC: "CONVERT_TO_LINEAR" "0..1" [ps20b] [ps30] [PC]
// DYNAMIC: "CONVERT_FROM_LINEAR" "0..0" [ps20b] [XBOX]
// DYNAMIC: "CONVERT_TO_LINEAR" "0..0" [ps20b] [XBOX]
// SKIP: ( $CONVERT_FROM_LINEAR == 0 ) && ( $CONVERT_TO_LINEAR == 1 )
// SKIP: ( $TOOL_MODE == 0 ) && ( $CONVERT_TO_LINEAR == 1 )
// DYNAMIC: "NOISE_ENABLE" "0..1" [ps20b] [ps30]
// DYNAMIC: "VIGNETTE_ENABLE" "0..1" [ps20b] [ps30]
// DYNAMIC: "LOCAL_CONTRAST_ENABLE" "0..1" [ps20b] [ps30]
// DYNAMIC: "BLURRED_VIGNETTE_ENABLE" "0..1" [ps20b] [ps30]
// DYNAMIC: "VOMIT_ENABLE" "0..1"
// SKIP: ( $LOCAL_CONTRAST_ENABLE == 0 ) && ( $BLURRED_VIGNETTE_ENABLE == 1 )
// DYNAMIC: "TV_GAMMA" "0..1" [ps20b] [PC]
// DYNAMIC: "DESATURATEENABLE" "0..1" [ps20b] [PC]
// SKIP: ( $TOOL_MODE == 0 ) && $TV_GAMMA
// SKIP: ( $TOOL_MODE == 0 ) && $DESATURATEENABLE
#include "common_ps_fxc.h"
sampler BaseTextureSampler : register( s0 );
sampler FBTextureSampler : register( s1 );
sampler ColorCorrectionVolumeTexture0 : register( s2 );
sampler ColorCorrectionVolumeTexture1 : register( s3 );
sampler ColorCorrectionVolumeTexture2 : register( s4 );
sampler ColorCorrectionVolumeTexture3 : register( s5 );
sampler NoiseSampler : register( s6 );
sampler VignetteSampler : register( s7 );
sampler ScreenEffectSampler : register( s8 ); // used for vomit/paint screen particle effects
float4 psTapOffs_Packed : register( c0 ); // psTapOffs_packed contains 1-pixel offsets: ( +dX, 0, +dY, -dX )
float4 tweakables : register( c1 ); // (x - AA strength/unused) (y - reduction of 1-pixel-line blur)
// (z - edge threshold multipler) (w - tap offset multiplier)
float4 uvTransform : register( c2 ); // Transform BaseTexture UVs for use with the FBTexture
float ColorCorrectionDefaultWeight : register( c3 );
float4 ColorCorrectionVolumeWeights : register( c4 );
// Bloom & Depth Blur parameters
// x: bloom amount; multiply bloom downscale buffer by this value and add to base color
// y: bloom lerp amount; lerp between base color and blurred bloom buffer with this factor (allows for color bleeding in dark areas)
// z: depth blur focal plane distance. Value is in dest alpha space [0,1], not world units.
// w: depth blur scale value; scale distance from focal plane by this amount
float4 BloomParameters : register( c5 );
#define g_flBloomAmount ( BloomParameters.x )
#define g_flBloomLerpFactor ( BloomParameters.y )
#define g_flDepthBlurFocalDistance ( BloomParameters.z )
#define g_flDepthBlurScale ( BloomParameters.w )
float g_flNoiseScalar : register( c6 );
float g_flTime : register( c7 );
float4 g_vLocalContrastParams : register( c8 );
#define g_flLocalContrastStrength g_vLocalContrastParams.x
#define g_flLocalContrastMidToneMask g_vLocalContrastParams.y
#define g_flBlurredVignetteStrength g_vLocalContrastParams.z
float4 g_vLocalContrastVignetteParams : register( c9 );
#define g_flLocalContrastVignetteStart g_vLocalContrastVignetteParams.x
#define g_flLocalContrastVignetteEnd g_vLocalContrastVignetteParams.y
#define g_flLocalContrastEdgeStrength g_vLocalContrastVignetteParams.z
float g_flFadeToBlackStrength : register( c10 );
float4 g_vVomitColor[2] : register( c11 );
#define g_flVomitRefractStrength g_vVomitColor[0].a
float4 g_vViewportTransform : register( c13 );
float4 g_vInvViewportTransform : register( c14 );
float4 g_vViewFadeColor : register( c15 );
float2 g_c16 : register( c16 );
#define g_flDesaturation g_c16.x
#define g_flFadeMode2 g_c16.y
float Luminance( float3 cColor )
{
float3 tmpv = { 0.2125, 0.7154, 0.0721 };
float flLuminance = dot( cColor.rgb, tmpv.rgb );
return flLuminance;
}
float4 GetBloomColor( float2 bloomUV )
{
return tex2D( BaseTextureSampler, bloomUV );
}
float4 PerformColorCorrection( float4 outColor )
{
if (COL_CORRECT_NUM_LOOKUPS > 0)
{
// NOTE: This code requires the color correction texture to be 32 units to be correct.
// This code will cause (0,0,0) to be read from 0.5f/32
// and (1,1,1) to be read from 31.5f/32
float4 offsetOutColor = outColor*(31.0f/32.0f) + (0.5f/32.0f);
outColor.rgb = outColor.rgb * ColorCorrectionDefaultWeight;
outColor.rgb += tex3D( ColorCorrectionVolumeTexture0, offsetOutColor.rgb ) * ColorCorrectionVolumeWeights.x;
if (COL_CORRECT_NUM_LOOKUPS > 1)
{
outColor.rgb += tex3D( ColorCorrectionVolumeTexture1, offsetOutColor.rgb ) * ColorCorrectionVolumeWeights.y;
if (COL_CORRECT_NUM_LOOKUPS > 2)
{
outColor.rgb += tex3D( ColorCorrectionVolumeTexture2, offsetOutColor.rgb ) * ColorCorrectionVolumeWeights.z;
if (COL_CORRECT_NUM_LOOKUPS > 3)
{
outColor.rgb += tex3D( ColorCorrectionVolumeTexture3, offsetOutColor.rgb ) * ColorCorrectionVolumeWeights.w;
}
}
}
}
return outColor;
}
float3 PerformVomitBlend( float3 vRefractParams, float3 vFullResColor, float3 vBlurredColor )
{
float3 vVomitColor = lerp( g_vVomitColor[0].rgb, g_vVomitColor[1].rgb, vRefractParams.z ); // vomit tint
vFullResColor.rgb *= lerp( float3( 1, 1, 1 ), vVomitColor, vRefractParams.z ); // vomit tint full-res buffer
vFullResColor.rgb = lerp ( vFullResColor.rgb, vVomitColor.rgb * vBlurredColor.rgb, vRefractParams.z );
return vFullResColor.rgb;
}
float2 PerformUVTransform( float2 bloomUVs )
{
// NOTE: 'wz' is used since 'zw' is not a valid swizzle for ps20 shaders
return bloomUVs*uvTransform.wz + uvTransform.xy;
}
// Apply TV Gamma for movie layoff specific to 360 TV movie playback path
float3 SrgbGammaToTvGamma( float3 cInput )
{
float3 cLinear = SrgbGammaToLinear( cInput );
return pow( cLinear, 1.0f / 2.5f );
}
struct PS_INPUT
{
float2 baseTexCoord : TEXCOORD0;
};
float4 main( PS_INPUT i ) : COLOR
{
float4 fbTexCoord = 0;
#if !defined( SHADER_MODEL_PS_2_0 )
{
fbTexCoord.xy = PerformUVTransform( i.baseTexCoord );
fbTexCoord.zw = i.baseTexCoord;
}
#else
{
fbTexCoord.xy = PerformUVTransform( i.baseTexCoord );
}
#endif
float4 cBloomBlurredLum = GetBloomColor( i.baseTexCoord ); // bloom color and blurred luminance in alpha
float4 vVomitRefractParams;
#if ( VOMIT_ENABLE == 1 )
{
// perturb texture coordinate
vVomitRefractParams = tex2D( ScreenEffectSampler, i.baseTexCoord );
fbTexCoord = fbTexCoord + g_flVomitRefractStrength * ( vVomitRefractParams.xyxy - 0.5 );
#if !defined( SHADER_MODEL_PS_2_0 )
{
// screen coords -> viewport coords
float4 vNormalizedTexCoord = g_vViewportTransform.xyxy * fbTexCoord + g_vViewportTransform.zwzw;
// mirrored repeat texcoord math doesn't fit into 2.0
vNormalizedTexCoord = min( 2.0 - vNormalizedTexCoord, abs( vNormalizedTexCoord ) );
// viewport coords -> screen coords
fbTexCoord = g_vInvViewportTransform.xyxy * vNormalizedTexCoord + g_vInvViewportTransform.zwzw;
cBloomBlurredLum = GetBloomColor( fbTexCoord.zw ); // fetch again with perturbed texcoords
}
#else
{
cBloomBlurredLum = GetBloomColor( fbTexCoord.xy ); // fetch again with perturbed texcoords
}
#endif
}
#endif
float4 rawColor = tex2D( FBTextureSampler, fbTexCoord.xy ).rgba;
float3 baseColor = rawColor.rgb;
float depthValue = rawColor.a;
#if ( CONVERT_FROM_LINEAR == 1 )
{
baseColor.rgb = SrgbLinearToGamma( baseColor.rgb );
}
#endif
float4 outColor = float4( baseColor, 1 );
#if ( AA_ENABLE == 1 )
{
float3 up;
float3 dn;
float3 lf;
float3 rt;
float3 uplf;
float3 uprt;
float3 dnlf;
float3 dnrt;
#if defined( _X360 )
asm
{
tfetch2D up.xyz, fbTexCoord.xy, FBTextureSampler, OffsetX = 0.0, OffsetY = -1.0, MagFilter = point, MinFilter = point, MipFilter = point
tfetch2D dn.xyz, fbTexCoord.xy, FBTextureSampler, OffsetX = 0.0, OffsetY = 1.0, MagFilter = point, MinFilter = point, MipFilter = point
tfetch2D lf.xyz, fbTexCoord.xy, FBTextureSampler, OffsetX = -1.0, OffsetY = 0.0, MagFilter = point, MinFilter = point, MipFilter = point
tfetch2D rt.xyz, fbTexCoord.xy, FBTextureSampler, OffsetX = 1.0, OffsetY = 0.0, MagFilter = point, MinFilter = point, MipFilter = point
tfetch2D uplf.xyz, fbTexCoord.xy, FBTextureSampler, OffsetX = -1.0, OffsetY = -1.0, MagFilter = point, MinFilter = point, MipFilter = point
tfetch2D uprt.xyz, fbTexCoord.xy, FBTextureSampler, OffsetX = 1.0, OffsetY = -1.0, MagFilter = point, MinFilter = point, MipFilter = point
tfetch2D dnlf.xyz, fbTexCoord.xy, FBTextureSampler, OffsetX = -1.0, OffsetY = 1.0, MagFilter = point, MinFilter = point, MipFilter = point
tfetch2D dnrt.xyz, fbTexCoord.xy, FBTextureSampler, OffsetX = 1.0, OffsetY = 1.0, MagFilter = point, MinFilter = point, MipFilter = point
};
#else
{
// psTapOffs_packed contains 1-pixel offsets: ( +dX, 0, +dY, -dX )
float4 texelDelta = psTapOffs_Packed.xyzw;
dn = tex2D( FBTextureSampler, fbTexCoord.xy + texelDelta.yz ).rgb; // ( 0,+1)
rt = tex2D( FBTextureSampler, fbTexCoord.xy + texelDelta.xy ).rgb; // (+1, 0)
up = tex2D( FBTextureSampler, fbTexCoord.xy - texelDelta.yz ).rgb; // ( 0,-1)
lf = tex2D( FBTextureSampler, fbTexCoord.xy - texelDelta.xy ).rgb; // (-1, 0)
dnlf = tex2D( FBTextureSampler, fbTexCoord.xy + texelDelta.wz ).rgb; // (-1,+1)
uprt = tex2D( FBTextureSampler, fbTexCoord.xy - texelDelta.wz ).rgb; // (+1,-1)
texelDelta.y = texelDelta.z; // Can't quite get all 8 sample offsets from a single float4 with the allowed swizzles!
uplf = tex2D( FBTextureSampler, fbTexCoord.xy + texelDelta.xy ).rgb; // (+1,+1)
dnrt = tex2D( FBTextureSampler, fbTexCoord.xy - texelDelta.xy ).rgb; // (-1,-1)
}
#endif
// Generate the edge mask
float flBaseLum = Luminance( baseColor.rgb );
float flEdge = saturate( abs( Luminance( dn.rgb ) - flBaseLum ) - 0.1 );
flEdge += saturate( abs( Luminance( up.rgb ) - flBaseLum ) - 0.1 );
flEdge += saturate( abs( Luminance( lf.rgb ) - flBaseLum ) - 0.1 );
flEdge += saturate( abs( Luminance( rt.rgb ) - flBaseLum ) - 0.1 );
flEdge *= 5.0;
#if defined( _X360 )
flEdge *= 4.0; // Magic number to compensate for 360 gamma space
#endif
// Average full 3x3 neighborhood of pixels giving more weight to the center sample
float3 vBlurColor = ( baseColor.rgb * 4.0f ) + up.rgb + dn.rgb + lf.rgb + rt.rgb + dnrt.rgb + uprt.rgb + dnlf.rgb + uplf.rgb;
vBlurColor.rgb *= 0.0833333; // 1.0 / 12.0
// Lerp between crisp and blurry pixel based on edge mask
outColor.rgb = lerp( baseColor.rgb, vBlurColor.rgb, saturate( flEdge ) );
}
#endif
#if ( VOMIT_ENABLE == 1 )
{
outColor.rgb = PerformVomitBlend( vVomitRefractParams.xyz, outColor.rgb, cBloomBlurredLum.aaa );
}
#endif
#if ( LOCAL_CONTRAST_ENABLE == 1 )
{
float fMask = 1.0;
// Extract midtones and limit contrast enhancement there
// TODO: This can probably go away for perf.
//float fBrightness = dot( outColor.rgb, float3( 0.3, 0.59, 0.11 ) );
// bell-shaped mask
//fMask = smoothstep( 0.5 - g_flLocalContrastMidToneMask, 0.5, fBrightness );
//fMask *= smoothstep( 0.5 + g_flLocalContrastMidToneMask, 0.5, fBrightness );
//fMask = smoothstep( 1.0, 0.5, fBrightness );
/*
// unsharp mask on luminance only
// This is the technically correct way, going to YUV, applying contrast to Y, and converting back to RGB
float3 outColorYUV;
outColorYUV.x = dot( outColor.rgb, float3( 0.299, 0.587, 0.114 ) );
outColorYUV.y = dot( outColor.rgb, float3( -0.14713, -0.28886, 0.436 ) );
outColorYUV.z = dot( outColor.rgb, float3( 0.615, -0.51499, -0.10001 ) );
outColorYUV.x = outColorYUV.x + g_flLocalContrastStrength * fMask * ( outColorYUV.x - cBloomBlurredLum.aaa );
outColor.r = dot( outColorYUV.xyz, float3( 1.0, 0.0, 1.13983 ) );
outColor.g = dot( outColorYUV.xyz, float3( 1.0, -0.39465, -0.58060 ) );
outColor.b = dot( outColorYUV.xyz, float3( 1.0, 2.03211, 0.0 ) );
*/
// This applies the delta contrast derived from the luminance to all color channels. The difference to the
// correct way is imperceptible.
float fLuminance = dot( outColor.rgb, float3( 0.299, 0.587, 0.114 ) );
float fContrastLum = fLuminance + g_flLocalContrastStrength * ( fLuminance - cBloomBlurredLum.a );
// Mask off pixels that got very bright, to control super-contrast
//fMask = 1.0 - smoothstep( 0.3, 1.0, fContrastLum );
float2 vCenterDir = ( 2.0 * i.baseTexCoord.xy ) - 1.0;
float fMyVignette = smoothstep( g_flLocalContrastVignetteStart, g_flLocalContrastVignetteEnd, length( vCenterDir ) );
float fMyVignette2 = fMyVignette;
fMyVignette = lerp( g_flLocalContrastStrength, g_flLocalContrastEdgeStrength, fMyVignette );
fMask = fMyVignette;
// If the mask is positive, only brighten pixels. If the mask is negative, don't let it get less than -1.0.
//outColor.rgb += fMask * ( fLuminance - cBloomBlurredLum.aaa );
outColor.rgb += max( fMask * ( fLuminance - cBloomBlurredLum.aaa ), -1.0 + step( 0.0, fMask ) ); // Selective clamp to positive adds 4 instructions
#if ( BLURRED_VIGNETTE_ENABLE == 1 )
outColor.rgb = lerp( outColor.rgb, cBloomBlurredLum.aaa, fMyVignette2 * g_flBlurredVignetteStrength );
#endif
}
#endif
// Composite bloom and full-screen + depth blur effects
#if ( DEPTH_BLUR_ENABLE )
{
float blurFactor = g_flBloomLerpFactor + abs( depthValue - g_flDepthBlurFocalDistance ) * g_flDepthBlurScale;
blurFactor = clamp( blurFactor, 0, 1 );
outColor.rgb = lerp( outColor.rgb, cBloomBlurredLum.rgb, blurFactor );
outColor.rgb += g_flBloomAmount * cBloomBlurredLum.rgb;
}
#else
{
outColor.rgb += g_flBloomAmount * cBloomBlurredLum.rgb;
}
#endif
// Used to be FADE_TYPE 0..2 combo
float3 vFadeDestColor = lerp( g_vViewFadeColor.rgb, g_vViewFadeColor.rgb * outColor.rgb, g_flFadeMode2 );
outColor.rgb = lerp( outColor.rgb, vFadeDestColor.rgb, g_vViewFadeColor.a );
#if ( DESATURATEENABLE )
{
float flLum = saturate( dot( outColor.rgb, float3( 0.3f, 0.59f, 0.11f) ) );
outColor.rgb = lerp( saturate( outColor.rgb ), flLum.xxx, saturate( g_flDesaturation ) );
}
#else
{
outColor = PerformColorCorrection( outColor ); // Color correction
}
#endif
// Vignette
#if ( VIGNETTE_ENABLE == 1 )
{
// Vignette
float2 vUv = i.baseTexCoord.xy;
//float2 vTmp = ( vUv.xy * 2.0 ) - 1.0;
float flVignette;
#if defined( _X360 )
{
// Make title safe and deal with different gamma space
//flVignette = 1.0 - pow( abs( vTmp.x ), 4.0f );
//flVignette *= 1.0 - pow( abs( vTmp.y ), 4.0f );
//flVignette = 1.0 - ( 1.0 - flVignette ) * ( ( saturate( ( 1.0 - vUv.y ) - 0.1 ) / 0.9 ) );
// This tex2D solves the 3 lines of math above
flVignette = tex2D( VignetteSampler, vUv.xy ).g; // Green is for the 360
flVignette = saturate( flVignette * 0.75 + 0.26 );
}
#else
{
//flVignette = 1.0 - pow( abs( vTmp.x ), 6.0f );
//flVignette *= 1.0 - pow( abs( vTmp.y ), 6.0f );
//flVignette = 1.0 - ( 1.0 - flVignette ) * ( ( saturate( ( 1.0 - vUv.y ) - 0.3 ) / 0.7 ) );
// This tex2D solves the 3 lines of math above
flVignette = tex2D( VignetteSampler, vUv.xy ).r; // Red is for the PC
flVignette = saturate( flVignette * 0.55 + 0.46 );
}
#endif
outColor.rgb *= flVignette;
}
#endif
// Noise
#if ( NOISE_ENABLE == 1 )
{
// Additive Noise
float2 vUv0 = i.baseTexCoord.xy * 10.0 + g_flTime;
float2 vUv1 = i.baseTexCoord.yx * 20.0 - g_flTime;
float2 vNoiseTexelUv;
vNoiseTexelUv.x = tex2D( NoiseSampler, vUv0.xy ).g;
vNoiseTexelUv.y = tex2D( NoiseSampler, vUv1.xy ).g;
float flNoiseTexel = tex2D( NoiseSampler, vNoiseTexelUv.xy ).g;
float3 vTmp = { 0.2125f, 0.7154f, 0.0721f };
float flLuminance = saturate( dot( outColor.rgb, vTmp.rgb ) );
#if defined( _X360 )
{
// 360
float flNoiseScalar = 0.2f + 1.0f * ( saturate( pow( 1.0 - flLuminance, 64.0 ) ) );
outColor.rgb += ( ( flNoiseTexel * 0.3f ) - 0.15f ) * g_flNoiseScalar * flNoiseScalar;
}
#else
{
// PC
float flNoiseScalar = 0.2f + 0.8f * ( saturate( pow( 1.0 - flLuminance, 12.0 ) ) );
outColor.rgb += ( ( flNoiseTexel * 0.3f ) - 0.15f ) * g_flNoiseScalar * flNoiseScalar;
}
#endif
}
#endif
// Fade to black
outColor.rgb = lerp( outColor.rgb, 0.0, g_flFadeToBlackStrength );
#if TV_GAMMA
{
// Used for SFM to record movies in native TV gamma space
outColor.rgb = SrgbGammaToTvGamma( outColor.rgb );
}
#endif
#if ( CONVERT_TO_LINEAR == 1 )
{
// If we have a float back buffer, we want to remain in linear space after this shader
outColor.rgb = SrgbGammaToLinear( outColor.rgb );
}
#endif
return FinalOutput( outColor, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
}

View File

@ -0,0 +1,133 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// $SHADER_SPECIFIC_CONST_0 = eyeball origin
// $SHADER_SPECIFIC_CONST_1 = eyeball up * 0.5
// $SHADER_SPECIFIC_CONST_2 = iris projection U
// $SHADER_SPECIFIC_CONST_3 = iris projection V
// $SHADER_SPECIFIC_CONST_4 = glint projection U
// $SHADER_SPECIFIC_CONST_5 = glint projection V
//===========================================================================//
// STATIC: "INTRO" "0..1"
// STATIC: "HALFLAMBERT" "0..1"
// DYNAMIC: "COMPRESSED_VERTS" "0..1"
// DYNAMIC: "SKINNING" "0..1"
#include "common_fog_vs_fxc.h"
// DYNAMIC: "DYNAMIC_LIGHT" "0..1"
// DYNAMIC: "STATIC_LIGHT" "0..1"
// DYNAMIC: "MORPHING" "0..1" [vs30] [ = pShaderAPI->IsHWMorphingEnabled() ]
#include "vortwarp_vs20_helper.h"
static const int g_bSkinning = SKINNING ? true : false;
static const int g_FogType = DOWATERFOG;
static const bool g_bHalfLambert = HALFLAMBERT ? true : false;
const float3 cEyeOrigin : register( SHADER_SPECIFIC_CONST_0 );
const float3 cHalfEyeballUp : register( SHADER_SPECIFIC_CONST_1 );
const float4 cIrisProjectionU : register( SHADER_SPECIFIC_CONST_2 );
const float4 cIrisProjectionV : register( SHADER_SPECIFIC_CONST_3 );
const float4 cGlintProjectionU : register( SHADER_SPECIFIC_CONST_4 );
const float4 cGlintProjectionV : register( SHADER_SPECIFIC_CONST_5 );
#if INTRO
const float4 const4 : register( SHADER_SPECIFIC_CONST_6 );
#define g_Time const4.w
#define modelOrigin const4.xyz
#endif
#ifdef SHADER_MODEL_VS_3_0
// NOTE: cMorphTargetTextureDim.xy = target dimensions,
// cMorphTargetTextureDim.z = 4tuples/morph
const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_7 );
const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_8 );
sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 );
#endif
struct VS_INPUT
{
float4 vPos : POSITION; // Position
float4 vBoneWeights : BLENDWEIGHT; // Skin weights
float4 vBoneIndices : BLENDINDICES; // Skin indices
float4 vTexCoord0 : TEXCOORD0; // Base (sclera) texture coordinates
float3 vPosFlex : POSITION1; // Delta positions for flexing
#ifdef SHADER_MODEL_VS_3_0
float vVertexID : POSITION2;
#endif
};
struct VS_OUTPUT
{
float4 projPos : POSITION; // Projection-space position
#if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 )
float fog : FOG; // Fixed-function fog factor
#endif
float2 baseTC : TEXCOORD0; // Base texture coordinate
float2 irisTC : TEXCOORD1; // Iris texture coordinates
float2 glintTC : TEXCOORD2; // Glint texture coordinates
float3 vColor : TEXCOORD3; // Vertex-lit color
float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog
};
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = (VS_OUTPUT)0;
bool bDynamicLight = DYNAMIC_LIGHT ? true : false;
bool bStaticLight = STATIC_LIGHT ? true : false;
float4 vPosition = v.vPos;
float3 dummy = v.vPos.xyz; // dummy values that can't be optimized out
#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING
ApplyMorph( v.vPosFlex, vPosition.xyz );
#else
ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, dummy, vPosition.xyz );
#endif
// Transform the position and dummy normal (not doing the dummy normal causes invariance issues with the flashlight!)
float3 worldNormal, worldPos;
SkinPositionAndNormal(
g_bSkinning,
vPosition, dummy,
v.vBoneWeights, v.vBoneIndices,
worldPos, worldNormal );
#if INTRO
WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, dummy, dummy, dummy );
#endif
// Transform into projection space
o.projPos = mul( float4( worldPos, 1 ), cViewProj );
o.worldPos_projPosZ = float4( worldPos.xyz, o.projPos.z );
#if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 )
o.fog = CalcFixedFunctionFog( worldPos, g_FogType );
#endif
// Normal = (Pos - Eye origin) - just step on dummy normal created above
worldNormal = worldPos - cEyeOrigin;
// Normal -= 0.5f * (Normal dot Eye Up) * Eye Up
float normalDotUp = -dot( worldNormal, cHalfEyeballUp) * 0.5f;
worldNormal = normalize(normalDotUp * cHalfEyeballUp + worldNormal);
// Compute vertex lighting
o.vColor = DoLighting( worldPos, worldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert );
// Texture 0 is the base texture
// Texture 1 is a planar projection used for the iris
// Texture 2 is a planar projection used for the glint
o.baseTC = v.vTexCoord0;
o.irisTC.x = dot( cIrisProjectionU, float4(worldPos, 1) );
o.irisTC.y = dot( cIrisProjectionV, float4(worldPos, 1) );
o.glintTC.x = dot( cGlintProjectionU, float4(worldPos, 1) );
o.glintTC.y = dot( cGlintProjectionV, float4(worldPos, 1) );
return o;
}

View File

@ -0,0 +1,81 @@
//========= Copyright <20> 1996-2004, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "BaseVSShader.h"
#include "common_hlsl_cpp_consts.h"
#include "hdrcombineto16bit_ps20.inc"
#include "hdrcombineto16bit_ps20b.inc"
#include "hdrcombineto16bit_vs20.inc"
#include "convar.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
BEGIN_VS_SHADER_FLAGS( HDRCombineTo16Bit, "Help for HDRCombineTo16Bit", SHADER_NOT_EDITABLE )
BEGIN_SHADER_PARAMS
SHADER_PARAM( SOURCEMRTRENDERTARGET, SHADER_PARAM_TYPE_TEXTURE, "", "" )
END_SHADER_PARAMS
SHADER_INIT
{
LoadTexture( SOURCEMRTRENDERTARGET );
}
SHADER_FALLBACK
{
return 0;
}
SHADER_DRAW
{
SHADOW_STATE
{
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableAlphaWrites( false );
pShaderShadow->EnableDepthTest( false );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
int fmt = VERTEX_POSITION;
pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 );
DECLARE_STATIC_VERTEX_SHADER( hdrcombineto16bit_vs20 );
SET_STATIC_VERTEX_SHADER( hdrcombineto16bit_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( hdrcombineto16bit_ps20b );
SET_STATIC_PIXEL_SHADER( hdrcombineto16bit_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( hdrcombineto16bit_ps20 );
SET_STATIC_PIXEL_SHADER( hdrcombineto16bit_ps20 );
}
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, SOURCEMRTRENDERTARGET, -1 );
DECLARE_DYNAMIC_VERTEX_SHADER( hdrcombineto16bit_vs20 );
SET_DYNAMIC_VERTEX_SHADER( hdrcombineto16bit_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( hdrcombineto16bit_ps20b );
SET_DYNAMIC_PIXEL_SHADER( hdrcombineto16bit_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( hdrcombineto16bit_ps20 );
SET_DYNAMIC_PIXEL_SHADER( hdrcombineto16bit_ps20 );
}
}
Draw();
}
END_SHADER

View File

@ -0,0 +1,23 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
#include "common_ps_fxc.h"
sampler LowSampler : register( s0 );
sampler HiSampler : register( s1 );
struct PS_INPUT
{
float2 texCoord : TEXCOORD0;
};
float4 main( PS_INPUT i ) : COLOR
{
float4 lowColor = tex2D( LowSampler, i.texCoord );
float3 hiColor = tex2D( HiSampler, i.texCoord );
lowColor.rgb = GammaToLinear( lowColor.rgb );
hiColor.rgb = GammaToLinear( hiColor.rgb );
float4 result = float4( ( 1.0f / MAX_HDR_OVERBRIGHT ) * max( lowColor.xyz, hiColor.xyz * MAX_HDR_OVERBRIGHT ), lowColor.a );
return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
}

View File

@ -0,0 +1,24 @@
#include "common_vs_fxc.h"
struct VS_INPUT
{
float3 vPos : POSITION;
float2 vBaseTexCoord : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 projPos : POSITION;
float2 texCoord : TEXCOORD0;
};
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
o.projPos = float4( v.vPos, 1.0f );
o.texCoord = v.vBaseTexCoord;
return o;
}

View File

@ -0,0 +1,79 @@
//========= Copyright <20> 1996-2004, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "BaseVSShader.h"
#include "common_hlsl_cpp_consts.h"
#include "hdrselectrange_ps20.inc"
#include "hdrselectrange_ps20b.inc"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
BEGIN_VS_SHADER_FLAGS( HDRSelectRange, "Help for HDRSelectRange", SHADER_NOT_EDITABLE )
BEGIN_SHADER_PARAMS
SHADER_PARAM( SOURCEMRTRENDERTARGET, SHADER_PARAM_TYPE_TEXTURE, "", "" )
END_SHADER_PARAMS
SHADER_INIT
{
LoadTexture( SOURCEMRTRENDERTARGET );
}
SHADER_FALLBACK
{
return 0;
}
SHADER_DRAW
{
SHADOW_STATE
{
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableAlphaWrites( false );
pShaderShadow->EnableDepthTest( false );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
int fmt = VERTEX_POSITION;
pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 );
pShaderShadow->SetVertexShader( "HDRSelectRange_vs20", 0 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( hdrselectrange_ps20b );
SET_STATIC_PIXEL_SHADER( hdrselectrange_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( hdrselectrange_ps20 );
SET_STATIC_PIXEL_SHADER( hdrselectrange_ps20 );
}
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, SOURCEMRTRENDERTARGET, -1 );
pShaderAPI->SetVertexShaderIndex( 0 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( hdrselectrange_ps20b );
SET_DYNAMIC_PIXEL_SHADER( hdrselectrange_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( hdrselectrange_ps20 );
SET_DYNAMIC_PIXEL_SHADER( hdrselectrange_ps20 );
}
}
Draw();
}
END_SHADER

View File

@ -0,0 +1,42 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
#include "common_ps_fxc.h"
sampler LowSampler : register( s0 );
sampler HiSampler : register( s1 );
struct PS_INPUT
{
float2 texCoord : TEXCOORD0;
};
struct MYHDR_PS_OUTPUT
{
float4 color[2] : COLOR0;
};
MYHDR_PS_OUTPUT main( PS_INPUT i ) : COLOR
{
float3 lowColor = GammaToLinear( tex2D( LowSampler, i.texCoord ) );
float3 hiColor = GammaToLinear( tex2D( HiSampler, i.texCoord ) );
float4 lowOut;
lowOut.a = 1.0f;
float4 hiOut;
hiOut.a = 1.0f;
float3 hdrColor = max( lowColor, hiColor * MAX_HDR_OVERBRIGHT );
float fMax = max( hdrColor.b, max( hdrColor.r, hdrColor.g ) );
float blendFactor = saturate( ( fMax - 0.9f ) * 10.0f );
blendFactor = 1.0f;
lowOut.rgb = LinearToGamma( lowColor * ( 1.0f - blendFactor ) );
hiOut.rgb = LinearToGamma( hiColor * ( blendFactor ) );
MYHDR_PS_OUTPUT output;
output.color[0] = lowOut;
output.color[1] = hiOut;
return output;
}

View File

@ -0,0 +1,24 @@
#include "common_vs_fxc.h"
struct VS_INPUT
{
float3 vPos : POSITION;
float2 vBaseTexCoord : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 projPos : POSITION;
float2 texCoord : TEXCOORD0;
};
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
o.projPos = float4( v.vPos, 1.0f );
o.texCoord = v.vBaseTexCoord;
return o;
}

View File

@ -0,0 +1,182 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "BaseVSShader.h"
#include "unlittwotexture_vs20.inc"
#include "monitorscreen_ps20.inc"
#include "monitorscreen_ps20b.inc"
#include "cpp_shader_constant_register_map.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
DEFINE_FALLBACK_SHADER( MonitorScreen, MonitorScreen_DX9 )
BEGIN_VS_SHADER( MonitorScreen_DX9,
"This is a shader that does a contrast/saturation version of base times lightmap." )
BEGIN_SHADER_PARAMS
SHADER_PARAM( CONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" )
SHADER_PARAM( SATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" )
SHADER_PARAM( TINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "monitor tint" )
SHADER_PARAM( TEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/lightmappedtexture", "second texture" )
SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $texture2" )
SHADER_PARAM( TEXTURE2TRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$texture2 texcoord transform" )
END_SHADER_PARAMS
// Set up anything that is necessary to make decisions in SHADER_FALLBACK.
SHADER_INIT_PARAMS()
{
SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
if( !params[CONTRAST]->IsDefined() )
{
params[CONTRAST]->SetFloatValue( 0.0f );
}
if( !params[SATURATION]->IsDefined() )
{
params[SATURATION]->SetFloatValue( 1.0f );
}
if( !params[TINT]->IsDefined() )
{
params[TINT]->SetVecValue( 1.0f, 1.0f, 1.0f );
}
if (!IS_FLAG_DEFINED( MATERIAL_VAR_MODEL ))
{
CLEAR_FLAGS( MATERIAL_VAR_MODEL );
}
}
SHADER_FALLBACK
{
if( params && !params[BASETEXTURE]->IsDefined() )
return "LightmappedGeneric";
return 0;
}
SHADER_INIT
{
if (params[BASETEXTURE]->IsDefined())
{
LoadTexture( BASETEXTURE );
}
if (params[TEXTURE2]->IsDefined())
{
LoadTexture( TEXTURE2 );
}
}
SHADER_DRAW
{
bool bHasTexture2 = params[TEXTURE2]->IsTexture();
BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true );
bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use
SHADOW_STATE
{
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true );
if ( bHasTexture2 )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true );
}
pShaderShadow->EnableSRGBWrite( true );
// Either we've got a constant modulation
bool isTranslucent = IsAlphaModulating();
// Or we've got a texture alpha on either texture
isTranslucent = isTranslucent || TextureIsTranslucent( BASETEXTURE, true ) ||
TextureIsTranslucent( TEXTURE2, true );
if ( isTranslucent )
{
if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) )
EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE );
else
EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
}
else
{
if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) )
EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE );
else
DisableAlphaBlending( );
}
// Set stream format (note that this shader supports compression)
unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED;
int nTexCoordCount = 1;
int userDataSize = 0;
pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize );
DECLARE_STATIC_VERTEX_SHADER( unlittwotexture_vs20 );
SET_STATIC_VERTEX_SHADER( unlittwotexture_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( monitorscreen_ps20b );
SET_STATIC_PIXEL_SHADER_COMBO( TEXTURE2, (bHasTexture2)?(1):(0) );
SET_STATIC_PIXEL_SHADER( monitorscreen_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( monitorscreen_ps20 );
SET_STATIC_PIXEL_SHADER_COMBO( TEXTURE2, (bHasTexture2)?(1):(0) );
SET_STATIC_PIXEL_SHADER( monitorscreen_ps20 );
}
DefaultFog();
pShaderShadow->EnableAlphaWrites( bFullyOpaque );
PI_BeginCommandBuffer();
PI_SetModulationVertexShaderDynamicState();
PI_EndCommandBuffer();
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
if( bHasTexture2 )
{
BindTexture( SHADER_SAMPLER1, TEXTURE2, FRAME2 );
SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, TEXTURE2TRANSFORM );
}
SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM );
SetPixelShaderConstant( 1, CONTRAST );
SetPixelShaderConstant( 2, SATURATION );
SetPixelShaderConstant( 3, TINT );
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 );
DECLARE_DYNAMIC_VERTEX_SHADER( unlittwotexture_vs20 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
SET_DYNAMIC_VERTEX_SHADER_COMBO( WORLD_NORMAL, 0 );
SET_DYNAMIC_VERTEX_SHADER( unlittwotexture_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( monitorscreen_ps20b );
SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() );
SET_DYNAMIC_PIXEL_SHADER( monitorscreen_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( monitorscreen_ps20 );
SET_DYNAMIC_PIXEL_SHADER( monitorscreen_ps20 );
}
}
Draw();
}
END_SHADER

View File

@ -0,0 +1,143 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
//
// Purpose:
//
//===========================================================================//
// STATIC: "MODEL" "0..1"
// STATIC: "COLORMODULATE" "0..1"
// DYNAMIC: "COMPRESSED_VERTS" "0..1"
// DYNAMIC: "SKINNING" "0..1"
#include "common_vs_fxc.h"
static const bool g_bSkinning = SKINNING ? true : false;
static const bool g_bModel = MODEL ? true : false;
const float4 cBumpTexCoordTransform[4] : register( SHADER_SPECIFIC_CONST_1 );
const float g_flTime : register( SHADER_SPECIFIC_CONST_5 );
const float4 g_vViewportMad : register( SHADER_SPECIFIC_CONST_6 );
struct VS_INPUT
{
float4 vPos : POSITION;
float4 vBoneWeights : BLENDWEIGHT;
float4 vBoneIndices : BLENDINDICES;
float4 vNormal : NORMAL;
float4 vBaseTexCoord : TEXCOORD0;
#if !MODEL
float3 vTangentS : TANGENT;
float3 vTangentT : BINORMAL0;
#else
float4 vUserData : TANGENT;
#endif
#if COLORMODULATE
float4 vColor : COLOR0;
#endif
};
struct VS_OUTPUT
{
float4 vProjPos_POSITION : POSITION;
#if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 )
float fog : FOG;
#endif
float4 vBumpTexCoord : TEXCOORD0;
float3 vTangentEyeVect : TEXCOORD1;
float3 vWorldNormal : TEXCOORD2;
float3 vWorldTangent : TEXCOORD3;
float3 vWorldBinormal : TEXCOORD4;
float3 vRefractXYW : TEXCOORD5;
float3 vWorldViewVector : TEXCOORD6;
#if COLORMODULATE
float4 vColor : COLOR0;
#endif
float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog
};
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
#if COLORMODULATE
o.vColor = v.vColor;
#endif
float3 worldNormal, worldPos, worldTangentS, worldTangentT;
float3 vObjNormal;
#if MODEL
float4 vObjTangent;
DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vObjNormal, vObjTangent );
SkinPositionNormalAndTangentSpace(
g_bSkinning,
v.vPos, vObjNormal, vObjTangent,
v.vBoneWeights, v.vBoneIndices,
worldPos, worldNormal, worldTangentS, worldTangentT );
#else
DecompressVertex_Normal( v.vNormal, vObjNormal );
worldPos = mul( v.vPos, cModel[0] );
worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] );
worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] );
worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] );
#endif
// World normal
o.vWorldNormal.xyz = normalize( worldNormal.xyz );
// Projected position
float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj );
o.vProjPos_POSITION = vProjPos;
o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z );
//o.projNormal.xyz = mul( worldNormal, cViewProj );
// Map projected position to the refraction texture
float2 vRefractPos;
vRefractPos.x = vProjPos.x;
vRefractPos.y = -vProjPos.y; // invert Y
vRefractPos = (vRefractPos + vProjPos.w) * 0.5f;
// Adjust for current viewport
vRefractPos.xy = ( ( ( vRefractPos.xy / vProjPos.w ) * g_vViewportMad.xy ) + g_vViewportMad.zw ) * vProjPos.w;
// Refraction transform
o.vRefractXYW = float3(vRefractPos.x, vRefractPos.y, vProjPos.w);
// Compute fog based on the position
float3 vWorldPos = mul( v.vPos, cModel[0] );
#if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 )
o.fog = CalcFixedFunctionFog( vWorldPos, FOGTYPE_RANGE );
#endif
// Eye vector
float3 vWorldEyeVect = normalize( cEyePos - vWorldPos );
o.vWorldViewVector.xyz = -vWorldEyeVect.xyz;
// Transform to the tangent space
o.vTangentEyeVect.x = dot( vWorldEyeVect, worldTangentS );
o.vTangentEyeVect.y = dot( vWorldEyeVect, worldTangentT );
o.vTangentEyeVect.z = dot( vWorldEyeVect, worldNormal );
// Tranform bump coordinates
o.vBumpTexCoord.x = dot( v.vBaseTexCoord, cBumpTexCoordTransform[0] );
o.vBumpTexCoord.y = dot( v.vBaseTexCoord, cBumpTexCoordTransform[1] );
// Tranform bump coordinates (note wz, not zw)
o.vBumpTexCoord.w = dot( v.vBaseTexCoord, cBumpTexCoordTransform[2] );
o.vBumpTexCoord.z = dot( v.vBaseTexCoord, cBumpTexCoordTransform[3] );
// Tangent space transform
o.vWorldNormal.xyz = normalize( worldNormal.xyz );
o.vWorldTangent.xyz = worldTangentS.xyz;
o.vWorldBinormal.xyz = worldTangentT.xyz;
return o;
}

View File

@ -0,0 +1,29 @@
vs.1.1
# DYNAMIC: "DOWATERFOG" "0..1"
;------------------------------------------------------------------------------
; Constants specified by the app
; c0 = (0, 1, 2, 0.5)
; c1 = (1/2.2, 3, 255, overbright factor)
; c2 = camera position *in world space*
; c4-c7 = modelViewProj matrix (transpose)
; c8-c11 = ViewProj matrix (transpose)
; c12-c15 = model->view matrix (transpose)
; c16 = [fogStart, fogEnd, fogRange, 1.0/fogRange]
; $SHADER_SPECIFIC_CONST_0-$SHADER_SPECIFIC_CONST_1 = Base texture transform
; $SHADER_SPECIFIC_CONST_2-$SHADER_SPECIFIC_CONST_3 = Mask texture transform
;------------------------------------------------------------------------------
#include "macros.vsh"
;------------------------------------------------------------------------------
; No vertex blending required. Input vertex data is in screen space
;------------------------------------------------------------------------------
mov oPos.xyz, $vPos.xyz
mov oPos.w, $cOne
;------------------------------------------------------------------------------
; Pass any and all texture coordinates through
;------------------------------------------------------------------------------
mov oT0, $vTexCoord0

View File

@ -0,0 +1,43 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Naively sets the depth buffer values without testing the old values and without writing to alpha or color
//
// $NoKeywords: $
//=============================================================================//
#include "shaderlib/CShader.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
DEFINE_FALLBACK_SHADER( SetZ, SetZ_DX6 )
BEGIN_SHADER_FLAGS( SetZ_DX6, "Help for SetZ_DX6", SHADER_NOT_EDITABLE )
BEGIN_SHADER_PARAMS
END_SHADER_PARAMS
SHADER_INIT_PARAMS()
{
}
SHADER_INIT
{
}
SHADER_DRAW
{
SHADOW_STATE
{
pShaderShadow->EnableColorWrites( false );
pShaderShadow->EnableAlphaWrites( false );
pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_ALWAYS );
pShaderShadow->DrawFlags( SHADER_DRAW_POSITION );
}
DYNAMIC_STATE
{
}
Draw();
}
END_SHADER

View File

@ -0,0 +1,22 @@
ps.1.1
;------------------------------------------------------------------------------
; Draw a texture . . woo hoo!
; t0 - texture
;
; The texture coordinates need to be defined as follows:
; tc0 - texcoords
;------------------------------------------------------------------------------
def c0,1.0f, 1.0f, 1.0f, 1.0f
tex t0 ; shadow color
texkill t1 ; Clip
texkill t2
texkill t3 ; backface cull
; Darkening equation, compute a color = (shadow color * shadow alpha + 1- shadow alpha)
;sub r1, t0, v0.a ; r1 = shadow alpha
lrp r0.rgb, t0.a, v0, c0 + ; r0.rgb = (shadow color * shadow alpha + 1 - shadow alpha)
mov r0.a, c0.a ; r0.a = 1

View File

@ -0,0 +1,85 @@
vs.1.1
# DYNAMIC: "DOWATERFOG" "0..1"
# DYNAMIC: "SKINNING" "0..1"
;------------------------------------------------------------------------------
; Constants specified by the app
; $SHADER_SPECIFIC_CONST_0-$SHADER_SPECIFIC_CONST_2 = Shadow texture matrix
; $SHADER_SPECIFIC_CONST_3 = Tex origin
; $SHADER_SPECIFIC_CONST_4 = Tex Scale
; $SHADER_SPECIFIC_CONST_5 = [Shadow falloff offset, 1/Shadow distance, Shadow scale, 0 ]
;------------------------------------------------------------------------------
#include "macros.vsh"
;------------------------------------------------------------------------------
; Vertex blending (whacks r1-r7, positions in r7, normals in r8)
;------------------------------------------------------------------------------
&AllocateRegister( \$worldPos );
&AllocateRegister( \$worldNormal );
&SkinPositionAndNormal( $worldPos, $worldNormal );
; Transform the position from world to view space
&AllocateRegister( \$projPos );
dp4 $projPos.x, $worldPos, $cViewProj0
dp4 $projPos.y, $worldPos, $cViewProj1
dp4 $projPos.z, $worldPos, $cViewProj2
dp4 $projPos.w, $worldPos, $cViewProj3
mov oPos, $projPos
;------------------------------------------------------------------------------
; Fog
;------------------------------------------------------------------------------
&CalcFog( $worldPos, $projPos );
&FreeRegister( \$projPos );
;------------------------------------------------------------------------------
; Transform position into texture space (from 0 to 1)
;------------------------------------------------------------------------------
&AllocateRegister( \$texturePos );
dp4 $texturePos.x, $worldPos, $SHADER_SPECIFIC_CONST_0
dp4 $texturePos.y, $worldPos, $SHADER_SPECIFIC_CONST_1
dp4 $texturePos.z, $worldPos, $SHADER_SPECIFIC_CONST_2
&FreeRegister( \$worldPos );
;------------------------------------------------------------------------------
; Figure out the shadow fade amount
;------------------------------------------------------------------------------
&AllocateRegister( \$shadowFade );
sub $shadowFade, $texturePos.z, $SHADER_SPECIFIC_CONST_5.x
mul $shadowFade, $shadowFade, $SHADER_SPECIFIC_CONST_5.y
;------------------------------------------------------------------------------
; Offset it into the texture
;------------------------------------------------------------------------------
&AllocateRegister( \$actualTextureCoord );
mul $actualTextureCoord.xyz, $SHADER_SPECIFIC_CONST_4, $texturePos
add oT0.xyz, $actualTextureCoord, $SHADER_SPECIFIC_CONST_3
;mov oT0.xyz, $texturePos
&FreeRegister( \$actualTextureCoord );
;------------------------------------------------------------------------------
; We're doing clipping by using texkill
;------------------------------------------------------------------------------
mov oT1.xyz, $texturePos ; also clips when shadow z < 0 !
sub oT2.xyz, $cOne, $texturePos
sub oT2.z, $cOne, $shadowFade.z ; clips when shadow z > shadow distance
&FreeRegister( \$texturePos );
;------------------------------------------------------------------------------
; We're doing backface culling by using texkill also (wow yucky)
;------------------------------------------------------------------------------
; Transform z component of normal in texture space
; If it's negative, then don't draw the pixel
dp3 oT3, $worldNormal, -$SHADER_SPECIFIC_CONST_2
&FreeRegister( \$worldNormal );
;------------------------------------------------------------------------------
; Shadow color, falloff
;------------------------------------------------------------------------------
mov oD0, $cModulationColor
mul oD0.w, $shadowFade.x, $SHADER_SPECIFIC_CONST_5.z
&FreeRegister( \$shadowFade );

View File

@ -0,0 +1,128 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// STATIC: "CUBEMAP" "0..1"
// STATIC: "VERTEXCOLOR" "0..1"
// STATIC: "ENVMAPMASK" "0..1"
// STATIC: "BASEALPHAENVMAPMASK" "0..1"
// STATIC: "HDRTYPE" "0..2"
#include "common_fog_ps_fxc.h"
// HDRFIXME: Need to make this work.
#define USE_32BIT_LIGHTMAPS_ON_360 //uncomment to use 32bit lightmaps, be sure to keep this in sync with the same #define in materialsystem/cmatlightmaps.cpp
#include "common_ps_fxc.h"
#include "common_lightmappedgeneric_fxc.h"
const HALF4 g_EnvmapTint : register( c0 );
const HALF3 g_DiffuseModulation : register( c1 );
const HALF3 g_EnvmapContrast : register( c2 );
const HALF3 g_EnvmapSaturation : register( c3 );
const HALF4 g_FresnelReflection : register( c4 );
const HALF3 g_EyePos : register( c5 );
const HALF3 g_OverbrightFactor : register( c6 );
const HALF4 g_FogParams : register( c12 );
// CENTROID: TEXCOORD2
sampler BaseTextureSampler : register( s0 );
sampler LightmapSampler : register( s1 );
sampler EnvmapSampler : register( s2 );
sampler DetailSampler : register( s3 );
sampler EnvmapMaskSampler : register( s5 );
sampler NormalizeSampler : register( s6 );
struct PS_INPUT
{
HALF2 baseTexCoord : TEXCOORD0;
HALF2 detailTexCoord : TEXCOORD1;
HALF2 lightmapTexCoord : TEXCOORD2;
HALF2 envmapMaskTexCoord : TEXCOORD3;
HALF4 worldPos_projPosZ : TEXCOORD4;
HALF3 worldSpaceNormal : TEXCOORD5;
HALF4 vertexColor : COLOR;
};
float4 main( PS_INPUT i ) : COLOR
{
bool bCubemap = CUBEMAP ? true : false;
bool bVertexColor = VERTEXCOLOR ? true : false;
bool bEnvmapMask = ENVMAPMASK ? true : false;
bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false;
HALF4 baseColor = tex2D( BaseTextureSampler, i.baseTexCoord );
HALF4 detailColor = tex2D( DetailSampler, i.detailTexCoord );
HALF2 lightmapCoordinates = i.lightmapTexCoord;
HALF3 lightmapColor = LightMapSample( LightmapSampler, lightmapCoordinates );
HALF3 specularFactor = 1.0f;
if( bEnvmapMask )
{
specularFactor = tex2D( EnvmapMaskSampler, i.detailTexCoord ).xyz;
}
if( bBaseAlphaEnvmapMask )
{
specularFactor *= 1.0 - baseColor.a; // this blows!
}
HALF3 diffuseLighting = lightmapColor;
diffuseLighting *= g_DiffuseModulation;
diffuseLighting *= LIGHT_MAP_SCALE;
HALF3 albedo = baseColor;
HALF alpha = 1.0f;
if( !bBaseAlphaEnvmapMask )
{
alpha *= baseColor.a;
}
albedo *= detailColor;
alpha *= detailColor.a;
// FIXME: seperate vertexcolor and vertexalpha?
// vertex alpha is ignored if vertexcolor isn't set. . need to check other version.
if( bVertexColor )
{
albedo *= i.vertexColor;
alpha *= i.vertexColor.a; // not sure about this one
}
HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f );
if( bCubemap )
{
float3 worldVertToEyeVector = g_EyePos - i.worldPos_projPosZ.xyz;
worldVertToEyeVector = NormalizeWithCubemap( NormalizeSampler, worldVertToEyeVector );
HALF3 reflectVect = CalcReflectionVectorUnnormalized( i.worldSpaceNormal, worldVertToEyeVector );
// Calc Fresnel factor
HALF3 worldSpaceNormal = NormalizeWithCubemap( NormalizeSampler, i.worldSpaceNormal );
HALF fresnel = 1.0 - dot( worldSpaceNormal, worldVertToEyeVector );
fresnel = pow( fresnel, 5.0 );
fresnel = fresnel * g_FresnelReflection.b + g_FresnelReflection.a;
specularLighting = texCUBE( EnvmapSampler, reflectVect );
specularLighting *= specularFactor;
specularLighting *= g_EnvmapTint;
#if HDRTYPE == HDR_TYPE_NONE
HALF3 specularLightingSquared = specularLighting * specularLighting;
specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast );
HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) );
specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation );
#endif
specularLighting *= fresnel;
}
// Do it somewhat unlit
HALF3 result = albedo*(g_OverbrightFactor.z*diffuseLighting + g_OverbrightFactor.y) + specularLighting;
float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w );
return FinalOutput( HALF4( result, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR );
}

View File

@ -0,0 +1,66 @@
#include "common_fog_vs_fxc.h"
// STATIC: "ENVMAP_MASK" "0..1"
#include "common_vs_fxc.h"
static const int g_FogType = DOWATERFOG;
static const bool g_UseSeparateEnvmapMask = ENVMAP_MASK;
const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 );
const float4 cDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_2 );
struct VS_INPUT
{
float3 vPos : POSITION;
float4 vNormal : NORMAL;
float2 vBaseTexCoord : TEXCOORD0;
float2 vLightmapTexCoord : TEXCOORD1;
float2 vDetailTexCoord : TEXCOORD2;
};
struct VS_OUTPUT
{
float4 projPos : POSITION;
#if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 )
float fog : FOG;
#endif
float2 baseTexCoord : TEXCOORD0;
float2 detailTexCoord : TEXCOORD1;
float2 lightmapTexCoord : TEXCOORD2;
float2 envmapMaskTexCoord : TEXCOORD3;
float4 worldPos_projPosZ : TEXCOORD4;
float3 worldNormal : TEXCOORD5;
float4 vertexColor : COLOR;
};
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
float3 vObjNormal;
DecompressVertex_Normal( v.vNormal, vObjNormal );
float4 projPos;
projPos = mul( float4( v.vPos, 1 ), cModelViewProj );
o.projPos = projPos;
o.worldPos_projPosZ.w = projPos.z;
o.worldPos_projPosZ.xyz = mul( float4( v.vPos, 1 ), cModel[0] );
o.worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] );
o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w;
o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w;
o.detailTexCoord.x = dot( v.vDetailTexCoord, cDetailTexCoordTransform[0] ) + cDetailTexCoordTransform[0].w;
o.detailTexCoord.y = dot( v.vDetailTexCoord, cDetailTexCoordTransform[1] ) + cDetailTexCoordTransform[1].w;
o.envmapMaskTexCoord.x = dot( v.vDetailTexCoord, cDetailTexCoordTransform[0] ) + cDetailTexCoordTransform[0].w;
o.envmapMaskTexCoord.y = dot( v.vDetailTexCoord, cDetailTexCoordTransform[1] ) + cDetailTexCoordTransform[1].w;
o.lightmapTexCoord = v.vLightmapTexCoord;
#if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 )
o.fog = CalcFixedFunctionFog( o.worldPos_projPosZ.xyz, g_FogType );
#endif
o.vertexColor = cModulationColor;
return o;
}

View File

@ -0,0 +1,96 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Header: $
// $NoKeywords: $
//=============================================================================//
#include "BaseVSShader.h"
#include "treeleaf_ps20.inc"
#include "treeleaf_ps20b.inc"
#include "treeleaf_vs20.inc"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
BEGIN_VS_SHADER_FLAGS( TreeLeaf, "Help for TreeLeaf", SHADER_NOT_EDITABLE )
BEGIN_SHADER_PARAMS
SHADER_PARAM( LEAFCENTER, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "Center of leaf cluster for lighting" )
END_SHADER_PARAMS
SHADER_INIT_PARAMS()
{
}
SHADER_FALLBACK
{
return 0;
}
SHADER_INIT
{
SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT );
if ( params[BASETEXTURE]->IsDefined() )
{
LoadTexture( BASETEXTURE );
}
}
SHADER_DRAW
{
SHADOW_STATE
{
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->EnableAlphaTest( true );
pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.5f );
unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL;
int numTexCoords = 1;
pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 );
DECLARE_STATIC_VERTEX_SHADER( treeleaf_vs20 );
SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, true );
SET_STATIC_VERTEX_SHADER( treeleaf_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( treeleaf_ps20b );
SET_STATIC_PIXEL_SHADER( treeleaf_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( treeleaf_ps20 );
SET_STATIC_PIXEL_SHADER( treeleaf_ps20 );
}
// we are writing linear values from this shader.
// This is kinda wrong. We are writing linear or gamma depending on "IsHDREnabled" below.
// The COLOR really decides if we are gamma or linear.
pShaderShadow->EnableSRGBWrite( false );
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
// We need the view matrix
LoadViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_VIEWMODEL );
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, params[ LEAFCENTER ]->GetVecValue() );
LightState_t lightState;
pShaderAPI->GetDX9LightState( &lightState );
DECLARE_DYNAMIC_VERTEX_SHADER( treeleaf_vs20 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() );
SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 );
SET_DYNAMIC_VERTEX_SHADER( treeleaf_vs20 );
}
Draw( );
}
END_SHADER

View File

@ -0,0 +1,19 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
#define HDRTYPE HDR_TYPE_NONE
#include "common_ps_fxc.h"
struct PS_INPUT
{
float2 texCoord0 : TEXCOORD0;
float3 color : COLOR;
};
sampler BaseTextureSampler : register( s0 );
HALF4 main( PS_INPUT i ) : COLOR
{
float4 baseTex = tex2D( BaseTextureSampler, i.texCoord0 );
return FinalOutput( baseTex * float4( i.color, 1 ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
}

View File

@ -0,0 +1,61 @@
// STATIC: "HALFLAMBERT" "0..1"
// DYNAMIC: "DYNAMIC_LIGHT" "0..1"
// DYNAMIC: "STATIC_LIGHT" "0..1"
#include "common_vs_fxc.h"
static const bool g_bHalfLambert = HALFLAMBERT ? true : false;
const float3 cLeafCenter : register(SHADER_SPECIFIC_CONST_0);
struct VS_INPUT
{
// This is all of the stuff that we ever use.
float4 vPos : POSITION;
float4 vNormal : NORMAL;
float2 vTexCoord : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 projPos : POSITION;
float2 texCoord : TEXCOORD0;
float3 color : COLOR;
};
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
bool bDynamicLight = DYNAMIC_LIGHT ? true : false;
bool bStaticLight = STATIC_LIGHT ? true : false;
float3 worldPos;
worldPos = mul( v.vPos, cModel[0] );
float3 normal = v.vPos.xyz - cLeafCenter.xyz;
normal = normalize( normal );
float3 worldNormal = mul( float4( normal, 0.0f ), cModel[0] );
float3 lighting = DoLighting( worldPos, worldNormal, float3(0,0,0), bStaticLight, bDynamicLight, g_bHalfLambert );
float3 xAxis = float3( cViewModel[0].x, cViewModel[1].x, cViewModel[2].x );
float3 yAxis = float3( cViewModel[0].y, cViewModel[1].y, cViewModel[2].y );
worldPos += xAxis * v.vTexCoord.x;
worldPos += yAxis * (1.0f-v.vTexCoord.y);
float4 projPos = mul( float4(worldPos, 1.0f), cViewProj );
float3 light_vec = float3( 1.0f, 0.0, 1.0 );
light_vec = normalize( light_vec );
o.projPos = projPos;
// FIXME: if this shader gets put back into use, be sure this usage of normals jives with compressed verts
o.texCoord = v.vNormal.xy;
o.color = lighting;
return o;
}

View File

@ -0,0 +1,13 @@
ps.1.1
;------------------------------------------------------------------------------
; Draw a texture . . woo hoo!
; t0 - texture
;
; The texture coordinates need to be defined as follows:
; tc0 - texcoords
;------------------------------------------------------------------------------
tex t0 ; base color
mul r0, t0, v0

View File

@ -0,0 +1,297 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// STATIC: "MULTITEXTURE" "0..1"
// STATIC: "FRESNEL" "0..1"
// STATIC: "BLEND" "0..1"
// STATIC: "REFRACTALPHA" "0..1"
// STATIC: "HDRTYPE" "0..2"
// STATIC: "FLOWMAP" "0..1"
// STATIC: "FLOW_DEBUG" "0..1"
// DYNAMIC: "HDRENABLED" "0..1"
#include "common_fog_ps_fxc.h"
#include "common_ps_fxc.h"
#include "shader_constant_register_map.h"
// Constants
const float3 g_WaterFogColor : register( c0 );
const float4 g_CheapWaterParams : register( c1 );
#define g_CheapWaterStart g_CheapWaterParams.x
#define g_CheapWaterEnd g_CheapWaterParams.y
#define g_CheapWaterDeltaRecip g_CheapWaterParams.z
#define g_CheapWaterStartDivDelta g_CheapWaterParams.w
const float4 g_ReflectTint : register( c2 );
const float g_flTime : register( c10 );
const float4 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT ); // c11
const float4 g_PixelFogParams : register( PSREG_FOG_PARAMS ); // c12
const float4 g_vFlowParams1 : register( c13 );
#define g_flWorldUvScale ( g_vFlowParams1.x ) // 1.0f / 10.0f
#define g_flNormalUvScale ( g_vFlowParams1.y ) // 1.0f / 1.15f
#define g_flBumpStrength ( g_vFlowParams1.z ) // 3.0f
#define g_flTimeScale ( g_vFlowParams1.w ) // 1.0f
const float3 g_vFlowParams2 : register( c14 );
#define g_flFlowTimeIntervalInSeconds ( g_vFlowParams2.x ) // 0.4f // Number of seconds to lerp from texture 1 to texture 2
#define g_flFlowUvScrollDistance ( g_vFlowParams2.y ) // 0.25f // Distance in uv space to fetch
#define g_flNoiseScale ( g_vFlowParams2.z )
// Textures
sampler EnvmapSampler : register( s0 );
sampler NormalMapSampler : register( s1 );
#if REFRACTALPHA
sampler RefractSampler : register( s2 );
#endif
sampler FlowSampler : register( s3 );
sampler FlowNoiseSampler : register( s4 );
sampler NormalizeSampler : register( s6 );
struct PS_INPUT
{
float4 worldSpaceEyeVect_normalMapX : TEXCOORD1;
float3x3 tangentSpaceTranspose : TEXCOORD2;
float4 vRefract_W_ProjZ : TEXCOORD5;
#if MULTITEXTURE
float4 vExtraBumpTexCoord : TEXCOORD6;
#endif
float4 worldPos_normalMapY : TEXCOORD7;
};
float2 UnpackNormal2D( float2 vNormal )
{
return ( ( vNormal.xy * 2.0 ) - 1.0 );
}
float3 UnpackNormal3D( float3 vNormal )
{
return ( ( vNormal.xyz * 2.0 ) - 1.0 );
}
float3 ComputeNormalFromXY( float2 vXY )
{
float3 vNormalTs;
vNormalTs.xy = vXY.xy;
vNormalTs.z = sqrt( saturate( 1.0 - dot( vNormalTs.xy, vNormalTs.xy ) ) );
return vNormalTs.xyz;
}
float3 ComputeNormalFromRGTexture( float2 vRGPixel )
{
float3 vNormalTs;
vNormalTs.xy = UnpackNormal2D( vRGPixel.rg );
vNormalTs.z = sqrt( saturate( 1.0 - dot( vNormalTs.xy, vNormalTs.xy ) ) );
return vNormalTs.xyz;
}
float4 main( PS_INPUT i ) : COLOR
{
float2 normalMapTexCoord = float2( i.worldSpaceEyeVect_normalMapX.w, i.worldPos_normalMapY.w );
float3 vNormal;
#if ( FLOWMAP )
{
//*
float flWorldUvScale = g_flWorldUvScale;
float flNormalUvScale = g_flNormalUvScale;
float flFlowTimeIntervalInSeconds = g_flFlowTimeIntervalInSeconds;
float flFlowUvScrollDistance = g_flFlowUvScrollDistance;
float flBumpStrength = g_flBumpStrength;
float flTimeScale = g_flTimeScale;
float flNoiseScale = g_flNoiseScale;
//*/
/* River
float flWorldUvScale = 1.0f / 6.0f;
float flNormalUvScale = 1.0f / 0.5f;
float flFlowTimeIntervalInSeconds = 0.4f; // Number of seconds to lerp from texture 1 to texture 2
float flFlowUvScrollDistance = 0.2f; // Distance in uv space to fetch
float flBumpStrength = 1.0f;
float flTimeScale = 0.75f;
//*/
/* Swamp - Heavy churn
float flWorldUvScale = 1.0f / 10.0f;
float flNormalUvScale = 1.0f / 1.15f;
float flFlowTimeIntervalInSeconds = 0.4f; // Number of seconds to lerp from texture 1 to texture 2
float flFlowUvScrollDistance = 0.25f; // Distance in uv space to fetch
float flBumpStrength = 3.0f;
float flTimeScale = 1.0f;
//*/
/* Swamp - Calmer
float flWorldUvScale = 1.0f / 10.0f;
float flNormalUvScale = 1.0f / 1.15f;
float flFlowTimeIntervalInSeconds = 0.25f; // Number of seconds to lerp from texture 1 to texture 2
float flFlowUvScrollDistance = 0.15f; // Distance in uv space to fetch
float flBumpStrength = 1.05f;
float flTimeScale = 0.35f;
//*/
// Input uv
float2 vWorldUv = normalMapTexCoord.xy * flWorldUvScale;
float2 vUv1 = float2( i.worldPos_normalMapY.x, -i.worldPos_normalMapY.y ) * flNormalUvScale;
float2 vUv2 = vUv1.xy;
// Noise texture is used to offset the time interval different spatially so we don't see pulsing
float flNoise = tex2D( FlowNoiseSampler, float2( i.worldPos_normalMapY.x, -i.worldPos_normalMapY.y ) * flNoiseScale ).g;
// Flow texel has a 2D flow vector in the rg channels of the texture
float4 vFlowTexel = tex2D( FlowSampler, vWorldUv.xy );
#if FLOW_DEBUG
{
return float4( vFlowTexel.rgb, 0 );
}
#endif
// Unpack world flow vector from texture
float2 vFlowVectorTs = ( vFlowTexel.rg * 2.0f ) - 1.0f;
float flTimeInIntervals = ( ( g_flTime * flTimeScale ) + flNoise ) / ( flFlowTimeIntervalInSeconds * 2.0f );
float flScrollTime1 = frac( flTimeInIntervals );
float flScrollTime2 = frac( flTimeInIntervals + 0.5f ); // Half an interval off from texture 1
// Every interval has a unique offset so we don't see the same bump texels repeating continuously
float flOffset1 = floor( flTimeInIntervals ) * 0.311f;
float flOffset2 = floor( flTimeInIntervals + 0.5f ) * 0.311f + 0.5f; // The +0.5 is to match the phase offset
// Final flow uv is originalUv + interval offset + ( flowvector * scroll
float2 vFlowUv1 = vUv1.xy + flOffset1 + ( flScrollTime1 * ( flFlowUvScrollDistance * vFlowVectorTs.xy ) );
float2 vFlowUv2 = vUv2.xy + flOffset2 + ( flScrollTime2 * ( flFlowUvScrollDistance * vFlowVectorTs.xy ) );
// Lerp values to blend between the two layers of bump
float flWeight1 = abs( ( 2.0f * frac( flTimeInIntervals + 0.5f ) ) - 1.0f );
float flWeight2 = abs( ( 2.0f * frac( flTimeInIntervals ) ) - 1.0f );
float4 vNormalTexel1 = tex2D( NormalMapSampler, vFlowUv1.xy );
float4 vNormalTexel2 = tex2D( NormalMapSampler, vFlowUv2.xy );
float3 vNormal1 = ( vNormalTexel1.rgb );
float3 vNormal2 = ( vNormalTexel2.rgb );
// Combine both layers
vNormal.xy = UnpackNormal2D( lerp( vNormal1.xy, vNormal2.xy, flWeight2 ) );
// Change bump strength based on the length of the flow vector
//vNormal.xy *= ( length( vFlowVectorTs.xy ) + 0.05f ) * flBumpStrength;
vNormal.xy *= ( ( vFlowVectorTs.x * vFlowVectorTs.x + vFlowVectorTs.y * vFlowVectorTs.y ) + 0.05f ) * flBumpStrength;
// Generate normal from 2D scaled normal
vNormal.xyz = ComputeNormalFromXY( vNormal.xy );
}
#elif ( MULTITEXTURE )
{
vNormal.xyz = tex2D( NormalMapSampler, normalMapTexCoord );
float3 vNormal1 = tex2D( NormalMapSampler, i.vExtraBumpTexCoord.xy );
float3 vNormal2 = tex2D( NormalMapSampler, i.vExtraBumpTexCoord.zw );
vNormal = 0.33 * ( vNormal + vNormal1 + vNormal2 );
vNormal = 2.0 * vNormal - 1.0;
}
#else
{
vNormal.xyz = DecompressNormal( NormalMapSampler, normalMapTexCoord, NORM_DECODE_NONE );
}
#endif
float3 worldSpaceNormal = mul( vNormal, i.tangentSpaceTranspose );
float3 worldSpaceEye;
float flWorldSpaceDist = 1.0f;
#ifdef NV3X
// for some reason, fxc doesn't convert length( half3 v ) into all _pp opcodes.
#if ( BLEND )
{
worldSpaceEye = i.worldSpaceEyeVect_normalMapX.xyz;
float worldSpaceDistSqr = dot( worldSpaceEye, worldSpaceEye );
float rcpWorldSpaceDist = rsqrt( worldSpaceDistSqr );
worldSpaceEye *= rcpWorldSpaceDist;
flWorldSpaceDist = worldSpaceDistSqr * rcpWorldSpaceDist;
}
#else
{
worldSpaceEye = NormalizeWithCubemap( NormalizeSampler, i.worldSpaceEyeVect_normalMapX.xyz );
}
#endif
#else // !NV3X
#if ( BLEND )
{
worldSpaceEye = i.worldSpaceEyeVect_normalMapX.xyz;
flWorldSpaceDist = length( worldSpaceEye );
worldSpaceEye /= flWorldSpaceDist;
}
#else
{
worldSpaceEye = NormalizeWithCubemap( NormalizeSampler, i.worldSpaceEyeVect_normalMapX.xyz );
}
#endif
#endif
float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, worldSpaceEye );
float3 specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect );
specularLighting *= g_ReflectTint;
#if FRESNEL
// FIXME: It's unclear that we want to do this for cheap water
// but the code did this previously and I didn't want to change it
float flDotResult = dot( worldSpaceEye, worldSpaceNormal );
flDotResult = 1.0f - max( 0.0f, flDotResult );
float flFresnelFactor = flDotResult * flDotResult;
flFresnelFactor *= flFresnelFactor;
flFresnelFactor *= flDotResult;
#else
float flFresnelFactor = g_ReflectTint.a;
#endif
float flAlpha;
#if ( BLEND )
{
float flReflectAmount = saturate( flWorldSpaceDist * g_CheapWaterDeltaRecip - g_CheapWaterStartDivDelta );
flAlpha = saturate( flFresnelFactor + flReflectAmount );
#if REFRACTALPHA
// Perform division by W only once
float ooW = 1.0f / i.vRefract_W_ProjZ.z;
float2 unwarpedRefractTexCoord = i.vRefract_W_ProjZ * ooW;
float fogDepthValue = tex2D( RefractSampler, unwarpedRefractTexCoord ).a;
// Fade on the border between the water and land.
flAlpha *= saturate( ( fogDepthValue - .05f ) * 20.0f );
#endif
}
#else
{
flAlpha = 1.0f;
#if HDRTYPE == 0 || HDRENABLED == 0
specularLighting = lerp( g_WaterFogColor, specularLighting, flFresnelFactor );
#else
specularLighting = lerp( GammaToLinear( g_WaterFogColor ), specularLighting, flFresnelFactor );
#endif
}
#endif
// multiply the color by alpha.since we are using alpha blending to blend against dest alpha for borders.
#if (PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE)
float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_PixelFogParams, g_EyePos.xyz, i.worldPos_normalMapY.xyz, i.vRefract_W_ProjZ.w );
#else
float fogFactor = 0;
#endif
return FinalOutput( float4( specularLighting, flAlpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR );
}

View File

@ -0,0 +1,86 @@
// STATIC: "BLEND" "0..1"
#include "common_vs_fxc.h"
struct VS_INPUT
{
float4 vPos : POSITION;
float4 vNormal : NORMAL;
float2 vNormalMapCoord : TEXCOORD0;
float3 vTangentS : TANGENT;
float3 vTangentT : BINORMAL;
};
struct VS_OUTPUT
{
float4 projPos : POSITION;
#if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 )
float fog : FOG;
#endif
float4 worldVertToEyeVector_normalMapX : TEXCOORD1;
float3x3 tangentSpaceTranspose : TEXCOORD2;
float4 vRefract_W_ProjZ : TEXCOORD5;
float4 vExtraBumpTexCoord : TEXCOORD6;
float4 worldPos_normalMapY : TEXCOORD7;
};
const float4 cNormalMapTransform[2] : register( SHADER_SPECIFIC_CONST_0 );
const float4 TexOffsets : register( SHADER_SPECIFIC_CONST_3 );
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
float3 vObjNormal;
DecompressVertex_Normal( v.vNormal, vObjNormal );
float4 projPos;
float3 worldPos;
projPos = mul( v.vPos, cModelViewProj );
o.projPos = projPos;
#if BLEND
// Map projected position to the reflection texture
o.vRefract_W_ProjZ.x = projPos.x;
o.vRefract_W_ProjZ.y = -projPos.y; // invert Y
o.vRefract_W_ProjZ.xy = (o.vRefract_W_ProjZ + projPos.w) * 0.5f;
o.vRefract_W_ProjZ.z = projPos.w;
#endif
o.vRefract_W_ProjZ.w = projPos.z;
worldPos = mul( v.vPos, cModel[0] );
float3 worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] );
float3 worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] );
float3 worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] );
o.tangentSpaceTranspose[0] = worldTangentS;
o.tangentSpaceTranspose[1] = worldTangentT;
o.tangentSpaceTranspose[2] = worldNormal;
float3 worldVertToEyeVector = VSHADER_VECT_SCALE * (cEyePos - worldPos);
o.worldVertToEyeVector_normalMapX.xyz = worldVertToEyeVector;
// FIXME: need to add a normalMapTransform to all of the water shaders.
//o.worldVertToEyeVector_normalMapX.w = dot( v.vNormalMapCoord, cNormalMapTransform[0] ) + cNormalMapTransform[0].w;
//o.worldPos_normalMapY.w = dot( v.vNormalMapCoord, cNormalMapTransform[1] ) + cNormalMapTransform[1].w;
o.worldVertToEyeVector_normalMapX.w = v.vNormalMapCoord.x;
o.worldPos_normalMapY.w = v.vNormalMapCoord.y;
float f45x=v.vNormalMapCoord.x+v.vNormalMapCoord.y;
float f45y=v.vNormalMapCoord.y-v.vNormalMapCoord.x;
o.vExtraBumpTexCoord.x=f45x*0.1+TexOffsets.x;
o.vExtraBumpTexCoord.y=f45y*0.1+TexOffsets.y;
o.vExtraBumpTexCoord.z=v.vNormalMapCoord.y*0.45+TexOffsets.z;
o.vExtraBumpTexCoord.w=v.vNormalMapCoord.x*0.45+TexOffsets.w;
o.worldPos_normalMapY.xyz = worldPos;
#if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 )
o.fog = CalcFixedFunctionFog( worldPos, FOGTYPE_RANGE );
#endif
return o;
}

View File

@ -0,0 +1,160 @@
//============ Copyright (c) Valve Corporation, All rights reserved. ============
// STATIC: "BASETEXTURE" "0..1"
// STATIC: "MULTITEXTURE" "0..1"
// STATIC: "FLASHLIGHT" "0..1"
// STATIC: "LIGHTMAPWATERFOG" "0..1"
// STATIC: "FLOWMAP" "0..1"
// Multitexture and basetexture are mutually exclusive.
// SKIP: $MULTITEXTURE && $BASETEXTURE
// flowmap doesn't play with multitexture or basetexture
// SKIP: $FLOWMAP && $MULTITEXTURE
// Have to have the flashlight on to get flashlightshadows.
// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 )
// basetexture doesn't work with flashlight or lightmapwaterfog. multitexture doesn't either. We don't use basetexture or multitexture in newer code and instead use flowmap and flashlight.
// SKIP: ( $FLASHLIGHT || $LIGHTMAPWATERFOG ) && ( ( $BASETEXTURE && !$FLOWMAP ) || $MULTITEXTURE )
#include "common_vs_fxc.h"
const float4 cBumpTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_1 );
const float4 TexOffsets : register( SHADER_SPECIFIC_CONST_3 );
#if FLASHLIGHT
const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_4 );
#endif
struct VS_INPUT
{
float4 vPos : POSITION;
float4 vNormal : NORMAL;
float4 vBaseTexCoord : TEXCOORD0;
float2 vLightmapTexCoord : TEXCOORD1;
float2 vLightmapTexCoordOffset : TEXCOORD2;
float3 vTangentS : TANGENT;
float3 vTangentT : BINORMAL0;
};
struct VS_OUTPUT
{
float4 vProjPos_POSITION : POSITION;
#if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 )
float fog : FOG;
#endif
float2 vBumpTexCoord : TEXCOORD0;
float3 vPositionToCameraRayWs : TEXCOORD1;
float4 vReflectXY_vRefractYX : TEXCOORD2;
float4 vProjPos : TEXCOORD3;
float3 worldPos : TEXCOORD4;
#if FLASHLIGHT
float4 flashlightSpacePos : TEXCOORD5;
#endif
#if MULTITEXTURE
float4 vExtraBumpTexCoord : TEXCOORD5;
#endif
#if ( BASETEXTURE && !FLOWMAP )
float4 lightmapTexCoord1And2 : TEXCOORD5;
float2 lightmapTexCoord3 : TEXCOORD6;
#endif
#if LIGHTMAPWATERFOG
float2 lightmapTexCoord : TEXCOORD7;
#endif
};
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o;
float3 vObjNormal;
DecompressVertex_Normal( v.vNormal, vObjNormal );
// Projected position
float4 vProjPos = mul( v.vPos, cModelViewProj );
o.vProjPos = o.vProjPos_POSITION = vProjPos;
// Project tangent basis
float2 vProjTangentS = mul( v.vTangentS, cViewProj );
float2 vProjTangentT = mul( v.vTangentT, cViewProj );
// Map projected position to the reflection texture
float2 vReflectPos;
vReflectPos = (vProjPos.xy + vProjPos.w) * 0.5f;
// Map projected position to the refraction texture
float2 vRefractPos;
vRefractPos.x = vProjPos.x;
vRefractPos.y = -vProjPos.y; // invert Y
vRefractPos = (vRefractPos + vProjPos.w) * 0.5f;
// Reflection transform
o.vReflectXY_vRefractYX = float4( vReflectPos.x, vReflectPos.y, vRefractPos.y, vRefractPos.x );
// Compute fog based on the position
float3 vWorldPos = mul( v.vPos, cModel[0] );
o.worldPos = vWorldPos;
#if ( !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 ) )
{
o.fog = CalcFixedFunctionFog( vWorldPos, FOGTYPE_RANGE );
}
#endif
// Eye vector
float3 vPositionToCameraRayWs = cEyePos.xyz - vWorldPos.xyz;
// Transform to the tangent space
//o.vTangentEyeVect.x = dot( vPositionToCameraRayWs, v.vTangentS );
//o.vTangentEyeVect.y = dot( vPositionToCameraRayWs, v.vTangentT );
//o.vTangentEyeVect.z = dot( vPositionToCameraRayWs, vObjNormal );
o.vPositionToCameraRayWs.xyz = vPositionToCameraRayWs.xyz;
// Tranform bump coordinates
o.vBumpTexCoord.x = dot( v.vBaseTexCoord, cBumpTexCoordTransform[0] );
o.vBumpTexCoord.y = dot( v.vBaseTexCoord, cBumpTexCoordTransform[1] );
float f45x=v.vBaseTexCoord.x+v.vBaseTexCoord.y;
float f45y=v.vBaseTexCoord.y-v.vBaseTexCoord.x;
#if ( MULTITEXTURE )
{
o.vExtraBumpTexCoord.x=f45x*0.1+TexOffsets.x;
o.vExtraBumpTexCoord.y=f45y*0.1+TexOffsets.y;
o.vExtraBumpTexCoord.z=v.vBaseTexCoord.y*0.45+TexOffsets.z;
o.vExtraBumpTexCoord.w=v.vBaseTexCoord.x*0.45+TexOffsets.w;
}
#endif
#if ( BASETEXTURE && !FLOWMAP )
{
o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord + v.vLightmapTexCoordOffset;
float2 lightmapTexCoord2 = o.lightmapTexCoord1And2.xy + v.vLightmapTexCoordOffset;
float2 lightmapTexCoord3 = lightmapTexCoord2 + v.vLightmapTexCoordOffset;
// reversed component order
o.lightmapTexCoord1And2.w = lightmapTexCoord2.x;
o.lightmapTexCoord1And2.z = lightmapTexCoord2.y;
o.lightmapTexCoord3.xy = lightmapTexCoord3;
}
#endif
#if LIGHTMAPWATERFOG
{
o.lightmapTexCoord.xy = v.vLightmapTexCoord.xy;
}
#endif
#if FLASHLIGHT
{
o.flashlightSpacePos = mul( float4( vWorldPos, 1.0f ), g_FlashlightWorldToTexture );
}
#endif
return o;
}

View File

@ -0,0 +1,10 @@
ps.1.1
tex t0 ; basetexture
tex t1 ; lightmap
mov r0.a, 1-t1.a
;mov r0.rgb, t0 ; * 2 * (overbrightFactor/2)
;mov_x2 r0.rgb, t0 ; * 2 * (overbrightFactor/2)
mul r0.rgb, t0, t1;
mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2)

View File

@ -0,0 +1,37 @@
vs.1.1
# DYNAMIC: "DOWATERFOG" "0..1"
#include "macros.vsh"
local( $worldPos, $worldNormal, $projPos, $reflectionVector );
&AllocateRegister( \$projPos );
dp4 $projPos.x, $vPos, $cModelViewProj0
dp4 $projPos.y, $vPos, $cModelViewProj1
dp4 $projPos.z, $vPos, $cModelViewProj2
dp4 $projPos.w, $vPos, $cModelViewProj3
mov oPos, $projPos
&AllocateRegister( \$worldPos );
; garymcthack
dp4 $worldPos.z, $vPos, $cModel2
&CalcFog( $worldPos, $projPos );
&FreeRegister( \$worldPos );
&FreeRegister( \$projPos );
;------------------------------------------------------------------------------
; Texture coordinates
;------------------------------------------------------------------------------
; base texcoords
mov oT0, $vTexCoord0
; lightmap texcoords
mov oT1, $vTexCoord1
&FreeRegister( \$worldPos ); # garymcthack

View File

@ -0,0 +1,42 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// STATIC: "PASS" "0..1"
#define HDRTYPE HDR_TYPE_NONE
#include "common_ps_fxc.h"
// CENTROID: TEXCOORD1
sampler BaseSampler : register( s0 );
sampler LightmapSampler: register( s1 );
sampler LightmapAlphaSampler: register( s2 );
struct PS_INPUT
{
float2 baseCoord : TEXCOORD0;
float2 lightmapCoord : TEXCOORD1;
};
float4 main( PS_INPUT i ) : COLOR
{
bool bAlphaPass = PASS ? true : false;
float4 base = tex2D( BaseSampler, i.baseCoord );
float4 lightmap = tex2D( LightmapSampler, i.lightmapCoord );
float4 alpha = tex2D( LightmapAlphaSampler, i.lightmapCoord );
float4 color;
base.a = dot( base, HALF3( HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f) ) );
color = 2.0f * base * lightmap; // The 2x is for an assumed overbright 2 (it's always 2 on dx9)
if( bAlphaPass )
{
// Don't care about color, just return pre-multiplied alpha
return FinalOutput( float4( 0.0f, 0.0f, 1.0f, (1.0f - alpha.a) * color.a ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
}
else
{
return FinalOutput( float4( color.rgb, (1.0f - alpha.a) ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
}
}

View File

@ -0,0 +1,48 @@
vs.1.1
# DYNAMIC: "DOWATERFOG" "0..1"
#include "macros.vsh"
local( $worldPos, $worldNormal, $projPos, $reflectionVector );
&AllocateRegister( \$projPos );
dp4 $projPos.x, $vPos, $cModelViewProj0
dp4 $projPos.y, $vPos, $cModelViewProj1
dp4 $projPos.z, $vPos, $cModelViewProj2
dp4 $projPos.w, $vPos, $cModelViewProj3
mov oPos, $projPos
&AllocateRegister( \$worldPos );
; garymcthack
dp4 $worldPos.z, $vPos, $cModel2
&CalcFog( $worldPos, $projPos );
&FreeRegister( \$worldPos );
&FreeRegister( \$projPos );
;------------------------------------------------------------------------------
; Texture coordinates
;------------------------------------------------------------------------------
; base texcoords
dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0
dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1
dp4 oT1.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2
dp4 oT1.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3
; lightmap texcoords
mov oT2, $vTexCoord1
; detail
dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4
dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5
; Now the basetexture/basetexture2 blend uses vertex color, so send it into the psh.
mov oD0, $vColor
&FreeRegister( \$worldPos ); # garymcthack

View File

@ -0,0 +1,16 @@
ps.1.1
;------------------------------------------------------------------------------
; Draw a texture . . woo hoo!
; t0 - texture
;
; The texture coordinates need to be defined as follows:
; tc0 - texcoords
;------------------------------------------------------------------------------
tex t0
tex t1
mul r0.rgb, t1, t0 ; fold in lightmap (color)
+mov r0.a, v0.a ; fold in lightmap (alpha)
mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2)

View File

@ -0,0 +1,10 @@
ps.1.1
tex t0 ; basetexture
tex t1 ; basetexture2
tex t2 ; lightmap
; The editor uses vertex alpha as the blend factor
lrp r0, 1-v0.a, t1, t0
mul r0, r0, t2
mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2)

View File

@ -0,0 +1,50 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// STATIC: "MACROS" "0..1"
#define HDRTYPE HDR_TYPE_NONE
#include "common_ps_fxc.h"
sampler BaseSampler : register( s0 );
// NOTE: LightmapSampler is at the same place as the lightmap sampler in lightmappedgeneric so that we have
// generally the same texture state here.
sampler LightmapSampler: register( s1 );
sampler BaseSampler2: register( s2 );
sampler LightmapAlphaSampler: register( s3 );
sampler MacrosSampler: register( s4 );
struct PS_INPUT
{
float2 baseCoord : TEXCOORD0;
float2 baseCoord2 : TEXCOORD1;
// CENTROID: TEXCOORD2
#if defined( _X360 )
float2 lightmapCoord : TEXCOORD2_centroid;
#else
float2 lightmapCoord : TEXCOORD2;
#endif
float2 macrosCoord : TEXCOORD3;
};
float4 main( PS_INPUT i ) : COLOR
{
bool bMacros = MACROS ? true : false;
float4 base = tex2D( BaseSampler, i.baseCoord );
float4 base2 = tex2D( BaseSampler2, i.baseCoord2 );
float4 lightmap = tex2D( LightmapSampler, i.lightmapCoord );
float blendFactor = lightmap.a;
float4 color = 2.0f * lightmap * lerp( base2, base, blendFactor );
if( bMacros )
{
float4 macros = tex2D( MacrosSampler, i.macrosCoord );
// Not sure what to do with macro alpha
color.rgb *= 2.0f * lerp( macros.a, macros.b, blendFactor );
}
return FinalOutput( color, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
}

View File

@ -0,0 +1,62 @@
#include "common_fog_vs_fxc.h"
#include "common_vs_fxc.h"
static const int g_FogType = DOWATERFOG;
const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 );
const float4 cBaseTexCoordTransform2[2] : register( SHADER_SPECIFIC_CONST_2 );
const float4 cMacrosTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 );
struct VS_INPUT
{
// This is all of the stuff that we ever use.
float4 vPos : POSITION;
float4 vColor : COLOR0;
float4 vTexCoord0 : TEXCOORD0;
float4 vTexCoord1 : TEXCOORD1;
};
struct VS_OUTPUT
{
float4 projPos : POSITION;
#if !defined( _X360 )
float fog : FOG;
#endif
float2 baseCoord : TEXCOORD0;
float2 baseCoord2 : TEXCOORD1;
float2 lightmapCoord : TEXCOORD2;
float2 macrosCoord : TEXCOORD3;
float4 color : COLOR0;
};
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
float3 worldNormal, worldPos;
float2 texCoord;
worldPos = mul( v.vPos, cModel[0] );
float4 projPos = mul( float4( worldPos, 1 ), cViewProj );
o.projPos = projPos;
o.fogFactorsYZW = CalcFog( worldPos, projPos, g_FogType );
#if !defined( _X360 )
o.fog = o.fogFactorsYZW;
#endif
o.color = v.vColor;
o.baseCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] );
o.baseCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] );
o.baseCoord2.x = dot( v.vTexCoord0, cBaseTexCoordTransform2[0] );
o.baseCoord2.y = dot( v.vTexCoord0, cBaseTexCoordTransform2[1] );
o.lightmapCoord = v.vTexCoord1;
o.macrosCoord.x = dot( v.vTexCoord0, cMacrosTexCoordTransform[0] );
o.macrosCoord.y = dot( v.vTexCoord0, cMacrosTexCoordTransform[1] );
return o;
}

View File

@ -0,0 +1,71 @@
//========= Copyright <20> 1996-2006, Valve Corporation, All rights reserved. ============//
#include "BaseVSShader.h"
#include "aftershock_helper.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
DEFINE_FALLBACK_SHADER( Aftershock, Aftershock_dx9 )
BEGIN_VS_SHADER( Aftershock_dx9, "Aftershock" )
BEGIN_SHADER_PARAMS
SHADER_PARAM( COLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Color tint" )
SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" )
SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "normal map" )
SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" )
SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" )
SHADER_PARAM( SILHOUETTETHICKNESS, SHADER_PARAM_TYPE_FLOAT, "1", "" )
SHADER_PARAM( SILHOUETTECOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Silhouette color tint" )
SHADER_PARAM( GROUNDMIN, SHADER_PARAM_TYPE_FLOAT, "1", "" )
SHADER_PARAM( GROUNDMAX, SHADER_PARAM_TYPE_FLOAT, "1", "" )
SHADER_PARAM( BLURAMOUNT, SHADER_PARAM_TYPE_FLOAT, "1", "" )
SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0", "Needs CurrentTime Proxy" )
END_SHADER_PARAMS
void SetupVarsAftershock( AftershockVars_t &info )
{
info.m_nColorTint = COLORTINT;
info.m_nRefractAmount = REFRACTAMOUNT;
info.m_nBumpmap = NORMALMAP;
info.m_nBumpFrame = BUMPFRAME;
info.m_nBumpTransform = BUMPTRANSFORM;
info.m_nSilhouetteThickness = SILHOUETTETHICKNESS;
info.m_nSilhouetteColor = SILHOUETTECOLOR;
info.m_nGroundMin = GROUNDMIN;
info.m_nGroundMax = GROUNDMAX;
info.m_nBlurAmount = BLURAMOUNT;
info.m_nTime = TIME;
}
SHADER_INIT_PARAMS()
{
AftershockVars_t info;
SetupVarsAftershock( info );
InitParamsAftershock( this, params, pMaterialName, info );
}
SHADER_FALLBACK
{
return 0;
}
SHADER_INIT
{
AftershockVars_t info;
SetupVarsAftershock( info );
InitAftershock( this, params, info );
}
SHADER_DRAW
{
AftershockVars_t info;
SetupVarsAftershock( info );
DrawAftershock( this, params, pShaderAPI, pShaderShadow, info, vertexCompression );
}
END_SHADER

View File

@ -0,0 +1,199 @@
//========= Copyright <20> 1996-2006, Valve Corporation, All rights reserved. ============//
#include "BaseVSShader.h"
#include "mathlib/VMatrix.h"
#include "aftershock_helper.h"
#include "convar.h"
// Auto generated inc files
#include "aftershock_vs20.inc"
#include "aftershock_ps20.inc"
#include "aftershock_ps20b.inc"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
void InitParamsAftershock( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, AftershockVars_t &info )
{
// Set material flags
SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES );
SET_FLAGS( MATERIAL_VAR_TRANSLUCENT );
SET_FLAGS2( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE );
// Set material parameter default values
if ( ( info.m_nRefractAmount != -1 ) && ( !params[info.m_nRefractAmount]->IsDefined() ) )
{
params[info.m_nRefractAmount]->SetFloatValue( kDefaultRefractAmount );
}
if ( ( info.m_nColorTint != -1 ) && ( !params[info.m_nColorTint]->IsDefined() ) )
{
params[info.m_nColorTint]->SetVecValue( kDefaultColorTint[0], kDefaultColorTint[1], kDefaultColorTint[2], kDefaultColorTint[3] );
}
if( (info.m_nBumpFrame != -1 ) && !params[info.m_nBumpFrame]->IsDefined() )
{
params[info.m_nBumpFrame]->SetIntValue( 0 );
}
if ( ( info.m_nSilhouetteThickness != -1 ) && ( !params[info.m_nSilhouetteThickness]->IsDefined() ) )
{
params[info.m_nSilhouetteThickness]->SetFloatValue( kDefaultSilhouetteThickness );
}
if ( ( info.m_nSilhouetteColor != -1 ) && ( !params[info.m_nSilhouetteColor]->IsDefined() ) )
{
params[info.m_nSilhouetteColor]->SetVecValue( kDefaultSilhouetteColor[0], kDefaultSilhouetteColor[1], kDefaultSilhouetteColor[2], kDefaultSilhouetteColor[3] );
}
if ( ( info.m_nGroundMin != -1 ) && ( !params[info.m_nGroundMin]->IsDefined() ) )
{
params[info.m_nGroundMin]->SetFloatValue( kDefaultGroundMin );
}
if ( ( info.m_nGroundMax != -1 ) && ( !params[info.m_nGroundMax]->IsDefined() ) )
{
params[info.m_nGroundMax]->SetFloatValue( kDefaultGroundMax );
}
if ( ( info.m_nBlurAmount != -1 ) && ( !params[info.m_nBlurAmount]->IsDefined() ) )
{
params[info.m_nBlurAmount]->SetFloatValue( kDefaultBlurAmount );
}
SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nTime, 0.0f );
}
void InitAftershock( CBaseVSShader *pShader, IMaterialVar** params, AftershockVars_t &info )
{
// Load textures
if ( (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined() )
{
pShader->LoadTexture( info.m_nBumpmap );
}
}
void DrawAftershock( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI,
IShaderShadow* pShaderShadow, AftershockVars_t &info, VertexCompressionType_t vertexCompression )
{
bool bBumpMapping = ( info.m_nBumpmap == -1 ) || !params[info.m_nBumpmap]->IsTexture() ? 0 : 1;
SHADOW_STATE
{
// Set stream format (note that this shader supports compression)
unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED;
int nTexCoordCount = 1;
int userDataSize = 0;
pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize );
// Vertex Shader
DECLARE_STATIC_VERTEX_SHADER( aftershock_vs20 );
SET_STATIC_VERTEX_SHADER( aftershock_vs20 );
// Pixel Shader
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( aftershock_ps20b );
SET_STATIC_PIXEL_SHADER( aftershock_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( aftershock_ps20 );
SET_STATIC_PIXEL_SHADER( aftershock_ps20 );
}
// Textures
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Refraction texture
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Bump
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); // Not sRGB
pShaderShadow->EnableSRGBWrite( true );
// Blending
pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
pShaderShadow->EnableAlphaWrites( false );
// !!! We need to turn this back on because EnableAlphaBlending() above disables it!
//pShaderShadow->EnableDepthWrites( true );
}
DYNAMIC_STATE
{
// Set Vertex Shader Combos
DECLARE_DYNAMIC_VERTEX_SHADER( aftershock_vs20 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
SET_DYNAMIC_VERTEX_SHADER( aftershock_vs20 );
// Set Vertex Shader Constants
if ( info.m_nBumpTransform != -1 )
{
pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, info.m_nBumpTransform );
}
// Time % 1000
float vPackedVsConst1[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
float flTime = IS_PARAM_DEFINED( info.m_nTime ) && params[info.m_nTime]->GetFloatValue() > 0.0f ? params[info.m_nTime]->GetFloatValue() : pShaderAPI->CurrentTime();
vPackedVsConst1[0] = flTime;
vPackedVsConst1[0] -= (float)( (int)( vPackedVsConst1[0] / 1000.0f ) ) * 1000.0f;
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, vPackedVsConst1, 1 );
// Set Pixel Shader Combos
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( aftershock_ps20b );
SET_DYNAMIC_PIXEL_SHADER( aftershock_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( aftershock_ps20 );
SET_DYNAMIC_PIXEL_SHADER( aftershock_ps20 );
}
// Bind textures
pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 ); // Refraction Map
if ( bBumpMapping )
{
pShader->BindTexture( SHADER_SAMPLER1, info.m_nBumpmap, info.m_nBumpFrame );
}
// Set Pixel Shader Constants
float vEyePos[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
pShaderAPI->GetWorldSpaceCameraPosition( vEyePos );
pShaderAPI->SetPixelShaderConstant( 5, vEyePos, 1 );
float vPackedConst1[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
vPackedConst1[0] = IS_PARAM_DEFINED( info.m_nBlurAmount ) ? params[info.m_nBlurAmount]->GetFloatValue() : kDefaultBlurAmount;
vPackedConst1[1] = IS_PARAM_DEFINED( info.m_nRefractAmount ) ? params[info.m_nRefractAmount]->GetFloatValue() : kDefaultRefractAmount;
vPackedConst1[3] = vPackedVsConst1[0]; // Time
pShaderAPI->SetPixelShaderConstant( 6, vPackedConst1, 1 );
// Refract color tint
pShaderAPI->SetPixelShaderConstant( 7, IS_PARAM_DEFINED( info.m_nColorTint ) ? params[info.m_nColorTint]->GetVecValue() : kDefaultColorTint, 1 );
// Silhouette values
float vPackedConst8[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
vPackedConst8[0] = IS_PARAM_DEFINED( info.m_nSilhouetteColor ) ? params[info.m_nSilhouetteColor]->GetVecValue()[0] : kDefaultSilhouetteColor[0];
vPackedConst8[1] = IS_PARAM_DEFINED( info.m_nSilhouetteColor ) ? params[info.m_nSilhouetteColor]->GetVecValue()[1] : kDefaultSilhouetteColor[1];
vPackedConst8[2] = IS_PARAM_DEFINED( info.m_nSilhouetteColor ) ? params[info.m_nSilhouetteColor]->GetVecValue()[2] : kDefaultSilhouetteColor[2];
vPackedConst8[3] = IS_PARAM_DEFINED( info.m_nSilhouetteThickness ) ? params[info.m_nSilhouetteThickness]->GetFloatValue() : kDefaultSilhouetteThickness;
pShaderAPI->SetPixelShaderConstant( 8, vPackedConst8, 1 );
// Ground min/max
float vPackedConst9[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
vPackedConst9[0] = IS_PARAM_DEFINED( info.m_nGroundMin ) ? params[info.m_nGroundMin]->GetFloatValue() : kDefaultGroundMin;
vPackedConst9[1] = IS_PARAM_DEFINED( info.m_nGroundMax ) ? params[info.m_nGroundMax]->GetFloatValue() : kDefaultGroundMax;
pShaderAPI->SetPixelShaderConstant( 9, vPackedConst9, 1 );
// Set c0 and c1 to contain first two rows of ViewProj matrix
VMatrix mView, mProj;
pShaderAPI->GetMatrix( MATERIAL_VIEW, mView.m[0] );
pShaderAPI->GetMatrix( MATERIAL_PROJECTION, mProj.m[0] );
VMatrix mViewProj = mView * mProj;
mViewProj = mViewProj.Transpose3x3();
pShaderAPI->SetPixelShaderConstant( 0, mViewProj.m[0], 2 );
}
pShader->Draw();
}

View File

@ -0,0 +1,56 @@
//========= Copyright <20> 1996-2006, Valve Corporation, All rights reserved. ============//
#ifndef AFTERSHOCK_HELPER_H
#define AFTERSHOCK_HELPER_H
#ifdef _WIN32
#pragma once
#endif
#include <string.h>
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class CBaseVSShader;
class IMaterialVar;
class IShaderDynamicAPI;
class IShaderShadow;
//-----------------------------------------------------------------------------
// Init params/ init/ draw methods
//-----------------------------------------------------------------------------
struct AftershockVars_t
{
AftershockVars_t() { memset( this, 0xFF, sizeof(AftershockVars_t) ); }
int m_nColorTint;
int m_nRefractAmount;
int m_nBumpmap;
int m_nBumpFrame;
int m_nBumpTransform;
int m_nSilhouetteThickness;
int m_nSilhouetteColor;
int m_nGroundMin;
int m_nGroundMax;
int m_nBlurAmount;
int m_nTime;
};
// Default values (Arrays should only be vec[4])
static const float kDefaultColorTint[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
static const float kDefaultRefractAmount = 0.1f;
static const float kDefaultSilhouetteThickness = 0.2f;
static const float kDefaultSilhouetteColor[4] = { 0.3f, 0.3f, 0.5f, 1.0f };
static const float kDefaultGroundMin = -0.3f;
static const float kDefaultGroundMax = -0.1f;
static const float kDefaultBlurAmount = 0.01f;
void InitParamsAftershock( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, AftershockVars_t &info );
void InitAftershock( CBaseVSShader *pShader, IMaterialVar** params, AftershockVars_t &info );
void DrawAftershock( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI,
IShaderShadow* pShaderShadow, AftershockVars_t &info, VertexCompressionType_t vertexCompression );
#endif // AFTERSHOCK_HELPER_H

View File

@ -0,0 +1,159 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// Includes =======================================================================================
#include "common_vertexlitgeneric_dx9.h"
// Texture Samplers ===============================================================================
sampler g_tRefractionSampler : register( s0 );
sampler g_tBumpSampler : register( s1 );
// Shaders Constants and Globals ==================================================================
const float4 g_mViewProj0 : register( c0 ); // 1st row of matrix
const float4 g_mViewProj1 : register( c1 ); // 2nd row of matrix
const float4 g_vCameraPosition : register( c5 );
const float4 g_vPackedConst6 : register( c6 );
#define g_flBlurAmount g_vPackedConst6.x // 0.01f;
#define g_flRefractAmount g_vPackedConst6.y // Default = 1.0f
#define g_flTime g_vPackedConst6.w
const float4 g_cColorTint : register( c7 );
const float4 g_vPackedConst8 : register( c8 );
#define g_cSilhouetteColor g_vPackedConst8 //= { 0.3, 0.3, 0.5 };
#define g_flSilhouetteThickness g_vPackedConst8.w //= 0.2f;
const float2 g_vGroundMinMax : register( c9 ); //= { -0.3, -0.1 };
// 8 2D Poisson offsets (designed to use .xy and .wz swizzles (not .zw)
static const float4 g_vPoissonOffset[4] = { float4 (-0.0876f, 0.9703f, 0.5651f, 0.4802f ),
float4 ( 0.1851f, 0.1580f, -0.0617f, -0.2616f ),
float4 (-0.5477f, -0.6603f, 0.0711f, -0.5325f ),
float4 (-0.0751f, -0.8954f, 0.4054f, 0.6384f ) };
// Interpolated values ============================================================================
struct PS_INPUT
{
float3 vWorldNormal : TEXCOORD0; // World-space normal
float3 vWorldTangent : TEXCOORD1;
float3 vWorldBinormal : TEXCOORD2;
float3 vProjPosForRefract : TEXCOORD3;
float3 vWorldViewVector : TEXCOORD4;
float4 vUv0 : TEXCOORD5; // uv.xy, uvScroll.xy
float4 vUv1 : TEXCOORD6; // uv.xy, uvScroll.xy
float2 vUvGroundNoise : TEXCOORD7;
};
// Main ===========================================================================================
float4 main( PS_INPUT i ) : COLOR
{
/*
// Bump layer 0
float2 vUv0 = i.vUv0Uv1.xy;
float2 vUv0Scroll = i.vUv0Uv1.xy * 3.0f;
vUv0Scroll.y -= g_flTime * 0.1f;
float4 vBumpTexel0 = tex2D( g_tBumpSampler, vUv0Scroll.xy );
vBumpTexel0 = tex2D( g_tBumpSampler, vUv0.xy + (vBumpTexel0.xy*0.03) );
// Bump layer 1
float2 vUv1 = i.vUv0Uv1.xy * 10.0f;
float2 vUv1Scroll = i.vUv0Uv1.xy * 32.0f;
vUv1Scroll.y -= g_flTime * 0.1f;
float4 vBumpTexel1 = tex2D( g_tBumpSampler, vUv1Scroll.xy );
vBumpTexel1 = tex2D( g_tBumpSampler, vUv1.xy + (vBumpTexel1.xy*0.03) );
//*/
// Bump layer 0
float4 vBumpTexel0 = tex2D( g_tBumpSampler, i.vUv0.wz );
vBumpTexel0 = tex2D( g_tBumpSampler, i.vUv0.xy + ( vBumpTexel0.xy*0.03 ) );
// Bump layer 1
float4 vBumpTexel1 = tex2D( g_tBumpSampler, i.vUv1.wz );
vBumpTexel1 = tex2D( g_tBumpSampler, i.vUv1.xy + ( vBumpTexel1.xy*0.03 ) );
// Combine bump layers into tangetn normal
float3 vTangentNormal = ( vBumpTexel0 * 2.0f ) - 1.0f;
vTangentNormal.xyz += ( vBumpTexel1 * 2.0f - 1.0f ) * 0.5f; // * 0.5f;
// Transform into world space
float3 vWorldNormal = Vec3TangentToWorld( vTangentNormal.xyz, i.vWorldNormal, i.vWorldTangent, i.vWorldBinormal );
// Effect mask
//float flEffectMask = saturate( dot( -i.vWorldViewVector.xyz, i.vWorldNormal.xyz ) * lerp( 2.0f, 1.0f, g_flSilhouetteThickness ) );
float flEffectMask = saturate( dot( -i.vWorldViewVector.xyz, i.vWorldNormal.xyz ) * ( (2.0f - g_flSilhouetteThickness) ) );
// Simulate ground intersection
flEffectMask *= smoothstep( g_vGroundMinMax.x, g_vGroundMinMax.y, i.vWorldNormal.z );
// Soften mask by squaring term
flEffectMask *= flEffectMask;
// Silhouette mask
float flSilhouetteHighlightMask = saturate( flEffectMask * ( 1.0f - flEffectMask ) * 4.0f );
flSilhouetteHighlightMask *= flSilhouetteHighlightMask * flSilhouetteHighlightMask;
// Transform world space normal into clip space and project
float3 vProjNormal;
vProjNormal.x = dot( vWorldNormal.xyz, g_mViewProj0.xyz ); // 1st row
vProjNormal.y = dot( vWorldNormal.xyz, g_mViewProj1.xyz ); // 2nd row
// Compute coordinates for sampling refraction
float2 vRefractTexCoordNoWarp = i.vProjPosForRefract.xy / i.vProjPosForRefract.z;
float2 vRefractTexCoord = vProjNormal.xy;
float scale = lerp( 0.0f, g_flRefractAmount, flEffectMask );// * flEffectMask * flEffectMask ); // Using flEffectMask^3
vRefractTexCoord.xy *= scale;
vRefractTexCoord.xy += vRefractTexCoordNoWarp.xy;
// Blur by scalable Poisson filter
float flBlurAmount = g_flBlurAmount * flEffectMask;
float3 cRefract = tex2D( g_tRefractionSampler, vRefractTexCoord.xy );
cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[0].xy * flBlurAmount ) );
cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[0].wz * flBlurAmount ) );
cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[1].xy * flBlurAmount ) );
cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[1].wz * flBlurAmount ) );
cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[2].xy * flBlurAmount ) );
cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[2].wz * flBlurAmount ) );
cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[3].xy * flBlurAmount ) );
cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[3].wz * flBlurAmount ) );
cRefract /= 9.0f;
// Undo tone mapping
cRefract /= LINEAR_LIGHT_SCALE;
// Refract color tint
float fColorTintStrength = 1.0f - flEffectMask;
float3 cRefractColorTint = lerp( g_cColorTint, 1.0f, fColorTintStrength );
// Ground noise
//float flGroundNoise = tex2D( g_tBumpSampler, i.vUvGroundNoise.xy ).g;
//flGroundNoise *= smoothstep( g_vGroundMinMax.y, g_vGroundMinMax.y+0.4, -i.vWorldNormal.z );
//flGroundNoise = smoothstep( 0.2, 0.9, flGroundNoise );
//===============//
// Combine terms //
//===============//
float4 result;
result.rgb = cRefract.rgb * cRefractColorTint.rgb;
result.rgb += result.rgb * ( flSilhouetteHighlightMask * g_cSilhouetteColor.rgb );
//result.rgb += flGroundNoise;
//result.rgb = float3( 0.0, 0.0, 0.0 );
//result.rg = vRefractTexCoord.xy;
//result.rg = i.vUv0Uv1.xy;
//result.rgb = vBumpTexel0.rgb;
//result.rgb = vTangentNormal;
//result.rgb = vWorldNormal;
//result = flEffectMask;
//result = flSilhouetteHighlightMask;
//result = tex2D( g_tBumpSampler, i.vUvGroundNoise.xy ).y;
//result.rgb = flGroundNoise;
// Set alpha to...
result.a = flEffectMask;
return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); //go back to final output when it'll fit.
}

View File

@ -0,0 +1,110 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// DYNAMIC: "COMPRESSED_VERTS" "0..1"
// DYNAMIC: "SKINNING" "0..1"
// Includes
#include "common_vs_fxc.h"
// Globals
static const bool g_bSkinning = SKINNING ? true : false;
const float g_flTime : register( SHADER_SPECIFIC_CONST_0 );
const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_1 );
// Structs
struct VS_INPUT
{
float4 vPos : POSITION; // Position
float4 vNormal : NORMAL; // Normal
float4 vBoneWeights : BLENDWEIGHT; // Skin weights
float4 vBoneIndices : BLENDINDICES; // Skin indices
float4 vTexCoord0 : TEXCOORD0; // Base texture coordinates
float4 vTangent : TANGENT;
};
struct VS_OUTPUT
{
float4 vProjPosition : POSITION; // Projection-space position
float3 vWorldNormal : TEXCOORD0; // World-space normal
float3 vWorldTangent : TEXCOORD1;
float3 vWorldBinormal : TEXCOORD2;
float3 vProjPosForRefract : TEXCOORD3;
float3 vWorldViewVector : TEXCOORD4;
float4 vUv0 : TEXCOORD5;
float4 vUv1 : TEXCOORD6;
float2 vUvGroundNoise : TEXCOORD7;
};
// Main
VS_OUTPUT main( const VS_INPUT i )
{
VS_OUTPUT o;
float4 vObjPosition = i.vPos;
float4 vObjTangent = i.vTangent;
float3 vObjNormal;
DecompressVertex_Normal( i.vNormal, vObjNormal );
// Transform the position
float3 vWorldPosition = { 0.0f, 0.0f, 0.0f };
float3 vWorldNormal = { 0.0f, 0.0f, 0.0f };
float3 vWorldTangent = { 0.0f, 0.0f, 0.0f };
float3 vWorldBinormal = { 0.0f, 0.0f, 0.0f };
SkinPositionNormalAndTangentSpace( g_bSkinning, vObjPosition, vObjNormal.xyz, vObjTangent.xyzw, i.vBoneWeights, i.vBoneIndices, vWorldPosition, vWorldNormal, vWorldTangent, vWorldBinormal );
vWorldNormal.xyz = normalize( vWorldNormal.xyz );
vWorldTangent.xyz = normalize( vWorldTangent.xyz );
vWorldBinormal.xyz = normalize( vWorldBinormal.xyz );
o.vWorldNormal.xyz = vWorldNormal.xyz;
o.vWorldTangent.xyz = vWorldTangent.xyz;
o.vWorldBinormal.xyz = vWorldBinormal.xyz;
// Transform into projection space
float4 vProjPosition = mul( float4( vWorldPosition, 1.0f ), cViewProj );
o.vProjPosition = vProjPosition;
// Map projected position to the refraction texture
float2 vRefractPos;
vRefractPos.x = vProjPosition.x;
vRefractPos.y = -vProjPosition.y; // Invert Y
vRefractPos = (vRefractPos + vProjPosition.w) * 0.5f;
o.vProjPosForRefract.xyz = float3(vRefractPos.x, vRefractPos.y, vProjPosition.w);
// View vector
float3 vWorldViewVector = normalize (vWorldPosition.xyz - cEyePos.xyz);
o.vWorldViewVector.xyz = vWorldViewVector.xyz;
// Tangent space transform
//o.mTangentSpaceTranspose[0] = float3( vWorldTangent.x, vWorldBinormal.x, vWorldNormal.x );
//o.mTangentSpaceTranspose[1] = float3( vWorldTangent.y, vWorldBinormal.y, vWorldNormal.y );
//o.mTangentSpaceTranspose[2] = float3( vWorldTangent.z, vWorldBinormal.z, vWorldNormal.z );
// Texture coordinates
float2 vBaseUv;
vBaseUv.x = dot( i.vTexCoord0.xy, cBaseTexCoordTransform[0] );
vBaseUv.y = dot( i.vTexCoord0.xy, cBaseTexCoordTransform[1] );
// Bump layer 0
float2 vUv0 = vBaseUv.xy;
float2 vUv0Scroll = vBaseUv.xy * 3.0f;
vUv0Scroll.y -= g_flTime * 0.1f;
o.vUv0.xy = vUv0.xy;
o.vUv0.wz = vUv0Scroll.xy;
// Bump layer 1
float2 vUv1 = vBaseUv.xy * 8.0f;
float2 vUv1Scroll = vBaseUv.xy * 16.0f;
vUv1Scroll.y -= g_flTime * 0.1f;
o.vUv1.xy = vUv1.xy;
o.vUv1.wz = vUv1Scroll.xy;
// Ground noise
o.vUvGroundNoise.xy = vBaseUv.xy;
o.vUvGroundNoise.x *= 3.5f;
o.vUvGroundNoise.y *= 0.2105f;
o.vUvGroundNoise.y -= g_flTime * 0.04f;
return o;
}

View File

@ -0,0 +1,19 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
#include "common_ps_fxc.h"
sampler TexSampler : register( s0 );
float g_flBloomAmount : register( c0 );
struct PS_INPUT
{
HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate
};
float4 main( PS_INPUT i ) : COLOR
{
float4 result = g_flBloomAmount * tex2D( TexSampler, i.baseTexCoord );
result.a = 1.0f;
return result; //FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
}

View File

@ -0,0 +1,34 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// blurs colors by averages
// bleeds alpha by max of current vs averages
sampler g_texSampler : register( s0 );
struct PS_INPUT
{
float2 uv : TEXCOORD0;
};
float2 g_vPsTapOffsets[2] : register( c0 );
float4 main( PS_INPUT i ) : COLOR
{
float4 cOut;
cOut = tex2D( g_texSampler, float2( i.uv.x + g_vPsTapOffsets[0].x, i.uv.y + g_vPsTapOffsets[0].y ) );
cOut += tex2D( g_texSampler, float2( i.uv.x , i.uv.y + g_vPsTapOffsets[0].y ) );
cOut += tex2D( g_texSampler, float2( i.uv.x - g_vPsTapOffsets[0].x, i.uv.y + g_vPsTapOffsets[0].y ) );
cOut += tex2D( g_texSampler, float2( i.uv.x + g_vPsTapOffsets[0].x, i.uv.y ) );
cOut += tex2D( g_texSampler, float2( i.uv.x , i.uv.y ) );
cOut += tex2D( g_texSampler, float2( i.uv.x - g_vPsTapOffsets[0].x, i.uv.y ) );
cOut += tex2D( g_texSampler, float2( i.uv.x + g_vPsTapOffsets[0].x, i.uv.y - g_vPsTapOffsets[0].y ) );
cOut += tex2D( g_texSampler, float2( i.uv.x , i.uv.y - g_vPsTapOffsets[0].y ) );
cOut += tex2D( g_texSampler, float2( i.uv.x - g_vPsTapOffsets[0].x, i.uv.y - g_vPsTapOffsets[0].y ) );
cOut *= (1.0f/9.0f);
cOut.a = max( cOut.a * 1.0f, tex2D( g_texSampler, i.uv ).a ); //never reduce alpha, only increase it
return saturate( cOut );
}

View File

@ -0,0 +1,22 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
sampler g_texSampler : register( s0 );
struct PS_INPUT
{
float2 uv : TEXCOORD0;
};
float2 g_vPsTapOffsets[2] : register( c0 );
float4 main( PS_INPUT i ) : COLOR
{
float4 cOut;
cOut = 0.25 * tex2D( g_texSampler, i.uv + g_vPsTapOffsets[0] );
cOut += 0.25 * tex2D( g_texSampler, i.uv - g_vPsTapOffsets[0] );
cOut += 0.25 * tex2D( g_texSampler, i.uv + g_vPsTapOffsets[1] );
cOut += 0.25 * tex2D( g_texSampler, i.uv - g_vPsTapOffsets[1] );
return cOut;
}

View File

@ -0,0 +1,13 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
#include "common_ps_fxc.h"
struct PS_INPUT
{
float4 vColor : COLOR0;
};
HALF4 main( PS_INPUT i ) : COLOR
{
return i.vColor;
}

View File

@ -0,0 +1,35 @@
#include "common_vs_fxc.h"
// STATIC: "USESCOLOR" "0..1"
struct VS_INPUT
{
float4 vPos : POSITION;
# if (USESCOLOR == 1)
float4 vColor : COLOR0;
# endif
};
struct VS_OUTPUT
{
float4 vProjPos : POSITION;
# if (USESCOLOR == 1)
float4 vColor : COLOR0;
# endif
};
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
o.vProjPos.xyz = v.vPos.xyz;
o.vProjPos.w = 1.0f;
# if (USESCOLOR == 1)
{
o.vColor = v.vColor;
}
# endif
return o;
}

View File

@ -0,0 +1,66 @@
@echo off
setlocal
rem Use dynamic shaders to build .inc files only
rem set dynamic_shaders=1
rem == Setup path to nmake.exe, from vc 2005 common tools directory ==
call "%VS80COMNTOOLS%vsvars32.bat"
rem ================================
rem ==== MOD PATH CONFIGURATIONS ===
rem == Set the absolute path to your mod's game directory here ==
rem == Note that this path needs does not support long file/directory names ==
rem == So instead of a path such as "C:\Program Files\Steam\steamapps\mymod" ==
rem == you need to find the 8.3 abbreviation for the directory name using 'dir /x' ==
rem == and set the directory to something like C:\PROGRA~2\Steam\steamapps\sourcemods\mymod ==
set GAMEDIR=
rem == Set the relative path to steamapps\common\Alien Swarm\bin ==
rem == As above, this path does not support long directory names or spaces ==
rem == e.g. ..\..\..\..\..\PROGRA~2\Steam\steamapps\common\ALIENS~1\bin ==
set SDKBINDIR=..\..\..\..\STEAME~1\steamapps\common\ALIENS~1\bin
rem == Set the Path to your mods root source code ==
rem this should already be correct, accepts relative paths only!
set SOURCEDIR=..\..
rem ==== MOD PATH CONFIGURATIONS END ===
rem ====================================
set TTEXE=..\..\devtools\bin\timeprecise.exe
if not exist %TTEXE% goto no_ttexe
goto no_ttexe_end
:no_ttexe
set TTEXE=time /t
:no_ttexe_end
rem echo.
rem echo ~~~~~~ buildsdkshaders %* ~~~~~~
%TTEXE% -cur-Q
set tt_all_start=%ERRORLEVEL%
set tt_all_chkpt=%tt_start%
set BUILD_SHADER=call buildshaders.bat
set ARG_EXTRA=
%BUILD_SHADER% stdshader_dx9_20b -game %GAMEDIR% -source %SOURCEDIR%
%BUILD_SHADER% stdshader_dx9_20b_new -game %GAMEDIR% -source %SOURCEDIR% -dx9_30
%BUILD_SHADER% stdshader_dx9_30 -game %GAMEDIR% -source %SOURCEDIR% -dx9_30 -force30
rem echo.
if not "%dynamic_shaders%" == "1" (
rem echo Finished full buildallshaders %*
) else (
rem echo Finished dynamic buildallshaders %*
)
rem %TTEXE% -diff %tt_all_start% -cur
rem echo.

View File

@ -0,0 +1,208 @@
@echo off
set TTEXE=..\..\devtools\bin\timeprecise.exe
if not exist %TTEXE% goto no_ttexe
goto no_ttexe_end
:no_ttexe
set TTEXE=time /t
:no_ttexe_end
echo.
rem echo ==================== buildshaders %* ==================
%TTEXE% -cur-Q
set tt_start=%ERRORLEVEL%
set tt_chkpt=%tt_start%
REM ****************
REM usage: buildshaders <shaderProjectName>
REM ****************
setlocal
set arg_filename=%1
set shadercompilecommand=shadercompile.exe
set targetdir=shaders
set SrcDirBase=..\..
set shaderDir=shaders
set SDKArgs=
set SHADERINCPATH=vshtmp9/... fxctmp9/...
if "%1" == "" goto usage
set inputbase=%1
set DIRECTX_SDK_VER=pc09.00
set DIRECTX_SDK_BIN_DIR=dx9sdk\utilities
if /i "%6" == "-dx9_30" goto dx_sdk_dx9_30
goto dx_sdk_end
:dx_sdk_dx9_30
set DIRECTX_SDK_VER=pc09.30
set DIRECTX_SDK_BIN_DIR=dx10sdk\utilities\dx9_30
goto dx_sdk_end
:dx_sdk_end
if /i "%7" == "-force30" goto set_force30_arg
goto set_force_end
:set_force30_arg
set DIRECTX_FORCE_MODEL=30
goto set_force_end
:set_force_end
if /i "%2" == "-game" goto set_mod_args
goto build_shaders
REM ****************
REM USAGE
REM ****************
:usage
echo.
echo "usage: buildshaders <shaderProjectName> [-game] [gameDir if -game was specified] [-source sourceDir]"
echo " gameDir is where gameinfo.txt is (where it will store the compiled shaders)."
echo " sourceDir is where the source code is (where it will find scripts and compilers)."
echo "ex : buildshaders myshaders"
echo "ex : buildshaders myshaders -game c:\steam\steamapps\sourcemods\mymod -source c:\mymod\src"
goto :end
REM ****************
REM MOD ARGS - look for -game or the vproject environment variable
REM ****************
:set_mod_args
if not exist %SDKBINDIR%\shadercompile.exe goto NoShaderCompile
set ChangeToDir=%SDKBINDIR%
if /i "%4" NEQ "-source" goto NoSourceDirSpecified
set SrcDirBase=%~5
REM ** use the -game parameter to tell us where to put the files
set targetdir=%~3\shaders
set SDKArgs=-nompi -nop4 -game "%~3"
if not exist "%~3\gameinfo.txt" goto InvalidGameDirectory
goto build_shaders
REM ****************
REM ERRORS
REM ****************
:InvalidGameDirectory
echo -
echo Error: "%~3" is not a valid game directory.
echo (The -game directory must have a gameinfo.txt file)
echo -
goto end
:NoSourceDirSpecified
echo ERROR: If you specify -game on the command line, you must specify -source.
goto usage
goto end
:NoShaderCompile
echo -
echo - ERROR: shadercompile.exe doesn't exist in %SDKBINDIR%
echo -
goto end
REM ****************
REM BUILD SHADERS
REM ****************
:build_shaders
rem echo --------------------------------
rem echo %inputbase%
rem echo --------------------------------
REM make sure that target dirs exist
REM files will be built in these targets and copied to their final destination
if not exist %shaderDir% mkdir %shaderDir%
if not exist %shaderDir%\fxc mkdir %shaderDir%\fxc
if not exist %shaderDir%\vsh mkdir %shaderDir%\vsh
if not exist %shaderDir%\psh mkdir %shaderDir%\psh
REM Nuke some files that we will add to later.
if exist filelist.txt del /f /q filelist.txt
if exist filestocopy.txt del /f /q filestocopy.txt
if exist filelistgen.txt del /f /q filelistgen.txt
if exist inclist.txt del /f /q inclist.txt
if exist vcslist.txt del /f /q vcslist.txt
REM ****************
REM Generate a makefile for the shader project
REM ****************
perl "%SrcDirBase%\devtools\bin\updateshaders.pl" -source "%SrcDirBase%" %inputbase%
REM ****************
REM Run the makefile, generating minimal work/build list for fxc files, go ahead and compile vsh and psh files.
REM ****************
rem nmake /S /C -f makefile.%inputbase% clean > clean.txt 2>&1
echo Building inc files, asm vcs files, and VMPI worklist for %inputbase%...
nmake /S /C -f makefile.%inputbase%
REM ****************
REM Copy the inc files to their target
REM ****************
if exist "inclist.txt" (
echo Publishing shader inc files to target...
perl %SrcDirBase%\devtools\bin\copyshaderincfiles.pl inclist.txt
)
REM ****************
REM Add the executables to the worklist.
REM ****************
if /i "%DIRECTX_SDK_VER%" == "pc09.00" (
rem echo "Copy extra files for dx 9 std
)
if /i "%DIRECTX_SDK_VER%" == "pc09.30" (
echo %SrcDirBase%\devtools\bin\d3dx9_33.dll >> filestocopy.txt
)
echo %SrcDirBase%\%DIRECTX_SDK_BIN_DIR%\dx_proxy.dll >> filestocopy.txt
echo %SDKBINDIR%\shadercompile.exe >> filestocopy.txt
echo %SDKBINDIR%\shadercompile_dll.dll >> filestocopy.txt
echo %SDKBINDIR%\vstdlib.dll >> filestocopy.txt
echo %SDKBINDIR%\tier0.dll >> filestocopy.txt
REM ****************
REM Cull duplicate entries in work/build list
REM ****************
if exist filestocopy.txt type filestocopy.txt | perl "%SrcDirBase%\devtools\bin\uniqifylist.pl" > uniquefilestocopy.txt
if exist filelistgen.txt if not "%dynamic_shaders%" == "1" (
echo Generating action list...
copy filelistgen.txt filelist.txt >nul
)
REM ****************
REM Execute distributed process on work/build list
REM ****************
set shader_path_cd=%cd%
if exist "filelist.txt" if exist "uniquefilestocopy.txt" if not "%dynamic_shaders%" == "1" (
echo Running distributed shader compilation...
cd /D %ChangeToDir%
%shadercompilecommand% %SDKArgs% -shaderpath "%shader_path_cd:/=\%" -allowdebug
cd /D %shader_path_cd%
)
REM ****************
REM PC Shader copy
REM Publish the generated files to the output dir using XCOPY
REM This batch file may have been invoked standalone or slaved (master does final smart mirror copy)
REM ****************
:DoXCopy
if not "%dynamic_shaders%" == "1" (
if not exist "%targetdir%" md "%targetdir%"
if not "%targetdir%"=="%shaderDir%" xcopy %shaderDir%\*.* "%targetdir%" /e /y
)
goto end
REM ****************
REM END
REM ****************
:end
%TTEXE% -diff %tt_start%
echo.

View File

@ -0,0 +1,133 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: A wet version of base * lightmap
//
// $Header: $
// $NoKeywords: $
//===========================================================================//
#include "BaseVSShader.h"
#include "cable_vs20.inc"
#include "cable_ps20.inc"
#include "cable_ps20b.inc"
#include "cpp_shader_constant_register_map.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
extern ConVar mat_fullbright;
DEFINE_FALLBACK_SHADER( Cable, Cable_DX9 )
BEGIN_VS_SHADER( Cable_DX9,
"Help for Cable shader" )
BEGIN_SHADER_PARAMS
SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "cable/cablenormalmap", "bumpmap texture" )
SHADER_PARAM( MINLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.1", "Minimum amount of light (0-1 value)" )
SHADER_PARAM( MAXLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.3", "Maximum amount of light" )
END_SHADER_PARAMS
SHADER_FALLBACK
{
return 0;
}
SHADER_INIT
{
LoadBumpMap( BUMPMAP );
LoadTexture( BASETEXTURE );
}
SHADER_DRAW
{
BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true );
bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use
SHADOW_STATE
{
// Enable blending?
if ( IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ) )
{
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableBlending( true );
pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
}
pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
if ( g_pHardwareConfig->GetDXSupportLevel() >= 90)
{
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true );
}
int tCoordDimensions[] = {2,2};
pShaderShadow->VertexShaderVertexFormat(
VERTEX_POSITION | VERTEX_COLOR | VERTEX_TANGENT_S | VERTEX_TANGENT_T,
2, tCoordDimensions, 0 );
DECLARE_STATIC_VERTEX_SHADER( cable_vs20 );
SET_STATIC_VERTEX_SHADER( cable_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( cable_ps20b );
SET_STATIC_PIXEL_SHADER( cable_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( cable_ps20 );
SET_STATIC_PIXEL_SHADER( cable_ps20 );
}
// we are writing linear values from this shader.
// This is kinda wrong. We are writing linear or gamma depending on "IsHDREnabled" below.
// The COLOR really decides if we are gamma or linear.
pShaderShadow->EnableSRGBWrite( true );
FogToFogColor();
pShaderShadow->EnableAlphaWrites( bFullyOpaque );
}
DYNAMIC_STATE
{
bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
BindTexture( SHADER_SAMPLER0, BUMPMAP );
if ( bLightingOnly )
{
pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY );
}
else
{
BindTexture( SHADER_SAMPLER1, BASETEXTURE );
}
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 );
DECLARE_DYNAMIC_VERTEX_SHADER( cable_vs20 );
SET_DYNAMIC_VERTEX_SHADER( cable_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( cable_ps20b );
SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() );
SET_DYNAMIC_PIXEL_SHADER( cable_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( cable_ps20 );
SET_DYNAMIC_PIXEL_SHADER( cable_ps20 );
}
}
Draw();
}
END_SHADER

View File

@ -0,0 +1,52 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
#include "common_fog_ps_fxc.h"
// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC]
// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX]
#if defined( SHADER_MODEL_PS_2_0 )
# define WRITE_DEPTH_TO_DESTALPHA 0
#endif
#include "common_ps_fxc.h"
#include "shader_constant_register_map.h"
sampler NormalSampler : register( s0 );
sampler BaseTextureSampler : register( s1 );
const float4 g_FogParams : register( PSREG_FOG_PARAMS );
const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT );
struct PS_INPUT
{
float2 vTexCoord0 : TEXCOORD0;
float2 vTexCoord1 : TEXCOORD1;
float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog
float4 directionalLightColor : COLOR0;
};
float4 main( PS_INPUT i ) : COLOR
{
float3 vNormalMapDir = tex2D( NormalSampler, i.vTexCoord0 ); // Get the 3-vector from the normal map
float4 textureColor = tex2D( BaseTextureSampler, i.vTexCoord1 ); // Interpret tcoord t1 as color data.
//Expand compacted vectors
//TODO: find if there's a better way to expand a color normal to a full vector ( _bx2 was used in the assembly code )
vNormalMapDir = (vNormalMapDir - 0.5) * 2.0;
float3 vLightDir = float3( 0.0f, 0.0f, 1.0f );
float lightDirDotNormalMap = dot( vNormalMapDir, vLightDir ); //normalMap dot dirLightDir
// do half-lambert on the dot
lightDirDotNormalMap = lightDirDotNormalMap * 0.5 + 0.5;
lightDirDotNormalMap = lightDirDotNormalMap * lightDirDotNormalMap;
float4 resultColor;
resultColor.xyz = lightDirDotNormalMap * ( textureColor.rgb * i.directionalLightColor.rgb );
resultColor.a = textureColor.a * i.directionalLightColor.a;
float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, i.worldPos_projPosZ.xyz, i.worldPos_projPosZ.w );
return FinalOutput( resultColor, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w );
}

View File

@ -0,0 +1,74 @@
#include "common_fog_vs_fxc.h"
#include "common_vs_fxc.h"
static const int g_FogType = DOWATERFOG;
struct VS_INPUT
{
float4 vPos : POSITION;
float2 vTexCoord0 : TEXCOORD0;
float2 vTexCoord1 : TEXCOORD1;
float4 directionalLightColor : COLOR0;
float3 vTangentS : TANGENT;
float3 vTangentT : BINORMAL;
};
struct VS_OUTPUT
{
float4 vProjPos : POSITION;
float2 vTexCoord0 : TEXCOORD0;
float2 vTexCoord1 : TEXCOORD1;
float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog
float4 directionalLightColor : COLOR0;
#if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 )
float fog : FOG;
#endif
};
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
float3 worldPos;
worldPos = mul( v.vPos, cModel[0] );
o.vProjPos = mul( float4( worldPos, 1 ), cViewProj );
o.worldPos_projPosZ = float4( worldPos.xyz, o.vProjPos.z );
#if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 )
o.fog = CalcFixedFunctionFog( worldPos, g_FogType );
#endif
//------------------------------------------------------------------------------
// Setup the tangent space
//------------------------------------------------------------------------------
// Get S crossed with T (call it R)
float3 r = cross( v.vTangentS, v.vTangentT );
// Normalize S (into s)
float3 s = normalize( v.vTangentS );
// Normalize R (into r)
r = normalize( r );
// Regenerate T (into t)
float3 t = cross( r, v.vTangentS );
//------------------------------------------------------------------------------
// Copy texcoords for the normal map and base texture
//------------------------------------------------------------------------------
o.vTexCoord0 = v.vTexCoord0;
o.vTexCoord1 = v.vTexCoord1;
// Pass the dirlight color through
o.directionalLightColor = v.directionalLightColor;
return o;
}

View File

@ -0,0 +1,43 @@
@echo off
setlocal
if /i "%1" == "-game" goto CleanGameDir
rem Clean out platform
if exist ..\..\..\game\platform\shaders rd /s /q ..\..\..\game\platform\shaders
goto CleanOtherStuff
:CleanGameDir
set __GameDir=%~2
if not exist "%__GameDir%\gameinfo.txt" goto MissingGameInfo
if exist "%__GameDir%\shaders" rd /s /q "%2\shaders"
goto CleanOtherStuff
:CleanOtherStuff
if exist debug_dx9 rd /s /q debug_dx9
if exist fxctmp9 rd /s /q fxctmp9
if exist vshtmp9 rd /s /q vshtmp9
if exist pshtmp9 rd /s /q pshtmp9
if exist fxctmp9_360 rd /s /q fxctmp9_360
if exist vshtmp9_360 rd /s /q vshtmp9_360
if exist pshtmp9_360 rd /s /q pshtmp9_360
if exist fxctmp9_tmp rd /s /q fxctmp9_tmp
if exist vshtmp9_tmp rd /s /q vshtmp9_tmp
if exist pshtmp9_tmp rd /s /q pshtmp9_tmp
if exist fxctmp9_360_tmp rd /s /q fxctmp9_360_tmp
if exist vshtmp9_360_tmp rd /s /q vshtmp9_360_tmp
if exist pshtmp9_360_tmp rd /s /q pshtmp9_360_tmp
if exist shaders rd /s /q shaders
goto end
:MissingGameInfo
echo Invalid -game parameter specified (no "%__GameDir%\gameinfo.txt" exists).
goto end
:end

View File

@ -0,0 +1,12 @@
@echo off
setlocal
if exist fxctmp9_tmp rd /s /q fxctmp9_tmp
if exist vshtmp9_tmp rd /s /q vshtmp9_tmp
if exist pshtmp9_tmp rd /s /q pshtmp9_tmp
if exist fxctmp9_360_tmp rd /s /q fxctmp9_360_tmp
if exist vshtmp9_360_tmp rd /s /q vshtmp9_360_tmp
if exist pshtmp9_360_tmp rd /s /q pshtmp9_360_tmp
if exist shaders rd /s /q shaders

View File

@ -0,0 +1,8 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
const float4 g_vClearVal : register( c0 );
float4 main() : COLOR
{
return g_vClearVal;
}

View File

@ -0,0 +1,123 @@
//========= Copyright <20> 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Purpose: Cloaking shader for Spy in TF2 (and probably many other things to come)
//
// $NoKeywords: $
//=====================================================================================//
#include "BaseVSShader.h"
#include "convar.h"
#include "cloak_dx9_helper.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
DEFINE_FALLBACK_SHADER( Cloak, Cloak_DX90 )
BEGIN_VS_SHADER( Cloak_DX90, "Help for Cloak" )
BEGIN_SHADER_PARAMS
SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE )
SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE )
SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" )
SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" )
SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "normal map" )
SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" )
SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" )
SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0f", "" )
SHADER_PARAM( REFRACTTINTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shield", "" )
SHADER_PARAM( REFRACTTINTTEXTUREFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" )
SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" )
SHADER_PARAM( NOWRITEZ, SHADER_PARAM_TYPE_INTEGER, "0", "0 == write z, 1 = no write z" )
SHADER_PARAM( MASKED, SHADER_PARAM_TYPE_BOOL, "0", "mask using dest alpha" )
SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0", "How cloaked? Zero is not cloaked, 1 is fully cloaked." )
SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "1D ramp texture for tinting scalar diffuse term" )
SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "5.0", "Phong exponent for local specular lights" )
SHADER_PARAM( PHONGTINT, SHADER_PARAM_TYPE_VEC3, "5.0", "Phong tint for local specular lights" )
SHADER_PARAM( PHONGALBEDOTINT, SHADER_PARAM_TYPE_BOOL, "1.0", "Apply tint by albedo (controlled by spec exponent texture" )
SHADER_PARAM( PHONGFRESNELRANGES, SHADER_PARAM_TYPE_VEC3, "[0 0.5 1]", "Parameters for remapping fresnel output" )
SHADER_PARAM( PHONGBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Phong overbrightening factor (specular mask channel should be authored to account for this)" )
SHADER_PARAM( PHONGEXPONENTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "Phong Exponent map" )
// Rim lighting terms
SHADER_PARAM( RIMLIGHT, SHADER_PARAM_TYPE_BOOL, "0", "enables rim lighting" )
SHADER_PARAM( RIMLIGHTEXPONENT, SHADER_PARAM_TYPE_FLOAT, "4.0", "Exponent for rim lights" )
SHADER_PARAM( RIMLIGHTBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Boost for rim lights" )
SHADER_PARAM( RIMMASK, SHADER_PARAM_TYPE_BOOL, "0", "Indicates whether or not to use alpha channel of exponent texture to mask the rim term" )
END_SHADER_PARAMS
// FIXME: doesn't support Fresnel!
void SetupVars( Cloak_DX9_Vars_t& info )
{
info.m_nBaseTexture = BASETEXTURE;
info.m_nRefractAmount = REFRACTAMOUNT;
info.m_nRefractTint = REFRACTTINT;
info.m_nNormalMap = NORMALMAP;
info.m_nBumpFrame = BUMPFRAME;
info.m_nBumpTransform = BUMPTRANSFORM;
info.m_nRefractTintTexture = REFRACTTINTTEXTURE;
info.m_nRefractTintTextureFrame = REFRACTTINTTEXTUREFRAME;
info.m_nFresnelReflection = FRESNELREFLECTION;
info.m_nMasked = MASKED;
info.m_nCloakFactor = CLOAKFACTOR;
info.m_nDiffuseWarpTexture = LIGHTWARPTEXTURE;
info.m_nPhongExponent = PHONGEXPONENT;
info.m_nPhongTint = PHONGTINT;
info.m_nPhongAlbedoTint = PHONGALBEDOTINT;
info.m_nPhongExponentTexture = PHONGEXPONENTTEXTURE;
info.m_nPhongBoost = PHONGBOOST;
info.m_nPhongFresnelRanges = PHONGFRESNELRANGES;
// Rim lighting parameters
info.m_nRimLight = RIMLIGHT;
info.m_nRimLightPower = RIMLIGHTEXPONENT;
info.m_nRimLightBoost = RIMLIGHTBOOST;
info.m_nRimMask = RIMMASK;
}
bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const
{
if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time
return true;
else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check
return true;
else
return false;
}
bool IsTranslucent( IMaterialVar **params ) const
{
if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check
return true;
else
return false;
}
SHADER_INIT_PARAMS()
{
Cloak_DX9_Vars_t info;
SetupVars( info );
InitParamsCloak_DX9( this, params, pMaterialName, info );
}
SHADER_FALLBACK
{
return 0;
}
SHADER_INIT
{
Cloak_DX9_Vars_t info;
SetupVars( info );
InitCloak_DX9( this, params, info );
}
SHADER_DRAW
{
Cloak_DX9_Vars_t info;
SetupVars( info );
DrawCloak_DX9( this, params, pShaderAPI, pShaderShadow, info, vertexCompression );
}
END_SHADER

View File

@ -0,0 +1,361 @@
//========= Copyright <20> 1996-2006, Valve Corporation, All rights reserved. ============//
/* Example how to plug this into an existing shader:
In the VMT:
// Cloak Pass
"$cloakPassEnabled" "1"
#include "cloak_blended_pass_helper.h"
In BEGIN_SHADER_PARAMS:
// Cloak Pass
SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" )
SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" )
SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" )
SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" )
// This should already exist
//SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" )
//SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" )
//SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" )
Add this above SHADER_INIT_PARAMS()
// Cloak Pass
void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info )
{
info.m_nCloakFactor = CLOAKFACTOR;
info.m_nCloakColorTint = CLOAKCOLORTINT;
info.m_nRefractAmount = REFRACTAMOUNT;
// Delete these lines if not bump mapping!
info.m_nBumpmap = BUMPMAP;
info.m_nBumpFrame = BUMPFRAME;
info.m_nBumpTransform = BUMPTRANSFORM;
}
bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const
{
if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking
{
if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time
return true;
else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check
return true;
// else, not cloaking this frame, so check flag2 in case the base material still needs it
}
// Check flag2 if not drawing cloak pass
return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE );
}
bool IsTranslucent( IMaterialVar **params ) const
{
if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking
{
if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check
return true;
// else, not cloaking this frame, so check flag in case the base material still needs it
}
// Check flag if not drawing cloak pass
return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT );
}
In SHADER_INIT_PARAMS()
// Cloak Pass
if ( !params[CLOAKPASSENABLED]->IsDefined() )
{
params[CLOAKPASSENABLED]->SetIntValue( 0 );
}
else if ( params[CLOAKPASSENABLED]->GetIntValue() )
{
CloakBlendedPassVars_t info;
SetupVarsCloakBlendedPass( info );
InitParamsCloakBlendedPass( this, params, pMaterialName, info );
}
In SHADER_INIT
// Cloak Pass
if ( params[CLOAKPASSENABLED]->GetIntValue() )
{
CloakBlendedPassVars_t info;
SetupVarsCloakBlendedPass( info );
InitCloakBlendedPass( this, params, info );
}
Modify SHADER_DRAW to look something like this:
// Skip the standard rendering if cloak pass is fully opaque
bool bDrawStandardPass = true;
if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting
{
CloakBlendedPassVars_t info;
SetupVarsCloakBlendedPass( info );
if ( CloakBlendedPassIsFullyOpaque( params, info ) )
{
bDrawStandardPass = false;
}
}
// Standard rendering pass
if ( bDrawStandardPass )
{
Eye_Refract_Vars_t info;
SetupVarsEyeRefract( info );
Draw_Eyes_Refract( this, params, pShaderAPI, pShaderShadow, info );
}
else
{
// Skip this pass!
Draw( false );
}
// Cloak Pass
if ( params[CLOAKPASSENABLED]->GetIntValue() )
{
// If ( snapshotting ) or ( we need to draw this frame )
if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) )
{
CloakBlendedPassVars_t info;
SetupVarsCloakBlendedPass( info );
DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info );
}
else // We're not snapshotting and we don't need to draw this frame
{
// Skip this pass!
Draw( false );
}
}
==================================================================================================== */
#include "BaseVSShader.h"
#include "mathlib/VMatrix.h"
#include "cloak_blended_pass_helper.h"
#include "convar.h"
// Auto generated inc files
#include "cloak_blended_pass_vs20.inc"
#include "cloak_blended_pass_ps20.inc"
#include "cloak_blended_pass_ps20b.inc"
#ifndef _X360
#include "cloak_blended_pass_vs30.inc"
#include "cloak_blended_pass_ps30.inc"
#endif
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
void InitParamsCloakBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, CloakBlendedPassVars_t &info )
{
// Set material flags
SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
SET_FLAGS( MATERIAL_VAR_MODEL );
SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES );
// Set material parameter default values
if ( ( info.m_nCloakFactor != -1 ) && ( !params[info.m_nCloakFactor]->IsDefined() ) )
{
params[info.m_nCloakFactor]->SetFloatValue( kDefaultCloakFactor );
}
if ( ( info.m_nRefractAmount != -1 ) && ( !params[info.m_nRefractAmount]->IsDefined() ) )
{
params[info.m_nRefractAmount]->SetFloatValue( kDefaultRefractAmount );
}
if ( ( info.m_nCloakColorTint != -1 ) && ( !params[info.m_nCloakColorTint]->IsDefined() ) )
{
params[info.m_nCloakColorTint]->SetVecValue( kDefaultCloakColorTint[0], kDefaultCloakColorTint[1], kDefaultCloakColorTint[2], kDefaultCloakColorTint[3] );
}
if( (info.m_nBumpFrame != -1 ) && !params[info.m_nBumpFrame]->IsDefined() )
{
params[info.m_nBumpFrame]->SetIntValue( 0 );
}
}
void InitCloakBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, CloakBlendedPassVars_t &info )
{
// Load textures
if ( g_pConfig->UseBumpmapping() )
{
if ( (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined() )
{
pShader->LoadTexture( info.m_nBumpmap );
}
}
}
void DrawCloakBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI,
IShaderShadow* pShaderShadow, CloakBlendedPassVars_t &info, VertexCompressionType_t vertexCompression )
{
bool bBumpMapping = ( !g_pConfig->UseBumpmapping() ) || ( info.m_nBumpmap == -1 ) || !params[info.m_nBumpmap]->IsTexture() ? 0 : 1;
SHADOW_STATE
{
// Reset shadow state manually since we're drawing from two materials
pShader->SetInitialShadowState( );
// Set stream format (note that this shader supports compression)
unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED;
int nTexCoordCount = 1;
int userDataSize = 0;
pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize );
#ifndef _X360
if ( !g_pHardwareConfig->HasFastVertexTextures() )
#endif
{
// Vertex Shader
DECLARE_STATIC_VERTEX_SHADER( cloak_blended_pass_vs20 );
SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, bBumpMapping ? 1 : 0 );
SET_STATIC_VERTEX_SHADER( cloak_blended_pass_vs20 );
// Pixel Shader
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( cloak_blended_pass_ps20b );
SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bBumpMapping ? 1 : 0 );
SET_STATIC_PIXEL_SHADER( cloak_blended_pass_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( cloak_blended_pass_ps20 );
SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bBumpMapping ? 1 : 0 );
SET_STATIC_PIXEL_SHADER( cloak_blended_pass_ps20 );
}
}
#ifndef _X360
else
{
// The vertex shader uses the vertex id stream
SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID );
// Vertex Shader
DECLARE_STATIC_VERTEX_SHADER( cloak_blended_pass_vs30 );
SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, bBumpMapping ? 1 : 0 );
SET_STATIC_VERTEX_SHADER( cloak_blended_pass_vs30 );
// Pixel Shader
DECLARE_STATIC_PIXEL_SHADER( cloak_blended_pass_ps30 );
SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bBumpMapping ? 1 : 0 );
SET_STATIC_PIXEL_SHADER( cloak_blended_pass_ps30 );
}
#endif
// Textures
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Refraction texture
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true );
if ( bBumpMapping )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Bump
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); // Not sRGB
}
pShaderShadow->EnableSRGBWrite( true );
// Blending
pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
pShaderShadow->EnableAlphaWrites( false );
// !!! We need to turn this back on because EnableAlphaBlending() above disables it!
pShaderShadow->EnableDepthWrites( true );
}
DYNAMIC_STATE
{
// Reset render state manually since we're drawing from two materials
pShaderAPI->SetDefaultState();
// Set Vertex Shader Constants
if ( ( bBumpMapping ) && ( info.m_nBumpTransform != -1 ) )
{
pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBumpTransform );
}
#ifndef _X360
if ( !g_pHardwareConfig->HasFastVertexTextures() )
#endif
{
// Set Vertex Shader Combos
DECLARE_DYNAMIC_VERTEX_SHADER( cloak_blended_pass_vs20 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
SET_DYNAMIC_VERTEX_SHADER( cloak_blended_pass_vs20 );
// Set Pixel Shader Combos
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( cloak_blended_pass_ps20b );
SET_DYNAMIC_PIXEL_SHADER( cloak_blended_pass_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( cloak_blended_pass_ps20 );
SET_DYNAMIC_PIXEL_SHADER( cloak_blended_pass_ps20 );
}
}
#ifndef _X360
else
{
pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 );
// Set Vertex Shader Combos
DECLARE_DYNAMIC_VERTEX_SHADER( cloak_blended_pass_vs30 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
SET_DYNAMIC_VERTEX_SHADER( cloak_blended_pass_vs30 );
// Set Pixel Shader Combos
DECLARE_DYNAMIC_PIXEL_SHADER( cloak_blended_pass_ps30 );
SET_DYNAMIC_PIXEL_SHADER( cloak_blended_pass_ps30 );
}
#endif
// Bind textures
pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 ); // Refraction Map
if ( bBumpMapping )
{
pShader->BindTexture( SHADER_SAMPLER1, info.m_nBumpmap, info.m_nBumpFrame );
}
// Set Pixel Shader Constants
float vEyePos[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
pShaderAPI->GetWorldSpaceCameraPosition( vEyePos );
pShaderAPI->SetPixelShaderConstant( 5, vEyePos, 1 );
float vPackedConst1[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
vPackedConst1[0] = IS_PARAM_DEFINED( info.m_nCloakFactor ) ? params[info.m_nCloakFactor]->GetFloatValue() : kDefaultCloakFactor;
vPackedConst1[1] = IS_PARAM_DEFINED( info.m_nRefractAmount ) ? params[info.m_nRefractAmount]->GetFloatValue() : kDefaultRefractAmount;
pShaderAPI->SetPixelShaderConstant( 6, vPackedConst1, 1 );
// Refract color tint
pShaderAPI->SetPixelShaderConstant( 7, IS_PARAM_DEFINED( info.m_nCloakColorTint ) ? params[info.m_nCloakColorTint]->GetVecValue() : kDefaultCloakColorTint, 1 );
// Set c0 and c1 to contain first two rows of ViewProj matrix
VMatrix mView, mProj;
pShaderAPI->GetMatrix( MATERIAL_VIEW, mView.m[0] );
pShaderAPI->GetMatrix( MATERIAL_PROJECTION, mProj.m[0] );
VMatrix mViewProj = mView * mProj;
mViewProj = mViewProj.Transpose3x3();
pShaderAPI->SetPixelShaderConstant( 0, mViewProj.m[0], 2 );
}
pShader->Draw();
}
bool CloakBlendedPassIsFullyOpaque ( IMaterialVar** params, CloakBlendedPassVars_t &info )
{
float flCloakFactor = IS_PARAM_DEFINED( info.m_nCloakFactor ) ? params[info.m_nCloakFactor]->GetFloatValue() : kDefaultCloakFactor;
//float flRefractAmount = IS_PARAM_DEFINED( info.m_nRefractAmount ) ? params[info.m_nRefractAmount]->GetFloatValue() : kDefaultRefractAmount;
// NOTE: If this math changes, you need to update the pixel shader code!
float flFresnel = 1.0f - ( 0.0f ); // Assume V.N = 0.0f;
float flCloakLerpFactor = clamp( Lerp( clamp( flCloakFactor, 0.0f, 1.0f ), 1.0f, flFresnel - 1.35f ), 0.0f, 1.0f );
//flCloakLerpFactor = 1.0f - smoothstep( 0.4f, 0.425f, flCloakLerpFactor );
if ( flCloakLerpFactor <= 0.4f )
return true;
return false;
}

View File

@ -0,0 +1,46 @@
//========= Copyright <20> 1996-2006, Valve Corporation, All rights reserved. ============//
#ifndef CLOAK_BLENDED_PASS_HELPER_H
#define CLOAK_BLENDED_PASS_HELPER_H
#ifdef _WIN32
#pragma once
#endif
#include <string.h>
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class CBaseVSShader;
class IMaterialVar;
class IShaderDynamicAPI;
class IShaderShadow;
//-----------------------------------------------------------------------------
// Init params/ init/ draw methods
//-----------------------------------------------------------------------------
struct CloakBlendedPassVars_t
{
CloakBlendedPassVars_t() { memset( this, 0xFF, sizeof(CloakBlendedPassVars_t) ); }
int m_nCloakFactor;
int m_nCloakColorTint;
int m_nRefractAmount;
int m_nBumpmap;
int m_nBumpFrame;
int m_nBumpTransform;
};
// Default values (Arrays should only be vec[4])
static const float kDefaultCloakFactor = 0.0f;
static const float kDefaultCloakColorTint[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
static const float kDefaultRefractAmount = 0.1f;
void InitParamsCloakBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, CloakBlendedPassVars_t &info );
void InitCloakBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, CloakBlendedPassVars_t &info );
void DrawCloakBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI,
IShaderShadow* pShaderShadow, CloakBlendedPassVars_t &info, VertexCompressionType_t vertexCompression );
bool CloakBlendedPassIsFullyOpaque ( IMaterialVar** params, CloakBlendedPassVars_t &info );
#endif // CLOAK_BLENDED_PASS_HELPER_H

View File

@ -0,0 +1,103 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// STATIC: "BUMPMAP" "0..1"
// Includes =======================================================================================
#include "common_vertexlitgeneric_dx9.h"
// Texture Samplers ===============================================================================
sampler g_tRefractionSampler : register( s0 );
#if BUMPMAP
sampler g_tBumpSampler : register( s1 );
#endif
// Shaders Constants and Globals ==================================================================
const float4 g_mViewProj0 : register( c0 ); // 1st row of matrix
const float4 g_mViewProj1 : register( c1 ); // 2nd row of matrix
const float4 g_vCameraPosition : register( c5 );
const float4 g_vPackedConst6 : register( c6 );
#define g_flCloakFactor g_vPackedConst6.x // Default = 1.0f
#define g_flRefractAmount g_vPackedConst6.y // Default = 1.0f
const float4 g_cCloakColorTint : register( c7 );
// 8 2D Poisson offsets (designed to use .xy and .wz swizzles (not .zw)
static const float4 g_vPoissonOffset[4] = { float4 (-0.0876f, 0.9703f, 0.5651f, 0.4802f ),
float4 ( 0.1851f, 0.1580f, -0.0617f, -0.2616f ),
float4 (-0.5477f, -0.6603f, 0.0711f, -0.5325f ),
float4 (-0.0751f, -0.8954f, 0.4054f, 0.6384f ) };
// Interpolated values ============================================================================
struct PS_INPUT
{
float3 vWorldNormal : TEXCOORD0; // World-space normal
float3 vProjPosForRefract : TEXCOORD1;
float3 vWorldViewVector : TEXCOORD2;
#if BUMPMAP
float3x3 mTangentSpaceTranspose : TEXCOORD3;
// second row : TEXCOORD4;
// third row : TEXCOORD5;
float2 vTexCoord0 : TEXCOORD6;
#endif
};
// Main ===========================================================================================
float4 main( PS_INPUT i ) : COLOR
{
float3 vWorldNormal = normalize( i.vWorldNormal.xyz );
#if BUMPMAP
float4 vBumpTexel = tex2D( g_tBumpSampler, i.vTexCoord0.xy );
float3 vTangentNormal = ( 2.0f * vBumpTexel ) - 1.0f;
vWorldNormal.xyz = mul( i.mTangentSpaceTranspose, vTangentNormal.xyz );
#endif
// Transform world space normal into clip space and project
float3 vProjNormal;
vProjNormal.x = dot( vWorldNormal.xyz, g_mViewProj0.xyz ); // 1st row
vProjNormal.y = dot( vWorldNormal.xyz, g_mViewProj1.xyz ); // 2nd row
// Compute coordinates for sampling refraction
float2 vRefractTexCoordNoWarp = i.vProjPosForRefract.xy / i.vProjPosForRefract.z;
float2 vRefractTexCoord = vProjNormal.xy;
float scale = lerp( g_flRefractAmount, 0.0f, saturate( g_flCloakFactor ) );
vRefractTexCoord.xy *= scale;
vRefractTexCoord.xy += vRefractTexCoordNoWarp.xy;
// Blur by scalable Poisson filter
float flBlurAmount = lerp( 0.05f, 0.0f, saturate( g_flCloakFactor ) );
float3 cRefract = tex2D( g_tRefractionSampler, vRefractTexCoord.xy );
cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[0].xy * flBlurAmount ) );
cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[0].wz * flBlurAmount ) );
cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[1].xy * flBlurAmount ) );
cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[1].wz * flBlurAmount ) );
cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[2].xy * flBlurAmount ) );
cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[2].wz * flBlurAmount ) );
cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[3].xy * flBlurAmount ) );
cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[3].wz * flBlurAmount ) );
cRefract /= 9.0f;
// 1-(N.V) for Fresnel term (NOTE: If this math changes, you need to update the C code that mimics this on the CPU)
float flFresnel = 1.0f - saturate( dot( i.vWorldNormal.xyz, normalize( -i.vWorldViewVector.xyz ) ) );
float flCloakLerpFactor = saturate( lerp( 1.0f, flFresnel - 1.35f, saturate( g_flCloakFactor ) ) );
flCloakLerpFactor = 1.0f - smoothstep( 0.4f, 0.425f, flCloakLerpFactor );
// Slightly dim the facing pixels and brighten the silhouette pixels
cRefract.rgb *= lerp( flFresnel * 0.4 + 0.8, 1.0f, saturate( g_flCloakFactor ) * saturate( g_flCloakFactor ) ); // This gives a scalar in the range [0.8 1.2]
// Refract color tint
float fColorTintStrength = saturate( ( saturate( g_flCloakFactor ) - 0.75f ) * 4.0f );
cRefract.rgb *= lerp( g_cCloakColorTint, 1.0f, fColorTintStrength );
//===============//
// Combine terms //
//===============//
float4 result;
result.rgb = cRefract.rgb;
// Set alpha to cloak mask
result.a = flCloakLerpFactor;
return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
}

View File

@ -0,0 +1,133 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// STATIC: "BUMPMAP" "0..1"
// DYNAMIC: "COMPRESSED_VERTS" "0..1"
// DYNAMIC: "SKINNING" "0..1"
// DYNAMIC: "MORPHING" "0..1" [vs30] [ = pShaderAPI->IsHWMorphingEnabled() ]
// Includes
#include "common_vs_fxc.h"
// Globals
static const bool g_bSkinning = SKINNING ? true : false;
const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 );
#ifdef SHADER_MODEL_VS_3_0
// NOTE: cMorphTargetTextureDim.xy = target dimensions,
// cMorphTargetTextureDim.z = 4tuples/morph
const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 );
const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 );
sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 );
#endif
// Structs
struct VS_INPUT
{
float4 vPos : POSITION; // Position
float4 vNormal : NORMAL; // Normal
float4 vBoneWeights : BLENDWEIGHT; // Skin weights
float4 vBoneIndices : BLENDINDICES; // Skin indices
float4 vTexCoord0 : TEXCOORD0; // Base texture coordinates
#if BUMPMAP
float4 vTangent : TANGENT;
#endif
// Position and normal/tangent deltas
float3 vPosFlex : POSITION1;
float3 vNormalFlex : NORMAL1;
#ifdef SHADER_MODEL_VS_3_0
float vVertexID : POSITION2;
#endif
};
struct VS_OUTPUT
{
float4 vProjPosition : POSITION; // Projection-space position
float3 vWorldNormal : TEXCOORD0; // World-space normal
float3 vProjPosForRefract : TEXCOORD1;
float3 vWorldViewVector : TEXCOORD2;
#if BUMPMAP
float3x3 mTangentSpaceTranspose : TEXCOORD3;
// second row : TEXCOORD4;
// third row : TEXCOORD5;
float2 vTexCoord0 : TEXCOORD6;
#endif
};
// Main
VS_OUTPUT main( const VS_INPUT i )
{
VS_OUTPUT o;
// Flexes coming in from a separate stream (contribution masked by cFlexScale.x)
float4 vObjPosition = i.vPos;
float3 vObjNormal;
#if BUMPMAP
float4 vObjTangent;
DecompressVertex_NormalTangent( i.vNormal, i.vTangent, vObjNormal, vObjTangent );
#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING
ApplyMorph( i.vPosFlex, i.vNormalFlex, vObjPosition.xyz, vObjNormal, vObjTangent.xyz );
#else
ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, i.vVertexID, float3( 0, 0, 0 ), vObjPosition.xyz, vObjNormal, vObjTangent.xyz );
#endif
#else // !BUMPMAP
DecompressVertex_Normal( i.vNormal, vObjNormal );
#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING
ApplyMorph( i.vPosFlex, i.vNormalFlex, vObjPosition.xyz, vObjNormal );
#else
ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, i.vVertexID, float3( 0, 0, 0 ),
vObjPosition.xyz, vObjNormal );
#endif
#endif
// Transform the position
float3 vWorldPosition = { 0.0f, 0.0f, 0.0f };
float3 vWorldNormal = { 0.0f, 0.0f, 0.0f };
#if BUMPMAP
float3 vWorldTangent = { 0.0f, 0.0f, 0.0f };
float3 vWorldBinormal = { 0.0f, 0.0f, 0.0f };
SkinPositionNormalAndTangentSpace( g_bSkinning, vObjPosition, vObjNormal.xyz, vObjTangent.xyzw, i.vBoneWeights, i.vBoneIndices, vWorldPosition, vWorldNormal, vWorldTangent, vWorldBinormal );
#else
SkinPositionAndNormal( g_bSkinning, vObjPosition, vObjNormal.xyz, i.vBoneWeights, i.vBoneIndices, vWorldPosition, vWorldNormal );
#endif
o.vWorldNormal.xyz = normalize( vWorldNormal.xyz );
// Transform into projection space
float4 vProjPosition = mul( float4( vWorldPosition, 1.0f ), cViewProj );
o.vProjPosition = vProjPosition;
// Map projected position to the refraction texture
float2 vRefractPos;
vRefractPos.x = vProjPosition.x;
vRefractPos.y = -vProjPosition.y; // Invert Y
vRefractPos = (vRefractPos + vProjPosition.w) * 0.5f;
o.vProjPosForRefract.xyz = float3(vRefractPos.x, vRefractPos.y, vProjPosition.w);
// View vector
float3 vWorldViewVector = normalize (vWorldPosition.xyz - cEyePos.xyz);
o.vWorldViewVector.xyz = vWorldViewVector.xyz;
// Tangent space transform
#if BUMPMAP
o.mTangentSpaceTranspose[0] = float3( vWorldTangent.x, vWorldBinormal.x, vWorldNormal.x );
o.mTangentSpaceTranspose[1] = float3( vWorldTangent.y, vWorldBinormal.y, vWorldNormal.y );
o.mTangentSpaceTranspose[2] = float3( vWorldTangent.z, vWorldBinormal.z, vWorldNormal.z );
#endif
// Texture coordinates
#if BUMPMAP
o.vTexCoord0.x = dot( i.vTexCoord0.xy, cBaseTexCoordTransform[0] );
o.vTexCoord0.y = dot( i.vTexCoord0.xy, cBaseTexCoordTransform[1] );
#endif
return o;
}

View File

@ -0,0 +1,328 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#include "BaseVSShader.h"
#include "cloak_dx9_helper.h"
#include "..\shaderapidx9\locald3dtypes.h"
#include "convar.h"
#include "cpp_shader_constant_register_map.h"
#include "cloak_vs20.inc"
#include "cloak_ps20.inc"
#include "cloak_ps20b.inc"
#ifndef _X360
#include "cloak_vs30.inc"
#include "cloak_ps30.inc"
#endif
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
static ConVar r_lightwarpidentity( "r_lightwarpidentity", "0", FCVAR_CHEAT );
// FIXME: doesn't support fresnel!
void InitParamsCloak_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, Cloak_DX9_Vars_t &info )
{
SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES );
SET_FLAGS( MATERIAL_VAR_TRANSLUCENT );
SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT );
if( !params[info.m_nFresnelReflection]->IsDefined() )
{
params[info.m_nFresnelReflection]->SetFloatValue( 1.0f );
}
if( !params[info.m_nMasked]->IsDefined() )
{
params[info.m_nMasked]->SetIntValue( 0 );
}
SET_FLAGS2( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE );
}
void InitCloak_DX9( CBaseVSShader *pShader, IMaterialVar** params, Cloak_DX9_Vars_t &info )
{
if (params[info.m_nBaseTexture]->IsDefined() )
{
pShader->LoadTexture( info.m_nBaseTexture );
}
if (params[info.m_nNormalMap]->IsDefined() )
{
pShader->LoadBumpMap( info.m_nNormalMap );
}
if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() )
{
pShader->LoadTexture( info.m_nDiffuseWarpTexture );
}
SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT );
}
void DrawCloak_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI,
IShaderShadow* pShaderShadow, Cloak_DX9_Vars_t &info, VertexCompressionType_t vertexCompression )
{
bool bIsModel = IS_FLAG_SET( MATERIAL_VAR_MODEL );
bool bMasked = (params[info.m_nMasked]->GetIntValue() != 0);
bool hasDiffuseWarp = (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsTexture();
bool hasPhongExponentTexture = (info.m_nPhongExponentTexture != -1) && params[info.m_nPhongExponentTexture]->IsTexture();
bool hasPhongTintMap = hasPhongExponentTexture && (info.m_nPhongAlbedoTint != -1) && ( params[info.m_nPhongAlbedoTint]->GetIntValue() != 0 );
bool bHasRimLight = (info.m_nRimLight != -1) && ( params[info.m_nRimLight]->GetIntValue() != 0 );
bool bHasRimMaskMap = hasPhongExponentTexture && bHasRimLight && (info.m_nRimMask != -1) && ( params[info.m_nRimMask]->GetIntValue() != 0 );
SHADOW_STATE
{
SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT );
pShader->SetInitialShadowState( );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); // Always SRGB read on base map
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); // Refraction map sampler...
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER5, true );
pShaderShadow->EnableSRGBWrite( true );
unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL;
int nTexCoordCount = 1;
int userDataSize = 0;
if( bIsModel )
{
userDataSize = 4;
}
else
{
flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T;
}
// This shader supports compressed vertices, so OR in that flag:
flags |= VERTEX_FORMAT_COMPRESSED;
pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize );
#ifndef _X360
if ( !g_pHardwareConfig->HasFastVertexTextures() )
#endif
{
DECLARE_STATIC_VERTEX_SHADER( cloak_vs20 );
SET_STATIC_VERTEX_SHADER_COMBO( MODEL, bIsModel );
SET_STATIC_VERTEX_SHADER( cloak_vs20 );
// Bind ps_2_b shader so we can get Phong terms
if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( cloak_ps20b );
SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, hasDiffuseWarp );
SET_STATIC_PIXEL_SHADER( cloak_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( cloak_ps20 );
SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, hasDiffuseWarp );
SET_STATIC_PIXEL_SHADER( cloak_ps20 );
}
}
#ifndef _X360
else
{
// The vertex shader uses the vertex id stream
SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID );
DECLARE_STATIC_VERTEX_SHADER( cloak_vs30 );
SET_STATIC_VERTEX_SHADER_COMBO( MODEL, bIsModel );
SET_STATIC_VERTEX_SHADER( cloak_vs30 );
// Bind ps_2_b shader so we can get Phong terms
DECLARE_STATIC_PIXEL_SHADER( cloak_ps30 );
SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, hasDiffuseWarp );
SET_STATIC_PIXEL_SHADER( cloak_ps30 );
}
#endif
pShader->DefaultFog();
if( bMasked )
{
pShader->EnableAlphaBlending( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA );
}
// Lighting constants
pShader->PI_BeginCommandBuffer();
pShader->PI_SetPixelShaderAmbientLightCube( PSREG_AMBIENT_CUBE );
pShader->PI_SetPixelShaderLocalLighting( PSREG_LIGHT_INFO_ARRAY );
pShader->PI_EndCommandBuffer();
}
DYNAMIC_STATE
{
pShaderAPI->SetDefaultState();
// Bind textures
pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, 0 ); // Base Map
pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 ); // Refraction Map
pShader->BindTexture( SHADER_SAMPLER3, info.m_nNormalMap, info.m_nBumpFrame ); // Normal Map
pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); // Normalization cube map
if ( hasDiffuseWarp )
{
if ( r_lightwarpidentity.GetBool() )
{
pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_IDENTITY_LIGHTWARP );
}
else
{
pShader->BindTexture( SHADER_SAMPLER1, info.m_nDiffuseWarpTexture ); // Light warp texture
}
}
MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode();
LightState_t lightState;
pShaderAPI->GetDX9LightState( &lightState );
#ifndef _X360
if ( !g_pHardwareConfig->HasFastVertexTextures() )
#endif
{
DECLARE_DYNAMIC_VERTEX_SHADER( cloak_vs20 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
SET_DYNAMIC_VERTEX_SHADER( cloak_vs20 );
// Bind ps_2_b shader so we can get Phong, rim and a cloudier refraction
if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( cloak_ps20b );
SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights );
SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
SET_DYNAMIC_PIXEL_SHADER( cloak_ps20b );
}
else
{
// JasonM Hack
//
// In general, cloaking on ps_2_0 needs re-working for multipass...yuck...
//
int nPS20NumLights = MAX( lightState.m_nNumLights, 1 );
DECLARE_DYNAMIC_PIXEL_SHADER( cloak_ps20 );
SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, nPS20NumLights );
SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
SET_DYNAMIC_PIXEL_SHADER( cloak_ps20 );
}
}
#ifndef _X360
else
{
pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 );
DECLARE_DYNAMIC_VERTEX_SHADER( cloak_vs30 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
SET_DYNAMIC_VERTEX_SHADER( cloak_vs30 );
DECLARE_DYNAMIC_PIXEL_SHADER( cloak_ps30 );
SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights );
SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
SET_DYNAMIC_PIXEL_SHADER( cloak_ps30 );
}
#endif
pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, info.m_nBumpTransform );
if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE )
{
pShader->SetPixelShaderConstant( 27, info.m_nRefractTint );
}
else
{
pShader->SetPixelShaderConstantGammaToLinear( 27, info.m_nRefractTint );
}
pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS );
// Pack phong exponent in with the eye position
float vEyePos_SpecExponent[4], vFresnelRanges_SpecBoost[4] = {0, 0.5, 1, 1};
float vSpecularTint[4] = {1, 1, 1, 1}, vRimBoost[4] = {1, 1, 1, 1};
pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent );
if ( (info.m_nPhongExponent != -1) && params[info.m_nPhongExponent]->IsDefined() )
vEyePos_SpecExponent[3] = params[info.m_nPhongExponent]->GetFloatValue(); // This overrides the channel in the map
else
vEyePos_SpecExponent[3] = 0; // Use the alpha channel of the normal map for the exponent
if ( (info.m_nPhongTint != -1 ) && params[info.m_nPhongTint]->IsDefined() ) // Get the tint parameter
params[info.m_nPhongTint]->GetVecValue(vSpecularTint, 4);
// Get the rim light power (goes in w of Phong tint)
if ( bHasRimLight && (info.m_nRimLightPower != -1) && params[info.m_nRimLightPower]->IsDefined() )
{
vSpecularTint[3] = params[info.m_nRimLightPower]->GetFloatValue();
vSpecularTint[3] = MAX(vSpecularTint[3], 1.0f); // Make sure this is at least 1
}
// Get the rim boost power (goes in w of flashlight position)
if ( bHasRimLight && (info.m_nRimLightBoost != -1) && params[info.m_nRimLightBoost]->IsDefined() )
{
vRimBoost[3] = params[info.m_nRimLightBoost]->GetFloatValue();
}
// Rim mask...if this is true, use alpha channel of spec exponent texture to mask the rim term
if ( bHasRimMaskMap )
{
float vRimMaskControl[4] = {0, 0, 0, 0}; // Only x is relevant in shader code
vRimMaskControl[0] = params[info.m_nRimMask]->GetFloatValue();
pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, vRimMaskControl, 1 );
}
// If it's all zeros, there was no constant tint in the vmt
if ( (vSpecularTint[0] == 0.0f) && (vSpecularTint[1] == 0.0f) && (vSpecularTint[2] == 0.0f) )
{
if ( hasPhongTintMap ) // If we have a map to use, tell the shader
{
vSpecularTint[0] = -1;
}
else // Otherwise, just tint with white
{
vSpecularTint[0] = 1.0f;
vSpecularTint[1] = 1.0f;
vSpecularTint[2] = 1.0f;
}
}
if ( (info.m_nPhongFresnelRanges != -1 ) && params[info.m_nPhongFresnelRanges]->IsDefined() )
params[info.m_nPhongFresnelRanges]->GetVecValue( vFresnelRanges_SpecBoost, 3 ); // Grab optional fresnel range parameters
if ( ( info.m_nPhongBoost != -1 ) &&params[info.m_nPhongBoost]->IsDefined() ) // Grab optional phong boost param
vFresnelRanges_SpecBoost[3] = params[info.m_nPhongBoost]->GetFloatValue();
else
vFresnelRanges_SpecBoost[3] = 1.0f;
pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 );
pShaderAPI->SetPixelShaderConstant( PSREG_FRESNEL_SPEC_PARAMS, vFresnelRanges_SpecBoost, 1 );
pShaderAPI->SetPixelShaderConstant( PSREG_SPEC_RIM_PARAMS, vSpecularTint, 1 );
pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, vRimBoost, 1 ); // Rim boost in w on non-flashlight pass
pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS );
// Set c0 and c1 to contain first two rows of ViewProj matrix
VMatrix matView, matProj, matViewProj;
pShaderAPI->GetMatrix( MATERIAL_VIEW, matView.m[0] );
pShaderAPI->GetMatrix( MATERIAL_PROJECTION, matProj.m[0] );
matViewProj = matView * matProj;
pShaderAPI->SetPixelShaderConstant( 0, matViewProj.m[0], 2 );
// Cloaking control constants
float vCloakControls[4] = { params[info.m_nRefractAmount]->GetFloatValue(), params[info.m_nCloakFactor]->GetFloatValue(), 0.0f, 0.0f };
pShaderAPI->SetPixelShaderConstant( 3, vCloakControls, 1 );
}
pShader->Draw();
}

View File

@ -0,0 +1,63 @@
//====== Copyright <20> 1996-2006, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef CLOAK_DX9_HELPER_H
#define CLOAK_DX9_HELPER_H
#ifdef _WIN32
#pragma once
#endif
#include <string.h>
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class CBaseVSShader;
class IMaterialVar;
class IShaderDynamicAPI;
class IShaderShadow;
//-----------------------------------------------------------------------------
// Init params/ init/ draw methods
//-----------------------------------------------------------------------------
struct Cloak_DX9_Vars_t
{
Cloak_DX9_Vars_t() { memset( this, 0xFF, sizeof( *this ) ); }
int m_nBaseTexture;
int m_nRefractAmount;
int m_nRefractTint;
int m_nNormalMap;
int m_nBumpFrame;
int m_nBumpTransform;
int m_nRefractTintTexture;
int m_nRefractTintTextureFrame;
int m_nFresnelReflection;
int m_nMasked;
int m_nCloakFactor;
int m_nDiffuseWarpTexture;
int m_nPhongExponent;
int m_nPhongTint;
int m_nPhongAlbedoTint;
int m_nPhongExponentTexture;
int m_nPhongBoost;
int m_nPhongFresnelRanges;
// Rim lighting parameters
int m_nRimLight;
int m_nRimLightPower;
int m_nRimLightBoost;
int m_nRimMask;
};
void InitParamsCloak_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName,
Cloak_DX9_Vars_t &info );
void InitCloak_DX9( CBaseVSShader *pShader, IMaterialVar** params, Cloak_DX9_Vars_t &info );
void DrawCloak_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI,
IShaderShadow* pShaderShadow, Cloak_DX9_Vars_t &info, VertexCompressionType_t vertexCompression );
#endif // CLOAK_DX9_HELPER_H

View File

@ -0,0 +1,194 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// STATIC: "LIGHTWARPTEXTURE" "0..1"
#include "common_fog_ps_fxc.h"
// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1"
// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20]
// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b]
// DYNAMIC: "NUM_LIGHTS" "0..4" [ps30]
#include "shader_constant_register_map.h"
sampler BaseSampler : register( s0 ); // Base map
sampler DiffuseWarpSampler : register( s1 ); // 1D texture for diffuse lighting modification
sampler RefractSampler : register( s2 ); // Refraction map copied from back buffer
sampler NormalSampler : register( s3 ); // Normal map
sampler SpecExponentSampler : register( s4 ); // Flashlight cookie
sampler NormalizeSampler : register( s5 ); // Normalization cube map
const float3x3 g_ViewProj : register( c0 ); // 1st row of Projection matrix
// c1 // 2nd row
// c2 // 4th row
const float2 g_CloakControl : register( c3 ); // { refract amount, cloak, ?, ? }
const float3 cAmbientCube[6] : register( PSREG_AMBIENT_CUBE );
const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT );
const float4 g_FogParams : register( PSREG_FOG_PARAMS );
const float4 g_FlashlightAttenuationFactors_RimMask : register( PSREG_FLASHLIGHT_ATTENUATION ); // On non-flashlight pass, x has rim mask control
const float4 g_RimBoost : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST );
const float4 g_FresnelSpecParams : register( PSREG_FRESNEL_SPEC_PARAMS ); // xyz are fresnel, w is specular boost
const float4 g_SpecularRimParams : register( PSREG_SPEC_RIM_PARAMS ); // xyz are specular tint color, w is rim power
PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total
#define g_fRimBoost g_RimBoost.w
#define g_FresnelRanges g_FresnelSpecParams.xyz
#define g_SpecularBoost g_FresnelSpecParams.w
#define g_SpecularTint g_SpecularRimParams.xyz
#define g_RimExponent g_SpecularRimParams.w
#define g_FlashlightAttenuationFactors g_FlashlightAttenuationFactors_RimMask
#define g_RimMaskControl g_FlashlightAttenuationFactors_RimMask.x
// 8 2D Poisson offsets (designed to use .xy and .wz swizzles (not .zw)
static const float4 gPoissonOffset[4] = { float4 (-0.0876f, 0.9703f, 0.5651f, 0.4802f ),
float4 ( 0.1851f, 0.1580f, -0.0617f, -0.2616f ),
float4 (-0.5477f, -0.6603f, 0.0711f, -0.5325f ),
float4 (-0.0751f, -0.8954f, 0.4054f, 0.6384f ) };
struct PS_INPUT
{
float2 vBaseTexCoord : TEXCOORD0;
float3x3 tangentSpaceTranspose : TEXCOORD1;
// second row : TEXCOORD2;
// third row : TEXCOORD3;
float3 worldPos : TEXCOORD4;
float3 projPos : TEXCOORD5;
float4 lightAtten : TEXCOORD6;
};
float4 main( PS_INPUT i ) : COLOR
{
float3 vSpecular = float3( 0.0f, 0.0f, 0.0f );
bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false;
int nNumLights = NUM_LIGHTS;
// Base color
float4 albedo = tex2D( BaseSampler, i.vBaseTexCoord );
// Load normal and expand range
float4 vNormalSample = tex2D( NormalSampler, i.vBaseTexCoord );
float3 tangentSpaceNormal = 2.0f * vNormalSample.xyz - 1.0f;
// We need a world space normal if we're doing any lighting
float3 vWorldNormal = normalize( mul( i.tangentSpaceTranspose, tangentSpaceNormal ) );
float3 vWorldEyeDir = normalize( g_EyePos_SpecExponent.xyz - i.worldPos );
// Vanilla 1-(N.V) fresnel term used later in transition lerp
float fresnel = 1-saturate( dot( vWorldNormal, vWorldEyeDir ) );
// Summation of diffuse illumination from all local lights
float3 diffuseLighting = PixelShaderDoLighting( i.worldPos, vWorldNormal,
float3( 0.0f, 0.0f, 0.0f ), false,
true, i.lightAtten, cAmbientCube, NormalizeSampler,
nNumLights, cLightInfo, true,
bDoDiffuseWarp, DiffuseWarpSampler );
// Transform world space normal into clip space and project
float2 vProjNormal;
vProjNormal.x = dot( vWorldNormal, g_ViewProj[0] ); // 1st row
vProjNormal.y = dot( vWorldNormal, g_ViewProj[1] ); // 2nd row
// Compute coordinates for sampling refraction
float2 vRefractTexCoordNoWarp = i.projPos.xy / i.projPos.z;
float2 vRefractTexCoord = vProjNormal.xy;
float scale = lerp( g_CloakControl.x, 0.0f, g_CloakControl.y );
vRefractTexCoord *= scale;
vRefractTexCoord += vRefractTexCoordNoWarp;
#ifdef SHADER_MODEL_PS_2_0
float3 vRefract = tex2D( RefractSampler, vRefractTexCoordNoWarp );
#endif
// Extra refraction rays, specular, rim etc are only done on ps_2_b
#if defined( SHADER_MODEL_PS_2_B ) || defined( SHADER_MODEL_PS_3_0 )
// Blur by scalable Poisson filter
float fBlurAmount = lerp( 0.05f, 0.0f, g_CloakControl.y );
float3 vRefract = tex2D( RefractSampler, vRefractTexCoord );
vRefract += tex2D( RefractSampler, vRefractTexCoord + gPoissonOffset[0].xy * fBlurAmount );
vRefract += tex2D( RefractSampler, vRefractTexCoord + gPoissonOffset[0].wz * fBlurAmount );
vRefract += tex2D( RefractSampler, vRefractTexCoord + gPoissonOffset[1].xy * fBlurAmount );
vRefract += tex2D( RefractSampler, vRefractTexCoord + gPoissonOffset[1].wz * fBlurAmount );
vRefract += tex2D( RefractSampler, vRefractTexCoord + gPoissonOffset[2].xy * fBlurAmount );
vRefract += tex2D( RefractSampler, vRefractTexCoord + gPoissonOffset[2].wz * fBlurAmount );
// We're right at the hairy edge of constant register usage and hence have to drop these taps...
// vRefract += tex2D( RefractSampler, vRefractTexCoord + gPoissonOffset[3].xy * fBlurAmount );
// vRefract += tex2D( RefractSampler, vRefractTexCoord + gPoissonOffset[3].wz * fBlurAmount );
vRefract /= 7.0f;
float3 rimLighting = float3( 0.0f, 0.0f, 0.0f );
float3 specularLighting = float3( 0.0f, 0.0f, 0.0f );
float fSpecExp = g_EyePos_SpecExponent.w;
float fSpecMask = vNormalSample.a;
float4 vSpecExpMap = tex2D( SpecExponentSampler, i.vBaseTexCoord );
float fSpecExpMap = vSpecExpMap.r;
float fRimMask = 1.0f;//lerp( 1.0f, vSpecExpMap.a, g_RimMaskControl ); // Select rim mask
float3 vSpecularTint;
// If the exponent passed in as a constant is zero, use the value from the map as the exponent
if ( fSpecExp == 0 )
fSpecExp = 1.0f - fSpecExpMap + 150.0f * fSpecExpMap;
// If constant tint is negative, tint with albedo, based upon scalar tint map
if ( g_SpecularTint.r == -1 )
vSpecularTint = lerp( float3(1.0f, 1.0f, 1.0f), albedo, vSpecExpMap.g );
else
vSpecularTint = g_SpecularTint.rgb;
// Fresnel to match regular specular lighting
float fFresnelRanges = Fresnel( vWorldNormal, vWorldEyeDir, g_FresnelRanges );
// Summation of specular from all local lights besides the flashlight
PixelShaderDoSpecularLighting( i.worldPos, vWorldNormal, fSpecExp, vWorldEyeDir,
i.lightAtten, nNumLights, cLightInfo, false,
NormalizeSampler, 1.0f, true, g_RimExponent,
// Outputs
specularLighting, rimLighting );
// Modulate with spec mask, boost, tint and fresnel ranges
specularLighting *= fSpecMask * g_SpecularBoost * fFresnelRanges * vSpecularTint;
float fRimFresnel = Fresnel4( vWorldNormal, vWorldEyeDir );
// Add in rim light modulated with tint, mask and traditional Fresnel (not using Fresnel ranges)
rimLighting *= vSpecularTint * fRimMask * fRimFresnel;
// Fold rim lighting into specular term by using the max so that we don't really add light twice...
specularLighting = max (specularLighting, rimLighting);
// Add in view-ray lookup from ambient cube
specularLighting += fRimFresnel * fRimMask * vSpecularTint /* g_fRimBoost */ * PixelShaderAmbientLight( vWorldEyeDir, cAmbientCube) * saturate(dot(vWorldNormal, float3(0, 0 , 1)) );
float tintLerpFactor = saturate(lerp( 1, fresnel-1.1, saturate(g_CloakControl.y)));
tintLerpFactor = smoothstep( 0.4f, 0.425f, tintLerpFactor );
float3 vTintedRefract = lerp( vRefract, albedo * vRefract, 0.7f );
vRefract = lerp( vRefract, vTintedRefract, tintLerpFactor );
vSpecular = specularLighting * smoothstep( 0.98, 0.8, saturate(g_CloakControl.y ));
#endif
// Blend refraction component with diffusely lit model
float diffuseLerpFactor = saturate(lerp( 1, fresnel - 1.35, saturate(g_CloakControl.y)));
diffuseLerpFactor = smoothstep( 0.4f, 0.425f, diffuseLerpFactor );
float3 fDiffuse = lerp( vRefract, albedo * diffuseLighting, diffuseLerpFactor );
float3 result = fDiffuse + vSpecular;
float alpha = 1.0f;
// Emulate LinearColorToHDROutput() when uncloaked
result = lerp( result.xyz * LINEAR_LIGHT_SCALE, result, saturate(g_CloakControl.y) );
float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.xyz, i.worldPos.xyz, i.projPos.z );
#if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT)
alpha = fogFactor;
#endif
return FinalOutput( float4( result, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE );
}

View File

@ -0,0 +1,129 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
//
// Purpose:
//
//===========================================================================//
// STATIC: "MODEL" "0..1"
// DYNAMIC: "COMPRESSED_VERTS" "0..1"
#include "common_fog_vs_fxc.h"
// DYNAMIC: "SKINNING" "0..1"
// DYNAMIC: "MORPHING" "0..1" [vs30] [ = pShaderAPI->IsHWMorphingEnabled() ]
#include "common_vs_fxc.h"
static const bool g_bSkinning = SKINNING ? true : false;
static const int g_FogType = DOWATERFOG;
#ifdef SHADER_MODEL_VS_3_0
// NOTE: cMorphTargetTextureDim.xy = target dimensions,
// cMorphTargetTextureDim.z = 4tuples/morph
const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 );
const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 );
sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 );
#endif
struct VS_INPUT
{
float4 vPos : POSITION;
float4 vBoneWeights : BLENDWEIGHT;
float4 vBoneIndices : BLENDINDICES;
float4 vNormal : NORMAL;
float4 vBaseTexCoord : TEXCOORD0;
float4 vUserData : TANGENT;
// Position and normal/tangent deltas
float3 vPosFlex : POSITION1;
float3 vNormalFlex : NORMAL1;
#ifdef SHADER_MODEL_VS_3_0
float vVertexID : POSITION2;
#endif
};
struct VS_OUTPUT
{
float4 vSetupProjPos : POSITION;
#if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 )
float fog : FOG;
#endif
float2 vBaseTexCoord : TEXCOORD0;
float3x3 tangentSpaceTranspose : TEXCOORD1;
// second row : TEXCOORD2;
// third row : TEXCOORD3;
float3 worldPos : TEXCOORD4;
float3 projPos : TEXCOORD5;
float4 lightAtten : TEXCOORD6;
};
VS_OUTPUT main( const VS_INPUT v )
{
VS_OUTPUT o = ( VS_OUTPUT )0;
float4 vPosition = v.vPos;
float3 vNormal;
float4 vTangent;
DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vNormal, vTangent );
#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING
ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal, vTangent.xyz );
#else
ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ),
vPosition.xyz, vNormal, vTangent.xyz );
#endif
// Perform skinning
float3 worldNormal, worldPos, worldTangentS, worldTangentT;
SkinPositionNormalAndTangentSpace( g_bSkinning, vPosition, vNormal, vTangent,
v.vBoneWeights, v.vBoneIndices, worldPos,
worldNormal, worldTangentS, worldTangentT );
// Always normalize since flex path is controlled by runtime
// constant not a shader combo and will always generate the normalization
worldNormal = normalize( worldNormal );
worldTangentS = normalize( worldTangentS );
worldTangentT = normalize( worldTangentT );
// Projected position
float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj );
o.vSetupProjPos = vProjPos;
// Map projected position to the refraction texture
float2 vRefractPos;
vRefractPos.x = vProjPos.x;
vRefractPos.y = -vProjPos.y; // invert Y
vRefractPos = (vRefractPos + vProjPos.w) * 0.5f;
// Scalar light attenuation
o.lightAtten.x = GetVertexAttenForLight( worldPos, 0 );
o.lightAtten.y = GetVertexAttenForLight( worldPos, 1 );
o.lightAtten.z = GetVertexAttenForLight( worldPos, 2 );
o.lightAtten.w = GetVertexAttenForLight( worldPos, 3 );
// Compute fog based on the position
float3 vWorldPos = mul( v.vPos, cModel[0] );
#if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 )
o.fog = CalcFixedFunctionFog( vWorldPos, g_FogType );
#endif
// World position
o.worldPos = worldPos;
// Refract position
o.projPos = float3(vRefractPos.x, vRefractPos.y, vProjPos.w);
// Tranform bump coordinates
o.vBaseTexCoord = v.vBaseTexCoord;
// Tangent space transform
o.tangentSpaceTranspose[0] = float3( worldTangentS.x, worldTangentT.x, worldNormal.x );
o.tangentSpaceTranspose[1] = float3( worldTangentS.y, worldTangentT.y, worldNormal.y );
o.tangentSpaceTranspose[2] = float3( worldTangentS.z, worldTangentT.z, worldNormal.z );
return o;
}

View File

@ -0,0 +1,76 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Header: $
// $NoKeywords: $
//=============================================================================//
#include "shaderlib/CShader.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
BEGIN_SHADER( Cloud,
"Help for Cloud" )
BEGIN_SHADER_PARAMS
SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloud", "cloud texture", 0 )
SHADER_PARAM( CLOUDALPHATEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloudalpha", "cloud alpha texture" )
SHADER_PARAM( CLOUDSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "cloudscale" )
SHADER_PARAM( MASKSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "maskscale" )
END_SHADER_PARAMS
SHADER_INIT
{
LoadTexture( BASETEXTURE );
LoadTexture( CLOUDALPHATEXTURE );
if( !params[CLOUDSCALE]->IsDefined() )
{
params[CLOUDSCALE]->SetVecValue( 1.0f, 1.0f );
}
if( !params[MASKSCALE]->IsDefined() )
{
params[MASKSCALE]->SetVecValue( 1.0f, 1.0f );
}
}
SHADER_DRAW
{
if( g_pHardwareConfig->GetSamplerCount() >= 2 )
{
SHADOW_STATE
{
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableBlending( true );
if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) )
{
pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE );
}
else
{
pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
}
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
pShaderShadow->DrawFlags( SHADER_DRAW_POSITION |
SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_TEXCOORD1 );
DefaultFog();
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
BindTexture( SHADER_SAMPLER1, CLOUDALPHATEXTURE );
// handle scrolling of base texture
SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE0,
BASETEXTURETRANSFORM, CLOUDSCALE );
SetFixedFunctionTextureScale( MATERIAL_TEXTURE1, MASKSCALE );
}
Draw();
}
else
{
ShaderWarning("Cloud not supported for single-texturing boards!\n");
}
}
END_SHADER

View File

@ -0,0 +1,140 @@
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "basevsshader.h"
#include "screenspaceeffect_vs20.inc"
#include "colorcorrection_ps20.inc"
#include "colorcorrection_ps20b.inc"
#include "..\materialsystem_global.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
BEGIN_VS_SHADER_FLAGS( ColorCorrection, "Help for ColorCorrection", SHADER_NOT_EDITABLE )
BEGIN_SHADER_PARAMS
SHADER_PARAM( WEIGHT_DEFAULT, SHADER_PARAM_TYPE_FLOAT, "1", "Volume Texture Default Weight" )
SHADER_PARAM( WEIGHT0, SHADER_PARAM_TYPE_FLOAT, "0", "Volume Texture Weight 0" )
SHADER_PARAM( WEIGHT1, SHADER_PARAM_TYPE_FLOAT, "0", "Volume Texture Weight 1" )
SHADER_PARAM( WEIGHT2, SHADER_PARAM_TYPE_FLOAT, "0", "Volume Texture Weight 2" )
SHADER_PARAM( WEIGHT3, SHADER_PARAM_TYPE_FLOAT, "0", "Volume Texture Weight 3" )
SHADER_PARAM( NUM_LOOKUPS, SHADER_PARAM_TYPE_INTEGER, "0", "Number of lookup maps" )
SHADER_PARAM( USE_FB_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", "Use frame buffer texture as input" )
SHADER_PARAM( INPUT_TEXTURE, SHADER_PARAM_TYPE_TEXTURE, "0", "Input texture" )
END_SHADER_PARAMS
SHADER_INIT_PARAMS()
{
if( !params[ WEIGHT_DEFAULT ]->IsDefined() )
{
params[ WEIGHT_DEFAULT ]->SetFloatValue( 1.0f) ;
}
if( !params[ WEIGHT0 ]->IsDefined() )
{
params[ WEIGHT0 ]->SetFloatValue( 1.0f );
}
if( !params[ WEIGHT1 ]->IsDefined() )
{
params[ WEIGHT1 ]->SetFloatValue( 1.0f );
}
if( !params[ WEIGHT2 ]->IsDefined() )
{
params[ WEIGHT2 ]->SetFloatValue( 1.0f );
}
if( !params[ WEIGHT3 ]->IsDefined() )
{
params[ WEIGHT3 ]->SetFloatValue( 1.0f );
}
if( !params[ NUM_LOOKUPS ]->IsDefined() )
{
params[ NUM_LOOKUPS ]->SetIntValue( 0 );
}
SET_FLAGS2( MATERIAL_VAR2_NEEDS_FULL_FRAME_BUFFER_TEXTURE );
}
SHADER_FALLBACK
{
return 0;
}
SHADER_INIT
{
}
SHADER_DRAW
{
SHADOW_STATE
{
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER4, true );
int fmt = VERTEX_POSITION;
pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 );
DECLARE_STATIC_VERTEX_SHADER( screenspaceeffect_vs20 );
SET_STATIC_VERTEX_SHADER( screenspaceeffect_vs20 );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( colorcorrection_ps20b );
SET_STATIC_PIXEL_SHADER( colorcorrection_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( colorcorrection_ps20 );
SET_STATIC_PIXEL_SHADER( colorcorrection_ps20 );
}
pShaderShadow->EnableSRGBWrite( false );
}
DYNAMIC_STATE
{
if( params[ USE_FB_TEXTURE ]->GetIntValue() )
pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 );
else
BindTexture( SHADER_SAMPLER0, INPUT_TEXTURE, -1 );
for( int i=0;i<params[NUM_LOOKUPS]->GetIntValue();i++ )
{
pShaderAPI->BindStandardTexture( (Sampler_t)(SHADER_SAMPLER1+i), (StandardTextureId_t)(TEXTURE_COLOR_CORRECTION_VOLUME_0+i) );
}
float default_weight = params[ WEIGHT_DEFAULT ]->GetFloatValue();
float weights[4] = { params[ WEIGHT0 ]->GetFloatValue(),
params[ WEIGHT1 ]->GetFloatValue(),
params[ WEIGHT2 ]->GetFloatValue(),
params[ WEIGHT3 ]->GetFloatValue() };
pShaderAPI->SetPixelShaderConstant( 0, &default_weight );
pShaderAPI->SetPixelShaderConstant( 1, &weights[0] );
pShaderAPI->SetPixelShaderConstant( 2, &weights[1] );
pShaderAPI->SetPixelShaderConstant( 3, &weights[2] );
pShaderAPI->SetPixelShaderConstant( 4, &weights[3] );
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( colorcorrection_ps20b );
SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LOOKUPS, params[ NUM_LOOKUPS ]->GetIntValue() );
SET_DYNAMIC_PIXEL_SHADER( colorcorrection_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( colorcorrection_ps20 );
SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LOOKUPS, params[ NUM_LOOKUPS ]->GetIntValue() );
SET_DYNAMIC_PIXEL_SHADER( colorcorrection_ps20 );
}
DECLARE_DYNAMIC_VERTEX_SHADER( screenspaceeffect_vs20 );
SET_DYNAMIC_VERTEX_SHADER( screenspaceeffect_vs20 );
}
Draw();
}
END_SHADER

View File

@ -0,0 +1,53 @@
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// DYNAMIC: "NUM_LOOKUPS" "0..4"
#include "common_ps_fxc.h"
sampler BaseTextureSampler : register( s0 );
sampler ColorCorrectionVolumeTexture0 : register( s1 );
sampler ColorCorrectionVolumeTexture1 : register( s2 );
sampler ColorCorrectionVolumeTexture2 : register( s3 );
sampler ColorCorrectionVolumeTexture3 : register( s4 );
float ColorCorrectionDefaultWeight : register( c0 );
float ColorCorrectionVolumeWeight0 : register( c1 );
float ColorCorrectionVolumeWeight1 : register( c2 );
float ColorCorrectionVolumeWeight2 : register( c3 );
float ColorCorrectionVolumeWeight3 : register( c4 );
struct PS_INPUT
{
float2 baseTexCoord : TEXCOORD0;
};
float4 main( PS_INPUT i ) : COLOR
{
float4 baseColor = tex2D( BaseTextureSampler, i.baseTexCoord );
// NOTE: This code requires the color correction texture to be 32 units to be correct.
// This code will cause (0,0,0) to be read from 0.5f/32
// and (1,1,1) to be read from 31.5f/32
float4 offsetBaseColor = baseColor*( 31.0f / 32.0f ) + ( 0.5f / 32.0f );
float4 outColor = float4( 0.0f, 0.0f, 0.0f, baseColor.a );
outColor.rgb = baseColor * ColorCorrectionDefaultWeight;
if (NUM_LOOKUPS > 0)
{
outColor.rgb += tex3D( ColorCorrectionVolumeTexture0, offsetBaseColor.rgb ) * ColorCorrectionVolumeWeight0;
if (NUM_LOOKUPS > 1)
{
outColor.rgb += tex3D( ColorCorrectionVolumeTexture1, offsetBaseColor.rgb ) * ColorCorrectionVolumeWeight1;
if (NUM_LOOKUPS > 2)
{
outColor.rgb += tex3D( ColorCorrectionVolumeTexture2, offsetBaseColor.rgb ) * ColorCorrectionVolumeWeight2;
if (NUM_LOOKUPS > 3)
{
outColor.rgb += tex3D( ColorCorrectionVolumeTexture3, offsetBaseColor.rgb ) * ColorCorrectionVolumeWeight3;
}
}
}
}
return FinalOutput( outColor, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
}

View File

@ -0,0 +1,865 @@
//========== Copyright (c) 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"
// Superellipse soft clipping
//
// Input:
// - Point Q on the x-y plane
// - The equations of two superellipses (with major/minor axes given by
// a,b and A,B for the inner and outer ellipses, respectively)
// - This is changed a bit from the original RenderMan code to be better vectorized
//
// Return value:
// - 0 if Q was inside the inner ellipse
// - 1 if Q was outside the outer ellipse
// - smoothly varying from 0 to 1 in between
float2 ClipSuperellipse( float2 Q, // Point on the xy plane
float4 aAbB, // Dimensions of superellipses
float2 rounds ) // Same roundness for both ellipses
{
float2 qr, Qabs = abs(Q); // Project to +x +y quadrant
float2 bx_Bx = Qabs.x * aAbB.zw;
float2 ay_Ay = Qabs.y * aAbB.xy;
qr.x = pow( pow(bx_Bx.x, rounds.x) + pow(ay_Ay.x, rounds.x), rounds.y ); // rounds.x = 2 / roundness
qr.y = pow( pow(bx_Bx.y, rounds.x) + pow(ay_Ay.y, rounds.x), rounds.y ); // rounds.y = -roundness/2
return qr * aAbB.xy * aAbB.zw;
}
// Volumetric light shaping
//
// Inputs:
// - the point being shaded, in the local light space
// - all information about the light shaping, including z smooth depth
// clipping, superellipse xy shaping, and distance falloff.
// Return value:
// - attenuation factor based on the falloff and shaping
float uberlight(float3 PL, // Point in light space
float3 smoothEdge0, // edge0 for three smooth steps
float3 smoothEdge1, // edge1 for three smooth steps
float3 smoothOneOverWidth, // width of three smooth steps
float2 shear, // shear in X and Y
float4 aAbB, // Superellipse dimensions
float2 rounds ) // two functions of roundness packed together
{
float2 qr = ClipSuperellipse( (PL / PL.z) - shear, aAbB, rounds );
smoothEdge0.x = qr.x; // Fill in the dynamic parts of the smoothsteps
smoothEdge1.x = qr.y; // The other components are pre-computed outside of the shader
smoothOneOverWidth.x = 1.0f / ( qr.y - qr.x );
float3 x = float3( 1, PL.z, PL.z );
float3 atten3 = smoothstep3( smoothEdge0, smoothEdge1, smoothOneOverWidth, x );
// Modulate the three resulting attenuations (flipping the sense of the attenuation from the superellipse and the far clip)
return (1.0f - atten3.x) * atten3.y * (1.0f - atten3.z);
}
// 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 bForceSimple, 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 )
{
if ( bForceSimple )
{
rotOffset.x = dot( RMatTop.xy, vPoissonOffset[1].xy ) + RMatTop.z;
rotOffset.y = dot( RMatBottom.xy, vPoissonOffset[1].xy ) + RMatBottom.z;
return tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x;
}
else
{
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;
// This should actually be float4( 0.125, 0.125, 0.125, 0.125) but we've tuned so many shots in the SFM
// relying on this bug that it doesn't seem right to fix until we have done something like move
// this code out to a staging branch for a shipping game.
// This is certainly one source of difference between ATI and nVidia in SFM layoffs
return dot( vLightDepths, float4( 0.25, 0.25, 0.25, 0.25) );
}
}
else if ( bFetch4 )
{
if ( bForceSimple )
{
rotOffset.x = dot( RMatTop.xy, vPoissonOffset[1].xy ) + RMatTop.z;
rotOffset.y = dot( RMatBottom.xy, vPoissonOffset[1].xy ) + RMatBottom.z;
vLightDepths = tex2D( DepthSampler, rotOffset.xy );
return dot( vLightDepths > objDepth.xxxx, float4( 0.25f, 0.25f, 0.25f, 0.25f ) );
}
else
{
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);
}
return 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
{
if ( bForceSimple )
{
rotOffset.x = dot( RMatTop.xy, vPoissonOffset[1].xy ) + RMatTop.z;
rotOffset.y = dot( RMatBottom.xy, vPoissonOffset[1].xy ) + RMatBottom.z;
return tex2D( DepthSampler, rotOffset.xy ).x > objDepth;
}
else
{
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);
}
return dot( accum, float4( 0.125, 0.125, 0.125, 0.125 ) );
}
}
}
#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, bool bForceSimple = false )
{
float flShadow = 1.0f;
#if !defined( _X360 ) //PC
if( nShadowLevel == NVIDIA_PCF_POISSON )
flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, bForceSimple, true, false );
else if( nShadowLevel == ATI_NOPCF )
flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, bForceSimple, false, false );
else if( nShadowLevel == ATI_NO_PCF_FETCH4 )
flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, bForceSimple, 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 ); // 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 bDoDiffuseWarp, sampler DiffuseWarpSampler, 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);
flashlightColor = tex2D( FlashlightSampler, vProjCoords );
#if !defined( _X360 )
#if defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)
flashlightColor *= flashlightSpacePosition.www > float3(0,0,0); // Catch back projection (PC-only, ps2b and up)
#endif
#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;
float NdotL = dot( L.xyz, worldNormal.xyz );
// JasonM - experimenting with light-warping the flashlight
if ( false )//bDoDiffuseWarp )
{
float warpCoord = saturate(NdotL * 0.5f + 0.5f); // 0..1
diffuseLighting *= tex2D( DiffuseWarpSampler, float2( warpCoord, 0.0f) ); // Look up warped light
}
else // common path
{
#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)
NdotL += flFlashlightNoLambertValue;
#endif
diffuseLighting *= saturate( NdotL ); // Lambertian term
}
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, bool bForceSimple = false )
{
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 );
ltz.z = 0.0f; // don't clip the near plane per pixel since we don't do that on the PC.
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 );
}
}
#else
{
flashlightColor = tex2D( FlashlightSampler, vProjCoords );
#if ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) )
flashlightColor *= flashlightSpacePosition.www > float3(0,0,0); // Catch back projection (PC-only, ps2b and up)
#endif
}
#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, bForceSimple );
float flAttenuated = lerp( saturate( 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_

View File

@ -0,0 +1,23 @@
//
// - This is the fog header to include for pixel shaders if the shader does support pixel-shader-blended vertex fog.
//
// -- PIXELFOGTYPE is 0 for RANGE FOG, 1 for WATER/HEIGHT FOG --
// DYNAMIC: "PIXELFOGTYPE" "0..0" [ = 0; ] //( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0 ]
// -- DOPIXELFOG is 1 if the material has $vertexfog 0, or if the material forces pixel fog by default (lightmappedgeneric for instance.) --
// STATIC: "DOPIXELFOG" "0..0" [ = 0 ]
#if ( PIXELFOGTYPE == 1 )
// No matter what shader model we are, we do pixel fog for water and don't use fixed function hardware fog blending.
#undef DOPIXELFOG
#define DOPIXELFOG 1
#endif
#if defined( SHADER_MODEL_PS_2_0 ) && ( PIXELFOGTYPE == 0 )
#define HARDWAREFOGBLEND 1
#else
#define HARDWAREFOGBLEND 0
#endif
// FIXME! Will need to revisit this once we are doing water/height fog again. Needs to be pixel for in the water case.

View File

@ -0,0 +1,22 @@
//
// - This is the fog header to include for pixel shaders if the shader doesn't support pixel-shader-blended vertex fog.
//
// -- PIXELFOGTYPE is 0 for RANGE FOG, 1 for WATER/HEIGHT FOG --
// DYNAMIC: "PIXELFOGTYPE" "0..1" [ = ( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ]
#if ( PIXELFOGTYPE == 1 )
// No matter what shader model we are, we do pixel fog for water.
#define DOPIXELFOG 1
#define HARDWAREFOGBLEND 0
#else
#if defined( SHADER_MODEL_PS_2_0 )
// Never do pixel for for ps20 (unless we are in water)
#define DOPIXELFOG 0
#define HARDWAREFOGBLEND 1
#else
// Never do vertex fog for >ps20
#define DOPIXELFOG 1
#define HARDWAREFOGBLEND 0
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More