Problem with shadows on terrain

raygeee

11-04-2008 20:31:23

hi everyone,
I'm trying to get shadows working with ETM (Mogre-Wrapper MET to be precise). The problem is that I only get the ShadowTechnique SHADOWTYPE_STENCIL_MODULATIVE working correctly with the terrain and objects. My objects cast shadow on the terrain and on themselves. The disadvantage with this technique is that the shadows are shacking.
The others either dont make shadows appear or even hide my objects too.
Is there a way to get the other shadowtechniques working? What am I missing? Do I have to set any other parameters or is there anything important to know?

This is a part of the code I'm using (VB.NET):
_SceneMgr.ShadowTechnique = ShadowTechnique.SHADOWTYPE_STENCIL_MODULATIVE
_SceneMgr.ShadowColour = New ColourValue(0.5F, 0.5F, 0.5F)
_SceneMgr.AmbientLight = ColourValue.Black

Dim l As Light = _SceneMgr.CreateLight("DirectionalLight")
l.Type = Light.LightTypes.LT_DIRECTIONAL
l.DiffuseColour = New ColourValue(25, 25, 25)
l.SpecularColour = New ColourValue(25, 25, 25)
l.Direction = New Vector3(-1, -1, 0)

CABAListic

11-04-2008 22:13:54

I assume you're using splatting for terrain texturing? The use of shadows makes it difficult for Ogre to add passes for texture shadows, you need to add the texture shadows to the terrain yourself. Look for depth shadow mapping in the Ogre wiki, there should be a tutorial on the usage of depth shadow mapping, you then need to modify the terrain material accordingly.

cyanbeck

08-05-2008 11:41:05

Hello,
I want to apply DepthShadowmap to my terrain, too.
I've set up all needed shaders and modified the terrain material as follow:

material ETTerrainMaterial
{
technique
{

// primary splatting technique, requires PS 2.0
// has issues with OpenGL rendering, though...
pass
{
// splatting pass

lighting off

vertex_program_ref ET/Programs/VSLodMorph2
{
}

fragment_program_ref ET/Programs/PSSplat2
{
param_named splatScaleX float 20
param_named splatScaleZ float 20
}

texture_unit
{
// first coverage map, dynamically managed
texture ETSplatting0
}
texture_unit
{
// second coverage map, dynamically managed
texture ETSplatting1
}

// splatting textures
texture_unit
{
texture splatting0.png
}
texture_unit
{
texture splatting1.png
}
texture_unit
{
texture splatting2.png
}
texture_unit
{
texture splatting3.png
}
texture_unit
{
texture splatting4.png
}
texture_unit
{
texture splatting5.png
}
}

pass
{
// lightmap texture pass

scene_blend modulate

vertex_program_ref ET/Programs/VSLodMorph2
{
}

fragment_program_ref ET/Programs/PSLighting
{
}

texture_unit
{
// dynamically created
texture ETLightmap
}

}

// Base ambient pass
pass Ambient
{
// base colours, not needed for rendering, but as information
// to lighting pass categorisation routine
ambient 1 1 1
diffuse 0 0 0
specular 0 0 0 0
// Really basic vertex program
vertex_program_ref ET/BasicVertexPrograms/AmbientOneTextureUnified
{
}
}

// Now do the lighting pass
// NB we don't do decal texture here because this is repeated per light
pass Lighting
{
// base colours, not needed for rendering, but as information
// to lighting pass categorisation routine
ambient 0 0 0

// do this for each light
iteration once_per_light

scene_blend add

// Vertex program reference
vertex_program_ref ET/DepthShadowmap/ReceiverVP
{
}

// Fragment program
fragment_program_ref ET/DepthShadowmap/ReceiverFP
{
}

texture_unit
{
content_type shadow
tex_address_mode clamp
filtering none
}
}

// Decal pass
pass Decal
{
// base colours, not needed for rendering, but as information
// to lighting pass categorisation routine
lighting off
// Really basic vertex program
vertex_program_ref ET/BasicVertexPrograms/AmbientOneTextureUnified
{
param_named ambient float4 1 1 1 1
}
scene_blend modulate


texture_unit
{
//texture_alias MainTexture
tex_address_mode clamp
}
}
}

But the result isn't correct, and it looks like this:
http://www9.atwiki.jp/cyan/?plugin=ref&page=PnP&file=problem.PNG

I am not good at material scripts nor shader code.
Could anyone give me some hints about modifying the terrain material to generate correct shadows, PLEASE?

Much appreciate in advance.

CABAListic

08-05-2008 12:03:02

Mh, this won't work. The passes you've added seem to be from an example designed for handling both lighting and shadowing. However, the lighting is already done by applying the lightmap. Remove the Ambient and Lighting passes, you need to modify the pass which applies the lightmap to include shadows (the second pass in your material).
For this, first add another texture_unit to it to get the depth shadow map, i. e.

texture_unit
{
content_type shadow
filtering none
}


Then you have to replace the vertex and fragment programs of that pass with according shaders. Those might serve:


struct Params
{
float4 pos: POSITION;
float4 shadowUV: TEXCOORD0;
float2 uv: TEXCOORD1;
};

Params mainVP
(
float4 position : POSITION,
float2 uv1 : TEXCOORD0,
float4 normal: NORMAL,
float delta : BLENDWEIGHT,

uniform float4x4 world,
uniform float4x4 worldViewProj,
uniform float4x4 texViewProj,
uniform float morphFactor
)
{
Params ret;
// vertex morphing
position.y = position.y + (delta.x * morphFactor);

float4 worldPos = mul(world, position);
ret.pos = mul(worldViewProj, position);

ret.shadowUV = mul(texViewProj, worldPos);
ret.uv = uv1;

return ret;
}


void mainFP
(
Params par,
out float4 oColor : COLOR,
uniform sampler2D lightMap,
uniform sampler2D shadowMap,
uniform float4 lightCol,
uniform float4 ambient
)
{
float4 precalc = tex2D(lightMap, par.uv);
float4 shadowUV = par.shadowUV / par.shadowUV.w;
float4 shadow = tex2D(shadowMap, shadowUV.xy);
float final = (shadowUV.z < shadow.x) ? 1.0 : 0.0;

float4 light = ambient + lightCol * final;
oColor = min(light, precalc);
}


This is only a very basic example which you'll likely have to modify (if you intend to get good shadows, there's really no way around learning shader programming, I'm afraid). Anyway, copy that example to some file (like TerrainShadows.cg), and then add those program definitions in your material file:

vertex_program Terrain/VSShadows cg
{
source TerrainShadows.cg
entry_point mainVP
profiles vs_2_0 arbvp1

default_params
{
param_named_auto morphFactor custom 77
param_named_auto world world_matrix
param_named_auto worldViewProj worldviewproj_matrix
param_named_auto texViewProj texture_viewproj_matrix
}
}

fragment_program Terrain/PSShadows cg
{
source TerrainShadows.cg
entry_point mainFP
profiles ps_2_0 arbfp1

default_params
{
param_named_auto lightCol light_diffuse_colour 0
param_named_auto ambient ambient_light_colour
}
}


Now replace the shaders in the pass with the specified Terrain/PSShadows and Terrain/VSShadows. I hope this works to some degree, it's a simplified version of what I'm currently using, but I didn't test it.

cyanbeck

08-05-2008 23:22:30

Hi, CABAListic
Thank you for quick reply and kind help!
I did my best trying all night but I can't figure out where the problem is. :oops:

I add this pass below the lightmap pass in the terrain material:

pass
{
scene_blend modulate

vertex_program_ref ET/Programs/VSShadows
{
}

fragment_program_ref ET/Programs/PSShadows
{
}

texture_unit
{
// dynamically created
texture ETLightmap
}

texture_unit
{
content_type shadow
filtering none
}
}

And the result is all black:
http://www9.atwiki.jp/cyan/?plugin=ref&page=PnP&file=problem1.PNG

But if I change the last line in pixel shader from

oColor = min(light, precalc);

to

oColor = float4(1, 0, 0, 0);

, the scene seems been rendered correctly:
http://www9.atwiki.jp/cyan/?plugin=ref&page=PnP&file=problem2.PNG

I don't know is it the problem of shadow map texture?

Thanks again for your help and
Appreciate in advance

CABAListic

08-05-2008 23:52:31

You weren't supposed to add another pass after the lightmap pass, you should *replace* the lightmap pass :)
Even so, if it comes out all black, then this suggests that something's wrong either in the shader (as I said, I stripped it down, but didn't test it), or the shadowmap is wrong. In either case, all black suggests that you didn't set an ambient colour for your scene.

haibo19981984

09-12-2009 13:20:38

I use the TerrainShadows.cg in my project.
The result is just the screenshot.
But I'm confused that how to set the color of shadow?
It seems that the color of shadow does not depend on the color of light.
So I have to try to edite the TerrainShadows.cg.
However,the result is always odd.
Anybody can resolve the problem.


material TerrainMaterial_1
{
technique
{
pass Splatting
{
lighting off
vertex_program_ref ET/Programs/VSLodMorph2
{
}
fragment_program_ref ET/Programs/PSSplat2
{
param_named splatScaleX float 20
param_named splatScaleZ float 20
}
texture_unit
{
texture ETSplatting10
}
texture_unit
{
texture ETSplatting11
}
// splatting textures
texture_unit
{
texture splatting1_0.png
}
texture_unit
{
texture splatting1_1.png
}
texture_unit
{
texture splatting1_2.png
}
texture_unit
{
texture splatting1_3.png
}
texture_unit
{
texture splatting1_4.png
}
texture_unit
{
texture splatting1_5.png
}
}
pass Lightmap
{
scene_blend modulate
iteration once_per_light directional
vertex_program_ref Terrain/VSShadows
{
}
fragment_program_ref Terrain/PSShadows
{
}
texture_unit
{
texture ETLightmap
}
texture_unit
{
content_type shadow
filtering none
}
}
}
}


mSceneMgr->setAmbientLight(ColourValue(0.9, 0.9, 0.9));
mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);
m_pLit2 = mSceneMgr->createLight("Light3");
m_pLit2->setType(Light::LT_DIRECTIONAL);
m_pLit2->setDiffuseColour(1.0, 1.0, 1.0);
m_pLit2->setSpecularColour(1.0, 1.0, 1.0);
m_pLit2->setDirection(Vector3( 1, -1, 1 ));

haibo19981984

12-12-2009 07:14:13

I find the mistake.
Before today,I don't think that the shadow is supported by ETM all the while.
This causes my mistake that make me to use Cg to resolve the shadow.
In fact , the use of shadow in ETM is as same as the ogre terrain.
So I'm so sorry to faze everybody . :oops: