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
|
// STATIC: "MAXTEXTURESTAGES" "0..2"
// STATIC: "HASALPHAMASK" "0..1"
// STATIC: "HASSTATICTEXTURE" "0..1"
// STATIC: "USEALTERNATEVIEW" "0..1"
// DYNAMIC: "SKINNING" "0..1"
// DYNAMIC: "ADDSTATIC" "0..1"
//in multipass configurations, this specifies whether we're adding static on this pass
#define TEXTURESTAGES (MAXTEXTURESTAGES + 1)
#define USESTATICTEXTURE (((ADDSTATIC == 1) && (HASSTATICTEXTURE == 1))?(1):(0))
#include "common_vs_fxc.h"
static const int g_bSkinning = SKINNING ? true : false;
#if ( USEALTERNATEVIEW == 1 )
const float4x4 g_CustomViewProj : register( SHADER_SPECIFIC_CONST_0 );
#endif
struct VS_INPUT
{
float4 vPos : POSITION;
float4 vBoneWeights : BLENDWEIGHT;
float4 vBoneIndices : BLENDINDICES;
float2 vMappingTexCoord : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 vProjPos : POSITION;
float2 vPrimaryTexCoord : TEXCOORD0; //either the portal cutout, or static
# if( TEXTURESTAGES == 3 )
# if( (HASALPHAMASK == 1) || (USESTATICTEXTURE == 1) )
float2 vSecondaryTexCoord : TEXCOORD1;
# if( (HASALPHAMASK == 1) && (USESTATICTEXTURE == 1) )
float2 vTertiaryTexCoord : TEXCOORD2;
# endif
# endif
# elif( TEXTURESTAGES > 1 && HASALPHAMASK == 1 )
float2 vSecondaryTexCoord : TEXCOORD1;
# endif
# if( !defined( _X360 ) )
float vFog : FOG;
# endif
};
float2 GetPortalTextureCoordinate( float3 worldPos, float4 projPos )
{
float2 result;
float4 vTextureProjectedPos;
#if ( USEALTERNATEVIEW == 1 )
vTextureProjectedPos = mul( float4( worldPos, 1 ), g_CustomViewProj );
#else
vTextureProjectedPos = projPos;
#endif
//Screen coordinates mapped back to texture coordinates for the portal texture
result.x = vTextureProjectedPos.x;
result.y = -vTextureProjectedPos.y; // invert Y
result.xy = (result.xy + vTextureProjectedPos.w) * 0.5f;
result.xy = result.xy / vTextureProjectedPos.w;
#if ( USEALTERNATEVIEW == 1 )
result.xy = saturate( result.xy ); //stretch instead of clipping.
#endif
return result;
}
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 );
o.vProjPos = mul( float4( worldPos, 1 ), cViewProj );
//Because we're pairing this with ps11, we can't divide the portal cutout texture coordinates in the pixel shader by w
//So, we had to divide it by w here in the vertex shader. Unfortunately that causes some interpolation inconsistencies
//between the position and the texture coordinate. So we also divide the position by w here. Causing the exact same projection
//errors for both position and texture coordinate, thereby eliminating the difference between the two that cause the "warping" look.
o.vProjPos.xyz = o.vProjPos.xyz * (1.0f / o.vProjPos.w);
o.vProjPos.w = 1.0f;
#if !defined( _X360 )
o.vFog = CalcFog( worldPos, o.vProjPos.xyz, FOGTYPE_RANGE );
#endif
# if( TEXTURESTAGES == 3 )//single pass configuration
{
o.vPrimaryTexCoord = GetPortalTextureCoordinate( worldPos, o.vProjPos );
# if( HASALPHAMASK == 1 )
{
o.vSecondaryTexCoord = v.vMappingTexCoord.xy;
# if( USESTATICTEXTURE == 1 )
o.vTertiaryTexCoord = v.vMappingTexCoord.xy;
# endif
}
# else
{
# if( USESTATICTEXTURE == 1 )
o.vSecondaryTexCoord = v.vMappingTexCoord.xy;
# endif
}
# endif
}
# else //multipass configuration
{
# if( ADDSTATIC == 0 ) //if addstatic is 0, we're rendering the cutout on this pass, if it's 1, we're rendering static on this pass
{
o.vPrimaryTexCoord = GetPortalTextureCoordinate( worldPos, o.vProjPos );
}
# else
{
o.vPrimaryTexCoord = v.vMappingTexCoord.xy;
}
# endif
# if( (TEXTURESTAGES > 1) && (HASALPHAMASK == 1) ) //supports alpha mask as well
o.vSecondaryTexCoord = v.vMappingTexCoord.xy;
# endif
}
# endif
return o;
}
|