Clients/Client2014/shaders/source/particle.hlsl

85 lines
2.1 KiB
HLSL

#include "globals.h"
sampler2D tex : register(s0);
//#define
uniform float4 colorBias;
uniform float4 throttleFactor; // .x = alpha cutoff, .y = alpha boost (clamp)
struct VS_INPUT
{
float4 pos : POSITION;
float4 scaleRotLife : TEXCOORD0; // transform matrix
float2 disp : TEXCOORD1; // .xy = corner, either (0,0), (1,0), (0,1), or (1,1)
float4 color0: COLOR0;
float4 color1: COLOR1;
};
struct VS_OUTPUT
{
float4 pos : POSITION;
float3 uvFog : TEXCOORD0;
float4 color : COLOR0;
};
float4 rotScale( float4 scaleRotLife )
{
float cr = cos( scaleRotLife.z );
float sr = sin( scaleRotLife.z );
float4 r;
r.x = cr * scaleRotLife.x;
r.y = -sr * scaleRotLife.x;
r.z = sr * scaleRotLife.y;
r.w = cr * scaleRotLife.y;
return r;
}
VS_OUTPUT vs( VS_INPUT input )
{
VS_OUTPUT o;
float4 pos = float4( input.pos.xyz, 1 );
float2 disp = input.disp.xy * 2 - 1; // -1..1
input.scaleRotLife *= float4( 1/256.0f, 1/256.0f, 2 * 3.1415926f / 32767, 1 / 32767.0f );
float4 rs = rotScale( input.scaleRotLife );
pos += G.ViewRight * dot( disp, rs.xy );
pos += G.ViewUp * dot( disp, rs.zw );
o.pos = mul( G.ViewProjection, pos );
o.uvFog.xy = input.disp.xy;
o.uvFog.y = 1 - o.uvFog.y;
o.uvFog.z = (G.FogParams.z - o.pos.w) * G.FogParams.w;
float t = max( 0, min(1, input.scaleRotLife.w ) );
o.color = lerp( input.color1, input.color0, t );
// alpha channel magic for particle throttling
float2 cmp = o.color.aa < throttleFactor.xy;
o.pos.xyz += cmp.xxx * (1e10f).xxx; // move the particle off-screen
o.color.a = lerp( o.color.a, throttleFactor.y, cmp.y ); // if below threshold, alpha = threshold
return o;
}
float4 psAdd( VS_OUTPUT input ) : COLOR0 // #0
{
float4 color = tex2D( tex, input.uvFog.xy );
float4 result = float4( input.color.rgb + color.rgb + colorBias.rgb, color.a * input.color.a );
result.rgb = lerp( G.FogColor.rgb, result.rgb, saturate( input.uvFog.zzz ) );
return result;
}
float4 psMul( VS_OUTPUT input ) : COLOR0 // #1
{
float4 color = tex2D( tex, input.uvFog.xy );
float4 result = input.color * color;
result.rgb = lerp( G.FogColor.rgb, result.rgb, saturate( input.uvFog.zzz ) );
return result;
}