aboutsummaryrefslogtreecommitdiff
path: root/mp/src/materialsystem/stdshaders/spritecard_vsxx.fxc
diff options
context:
space:
mode:
Diffstat (limited to 'mp/src/materialsystem/stdshaders/spritecard_vsxx.fxc')
-rw-r--r--mp/src/materialsystem/stdshaders/spritecard_vsxx.fxc347
1 files changed, 347 insertions, 0 deletions
diff --git a/mp/src/materialsystem/stdshaders/spritecard_vsxx.fxc b/mp/src/materialsystem/stdshaders/spritecard_vsxx.fxc
new file mode 100644
index 00000000..6f670101
--- /dev/null
+++ b/mp/src/materialsystem/stdshaders/spritecard_vsxx.fxc
@@ -0,0 +1,347 @@
+// STATIC: "ZOOM_ANIMATE_SEQ2" "0..1" [vs20]
+// STATIC: "DUALSEQUENCE" "0..1" [vs20]
+// STATIC: "EXTRACTGREENALPHA" "0..1" [vs20]
+
+// STATIC: "ZOOM_ANIMATE_SEQ2" "0..0" [vs11]
+// STATIC: "DUALSEQUENCE" "0..0" [vs11]
+// STATIC: "EXTRACTGREENALPHA" "0..0" [vs11]
+
+// STATIC: "USE_INSTANCING" "0..1" [vs20]
+// DYNAMIC: "ORIENTATION" "0..2"
+
+
+#include "common_vs_fxc.h"
+
+const float4x3 cModelView : register(SHADER_SPECIFIC_CONST_0);
+const float4x4 cProj : register(SHADER_SPECIFIC_CONST_3);
+
+#if ZOOM_ANIMATE_SEQ2
+const float4 ScaleParms : register(SHADER_SPECIFIC_CONST_7);
+#define OLDFRM_SCALE_START (ScaleParms.x)
+#define OLDFRM_SCALE_END (ScaleParms.y)
+#endif
+
+const float4 SizeParms : register(SHADER_SPECIFIC_CONST_8);
+const float4 SizeParms2 : register(SHADER_SPECIFIC_CONST_9);
+const float4 ViewportTransformScaled : register(SHADER_SPECIFIC_CONST_10);
+
+#define MINIMUM_SIZE_FACTOR (SizeParms.x)
+#define MAXIMUM_SIZE_FACTOR (SizeParms.y)
+
+#define START_FADE_SIZE_FACTOR (SizeParms.z)
+#define END_FADE_SIZE_FACTOR (SizeParms.w)
+
+// alpha fade w/ distance
+#define START_FAR_FADE ( SizeParms2.x )
+#define FAR_FADE_FACTOR ( SizeParms2.y ) // alpha = 1-min(1,max(0, (dist-start_fade)*factor))
+
+// Define stuff for instancing on 360
+#if ( defined( _X360 ) && defined( SHADER_MODEL_VS_2_0 ) )
+#define CONST_PC
+#define VERTEX_INDEX_PARAM_360 ,int Index:INDEX
+#define DO_INSTANCING 1
+#else
+#define CONST_PC const
+#define VERTEX_INDEX_PARAM_360
+#endif
+
+
+struct VS_INPUT
+{
+ // This is all of the stuff that we ever use.
+ float4 vTint : COLOR;
+ float4 vPos : POSITION;
+ float4 vTexCoord0 : TEXCOORD0;
+ float4 vTexCoord1 : TEXCOORD1;
+ float4 vParms : TEXCOORD2; // frame blend, rot, radius, yaw
+ // FIXME: remove this vertex element for (USE_INSTANCING == 1), need to shuffle the following elements down
+ float2 vCornerID : TEXCOORD3; // 0,0 1,0 1,1 0,1
+ float4 vTexCoord2 : TEXCOORD4;
+#if DUALSEQUENCE
+ float4 vSeq2TexCoord0 : TEXCOORD5;
+ float4 vSeq2TexCoord1 : TEXCOORD6;
+ float4 vParms1 : TEXCOORD7; // second frame blend, ?,?,?
+#endif
+};
+
+struct VS_OUTPUT
+{
+ float4 projPos : POSITION;
+
+ float2 texCoord0 : TEXCOORD0;
+ float2 texCoord1 : TEXCOORD1;
+ float4 argbcolor : COLOR;
+ float4 blendfactor0 : TEXCOORD2;
+ float2 texCoord2 : TEXCOORD3;
+#if !defined( SHADER_MODEL_VS_1_1 )
+ float4 blendfactor1 : TEXCOORD4; // for extracting green/alpha
+#endif
+#if DUALSEQUENCE
+ float2 vSeq2TexCoord0 : TEXCOORD5;
+ float2 vSeq2TexCoord1 : TEXCOORD6;
+#endif
+
+#if defined( _X360 )
+ float4 vScreenPos_ReverseZ : TEXCOORD7;
+#else
+ float4 vScreenPos : TEXCOORD7;
+#endif
+};
+
+#define BLENDFACTOR v.vParms.x
+#define ROTATION v.vParms.y
+#define RADIUS v.vParms.z
+#define YAW (v.vParms.w)
+
+#if ( ZOOM_ANIMATE_SEQ2 )
+float getlerpscaled( float l_in, float s0, float s1, float ts )
+{
+ l_in = 2.0*(l_in-.5);
+ l_in *= lerp(s0,s1,ts);
+ return 0.5+0.5*l_in;
+}
+
+float getlerpscale_for_old_frame( float l_in, float ts )
+{
+ return getlerpscaled( l_in, OLDFRM_SCALE_START, OLDFRM_SCALE_END, ts);
+}
+
+float getlerpscale_for_new_frame( float l_in, float ts )
+{
+ return getlerpscaled( l_in, 1.0, OLDFRM_SCALE_START, ts );
+}
+#endif // ZOOM_ANIMATE_SEQ2
+
+#ifdef DO_INSTANCING
+void InstancedVertexRead( inout VS_INPUT v, int index )
+{
+ // Duplicate each VB vertex 4 times (and generate vCornerID - the only thing that varies per-corner)
+ float4 vTint;
+ float4 vPos;
+ float4 vTexCoord0;
+ float4 vTexCoord1;
+ float4 vParms;
+ float4 vTexCoord2;
+ float4 vSeq_TexCoord0; // NOTE: April XDK compiler barfs on var names which have a number in the middle! (i.e. vSeq2TexCoord0)
+ float4 vSeq_TexCoord1;
+ float4 vParms1;
+
+ int spriteIndex = index / 4;
+ int cornerIndex = index - 4*spriteIndex;
+ asm
+ {
+ vfetch vTint, spriteIndex, color0;
+ vfetch vPos, spriteIndex, position0;
+ vfetch vTexCoord0, spriteIndex, texcoord0;
+ vfetch vTexCoord1, spriteIndex, texcoord1;
+ vfetch vParms, spriteIndex, texcoord2;
+ vfetch vTexCoord2, spriteIndex, texcoord4;
+#if DUALSEQUENCE
+ vfetch vSeq_TexCoord0, spriteIndex, texcoord5;
+ vfetch vSeq_TexCoord1, spriteIndex, texcoord6;
+ vfetch vParms1, spriteIndex, texcoord7;
+#endif
+ };
+
+ v.vTint = vTint;
+ v.vPos = vPos;
+ v.vTexCoord0 = vTexCoord0;
+ v.vTexCoord1 = vTexCoord1;
+ v.vParms = vParms;
+ v.vTexCoord2 = vTexCoord2;
+#if DUALSEQUENCE
+ v.vSeq2TexCoord0 = vSeq_TexCoord0;
+ v.vSeq2TexCoord1 = vSeq_TexCoord1;
+ v.vParms1 = vParms1;
+#endif
+
+ // Compute vCornerID - order is: (0,0) (1,0) (1,1) (0,1)
+ // float2 IDs[4] = { {0,0}, {1,0}, {1,1}, {0,1} };
+ // v.vCornerID.xy = IDs[ cornerIndex ];
+ // This compiles to 2 ops on 360 (MADDs with abs/sat register read/write modifiers):
+ v.vCornerID.xy = float2( 1.5f, 0.0f ) + cornerIndex*float2( -1.0f, 1.0f );
+ v.vCornerID.xy = saturate( float2(1.5f, -3.0f) + float2( -1.0f, 2.0f )*abs( v.vCornerID.xy ) );
+}
+#endif
+
+VS_OUTPUT main( CONST_PC VS_INPUT v
+ VERTEX_INDEX_PARAM_360 )
+{
+ VS_OUTPUT o;
+
+#ifdef DO_INSTANCING
+ if ( USE_INSTANCING )
+ {
+ InstancedVertexRead( v, Index );
+ }
+#endif
+
+#if SHADER_MODEL_VS_1_1
+ float4 tint = v.vTint;
+#else
+ float4 tint = GammaToLinear( v.vTint );
+#endif
+
+ float2 sc_yaw;
+ sincos( YAW, sc_yaw.y, sc_yaw.x );
+
+ float2 sc;
+ sincos( ROTATION, sc.y, sc.x );
+
+ float2 ix=2*v.vCornerID.xy-1;
+ float x1=dot(ix,sc);
+ float y1=sc.x*ix.y-sc.y*ix.x;
+
+ float4 projPos;
+ float3 worldPos;
+ worldPos = mul4x3( v.vPos, cModel[0] );
+
+ float rad = RADIUS;
+ float3 v2p = ( worldPos - cEyePos );
+ float l = length(v2p);
+ rad=max(rad, MINIMUM_SIZE_FACTOR * l);
+ // now, perform fade out
+#ifndef SHADER_MODEL_VS_1_1
+ if ( rad > START_FADE_SIZE_FACTOR * l )
+ {
+ if ( rad > END_FADE_SIZE_FACTOR *l )
+ {
+ tint = 0;
+ rad = 0; // cull so we emit 0-sized sprite
+ }
+ else
+ {
+ tint *= 1-(rad-START_FADE_SIZE_FACTOR*l)/(END_FADE_SIZE_FACTOR*l-START_FADE_SIZE_FACTOR*l);
+ }
+ }
+#endif
+
+
+#ifndef SHADER_MODEL_VS_1_1
+ // perform far fade
+ float tscale = 1-min(1, max(0, (l-START_FAR_FADE)*FAR_FADE_FACTOR) );
+ tint *= tscale;
+
+ if ( tscale <= 0)
+ rad = 0; // cull so we emit 0-sized sprite
+#endif
+
+ rad=min(rad, MAXIMUM_SIZE_FACTOR * l);
+
+#if ORIENTATION == 0
+ // Screen-aligned case
+ float3 viewPos;
+ viewPos = mul4x3( v.vPos, cModelView );
+
+ float3 disp=float3( -x1,y1,0);
+ float tmpx=disp.x*sc_yaw.x+disp.z*sc_yaw.y;
+ disp.z = disp.z*sc_yaw.x-disp.x*sc_yaw.y;
+ disp.x=tmpx;
+
+ viewPos.xyz += disp * rad;
+
+ projPos = mul( float4(viewPos, 1.0f), cProj );
+#endif
+
+#if ORIENTATION == 1
+ // Z-aligned case
+ if (l > rad/2)
+ {
+ float3 up = float3(0,0,1);
+ float3 right = normalize(cross(up, v2p));
+ float tmpx=right.x*sc_yaw.x+right.y*sc_yaw.y;
+ right.y = right.y*sc_yaw.x-right.x*sc_yaw.y;
+ right.x=tmpx;
+
+ worldPos += (x1*rad)*right;
+ worldPos.z += (y1*rad)*up.z;
+
+#ifndef SHADER_MODEL_VS_1_1
+ if (l < rad*2 )
+ {
+ tint *= smoothstep(rad/2,rad,l);
+ }
+#endif
+
+ }
+ projPos = mul( float4(worldPos, 1.0f), cViewProj );
+#endif
+
+#if ORIENTATION == 2
+ // aligned with z plane case - easy
+ float3 wpos=v.vPos+RADIUS*float3( y1,x1,0);
+ projPos = mul( float4(wpos, 1.0f), cModelViewProj );
+#endif
+
+ o.blendfactor0 = float4( v.vParms.x, 0, 0, 0 );
+ o.projPos = projPos;
+ o.texCoord0.x = lerp( v.vTexCoord0.z, v.vTexCoord0.x, v.vCornerID.x );
+ o.texCoord0.y = lerp( v.vTexCoord0.w, v.vTexCoord0.y, v.vCornerID.y );
+ o.texCoord1.x = lerp( v.vTexCoord1.z, v.vTexCoord1.x, v.vCornerID.x );
+ o.texCoord1.y = lerp( v.vTexCoord1.w, v.vTexCoord1.y, v.vCornerID.y );
+ o.texCoord2.x = lerp( v.vTexCoord2.z, v.vTexCoord2.x, v.vCornerID.x );
+ o.texCoord2.y = lerp( v.vTexCoord2.w, v.vTexCoord2.y, v.vCornerID.y );
+
+#if ( DUALSEQUENCE )
+ float2 lerpold = v.vCornerID.xy;
+ float2 lerpnew = v.vCornerID.xy;
+
+#if ( ZOOM_ANIMATE_SEQ2 )
+ lerpold.x = getlerpscale_for_old_frame( v.vCornerID.x, v.vParms1.x );
+ lerpold.y = getlerpscale_for_old_frame( v.vCornerID.y, v.vParms1.x );
+ lerpnew.x = getlerpscale_for_new_frame( v.vCornerID.x, v.vParms1.x );
+ lerpnew.y = getlerpscale_for_new_frame( v.vCornerID.y, v.vParms1.x );
+#endif
+
+ o.vSeq2TexCoord0.xy = lerp( v.vSeq2TexCoord0.zw, v.vSeq2TexCoord0.xy, lerpold.xy );
+ o.vSeq2TexCoord1.xy = lerp( v.vSeq2TexCoord1.zw, v.vSeq2TexCoord1.xy, lerpnew.xy );
+
+ o.blendfactor0.z = v.vParms1.x;
+#endif
+
+
+#if !defined( SHADER_MODEL_VS_1_1 )
+
+ o.blendfactor1 = float4( 0.0f, 0.0f, 0.0f, 0.0f );
+
+#if ( EXTRACTGREENALPHA )
+ // Input range Output range
+ if ( v.vParms.x < 0.25f ) // 0.0 .. 0.25
+ {
+ o.blendfactor0.a = v.vParms.x * 2 + 0.5f; // 0.5 .. 1.0
+ o.blendfactor0.g = 1 - o.blendfactor0.a; // 0.5 .. 0.0
+ }
+ else if ( v.vParms.x < 0.75f ) // 0.25 .. 0.75
+ {
+ o.blendfactor1.g = v.vParms.x * 2 - 0.5f; // 0.0 .. 1.0
+ o.blendfactor0.a = 1 - o.blendfactor1.g; // 1.0 .. 0.0
+ }
+ else // 0.75 .. 1.0
+ {
+ o.blendfactor1.a = v.vParms.x * 2 - 1.5f; // 0.0 .. 0.5
+ o.blendfactor1.g = 1 - o.blendfactor1.a; // 1.0 .. 0.5
+ }
+#endif
+
+#endif
+
+ // Map projected position to the refraction texture
+ float2 vScreenPos;
+ vScreenPos.x = projPos.x;
+ vScreenPos.y = -projPos.y; // invert Y
+ vScreenPos = (vScreenPos + projPos.w) * 0.5f;
+
+ // Need to also account for the viewport transform, which matters when rendering with mat_viewportscale != 1.0
+ vScreenPos = (vScreenPos * ViewportTransformScaled.xy) + (projPos.w * ViewportTransformScaled.zw);
+
+#if defined( _X360 )
+ o.vScreenPos_ReverseZ = float4(vScreenPos.x, vScreenPos.y, projPos.w - projPos.z, projPos.w );
+#else
+ o.vScreenPos = float4(vScreenPos.x, vScreenPos.y, projPos.z, projPos.w );
+#endif
+
+ o.argbcolor = tint;
+ return o;
+}
+
+