mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-01-21 11:17:56 +03:00
7309a5f13f
This should include the latest version of every shader that was in the 2007 SDK. It also includes a smattering of debug shaders, both VR distortion shaders, and other assorted shaders that will hopefully be useful. None of these new files are included in the game shader DLL project. If you need to modify one of these shaders for use in your mod you will need to rename it so that you don't collide with the version of that shader that lives in stdshader_dx9.dll.
218 lines
8.8 KiB
Plaintext
218 lines
8.8 KiB
Plaintext
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
|
|
|
|
// STATIC: "INTRO" "0..1"
|
|
// STATIC: "HALFLAMBERT" "0..1"
|
|
// STATIC: "FLASHLIGHT" "0..1"
|
|
// STATIC: "LIGHTWARPTEXTURE" "0..1"
|
|
|
|
// DYNAMIC: "COMPRESSED_VERTS" "0..1"
|
|
// DYNAMIC: "SKINNING" "0..1"
|
|
// DYNAMIC: "DOWATERFOG" "0..1"
|
|
// DYNAMIC: "DYNAMIC_LIGHT" "0..1"
|
|
// DYNAMIC: "STATIC_LIGHT" "0..1"
|
|
// DYNAMIC: "NUM_LIGHTS" "0..4"
|
|
// DYNAMIC: "MORPHING" "0..1" [vs30]
|
|
|
|
#include "vortwarp_vs20_helper.h"
|
|
|
|
static const bool g_bSkinning = SKINNING ? true : false;
|
|
static const int g_iFogType = DOWATERFOG;
|
|
static const bool g_bHalfLambert = HALFLAMBERT ? true : false;
|
|
|
|
const float3 g_cEyeOrigin : register( SHADER_SPECIFIC_CONST_0 );
|
|
const float4 g_vIrisProjectionU : register( SHADER_SPECIFIC_CONST_2 );
|
|
const float4 g_vIrisProjectionV : register( SHADER_SPECIFIC_CONST_3 );
|
|
const float4 g_vFlashlightPosition : register( SHADER_SPECIFIC_CONST_4 );
|
|
|
|
#if INTRO
|
|
const float4 g_vConst4 : register( SHADER_SPECIFIC_CONST_5 );
|
|
#define g_vModelOrigin g_vConst4.xyz
|
|
#define g_flTime g_vConst4.w
|
|
#endif
|
|
|
|
const float4 g_vFlashlightMatrixRow1 : register( SHADER_SPECIFIC_CONST_6 );
|
|
const float4 g_vFlashlightMatrixRow2 : register( SHADER_SPECIFIC_CONST_7 );
|
|
const float4 g_vFlashlightMatrixRow3 : register( SHADER_SPECIFIC_CONST_8 );
|
|
const float4 g_vFlashlightMatrixRow4 : register( SHADER_SPECIFIC_CONST_9 );
|
|
|
|
#ifdef SHADER_MODEL_VS_3_0
|
|
// NOTE: cMorphTargetTextureDim.xy = target dimensions,
|
|
// cMorphTargetTextureDim.z = 4tuples/morph
|
|
const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 );
|
|
const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 );
|
|
|
|
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
|
|
|
|
// Position deltas
|
|
float3 vPosFlex : POSITION1;
|
|
|
|
#ifdef SHADER_MODEL_VS_3_0
|
|
float vVertexID : POSITION2;
|
|
#endif
|
|
};
|
|
|
|
struct VS_OUTPUT
|
|
{
|
|
float4 projPos : POSITION; // Projection-space position
|
|
#if !defined( _X360 )
|
|
float fog : FOG; // Fixed-function fog factor
|
|
#endif
|
|
float4 vAmbientOcclUv_fallbackCorneaUv : TEXCOORD0; // Base texture coordinate
|
|
float4 cVertexLight : TEXCOORD1; // Vertex-lit color (Note: w is used for flashlight pass)
|
|
float4 vTangentViewVector : TEXCOORD2; // Tangent view vector (Note: w is used for flashlight pass)
|
|
float4 vWorldPosition_ProjPosZ : TEXCOORD3;
|
|
float3 vWorldNormal : TEXCOORD4; // World-space normal
|
|
float3 vWorldTangent : TEXCOORD5; // World-space tangent
|
|
float4 vLightFalloffCosine01 : TEXCOORD6; // Light falloff and cosine terms for first two local lights
|
|
float4 vLightFalloffCosine23 : TEXCOORD7; // Light falloff and cosine terms for next two local lights
|
|
|
|
float3 vWorldBinormal : COLOR0; // World-space normal
|
|
};
|
|
|
|
VS_OUTPUT main( const VS_INPUT v )
|
|
{
|
|
VS_OUTPUT o;
|
|
|
|
bool bDynamicLight = DYNAMIC_LIGHT ? true : false;
|
|
bool bStaticLight = STATIC_LIGHT ? true : false;
|
|
int nNumLights = NUM_LIGHTS;
|
|
|
|
float4 vPosition = v.vPos;
|
|
|
|
#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING
|
|
ApplyMorph( v.vPosFlex, vPosition.xyz );
|
|
#else
|
|
ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz );
|
|
#endif
|
|
|
|
// Transform the position
|
|
float3 vWorldPosition;
|
|
SkinPosition( g_bSkinning, vPosition, v.vBoneWeights, v.vBoneIndices, vWorldPosition );
|
|
|
|
// Note: I'm relying on the iris projection vector math not changing or this will break
|
|
float3 vEyeSocketUpVector = normalize( -g_vIrisProjectionV.xyz );
|
|
float3 vEyeSocketLeftVector = normalize( -g_vIrisProjectionU.xyz );
|
|
|
|
#if INTRO
|
|
float3 dummy = float3( 0.0f, 0.0f, 0.0f );
|
|
WorldSpaceVertexProcess( g_flTime, g_vModelOrigin, vWorldPosition, dummy, dummy, dummy );
|
|
#endif
|
|
|
|
o.vWorldPosition_ProjPosZ.xyz = vWorldPosition.xyz;
|
|
|
|
// Transform into projection space
|
|
//vWorldPosition -= ( vWorldPosition - g_cEyeOrigin ) * 0.9; //Debug to visualize eye origin
|
|
float4 vProjPos = mul( float4( vWorldPosition, 1.0f ), cViewProj );
|
|
o.projPos = vProjPos;
|
|
vProjPos.z = dot( float4( vWorldPosition, 1.0f ), cViewProjZ );
|
|
|
|
|
|
o.vWorldPosition_ProjPosZ.w = vProjPos.z;
|
|
|
|
#if !defined( _X360 )
|
|
// Set fixed-function fog factor
|
|
o.fog = CalcFog( vWorldPosition, vProjPos, g_iFogType );
|
|
#endif
|
|
|
|
// Normal = (Pos - Eye origin)
|
|
float3 vWorldNormal = normalize( vWorldPosition.xyz - g_cEyeOrigin.xyz );
|
|
o.vWorldNormal.xyz = vWorldNormal.xyz;
|
|
|
|
// Tangent & binormal
|
|
/*
|
|
float3 vWorldBinormal = normalize( cross( vWorldNormal.xyz, vEyeSocketLeftVector.xyz ) );
|
|
o.vWorldBinormal.xyz = vWorldBinormal.xyz * 0.5f + 0.5f;
|
|
|
|
float3 vWorldTangent = normalize( cross( vWorldBinormal.xyz, vWorldNormal.xyz ) );
|
|
o.vWorldTangent.xyz = vWorldTangent.xyz;
|
|
//*/
|
|
|
|
//*
|
|
float3 vWorldTangent = normalize( cross( vEyeSocketUpVector.xyz, vWorldNormal.xyz ) );
|
|
o.vWorldTangent.xyz = vWorldTangent.xyz;
|
|
|
|
float3 vWorldBinormal = normalize( cross( vWorldNormal.xyz, vWorldTangent.xyz ) );
|
|
o.vWorldBinormal.xyz = vWorldBinormal.xyz * 0.5f + 0.5f;
|
|
//*/
|
|
|
|
float3 vWorldViewVector = normalize (vWorldPosition.xyz - cEyePos.xyz);
|
|
o.vTangentViewVector.xyz = Vec3WorldToTangentNormalized (vWorldViewVector.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz);
|
|
|
|
// AV - I think this will effectively make the eyeball less rounded left to right to help vertext lighting quality
|
|
// AV - Note: This probably won't look good if put on an exposed eyeball
|
|
//float vNormalDotSideVec = -dot( vWorldNormal, g_vEyeballUp ) * 0.5f;
|
|
float vNormalDotSideVec = -dot( vWorldNormal, vEyeSocketLeftVector) * 0.5f;
|
|
float3 vBentWorldNormal = normalize(vNormalDotSideVec * vEyeSocketLeftVector + vWorldNormal);
|
|
|
|
// Compute vertex lighting
|
|
o.cVertexLight.a = 0.0f; //Only used for flashlight pass
|
|
o.cVertexLight.rgb = DoLightingUnrolled( vWorldPosition, vBentWorldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert, nNumLights );
|
|
|
|
// Only interpolate ambient light for TF NPR lighting
|
|
bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false;
|
|
if ( bDoDiffuseWarp )
|
|
{
|
|
if( bDynamicLight )
|
|
{
|
|
o.cVertexLight.rgb = AmbientLight( vBentWorldNormal.xyz );
|
|
}
|
|
else
|
|
{
|
|
o.cVertexLight.rgb = float3( 0.0f, 0.0f, 0.0f );
|
|
}
|
|
}
|
|
|
|
// NOTE: it appears that o.vLightFalloffCosine01 and o.vLightFalloffCosine23 are filled in even if
|
|
// we don't have enough lights, meaning we pass garbage to the pixel shader which then throws it away
|
|
|
|
// Light falloff for first two local lights
|
|
o.vLightFalloffCosine01.x = VertexAttenInternal( vWorldPosition.xyz, 0 );
|
|
o.vLightFalloffCosine01.y = VertexAttenInternal( vWorldPosition.xyz, 1 );
|
|
o.vLightFalloffCosine01.z = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 0, g_bHalfLambert );
|
|
o.vLightFalloffCosine01.w = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 1, g_bHalfLambert );
|
|
|
|
// Light falloff for next two local lights
|
|
o.vLightFalloffCosine23.x = VertexAttenInternal( vWorldPosition.xyz, 2 );
|
|
o.vLightFalloffCosine23.y = VertexAttenInternal( vWorldPosition.xyz, 3 );
|
|
o.vLightFalloffCosine23.z = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 2, g_bHalfLambert );
|
|
o.vLightFalloffCosine23.w = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 3, g_bHalfLambert );
|
|
|
|
// Texture coordinates set by artists for ambient occlusion
|
|
o.vAmbientOcclUv_fallbackCorneaUv.xy = v.vTexCoord0.xy;
|
|
|
|
// Cornea uv for ps.2.0 fallback
|
|
float2 vCorneaUv; // Note: Cornea texture is a cropped version of the iris texture
|
|
vCorneaUv.x = dot( g_vIrisProjectionU, float4( vWorldPosition, 1.0f ) );
|
|
vCorneaUv.y = dot( g_vIrisProjectionV, float4( vWorldPosition, 1.0f ) );
|
|
float2 vSphereUv = ( vCorneaUv.xy * 0.5f ) + 0.25f;
|
|
o.vAmbientOcclUv_fallbackCorneaUv.wz = vCorneaUv.xy; // Note: wz unpacks faster than zw in ps.2.0!
|
|
|
|
// Step on the vertex light interpolator for the flashlight tex coords
|
|
bool bFlashlight = ( FLASHLIGHT != 0 ) ? true : false;
|
|
o.vTangentViewVector.w = 0.0f;
|
|
if ( bFlashlight )
|
|
{
|
|
o.cVertexLight.x = dot( g_vFlashlightMatrixRow1.xyzw, float4( vWorldPosition, 1.0f ) );
|
|
o.cVertexLight.y = dot( g_vFlashlightMatrixRow2.xyzw, float4( vWorldPosition, 1.0f ) );
|
|
o.cVertexLight.z = dot( g_vFlashlightMatrixRow3.xyzw, float4( vWorldPosition, 1.0f ) );
|
|
o.cVertexLight.w = dot( g_vFlashlightMatrixRow4.xyzw, float4( vWorldPosition, 1.0f ) );
|
|
|
|
o.vTangentViewVector.w = saturate( dot( vBentWorldNormal.xyz, normalize ( g_vFlashlightPosition.xyz - vWorldPosition.xyz ) ) ); // Flashlight N.L with modified normal
|
|
|
|
// Half lambert version
|
|
//o.cVertexLight.z = dot( vBentWorldNormal.xyz, normalize ( g_vFlashlightPosition.xyz - vWorldPosition.xyz ) ); // Flashlight N.L with modified normal
|
|
//o.cVertexLight.z = ( o.cVertexLight.z * 0.5f ) + 0.5f;
|
|
//o.cVertexLight.z *= o.cVertexLight.z;
|
|
}
|
|
|
|
return o;
|
|
}
|