etqw-sdk/base/renderprogs/litsmoke.hg

217 lines
6.5 KiB
Plaintext

/**
Template cg program
*/
struct VsInputs {
float3 corner : $positionAttrib;
float4 tex : $texCoordAttrib;
float4 col : $colorAttrib;
float3 center : $normalAttrib;
float4 tang : $tangentAttrib;
$if r_32ByteVtx
float4 signs : $signAttrib;
$endif
};
struct VsOutputs {
float4 col : COLOR1;
float4 atten: COLOR0;
float2 tex : TEXCOORD0;
float3 tang : TEXCOORD1;
float3 bino : TEXCOORD2;
float3 norm : TEXCOORD3;
float3 toLight0 : TEXCOORD4;
float3 toLight1 : TEXCOORD5;
float3 toLight2 : TEXCOORD6;
float3 toLight3 : TEXCOORD7;
};
uniform float3 viewOrigin : $viewOrigin;
uniform float4 lightOrigin0 : $lightOrigin_0;
uniform float4 lightOrigin1 : $lightOrigin_1;
uniform float4 lightOrigin2 : $lightOrigin_2;
uniform float4 lightOrigin3 : $lightOrigin_3;
uniform float4 lightFallOff0 : $lightFalloff_0;
uniform float4 lightFallOff1 : $lightFalloff_1;
uniform float4 lightFallOff2 : $lightFalloff_2;
uniform float4 lightFallOff3 : $lightFalloff_3;
uniform float4 lightColor0 : $lightColor_0;
uniform float4 lightColor1 : $lightColor_1;
uniform float4 lightColor2 : $lightColor_2;
uniform float4 lightColor3 : $lightColor_3;
#ifdef TRAIL
uniform float2 normalScroll : $parameters;
#endif
sampler2D diffuseMap : $diffuseMap;
sampler2D normalMap : $bumpMap;
samplerCUBE ambientMap : $ambientCubeMapSun;
float GetZ( float2 value, float sign ) {
return ( sqrt( 1.0f - ( dot( value.xy, value.xy ) ) ) * ( sign - 1.f ) );
}
#define TO_LIGHT( lightOrigin, lightFallOff, dest, atten ) \
toLight = lightOrigin.xyz - indata.center;\
temp = toLight * lightFallOff.xyz;\
atten = length( temp );\
toLight = normalize( toLight );\
dest.x = dot( tang, toLight );\
dest.y = dot( bino, toLight );\
dest.z = dot( normal, toLight )
$include "atmosphere.hg"
uniform float4 Matrix_x : $transposedModelMatrix_x;
uniform float4 Matrix_y : $transposedModelMatrix_y;
uniform float4 Matrix_z : $transposedModelMatrix_z;
uniform float4 diffuseMatrix_s : $diffuseMatrix_s;
uniform float4 diffuseMatrix_t : $diffuseMatrix_t;
VsOutputs vertex(VsInputs indata) {
VsOutputs outdata;
$if r_32ByteVtx
indata.tex.xy *= 1.f/4096.f;
#ifdef TRAIL
indata.center.xy *= 1.f / 32767.f;
indata.tang.xy *= 1.f / 32767.f;
indata.center.z = GetZ( indata.center.xy, indata.signs.x );
indata.tang.z = GetZ( indata.tang.xy, indata.signs.y );
indata.tang.w = ( indata.signs.z - 1.f );
#else
indata.center.z = indata.tang.x;
indata.tang = indata.signs;
#endif
$endif
outdata.tex.x = dot( indata.tex, diffuseMatrix_s );
outdata.tex.y = dot( indata.tex, diffuseMatrix_t );
outdata.col = indata.col;
//
// Atmosphere
//
#if 0
float2 r = float2(0.5, 1.0 );
#else
float2 r = Extinction(indata.center);
#endif
float4 tempc = float4( indata.col.rgb, r.x * indata.col.a );
outdata.col= tempc;
#ifdef TRAIL
float3 normal = indata.center;
float3 bino = indata.tang.xyz;
float3 tang = cross( bino, normal );
float3 toView = normalize( viewOrigin - indata.center );
outdata.col.a *= 1-pow( abs( dot( toView, tang ) ), 32 );
#else
// Calculate the tangent space for this billboard, this is a bit tricky as our billboards are all lying in planes paralel
// to the near plane, this makes for cheap billboard calculations on the CPU. But then they all lit identical because they
// all have identical tangent space, and it is also dependent on the view angles. So we want a view-vector billboard tangent
// space. We fake this by taking the view-vector and thus not the billboard-normal as the normal for our tangent space and
// rederive the other two vectors.
float3 normal = normalize( viewOrigin - indata.center );
float3 bino = cross( normal, indata.tang.xyz );
float3 tang = cross( normal, bino );
#endif
#if 1
// Tangent -> World (for the ambient cubemap lookup)
outdata.tang.x = dot( tang, Matrix_x.xyz );
outdata.tang.y = dot( bino, Matrix_x.xyz );
outdata.tang.z = dot( normal, Matrix_x.xyz );
outdata.bino.x = dot( tang, Matrix_y.xyz );
outdata.bino.y = dot( bino, Matrix_y.xyz );
outdata.bino.z = dot( normal, Matrix_y.xyz );
outdata.norm.x = dot( tang, Matrix_z.xyz );
outdata.norm.y = dot( bino, Matrix_z.xyz );
outdata.norm.z = dot( normal, Matrix_z.xyz );
#else
outdata.tang = tang;
outdata.bino = bino;
outdata.norm = normal;
#endif
// toLight in tangent space
float3 toLight;
float3 temp;
float len;
outdata.atten = 0;
#ifdef LIGHT_1
TO_LIGHT( lightOrigin0, lightFallOff0, outdata.toLight0, outdata.atten.r );
#endif
#ifdef LIGHT_2
TO_LIGHT( lightOrigin1, lightFallOff1, outdata.toLight1, outdata.atten.g );
#endif
#ifdef LIGHT_3
TO_LIGHT( lightOrigin2, lightFallOff2, outdata.toLight2, outdata.atten.b );
#endif
#ifdef LIGHT_4
TO_LIGHT( lightOrigin3, lightFallOff3, outdata.toLight3, outdata.atten.a );
#endif
#ifdef LIGHT_1
// Atten just contains the lengt of the scaled tolight vector now make it in the 0-1 range
outdata.atten = 1.0 - min( outdata.atten, 1.0 );
#endif
//outdata.atten.y = 1.0f;
return outdata;
}
float3 CalculateLight( float3 normal, float3 direction, float3 color, float3 falloff ) {
return max( dot( normal, direction), 0 ) * color * falloff;
}
float4 fragment(VsOutputs indata) : COLOR {
float4 diffuse = tex2D( diffuseMap, indata.tex );
if ( diffuse.a < 0.01 ) discard;
#ifdef TRAIL
float4 normalt = tex2D( normalMap, indata.tex - normalScroll ) * 2 - 1;
//float4 normalt = ( 0.5 * tex2D( normalMap, indata.tex ) + 0.5 * tex2D( normalMap, indata.tex - normalScroll ) ) * 2 - 1;
#else
float4 normalt = tex2D( normalMap, indata.tex ) * 2 - 1;
#endif
$if !r_dxnNormalMaps
normalt.x = normalt.a;
$endif
normalt.z = sqrt( 1.f - dot( normalt.xy, normalt.xy ) );
float3 normal = normalt.rgb;
diffuse *= indata.col;
float3 wNormal;
wNormal.x = dot( indata.tang, normal );
wNormal.y = dot( indata.bino, normal );
wNormal.z = dot( indata.norm, normal );
float3 light = texCUBE( ambientMap, wNormal ).rgb * 4;
#ifdef LIGHT_1
light += CalculateLight( normal, normalize( indata.toLight0 ), lightColor0.rgb, indata.atten.x );
#endif
#ifdef LIGHT_2
light += CalculateLight( normal, normalize( indata.toLight1 ), lightColor1.rgb, indata.atten.y );
#endif
#ifdef LIGHT_3
light += CalculateLight( normal, normalize( indata.toLight2 ), lightColor2.rgb, indata.atten.z );
#endif
#ifdef LIGHT_4
light += CalculateLight( normal, normalize( indata.toLight3 ), lightColor3.rgb, indata.atten.w );
#endif
return float4( light * diffuse.rgb, diffuse.a );
//return float4( diffuse.rgb, diffuse.a );
}