Interesting discussion. I was able to make it work with 1.9 SVN on GL but the rendering fail with some models and I didn't know why. Your idea that transparency could be an issue may be right. I've checked with a model that I have that I'm sure have transparent parts, and the shadow projection fail. Removing the object and shadow projection is fine again. Perhaps something is done with the ALPHA channel in the shader that make the shader fail.
Have you tried theses types of objects on DX? Is the rendering ok there?
EDIT: Checked the source code perhaps there is something in the
EffectHandler.cpp file as (starting line 358):
- cpp Code: Select all
// Render all the excluded and casting-only nodes.
for(u32 i = 0;i < ShadowNodeArraySize;++i)
{
if(ShadowNodeArray[i].shadowMode != ESM_CAST && ShadowNodeArray[i].shadowMode != ESM_EXCLUDE)
continue;
const u32 CurrentMaterialCount = ShadowNodeArray[i].node->getMaterialCount();
core::array<irr::s32> BufferMaterialList(CurrentMaterialCount);
BufferMaterialList.set_used(0);
for(u32 m = 0;m < CurrentMaterialCount;++m)
{
BufferMaterialList.push_back(ShadowNodeArray[i].node->getMaterial(m).MaterialType);
switch(BufferMaterialList[m])
{
case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:
ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)WhiteWashTRef;
break;
case EMT_TRANSPARENT_ADD_COLOR:
ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)WhiteWashTAdd;
break;
case EMT_TRANSPARENT_ALPHA_CHANNEL:
ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)WhiteWashTAlpha;
break;
default:
ShadowNodeArray[i].node->getMaterial(m).MaterialType = (E_MATERIAL_TYPE)WhiteWash;
break;
}
}
Theses lines change the material type. So maybe for a unknown reason the current Irrlicht is not rendering the same way with the material taken.
The whitewash material is defined from line 54:
- cpp Code: Select all
WhiteWash = gpu->addHighLevelShaderMaterial(
sPP.ppShader(SHADOW_PASS_1V[shaderExt]).c_str(), "vertexMain", video::EVST_VS_2_0,
sPP.ppShader(WHITE_WASH_P[shaderExt]).c_str(), "pixelMain", video::EPST_PS_2_0,
depthMC, video::EMT_SOLID);
WhiteWashTRef = gpu->addHighLevelShaderMaterial(
sPP.ppShader(SHADOW_PASS_1V[shaderExt]).c_str(), "vertexMain", video::EVST_VS_2_0,
sPP.ppShader(WHITE_WASH_P[shaderExt]).c_str(), "pixelMain", video::EPST_PS_2_0,
depthMC, video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
WhiteWashTAdd = gpu->addHighLevelShaderMaterial(
sPP.ppShader(SHADOW_PASS_1V[shaderExt]).c_str(), "vertexMain", video::EVST_VS_2_0,
sPP.ppShader(WHITE_WASH_P_ADD[shaderExt]).c_str(), "pixelMain", video::EPST_PS_2_0,
depthMC, video::EMT_TRANSPARENT_ALPHA_CHANNEL);
WhiteWashTAlpha = gpu->addHighLevelShaderMaterial(
sPP.ppShader(SHADOW_PASS_1V[shaderExt]).c_str(), "vertexMain", video::EVST_VS_2_0,
sPP.ppShader(WHITE_WASH_P[shaderExt]).c_str(), "pixelMain", video::EPST_PS_2_0,
depthMC, video::EMT_TRANSPARENT_ALPHA_CHANNEL);
Theses are calling a material named WHITEWASH defined in EffectShaders.h and here is the definition:
- cpp Code: Select all
const char* WHITE_WASH_P[ESE_COUNT] = {"uniform sampler2D ColorMapSampler;\n"
""
"void main() "
"{"
" float alpha = texture2D(ColorMapSampler, gl_TexCoord[1].xy).a;\n"
""
" gl_FragColor = vec4(1.0, 1.0, 1.0, alpha);\n"
"}"
,
"sampler2D ColorMapSampler : register(s0);\n"
""
"float4 pixelMain(float4 Color: TEXCOORD0, float2 Texcoords: TEXCOORD1) : COLOR0"
"{"
" float alpha = tex2D(ColorMapSampler, Texcoords).a;\n"
""
" return float4(1.0, 1.0, 1.0, alpha);\n"
"}"};
const char* WHITE_WASH_P_ADD[ESE_COUNT] = {"uniform sampler2D ColorMapSampler;\n"
"float luminance(vec3 color)"
"{"
" return clamp(color.r * 0.3 + color.g * 0.59 + color.b * 0.11, 0.0, 1.0);\n"
"}"
"void main() "
"{"
" vec4 diffuseTex = texture2D(ColorMapSampler, gl_TexCoord[1].xy);\n"
" //diffuseTex *= gl_TexCoord[2];\n"
""
" gl_FragColor = vec4(1.0, 1.0, 1.0, luminance(diffuseTex.rgb));\n"
"}"
,
"sampler2D ColorMapSampler : register(s0);\n"
""
"float luminance(float3 color)"
"{"
" return clamp(color.r * 0.3 + color.g * 0.59 + color.b * 0.11, 0.0, 1.0);\n"
"}"
""
"float4 pixelMain(float4 Color : TEXCOORD0, float2 Texcoords : TEXCOORD1, float4 VColor : TEXCOORD2) : COLOR0"
"{"
" float4 diffuseTex = tex2D(ColorMapSampler, Texcoords);\n"
" diffuseTex *= VColor;\n"
""
" return float4(1.0, 1.0, 1.0, luminance(diffuseTex.rgb));\n"
"}"};const char* WHITE_WASH_P[ESE_COUNT] = {"uniform sampler2D ColorMapSampler;\n"
""
"void main() "
"{"
" float alpha = texture2D(ColorMapSampler, gl_TexCoord[1].xy).a;\n"
""
" gl_FragColor = vec4(1.0, 1.0, 1.0, alpha);\n"
"}"
,
"sampler2D ColorMapSampler : register(s0);\n"
""
"float4 pixelMain(float4 Color: TEXCOORD0, float2 Texcoords: TEXCOORD1) : COLOR0"
"{"
" float alpha = tex2D(ColorMapSampler, Texcoords).a;\n"
""
" return float4(1.0, 1.0, 1.0, alpha);\n"
"}"};
const char* WHITE_WASH_P_ADD[ESE_COUNT] = {"uniform sampler2D ColorMapSampler;\n"
"float luminance(vec3 color)"
"{"
" return clamp(color.r * 0.3 + color.g * 0.59 + color.b * 0.11, 0.0, 1.0);\n"
"}"
"void main() "
"{"
" vec4 diffuseTex = texture2D(ColorMapSampler, gl_TexCoord[1].xy);\n"
" //diffuseTex *= gl_TexCoord[2];\n"
""
" gl_FragColor = vec4(1.0, 1.0, 1.0, luminance(diffuseTex.rgb));\n"
"}"
,
"sampler2D ColorMapSampler : register(s0);\n"
""
"float luminance(float3 color)"
"{"
" return clamp(color.r * 0.3 + color.g * 0.59 + color.b * 0.11, 0.0, 1.0);\n"
"}"
""
"float4 pixelMain(float4 Color : TEXCOORD0, float2 Texcoords : TEXCOORD1, float4 VColor : TEXCOORD2) : COLOR0"
"{"
" float4 diffuseTex = tex2D(ColorMapSampler, Texcoords);\n"
" diffuseTex *= VColor;\n"
""
" return float4(1.0, 1.0, 1.0, luminance(diffuseTex.rgb));\n"
"}"};
Here is a screen showing the shadow projection failing when an object containing transparent material is rendered:

If you look at the picture, the "contour" is draw, but the shadow mass is absent. Also the "contour" is draw all over the image and not clipped. I'm using a directional light and using VSM.
EDIT: I'm adding the source of XEffect I'm using with Irrlicht SVN 1.9 if someone need it:
http://irrrpgbuilder.sourceforge.net/files/XEffects.zip