1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
//========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============//
// STATIC: "HALFLAMBERT" "0..1"
// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20]
// 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..2" [vs20]
// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo
// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20]
// Includes
#include "common_vs_fxc.h"
// Globals
static const int g_iFogType = DOWATERFOG;
static const bool g_bHalfLambert = HALFLAMBERT ? true : false;
static const bool g_bSkinning = SKINNING ? true : false;
const float4 g_vConst0 : register( SHADER_SPECIFIC_CONST_0 );
#define g_flTime g_vConst0.x
#define g_flNoiseUvScroll g_vConst0.y
#define g_flBorderNoiseScale g_vConst0.z
#define g_flDebugForceFleshOn g_vConst0.w
const float4 g_vEffectCenterOoRadius1 : register( SHADER_SPECIFIC_CONST_1 ); //= { -295.0f, -5.0f, 40.0f, 1.0f/20.0f };
const float4 g_vEffectCenterOoRadius2 : register( SHADER_SPECIFIC_CONST_2 ); //= { -295.0f, 15.0f, 40.0f, 1.0f/10.0f };
const float4 g_vEffectCenterOoRadius3 : register( SHADER_SPECIFIC_CONST_3 ); //= { -295.0f, 35.0f, 40.0f, 1.0f/10.0f };
const float4 g_vEffectCenterOoRadius4 : register( SHADER_SPECIFIC_CONST_4 ); //= { -295.0f, 55.0f, 40.0f, 1.0f/10.0f };
// 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
float3 vPosFlex : POSITION1; // Delta positions for flexing
float4 vTangent : TANGENT;
};
struct VS_OUTPUT
{
float4 vProjPosition : POSITION; // Projection-space position
float2 vTexCoord0 : TEXCOORD0;
float2 flDistanceToEffectCenter_flFresnelEffect : TEXCOORD1;
float4 vNoiseTexCoord : TEXCOORD2;
float3 vTangentViewVector : TEXCOORD3;
float3 cVertexLight : TEXCOORD4;
float3x3 mTangentSpaceTranspose : TEXCOORD5;
// second row : TEXCOORD6;
// third row : TEXCOORD7;
};
// 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;
vObjPosition.xyz += i.vPosFlex.xyz * cFlexScale.x;
float3 vObjNormal;
float4 vObjTangent;
DecompressVertex_NormalTangent( i.vNormal, i.vTangent, vObjNormal, vObjTangent );
// 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, vObjTangent, i.vBoneWeights, i.vBoneIndices, vWorldPosition, vWorldNormal, vWorldTangent, vWorldBinormal );
// Transform into projection space
float4 vProjPosition = mul( float4( vWorldPosition, 1.0f ), cViewProj );
o.vProjPosition = vProjPosition;
// Pass through tex coords
o.vTexCoord0.xy = i.vTexCoord0.xy;
// Store the closest effect intensity
o.flDistanceToEffectCenter_flFresnelEffect.x = 9999.0f; // A very large distance
o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius1.xyz ) * g_vEffectCenterOoRadius1.w );
o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius2.xyz ) * g_vEffectCenterOoRadius2.w );
o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius3.xyz ) * g_vEffectCenterOoRadius3.w );
o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius4.xyz ) * g_vEffectCenterOoRadius4.w );
/*
// Test values for development in Alyx_interior map
o.flDistanceToEffectCenter_flFresnelEffect.x = 9999.0f; // A very large distance
float3 vTestPosition = { -295.0f, -5.0f, 40.0f };
float flMinY = -5.0f;
float flMaxY = 66.0f;
vTestPosition.y = lerp( flMinY, flMaxY, ( abs( frac( g_flTime / 20.0f ) * 2.0 - 1.0 ) ) );
//vTestPosition.y = lerp( flMinY, flMaxY, 0.65f );
//1.0f - saturate( i.flDistanceToEffectCenter_flFresnelEffect.x * 4.0f - 3.0f )
//o.flDistanceToEffectCenter_flFresnelEffect.x = 9999.0f; // A very large distance
const float g_flInteriorRadius = 20.0f;
if ( g_flInteriorRadius )
{
o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - vTestPosition.xyz ) / g_flInteriorRadius );
}
const float g_flInteriorRadius2 = 14.0f;
if ( g_flInteriorRadius2 )
{
vTestPosition.y = lerp( flMinY, flMaxY, 0.65f );
//vTestPosition.z = lerp( 37, 45, ( abs( frac( g_flTime / 4.0f ) * 2.0 - 1.0 ) ) );
o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - vTestPosition.xyz ) / g_flInteriorRadius2 );
}
//*/
if ( g_flDebugForceFleshOn )
{
o.flDistanceToEffectCenter_flFresnelEffect.x = 0.0f;
}
// Fresnel mask
float3 vWorldViewVector = normalize( vWorldPosition.xyz - cEyePos.xyz );
o.flDistanceToEffectCenter_flFresnelEffect.y = pow( saturate( dot( -vWorldViewVector.xyz, vWorldNormal.xyz ) ), 1.5f );
// Noise UV
o.vNoiseTexCoord.xy = o.vTexCoord0.xy * g_flBorderNoiseScale + g_flNoiseUvScroll;
o.vNoiseTexCoord.zw = o.vTexCoord0.xy * g_flBorderNoiseScale - g_flNoiseUvScroll; // Will fetch as wz to avoid matching layers
// Tangent view vector
o.vTangentViewVector.xyz = Vec3WorldToTangentNormalized( vWorldViewVector.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz );
// Compute vertex lighting
bool bDynamicLight = DYNAMIC_LIGHT ? true : false;
bool bStaticLight = STATIC_LIGHT ? true : false;
#if ( USE_STATIC_CONTROL_FLOW ) || defined ( SHADER_MODEL_VS_3_0 )
o.cVertexLight.rgb = DoLighting( vWorldPosition, vWorldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert );
#else
o.cVertexLight.rgb = DoLightingUnrolled( vWorldPosition, vWorldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert, NUM_LIGHTS );
#endif
// 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 );
return o;
}
|