This is a sub-page of Ghostbusters: Sanctum of Slime.
Shader Source Code#
These uncompiled C++ header files can be found inside the data\art\dxshaders\util folder within the data_common archives.
colorutils.h#
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
}
lighting.h#
/*
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(half3 iDir, half3 normal, half3 view, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS, sampler2D spotMap, float4 spotTex)
{
half3 fvLightDir = iDir;
float fNDotL = dot(normal, fvLightDir);
float3 lightColor = tex2Dproj(spotMap, spotTex).rgb;
oD += lightColor * iD * saturate(fNDotL) * Factor;
#ifndef _MATERIAL_NOSPECULAR
half3 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
}
void LightDirectionalBB_PPL_PS(
float3 iDir, ///< Direction of the light
float3 n, ///< Normal vector
float3 v, ///< View direction
float3 iD, ///< Diffuse Color
float4 iS, ///< Specular Color
float4 vpos, ///< Vertex position on world coordinates
float4 aaMin, ///< Minimum coordinate of the light aabox
float4 aaMax, ///< Maximum coordinate of the light aabox
inout float3 oD, ///< Result and input diffuse color
inout float3 oS) ///< Result and input specular color
{
// First check that the vertex is on the AABB of the light
if ( vpos.x > aaMin.x &&
vpos.y > aaMin.y &&
vpos.z > aaMin.z &&
vpos.x < aaMax.x &&
vpos.y < aaMax.y &&
vpos.z < aaMax.z )
{
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
}
void LightDirectionalBB_PVL_PS(
float3 iDir, ///< Direction of the light (world space)
float3 normal, ///< Normal of the surface (world space)
float3 view, ///< View direction (world space)
float3 iD, ///< Diffuse color
float transColor, ///< Factor for translucency
float4 iS, ///< Speculat color
float4 vpos, ///< Vertex position (world space)
float4 aaMin, ///< Minimum coordinate of the light aabox
float4 aaMax, ///< Maximum coordinate of the light aabox
inout float3 oD, ///< Result and input diffuse color
inout float3 oS) ///< Result and input specular color
{
// First check that the vertex is on the AABB of the light
if ( vpos.x > aaMin.x &&
vpos.y > aaMin.y &&
vpos.z > aaMin.z &&
vpos.x < aaMax.x &&
vpos.y < aaMax.y &&
vpos.z < aaMax.z )
{
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
}
}
void LightAmbientBB( float3 ambientColor, ///< The ambient color
float4 vpos, ///< Vertex position on world space
float4 aaMin, ///< Minimum vertex of the AABOX on world space
float4 aaMax, ///< Maximum vertex of the AABOX on world space
inout float3 outAmbient ///< accumulated ambient light
)
{
// Only apply the light check that the vertex is on the AABB of the light
if ( vpos.x > aaMin.x &&
vpos.y > aaMin.y &&
vpos.z > aaMin.z &&
vpos.x < aaMax.x &&
vpos.y < aaMax.y &&
vpos.z < aaMax.z )
{
outAmbient+=ambientColor;
}
}
/*
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
}
matrix.h#
//////////////////////////////////////
// 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);
}
mrt.h#
#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
mrtpsmethods.h#
#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
mrtpso.h#
#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
shadowmap.h#
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) * 1;
float4 tY = float4(0, g_texelSize89.w, 0, 0) * 1;
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;
#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 _PS3
return 1;
#endif
#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);
}
skinning.h#
uniform float4x4 g_skinMatrix[_MAXBONES]; ///< 128 Registers for skin bones
struct SKINVERTEX
{
float4 P;
half3 N;
half3 T;
};
SKINVERTEX SkinVertex(float3 p, half3 n, half3 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 += (half3)(Transform((float3x3) g_skinMatrix[indices.x], n) * weights.x);
#if !defined(SH_VERSION_SH1)
Out.T += (half3)(Transform((float3x3) g_skinMatrix[indices.x], t) * weights.x);
#endif
indices.xyzw = indices.yzwx;
weights.xyzw = weights.yzwx;
}
Out.P.w = 1;
Out.N = (half3)normalize(Out.N);
#if !defined(SH_VERSION_SH1)
Out.T = (half3)normalize(Out.T);
#endif
return Out;
}