This is a sub-page of Ghostbusters: Sanctum of Slime.
The following source code was found embedded inside the main Sanctum of Slime executable, from 0x4CD0B0 to 0x4F6365, in the PC (Steam) version of the game. This source code is not in the PS3 or Xbox 360 versions.
|
|
This needs some investigation. |
// Translate composite pixel options
//////////////////////////////////////
// MATRIX MULTIPLICATION
//////////////////////////////////////
float3 Transform(float3x3 mat, float3 v)
{
#if defined(_XENON)
[isolate]
{
return mul(mat, v);
}
#elif defined(_GCM)
return mul(v, mat);
#else
return mul(mat, v);
#endif
}
float4 Transform(float4x4 mat, float4 v)
{
#if defined(_XENON)
[isolate]
{
return mul(mat, v);
}
#elif defined(_GCM)
return mul(v, mat);
#else
return mul(mat, v);
#endif
}
float2 Transform(float2x2 mat, float2 v)
{
#if defined(_XENON)
[isolate]
{
return mul(mat, v);
}
#elif defined(_GCM)
return mul(v, mat);
#else
return mul(mat, v);
#endif
}
//this conversion will not deal with renormalizations because is a bad way to handle bad data passing to the shader.
//the main problem is that cg-compiler isn't as smart as hlsl-compiler dealing with already normalized vectors
float3x3 GetWorldToTangentMatrix(float3x3 worldmtx,float3 tangent, float3 normal)
{
float3x3 worldToTangent = 0;
worldToTangent[0] = normalize(Transform(worldmtx, tangent));
worldToTangent[2] = normalize(Transform(worldmtx, normal));
worldToTangent[1] = normalize(cross(worldToTangent[0], worldToTangent[2]));
return worldToTangent;
}
float4 TransformPlanarReflection(float4 inPos)
{
float4x4 matTexScale = 0;
#if !defined(_GCM)
matTexScale._m00 = 0.5f;
matTexScale._m11 = -.5f;
matTexScale._m22 = 0.0f;
matTexScale._m03 = 0.5f;
matTexScale._m13 = 0.5f;
matTexScale._m23 = 1.0f;
matTexScale._m33 = 1.0f;
#else
matTexScale._m00 = 0.5f;
matTexScale._m11 = -0.5f;
matTexScale._m22 = 0.0f;
matTexScale._m30 = 0.5f;
matTexScale._m31 = 0.5f;
matTexScale._m32 = 1.0f;
matTexScale._m33 = 1.0f;
#endif
return Transform(matTexScale,inPos);
}
#define _COMPOSITE_CGFX
// In the case low, med or high shadows are used, we are using shadows!
#if defined (_SHADOW_LOW) || defined (_SHADOW_MED) || defined(_SHADOW_HI)
#define __USE_SHADOWMAP
#endif
#ifndef _POINTSPRITE
#ifdef _PIXELOPTION0
#define _COMPOSITE_LIGHTED
#endif
#ifdef _PIXELOPTION1
#define _COMPOSITE_2LAYERS
#endif
#ifdef _PIXELOPTION2
#define _COMPOSITE_L0_ADD
#endif
#ifdef _PIXELOPTION3
#define _COMPOSITE_L0_MULTIPLY
#endif
// For comodity we define _COMPOSITE_2LAYERS if there is a layer1 operation
#if defined(_COMPOSITE_L1_ADD) || defined(_COMPOSITE_L1_MULTIPLY) || defined(_COMPOSITE_L1_MULTIPLY2X) || defined(_COMPOSITE_L1_REPLACE) || defined(_UV1_USESCHANNEL0) || defined(_UV1_USESCHANNEL1)
#define _COMPOSITE_2LAYERS
#endif
//////////////////////////////////////
// SKINNING
//////////////////////////////////////
#if defined(_VERTEX_SHADER) && defined(_USE_SKINMATRIX)
uniform float4x4 g_skinMatrix[_MAXBONES]; ///< 128 Registers for skin bones
struct SKINVERTEX
{
float4 P;
float3 N;
float3 T;
};
SKINVERTEX SkinVertex(float3 p, float3 n, float3 t, float4 indices, float4 weights)
{
SKINVERTEX Out = (SKINVERTEX) 0;
for(int i = 0; i < 4; i++)
{
Out.P.xyz += Transform(g_skinMatrix[indices.x], float4(p,1)).xyz * weights.x;
Out.N += (float3)(Transform((float3x3) g_skinMatrix[indices.x], n) * weights.x);
#if !defined(SH_VERSION_SH1)
Out.T += (float3)(Transform((float3x3) g_skinMatrix[indices.x], t) * weights.x);
#endif
indices.xyzw = indices.yzwx;
weights.xyzw = weights.yzwx;
}
Out.P.w = 1;
Out.N = (float3)normalize(Out.N);
#if !defined(SH_VERSION_SH1)
Out.T = (float3)normalize(Out.T);
#endif
return Out;
}
#endif
//////////////////////////////////////
// END SKINNING
//////////////////////////////////////
float GetRimFading(float3 CamPos,float3 FragmentWorldPos,float3 Normal,float InvThreshold)
{
float3 nCminP = normalize(CamPos.xyz-FragmentWorldPos.xyz);
float NdotCmP = dot(Normal,nCminP);
return saturate(NdotCmP*InvThreshold);
}
void ComputeFog(inout float4 PixelColor,float3 FogColor,float DistancePixelToCamera,float MinDistanceToFog,float MaxMinusMinDistanceToFog)
{
#if defined(_PIXEL_FOG)
float CamMinusFogMin = (DistancePixelToCamera-MinDistanceToFog);
float FogFactor = 1-saturate(CamMinusFogMin/MaxMinusMinDistanceToFog);
#if !defined(_ADDITIVE_PIXEL_FOG)
PixelColor.rgb = lerp(FogColor, PixelColor.rgb, FogFactor);
#elif defined(_ADDITIVE_PIXEL_FOG)
PixelColor.rgb*=FogFactor;
clip(MaxMinusMinDistanceToFog-CamMinusFogMin);
#endif
#endif
}
//////////////////////////////////////
// UV GENERATION
//////////////////////////////////////
#ifdef _VERTEX_SHADER
#if defined(_UV0_AUTO_SPHEREVIEW) || defined(_UV1_AUTO_SPHEREVIEW)
float3x3 g_matView;
#endif
float3 GetUVCoordinate3L0(float3 position, float3 normal, float3 viewer)
{
#ifdef _UV0_AUTO_POSITION
return position;
#elif defined(_UV0_AUTO_REFLECTION)
return (2.f * dot(viewer,normal) * normal - viewer) * .5f + .5f;
#elif defined(_UV0_AUTO_NORMAL)
return normal;
#elif defined(_UV0_AUTO_SPHERE)
return normal * .5f + .5f;
#elif defined(_UV0_AUTO_SPHEREVIEW)
float3 normalViewSpace = Transform(g_matView, normal);
return float3(normalViewSpace.x, -normalViewSpace.y, 1.0f) * .5f + .5f;
#else
return normal;
#endif
}
float3 GetUVCoordinate3L1(float3 position, float3 normal, float3 viewer)
{
#ifdef _UV1_AUTO_POSITION
return position;
#elif defined(_UV1_AUTO_REFLECTION)
return (2.f * dot(viewer,normal) * normal - viewer) * .5f + .5f;
#elif defined(_UV1_AUTO_NORMAL)
return normal;
#elif defined(_UV1_AUTO_SPHERE)
return normal * .5f + .5f;
#elif defined(_UV1_AUTO_SPHEREVIEW)
float3 normalViewSpace = Transform(g_matView, normal);
return float3(normalViewSpace.x, -normalViewSpace.y, 1.0f) * .5f + .5f;
#else
return normal;
#endif
}
#endif
//////////////////////////////////////
// END UV GENERATION
//////////////////////////////////////
//////////////////////////////////////
// VERTEX SHADER INPUT
//////////////////////////////////////
#ifdef _VERTEX_SHADER
struct Composite_InputVS
{
float3 pos : POSITION; ///< Vertex position
#ifdef _USE_SKINMATRIX
float4 weight : BLENDWEIGHT; ///< Weight vector used for skinning ( how much each bone affects the vertex )
float4 indices : BLENDINDICES; ///< Index vector used for skinning ( the index of each bone )
#endif
#ifdef _HAS_NORMAL
float3 normal : NORMAL; ///< Vertex Normal
#endif
#ifdef _HAS_TANGENT3
float3 tangent : TANGENT; ///< Vertex tangent, for use to map to tangent space normal maps
#endif
#ifdef _HAS_TANGENT
float4 tangent : TANGENT; ///< Vertex tangent, for use to map to tangent space normal maps
#endif
#ifdef _HAS_COLOR
float4 color : COLOR0; ///< Diffuse color of the vertex
#endif
#ifdef _HAS_UV0
float2 uv0 : TEXCOORD0; ///< UV Coordinates for layer 0
#endif
#ifdef _HAS_UV1
float2 uv1 : TEXCOORD1; ///< UV Coordinates for layer 1
#endif
#ifdef _HAS_UV2
float2 uv2 : TEXCOORD2;
#endif
};
#endif
//////////////////////////////////////
// END VERTEX SHADER INPUT
//////////////////////////////////////
//////////////////////////////////////
// LIGHTING
//////////////////////////////////////
//////////////////////////////////////
// LIGHTING INFO
#ifdef _COMPOSITE_LIGHTED
float4 g_lightDirection0;
float4 g_lightPosition0;
float4 g_lightColor0;
float4 g_lightSpecular0;
#if defined(_LIGHT1_POINT) || defined(_LIGHT1_DIRECTIONAL)
float4 g_lightDirection1;
float4 g_lightPosition1;
float4 g_lightColor1;
float4 g_lightSpecular1;
#endif
#endif //_COMPOSITE_LIGHTED
uniform float4 g_cameraPos, g_compositePixelOptions;
uniform float4 g_RimFading;
/// Tongas upload variables
float4 g_ambient;
float4 g_ambientColor;
float4 g_diffuseColor;
float4 g_emissiveColor;
float4 g_specularColor;
#define g_bloomFactor g_emissiveColor.a
///////////////////////////////////////
// FX INFO
uniform float4 g_zBlurOptions;
//////////////////////////////////////
// LIGHTING FUNCTIONS
/*
CalculateSpecularLighting
Calculates the specular lighting for an interest point
*/
float3 CalculateSpecularLighting(
in float3 lightDirection, ///< Direction of the light MUST BE NORMALIZED!
in float3 lightSpecularColor, ///< Specular color
in float3 normalVector, ///< Normal vector of the intereset point
in float3 viewVector ///< View vector of the interest point
)
{
float3 Half = normalize( lightDirection + viewVector);
return lightSpecularColor.xyz * pow(saturate( dot( Half, normalVector) ), g_specularColor.a);
}
/*
CalculatePointLightAttenuation
Calculates the attenuation of a point light on a surface point
*/
float CalculatePointLightAttenuation(
in float3 iLightDirection, ///< Direction NOT NORMALIZED, from the point to the light position
float iLightInverseRange ///< Inverse range (1/r) of the point light
)
{
float3 attenuatedLightDirection = iLightDirection * iLightInverseRange;
return saturate ( 1.0f - dot (attenuatedLightDirection, attenuatedLightDirection));
}
void LightSpot_VS(float3 iDir, float invRange, out float3 oDir, out float oFactor)
{
oDir.xyz = iDir;
//oFactor = length(iDir);
//oFactor = ( 1.0f - (oFactor / Range) );
oFactor = saturate ( 1.0f - dot (iDir * invRange, iDir * invRange));
}
void LightSpot_PS(float3 iDir, float3 normal, float3 view, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS, sampler2D spotMap, float4 spotTex)
{
float3 fvLightDir = iDir;
float fNDotL = dot(normal, fvLightDir);
float3 lightColor = tex2Dproj(spotMap, spotTex).rgb;
oD += lightColor * iD * saturate(fNDotL) * Factor;
#ifndef _MATERIAL_NOSPECULAR
float3 Half = normalize(fvLightDir+view);
oS += Factor * lightColor * iS.xyz * pow(saturate(dot(Half,normal)), iS.a);
#endif
}
/*
GetPointLightDirectionInTangentSpace
Retrieves the direction of a point light in tangent space
*/
float3 GetPointLightDirectionInTangentSpace(
float3 lightPosition, ///< Light position in world space
float3 vertexPosition, ///< Vertex position in world space
float3x3 worldToTangentTransform ///< World to Tangent space transformation
)
{
float3 lightDir = lightPosition - vertexPosition;
lightDir = mul(worldToTangentTransform, lightDir);
return lightDir;
}
/*
GetPointLightDirectionInWorldSpace
Calculates the point light direction in world space
*/
float3 GetPointLightDirectionInWorldSpace(
float3 lightPosition, ///< Light position in world space
float3 vertexPosition //< Vertex position in world space
)
{
return lightPosition - vertexPosition;
}
void OutLightDirSpotPPL(float3 iDir, float invRange, float3x3 TBN, out float3 oDir, out float oFactor)
{
oDir.xyz = iDir;
//oFactor = length(iDir.xyz);
//oFactor = ( 1.0f - (oFactor * invRange) );
oDir.xyz = mul(TBN, oDir.xyz);
oFactor = saturate ( 1.0f - dot (iDir * invRange, iDir * invRange));
}
void OutLightDirSpotPVL(float3 iDir, float invRange, out float3 oDir, out float oFactor)
{
oDir.xyz = iDir;
//oFactor = length(iDir.xyz);
//oFactor = ( 1.0f - (oFactor / Range) );
oFactor = saturate ( 1.0f - dot (iDir * invRange, iDir * invRange));
}
void LightDirectional_PPL_PS(float3 iDir, float3 n, float3 v, float3 iD, float3 iS, inout float3 oD, inout float3 oS)
{
float3 fvLightDir = normalize(iDir);
float fNDotL = dot(n, fvLightDir);
oD += iD * saturate(fNDotL);
#ifndef _MATERIAL_NOSPECULAR
float3 Half = normalize(fvLightDir + v);
oS.xyz += iS.xyz * pow(saturate(dot(Half, n)), g_specularColor.a);
#endif
}
/*
AddPointLightContributionTangentSpace
Adds the contribution diffuse and specular lighting of a point light to a point of a surface
*/
void AddPointLightContributionTangentSpace(
in float3 iLightDirectionTangentSpace, ///< Direction to the light from the 3d point in tangent space
in float3 iLightPositionWorldSpace, ///< Position of the point light in world space
in float iLightInverseRange, ///< Inverse range of the point light (1/r)
in float3 iLightDiffuseColor, ///< Diffuse color of the light
in float3 iLightSpecularColor, ///< Specular color of the light
in float3 iPointNormalTangentSpace, ///< Normal on the 3d point in tangent space
in float3 iPointViewTangentSpace, ///< View vector on the 3d point in tangent space
in float3 iPointPositionWorldSpace, ///< Position of the 3d point in world space
inout float3 ioAcumulatedDiffuseLight, ///< Acumulated diffuse light
inout float3 ioAcumulatedSpecularLight ///< Acumulated specular light
)
{
// Calculate attenuation of the spot light
float lightAttenuation = CalculatePointLightAttenuation(iLightPositionWorldSpace - iPointPositionWorldSpace, iLightInverseRange );
// Calculate diffuse lighting contribution
float3 lightDirectionNormalized = normalize( iLightDirectionTangentSpace );
float fNDotL = dot(iPointNormalTangentSpace, lightDirectionNormalized);
ioAcumulatedDiffuseLight += iLightDiffuseColor * saturate(fNDotL) * lightAttenuation;
// Calculate specular lighting contribution
#ifndef _MATERIAL_NOSPECULAR
ioAcumulatedSpecularLight += lightAttenuation *
CalculateSpecularLighting(lightDirectionNormalized, iLightSpecularColor, iPointNormalTangentSpace, iPointViewTangentSpace );
#endif
}
void LightPoint_PPL_PS(float3 iDir, float3 n, float3 v, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS)
{
float3 fvLightDir = normalize(iDir);
float fNDotL = dot(n, fvLightDir);
oD += iD * saturate(fNDotL) * Factor;
#ifndef _MATERIAL_NOSPECULAR
float3 Half = normalize(fvLightDir+v);
oS.rgb += Factor * iS.xyz * pow(saturate( dot(Half,n) ), g_specularColor.a);
#endif
}
void LightSpot_PPL_PS(float3 iDir, float3 normal, float3 view, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS, sampler2D spotMap, float4 spotTex)
{
float3 fvLightDir = normalize(iDir);
float fNDotL = dot(normal, fvLightDir);
float3 lightColor = tex2Dproj(spotMap, spotTex).rgb;
oD += saturate( lightColor * iD * saturate(fNDotL) * Factor );
#ifndef _MATERIAL_NOSPECULAR
float3 Half = normalize(fvLightDir+view);
oS += saturate( lightColor * Factor * iS.xyz * pow(saturate(dot(Half,normal)), g_specularColor.a) );
#endif
}
void LightDirectional_PVL_PS(float3 iDir, float3 normal, float3 view, float3 iD, float transColor, float3 iS, inout float3 oD, inout float3 oS)
{
float fNDotL = dot(normal, iDir);
oD += iD.rgb * saturate(fNDotL);
#ifdef _TRANSLUCENCY
float fNDotL2 = dot(-normal, iDir);
oD += iD.rgb * saturate(fNDotL2) * transColor;
#endif
#ifndef _MATERIAL_NOSPECULAR
float3 Half = normalize(iDir + view);
oS += iS.xyz * pow( saturate(dot(Half,normal)), g_specularColor.a);
#endif
}
/*
AddPointLightContributionWorldSpace
Adds the contribution diffuse and specular lighting of a point light to a point of a surface
*/
void AddPointLightContributionWorldSpace(
in float3 iLightPosition, ///< Light position in world space
in float iLightInverseRange, ///< Inverse range of the point light (1/r)
in float3 iLightDiffuseColor, ///< Diffuse color of the light
in float3 iLightSpecularColor, ///< Specular color of the light
in float3 iPointNormal, ///< Normal of the 3d point in world space
in float3 iPointView, ///< View vector of the 3d point in world space
in float3 iPointPosition, ///< Poisition of the 3d point in worls space
inout float3 ioAcumulatedDiffuseLight, ///< Acumulated diffuse lighting
inout float3 ioAcumulatedSpecularLight ///< Acumulated specular lighting
)
{
// Determiate the light direction, used for attenuation and light contribution
float3 lightDirection = iLightPosition - iPointPosition;
// Calculate attenuation of the spot light
float lightAttenuation = CalculatePointLightAttenuation(lightDirection, iLightInverseRange);
// Calculate diffuse lighting contribution
lightDirection = normalize( lightDirection );
float fNDotL = dot(iPointNormal, lightDirection);
ioAcumulatedDiffuseLight += iLightDiffuseColor * saturate(fNDotL) * lightAttenuation;
// Calculate specular lighting contribution
#ifndef _MATERIAL_NOSPECULAR
ioAcumulatedSpecularLight += lightAttenuation *
CalculateSpecularLighting(lightDirection, iLightSpecularColor, iPointNormal, iPointView);
#endif
}
void LightSpot_PVL_PS(float3 iDir, float3 normal, float3 view, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS, sampler2D spotMap, float4 spotTex)
{
float3 fvLightDir = iDir;
float fNDotL = dot(normal, fvLightDir);
float3 lightColor = tex2Dproj(spotMap, spotTex).rgb;
oD += lightColor * iD * saturate(fNDotL) * Factor;
#ifndef _MATERIAL_NOSPECULAR
float3 Half = normalize(fvLightDir+view);
oS += lightColor * Factor * iS.xyz * pow(saturate(dot(Half,normal)), g_specularColor.a);
#endif
}
//////////////////////////////////////
// END LIGHTING
//////////////////////////////////////
//////////////////////////////////////
// VERTEX SHADER OUTPUT
//////////////////////////////////////
struct Composite_OutputVS
{
float4 hpos : POSITION; ///< Clip space transformed vertex position
float4 color : COLOR0; ///< Vertex color
float3 uv0 : TEXCOORD0; ///< UV Coordinates used by layer 1
float3 uv1 : TEXCOORD1; ///< UV Coordinates used by layer 2
float4 vpos : TEXCOORD2; ///< Position of the vertex in world space, and shadowprojection distance
float4 lightfactors : COLOR1; ///< Light factos used for point lights
float3 normal : TEXCOORD3; ///< Vertex normal
float3 view : TEXCOORD4; ///< View direction to the vertex
float4 lightDir0 : TEXCOORD5; ///< Direction of light 0
#ifdef _LIGHT0_SPOT
float4 spotProjection1 : TEXCOORD6; ///< spot projection
#endif
#if defined(__USE_SHADOWMAP) && (defined(_LIGHT0_DIRECTIONAL) || defined(_LIGHT0_SPOT))
float4 shadowProjection : TEXCOORD7; ///< Shadow map projection
#endif
#ifdef _PS3_VSCLIPPLANE0
float oClip0 : CLP0;
#endif
};
//////////////////////////////////////
// END VERTEX SHADER OUTPUT
//////////////////////////////////////
//////////////////////////////////////
// SHADOWMAPPING
//////////////////////////////////////
#ifndef _COMPOSITE_LIGHTED
#undef __USE_SHADOWMAP
#endif
#ifdef __USE_SHADOWMAP
uniform float4x4 g_matTextureProjection;
uniform float4 g_shadowmapOptions;
uniform float4 g_texelSize89;
#define g_ShadowmapFactor (1-g_shadowmapOptions.x) /// default 0.0
#define g_ShadowmapZBias (g_shadowmapOptions.y) /// default -0.001
uniform sampler2D g_shadowMap : register(s9);
uniform samplerCUBE g_shadowCubeMap : register(s9);
////////////////////////////////////
// DIRECTIONAL
float SampleShadowTest(float4 ShadowTexC)
{
#if defined(_XENON) || defined(_SHADOWMAP_FLOAT) //Xenon & ATI
return tex2D(g_shadowMap, ShadowTexC.xy).r >= ShadowTexC.z;
#else //nVidia
return tex2Dproj(g_shadowMap, ShadowTexC).r;
#endif
}
float GetShadowDirectional(float4 TexCoords)
{
float4 ShadowTexC = TexCoords;
ShadowTexC.xy = 0.5 * TexCoords.xy + float2( 0.5, 0.5 );
ShadowTexC.y = 1.f - ShadowTexC.y;
#ifdef _PS3
ShadowTexC.z = ShadowTexC.z * .5f + .5f;
#endif
#ifdef _XENON
ShadowTexC.xyz = ShadowTexC.xyz / ShadowTexC.w;
// [BP] On xbox360 we are getting projected distances that are higher than 1
// as they are not being cut by the far plane of the light frustum
// still we need to study more this effect, even check if it can be done on vertex
// shader stage to save gpu process
ShadowTexC.z = min(1,ShadowTexC.z); // Check that z the minimum value to 1
#endif
#ifdef _DEBUG_SHADOWMAPS
//Dark regions out of shadow projection
if(ShadowTexC.x < 0 ||
ShadowTexC.y < 0 ||
ShadowTexC.x > 1 ||
ShadowTexC.y > 1)
return 0;
#endif
ShadowTexC.z += g_ShadowmapZBias;
ShadowTexC.w = 1;
#if defined(SH_VERSION_SH2) || defined(_SHADOW_LOW)
return saturate(SampleShadowTest(ShadowTexC) + g_ShadowmapFactor);
#else
float4 tX = float4(g_texelSize89.z, 0, 0, 0) * 2;
float4 tY = float4(0, g_texelSize89.w, 0, 0) * 2;
float accum = 0;
#if defined(_SHADOW_MED)
accum += SampleShadowTest(ShadowTexC + tX * -.5 + tY * -.5);
accum += SampleShadowTest(ShadowTexC + tX * .5 + tY * -.5);
accum += SampleShadowTest(ShadowTexC + tX * -.5 + tY * .5);
accum += SampleShadowTest(ShadowTexC + tX * .5 + tY * .5);
return saturate((accum/4.f) + g_ShadowmapFactor);
#elif defined(_SHADOW_HI)
accum += SampleShadowTest(ShadowTexC + tX * -1 + tY * -1);
accum += SampleShadowTest(ShadowTexC + tX * 0 + tY * -1);
accum += SampleShadowTest(ShadowTexC + tX * 1 + tY * -1);
accum += SampleShadowTest(ShadowTexC + tX * -1 + tY * 0);
accum += SampleShadowTest(ShadowTexC + tX * 0 + tY * 0);
accum += SampleShadowTest(ShadowTexC + tX * 1 + tY * 0);
accum += SampleShadowTest(ShadowTexC + tX * -1 + tY * 1);
accum += SampleShadowTest(ShadowTexC + tX * 0 + tY * 1);
accum += SampleShadowTest(ShadowTexC + tX * 1 + tY * 1);
return saturate((accum/9.f) + g_ShadowmapFactor);
#else
return 1;
#endif
#endif
}
/////////////////////////////////
// SPOT
//[VC]: why this is just a copy paste from spotdirectional???
float GetShadowSpotSample(float4 ShadowTexC)
{
float shadow;
#if defined(_XENON) || defined(_SHADOWMAP_FLOAT) //Xenon & ATI
float a = tex2D(g_shadowMap, ShadowTexC.xy).r > ShadowTexC.z;
float b = tex2D(g_shadowMap, ShadowTexC.xy + float2(g_texelSize89.z, 0)).r > ShadowTexC.z;
float c = tex2D(g_shadowMap, ShadowTexC.xy + float2(0, g_texelSize89.w)).r > ShadowTexC.z;
float d = tex2D(g_shadowMap, ShadowTexC.xy + float2(g_texelSize89.z, g_texelSize89.w)).r > ShadowTexC.z;
#if defined(SH_VERSION_SH2)
return a;
#endif
// transform to texel space
float2 texelpos = (1.f/g_texelSize89.zw) * ShadowTexC;
// Determine the lerp amounts
float2 lerps = frac( texelpos );
// lerp between the shadow values to calculate our light amount
shadow = lerp( lerp( a, b, lerps.x ),
lerp( c, d, lerps.x ),
lerps.y );
return shadow;
#else //nVidia
shadow = tex2Dproj(g_shadowMap, ShadowTexC).r;
#endif
return shadow;
}
float GetShadowSpot(float4 TexCoords)
{
float4 ShadowTexC = TexCoords;
ShadowTexC.xy = 0.5 * TexCoords.xy / TexCoords.w + float2( 0.5, 0.5 );
ShadowTexC.y = 1.0f - ShadowTexC.y;
//not needed for spot lights
#ifdef _PS3
//ShadowTexC.z = ShadowTexC.z * .5f + .5f;
#endif
#ifdef _DEBUG_SHADOWMAPS
//Dark regions out of shadow projection
if(ShadowTexC.x < 0 ||
ShadowTexC.y < 0 ||
ShadowTexC.x > 1 ||
ShadowTexC.y > 1)
return 0;
#endif
ShadowTexC.z += g_ShadowmapZBias;
ShadowTexC.z /= ShadowTexC.w;
ShadowTexC.w = 1;
#if defined(SH_VERSION_SH2) || defined(_SHADOW_LOW)
return saturate(GetShadowSpotSample(ShadowTexC) + g_ShadowmapFactor);
#endif
float4 tX = float4(g_texelSize89.z, 0, 0, 0) * 1;
float4 tY = float4(0, g_texelSize89.w, 0, 0) * 1;
float accum = 0;
#if defined(_SHADOW_MED)
accum += GetShadowSpotSample(ShadowTexC + tX * -.5 + tY * -.5);
accum += GetShadowSpotSample(ShadowTexC + tX * .5 + tY * -.5);
accum += GetShadowSpotSample(ShadowTexC + tX * -.5 + tY * .5);
accum += GetShadowSpotSample(ShadowTexC + tX * .5 + tY * .5);
return saturate((accum/4.f) + g_ShadowmapFactor);
#endif
#if defined(_SHADOW_HI)
accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY * -1);
accum += GetShadowSpotSample(ShadowTexC + tX * 0 + tY * -1);
accum += GetShadowSpotSample(ShadowTexC + tX * 1 + tY * -1);
accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY * 0);
accum += GetShadowSpotSample(ShadowTexC + tX * 0 + tY * 0);
accum += GetShadowSpotSample(ShadowTexC + tX * 1 + tY * 0);
accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY * 1);
accum += GetShadowSpotSample(ShadowTexC + tX * 0 + tY * 1);
accum += GetShadowSpotSample(ShadowTexC + tX * 1 + tY * 1);
return saturate((accum/9.f) + g_ShadowmapFactor);
#endif
return 1;
}
/////////////////////////////////
// POINT
float GetShadowPointSample(float3 Pos)
{
float shadow = 1;
#ifdef _LIGHT0_POINT
shadow = texCUBE(g_shadowCubeMap, Pos.xyz-g_lightPosition0.xyz).r > (length(Pos.xyz-g_lightPosition0.xyz) * g_lightPosition0.w) + g_ShadowmapZBias;
#endif
return shadow;
}
float GetShadowPoint(float3 Pos)
{
return saturate(GetShadowPointSample(Pos) + g_ShadowmapFactor);
}
#endif
//////////////////////////////////////
// END SHADOWMAPPING
//////////////////////////////////////
//////////////////////////////////////
//VERTEX SHADER
//////////////////////////////////////
//////////////////////////////////////
// VERTEX SHADER CONSTANTS
#ifdef _VERTEX_SHADER
float4x4 g_matWorld, g_matWorldView, g_matWorldViewProjection;
float4 g_textureTransform0;
float4 g_textureTransform1;
float4 g_textureTransformExt0;
float4 g_textureTransformExt1;
#ifdef _LIGHT0_SPOT
float4x4 g_matTexture2;
#endif
#ifdef _PS3_VSCLIPPLANE0
uniform float4 g_ps3ClipPlane0;
#endif
#endif
//////////////////////////////////////
// VERTEX SHADER
#ifdef _VERTEX_SHADER
void main_VS( Composite_InputVS inVertex, out Composite_OutputVS outResult )
{
outResult = (Composite_OutputVS) 0;
// Init Color
#ifdef _HAS_COLOR
outResult.color = inVertex.color;
#else
outResult.color = float4(1,1,1,1);
#endif
// Init normal
#if defined(_COMPOSITE_LIGHTED) && defined(_HAS_NORMAL)
float3 normal = normalize(inVertex.normal);
#else
float3 normal = float3(0,0,1);
#endif
float4 position;
#ifdef _USE_SKINMATRIX
SKINVERTEX v = SkinVertex(float4(inVertex.pos, 1), normal,float3(1,0,0), inVertex.indices, inVertex.weight);
position = v.P;
normal = v.N;
#else
position = float4(inVertex.pos, 1);
#endif //_USE_SKINMATRIX
/// Transform the position to clip space
outResult.hpos = Transform(g_matWorldViewProjection, position);
outResult.vpos = Transform(g_matWorld, position);
#ifdef _PS3_VSCLIPPLANE0
outResult.oClip0 = dot(outResult.vpos, g_ps3ClipPlane0);
#endif
#ifdef _COMPOSITE_LIGHTED
outResult.normal = Transform((float3x3) g_matWorld, normal); ///< Normal in world space
#endif
#ifdef _HAS_UV0
outResult.uv0 = float3(inVertex.uv0, 1);
outResult.uv1 = float3(inVertex.uv0, 1);
#endif
/// Create parameters for autogenerated coordinates
#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW) || defined(_UV1_AUTO_POSITION) || defined(_UV1_AUTO_NORMAL) || defined(_UV1_AUTO_REFLECTION) || defined(_UV1_AUTO_SPHERE) || defined(_UV1_AUTO_SPHEREVIEW)
float3 P = Transform(g_matWorldView, position); ///< Vertex position in view space
float3 N = Transform((float3x3) g_matWorld, normal); ///< Normal in world space
float3 V = normalize(g_cameraPos-P); ///< Viewer position
#endif
/// Calculate the uv transformations for the diffuse layer
#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW)
outResult.uv0 = GetUVCoordinate3L0(P, N, V);
#endif
/// Calculate the uv transformation for the enviromental layer
#if defined(_UV1_AUTO_POSITION) || defined(_UV1_AUTO_NORMAL) || defined(_UV1_AUTO_REFLECTION) || defined(_UV1_AUTO_SPHERE) || defined(_UV1_AUTO_SPHEREVIEW)
outResult.uv1 = GetUVCoordinate3L1(P, N, V);
#elif defined(_HAS_UV1)
#if !defined(_UV1_USESCHANNEL0) && defined(_COMPOSITE_2LAYERS)
outResult.uv1.xy = inVertex.uv1;
#endif
#endif
/// Finally transform the uv coordinates by the texture matrix transformations
outResult.uv0.xy = outResult.uv0.xy * g_textureTransform0.xy + outResult.uv0.yx * g_textureTransformExt0.yx + g_textureTransform0.zw;
outResult.uv1.xy = outResult.uv1.xy * g_textureTransform1.xy + outResult.uv1.yx * g_textureTransformExt1.yx + g_textureTransform1.zw;
#ifdef _COMPOSITE_LIGHTED
/// The outResult.view vector is only used to calculate specular lighting, so if there is no specular dont calculate the view
#ifndef _MATERIAL_NOSPECULAR
float3 pWorld = Transform(g_matWorld, position); ///< Vertex position in world space
outResult.view = normalize(g_cameraPos - pWorld); ///< View direction
#endif
#ifdef _LIGHT0_DIRECTIONAL
#ifdef __USE_SHADOWMAP
outResult.shadowProjection = Transform(g_matTextureProjection, float4(position.xyz,1));
#endif
#endif
#ifdef _LIGHT0_POINT
outResult.lightfactors.x = length(g_lightPosition0.xyz - outResult.vpos);
outResult.lightfactors.x = saturate(1.0f - (outResult.lightfactors.x * g_lightPosition0.w));
#endif
#ifdef _LIGHT1_POINT
outResult.lightfactors.y = length(g_lightPosition1.xyz - outResult.vpos);
outResult.lightfactors.y = saturate(1.0f - (outResult.lightfactors.y * g_lightPosition1.w));
#endif
#ifdef _LIGHT0_SPOT
LightSpot_VS(g_lightPosition0.xyz - outResult.vpos.xyz, g_lightPosition0.w, outResult.lightDir0.xyz, outResult.lightDir0.w);
outResult.spotProjection1 = Transform(g_matTexture2, position);
#ifdef __USE_SHADOWMAP
outResult.shadowProjection = Transform(g_matTextureProjection, float4(position.xyz,1));
#endif
#endif
#endif //_COMPOSITE_LIGHTED
}
#endif
//////////////////////////////////////
// END VERTEX SHADER
//////////////////////////////////////
//////////////////////////////////////
//PIXEL SHADERS
//////////////////////////////////////
#ifdef _PIXEL_SHADER
//////////////////////////////////////
// SAMPLERS
uniform sampler2D g_layer0 : register(s0); ///< First texture layer
uniform sampler2D g_layer1 : register(s1); ///< Second texture layer
uniform sampler2D g_spot1Map: register(s8); ///< Spot light proyection texture
#if defined(_MRT3) && !defined(_MRT2)
#define _MRT2
#endif
#if defined(_MRT2) && !defined(_MRT1)
#define _MRT1
#endif
struct Composite_OutputPS
{
#if !defined(_MRT)
float4 color : COLOR0;
#else
#if defined(_MRT_RT_0_1)
float4 color : COLOR1;
#elif defined(_MRT_RT_0_2)
float4 color : COLOR2;
#elif defined(_MRT_RT_0_3)
float4 color : COLOR3;
#else
float4 color : COLOR0;
#endif
#if defined(_MRT1)
#if defined(_MRT_RT_1_0)
float4 color1 : COLOR0;
#elif defined(_MRT_RT_1_2)
float4 color1 : COLOR2;
#elif defined(_MRT_RT_1_3)
float4 color1 : COLOR3;
#else
float4 color1 : COLOR1;
#endif
#endif
#if defined(_MRT2)
#if defined(_MRT_RT_2_0)
float4 color2 : COLOR0;
#elif defined(_MRT_RT_2_1)
float4 color2 : COLOR1;
#elif defined(_MRT_RT_2_3)
float4 color2 : COLOR3;
#else
float4 color2 : COLOR2;
#endif
#endif
#if defined(_MRT3)
#if defined(_MRT_RT_3_0)
float4 color3 : COLOR0;
#elif defined(_MRT_RT_3_1)
float4 color3 : COLOR1;
#elif defined(_MRT_RT_3_2)
float4 color3 : COLOR2;
#else
float4 color3 : COLOR3;
#endif
#endif
#endif
};
//////////////////////////////////////
// FOG
#ifdef _VERTICAL_FOG
float4 g_verticalFogColor;
float4 g_verticalFogValues;
#endif
#ifdef _PIXEL_FOG
float4 g_pixelFogColor;
float4 g_pixelFogOptions;
#endif
#if defined(_ALPHA_TEST)
float4 g_PixelAlphaTesting;
#endif
#if defined(_MRT)
#define _MRT_DEFAULT_COLOR float4(0,0,0,0)
#define _MRT_BLACK_COLOR float4(0,0,0,1)
#ifndef _PIXEL_FOG
float4 g_pixelFogOptions;
#endif
uniform float4 g_multilayerTextureOptions;
float4 getBloomOutput(float2 uvCoords,uniform sampler2D tex)
{
float mulFactor = 0;
if(g_emissiveColor.a>0)
mulFactor = 1;
#if !defined(_POINTSPRITE)
float4 ret = float4(0,0,0,1);
ret.g = g_emissiveColor.a;
#else
float4 ret = float4(0,1,0,1);
#endif
// Determinate the alpha color from the diffuse stage
if (g_multilayerTextureOptions.x > 1)
{
/// Texture with additive blending
float4 color = tex2D( tex, uvCoords );
ret.a*= (color.r + color.g + color.b)*0.3333 * color.a;
}
else if (g_multilayerTextureOptions.x > 0)
{
// Texture with alpha
ret.a*= tex2D( tex, uvCoords ).a;
}
ret*=mulFactor;
return ret;
}
#if !defined(_POINTSPRITE)
float4 getFocusBloomOutput(float opacity,float3 pos,float2 uvCoords,uniform sampler2D tex)
{
float mulFactor = 0;
if(g_emissiveColor.a>0)
mulFactor = 1;
if(opacity>=1)
mulFactor = 1;
float4 ret = float4(0,0,0,opacity);
ret.g = g_emissiveColor.a*opacity;
// Determinate the alpha color from the diffuse stage
if (g_multilayerTextureOptions.x > 1)
{
/// Texture with additive blending
float4 color = tex2D( tex, uvCoords );
ret.a*= (color.r + color.g + color.b)*0.3333 * color.a;
}
else if (g_multilayerTextureOptions.x > 0)
{
// Texture with alpha
ret.a*= tex2D( tex, uvCoords ).a;
}
ret*=mulFactor;
return ret;
}
#endif
#if defined(_MULTILAYER_CGFX)
//default output
float4 pso_MRT_default_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_default_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_default_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_default_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_focusBloom_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
#if !defined(_POINTSPRITE)
return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
#else
return getBloomOutput(IN.uv.xy,g_diffuseMap);
#endif
}
float4 pso_MRT_focusBloom_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uvcoords.xy,g_diffuseMap);
}
float4 pso_MRT_focusBloom_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
}
float4 pso_MRT_focusBloom_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
}
#endif
//default output
#if defined(_COMPOSITE_CGFX)
#ifndef _POINTSPRITE
float4 pso_MRT_default_output(Composite_OutputVS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(Composite_OutputVS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(Composite_OutputVS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_focusBloom_output(Composite_OutputVS IN,float4 mainColor)
{
return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_layer0);
}
#else
float4 pso_MRT_default_output(CompositeSprite_InputPS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(CompositeSprite_InputPS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(CompositeSprite_InputPS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_focusBloom_output(CompositeSprite_InputPS IN,float4 mainColor)
{
return getBloomOutput(IN.uv.xy,g_layer0);
}
#endif
#endif
#if defined(_MRT3) && !defined(_MRT2)
#define _MRT2
#endif
#if defined(_MRT2) && !defined(_MRT1)
#define _MRT1
#endif
#if defined(_MRT1) && !defined(_MRT1_OUTMETHOD)
#define _MRT1_OUTMETHOD pso_MRT_default_output
#endif
#if defined(_MRT2) && !defined(_MRT2_OUTMETHOD)
#define _MRT2_OUTMETHOD pso_MRT_default_output
#endif
#if defined(_MRT3) && !defined(_MRT3_OUTMETHOD)
#define _MRT3_OUTMETHOD pso_MRT_default_output
#endif
#endif
void Composite_MainPS(Composite_OutputVS IN,out float4 OUT);
void main_PS( Composite_OutputVS inData, out Composite_OutputPS outResult )
{
float4 color;
Composite_MainPS(inData,color);
outResult.color = color;
#if defined(_MRT1)
outResult.color1 = _MRT1_OUTMETHOD(inData, outResult.color);
#endif
#if defined(_MRT2)
outResult.color2 = _MRT2_OUTMETHOD(inData, outResult.color);
#endif
#if defined(_MRT3)
outResult.color3 = _MRT3_OUTMETHOD(inData,outResult.color);
#endif
#if defined(_ALPHA_TEST)
clip(outResult.color.a-g_PixelAlphaTesting.x);
#endif
}
void Composite_MainPS( Composite_OutputVS inData, out float4 outResult)
{
outResult = inData.color;
outResult.a = 1;
#ifdef _COMPOSITE_LIGHTED
float3 normal = normalize(inData.normal);
/// Calculate lighting
float fNDotL = 0;
float3 myLight = 0;
float3 fvLightDir = 0;
float3 Half = 0;
float3 mySpecular = 0;
float3 view = normalize(inData.view);
/// Calculate directional lighting
#ifdef _LIGHT0_DIRECTIONAL
fNDotL = dot(normal, -g_lightDirection0);
myLight += g_lightColor0.rgb * saturate(max(0, fNDotL));
#ifndef _MATERIAL_NOSPECULAR
Half = normalize(-g_lightDirection0 + view);
mySpecular += g_lightSpecular0 * pow(max(0, dot(Half,normal)), g_specularColor.a);
#endif
#ifdef __USE_SHADOWMAP
float shadow = GetShadowDirectional(inData.shadowProjection);
myLight *= shadow;
#ifndef _MATERIAL_NOSPECULAR
mySpecular *= shadow;
#endif
#endif
#endif
#ifdef _LIGHT1_DIRECTIONAL
fNDotL = dot(normal, -g_lightDirection1);
myLight += g_lightColor1.rgb * saturate(max(0, fNDotL));
#ifndef _MATERIAL_NOSPECULAR
Half = normalize(-g_lightDirection1 + view);
mySpecular += g_lightSpecular1.rgb * pow(max(0, dot(Half,normal)) ,g_specularColor.a);
#endif
#endif
/// Calculate point lights
#ifdef _LIGHT0_POINT
fvLightDir = normalize(g_lightPosition0.xyz - inData.vpos);
fNDotL = dot(normal, fvLightDir);
myLight += g_lightColor0.rgb * saturate(max(0, fNDotL)) * inData.lightfactors.x;
#ifndef _MATERIAL_NOSPECULAR
Half = normalize(fvLightDir+view);
mySpecular += inData.lightfactors.x * g_lightSpecular0 * pow(max(0, dot(Half,normal)), g_specularColor.a);
#endif
#ifdef __USE_SHADOWMAP
float shadow = GetShadowPointSample(inData.vpos);
myLight *= shadow;
#ifndef _MATERIAL_NOSPECULAR
mySpecular *= shadow;
#endif
#endif
#endif
#ifdef _LIGHT1_POINT
fvLightDir = normalize(g_lightPosition1.xyz - inData.vpos);
fNDotL = dot(normal, fvLightDir);
myLight += g_lightColor1.rgb * saturate(max(0, fNDotL)) * inData.lightfactors.y;
#ifndef _MATERIAL_NOSPECULAR
Half = normalize(fvLightDir+view);
mySpecular += inData.lightfactors.y * g_lightSpecular1 * pow(max(0, dot(Half,normal)), g_specularColor.a);
#endif
#endif
#ifdef _LIGHT0_SPOT
fvLightDir = g_lightPosition0.xyz - inData.vpos;
if(dot(normalize(fvLightDir),-g_lightDirection0.xyz)>0)
LightSpot_PS(normalize(inData.lightDir0.xyz), inData.normal, inData.view, inData.lightDir0.w, g_lightColor0.xyz, float4(g_lightSpecular0.xyz,g_specularColor.w), myLight, mySpecular, g_spot1Map, inData.spotProjection1);
#ifdef __USE_SHADOWMAP
float shadow = GetShadowSpot(inData.shadowProjection);
myLight *= shadow;
#ifndef _MATERIAL_NOSPECULAR
mySpecular *= shadow;
#endif
#endif
#endif
float3 ambient = 0;
#ifndef _LIGHT0_SPOT
ambient = g_ambient.rgb * g_ambientColor.rgb;
#endif
outResult.rgb *= myLight * g_diffuseColor.rgb + ambient;
#else
// No Lighting
outResult.rgb *= g_diffuseColor.rgb;
#endif
{
float4 Layer0 = g_diffuseColor;
#ifdef _MAP_DIFFUSE
if (g_compositePixelOptions[2] == 0)
Layer0 = tex2D( g_layer0, inData.uv0.xy);
#endif
#ifdef _COMPOSITE_L0_ADD
outResult += Layer0;
#endif
#ifdef _COMPOSITE_L0_MULTIPLY
outResult *= Layer0;
#endif
#ifdef _COMPOSITE_L0_MULTIPLY2X
outResult *= 2.f * Layer0;
#endif
#ifdef _COMPOSITE_L0_REPLACE
outResult = Layer0;
#endif
}
#ifdef _COMPOSITE_2LAYERS
{
float4 Layer1 = g_diffuseColor;
if (g_compositePixelOptions[3] == 0)
Layer1 = tex2D( g_layer1, inData.uv1.xy);
#ifdef _COMPOSITE_L1_ADD
outResult.rgb += Layer1.rgb;
#endif
#ifdef _COMPOSITE_L1_MULTIPLY
outResult.rgb *= Layer1.rgb;
#endif
#ifdef _COMPOSITE_L1_MULTIPLY2X
outResult.rgb *= 2.0f * Layer1.rgb;
#endif
#ifdef _COMPOSITE_L1_REPLACE
outResult.rgb = Layer1.rgb;
#endif
}
#endif
#ifdef _COMPOSITE_LIGHTED
#ifndef _MATERIAL_NOSPECULAR
outResult.rgb += mySpecular * g_specularColor.rgb;
#endif
#endif
float fogValue;
#ifdef _VERTICAL_FOG
fogValue = saturate( (inData.vpos.y - g_verticalFogValues.x) / g_verticalFogValues.z);
outResult.rgb = lerp(g_verticalFogColor.rgb, outResult.rgb, fogValue);
#endif
#ifdef _PIXEL_FOG
ComputeFog(outResult,g_pixelFogColor.rgb,distance(g_cameraPos.xyz, inData.vpos.xyz),g_pixelFogOptions.x,g_pixelFogOptions.z);
#endif
/// Apply alpha from the material diffuse color
float alphaValue = inData.color.a * g_diffuseColor.a;
#ifdef _PIXELOPTION4
float invAlphaValue = 1 - alphaValue;
if (outResult.a < invAlphaValue)
{
outResult.a = 0;
}
else if (outResult.a < invAlphaValue + 0.1)
{
//outResult.rgb = 1;
float factor = outResult.a -invAlphaValue;
factor *= 10;
outResult.a *=factor;
//outResult.a -= invAlphaValue;
//outResult.a /= 0.1;
//outResult.rgb = outResult.a;
//outResult.a = 1;
}
#else
outResult.a *= alphaValue;
#endif
outResult = saturate(outResult);
#if defined(_RIM_FADING)
outResult.a*=GetRimFading(g_cameraPos.xyz,inData.vpos.xyz,inData.normal,g_RimFading.y);
#endif
}
#endif
#else //POINTSPRITES
//PointSprites code
struct CompositeSprite_InputVS
{
float4 pos : POSITION;
float4 color : COLOR0;
float2 size : TEXCOORD0;
};
struct CompositeSprite_OutputVS
{
float4 hpos : POSITION;
float4 color : COLOR0;
float pointSize : PSIZE;
};
struct CompositeSprite_InputPS
{
float4 color : COLOR0;
#ifdef _XENON
float2 t : SPRITETEXCOORD;
#else
float4 t : TEXCOORD0;
#endif
};
#if defined(_MRT3) && !defined(_MRT2)
#define _MRT2
#endif
#if defined(_MRT2) && !defined(_MRT1)
#define _MRT1
#endif
struct Composite_OutputPS
{
#if !defined(_MRT)
float4 color : COLOR0;
#else
#if defined(_MRT_RT_0_1)
float4 color : COLOR1;
#elif defined(_MRT_RT_0_2)
float4 color : COLOR2;
#elif defined(_MRT_RT_0_3)
float4 color : COLOR3;
#else
float4 color : COLOR0;
#endif
#if defined(_MRT1)
#if defined(_MRT_RT_1_0)
float4 color1 : COLOR0;
#elif defined(_MRT_RT_1_2)
float4 color1 : COLOR2;
#elif defined(_MRT_RT_1_3)
float4 color1 : COLOR3;
#else
float4 color1 : COLOR1;
#endif
#endif
#if defined(_MRT2)
#if defined(_MRT_RT_2_0)
float4 color2 : COLOR0;
#elif defined(_MRT_RT_2_1)
float4 color2 : COLOR1;
#elif defined(_MRT_RT_2_3)
float4 color2 : COLOR3;
#else
float4 color2 : COLOR2;
#endif
#endif
#if defined(_MRT3)
#if defined(_MRT_RT_3_0)
float4 color3 : COLOR0;
#elif defined(_MRT_RT_3_1)
float4 color3 : COLOR1;
#elif defined(_MRT_RT_3_2)
float4 color3 : COLOR2;
#else
float4 color3 : COLOR3;
#endif
#endif
#endif
};
sampler g_layer0:register(s0);
sampler g_layer1:register(s0);
float4 g_diffuseColor;
float4 g_ambientColor;
float4 g_emissiveColor;
float4 g_specularColor;
float4x4 g_matWorldViewProjection;
float4x4 g_matWorldView;
float4 g_cameraPos;
float4 g_screenSize;
#define g_bloomFactor g_emissiveColor.a
#if defined(_ALPHA_TEST)
float4 g_PixelAlphaTesting;
#endif
void main_VS( CompositeSprite_InputVS inVertex, out CompositeSprite_OutputVS outResult )
{
outResult.color = inVertex.color;
/// Transform position from object to projection
outResult.hpos = Transform( g_matWorldViewProjection, inVertex.pos);
float d = distance(inVertex.pos.xyz, g_cameraPos.xyz);
outResult.pointSize = inVertex.size.x / d;
outResult.pointSize *= g_screenSize.x;
}
#if defined(_MRT)
#define _MRT_DEFAULT_COLOR float4(0,0,0,0)
#define _MRT_BLACK_COLOR float4(0,0,0,1)
#ifndef _PIXEL_FOG
float4 g_pixelFogOptions;
#endif
uniform float4 g_multilayerTextureOptions;
float4 getBloomOutput(float2 uvCoords,uniform sampler2D tex)
{
float mulFactor = 0;
if(g_emissiveColor.a>0)
mulFactor = 1;
#if !defined(_POINTSPRITE)
float4 ret = float4(0,0,0,1);
ret.g = g_emissiveColor.a;
#else
float4 ret = float4(0,1,0,1);
#endif
// Determinate the alpha color from the diffuse stage
if (g_multilayerTextureOptions.x > 1)
{
/// Texture with additive blending
float4 color = tex2D( tex, uvCoords );
ret.a*= (color.r + color.g + color.b)*0.3333 * color.a;
}
else if (g_multilayerTextureOptions.x > 0)
{
// Texture with alpha
ret.a*= tex2D( tex, uvCoords ).a;
}
ret*=mulFactor;
return ret;
}
#if !defined(_POINTSPRITE)
float4 getFocusBloomOutput(float opacity,float3 pos,float2 uvCoords,uniform sampler2D tex)
{
float mulFactor = 0;
if(g_emissiveColor.a>0)
mulFactor = 1;
if(opacity>=1)
mulFactor = 1;
float4 ret = float4(0,0,0,opacity);
ret.g = g_emissiveColor.a*opacity;
// Determinate the alpha color from the diffuse stage
if (g_multilayerTextureOptions.x > 1)
{
/// Texture with additive blending
float4 color = tex2D( tex, uvCoords );
ret.a*= (color.r + color.g + color.b)*0.3333 * color.a;
}
else if (g_multilayerTextureOptions.x > 0)
{
// Texture with alpha
ret.a*= tex2D( tex, uvCoords ).a;
}
ret*=mulFactor;
return ret;
}
#endif
#if defined(_MULTILAYER_CGFX)
//default output
float4 pso_MRT_default_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_default_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_default_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_default_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_focusBloom_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
#if !defined(_POINTSPRITE)
return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
#else
return getBloomOutput(IN.uv.xy,g_diffuseMap);
#endif
}
float4 pso_MRT_focusBloom_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uvcoords.xy,g_diffuseMap);
}
float4 pso_MRT_focusBloom_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
}
float4 pso_MRT_focusBloom_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
}
#endif
//default output
#if defined(_COMPOSITE_CGFX)
#ifndef _POINTSPRITE
float4 pso_MRT_default_output(Composite_OutputVS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(Composite_OutputVS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(Composite_OutputVS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_focusBloom_output(Composite_OutputVS IN,float4 mainColor)
{
return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_layer0);
}
#else
float4 pso_MRT_default_output(CompositeSprite_InputPS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(CompositeSprite_InputPS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(CompositeSprite_InputPS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_focusBloom_output(CompositeSprite_InputPS IN,float4 mainColor)
{
return getBloomOutput(IN.uv.xy,g_layer0);
}
#endif
#endif
#if defined(_MRT3) && !defined(_MRT2)
#define _MRT2
#endif
#if defined(_MRT2) && !defined(_MRT1)
#define _MRT1
#endif
#if defined(_MRT1) && !defined(_MRT1_OUTMETHOD)
#define _MRT1_OUTMETHOD pso_MRT_default_output
#endif
#if defined(_MRT2) && !defined(_MRT2_OUTMETHOD)
#define _MRT2_OUTMETHOD pso_MRT_default_output
#endif
#if defined(_MRT3) && !defined(_MRT3_OUTMETHOD)
#define _MRT3_OUTMETHOD pso_MRT_default_output
#endif
#endif
void main_PS( CompositeSprite_InputPS inData, out Composite_OutputPS outResult )
{
outResult.color.rgb = inData.color.rgb * g_diffuseColor.rgb;
outResult.color.a = inData.color.a * g_diffuseColor.a;
float2 uv = inData.t;
float4 texColor = tex2D( g_layer0, uv);
#ifdef _PIXELOPTION2
outResult.color.rgb += texColor.rgb;
#endif
#ifdef _PIXELOPTION3
outResult.color *= texColor;
#endif
#ifdef _COMPOSITE_L0_MULTIPLY2X
outResult.color *= 2 * texColor;
#endif
#ifdef _COMPOSITE_L0_REPLACE
outResult.color = texColor;
#endif
/*
/// Apply emissive material color
/// Then saturate the color
OUT.color.rgb += g_emissiveColor.rgb;
OUT.color.rgb = saturate(OUT.color.rgb);
#if defined (_VERTICAL_FOG ) || defined (_PIXEL_FOG)
OUT.color.rgb = lerp(IN.fog, OUT.color.rgb, IN.fog.a);
#endif
*/
#if defined(_MRT1)
outResult.color1 = _MRT1_OUTMETHOD(inData,OUT.color);
#endif
#if defined(_MRT2)
outResult.color2 = _MRT2_OUTMETHOD(inData,OUT.color);
#endif
#if defined(_MRT3)
outResult.color3 = _MRT3_OUTMETHOD(inData,OUT.color);
#endif
#if defined(_ALPHA_TEST)
clip(g_PixelAlphaTesting.x - outResult.color.a);
#endif
}
#endif
// If the use os axis aligned box for a light has been defined, but not the type of light we asume that it corresponds to an ambient light
#define _MULTILAYER_CGFX
// In the case low, med or high shadows are used, we are using shadows!
#if defined (_SHADOW_LOW) || defined (_SHADOW_MED) || defined(_SHADOW_HI)
#define __USE_SHADOWMAP
#endif
#ifdef _PIXELOPTION3
#define BLEND_DIFFUSE2_WITH_LIGHTMAPALPHA
#endif
//////////////////////////////////////
// VERTEX SHADER CONSTANTS
#ifdef _VERTEX_SHADER
uniform float4x4 g_matWorld, g_matWorldView, g_matWorldViewProjection;
float4 g_textureTransform0;
float4 g_textureTransform1;
float4 g_textureTransformExt0;
float4 g_textureTransformExt1;
#ifdef _LIGHT0_SPOT
float4x4 g_matTexture2;
#endif
#ifdef _LIGHT1_SPOT
float4x4 g_matTexture3;
#endif
#if defined(_UV0_AUTO_SPHEREVIEW) || defined(_UV1_AUTO_SPHEREVIEW)
float3x3 g_matView;
#endif
#if defined(_USE_TAPER)
uniform float4x4 g_matViewProjection;
#endif
#elif defined(_MAP_EMISSIVE) || defined(_EMISSIVE_FLIPBOOK)
float4 g_textureTransform5;
#endif
uniform float4 g_cameraPos;
#ifdef _PS3_VSCLIPPLANE0
uniform float4 g_ps3ClipPlane0;
#endif
#ifdef _POINTSPRITE
float4 g_screenSize;
#endif
////////////////////////////////////////
// MATERIAL INFO
uniform float4 g_diffuseColor;
uniform float4 g_ambientColor;
uniform float4 g_emissiveColor;
uniform float4 g_specularColor;
uniform float4 g_enviromentColor;
#define g_bloomFactor g_emissiveColor.a
///////////////////////////////////////
// FX INFO
uniform float4 g_zBlurOptions;
//////////////////////////////////////
// LIGHTING
//////////////////////////////////////
//////////////////////////////////////
// LIGHTING INFO
float4 g_ambient;
#if defined(_LIGHT0_POINT) || defined(_LIGHT0_DIRECTIONAL) || defined(_LIGHT0_SPOT)
uniform float4 g_lightDirection0;
uniform float4 g_lightPosition0;
uniform float4 g_lightColor0;
uniform float4 g_lightSpecular0;
#endif
#if defined(_LIGHT1_POINT) || defined(_LIGHT1_DIRECTIONAL) || defined(_LIGHT1_SPOT)
uniform float4 g_lightDirection1;
uniform float4 g_lightPosition1;
uniform float4 g_lightColor1;
uniform float4 g_lightSpecular1;
#endif
#if defined(_LIGHT2_POINT) || defined(_LIGHT2_DIRECTIONAL)
uniform float4 g_lightDirection2;
uniform float4 g_lightPosition2;
uniform float4 g_lightColor2;
uniform float4 g_lightSpecular2;
#endif
#if defined(_LIGHT3_POINT) || defined(_LIGHT3_DIRECTIONAL)
uniform float4 g_lightDirection3;
uniform float4 g_lightPosition3;
uniform float4 g_lightColor3;
uniform float4 g_lightSpecular3;
#endif
#if defined(_RIM_FADING)
uniform float4 g_RimFading;
#endif
#if defined(_USE_TAPER)
uniform float4 g_TaperOrigin;
uniform float4 g_TaperDir;
//Returns tapered pos
float3 TaperVert(float3 worldPos)
{
float3 taperOrigin = g_TaperOrigin.xyz;
float3 taperDir = g_TaperDir.xyz;
float taperMaxDist = g_TaperOrigin.w;
float taperFactor = g_TaperDir.w;
float3 from = worldPos-taperOrigin;
float proj = dot(from,taperDir);
if (proj <= 0)
return taperOrigin;
float3 projVec = proj*taperDir;
float3 delta = (from-projVec);
float len = length(delta);
float3 newDelta = delta - lerp(0,len,saturate(taperFactor*(taperMaxDist-proj)))*delta/len;
float3 newPos = taperOrigin+projVec+newDelta;
return newPos;
}
#endif
//////////////////////////////////////
// MATRIX MULTIPLICATION
//////////////////////////////////////
float3 Transform(float3x3 mat, float3 v)
{
#if defined(_XENON)
[isolate]
{
return mul(mat, v);
}
#elif defined(_GCM)
return mul(v, mat);
#else
return mul(mat, v);
#endif
}
float4 Transform(float4x4 mat, float4 v)
{
#if defined(_XENON)
[isolate]
{
return mul(mat, v);
}
#elif defined(_GCM)
return mul(v, mat);
#else
return mul(mat, v);
#endif
}
float2 Transform(float2x2 mat, float2 v)
{
#if defined(_XENON)
[isolate]
{
return mul(mat, v);
}
#elif defined(_GCM)
return mul(v, mat);
#else
return mul(mat, v);
#endif
}
//this conversion will not deal with renormalizations because is a bad way to handle bad data passing to the shader.
//the main problem is that cg-compiler isn't as smart as hlsl-compiler dealing with already normalized vectors
float3x3 GetWorldToTangentMatrix(float3x3 worldmtx,float3 tangent, float3 normal)
{
float3x3 worldToTangent = 0;
worldToTangent[0] = normalize(Transform(worldmtx, tangent));
worldToTangent[2] = normalize(Transform(worldmtx, normal));
worldToTangent[1] = normalize(cross(worldToTangent[0], worldToTangent[2]));
return worldToTangent;
}
float4 TransformPlanarReflection(float4 inPos)
{
float4x4 matTexScale = 0;
#if !defined(_GCM)
matTexScale._m00 = 0.5f;
matTexScale._m11 = -.5f;
matTexScale._m22 = 0.0f;
matTexScale._m03 = 0.5f;
matTexScale._m13 = 0.5f;
matTexScale._m23 = 1.0f;
matTexScale._m33 = 1.0f;
#else
matTexScale._m00 = 0.5f;
matTexScale._m11 = -0.5f;
matTexScale._m22 = 0.0f;
matTexScale._m30 = 0.5f;
matTexScale._m31 = 0.5f;
matTexScale._m32 = 1.0f;
matTexScale._m33 = 1.0f;
#endif
return Transform(matTexScale,inPos);
}
//////////////////////////////////////
// SKINNING
//////////////////////////////////////
#if defined(_VERTEX_SHADER) && defined(_USE_SKINMATRIX)
uniform float4x4 g_skinMatrix[_MAXBONES]; ///< 128 Registers for skin bones
struct SKINVERTEX
{
float4 P;
float3 N;
float3 T;
};
SKINVERTEX SkinVertex(float3 p, float3 n, float3 t, float4 indices, float4 weights)
{
SKINVERTEX Out = (SKINVERTEX) 0;
for(int i = 0; i < 4; i++)
{
Out.P.xyz += Transform(g_skinMatrix[indices.x], float4(p,1)).xyz * weights.x;
Out.N += (float3)(Transform((float3x3) g_skinMatrix[indices.x], n) * weights.x);
#if !defined(SH_VERSION_SH1)
Out.T += (float3)(Transform((float3x3) g_skinMatrix[indices.x], t) * weights.x);
#endif
indices.xyzw = indices.yzwx;
weights.xyzw = weights.yzwx;
}
Out.P.w = 1;
Out.N = (float3)normalize(Out.N);
#if !defined(SH_VERSION_SH1)
Out.T = (float3)normalize(Out.T);
#endif
return Out;
}
#endif
//////////////////////////////////////
// END SKINNING
//////////////////////////////////////
#ifdef _VERTEX_SHADER
float3 GetUVCoordinate3L0(float3 position, float3 normal, float3 viewer)
{
#ifdef _UV0_AUTO_POSITION
return position;
#elif defined(_UV0_AUTO_REFLECTION)
return (2.f * dot(viewer,normal) * normal - viewer) * .5f + .5f;
#elif defined(_UV0_AUTO_NORMAL)
return normal;
#elif defined(_UV0_AUTO_SPHERE)
return normal * .5f + .5f;
#elif defined(_UV0_AUTO_SPHEREVIEW)
float3 normalViewSpace = Transform(g_matView, normal);
return float3(normalViewSpace.x, -normalViewSpace.y, 1.0f) * .5f + .5f;
#else
return normal;
#endif
}
float3 GetUVCoordinate3L1(float3 position, float3 normal, float3 viewer)
{
#ifdef _UV1_AUTO_POSITION
return position;
#elif defined(_UV1_AUTO_REFLECTION)
return (2.f * dot(viewer,normal) * normal - viewer) * .5f + .5f;
#elif defined(_UV1_AUTO_NORMAL)
return normal;
#elif defined(_UV1_AUTO_SPHERE)
return normal * .5f + .5f;
#elif defined(_UV1_AUTO_SPHEREVIEW)
float3 normalViewSpace = Transform(g_matView, normal);
return float3(normalViewSpace.x, -normalViewSpace.y, 1.0f) * .5f + .5f;
#else
return normal;
#endif
}
#endif
#ifdef _VERTEX_SHADER
/// FOR PER VERTEX SHADERS
struct Multilayer_InputVS
{
float4 pos : POSITION; ///< Vertex position
#ifdef _USE_SKINMATRIX
float4 weight : BLENDWEIGHT; ///< Weights values for skinning
float4 indices : BLENDINDICES; ///< Index of bones for skinning
#endif
#ifdef _HAS_NORMAL
float3 normal : NORMAL; ///< Vertex Normal
#endif
#ifdef _HAS_TANGENT3
float3 tangent : TANGENT; ///< Vertex tangent, for use to map to tangent space normal maps
#endif
#ifdef _HAS_TANGENT
float4 tangent : TANGENT; ///< Vertex tangent, for use to map to tangent space normal maps
#endif
#ifdef _HAS_COLOR
float4 color : COLOR0; ///< Diffuse color of the vertex
#endif
#ifdef _HAS_UV0
float2 uv0 : TEXCOORD0; ///< UV Coordinates for diffuse, enviroment and normal map
#endif
#ifdef _HAS_UV1
float2 uv1 : TEXCOORD1; ///< UV Coordinates for light map
#endif
#ifdef _HAS_UV2
float2 uv2 : TEXCOORD2;
#endif
};
#endif
struct MultilayerPVL_OuputVS
{
float4 hpos : POSITION; ///< Clip space transformed vertex position
float4 color : COLOR0; ///< Vertex color
#ifndef _POINTSPRITE
float4 vpos : TEXCOORD0; ///< Position of the vertex in world space, and shadowprojection distance
float3 uv0 : TEXCOORD1; ///< UV Coordinates used by the diffuse texture, enviroment mask, and the normal map
float3 uv1 : TEXCOORD2; ///< UV Coordinates used by the enviroment map
float2 uv2 : TEXCOORD3; ///< UV Coordinates used by the light map
float3 normal : TEXCOORD4; ///< Vertex normal
float3 view : TEXCOORD5; ///< View direction to the vertex
#ifdef __USE_SHADOWMAP
float4 shadowProjection : TEXCOORD6; ///< Shadow map projection
#endif
#ifdef _PS3_VSCLIPPLANE0
float oClip0 : CLP0;
#endif
#else //POINTSPRITE code
float pointSize : PSIZE;
#endif
};
struct MultilayerPVLSpot_OuputVS
{
float4 hpos : POSITION; ///< Clip space trasnformed vertex
float4 color : COLOR0; ///< Vertex color
float3 uv0 : TEXCOORD0; ///< UV Coordinates used by the diffuse texture, enviroment mask, and the normal map
float3 normal : TEXCOORD1; ///< Vertex normal
float3 view : TEXCOORD2; ///< View direction to the vertex
float3 vpos : TEXCOORD3; ///< Position of the vertex in world space
float4 lightDir0 : TEXCOORD4; ///< Direction of light 0
#ifdef _LIGHT0_SPOT
float4 spotProjection1 : TEXCOORD5; ///< Shadow map projection
#endif
#ifdef _LIGHT1_SPOT
#undef __USE_SHADOWMAP // [BP] 2 spot lights do not allow the use of shadow maps (Using texcoord7)
float4 lightDir1 : TEXCOORD6; ///< Direction of light 1
float4 spotProjection2 : TEXCOORD7; ///< Shadow map projection
#endif
#if defined(__USE_SHADOWMAP)
float4 shadowProjection : TEXCOORD7; ///< Shadow map projection
#endif
#ifdef _PS3_VSCLIPPLANE0
float oClip0 : CLP0;
#endif
};
struct MultilayerPPL_OutputVS
{
float4 hpos : POSITION; ///< Clip space transformed vertex position
float4 color : COLOR0; ///< Diffuse color
float4 uvcoords : TEXCOORD0; ///< Uv coordinates of diffuse and enviroment maps
float4 vpos : TEXCOORD1; ///< Position in world space and lightspace depth
float4 lightDir0 : TEXCOORD2; ///< Direction of light 0
float4 lightDir1 : TEXCOORD3; ///< Direction of light 1
float4 lightDir2 : TEXCOORD4; ///< Direction of light 2
float4 lightDir3 : TEXCOORD5; ///< Direction of light 3
float3 viewDir : TEXCOORD6; ///< View direction to the vertex (tangent space)
#if defined(__USE_SHADOWMAP)
float4 shadowProjection : TEXCOORD7; ///< Shadow map projection
#endif
#ifdef _PS3_VSCLIPPLANE0
float oClip0 : CLP0;
#endif
};
struct MultilayerPPLSpot_OutputVS
{
float4 hpos : POSITION;
float4 color : COLOR0;
float3 uv0 : TEXCOORD0; ///< UV Coordinates used by the diffuse texture, enviroment mask, and the normal map
float3 vpos : TEXCOORD1; ///< Position in world space of the vertex
float4 lightDir0 : TEXCOORD2; ///< Direction of light 0
#ifdef _LIGHT0_SPOT
float4 spotProjection1 : TEXCOORD3; ///< Shadow map projection
#endif
#ifdef _LIGHT1_SPOT
#undef __USE_SHADOWMAP
float4 lightDir1 : TEXCOORD4; ///< Direction of light 1
float4 spotProjection2 : TEXCOORD5; ///< Shadow map projection
#endif
float3 view : TEXCOORD6; ///< Vire direction vector
#if defined(__USE_SHADOWMAP)
float4 shadowProjection : TEXCOORD7; ///< Shadow map projection
#endif
#ifdef _PS3_VSCLIPPLANE0
float oClip0 : CLP0;
#endif
};
struct MultilayerPVL_OutputPS
{
#if !defined(_MRT)
float4 color : COLOR0;
#else
#if defined(_MRT_RT_0_1)
float4 color : COLOR1;
#elif defined(_MRT_RT_0_2)
float4 color : COLOR2;
#elif defined(_MRT_RT_0_3)
float4 color : COLOR3;
#else
float4 color : COLOR0;
#endif
#if defined(_MRT1)
#if defined(_MRT_RT_1_0)
float4 color1 : COLOR0;
#elif defined(_MRT_RT_1_2)
float4 color1 : COLOR2;
#elif defined(_MRT_RT_1_3)
float4 color1 : COLOR3;
#else
float4 color1 : COLOR1;
#endif
#endif
#if defined(_MRT2)
#if defined(_MRT_RT_2_0)
float4 color2 : COLOR0;
#elif defined(_MRT_RT_2_1)
float4 color2 : COLOR1;
#elif defined(_MRT_RT_2_3)
float4 color2 : COLOR3;
#else
float4 color2 : COLOR2;
#endif
#endif
#if defined(_MRT3)
#if defined(_MRT_RT_3_0)
float4 color3 : COLOR0;
#elif defined(_MRT_RT_3_1)
float4 color3 : COLOR1;
#elif defined(_MRT_RT_3_2)
float4 color3 : COLOR2;
#else
float4 color3 : COLOR3;
#endif
#endif
#endif
};
//////////////////////////////////////
// LIGHTING FUNCTIONS
//////////////////////////////////////
/*
CalculateSpecularLighting
Calculates the specular lighting for an interest point
*/
float3 CalculateSpecularLighting(
in float3 lightDirection, ///< Direction of the light MUST BE NORMALIZED!
in float3 lightSpecularColor, ///< Specular color
in float3 normalVector, ///< Normal vector of the intereset point
in float3 viewVector ///< View vector of the interest point
)
{
float3 Half = normalize( lightDirection + viewVector);
return lightSpecularColor.xyz * pow(saturate( dot( Half, normalVector) ), g_specularColor.a);
}
/*
CalculatePointLightAttenuation
Calculates the attenuation of a point light on a surface point
*/
float CalculatePointLightAttenuation(
in float3 iLightDirection, ///< Direction NOT NORMALIZED, from the point to the light position
float iLightInverseRange ///< Inverse range (1/r) of the point light
)
{
float3 attenuatedLightDirection = iLightDirection * iLightInverseRange;
return saturate ( 1.0f - dot (attenuatedLightDirection, attenuatedLightDirection));
}
void LightSpot_VS(float3 iDir, float invRange, out float3 oDir, out float oFactor)
{
oDir.xyz = iDir;
//oFactor = length(iDir);
//oFactor = ( 1.0f - (oFactor / Range) );
oFactor = saturate ( 1.0f - dot (iDir * invRange, iDir * invRange));
}
void LightSpot_PS(float3 iDir, float3 normal, float3 view, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS, sampler2D spotMap, float4 spotTex)
{
float3 fvLightDir = iDir;
float fNDotL = dot(normal, fvLightDir);
float3 lightColor = tex2Dproj(spotMap, spotTex).rgb;
oD += lightColor * iD * saturate(fNDotL) * Factor;
#ifndef _MATERIAL_NOSPECULAR
float3 Half = normalize(fvLightDir+view);
oS += Factor * lightColor * iS.xyz * pow(saturate(dot(Half,normal)), iS.a);
#endif
}
/*
GetPointLightDirectionInTangentSpace
Retrieves the direction of a point light in tangent space
*/
float3 GetPointLightDirectionInTangentSpace(
float3 lightPosition, ///< Light position in world space
float3 vertexPosition, ///< Vertex position in world space
float3x3 worldToTangentTransform ///< World to Tangent space transformation
)
{
float3 lightDir = lightPosition - vertexPosition;
lightDir = mul(worldToTangentTransform, lightDir);
return lightDir;
}
/*
GetPointLightDirectionInWorldSpace
Calculates the point light direction in world space
*/
float3 GetPointLightDirectionInWorldSpace(
float3 lightPosition, ///< Light position in world space
float3 vertexPosition //< Vertex position in world space
)
{
return lightPosition - vertexPosition;
}
void OutLightDirSpotPPL(float3 iDir, float invRange, float3x3 TBN, out float3 oDir, out float oFactor)
{
oDir.xyz = iDir;
//oFactor = length(iDir.xyz);
//oFactor = ( 1.0f - (oFactor * invRange) );
oDir.xyz = mul(TBN, oDir.xyz);
oFactor = saturate ( 1.0f - dot (iDir * invRange, iDir * invRange));
}
void OutLightDirSpotPVL(float3 iDir, float invRange, out float3 oDir, out float oFactor)
{
oDir.xyz = iDir;
//oFactor = length(iDir.xyz);
//oFactor = ( 1.0f - (oFactor / Range) );
oFactor = saturate ( 1.0f - dot (iDir * invRange, iDir * invRange));
}
void LightDirectional_PPL_PS(float3 iDir, float3 n, float3 v, float3 iD, float3 iS, inout float3 oD, inout float3 oS)
{
float3 fvLightDir = normalize(iDir);
float fNDotL = dot(n, fvLightDir);
oD += iD * saturate(fNDotL);
#ifndef _MATERIAL_NOSPECULAR
float3 Half = normalize(fvLightDir + v);
oS.xyz += iS.xyz * pow(saturate(dot(Half, n)), g_specularColor.a);
#endif
}
/*
AddPointLightContributionTangentSpace
Adds the contribution diffuse and specular lighting of a point light to a point of a surface
*/
void AddPointLightContributionTangentSpace(
in float3 iLightDirectionTangentSpace, ///< Direction to the light from the 3d point in tangent space
in float3 iLightPositionWorldSpace, ///< Position of the point light in world space
in float iLightInverseRange, ///< Inverse range of the point light (1/r)
in float3 iLightDiffuseColor, ///< Diffuse color of the light
in float3 iLightSpecularColor, ///< Specular color of the light
in float3 iPointNormalTangentSpace, ///< Normal on the 3d point in tangent space
in float3 iPointViewTangentSpace, ///< View vector on the 3d point in tangent space
in float3 iPointPositionWorldSpace, ///< Position of the 3d point in world space
inout float3 ioAcumulatedDiffuseLight, ///< Acumulated diffuse light
inout float3 ioAcumulatedSpecularLight ///< Acumulated specular light
)
{
// Calculate attenuation of the spot light
float lightAttenuation = CalculatePointLightAttenuation(iLightPositionWorldSpace - iPointPositionWorldSpace, iLightInverseRange );
// Calculate diffuse lighting contribution
float3 lightDirectionNormalized = normalize( iLightDirectionTangentSpace );
float fNDotL = dot(iPointNormalTangentSpace, lightDirectionNormalized);
ioAcumulatedDiffuseLight += iLightDiffuseColor * saturate(fNDotL) * lightAttenuation;
// Calculate specular lighting contribution
#ifndef _MATERIAL_NOSPECULAR
ioAcumulatedSpecularLight += lightAttenuation *
CalculateSpecularLighting(lightDirectionNormalized, iLightSpecularColor, iPointNormalTangentSpace, iPointViewTangentSpace );
#endif
}
void LightPoint_PPL_PS(float3 iDir, float3 n, float3 v, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS)
{
float3 fvLightDir = normalize(iDir);
float fNDotL = dot(n, fvLightDir);
oD += iD * saturate(fNDotL) * Factor;
#ifndef _MATERIAL_NOSPECULAR
float3 Half = normalize(fvLightDir+v);
oS.rgb += Factor * iS.xyz * pow(saturate( dot(Half,n) ), g_specularColor.a);
#endif
}
void LightSpot_PPL_PS(float3 iDir, float3 normal, float3 view, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS, sampler2D spotMap, float4 spotTex)
{
float3 fvLightDir = normalize(iDir);
float fNDotL = dot(normal, fvLightDir);
float3 lightColor = tex2Dproj(spotMap, spotTex).rgb;
oD += saturate( lightColor * iD * saturate(fNDotL) * Factor );
#ifndef _MATERIAL_NOSPECULAR
float3 Half = normalize(fvLightDir+view);
oS += saturate( lightColor * Factor * iS.xyz * pow(saturate(dot(Half,normal)), g_specularColor.a) );
#endif
}
void LightDirectional_PVL_PS(float3 iDir, float3 normal, float3 view, float3 iD, float transColor, float3 iS, inout float3 oD, inout float3 oS)
{
float fNDotL = dot(normal, iDir);
oD += iD.rgb * saturate(fNDotL);
#ifdef _TRANSLUCENCY
float fNDotL2 = dot(-normal, iDir);
oD += iD.rgb * saturate(fNDotL2) * transColor;
#endif
#ifndef _MATERIAL_NOSPECULAR
float3 Half = normalize(iDir + view);
oS += iS.xyz * pow( saturate(dot(Half,normal)), g_specularColor.a);
#endif
}
/*
AddPointLightContributionWorldSpace
Adds the contribution diffuse and specular lighting of a point light to a point of a surface
*/
void AddPointLightContributionWorldSpace(
in float3 iLightPosition, ///< Light position in world space
in float iLightInverseRange, ///< Inverse range of the point light (1/r)
in float3 iLightDiffuseColor, ///< Diffuse color of the light
in float3 iLightSpecularColor, ///< Specular color of the light
in float3 iPointNormal, ///< Normal of the 3d point in world space
in float3 iPointView, ///< View vector of the 3d point in world space
in float3 iPointPosition, ///< Poisition of the 3d point in worls space
inout float3 ioAcumulatedDiffuseLight, ///< Acumulated diffuse lighting
inout float3 ioAcumulatedSpecularLight ///< Acumulated specular lighting
)
{
// Determiate the light direction, used for attenuation and light contribution
float3 lightDirection = iLightPosition - iPointPosition;
// Calculate attenuation of the spot light
float lightAttenuation = CalculatePointLightAttenuation(lightDirection, iLightInverseRange);
// Calculate diffuse lighting contribution
lightDirection = normalize( lightDirection );
float fNDotL = dot(iPointNormal, lightDirection);
ioAcumulatedDiffuseLight += iLightDiffuseColor * saturate(fNDotL) * lightAttenuation;
// Calculate specular lighting contribution
#ifndef _MATERIAL_NOSPECULAR
ioAcumulatedSpecularLight += lightAttenuation *
CalculateSpecularLighting(lightDirection, iLightSpecularColor, iPointNormal, iPointView);
#endif
}
void LightSpot_PVL_PS(float3 iDir, float3 normal, float3 view, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS, sampler2D spotMap, float4 spotTex)
{
float3 fvLightDir = iDir;
float fNDotL = dot(normal, fvLightDir);
float3 lightColor = tex2Dproj(spotMap, spotTex).rgb;
oD += lightColor * iD * saturate(fNDotL) * Factor;
#ifndef _MATERIAL_NOSPECULAR
float3 Half = normalize(fvLightDir+view);
oS += lightColor * Factor * iS.xyz * pow(saturate(dot(Half,normal)), g_specularColor.a);
#endif
}
//////////////////////////////////////
// END LIGHTING
//////////////////////////////////////
//////////////////////////////////////
// SHADOWMAPPING
//////////////////////////////////////
#ifdef __USE_SHADOWMAP
uniform float4x4 g_matTextureProjection;
uniform float4 g_shadowmapOptions;
uniform float4 g_texelSize89;
#define g_ShadowmapFactor (1-g_shadowmapOptions.x) /// default 0.0
#define g_ShadowmapZBias (g_shadowmapOptions.y) /// default -0.001
uniform sampler2D g_shadowMap : register(s9);
uniform samplerCUBE g_shadowCubeMap : register(s9);
////////////////////////////////////
// DIRECTIONAL
float SampleShadowTest(float4 ShadowTexC)
{
#if defined(_XENON) || defined(_SHADOWMAP_FLOAT) //Xenon & ATI
return tex2D(g_shadowMap, ShadowTexC.xy).r >= ShadowTexC.z;
#else //nVidia
return tex2Dproj(g_shadowMap, ShadowTexC).r;
#endif
}
float GetShadowDirectional(float4 TexCoords)
{
float4 ShadowTexC = TexCoords;
ShadowTexC.xy = 0.5 * TexCoords.xy + float2( 0.5, 0.5 );
ShadowTexC.y = 1.f - ShadowTexC.y;
#ifdef _PS3
ShadowTexC.z = ShadowTexC.z * .5f + .5f;
#endif
#ifdef _XENON
ShadowTexC.xyz = ShadowTexC.xyz / ShadowTexC.w;
// [BP] On xbox360 we are getting projected distances that are higher than 1
// as they are not being cut by the far plane of the light frustum
// still we need to study more this effect, even check if it can be done on vertex
// shader stage to save gpu process
ShadowTexC.z = min(1,ShadowTexC.z); // Check that z the minimum value to 1
#endif
#ifdef _DEBUG_SHADOWMAPS
//Dark regions out of shadow projection
if(ShadowTexC.x < 0 ||
ShadowTexC.y < 0 ||
ShadowTexC.x > 1 ||
ShadowTexC.y > 1)
return 0;
#endif
ShadowTexC.z += g_ShadowmapZBias;
ShadowTexC.w = 1;
#if defined(SH_VERSION_SH2) || defined(_SHADOW_LOW)
return saturate(SampleShadowTest(ShadowTexC) + g_ShadowmapFactor);
#else
float4 tX = float4(g_texelSize89.z, 0, 0, 0) * 2;
float4 tY = float4(0, g_texelSize89.w, 0, 0) * 2;
float accum = 0;
#if defined(_SHADOW_MED)
accum += SampleShadowTest(ShadowTexC + tX * -.5 + tY * -.5);
accum += SampleShadowTest(ShadowTexC + tX * .5 + tY * -.5);
accum += SampleShadowTest(ShadowTexC + tX * -.5 + tY * .5);
accum += SampleShadowTest(ShadowTexC + tX * .5 + tY * .5);
return saturate((accum/4.f) + g_ShadowmapFactor);
#elif defined(_SHADOW_HI)
accum += SampleShadowTest(ShadowTexC + tX * -1 + tY * -1);
accum += SampleShadowTest(ShadowTexC + tX * 0 + tY * -1);
accum += SampleShadowTest(ShadowTexC + tX * 1 + tY * -1);
accum += SampleShadowTest(ShadowTexC + tX * -1 + tY * 0);
accum += SampleShadowTest(ShadowTexC + tX * 0 + tY * 0);
accum += SampleShadowTest(ShadowTexC + tX * 1 + tY * 0);
accum += SampleShadowTest(ShadowTexC + tX * -1 + tY * 1);
accum += SampleShadowTest(ShadowTexC + tX * 0 + tY * 1);
accum += SampleShadowTest(ShadowTexC + tX * 1 + tY * 1);
return saturate((accum/9.f) + g_ShadowmapFactor);
#else
return 1;
#endif
#endif
}
/////////////////////////////////
// SPOT
//[VC]: why this is just a copy paste from spotdirectional???
float GetShadowSpotSample(float4 ShadowTexC)
{
float shadow;
#if defined(_XENON) || defined(_SHADOWMAP_FLOAT) //Xenon & ATI
float a = tex2D(g_shadowMap, ShadowTexC.xy).r > ShadowTexC.z;
float b = tex2D(g_shadowMap, ShadowTexC.xy + float2(g_texelSize89.z, 0)).r > ShadowTexC.z;
float c = tex2D(g_shadowMap, ShadowTexC.xy + float2(0, g_texelSize89.w)).r > ShadowTexC.z;
float d = tex2D(g_shadowMap, ShadowTexC.xy + float2(g_texelSize89.z, g_texelSize89.w)).r > ShadowTexC.z;
#if defined(SH_VERSION_SH2)
return a;
#endif
// transform to texel space
float2 texelpos = (1.f/g_texelSize89.zw) * ShadowTexC;
// Determine the lerp amounts
float2 lerps = frac( texelpos );
// lerp between the shadow values to calculate our light amount
shadow = lerp( lerp( a, b, lerps.x ),
lerp( c, d, lerps.x ),
lerps.y );
return shadow;
#else //nVidia
shadow = tex2Dproj(g_shadowMap, ShadowTexC).r;
#endif
return shadow;
}
float GetShadowSpot(float4 TexCoords)
{
float4 ShadowTexC = TexCoords;
ShadowTexC.xy = 0.5 * TexCoords.xy / TexCoords.w + float2( 0.5, 0.5 );
ShadowTexC.y = 1.0f - ShadowTexC.y;
//not needed for spot lights
#ifdef _PS3
//ShadowTexC.z = ShadowTexC.z * .5f + .5f;
#endif
#ifdef _DEBUG_SHADOWMAPS
//Dark regions out of shadow projection
if(ShadowTexC.x < 0 ||
ShadowTexC.y < 0 ||
ShadowTexC.x > 1 ||
ShadowTexC.y > 1)
return 0;
#endif
ShadowTexC.z += g_ShadowmapZBias;
ShadowTexC.z /= ShadowTexC.w;
ShadowTexC.w = 1;
#if defined(SH_VERSION_SH2) || defined(_SHADOW_LOW)
return saturate(GetShadowSpotSample(ShadowTexC) + g_ShadowmapFactor);
#endif
float4 tX = float4(g_texelSize89.z, 0, 0, 0) * 1;
float4 tY = float4(0, g_texelSize89.w, 0, 0) * 1;
float accum = 0;
#if defined(_SHADOW_MED)
accum += GetShadowSpotSample(ShadowTexC + tX * -.5 + tY * -.5);
accum += GetShadowSpotSample(ShadowTexC + tX * .5 + tY * -.5);
accum += GetShadowSpotSample(ShadowTexC + tX * -.5 + tY * .5);
accum += GetShadowSpotSample(ShadowTexC + tX * .5 + tY * .5);
return saturate((accum/4.f) + g_ShadowmapFactor);
#endif
#if defined(_SHADOW_HI)
accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY * -1);
accum += GetShadowSpotSample(ShadowTexC + tX * 0 + tY * -1);
accum += GetShadowSpotSample(ShadowTexC + tX * 1 + tY * -1);
accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY * 0);
accum += GetShadowSpotSample(ShadowTexC + tX * 0 + tY * 0);
accum += GetShadowSpotSample(ShadowTexC + tX * 1 + tY * 0);
accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY * 1);
accum += GetShadowSpotSample(ShadowTexC + tX * 0 + tY * 1);
accum += GetShadowSpotSample(ShadowTexC + tX * 1 + tY * 1);
return saturate((accum/9.f) + g_ShadowmapFactor);
#endif
return 1;
}
/////////////////////////////////
// POINT
float GetShadowPointSample(float3 Pos)
{
float shadow = 1;
#ifdef _LIGHT0_POINT
shadow = texCUBE(g_shadowCubeMap, Pos.xyz-g_lightPosition0.xyz).r > (length(Pos.xyz-g_lightPosition0.xyz) * g_lightPosition0.w) + g_ShadowmapZBias;
#endif
return shadow;
}
float GetShadowPoint(float3 Pos)
{
return saturate(GetShadowPointSample(Pos) + g_ShadowmapFactor);
}
#endif
//////////////////////////////////////
// END SHADOWMAPPING
//////////////////////////////////////
float GetRimFading(float3 CamPos,float3 FragmentWorldPos,float3 Normal,float InvThreshold)
{
float3 nCminP = normalize(CamPos.xyz-FragmentWorldPos.xyz);
float NdotCmP = dot(Normal,nCminP);
return saturate(NdotCmP*InvThreshold);
}
void ComputeFog(inout float4 PixelColor,float3 FogColor,float DistancePixelToCamera,float MinDistanceToFog,float MaxMinusMinDistanceToFog)
{
#if defined(_PIXEL_FOG)
float CamMinusFogMin = (DistancePixelToCamera-MinDistanceToFog);
float FogFactor = 1-saturate(CamMinusFogMin/MaxMinusMinDistanceToFog);
#if !defined(_ADDITIVE_PIXEL_FOG)
PixelColor.rgb = lerp(FogColor, PixelColor.rgb, FogFactor);
#elif defined(_ADDITIVE_PIXEL_FOG)
PixelColor.rgb*=FogFactor;
clip(MaxMinusMinDistanceToFog-CamMinusFogMin);
#endif
#endif
}
///////////////////////////////////////////////////////////////
//VERTEX SHADERS
///////////////////////////////////////////////////////////////
#ifdef _VERTEX_SHADER
#ifdef _PERPIXEL_LIGHTING
#ifdef _LIGHT0_SPOT
#define MULTILAYER_OUTPUT_VS MultilayerPPLSpot_OutputVS
#define MULTILAYER_MAIN_VS MultilayerPPLSpot_MainVS
#else
#define MULTILAYER_OUTPUT_VS MultilayerPPL_OutputVS
#define MULTILAYER_MAIN_VS MultilayerPPL_MainVS
#endif
#else
#ifdef _LIGHT0_SPOT
#define MULTILAYER_OUTPUT_VS MultilayerPVLSpot_OuputVS
#define MULTILAYER_MAIN_VS MultilayerPVLSpot_MainVS
#else
#define MULTILAYER_OUTPUT_VS MultilayerPVL_OuputVS
#define MULTILAYER_MAIN_VS MultilayerPVL_MainVS
#endif
#endif
void MultilayerPPL_MainVS( Multilayer_InputVS inVertex,out MultilayerPPL_OutputVS outResult);
void MultilayerPPLSpot_MainVS( Multilayer_InputVS inVertex,out MultilayerPPLSpot_OutputVS outResult);
void MultilayerPVL_MainVS( Multilayer_InputVS inVertex,out MultilayerPVL_OuputVS outResult);
void MultilayerPVLSpot_MainVS( Multilayer_InputVS inVertex,out MultilayerPVLSpot_OuputVS outResult);
void main_VS( Multilayer_InputVS inVertex, out MULTILAYER_OUTPUT_VS outResult )
{
MULTILAYER_MAIN_VS(inVertex, outResult);
}
///////////////////////////////////////////////
// Omni & Direct Per Pixel Vertex Shader
///////////////////////////////////////////////
void MultilayerPPL_MainVS( Multilayer_InputVS inVertex, out MultilayerPPL_OutputVS outResult)
{
outResult = (MultilayerPPL_OutputVS) 0;
#ifdef _HAS_NORMAL
float3 tempNormal = normalize(inVertex.normal.xyz);
#else
float3 tempNormal = float3(0,0,1);
#endif
#if defined(_HAS_TANGENT3) || defined(_HAS_TANGENT)
float3 tempTangent = normalize(inVertex.tangent.xyz);
#else
float3 tempTangent = float3(1,0,0);
#endif
#ifdef _HAS_COLOR
outResult.color = inVertex.color;
#else
outResult.color = float4(1,1,1,1);
#endif
/// Determinate the vertex position, normal and tangent from skinning
#ifdef _USE_SKINMATRIX
SKINVERTEX v = SkinVertex(inVertex.pos.xyz, tempNormal, tempTangent, inVertex.indices, inVertex.weight);
float4 position = v.P;
float3 normal = v.N;
float3 tangent = v.T;
#else
float4 position = float4(inVertex.pos.xyz,1);
float3 normal = tempNormal;
float3 tangent = tempTangent;
#endif
/// Transform the position and the normal to projection space
outResult.vpos = Transform(g_matWorld, position);
#if defined (_USE_TAPER)
outResult.vpos = float4(TaperVert(outResult.vpos.xyz),1);
outResult.hpos = Transform(g_matViewProjection, outResult.vpos);
#else
outResult.hpos = Transform(g_matWorldViewProjection, position);
#endif
#ifdef _PS3_VSCLIPPLANE0
outResult.oClip0 = dot(outResult.vpos, g_ps3ClipPlane0);
#endif
/// Compute the tangent transformation matrix
float3x3 worldToTangent = GetWorldToTangentMatrix((float3x3)g_matWorld,tangent,normal);
#ifdef _HAS_TANGENT
worldToTangent[1] *= inVertex.tangent.w;
#endif
/// Calculate lighting for directional lights, these must be transformed into tangent space
#ifdef _LIGHT0_DIRECTIONAL
outResult.lightDir0.xyz = -mul(worldToTangent, g_lightDirection0.xyz);
#ifdef __USE_SHADOWMAP
outResult.shadowProjection = Transform(g_matTextureProjection, position);
#endif
#endif
#ifdef _LIGHT1_DIRECTIONAL
outResult.lightDir1.xyz = -mul(worldToTangent, g_lightDirection1.xyz);
#endif
#ifdef _LIGHT2_DIRECTIONAL
outResult.lightDir2.xyz = -mul(worldToTangent, g_lightDirection2.xyz);
#endif
#ifdef _LIGHT3_DIRECTIONAL
outResult.lightDir3.xyz = -mul(worldToTangent, g_lightDirection3.xyz);
#endif
/// Calculate lighting for point lights
#ifdef _LIGHT0_POINT
outResult.lightDir0.xyz = GetPointLightDirectionInTangentSpace(g_lightPosition0.xyz, outResult.vpos.xyz, worldToTangent);
#endif
#ifdef _LIGHT1_POINT
outResult.lightDir1.xyz = GetPointLightDirectionInTangentSpace(g_lightPosition1.xyz, outResult.vpos.xyz, worldToTangent);
#endif
#ifdef _LIGHT2_POINT
outResult.lightDir2.xyz = GetPointLightDirectionInTangentSpace(g_lightPosition2.xyz, outResult.vpos.xyz, worldToTangent);
#endif
#ifdef _LIGHT3_POINT
outResult.lightDir3.xyz = GetPointLightDirectionInTangentSpace(g_lightPosition3.xyz, outResult.vpos.xyz, worldToTangent);
#endif
/// Calculate the view space normal, vertex position and viewer position
/// This are going to be used to calculate the vertex uv
/// Create parameters for autogenerated coordinates
#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW) || defined(_UV1_AUTO_POSITION) || defined(_UV1_AUTO_NORMAL) || defined(_UV1_AUTO_REFLECTION) || defined(_UV1_AUTO_SPHERE) || defined(_UV1_AUTO_SPHEREVIEW)
float3 P = outResult.vpos.xyz; ///< Vertex position in world space
float3 N = Transform((float3x3) g_matWorld, normal); ///< Normal in world space
float3 V = normalize(P-g_cameraPos.xyz); ///< Viewer position
N = normalize(N);
#endif
/// Calculate the uv transformations for the diffuse layer
#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW)
outResult.uvcoords.xy = GetUVCoordinate3L0(P, N, V);
#elif defined(_HAS_UV0)
outResult.uvcoords.xy = inVertex.uv0;
#endif
float3 env = 0;
#ifndef _MAP_PLANAR_REFLECTION
#if defined(_UV1_AUTO_POSITION) || defined(_UV1_AUTO_NORMAL) || defined(_UV1_AUTO_REFLECTION) || defined(_UV1_AUTO_SPHERE) || defined(_UV1_AUTO_SPHEREVIEW)
#ifdef _MAP_ENVIROMENT_CUBE
env = GetUVCoordinate3L1(P, N, V);
#else
env.xy = GetUVCoordinate3L1(P, N, V);
#endif
#elif defined(_HAS_UV0)
env.xy = inVertex.uv0;
env.z = 1;
#endif
#endif
/// Finally transform the uv coordinates by the texture matrix transformations
float3 uv3;
uv3.xy = outResult.uvcoords.xy;
uv3.z = 1;
outResult.uvcoords.xy = outResult.uvcoords.xy * g_textureTransform0.xy + outResult.uvcoords.yx * g_textureTransformExt0.yx + g_textureTransform0.zw;
#ifndef _MAP_ENVIROMENT_CUBE
env.xy = env.xy * g_textureTransform1.xy + env.yx * g_textureTransformExt1.yx + g_textureTransform1.zw;
#endif
#if !defined(_MAP_PLANAR_REFLECTION)
outResult.uvcoords.zw = env.xy;
outResult.vpos.w = env.z;
#else
float4 ScreenSpace = TransformPlanarReflection(outResult.hpos);
outResult.uvcoords.zw = ScreenSpace.xy;
outResult.vpos.w = ScreenSpace.z;
#endif
/// Write the UV used for the lightmap
#ifdef _HAS_UV1
outResult.lightDir0.w = inVertex.uv1.x;
outResult.lightDir1.w = inVertex.uv1.y;
#elif defined(_HAS_UV0)
outResult.lightDir0.w = inVertex.uv0.x;
outResult.lightDir1.w = inVertex.uv0.y;
#endif
/// Write the view direction in tangent space
//< Vertex position in world space
//#if !defined(_MATERIAL_NOSPECULAR) || defined(_PARALLAX)
outResult.viewDir.xyz = g_cameraPos.xyz - outResult.vpos.xyz;
outResult.viewDir.xyz = mul(worldToTangent, outResult.viewDir.xyz);
outResult.viewDir.xyz = normalize(outResult.viewDir.xyz);
//#endif
}
///////////////////////////////////////////////
// Spot Per Pixel Vertex Shader
///////////////////////////////////////////////
void MultilayerPPLSpot_MainVS( Multilayer_InputVS inVertex,out MultilayerPPLSpot_OutputVS outResult)
{
outResult = (MultilayerPPLSpot_OutputVS) 0;
float3 tempNormal = float3(0,0,1);
float3 tempTangent = float3(1,0,0);
outResult.color = float4(1,1,1,1);
#ifdef _HAS_NORMAL
tempNormal = normalize(inVertex.normal);
#endif
#if defined(_HAS_TANGENT3) || defined(_HAS_TANGENT)
tempTangent = normalize(inVertex.tangent);
#endif
#ifdef _HAS_COLOR
outResult.color = inVertex.color;
#endif
#ifdef _USE_SKINMATRIX
SKINVERTEX v = SkinVertex(inVertex.pos.xyz, tempNormal, tempTangent, inVertex.indices, inVertex.weight);
float4 position = v.P;
float3 normal = v.N;
float3 tangent = v.T;
#else
float4 position = float4(inVertex.pos.xyz,1);
float3 normal = normalize(tempNormal);
float3 tangent = normalize(tempTangent);
#endif
/// Transform the position and the normal to projection space
outResult.vpos = Transform(g_matWorld, position);
#if defined (_USE_TAPER)
outResult.vpos = TaperVert(outResult.vpos.xyz);
outResult.hpos = Transform(g_matViewProjection, float4(outResult.vpos.xyz,1));
#else
outResult.hpos = Transform(g_matWorldViewProjection, position);
#endif
#ifdef _PS3_VSCLIPPLANE0
outResult.oClip0 = dot(outResult.vpos, g_ps3ClipPlane0);
#endif
/// Compute the tangent transformation matrix
float3x3 worldToTangent = GetWorldToTangentMatrix((float3x3)g_matWorld, tangent,normal);
#ifdef _HAS_TANGENT
worldToTangent[1] *= inVertex.tangent.w;
#endif
/// Determinate the view vector
#if !defined(_MATERIAL_NOSPECULAR) && defined(_PARALLAX)
float3 view = g_cameraPos.xyz - outResult.vpos.xyz;
outResult.view.xyz = Transform(worldToTangent, view);
outResult.view.xyz = normalize(outResult.view.xyz);
#endif
/// Calculate the view space normal, vertex position and viewer position
/// This are going to be used to calculate the vertex uv
/// Create parameters for autogenerated coordinates
#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW)
float3 P = outResult.vpos.xyz; ///< Vertex position in world space
float3 N = Transform((float3x3) g_matWorld, normal); ///< Normal in world space
float3 V = -normalize(P-g_cameraPos); ///< Viewer position
N = normalize(N);
#endif
/// Calculate the uv transformations for the diffuse layer
#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW)
outResult.uv0 = GetUVCoordinate3L0(P, N, V);
#elif defined(_HAS_UV0)
outResult.uv0.xy = inVertex.uv0;
outResult.uv0.z = 1;
#endif
/// Finally transform the uv coordinates by the texture matrix transformations
outResult.uv0.xy = outResult.uv0.xy * g_textureTransform0.xy + outResult.uv0.yx * g_textureTransformExt0.yx + g_textureTransform0.zw;
/// Calculate spot light lightining attributes
float factor;
float fNDotLSpot;
#ifdef _LIGHT0_SPOT
OutLightDirSpotPPL(g_lightPosition0.xyz - outResult.vpos.xyz, g_lightPosition0.w, worldToTangent, outResult.lightDir0.xyz, outResult.lightDir0.w);
#ifdef __USE_SHADOWMAP
outResult.shadowProjection = Transform(g_matTextureProjection, position);
#endif
outResult.spotProjection1 = Transform(g_matTexture2, position);
#endif
#ifdef _LIGHT1_SPOT
OutLightDirSpotPPL(g_lightPosition1.xyz - outResult.vpos.xyz, g_lightPosition1.w, worldToTangent, outResult.lightDir1.xyz, outResult.lightDir1.w);
outResult.spotProjection2 = Transform(g_matTexture3, position);
#endif
}
///////////////////////////////////////////////
// Omni & Direct Vertex Shader
///////////////////////////////////////////////
void MultilayerPVL_MainVS( Multilayer_InputVS inVertex,out MultilayerPVL_OuputVS outResult)
{
outResult = (MultilayerPVL_OuputVS) 0;
#ifndef _POINTSPRITE
outResult.normal = float3(0,0,1);
outResult.color = float4(1,1,1,1);
#ifdef _HAS_NORMAL
outResult.normal = normalize(inVertex.normal);
#endif
#ifdef _HAS_COLOR
outResult.color = inVertex.color;
#endif
#ifdef _USE_SKINMATRIX
SKINVERTEX v = SkinVertex(inVertex.pos.xyz, outResult.normal, float3(1,0,0), inVertex.indices, inVertex.weight);
float4 position = v.P;
float3 normal = v.N;
#else
float4 position = float4(inVertex.pos.xyz,1);
float3 normal = outResult.normal;
#endif
/// Transform the position to clip space
outResult.vpos = Transform(g_matWorld, position);
#if defined (_USE_TAPER)
outResult.vpos = float4(TaperVert(outResult.vpos.xyz),1);
outResult.hpos = Transform(g_matViewProjection, outResult.vpos);
#else
outResult.hpos = Transform(g_matWorldViewProjection, position);
#endif
outResult.normal = Transform ((float3x3) g_matWorld, normal); ///< Normal in world space
#ifdef _PS3_VSCLIPPLANE0
outResult.oClip0 = dot(outResult.vpos, g_ps3ClipPlane0);
#endif
/// Create parameters for autogenerated coordinates
#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW) || defined(_UV1_AUTO_POSITION) || defined(_UV1_AUTO_NORMAL) || defined(_UV1_AUTO_REFLECTION) || defined(_UV1_AUTO_SPHERE) || defined(_UV1_AUTO_SPHEREVIEW)
float3 P = outResult.vpos.xyz; ///< Vertex position in world space
float3 N = Transform((float3x3) g_matWorld, normal); ///< Normal in world space
float3 V = normalize(P-g_cameraPos); ///< Viewer position
N = normalize(N);
#endif
/// Calculate the uv transformations for the diffuse layer
#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW)
outResult.uv0.xy = GetUVCoordinate3L0(P, N, V);
#elif defined(_HAS_UV0)
outResult.uv0.xy = inVertex.uv0;
outResult.uv0.z = 1;
#endif
float3 env = 0;
/// Calculate the uv transformation for the enviromental layer
#if defined(_UV1_AUTO_POSITION) || defined(_UV1_AUTO_NORMAL) || defined(_UV1_AUTO_REFLECTION) || defined(_UV1_AUTO_SPHERE) || defined(_UV1_AUTO_SPHEREVIEW)
#ifdef _MAP_ENVIROMENT_CUBE
env = GetUVCoordinate3L1(P, N, V);
#else
env.xy = GetUVCoordinate3L1(P, N, V);
#endif
#if defined(_MAP_PLANAR_REFLECTION) || defined(_MAP_ENVIROMENT)
outResult.uv1 = env;
#endif
#elif defined(_HAS_UV0)
#if defined(_MAP_PLANAR_REFLECTION) || defined(_MAP_ENVIROMENT)
outResult.uv1.xy = inVertex.uv0;
outResult.uv1.z = 1;
#endif
#endif
/// Finally transform the uv coordinates by the texture matrix transformations
outResult.uv0.xy = outResult.uv0.xy * g_textureTransform0.xy + outResult.uv0.yx * g_textureTransformExt0.yx + g_textureTransform0.zw;
#ifndef _MAP_ENVIROMENT_CUBE
#if defined(_MAP_PLANAR_REFLECTION) || defined(_MAP_ENVIROMENT)
outResult.uv1.xy = outResult.uv1.xy * g_textureTransform1.xy + outResult.uv1.yx * g_textureTransformExt1.yx + g_textureTransform1.zw;
#endif
#endif
/// Write the UV used for the lightmap
#ifdef _HAS_UV1
outResult.uv2 = inVertex.uv1;
#elif defined(_HAS_UV0)
outResult.uv2 = inVertex.uv0;
#endif
/// The outResult.view vector is only used to calculate specular lighting, so if there is no specular
/// dont calculate the view
#ifndef _MATERIAL_NOSPECULAR
float3 pWorld = Transform(g_matWorld, position); ///< Vertex position in world space
outResult.view = normalize(g_cameraPos - pWorld); ///< View direction
#endif
#ifdef _MAP_PLANAR_REFLECTION
float4 ScreenSpace = TransformPlanarReflection(outResult.hpos);
outResult.uv1.xyz = ScreenSpace.xyz;
#endif
#ifdef _LIGHT0_DIRECTIONAL
#ifdef __USE_SHADOWMAP
outResult.shadowProjection = Transform(g_matTextureProjection, position);
#endif
#endif
/// Calculate lighting for point lights
/*
float3 lightDir;
#ifdef _LIGHT0_POINT
OutLightDirPointPVL(g_lightPosition0.xyz - outResult.vpos, g_lightPosition0.w, lightDir, outResult.lightfactors.x);
#endif
#ifdef _LIGHT1_POINT
OutLightDirPointPVL(g_lightPosition1.xyz - outResult.vpos, g_lightPosition1.w, lightDir, outResult.lightfactors.y);
#endif
#ifdef _LIGHT2_POINT
OutLightDirPointPVL(g_lightPosition2.xyz - outResult.vpos, g_lightPosition2.w, lightDir, outResult.lightfactors.z);
#endif
#ifdef _LIGHT3_POINT
OutLightDirPointPVL(g_lightPosition3.xyz - outResult.vpos, g_lightPosition3.w, lightDir, outResult.lightfactors.w);
#endif
*/
#else//POINTSPRITE
outResult.color = inVertex.color;
outResult.hpos = Transform( g_matWorldViewProjection, inVertex.pos);
float d = distance(inVertex.pos.xyz, g_cameraPos.xyz);
outResult.pointSize = inVertex.uv0.x / d;
outResult.pointSize *= g_screenSize.x;
#endif
}
///////////////////////////////////////////////
// Spot Vertex Shader
///////////////////////////////////////////////
void MultilayerPVLSpot_MainVS( Multilayer_InputVS inVertex,out MultilayerPVLSpot_OuputVS outResult)
{
outResult = (MultilayerPVLSpot_OuputVS) 0;
outResult.normal = float3(0,0,1);
outResult.color = float4(1,1,1,1);
#ifdef _HAS_NORMAL
outResult.normal = normalize(inVertex.normal);
#endif
#ifdef _HAS_COLOR
outResult.color = inVertex.color;
#endif
#ifdef _USE_SKINMATRIX
SKINVERTEX v = SkinVertex(inVertex.pos.xyz, outResult.normal, float3(1,0,0), inVertex.indices, inVertex.weight);
float4 position = v.P;
float3 normal = v.N;
#else
float4 position = float4(inVertex.pos.xyz,1);
float3 normal = outResult.normal;
#endif
/// Transform the position to clip space
outResult.vpos = Transform(g_matWorld, position);
#if defined (_USE_TAPER)
outResult.vpos = TaperVert(outResult.vpos.xyz);
outResult.hpos = Transform(g_matViewProjection, float4(outResult.vpos.xyz,1));
#else
outResult.hpos = Transform(g_matWorldViewProjection, position);
#endif
outResult.normal = Transform ((float3x3) g_matWorld, normal); ///< Normal in world space
#ifdef _PS3_VSCLIPPLANE0
outResult.oClip0 = dot(outResult.vpos, g_ps3ClipPlane0);
#endif
/// Create parameters for autogenerated coordinates
#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW) || defined(_UV1_AUTO_POSITION) || defined(_UV1_AUTO_NORMAL) || defined(_UV1_AUTO_REFLECTION) || defined(_UV1_AUTO_SPHERE) || defined(_UV1_AUTO_SPHEREVIEW)
float3 P = outResult.vpos.xyz; ///< Vertex position in world space
float3 N = Transform((float3x3) g_matWorld, normal); ///< Normal in world space
float3 V = -normalize(P-g_cameraPos); ///< Viewer position
N = normalize(N);
#endif
/// Calculate the uv transformations for the diffuse layer
#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW)
outResult.uv0 = GetUVCoordinate3L0(P, N, V);
#elif defined(_HAS_UV0)
outResult.uv0.xy = inVertex.uv0;
outResult.uv0.z = 1;
#endif
/// Finally transform the uv coordinates by the texture matrix transformations
outResult.uv0.xy = outResult.uv0.xy * g_textureTransform0.xy + outResult.uv0.yx * g_textureTransformExt0.yx + g_textureTransform0.zw;
/// Calculate spot light lightining attributes
float factor;
float fNDotLSpot;
#ifdef _LIGHT0_SPOT
outResult.spotProjection1 = Transform(g_matTexture2, position);
OutLightDirSpotPVL(g_lightPosition0.xyz - outResult.vpos.xyz, g_lightPosition0.w, outResult.lightDir0.xyz, outResult.lightDir0.w);
#ifdef __USE_SHADOWMAP
outResult.shadowProjection = Transform(g_matTextureProjection, position);
#endif
#endif
#ifdef _LIGHT1_SPOT
outResult.spotProjection2 = Transform(g_matTexture3, position);
OutLightDirSpotPVL(g_lightPosition1.xyz - outResult.vpos.xyz, g_lightPosition1.w, outResult.lightDir1.xyz, outResult.lightDir1.w);
#endif
/// The outResult.view vector is only used to calculate specular lighting, so if there is no specular
/// dont calculate the view
#ifndef _MATERIAL_NOSPECULAR
float3 pWorld = Transform(g_matWorld, position); ///< Vertex position in world space
outResult.view = g_cameraPos.xyz - pWorld; ///< View direction
#endif
}
#endif
///////////////////////////////////////////////////////////////
//PIXEL SHADERS
///////////////////////////////////////////////////////////////
#if defined(_PIXEL_SHADER)
#ifdef _PERPIXEL_LIGHTING
#ifdef _LIGHT0_SPOT
#define MULTILAYER_OUTPUT_PS MultilayerPVL_OutputPS
#define MULTILAYER_INPUT_PS MultilayerPPLSpot_OutputVS
#define MULTILAYER_MAIN_PS MultilayerPPLSpot_MainPS
#else
#define MULTILAYER_OUTPUT_PS MultilayerPVL_OutputPS
#define MULTILAYER_INPUT_PS MultilayerPPL_OutputVS
#define MULTILAYER_MAIN_PS MultilayerPPL_MainPS
#endif
#else
#ifdef _LIGHT0_SPOT
#define MULTILAYER_OUTPUT_PS MultilayerPVL_OutputPS
#define MULTILAYER_INPUT_PS MultilayerPVLSpot_OuputVS
#define MULTILAYER_MAIN_PS MultilayerPVLSpot_MainPS
#else
#define MULTILAYER_OUTPUT_PS MultilayerPVL_OutputPS
#define MULTILAYER_INPUT_PS MultilayerPVL_OuputVS
#define MULTILAYER_MAIN_PS MultilayerPVL_MainPS
#endif
#endif
void MultilayerPPL_MainPS(MultilayerPPL_OutputVS inData , out MultilayerPVL_OutputPS outResult);
void MultilayerPPLSpot_MainPS(MultilayerPPLSpot_OutputVS inData, out MultilayerPVL_OutputPS outResult);
void MultilayerPVL_MainPS(MultilayerPVL_OuputVS inData , out MultilayerPVL_OutputPS outResult);
void MultilayerPVLSpot_MainPS(MultilayerPVLSpot_OuputVS inData , out MultilayerPVL_OutputPS outResult);
uniform sampler2D g_diffuseMap : register(s0);
#ifdef _MAP_ENVIROMENT_CUBE
uniform samplerCUBE g_enviromentMap : register(s1);
#else
uniform sampler2D g_enviromentMap : register(s1);
#endif
uniform sampler2D g_glossMap : register(s2);
uniform sampler2D g_lightMap : register(s3);
uniform sampler2D g_specularMap : register(s4);
uniform sampler2D g_emissiveMap : register(s5);
uniform sampler2D g_normalMap : register(s6);
uniform sampler2D g_planarReflection : register(s7);
uniform sampler2D g_spot1Map : register(s8);
uniform sampler2D g_spot2Map : register(s9);
uniform sampler2D g_diffuse2Map : register(s10);
/// Tongas upload variables
#ifdef _VERTICAL_FOG
float4 g_verticalFogColor;
float4 g_verticalFogValues;
#endif
#ifdef _PIXEL_FOG
float4 g_pixelFogColor;
float4 g_pixelFogOptions;
#endif
#ifdef _PARALLAX
float g_fParallaxScale;
#endif
#if defined(_CAMERA_LIGHT) || defined(_RIM_FADING)
float4 g_cameraDir;
float4 g_cameraLightColor;
#endif
float4 g_lightMapColor;
#if defined(_MRT)
#define _MRT_DEFAULT_COLOR float4(0,0,0,0)
#define _MRT_BLACK_COLOR float4(0,0,0,1)
#ifndef _PIXEL_FOG
float4 g_pixelFogOptions;
#endif
uniform float4 g_multilayerTextureOptions;
float4 getBloomOutput(float2 uvCoords,uniform sampler2D tex)
{
float mulFactor = 0;
if(g_emissiveColor.a>0)
mulFactor = 1;
#if !defined(_POINTSPRITE)
float4 ret = float4(0,0,0,1);
ret.g = g_emissiveColor.a;
#else
float4 ret = float4(0,1,0,1);
#endif
// Determinate the alpha color from the diffuse stage
if (g_multilayerTextureOptions.x > 1)
{
/// Texture with additive blending
float4 color = tex2D( tex, uvCoords );
ret.a*= (color.r + color.g + color.b)*0.3333 * color.a;
}
else if (g_multilayerTextureOptions.x > 0)
{
// Texture with alpha
ret.a*= tex2D( tex, uvCoords ).a;
}
ret*=mulFactor;
return ret;
}
#if !defined(_POINTSPRITE)
float4 getFocusBloomOutput(float opacity,float3 pos,float2 uvCoords,uniform sampler2D tex)
{
float mulFactor = 0;
if(g_emissiveColor.a>0)
mulFactor = 1;
if(opacity>=1)
mulFactor = 1;
float4 ret = float4(0,0,0,opacity);
ret.g = g_emissiveColor.a*opacity;
// Determinate the alpha color from the diffuse stage
if (g_multilayerTextureOptions.x > 1)
{
/// Texture with additive blending
float4 color = tex2D( tex, uvCoords );
ret.a*= (color.r + color.g + color.b)*0.3333 * color.a;
}
else if (g_multilayerTextureOptions.x > 0)
{
// Texture with alpha
ret.a*= tex2D( tex, uvCoords ).a;
}
ret*=mulFactor;
return ret;
}
#endif
#if defined(_MULTILAYER_CGFX)
//default output
float4 pso_MRT_default_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_default_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_default_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_default_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_focusBloom_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
#if !defined(_POINTSPRITE)
return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
#else
return getBloomOutput(IN.uv.xy,g_diffuseMap);
#endif
}
float4 pso_MRT_focusBloom_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uvcoords.xy,g_diffuseMap);
}
float4 pso_MRT_focusBloom_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
}
float4 pso_MRT_focusBloom_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
}
#endif
//default output
#if defined(_COMPOSITE_CGFX)
#ifndef _POINTSPRITE
float4 pso_MRT_default_output(Composite_OutputVS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(Composite_OutputVS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(Composite_OutputVS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_focusBloom_output(Composite_OutputVS IN,float4 mainColor)
{
return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_layer0);
}
#else
float4 pso_MRT_default_output(CompositeSprite_InputPS IN,float4 mainColor)
{
return _MRT_DEFAULT_COLOR;
}
float4 pso_MRT_black_output(CompositeSprite_InputPS IN,float4 mainColor)
{
return _MRT_BLACK_COLOR;
}
float4 pso_MRT_blackBoolAlpha_output(CompositeSprite_InputPS IN,float4 mainColor)
{
return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}
float4 pso_MRT_focusBloom_output(CompositeSprite_InputPS IN,float4 mainColor)
{
return getBloomOutput(IN.uv.xy,g_layer0);
}
#endif
#endif
#if defined(_MRT3) && !defined(_MRT2)
#define _MRT2
#endif
#if defined(_MRT2) && !defined(_MRT1)
#define _MRT1
#endif
#if defined(_MRT1) && !defined(_MRT1_OUTMETHOD)
#define _MRT1_OUTMETHOD pso_MRT_default_output
#endif
#if defined(_MRT2) && !defined(_MRT2_OUTMETHOD)
#define _MRT2_OUTMETHOD pso_MRT_default_output
#endif
#if defined(_MRT3) && !defined(_MRT3_OUTMETHOD)
#define _MRT3_OUTMETHOD pso_MRT_default_output
#endif
#endif
#if defined(_ALPHA_TEST)
float4 g_PixelAlphaTesting;
#endif
void main_PS( MULTILAYER_INPUT_PS inData,out MULTILAYER_OUTPUT_PS outResult)
{
MULTILAYER_MAIN_PS(inData,outResult);
#if defined(_MRT1)
outResult.color1 = _MRT1_OUTMETHOD(inData,outResult.color);
#endif
#if defined(_MRT2)
outResult.color2 = _MRT2_OUTMETHOD(inData,outResult.color);
#endif
#if defined(_MRT3)
outResult.color3 = _MRT3_OUTMETHOD(inData,outResult.color);
#endif
#if defined(_ALPHA_TEST)
clip(outResult.color.a-g_PixelAlphaTesting.x);
#endif
}
///////////////////////////////////////////////
// Omni & Direct Per Pixel PixelShader
///////////////////////////////////////////////
void MultilayerPPL_MainPS( MultilayerPPL_OutputVS inData,out MultilayerPVL_OutputPS outResult)
{
outResult = (MultilayerPVL_OutputPS) 0;
float3 view = normalize(inData.viewDir.xyz);
#ifdef _PARALLAX
inData.uvcoords.xy += (tex2D(g_normalMap, inData.uvcoords.xy).a * g_fParallaxScale - g_fParallaxScale*.5f ) * view;
#endif
// As the usage of the second diffuse is encoded on the lightmap, must retrieve that first
#if defined (_MAP_LIGHTMAP) || defined (BLEND_DIFFUSE2_WITH_LIGHTMAPALPHA)
float4 lightMapColor;
float2 luv;
luv.x = inData.lightDir0.w;
luv.y = inData.lightDir1.w;
lightMapColor = tex2D( g_lightMap, luv);
lightMapColor.rgb *= g_lightMapColor.rgb;
lightMapColor.rgb *= g_lightMapColor.a;
#endif // _MAP_LIGHTMAP
// Calculate the albedo color
// Start with the vertex color, separate color from alpha for best processing
// BLEND_DIFFUSE2_WITH_LIGHTMAPALPHA means that we merge to diffuse textures with the lighmap alpha color
float3 albedo = inData.color.rgb;
float opacity = inData.color.a;
#ifdef _MAP_DIFFUSE
#ifdef BLEND_DIFFUSE2_WITH_LIGHTMAPALPHA
// Merge both diffuse maps with the alpha color of the lightmap
float4 albedoTexture = lerp( tex2D( g_diffuseMap, inData.uvcoords.xy ),
tex2D( g_diffuse2Map, inData.uvcoords.xy ),
lightMapColor.a);
#else
float4 albedoTexture = tex2D( g_diffuseMap, inData.uvcoords.xy );
#endif
albedo*=albedoTexture.rgb;
#if !defined(_ALPHACAMERALIGHTMASK) && !defined(_TRANSLUCENCY) && !defined(_ALPHAENVIROMENTMASK)
opacity*=albedoTexture.a;
#endif
#endif
/// Retrieve the normal for the model, this is in normal texture space
float3 normal = normalize( 2.0 * tex2D( g_normalMap, inData.uvcoords.xy ).rgb - 1.0 );
/// Calculate lighting -----------------------------------------------------------------------
// If we have a light with a shadowmap, lets retrieve it early for different objectives
#ifdef __USE_SHADOWMAP
#if defined (_LIGHT0_DIRECTIONAL)
float shadow = GetShadowDirectional(inData.shadowProjection);
#elif defined ( _LIGHT0_POINT )
float shadow = GetShadowPoint(inData.vpos.xyz);
#endif
#endif
// Check for static lighting conditions (lightmap)
// In the case of not having lightmaps, start with black
#ifdef _MAP_LIGHTMAP
outResult.color.rgb = 2.0f * albedo * lightMapColor.rgb;
// Check if we must apply the shadow on the lightmap
#ifdef _SHADOWLIGHTMAP
outResult.color.rgb*=shadow;
#endif
#else
outResult.color.rgb = 0;
#endif
/// Now proceed with dynamic lighting
float fNDotL; ///< Auxiliary to calculate how does the light affects the surface
float3 fvLightDir; ///< Auxiliary for the light direction
float3 myLight = 0; ///< This will acumulate the diffuse lighting
float3 mySpecular = 0; ///< This will acumulate the specular lighting
/// Calculate directional lighting
#if defined (_LIGHT0_DIRECTIONAL) && !defined(_ONLYSHADOW)
LightDirectional_PPL_PS(inData.lightDir0.xyz, normal, view, g_lightColor0.xyz, g_lightSpecular0.xyz, myLight, mySpecular);
#ifdef __USE_SHADOWMAP
myLight *= shadow;
#ifndef _MATERIAL_NOSPECULAR
mySpecular *= shadow;
#endif
#endif
#endif
#ifdef _LIGHT1_DIRECTIONAL
LightDirectional_PPL_PS(inData.lightDir1.xyz, normal, view, g_lightColor1.xyz, g_lightSpecular1.xyz, myLight, mySpecular);
#endif
#ifdef _LIGHT2_DIRECTIONAL
LightDirectional_PPL_PS(inData.lightDir2.xyz, normal, view, g_lightColor2.xyz, g_lightSpecular2.xyz, myLight, mySpecular);
#endif
#ifdef _LIGHT3_DIRECTIONAL
LightDirectional_PPL_PS(inData.lightDir3.xyz, normal, view, g_lightColor3.xyz, g_lightSpecular3.xyz, myLight, mySpecular);
#endif
#define myAmbientLight g_ambient.rgb
/// Calculate point lights
#if defined (_LIGHT0_POINT) && !defined(_ONLYSHADOW)
AddPointLightContributionTangentSpace(inData.lightDir0.xyz, g_lightPosition0.xyz, g_lightPosition0.w, g_lightColor0.rgb, g_lightSpecular0.rgb,
normal, view, inData.vpos, myLight, mySpecular);
#ifdef __USE_SHADOWMAP
myLight *= shadow;
#ifndef _MATERIAL_NOSPECULAR
mySpecular *= shadow;
#endif
#endif
#endif
#ifdef _LIGHT1_POINT
AddPointLightContributionTangentSpace(inData.lightDir1.xyz, g_lightPosition1.xyz, g_lightPosition1.w, g_lightColor1.rgb, g_lightSpecular1.rgb,
normal, view, inData.vpos, myLight, mySpecular);
#endif
#ifdef _LIGHT2_POINT
AddPointLightContributionTangentSpace(inData.lightDir2.xyz, g_lightPosition2.xyz, g_lightPosition2.w, g_lightColor2.rgb, g_lightSpecular2.rgb,
normal, view, inData.vpos, myLight, mySpecular);
#endif
#ifdef _LIGHT3_POINT
AddPointLightContributionTangentSpace(inData.lightDir3.xyz, g_lightPosition3.xyz, g_lightPosition3.w, g_lightColor3.rgb, g_lightSpecular3.rgb,
normal, view, inData.vpos, myLight, mySpecular);
#endif
#ifdef _NON_LIGHTED
myLight = 1;
#endif
/// Apply the directional lighting to the output color
outResult.color.rgb += albedo * (myLight * g_diffuseColor.rgb + myAmbientLight * g_ambientColor.rgb);
/// If we got a specular map then proceed to get the specular color from it
#ifndef _MATERIAL_NOSPECULAR
float3 mySpecularColor = g_specularColor.rgb;
#ifdef _MAP_SPECULAR
mySpecularColor *= tex2D(g_specularMap,inData.uvcoords.xy ).rgb;
#endif
outResult.color.rgb += mySpecular * mySpecularColor;
#endif
/// Apply the enviromental using the gloss map
#ifdef _MAP_PLANAR_REFLECTION
float2 refCoords = inData.uvcoords.zw/inData.vpos.w;
#ifdef _PARALLAX
refCoords += normal * g_fParallaxScale;
#else
refCoords += normal * .01f;
#endif
float3 reflection = tex2D(g_planarReflection, refCoords);
#ifdef _MAP_ENVIROMENTGLOSS
reflection *= tex2D( g_glossMap, inData.uvcoords.xy );
#endif
outResult.color.rgb += reflection;
#else
#ifdef _MAP_ENVIROMENT
#ifdef _MAP_ENVIROMENT_CUBE
float3 enviroment = texCUBE( g_enviromentMap, float3(inData.uvcoords.zw, inData.vpos.w) ).rgb;
#else
float3 enviroment = tex2D( g_enviromentMap, inData.uvcoords.zw ).rgb;
#endif
#ifdef _MAP_ENVIROMENTGLOSS
enviroment.rgb *= tex2D( g_glossMap, inData.uvcoords.xy ).rgb;
#endif
outResult.color.rgb += enviroment.rgb * g_enviromentColor.rgb;
#endif
#endif
/// Apply emissive material color and map
/// Then saturate the color
outResult.color.rgb += g_emissiveColor.rgb;
#ifdef _MAP_EMISSIVE
#ifdef _EMISSIVE_FLIPBOOK
inData.uvcoords.z = 1;
float2 euv = inData.uvcoords.xy * g_textureTransform5.xy + g_textureTransform5.zw;
outResult.color.rgb+= tex2D( g_emissiveMap, euv).rgb;
#else
outResult.color.rgb+= tex2D( g_emissiveMap, inData.uvcoords.xy).rgb;
#endif
#endif
float fogValue;
#ifdef _VERTICAL_FOG
fogValue = saturate( (inData.vpos.y - g_verticalFogValues.x) / g_verticalFogValues.z);
outResult.color.rgb = lerp(g_verticalFogColor.rgb, outResult.color.rgb, fogValue);
#endif
#ifdef _PIXEL_FOG
ComputeFog(outResult.color,g_pixelFogColor.rgb,distance(g_cameraPos.xyz, inData.vpos.xyz),g_pixelFogOptions.x,g_pixelFogOptions.z);
#endif
// Calculate the output alpha from the calculated opacity and from the material diffuse color
outResult.color.a = opacity * g_diffuseColor.a;
#ifdef _CAMERA_LIGHT
float vdn = abs(dot(view,normal));
vdn = saturate(vdn);
vdn = 1 - vdn;
vdn *= vdn;
#ifdef _ALPHACAMERALIGHTMASK
vdn*=albedoTexture.a;
#endif
outResult.color.rgb += vdn * g_cameraLightColor.rgb;
#endif
#if defined(_RIM_FADING)
outResult.color.a*=GetRimFading(g_cameraPos.xyz,inData.vpos.xyz,normal,g_RimFading.y);
#endif
}
///////////////////////////////////////////////
// Spot Per Pixel PixelShader
///////////////////////////////////////////////
void MultilayerPPLSpot_MainPS( MultilayerPPLSpot_OutputVS inData,out MultilayerPVL_OutputPS outResult)
{
outResult = (MultilayerPVL_OutputPS)1;
#ifdef _PARALLAX
inData.uv0.xy += (tex2D(g_normalMap, inData.uv0.xy).a * g_fParallaxScale - g_fParallaxScale*.5f ) * normalize(inData.view);
#endif
float4 diffuseColor = tex2D( g_diffuseMap, inData.uv0.xy );
/// Retrieve the normal for the model, this is in normal texture space
float3 normal = normalize( 2.0 * tex2D( g_normalMap, inData.uv0.xy ).rgb - 1.0 );
/// Calculate lighting
float fNDotL;
float fNDotLSpot;
float3 myLight = 0;
float3 fvLightDir;
float4 lightColor;
float factor;
float3 mySpecular = 0;
float3 Half;
float3 view = 0;
#if !defined(_MATERIAL_NOSPECULAR)
view = normalize(inData.view.xyz);
#endif
#ifdef _LIGHT0_SPOT
fvLightDir = g_lightPosition0.xyz - inData.vpos;
LightSpot_PPL_PS(inData.lightDir0.xyz, normal, view, (dot(normalize(fvLightDir),-g_lightDirection0.xyz)>0) * inData.lightDir0.w, g_lightColor0, g_lightSpecular0, myLight, mySpecular, g_spot1Map, inData.spotProjection1);
#ifdef __USE_SHADOWMAP
float shadow = GetShadowSpot(inData.shadowProjection);
myLight *= shadow;
#ifndef _MATERIAL_NOSPECULAR
mySpecular *= shadow;
#endif
#endif
#endif
#ifdef _LIGHT1_SPOT
fvLightDir = g_lightPosition1.xyz - inData.vpos;
LightSpot_PPL_PS(inData.lightDir1.xyz, normal, view, (dot(normalize(fvLightDir),-g_lightDirection1.xyz)>0) * inData.lightDir1.w, g_lightColor1, g_lightSpecular1, myLight, mySpecular, g_spot2Map, inData.spotProjection2);
#endif
outResult.color.rgb = myLight * saturate(diffuseColor.rgb) * g_diffuseColor.rgb;
#ifndef _MATERIAL_NOSPECULAR
float3 mySpecularColor = g_specularColor.rgb;
#ifdef _MAP_SPECULAR
mySpecular *= tex2D(g_specularMap,inData.uv0.xy ).rgb;
#endif
outResult.color.rgb += mySpecular * mySpecularColor;
#endif
/// Apply alpha from the material diffuse color
outResult.color.a = inData.color.a * g_diffuseColor.a * diffuseColor.a;
#if defined(_RIM_FADING)
outResult.color.a*=GetRimFading(g_cameraPos.xyz,inData.vpos.xyz,normal,g_RimFading.y);
#endif
}
///////////////////////////////////////////////
// Omni & Direct Per Vertex PixelShader
///////////////////////////////////////////////
void MultilayerPVL_MainPS( MultilayerPVL_OuputVS inData,out MultilayerPVL_OutputPS outResult)
{
outResult = (MultilayerPVL_OutputPS) 0;
/// Determinate the surface diffuse color
outResult.color = inData.color;
#ifndef _POINTSPRITE
// Retrieve the albedo texture
// As the usage of the second diffuse is encoded on the lightmap, must retrieve that first
#if defined (_MAP_LIGHTMAP) || defined (BLEND_DIFFUSE2_WITH_LIGHTMAPALPHA)
float4 lightMapColor;
lightMapColor = tex2D( g_lightMap, inData.uv2);
lightMapColor.rgb *= g_lightMapColor.rgb;
lightMapColor.rgb *= g_lightMapColor.a;
#endif // _MAP_LIGHTMAP
// Calculate the albedo color
// Start with the vertex color, separate color from alpha for best processing
// BLEND_DIFFUSE2_WITH_LIGHTMAPALPHA means that we merge to diffuse textures with the lighmap alpha color
float3 albedo = inData.color.rgb;
float opacity = inData.color.a;
#ifdef _MAP_DIFFUSE
#if defined(BLEND_DIFFUSE2_WITH_LIGHTMAPALPHA)
float4 albedoTexture = lerp( tex2D( g_diffuseMap, inData.uv0.xy ),
tex2D( g_diffuse2Map, inData.uv0.xy ),
lightMapColor.a);
#else
float4 albedoTexture = tex2D( g_diffuseMap, inData.uv0.xy );
#endif
albedo*=albedoTexture.rgb;
#if !defined(_ALPHACAMERALIGHTMASK) && !defined(_TRANSLUCENCY) && !defined(_ALPHAENVIROMENTMASK)
opacity*=albedoTexture.a;
#endif
#endif
#if defined(_MAP_DIFFUSE) && defined( _TRANSLUCENCY)
#define translucencyColor albedoTexture.a
#else
float translucencyColor = 0;
#endif
float3 normal = normalize(inData.normal);
/// Calculate lighting
// First we proceed with static lighting (lightmaps)
// For the case of having a directional light with shadow, we
// need the shadow value to apply it to the light map, before applying the ligh
#ifdef __USE_SHADOWMAP
#if defined ( _LIGHT0_DIRECTIONAL )
float shadow = GetShadowDirectional(inData.shadowProjection);
#elif defined (_LIGHT0_POINT )
float shadow = GetShadowPoint(inData.vpos.xyz);
#endif
#endif
/// First apply the light from the lightmap
#ifdef _MAP_LIGHTMAP
outResult.color.rgb = 2.0f * albedo * lightMapColor.rgb;
#ifdef _SHADOWLIGHTMAP
outResult.color.rgb*=shadow;
#endif
#else
outResult.color.rgb = 0;
#endif
// Now proceed with dynamic lighting
// We will acumulate the diffuse light on myLight and the specular light on mySpecular
float fNDotL = 0;
float3 myLight = 0;
float3 fvLightDir = 0;
float3 mySpecular = 0;
float3 view = 0;
#if !defined(_MATERIAL_NOSPECULAR)
view = normalize(inData.view);
#endif
/// Calculate directional lighting
#if defined (_LIGHT0_DIRECTIONAL) && !defined(_ONLYSHADOW)
LightDirectional_PVL_PS(-g_lightDirection0.xyz, normal, view, g_lightColor0.xyz, translucencyColor, g_lightSpecular0.xyz, myLight, mySpecular);
#ifdef __USE_SHADOWMAP
myLight *= shadow;
#ifndef _MATERIAL_NOSPECULAR
mySpecular *= shadow;
#endif
#endif
#endif
#ifdef _LIGHT1_DIRECTIONAL
LightDirectional_PVL_PS(-g_lightDirection1.xyz, normal, view, g_lightColor1.xyz, translucencyColor, g_lightSpecular1.xyz, myLight, mySpecular);
#endif
#ifdef _LIGHT2_DIRECTIONAL
LightDirectional_PVL_PS(-g_lightDirection2.xyz, normal, view, g_lightColor2.xyz, translucencyColor, g_lightSpecular2.xyz, myLight, mySpecular);
#endif
#ifdef _LIGHT3_DIRECTIONAL
LightDirectional_PVL_PS(-g_lightDirection3.xyz, normal, view, g_lightColor3.xyz, translucencyColor, g_lightSpecular3.xyz, myLight, mySpecular);
#endif
#define myAmbientLight g_ambient.rgb
/// Calculate point lights
#if defined (_LIGHT0_POINT) && !defined(_ONLYSHADOW)
AddPointLightContributionWorldSpace(g_lightPosition0.xyz, g_lightPosition0.w, g_lightColor0.rgb, g_lightSpecular0.rgb,
normal, view, inData.vpos.xyz, myLight, mySpecular );
#ifdef __USE_SHADOWMAP
myLight *= shadow;
#ifndef _MATERIAL_NOSPECULAR
mySpecular *= shadow;
#endif
#endif
#endif
#ifdef _LIGHT1_POINT
AddPointLightContributionWorldSpace(g_lightPosition1.xyz, g_lightPosition1.w, g_lightColor1.rgb, g_lightSpecular1.rgb,
normal, view, inData.vpos.xyz, myLight, mySpecular );
#endif
#ifdef _LIGHT2_POINT
AddPointLightContributionWorldSpace(g_lightPosition2.xyz, g_lightPosition2.w, g_lightColor2.rgb, g_lightSpecular2.rgb,
normal, view, inData.vpos.xyz, myLight, mySpecular );
#endif
#ifdef _LIGHT3_POINT
AddPointLightContributionWorldSpace(g_lightPosition3.xyz, g_lightPosition3.w, g_lightColor3.rgb, g_lightSpecular3.rgb,
normal, view, inData.vpos.xyz, myLight, mySpecular );
#endif
#ifdef _NON_LIGHTED
myLight = 1;
#endif
outResult.color.rgb += albedo * (myLight * g_diffuseColor.rgb + myAmbientLight * g_ambientColor.rgb);
/// If we got a specular map then proceed to get the specular color from it
#ifndef _MATERIAL_NOSPECULAR
float3 mySpecularColor = g_specularColor.rgb;
#ifdef _MAP_SPECULAR
mySpecularColor *= tex2D(g_specularMap,inData.uv0.xy ).rgb;
#endif
outResult.color.rgb+= mySpecular * mySpecularColor;
#endif
/// Apply the enviromental using the gloss map
#ifdef _MAP_PLANAR_REFLECTION
float3 reflection = tex2D(g_planarReflection, inData.uv1.xy/inData.uv1.z);
#ifdef _MAP_ENVIROMENTGLOSS
reflection *= tex2D( g_glossMap, inData.uv0.xy );
#endif
outResult.color.rgb += reflection;
#else
#ifdef _MAP_ENVIROMENT
#ifdef _MAP_ENVIROMENT_CUBE
float3 enviroment = texCUBE( g_enviromentMap, inData.uv1.xyz );
#else
float3 enviroment = tex2D( g_enviromentMap, inData.uv1.xy );
#endif
#ifdef _MAP_ENVIROMENTGLOSS
enviroment *= tex2D( g_glossMap, inData.uv0.xy );
#endif
outResult.color.rgb += enviroment * g_enviromentColor.rgb;
#endif
#endif
/// Apply emissive material color and map
/// Then saturate the color
outResult.color.rgb +=g_emissiveColor.rgb;
#ifdef _MAP_EMISSIVE
#ifdef _EMISSIVE_FLIPBOOK
float2 euv = inData.uv0.xy * g_textureTransform5.xy + g_textureTransform5.zw;
outResult.color.rgb+= tex2D( g_emissiveMap, euv).rgb;
#else
outResult.color.rgb+= tex2D( g_emissiveMap, inData.uv0.xy).rgb;
#endif
#endif
float fogValue;
#ifdef _VERTICAL_FOG
fogValue = saturate( (inData.vpos.y - g_verticalFogValues.x) / g_verticalFogValues.z);
outResult.color.rgb = lerp(g_verticalFogColor.rgb, outResult.color.rgb, fogValue);
#endif
#ifdef _PIXEL_FOG
ComputeFog(outResult.color,g_pixelFogColor.rgb,distance(g_cameraPos.xyz, inData.vpos.xyz),g_pixelFogOptions.x,g_pixelFogOptions.z);
#endif
// Calculate the output alpha from the calculated opacity and from the material diffuse color
outResult.color.a = opacity * g_diffuseColor.a;
#ifdef _CAMERA_LIGHT
float vdn = abs(dot(g_cameraDir,normal));
vdn = saturate(vdn);
vdn = 1 - vdn;
vdn *= vdn;
#ifdef _ALPHACAMERALIGHTMASK
vdn *= albedoTexture.a;
#endif
outResult.color.rgb += vdn * g_cameraLightColor.rgb;
#endif
#if defined(_RIM_FADING)
outResult.color.a*=GetRimFading(g_cameraPos.xyz,inData.vpos.xyz,normal,g_RimFading.y);
#endif
#else//POINTSPRITE
float2 uv = inData.uv;
outResult.color = tex2D( g_diffuseMap, uv);
#endif
}
///////////////////////////////////////////////
// Spot Per Vertex PixelShader
///////////////////////////////////////////////
void MultilayerPVLSpot_MainPS( MultilayerPVLSpot_OuputVS inData,out MultilayerPVL_OutputPS outResult)
{
outResult = (MultilayerPVL_OutputPS)0;
outResult.color = inData.color;
float4 diffuseColor = tex2D( g_diffuseMap, inData.uv0.xy );
/////// Calculate lighting
float fNDotL;
float fNDotLSpot;
float3 myLight = 0;
float3 fvLightDir;
float factor;
float4 lightColor;
float3 Half;
float3 mySpecular = 0;
float3 view = 0;
#if !defined(_MATERIAL_NOSPECULAR)
view = normalize(inData.view);
#endif
inData.normal = normalize(inData.normal);
#ifdef _LIGHT0_SPOT
fvLightDir = g_lightPosition0.xyz - inData.vpos;
if(dot(normalize(fvLightDir),-g_lightDirection0.xyz)>0)
LightSpot_PVL_PS(normalize(inData.lightDir0.xyz), inData.normal, view, inData.lightDir0.w, g_lightColor0, g_lightSpecular0, myLight, mySpecular, g_spot1Map, inData.spotProjection1);
#ifdef __USE_SHADOWMAP
float shadow = GetShadowSpot(inData.shadowProjection);
myLight *= shadow;
#ifndef _MATERIAL_NOSPECULAR
mySpecular *= shadow;
#endif
#endif
#endif
#ifdef _LIGHT1_SPOT
fvLightDir = g_lightPosition1.xyz - inData.vpos;
if(dot(normalize(fvLightDir),-g_lightDirection1.xyz)>0)
LightSpot_PVL_PS(normalize(inData.lightDir1.xyz), inData.normal, view, inData.lightDir1.w, g_lightColor1, g_lightSpecular1, myLight, mySpecular, g_spot2Map, inData.spotProjection2);
#endif
outResult.color.rgb = myLight * diffuseColor.rgb * g_diffuseColor.rgb;
/// If we got a specular map then proceed to get the specular color from it
#ifndef _MATERIAL_NOSPECULAR
#ifdef _MAP_SPECULAR
mySpecular *= tex2D(g_specularMap,inData.uv0.xy ).rgb;
#endif
outResult.color.rgb += mySpecular;
#endif
/// Apply alpha from the material diffuse color
outResult.color.a = inData.color.a * g_diffuseColor.a * diffuseColor.a;
#if defined(_RIM_FADING)
outResult.color.a*=GetRimFading(g_cameraPos.xyz,inData.vpos.xyz,inData.normal,g_RimFading.y);
#endif
}
#endif
#define _SIMPLE_CGFX
// In the case low, med or high shadows are used, we are using shadows!
#if defined (_SHADOW_LOW) || defined (_SHADOW_MED) || defined(_SHADOW_HI)
#define __USE_SHADOWMAP
#endif
//////////////////////////////////////
// MATRIX MULTIPLICATION
//////////////////////////////////////
float3 Transform(float3x3 mat, float3 v)
{
#if defined(_XENON)
[isolate]
{
return mul(mat, v);
}
#elif defined(_GCM)
return mul(v, mat);
#else
return mul(mat, v);
#endif
}
float4 Transform(float4x4 mat, float4 v)
{
#if defined(_XENON)
[isolate]
{
return mul(mat, v);
}
#elif defined(_GCM)
return mul(v, mat);
#else
return mul(mat, v);
#endif
}
float2 Transform(float2x2 mat, float2 v)
{
#if defined(_XENON)
[isolate]
{
return mul(mat, v);
}
#elif defined(_GCM)
return mul(v, mat);
#else
return mul(mat, v);
#endif
}
//this conversion will not deal with renormalizations because is a bad way to handle bad data passing to the shader.
//the main problem is that cg-compiler isn't as smart as hlsl-compiler dealing with already normalized vectors
float3x3 GetWorldToTangentMatrix(float3x3 worldmtx,float3 tangent, float3 normal)
{
float3x3 worldToTangent = 0;
worldToTangent[0] = normalize(Transform(worldmtx, tangent));
worldToTangent[2] = normalize(Transform(worldmtx, normal));
worldToTangent[1] = normalize(cross(worldToTangent[0], worldToTangent[2]));
return worldToTangent;
}
float4 TransformPlanarReflection(float4 inPos)
{
float4x4 matTexScale = 0;
#if !defined(_GCM)
matTexScale._m00 = 0.5f;
matTexScale._m11 = -.5f;
matTexScale._m22 = 0.0f;
matTexScale._m03 = 0.5f;
matTexScale._m13 = 0.5f;
matTexScale._m23 = 1.0f;
matTexScale._m33 = 1.0f;
#else
matTexScale._m00 = 0.5f;
matTexScale._m11 = -0.5f;
matTexScale._m22 = 0.0f;
matTexScale._m30 = 0.5f;
matTexScale._m31 = 0.5f;
matTexScale._m32 = 1.0f;
matTexScale._m33 = 1.0f;
#endif
return Transform(matTexScale,inPos);
}
uniform float4x4 g_skinMatrix[_MAXBONES]; ///< 128 Registers for skin bones
struct SKINVERTEX
{
float4 P;
float3 N;
float3 T;
};
SKINVERTEX SkinVertex(float3 p, float3 n, float3 t, float4 indices, float4 weights)
{
SKINVERTEX Out = (SKINVERTEX) 0;
for(int i = 0; i < 4; i++)
{
Out.P.xyz += Transform(g_skinMatrix[indices.x], float4(p,1)).xyz * weights.x;
Out.N += (float3)(Transform((float3x3) g_skinMatrix[indices.x], n) * weights.x);
#if !defined(SH_VERSION_SH1)
Out.T += (float3)(Transform((float3x3) g_skinMatrix[indices.x], t) * weights.x);
#endif
indices.xyzw = indices.yzwx;
weights.xyzw = weights.yzwx;
}
Out.P.w = 1;
Out.N = (float3)normalize(Out.N);
#if !defined(SH_VERSION_SH1)
Out.T = (float3)normalize(Out.T);
#endif
return Out;
}
//////////////////////////////////////
// VERTEX SHADER INPUT
//////////////////////////////////////
struct VSINPUT
{
float4 pos : POSITION; ///< Vertex position
#ifdef _USE_SKINMATRIX
float4 weight : BLENDWEIGHT;
float4 indices : BLENDINDICES;
#endif
#ifdef _HAS_NORMAL
float3 normal : NORMAL; ///< Vertex Normal
#endif
#ifdef _HAS_COLOR
float4 color : COLOR0; ///< Diffuse color of the vertex
#endif
float2 uv0 : TEXCOORD0; ///< UV Coordinates for diffuse, enviroment and normal map
#ifdef _HAS_UV1
float2 uv1 : TEXCOORD1; ///< UV Coordinates
#endif
};
//////////////////////////////////////
// END VERTEX SHADER INPUT
//////////////////////////////////////
//////////////////////////////////////
// VERTEX SHADER OUTPUT
//////////////////////////////////////
struct VSOUTPUT
{
float4 hpos : POSITION; ///< Clip space transformed vertex position
float4 color : COLOR0; ///< Vertex color
float4 specular : COLOR1;
#ifdef _PS3
float3 uv0 : TEXCOORD0; ///< UV Coordinates used by the diffuse texture
#else
float3 uv0 : TEXCOORD0_centroid; ///< UV Coordinates used by the diffuse texture
#endif
float3 uv1 : TEXCOORD1;
#ifdef _PS3
float4 vpos : TEXCOORD2; ///< Position of the vertex in world space, and shadowprojection distance
#else
float4 vpos : TEXCOORD2_centroid; ///< Position of the vertex in world space, and shadowprojection distance
#endif
#ifdef _LIGHT0_SPOT
float4 spot1Projection : TEXCOORD3; ///< Shadow map projection
#endif
#ifdef _LIGHT1_SPOT
float4 spot2Projection : TEXCOORD4; ///< Shadow map projection
float4 color2 : TEXCOORD5;
float4 specular2 : TEXCOORD6;
#endif
#if defined(__USE_SHADOWMAP) && (defined(_LIGHT0_DIRECTIONAL) || defined(_LIGHT0_SPOT))
#ifdef _PS3
float4 shadowProjection : TEXCOORD4; ///< Shadow map projection
#else
float4 shadowProjection : TEXCOORD4_centroid; ///< Shadow map projection
#endif
#endif
float4 refl : TEXCOORD7; ///< UV Coordinates
};
//////////////////////////////////////
// END VERTEX SHADER OUTPUT
//////////////////////////////////////
//////////////////////////////////////
// LIGHTING
//////////////////////////////////////
/// Tongas upload variables
float4 g_ambient;
float4 g_ambientColor;
float4 g_diffuseColor;
float4 g_emissiveColor;
float4 g_specularColor;
//////////////////////////////////////
// LIGHTING INFO
float4 g_lightDirection0;
float4 g_lightPosition0;
float4 g_lightColor0;
float4 g_lightSpecular0;
#if defined(_LIGHT1_POINT) || defined(_LIGHT1_DIRECTIONAL) || defined(_LIGHT1_SPOT)
float4 g_lightDirection1;
float4 g_lightPosition1;
float4 g_lightColor1;
float4 g_lightSpecular1;
#endif
//////////////////////////////////////
// LIGHTING FUNCTIONS
void LightSpot_VS(float3 iDir, float Range, float3 normal, float3 view, float3 iD, float4 iS, inout float3 oD, inout float3 oS)
{
float3 Factor = length(iDir.xyz);
Factor = ( 1.0f - (Factor / Range) );
float3 fvLightDir = normalize(iDir);
float fNDotL = dot(normal, fvLightDir);
oD += iD * saturate(fNDotL) * Factor;
#ifndef _MATERIAL_NOSPECULAR
float3 Half = normalize(fvLightDir+view);
oS += Factor * iS.xyz * pow(saturate(dot(Half,normal)), g_specularColor.a);
#endif
}
//////////////////////////////////////
// END LIGHTING
//////////////////////////////////////
uniform float4x4 g_matTextureProjection;
uniform float4 g_shadowmapOptions;
uniform float4 g_texelSize89;
#define g_ShadowmapFactor (1-g_shadowmapOptions.x) /// default 0.0
#define g_ShadowmapZBias (g_shadowmapOptions.y) /// default -0.001
uniform sampler2D g_shadowMap : register(s9);
uniform samplerCUBE g_shadowCubeMap : register(s9);
////////////////////////////////////
// DIRECTIONAL
float SampleShadowTest(float4 ShadowTexC)
{
#if defined(_XENON) || defined(_SHADOWMAP_FLOAT) //Xenon & ATI
return tex2D(g_shadowMap, ShadowTexC.xy).r >= ShadowTexC.z;
#else //nVidia
return tex2Dproj(g_shadowMap, ShadowTexC).r;
#endif
}
float GetShadowDirectional(float4 TexCoords)
{
float4 ShadowTexC = TexCoords;
ShadowTexC.xy = 0.5 * TexCoords.xy + float2( 0.5, 0.5 );
ShadowTexC.y = 1.f - ShadowTexC.y;
#ifdef _PS3
ShadowTexC.z = ShadowTexC.z * .5f + .5f;
#endif
#ifdef _XENON
ShadowTexC.xyz = ShadowTexC.xyz / ShadowTexC.w;
// [BP] On xbox360 we are getting projected distances that are higher than 1
// as they are not being cut by the far plane of the light frustum
// still we need to study more this effect, even check if it can be done on vertex
// shader stage to save gpu process
ShadowTexC.z = min(1,ShadowTexC.z); // Check that z the minimum value to 1
#endif
#ifdef _DEBUG_SHADOWMAPS
//Dark regions out of shadow projection
if(ShadowTexC.x < 0 ||
ShadowTexC.y < 0 ||
ShadowTexC.x > 1 ||
ShadowTexC.y > 1)
return 0;
#endif
ShadowTexC.z += g_ShadowmapZBias;
ShadowTexC.w = 1;
#if defined(SH_VERSION_SH2) || defined(_SHADOW_LOW)
return saturate(SampleShadowTest(ShadowTexC) + g_ShadowmapFactor);
#else
float4 tX = float4(g_texelSize89.z, 0, 0, 0) * 2;
float4 tY = float4(0, g_texelSize89.w, 0, 0) * 2;
float accum = 0;
#if defined(_SHADOW_MED)
accum += SampleShadowTest(ShadowTexC + tX * -.5 + tY * -.5);
accum += SampleShadowTest(ShadowTexC + tX * .5 + tY * -.5);
accum += SampleShadowTest(ShadowTexC + tX * -.5 + tY * .5);
accum += SampleShadowTest(ShadowTexC + tX * .5 + tY * .5);
return saturate((accum/4.f) + g_ShadowmapFactor);
#elif defined(_SHADOW_HI)
accum += SampleShadowTest(ShadowTexC + tX * -1 + tY * -1);
accum += SampleShadowTest(ShadowTexC + tX * 0 + tY * -1);
accum += SampleShadowTest(ShadowTexC + tX * 1 + tY * -1);
accum += SampleShadowTest(ShadowTexC + tX * -1 + tY * 0);
accum += SampleShadowTest(ShadowTexC + tX * 0 + tY * 0);
accum += SampleShadowTest(ShadowTexC + tX * 1 + tY * 0);
accum += SampleShadowTest(ShadowTexC + tX * -1 + tY * 1);
accum += SampleShadowTest(ShadowTexC + tX * 0 + tY * 1);
accum += SampleShadowTest(ShadowTexC + tX * 1 + tY * 1);
return saturate((accum/9.f) + g_ShadowmapFactor);
#else
return 1;
#endif
#endif
}
/////////////////////////////////
// SPOT
//[VC]: why this is just a copy paste from spotdirectional???
float GetShadowSpotSample(float4 ShadowTexC)
{
float shadow;
#if defined(_XENON) || defined(_SHADOWMAP_FLOAT) //Xenon & ATI
float a = tex2D(g_shadowMap, ShadowTexC.xy).r > ShadowTexC.z;
float b = tex2D(g_shadowMap, ShadowTexC.xy + float2(g_texelSize89.z, 0)).r > ShadowTexC.z;
float c = tex2D(g_shadowMap, ShadowTexC.xy + float2(0, g_texelSize89.w)).r > ShadowTexC.z;
float d = tex2D(g_shadowMap, ShadowTexC.xy + float2(g_texelSize89.z, g_texelSize89.w)).r > ShadowTexC.z;
#if defined(SH_VERSION_SH2)
return a;
#endif
// transform to texel space
float2 texelpos = (1.f/g_texelSize89.zw) * ShadowTexC;
// Determine the lerp amounts
float2 lerps = frac( texelpos );
// lerp between the shadow values to calculate our light amount
shadow = lerp( lerp( a, b, lerps.x ),
lerp( c, d, lerps.x ),
lerps.y );
return shadow;
#else //nVidia
shadow = tex2Dproj(g_shadowMap, ShadowTexC).r;
#endif
return shadow;
}
float GetShadowSpot(float4 TexCoords)
{
float4 ShadowTexC = TexCoords;
ShadowTexC.xy = 0.5 * TexCoords.xy / TexCoords.w + float2( 0.5, 0.5 );
ShadowTexC.y = 1.0f - ShadowTexC.y;
//not needed for spot lights
#ifdef _PS3
//ShadowTexC.z = ShadowTexC.z * .5f + .5f;
#endif
#ifdef _DEBUG_SHADOWMAPS
//Dark regions out of shadow projection
if(ShadowTexC.x < 0 ||
ShadowTexC.y < 0 ||
ShadowTexC.x > 1 ||
ShadowTexC.y > 1)
return 0;
#endif
ShadowTexC.z += g_ShadowmapZBias;
ShadowTexC.z /= ShadowTexC.w;
ShadowTexC.w = 1;
#if defined(SH_VERSION_SH2) || defined(_SHADOW_LOW)
return saturate(GetShadowSpotSample(ShadowTexC) + g_ShadowmapFactor);
#endif
float4 tX = float4(g_texelSize89.z, 0, 0, 0) * 1;
float4 tY = float4(0, g_texelSize89.w, 0, 0) * 1;
float accum = 0;
#if defined(_SHADOW_MED)
accum += GetShadowSpotSample(ShadowTexC + tX * -.5 + tY * -.5);
accum += GetShadowSpotSample(ShadowTexC + tX * .5 + tY * -.5);
accum += GetShadowSpotSample(ShadowTexC + tX * -.5 + tY * .5);
accum += GetShadowSpotSample(ShadowTexC + tX * .5 + tY * .5);
return saturate((accum/4.f) + g_ShadowmapFactor);
#endif
#if defined(_SHADOW_HI)
accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY * -1);
accum += GetShadowSpotSample(ShadowTexC + tX * 0 + tY * -1);
accum += GetShadowSpotSample(ShadowTexC + tX * 1 + tY * -1);
accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY * 0);
accum += GetShadowSpotSample(ShadowTexC + tX * 0 + tY * 0);
accum += GetShadowSpotSample(ShadowTexC + tX * 1 + tY * 0);
accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY * 1);
accum += GetShadowSpotSample(ShadowTexC + tX * 0 + tY * 1);
accum += GetShadowSpotSample(ShadowTexC + tX * 1 + tY * 1);
return saturate((accum/9.f) + g_ShadowmapFactor);
#endif
return 1;
}
/////////////////////////////////
// POINT
float GetShadowPointSample(float3 Pos)
{
float shadow = 1;
#ifdef _LIGHT0_POINT
shadow = texCUBE(g_shadowCubeMap, Pos.xyz-g_lightPosition0.xyz).r > (length(Pos.xyz-g_lightPosition0.xyz) * g_lightPosition0.w) + g_ShadowmapZBias;
#endif
return shadow;
}
float GetShadowPoint(float3 Pos)
{
return saturate(GetShadowPointSample(Pos) + g_ShadowmapFactor);
}
//////////////////////////////////////
//VERTEX SHADER
//////////////////////////////////////
//////////////////////////////////////
// VERTEX SHADER CONSTANTS
//float4x4 g_matWorld, g_matWorldTR, g_matWorldView, g_matWorldViewIT, g_matWorldViewProjection;
float4x4 g_matWorld, g_matWorldView, g_matWorldViewProjection;
float4x4 g_matTexture0, g_matTexture1, g_matTexture2, g_matTexture3;
float4 g_cameraPos;
//////////////////////////////////////
// VERTEX SHADER
VSOUTPUT main_VS(VSINPUT IN)
{
VSOUTPUT OUT = (VSOUTPUT) 0;
OUT.color = float4(1,1,1,1);
float3 normal = float3(0,0,1);
#ifdef _HAS_NORMAL
normal = normalize(IN.normal);
#endif
#ifdef _HAS_COLOR
OUT.color = IN.color;
#endif
#ifdef _USE_SKINMATRIX
SKINVERTEX v = SkinVertex(IN.pos, normal,0, IN.indices, IN.weight);
float4 position = v.P;
normal = v.N;
#else
float4 position = IN.pos;
#endif //_USE_SKINMATRIX
/// Transform the position to clip space
OUT.hpos = Transform(g_matWorldViewProjection, position);
OUT.vpos = Transform(g_matWorld, position);
OUT.uv0 = float3(IN.uv0, 1);
OUT.uv1 = float3(IN.uv0, 1);
#ifdef _HAS_UV1
OUT.uv1 = float3(IN.uv1, 1);
#endif
#ifndef _NON_LIGHTED
float fNDotL = 0;
float3 myLight = 0;
float3 fvLightDir = 0;
float lightFactor = 0;
float3 Half = 0;
float3 mySpecular = 0;
float3 view = -normalize(OUT.vpos-g_cameraPos);
#ifdef _LIGHT0_DIRECTIONAL
fNDotL = dot(normal, -g_lightDirection0);
myLight += g_lightColor0.rgb * saturate(max(0, fNDotL));
#ifndef _MATERIAL_NOSPECULAR
Half = normalize(-g_lightDirection0 + view);
mySpecular += g_lightSpecular0 * pow(max(0, dot(Half,normal)), g_specularColor.a);
#endif
#ifdef __USE_SHADOWMAP
OUT.shadowProjection = Transform(g_matTextureProjection, float4(position.xyz,1));
#endif
#endif
#ifdef _LIGHT1_DIRECTIONAL
fNDotL = dot(normal, -g_lightDirection1);
myLight += g_lightColor1.rgb * saturate(max(0, fNDotL));
#ifndef _MATERIAL_NOSPECULAR
Half = normalize(-g_lightDirection1 + view);
mySpecular += g_lightSpecular1 * pow(max(0, dot(Half,normal)), g_specularColor.a);
#endif
#endif
#ifdef _LIGHT0_POINT
lightFactor = length(g_lightPosition0.xyz - OUT.vpos);
lightFactor = saturate(1.0f - (lightFactor / g_lightPosition0.w));
fvLightDir = normalize(g_lightPosition0.xyz - OUT.vpos);
fNDotL = dot(normal, fvLightDir);
myLight += g_lightColor0.rgb * saturate(max(0, fNDotL)) * lightFactor;
#ifndef _MATERIAL_NOSPECULAR
Half = normalize(fvLightDir+view);
mySpecular += lightFactor * g_lightSpecular0 * pow(max(0, dot(Half,normal)), g_specularColor.a);
#endif
#endif
#ifdef _LIGHT1_POINT
lightFactor = length(g_lightPosition1.xyz - OUT.vpos);
lightFactor = saturate(1.0f - (lightFactor / g_lightPosition1.w));
fvLightDir = normalize(g_lightPosition1.xyz - OUT.vpos);
fNDotL = dot(normal, fvLightDir);
myLight += g_lightColor1.rgb * saturate(max(0, fNDotL)) * lightFactor;
#ifndef _MATERIAL_NOSPECULAR
Half = normalize(fvLightDir+view);
mySpecular += lightFactor * g_lightSpecular1 * pow(max(0, dot(Half,normal)), g_specularColor.a);
#endif
#endif
#ifdef _LIGHT0_SPOT
OUT.color.xyz = OUT.specular.xyz = 0;
LightSpot_VS(g_lightPosition0.xyz - OUT.vpos.xyz, g_lightPosition0.w, normal, view, g_lightColor0.rgb, g_lightSpecular0, OUT.color.xyz, OUT.specular.xyz);
OUT.spot1Projection = Transform(g_matTexture2, float4(position.xyz,1));
OUT.color *= g_diffuseColor;
OUT.specular *= g_specularColor;
#ifdef __USE_SHADOWMAP
OUT.shadowProjection = Transform(g_matTextureProjection, float4(position.xyz,1));
#endif
#endif
#ifdef _LIGHT1_SPOT
OUT.color2.xyz = OUT.specular2.xyz = 0;
LightSpot_VS(g_lightPosition1.xyz - OUT.vpos.xyz, g_lightPosition1.w, normal, view, g_lightColor1.rgb, g_lightSpecular0, OUT.color2.xyz, OUT.specular2.xyz);
OUT.spot2Projection = Transform(g_matTexture3, float4(position.xyz,1));
OUT.color2 *= g_diffuseColor;
OUT.specular2 *= g_specularColor;
#endif
#ifndef _LIGHT0_SPOT
OUT.color.rgb *= myLight * g_diffuseColor;
#ifndef _MATERIAL_NOSPECULAR
OUT.specular.rgb = mySpecular * g_specularColor.rgb;
#endif
#endif
#else
OUT.color.rgb = g_diffuseColor;
#endif //_NON_LIGHTED
OUT.color.a = g_diffuseColor.a;
return( OUT );
}
//////////////////////////////////////
// END VERTEX SHADER
//////////////////////////////////////
//////////////////////////////////////
//PIXEL SHADERS
//////////////////////////////////////
//////////////////////////////////////
// SAMPLERS
sampler g_layer0 : register(s0);
sampler g_spotMap1 : register(s8);
sampler g_spotMap2 : register(s9);
///////////////////////////////////////////////
// PIXEL SHADER
///////////////////////////////////////////////
float4 main_PS( VSOUTPUT IN
#if defined(_MRT1)
,out float4 oColor1 : COLOR1
#endif
#if defined(_MRT2)
,out float4 oColor2 : COLOR2
#endif
#if defined(_MRT3)
,out float4 oColor3 : COLOR3
#endif
) : COLOR0
{
float3 shadow = 1;
float4 OUT = 0;
float4 Layer0 = tex2D(g_layer0, IN.uv0);
OUT.a = IN.color.a * Layer0.a;
#ifndef _LIGHT0_SPOT
OUT.rgb = IN.color * Layer0;
#ifndef _MATERIAL_NOSPECULAR
OUT.rgb += IN.specular.xyz;
#endif
#ifdef __USE_SHADOWMAP
#ifdef _LIGHT0_DIRECTIONAL
shadow = GetShadowDirectional(IN.shadowProjection);
#endif
#ifdef _LIGHT0_POINT
shadow = GetShadowPoint(IN.vpos.xyz);
#endif
#endif
#endif
#ifdef _LIGHT0_SPOT
float3 spot1 = tex2Dproj(g_spotMap1, IN.spot1Projection);
OUT.rgb = IN.color * spot1 * Layer0;
#ifndef _MATERIAL_NOSPECULAR
OUT.rgb += IN.specular.xyz * spot1;
#endif
#ifdef __USE_SHADOWMAP
shadow = GetShadowSpot(IN.shadowProjection);
#endif
#endif
#ifdef _LIGHT1_SPOT
float3 spot2 = tex2Dproj(g_spotMap2, IN.spot2Projection);
OUT.rgb += IN.color2 * spot2 * Layer0;
#ifndef _MATERIAL_NOSPECULAR
OUT.rgb += IN.specular2.xyz * spot2;
#endif
#endif
#ifdef __USE_SHADOWMAP
#ifndef _LIGHT0_SPOT
shadow += Layer0 * g_ambient.rgb * g_ambientColor;
#endif
OUT.rgb *= shadow;
#elif !defined(_LIGHT0_SPOT)
OUT.rgb += Layer0 * g_ambient.rgb * g_ambientColor;
#endif
return OUT;
}
struct VSI_SCREEN
{
float4 pos : POSITION;
float4 color : COLOR0;
float2 uv : TEXCOORD0;
};
struct VSO_SCREEN
{
float4 pos : POSITION;
#ifdef _PS3
float2 uv : TEXCOORD0;
#else
float2 uv : TEXCOORD0_centroid;
#endif
};
////////////////////////////////////////////////////
// bloom3_filterScreen
////////////////////////////////////////////////////
sampler sceneTexture : register(s0);
sampler brightTexture : register(s1);
#ifndef _GCM
float4 g_screenFilterValues[9]; ///< 9 tap distance filter values
#else
DECLARE_GCM_FILTERVALUES9
#endif
float4 g_bloomBrightness; ///< Brightness fitering options
float4 g_texelSize01;
VSO_SCREEN vsFilterScreen( VSI_SCREEN IN )
{
VSO_SCREEN OUT = (VSO_SCREEN) 0;
OUT.pos = IN.pos;
OUT.uv = IN.uv;
return OUT;
}
float4 psFilterScreen( VSO_SCREEN IN
#if defined(_MRT1)
,out float4 oColor1 : COLOR1
#endif
#if defined(_MRT2)
,out float4 oColor2 : COLOR2
#endif
#if defined(_MRT3)
,out float4 oColor3 : COLOR3
#endif
) : color
{
#ifdef _GCM
INIT_GCM_FILTERVALUES9
#endif
float4 color = { 0.0f, 0.0f, 0.0f, 0.0f };
float2 uv;
/// Compine the textures in a 9 tap distance filter
//float totalLum = 0;
for( int i = 0; i < 9; i++ )
{
uv = IN.uv + g_screenFilterValues[i].xy * 2 + 2 *g_texelSize01.xy;
color += tex2D( sceneTexture, uv) *
tex2D( brightTexture, uv).g;
// totalLum +=(color.r+color.g+color.b) *0.33;
}
color /= 9; //totalLum; //9.0f;
/// Determine the brightness of this particular pixel.
float luminance = dot( color.rgb, g_bloomBrightness.rgb);
/// If this pixel satisfies the bright pass threshold it will
/// be > 0.0 after this operation
luminance = max( 0.0f, luminance - g_bloomBrightness.w);
/// Muliply by the above predicate, use the sign() intrinsic
/// to make sure that luminance is either 0.0 or 1.0, thus not
/// scaling any bright pixels that are needed.
color.rgb *= sign( luminance );
/// Write the colour to the bright-pass render target
color.a = 1.0f;
return color;
}
////////////////////////////////////////////////////
// bloom3_gaussian
////////////////////////////////////////////////////
struct VS_OUTPUT
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
sampler tex0 : register( s0 ); ///< Whatever texture is set using IDirect3DDevice9::SetTexture( 0, ... )
// -------------------------------------------------------------
// vertex shader function (input channels)
// -------------------------------------------------------------
VS_OUTPUT vsGaussianBlur(float4 pos : POSITION, float2 uv : TEXCOORD0)
{
VS_OUTPUT Out;
Out.pos.xy = pos.xy;
Out.pos.z = 0.5f;
Out.pos.w = 1.0f;
Out.uv = uv;
return Out;
}
float4 psGaussianBlur( in float2 t : TEXCOORD0
#if defined(_MRT1)
,out float4 oColor1 : COLOR1
#endif
#if defined(_MRT2)
,out float4 oColor2 : COLOR2
#endif
#if defined(_MRT3)
,out float4 oColor3 : COLOR3
#endif
) : COLOR
{
#ifdef _GCM
INIT_GCM_FILTERVALUES9
#endif
float4 color = { 0.0f, 0.0f, 0.0f, 0.0f };
//float2 of = float2(g_texelSize01.x, - 1 * g_texelSize01.y);
float fc = 0;
float2 offset;
/*
for( int i = 0; i <3; i++ )
{
of.x = -1 * g_texelSize01.x;
// color += tex2D( tex0, float2(t.x,t.y) + tc + float2( g_screenFilterValues[i].x, g_screenFilterValues[i].y ) ) ; g_screenFilterValues[i].z;
for (int j= 0; j < 3; j++)
{
of.x+= g_texelSize01.x;
offset = of*5;
color += tex2D( tex0, t + offset + float2(g_texelSize01.x*2, g_texelSize01.y*2));
}
of.y +=g_texelSize01.y;
}
/*
float2 circle[9] = {
float2 (-1,-1),
float2 (0,-1),
float2 (1, -1),
float2 (-1,0),
float2 (0,0),
float2 (1, 0),
float2 (-1,1),
float2 (0,1),
float2 (1, 1)
};
float factor[9] = {
3,9,3,
9,1,9,
3,9,3
};
/**/
float2 of = float2(g_texelSize01.x, 1 * g_texelSize01.y);
for( int i = 0; i <9; i++ )
{
//color += tex2D( tex0, t + of * g_screenFilterValues[i].xy * g_screenFilterValues[i].w + float2(g_texelSize01.x*2, g_texelSize01.y*2)) * g_screenFilterValues[i].z;
color += tex2D( tex0, t + of * g_screenFilterValues[i].xy * g_screenFilterValues[i].w + 2 * g_texelSize01.xy) * g_screenFilterValues[i].z;
//color += tex2D( tex0, t + of * circle[i]* 2 + float2(g_texelSize01.x*2, g_texelSize01.y*2)) * factor[i];
fc+=g_screenFilterValues[i].z;
//fc+=factor[i];
}
color/=fc;
color.a = 1;
return color;
}
////////////////////////////////////////////////////
// bloom3_render
////////////////////////////////////////////////////
sampler bloom : register(s0);
sampler original_scene : register(s1);
sampler blur : register(s2);
sampler focusBlur : register(s3);
float4 g_bloomRenderOptions;
float4 g_auxiliary0;
#define g_exposure g_bloomRenderOptions.x
#define g_blendFactor g_bloomRenderOptions.y
#define g_doBlur g_bloomRenderOptions.z
#define g_blurEffect g_bloomRenderOptions.w
VSO_SCREEN vsRenderBloom( VSI_SCREEN IN )
{
VSO_SCREEN OUT = (VSO_SCREEN) 0;
OUT.pos = IN.pos;
OUT.pos.z = 0.5f;
OUT.pos.w = 1;
OUT.uv = IN.uv;
return OUT;
}
float4 g_kernelValues;
//float4 g_texelSize01;
float4 psRenderBloom( in float2 t : TEXCOORD0
#if defined(_MRT1)
,out float4 oColor1 : COLOR1
#endif
#if defined(_MRT2)
,out float4 oColor2 : COLOR2
#endif
#if defined(_MRT3)
,out float4 oColor3 : COLOR3
#endif
) : COLOR0
{
t.x+=sin(g_kernelValues.y+t.x*16) * g_texelSize01.z * 4 * g_blurEffect;
t.y+=cos(g_kernelValues.y+t.y*16) * g_texelSize01.w * 4 * g_blurEffect;
float4 c = tex2D( original_scene, t );
/// Apply focus blur effect
if (g_doBlur > 0)
{
float blurV = tex2D(focusBlur,t).r;
if (blurV > 0)
{
//blurV = blurV;
c = lerp(c,tex2D(blur,t),blurV);
}
}
c = c * g_exposure + g_blendFactor * tex2D( bloom, t);
/*
c.r += sin(g_kernelValues.y*1.5) *0.5f * g_blurEffect;
c.g += cos(g_kernelValues.y*2+23) * 0.5f * g_blurEffect;
c.b += sin(g_kernelValues.y*1-15) * 0.5f * g_blurEffect;
/**/
/**/
c.r = lerp(c.r,1 - c.r,g_auxiliary0.x*0.5);
c.g = lerp(c.g,1 - c.g,g_auxiliary0.y*0.5);
c.b = lerp(c.b,1 - c.b,g_auxiliary0.z*0.5);
/**/
c.a = 1.0f;
return c;
}
struct VSI_SCREEN
{
float4 pos : POSITION;
float4 color : COLOR0;
float2 uv : TEXCOORD0;
};
struct VSO_SCREEN
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
////////////////////////////////////////////////////
// Vertex Shaders
////////////////////////////////////////////////////
float4 g_bloomBrightness;
float4 g_texelSize01;
void main_VS(float4 iPos : POSITION,
float2 iTC : TEXCOORD0,
out float4 oPos : POSITION,
out float2 oTC[4] : TEXCOORD0)
{
oPos = iPos;
float2 texelSize = g_texelSize01.xy;
float2 u = float2(1.f, 0) * g_bloomBrightness.w;
float2 v = float2(0, 1.f) * g_bloomBrightness.w;
oTC[0] = (iTC - u - v) + texelSize.xy;
oTC[1] = (iTC - u + v) + texelSize.xy;
oTC[2] = (iTC + u - v) + texelSize.xy;
oTC[3] = (iTC + u + v) + texelSize.xy;
}
void BrightPass_VS(float4 iPos : POSITION,
float2 iTC : TEXCOORD0,
out float4 oPos : POSITION,
out float2 oTC[2] : TEXCOORD0)
{
oPos = iPos;
float2 texelSize = g_texelSize01.xy;
float2 u = float2(1.f, 0) * g_bloomBrightness.w;
float2 v = float2(0, 1.f) * g_bloomBrightness.w;
oTC[0] = (iTC - u - v) + texelSize.xy;
oTC[1] = (iTC - u + v) + texelSize.xy;
}
void mainFinal_VS(float4 iPos : POSITION,
float2 iTC : TEXCOORD0,
out float4 oPos : POSITION,
out float2 oTC : TEXCOORD0,
out float2 oTC1 : TEXCOORD1)
{
oPos = iPos;
oTC = iTC + (g_texelSize01.xy * .5f);
oTC1 = iTC + (g_texelSize01.zw * .5f);
}
////////////////////////////////////////////////////
// Pixel Shaders
////////////////////////////////////////////////////
sampler Tex : register(s0);
sampler Bloom : register(s1);
float4 main_PS( float2 iTC[4] : TEXCOORD0
#if defined(_MRT1)
,out float4 oColor1 : COLOR1
#endif
#if defined(_MRT2)
,out float4 oColor2 : COLOR2
#endif
#if defined(_MRT3)
,out float4 oColor3 : COLOR3
#endif
) : COLOR0
{
float3 colorSum = 0;
for(int i = 0; i < 4; i++)
colorSum += tex2D(Tex, iTC[i]).xyz * .25f;
return float4(colorSum, 1);
}
float4 BrightPass_PS(float2 tc : TEXCOORD0,
float2 tc1 : TEXCOORD1
#if defined(_MRT1)
,out float4 oColor1 : COLOR1
#endif
#if defined(_MRT2)
,out float4 oColor2 : COLOR2
#endif
#if defined(_MRT3)
,out float4 oColor3 : COLOR3
#endif
) : COLOR0
{
float3 c = tex2D(Tex, tc);
if(dot(c, float3(.33,.33,.33)) < g_bloomBrightness.x)
c = 0;
return float4(c,1);
}
float4 FinalPass_PS( float2 tc : TEXCOORD0,
float2 tc1 : TEXCOORD1
#if defined(_MRT1)
,out float4 oColor1 : COLOR1
#endif
#if defined(_MRT2)
,out float4 oColor2 : COLOR2
#endif
#if defined(_MRT3)
,out float4 oColor3 : COLOR3
#endif
) : COLOR0
{
float3 b = tex2D(Bloom, tc1).rgb * g_bloomBrightness.y;
return float4(b,1);
}
float4 g_texelSize01;
void main_VS(float3 iPos : POSITION,
float2 iTC : TEXCOORD0,
out float4 oPos : POSITION,
out float2 oTC : TEXCOORD0)
{
oPos = float4(iPos.xyz, 1);
oTC = iTC + g_texelSize01.xy * .5f;
}
sampler2D tex : register(s0);
float4 g_specialVector1;
float4 main_PS( float2 tc : TEXCOORD0
#if defined(_MRT1)
,out float4 oColor1 : COLOR1
#endif
#if defined(_MRT2)
,out float4 oColor2 : COLOR2
#endif
#if defined(_MRT3)
,out float4 oColor3 : COLOR3
#endif
) : COLOR
{
return float4(tex2D(tex, tc).xyz, g_specialVector1.w);
}
#define _DEPTH_OF_FIELD_CGFX
//////////////////////////////////////
// MATRIX MULTIPLICATION
//////////////////////////////////////
float3 Transform(float3x3 mat, float3 v)
{
#if defined(_XENON)
[isolate]
{
return mul(mat, v);
}
#elif defined(_GCM)
return mul(v, mat);
#else
return mul(mat, v);
#endif
}
float4 Transform(float4x4 mat, float4 v)
{
#if defined(_XENON)
[isolate]
{
return mul(mat, v);
}
#elif defined(_GCM)
return mul(v, mat);
#else
return mul(mat, v);
#endif
}
float2 Transform(float2x2 mat, float2 v)
{
#if defined(_XENON)
[isolate]
{
return mul(mat, v);
}
#elif defined(_GCM)
return mul(v, mat);
#else
return mul(mat, v);
#endif
}
//this conversion will not deal with renormalizations because is a bad way to handle bad data passing to the shader.
//the main problem is that cg-compiler isn't as smart as hlsl-compiler dealing with already normalized vectors
float3x3 GetWorldToTangentMatrix(float3x3 worldmtx,float3 tangent, float3 normal)
{
float3x3 worldToTangent = 0;
worldToTangent[0] = normalize(Transform(worldmtx, tangent));
worldToTangent[2] = normalize(Transform(worldmtx, normal));
worldToTangent[1] = normalize(cross(worldToTangent[0], worldToTangent[2]));
return worldToTangent;
}
float4 TransformPlanarReflection(float4 inPos)
{
float4x4 matTexScale = 0;
#if !defined(_GCM)
matTexScale._m00 = 0.5f;
matTexScale._m11 = -.5f;
matTexScale._m22 = 0.0f;
matTexScale._m03 = 0.5f;
matTexScale._m13 = 0.5f;
matTexScale._m23 = 1.0f;
matTexScale._m33 = 1.0f;
#else
matTexScale._m00 = 0.5f;
matTexScale._m11 = -0.5f;
matTexScale._m22 = 0.0f;
matTexScale._m30 = 0.5f;
matTexScale._m31 = 0.5f;
matTexScale._m32 = 1.0f;
matTexScale._m33 = 1.0f;
#endif
return Transform(matTexScale,inPos);
}
uniform float4x4 g_skinMatrix[_MAXBONES]; ///< 128 Registers for skin bones
struct SKINVERTEX
{
float4 P;
float3 N;
float3 T;
};
SKINVERTEX SkinVertex(float3 p, float3 n, float3 t, float4 indices, float4 weights)
{
SKINVERTEX Out = (SKINVERTEX) 0;
for(int i = 0; i < 4; i++)
{
Out.P.xyz += Transform(g_skinMatrix[indices.x], float4(p,1)).xyz * weights.x;
Out.N += (float3)(Transform((float3x3) g_skinMatrix[indices.x], n) * weights.x);
#if !defined(SH_VERSION_SH1)
Out.T += (float3)(Transform((float3x3) g_skinMatrix[indices.x], t) * weights.x);
#endif
indices.xyzw = indices.yzwx;
weights.xyzw = weights.yzwx;
}
Out.P.w = 1;
Out.N = (float3)normalize(Out.N);
#if !defined(SH_VERSION_SH1)
Out.T = (float3)normalize(Out.T);
#endif
return Out;
}
////////////////////////////////////////////////////
// Vertex Shaders
////////////////////////////////////////////////////
float4 FocusZ : register(c0);
float4 g_texelSize01, g_texelSize23;
void DOF_VS(float4 iPos : POSITION,
float2 iTC : TEXCOORD0,
out float4 oPos : POSITION,
out float2 oTC : TEXCOORD0)
{
oPos = iPos;
oTC = iTC;
}
float4x4 g_matWorldViewProjection, g_matWorldView;
float3x3 g_matWorld;
float4 g_kernelValues;
static float4 vFocalPlane = float4(0,0,1,1);
static float fHyperfocalDistance = 0.1f;
static float MaxBlurFactor = 3.0f / 4.0f;
void Object_VS(float4 iPos : POSITION,
#ifdef _USE_SKINMATRIX
float4 Indices : BLENDINDICES,
float4 Weights : BLENDWEIGHT,
#endif
out float4 oPos : POSITION,
out float oTC : TEXCOORD0)
{
#ifdef _USE_SKINMATRIX
SKINVERTEX v = SkinVertex(iPos, 0, 0, Indices, Weights);
iPos = v.P;
#endif
oPos = Transform(g_matWorldViewProjection, iPos);
float3 vViewPosition = Transform(g_matWorldView, iPos);
vFocalPlane.w = -abs( sin( g_kernelValues.y * .1f ) ) * 70;
float fBlurFactor = dot(float4(vViewPosition, 1.0), vFocalPlane) * fHyperfocalDistance;
oTC = pow(fBlurFactor, 2);
}
////////////////////////////////////////////////////
// Pixel Shaders
////////////////////////////////////////////////////
sampler Original_Image : register(s0);
sampler Depth_Image : register(s1);
sampler Blur_Image : register(s2);
float4 DOF_PS(float2 iTC : TEXCOORD0
#if defined(_MRT1)
,out float4 oColor1 : COLOR1
#endif
#if defined(_MRT2)
,out float4 oColor2 : COLOR2
#endif
#if defined(_MRT3)
,out float4 oColor3 : COLOR3
#endif
) : COLOR0
{
float3 original = tex2D(Original_Image, iTC + g_texelSize01.xy * .5f);
float d = 0;
{
float x = g_texelSize01.z*2;
float y = g_texelSize01.w*2;
d += tex2D(Depth_Image, iTC + float2(-x,-y)).r;
d += tex2D(Depth_Image, iTC + float2(x,-y)).r;
d += tex2D(Depth_Image, iTC + float2(-x,y)).r;
d += tex2D(Depth_Image, iTC + float2(x,y)).r;
d /= 4;
}
float3 blur = 0;
{
float x = g_texelSize23.x;
float y = g_texelSize23.y;
blur += tex2D(Blur_Image, iTC + float2(-x, -y) * 1);
blur += tex2D(Blur_Image, iTC + float2(x, -y) * 1);
blur += tex2D(Blur_Image, iTC + float2(-x, y) * 1);
blur += tex2D(Blur_Image, iTC + float2(x, y) * 1);
blur /= 4;
}
return float4(original * (1-d) + blur * (d), 1);
}
float4 Object_PS(float iTC : TEXCOORD0
#if defined(_MRT1)
,out float4 oColor1 : COLOR1
#endif
#if defined(_MRT2)
,out float4 oColor2 : COLOR2
#endif
#if defined(_MRT3)
,out float4 oColor3 : COLOR3
#endif
) : COLOR0
{
float d = iTC.x;
return float4(d, d, d, d);
}
#ifdef _VERTEX_SHADER
#define _SHADOWMAP_CGFX
//////////////////////////////////////
// MATRIX MULTIPLICATION
//////////////////////////////////////
float3 Transform(float3x3 mat, float3 v)
{
#if defined(_XENON)
[isolate]
{
return mul(mat, v);
}
#elif defined(_GCM)
return mul(v, mat);
#else
return mul(mat, v);
#endif
}
float4 Transform(float4x4 mat, float4 v)
{
#if defined(_XENON)
[isolate]
{
return mul(mat, v);
}
#elif defined(_GCM)
return mul(v, mat);
#else
return mul(mat, v);
#endif
}
float2 Transform(float2x2 mat, float2 v)
{
#if defined(_XENON)
[isolate]
{
return mul(mat, v);
}
#elif defined(_GCM)
return mul(v, mat);
#else
return mul(mat, v);
#endif
}
//this conversion will not deal with renormalizations because is a bad way to handle bad data passing to the shader.
//the main problem is that cg-compiler isn't as smart as hlsl-compiler dealing with already normalized vectors
float3x3 GetWorldToTangentMatrix(float3x3 worldmtx,float3 tangent, float3 normal)
{
float3x3 worldToTangent = 0;
worldToTangent[0] = normalize(Transform(worldmtx, tangent));
worldToTangent[2] = normalize(Transform(worldmtx, normal));
worldToTangent[1] = normalize(cross(worldToTangent[0], worldToTangent[2]));
return worldToTangent;
}
float4 TransformPlanarReflection(float4 inPos)
{
float4x4 matTexScale = 0;
#if !defined(_GCM)
matTexScale._m00 = 0.5f;
matTexScale._m11 = -.5f;
matTexScale._m22 = 0.0f;
matTexScale._m03 = 0.5f;
matTexScale._m13 = 0.5f;
matTexScale._m23 = 1.0f;
matTexScale._m33 = 1.0f;
#else
matTexScale._m00 = 0.5f;
matTexScale._m11 = -0.5f;
matTexScale._m22 = 0.0f;
matTexScale._m30 = 0.5f;
matTexScale._m31 = 0.5f;
matTexScale._m32 = 1.0f;
matTexScale._m33 = 1.0f;
#endif
return Transform(matTexScale,inPos);
}
uniform float4x4 g_skinMatrix[_MAXBONES]; ///< 128 Registers for skin bones
struct SKINVERTEX
{
float4 P;
float3 N;
float3 T;
};
SKINVERTEX SkinVertex(float3 p, float3 n, float3 t, float4 indices, float4 weights)
{
SKINVERTEX Out = (SKINVERTEX) 0;
for(int i = 0; i < 4; i++)
{
Out.P.xyz += Transform(g_skinMatrix[indices.x], float4(p,1)).xyz * weights.x;
Out.N += (float3)(Transform((float3x3) g_skinMatrix[indices.x], n) * weights.x);
#if !defined(SH_VERSION_SH1)
Out.T += (float3)(Transform((float3x3) g_skinMatrix[indices.x], t) * weights.x);
#endif
indices.xyzw = indices.yzwx;
weights.xyzw = weights.yzwx;
}
Out.P.w = 1;
Out.N = (float3)normalize(Out.N);
#if !defined(SH_VERSION_SH1)
Out.T = (float3)normalize(Out.T);
#endif
return Out;
}
////////////////////////////////////////////////////
// Vertex Shaders
////////////////////////////////////////////////////
#ifdef _LIGHT0_POINT
float4x4 g_matWorld;
#endif
float4x4 g_matWorldViewProjection;
float4x4 g_matTextureProjection;
void Object_VS(
float3 inPos : POSITION, ///< Untransformed vertex position
#ifdef _USE_SKINMATRIX
float4 inSkinIndices : BLENDINDICES, ///< Skin vertex indices
float4 inSkinWeights : BLENDWEIGHT, ///< Skin vertex weights
#endif
#ifdef _MAP_DIFFUSE
float2 inUV : TEXCOORD0, ///< Vertex uv coordinates
#endif
out float4 outHPos : POSITION, ///< Transformed vertex position
out float4 outVPos : TEXCOORD0 ///< Position of the vertex
#ifdef _MAP_DIFFUSE
,out float2 outUV : TEXCOORD1 ///< UV coordinate for albedo Albedo
#endif
)
{
// Apply Skin to the Vertex
#ifdef _USE_SKINMATRIX
SKINVERTEX skin = SkinVertex(inPos.xyz,0,0, inSkinIndices, inSkinWeights);
float4 nPos = skin.P;
#else
float4 nPos = float4(inPos, 1);
#endif
// The matTextureProjection has the transformation (view and projection) of the light camera
outHPos = Transform(g_matTextureProjection, nPos);
#ifdef _LIGHT0_POINT
outVPos = Transform(g_matWorld, nPos);
#else
outVPos = outHPos;
#endif
// Copy the uv mapping, this is used to check for pixels with transparency
#ifdef _MAP_DIFFUSE
outUV.xy = inUV;
#endif
}
#else // End of Vertex Shader
////////////////////////////////////////////////////
// Pixel Shaders
////////////////////////////////////////////////////
#ifdef _LIGHT0_POINT
float4 g_lightPosition0;
#endif
#ifdef _MAP_DIFFUSE
uniform sampler2D sDiffuse : register(s0);
#endif
float4 Object_PS(
float4 inVertexPos : TEXCOORD0
#ifdef _MAP_DIFFUSE
,float2 inVertexUV : TEXCOORD1
#endif
#if defined(_MRT1)
,out float4 oColor1 : COLOR1
#endif
#if defined(_MRT2)
,out float4 oColor2 : COLOR2
#endif
#if defined(_MRT3)
,out float4 oColor3 : COLOR3
#endif
) : COLOR0
{
float4 Out = 1;
// Read the albedo texture to check for transparency
#ifdef _MAP_DIFFUSE
Out.a = tex2D(sDiffuse, inVertexUV.xy).a;
#endif
#ifdef _LIGHT0_DIRECTIONAL
Out.r = inVertexPos.z;
#endif
#ifdef _LIGHT0_SPOT
Out.r = inVertexPos.z / inVertexPos.w;
#endif
#ifdef _LIGHT0_POINT
Out.r = length(inVertexPos.xyz - g_lightPosition0.xyz) * g_lightPosition0.w;
#endif
return Out;
}
#endif
struct VSI_SCREEN
{
float4 pos : POSITION;
float4 color : COLOR0;
float2 uv : TEXCOORD0;
};
struct VSO_SCREEN
{
float4 pos : POSITION;
float2 uv : TEXCOORD0_centroid;
};
////////////////////////////////////////////////////
// Vertex Shaders
////////////////////////////////////////////////////
float4 g_texelSize01;
float4 g_texelSize89;
void main_VS(float4 iPos : POSITION,
float2 iTC : TEXCOORD0,
out float4 oPos : POSITION,
out float2 oTC : TEXCOORD0)
{
oPos = iPos;
#ifndef _XENON
oTC = iTC + g_texelSize89.xy * .5f;
#else
oTC = iTC;// + g_texelSize89.xy * .5f;
#endif
}
////////////////////////////////////////////////////
// Pixel Shaders
////////////////////////////////////////////////////
sampler2D sTex : register(s0);
sampler2D DepthTex : register(s9);
float4 main_PS(float2 iTC : TEXCOORD0
#if defined(_MRT1)
,out float4 oColor1 : COLOR1
#endif
#if defined(_MRT2)
,out float4 oColor2 : COLOR2
#endif
#if defined(_MRT3)
,out float4 oColor3 : COLOR3
#endif
) : COLOR0
{
return float4(tex2Dproj(DepthTex, float4(iTC.xy, .9, 1)).rgb, 1);
}
float4 main_copy_PS(float2 iTC : TEXCOORD0_centroid
#if defined(_MRT1)
,out float4 oColor1 : COLOR1
#endif
#if defined(_MRT2)
,out float4 oColor2 : COLOR2
#endif
#if defined(_MRT3)
,out float4 oColor3 : COLOR3
#endif
) : COLOR0
{
return float4(tex2D(DepthTex, iTC.xy).rgb,1);
}
float4 frustum_PS(float2 iTC : TEXCOORD0
#if defined(_MRT1)
,out float4 oColor1 : COLOR1
#endif
#if defined(_MRT2)
,out float4 oColor2 : COLOR2
#endif
#if defined(_MRT3)
,out float4 oColor3 : COLOR3
#endif
) : COLOR0
{
return float4(1,1,0,1);
}
// now this shader program has become an official 'render a whatever-you-want squad' program
float4 g_specialVector1; // adjust factors for texture coordinates
float4 g_specialVector2; // adjust factors for screen space position
void main_VS(float3 iPos : POSITION,
float2 iTC : TEXCOORD0,
out float4 oPos : POSITION,
out float2 oTC : TEXCOORD0)
{
oPos = float4( iPos.x * g_specialVector2.x + g_specialVector2.y,
iPos.y * g_specialVector2.z + g_specialVector2.w,
iPos.z,
1.f
);
oTC = float2( iTC.x * g_specialVector1.x + g_specialVector1.y,
iTC.y * g_specialVector1.z + g_specialVector1.w
);
}
sampler2D tex : register(s0);
float4 main_PS( float2 tc : TEXCOORD0
#if defined(_MRT1)
,out float4 oColor1 : COLOR1
#endif
#if defined(_MRT2)
,out float4 oColor2 : COLOR2
#endif
#if defined(_MRT3)
,out float4 oColor3 : COLOR3
#endif
) : COLOR
{
//return float4(tex2D(tex, tc).xyz, 1.f);
return tex2D(tex, tc);
}