Problems with depth shadows

codo

16-04-2009 15:30:37

I need to implement texture based shadows in ma app. The problem is: I can't make it work in Mogre :) I can easily run Ogre sample code ('shadow example').
I tried to convert Mogre sample app called 'SkeletalAnimation' to display shadows (for some reason I can't find shadow sample app for Mogre). There are no shadows at all, no matter what I do.
Here is the code:
using System;
using System.Collections.Generic;
using Mogre;

namespace Mogre.Demo.SkeletalAnimation
{
class Skeletal : Demo.ExampleApplication.Example
{
// protected SceneManager sceneMgr;

const int NUM_ROBOTS = 10;
const int ROW_COUNT = 10;

AnimationState[] _animState = new AnimationState[NUM_ROBOTS];
float[] _animationSpeed = new float[NUM_ROBOTS];

public override void CreateFrameListener()
{
base.CreateFrameListener();
root.FrameStarted += new FrameListener.FrameStartedHandler(Skeletal_FrameStarted);
}

bool Skeletal_FrameStarted(FrameEvent evt)
{
for (int i = 0; i < NUM_ROBOTS; ++i)
{
_animState[i].AddTime(evt.timeSinceLastFrame * _animationSpeed[i]);
}

return true;
}

public override void CreateScene()
{
// Setup animation default
Animation.DefaultInterpolationMode = Animation.InterpolationMode.IM_LINEAR;
Animation.DefaultRotationInterpolationMode = Animation.RotationInterpolationMode.RIM_LINEAR;

// Set ambient light

Entity ent = null;
int row = 0;
int column = 0;
Random rnd = new Random();
for (int i = 0; i < NUM_ROBOTS; ++i, ++column)
{
if (column > ROW_COUNT)
{
++row;
column = 0;
}
ent = sceneMgr.CreateEntity("robot" + i, "robot.mesh");
ent.CastShadows = true;
ent.SetMaterialName("Ogre/DepthShadowmap/Receiver/RockWall");
sceneMgr.RootSceneNode.CreateChildSceneNode(
new Vector3(-(row * 100), 0, (column * 50))).AttachObject(ent);

_animState[i] = ent.GetAnimationState("Walk");
_animState[i].Enabled = true;
_animationSpeed[i] = (float)(rnd.NextDouble() + 0.5);
}


// Give it a little ambience with lights
Light l = null;
l = sceneMgr.CreateLight("BlueLight");
l.Type = Mogre.Light.LightTypes.LT_DIRECTIONAL;
l.Direction = new Vector3(-0.2f,-1,1);

l.SetPosition(50, 200, -100);
l.SetDiffuseColour(0.5f, 0.5f, 1.0f);
l.CastShadows = true;
l = sceneMgr.CreateLight("GreenLight");
l.SetPosition(0, 0, -100);
l.SetDiffuseColour(0.5f, 1.0f, 0.5f);
l.CastShadows = true;

// Position the camera
camera.SetPosition(100, 50, 100);
camera.LookAt(-50, 50, 0);


// Report whether hardware skinning is enabled or not
Technique te = ent.GetSubEntity(0).GetMaterial().GetBestTechnique();
Pass p = te.GetPass(0);
if (p.HasVertexProgram && p.GetVertexProgram().IsSkeletalAnimationIncluded)
{
mDebugText = "Hardware skinning is enabled";
}
else
{
mDebugText = "Software skinning is enabled";
}
sceneMgr.AmbientLight = new ColourValue(0.5f, 0.5f, 0.5f);


sceneMgr.SetShadowCameraSetup(new ShadowCameraSetupPtr(new DefaultShadowCameraSetup()));

sceneMgr.SetShadowTexturePixelFormat(PixelFormat.PF_FLOAT32_R);

sceneMgr.SetShadowTextureCasterMaterial("Ogre/DepthShadowmap/Caster/Float");
sceneMgr.SetShadowTextureReceiverMaterial("Ogre/DepthShadowmap/Receiver/Float");
sceneMgr.ShadowTextureSelfShadow = (true);
sceneMgr.SetShadowTextureSettings(1024, 2);
sceneMgr.SetShadowTexturePixelFormat(PixelFormat.PF_FLOAT32_R);

sceneMgr.ShadowColour = (new ColourValue(0.5f, 0.5f, 0.5f));
sceneMgr.ShadowTechnique = (ShadowTechnique.SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED);

Mogre.Plane mPlane = new Mogre.Plane(Vector3.UNIT_Y, new Vector3(0,0,0));

MeshManager.Singleton.CreatePlane("Myplane"+this.GetHashCode(),
ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME, mPlane, 10000,10000,50,50,true,1,5,5,Vector3.UNIT_Z);

Entity pPlaneEnt = sceneMgr.CreateEntity( "plane"+this.GetHashCode(), "Myplane"+this.GetHashCode() );
pPlaneEnt.SetMaterialName("Ogre/DepthShadowmap/Receiver/RockWall");
pPlaneEnt.CastShadows = false;

sceneMgr.RootSceneNode.AttachObject(pPlaneEnt);

}
}
}


What am I doing wrong? I use default media directory from Mogre 1.4.8 installation. Log is showing no severe errors, only stuff like:
16:33:23: WARNING: Texture instance 'Ogre/ShadowTexture0' was defined as manually loaded, but no manual loader was provided. This Resource will be lost if it has to be reloaded.
16:33:23: WARNING: Texture instance 'Ogre/ShadowTexture1' was defined as manually loaded, but no manual loader was provided. This Resource will be lost if it has to be reloaded.
16:33:23: Creating viewport on target 'rtt/2274528', rendering from camera 'Ogre/ShadowTexture0Cam', relative dimensions L: 0.00 T: 0.00 W: 1.00 H: 1.00 ZOrder: 0
16:33:23: Creating viewport on target 'rtt/72627104', rendering from camera 'Ogre/ShadowTexture1Cam', relative dimensions L: 0.00 T: 0.00 W: 1.00 H: 1.00 ZOrder: 0


I changed the shader to draw shaded pixels in red. Result is attached along with this post (everything is in shadow). Any ideas?

dunce

17-04-2009 07:00:41

I tried to use different shadowing techniques with Mogre, and the only one that worked for me was SHADOWTYPE_STENCIL_MODULATIVE. I don't know why.

feanor91

17-04-2009 08:00:03

Hi,

perhaps a way to follow: is the robot be exported to cast shadows. If not, it can't cast them even if you ask it to do. In oFusion, for example, wa have to check that the "Build edge list" box is checked to have object exported be able to cast shadows.

All I can say is tha shadows work well with objects with edge list.

codo

17-04-2009 08:20:31

I can't use stencil shadows because I'm employing MHydrax in my app.
I've just replaced robots with column (column.mesh) models from Ogre shadows sample (they have embedded edge list all right) but it made no difference at all. Everything seems to be in shadow... :(

dunce

17-04-2009 09:01:38

perhaps a way to follow: is the robot be exported to cast shadows
I experimented with the Ninja model that CAN cast shadows. My results are described in the post above. :cry:
I think it's time to dig in Mogre wrapper code and look how those C++ things are wrapped.

Edit:
I tested the same app with DX9 and OGL renderers ( I built my own version of MOGRE based on Ogre-1.4.9 that works with OGL correctly). No shadows except stencil modulative.

codo

17-04-2009 09:36:24

Do you suggest that Mogre has badly wrapped texture shadows? Maybe someone from the Mogre team should take a look at it?

feanor91

17-04-2009 09:49:44

I' ve just tested in my oFusion viewer app and all shadows are OK exept the 2 _integrated witch show nothing but perhaps it's due to a property of my objects, I don't know.

You can see example pictures here (I hope) http://picasaweb.google.com/cramayailes/Ombres#

codo

17-04-2009 09:53:03

Yeah, but the problem is with the integrated shadows. The way I understand is that when you want to use a shader to render objects (bump maps etc), and you can't use stencil shadows, you HAVE to use integrated texture shadows, right?

dunce

17-04-2009 10:29:44

Do you suggest that Mogre has badly wrapped texture shadows?
It's just an assumption that something goes wrong with native/managed pointers.

feanor91

17-04-2009 10:40:36

Yeah, but the problem is with the integrated shadows. The way I understand is that when you want to use a shader to render objects (bump maps etc), and you can't use stencil shadows, you HAVE to use integrated texture shadows, right?

Ah, OK, so here, I don't kow, I did not understand, ad so far use, shader.

lilljohan

17-04-2009 16:03:28

I've got integrated shadows to work in MOGRE before. I had some problems but they were all in my shader code.
SetShadowTextureReceiverMaterial Is pointless if you are using integrated shadows, you will have to add them yourself in your materials.

texturu_unit
{
content_type shadows
}

This can be used to get the current shadow texture.

raygeee

17-04-2009 21:02:35

for some reason I can't find shadow sample app for MogreI think only the demo samples not using CEGUI have been converted to Mogre. In Ogre there are a lot more than in Mogre (I didn't notice that for quite a while).

I converted the biggest part of the Shadows Demo from Ogre. There are some good hints about shadows in it. Like:
case ShadowTechnique.SHADOWTYPE_STENCIL_MODULATIVE:
// Multiple lights cause obvious silhouette edges in modulative mode
// So turn off shadows on the direct light
Then it only uses the moving light, the fixed light is being disabled.

All four basic ShadowTechniques work fine - however both _Integrated ShadowTechniques didn't show any shadow at all.

codo

20-04-2009 13:37:57

Allrighty, I managed to make SHADOWTYPE_TEXTURE_ADDITIVE work. I thought I needed "_inegrated" shadows to work with materials using shaders, but that's not true. "_integrated" shadows are for people who want want to generate shadow map by themselves...

I'm using directional lights to simulate daylight. I played with many parameters but no matter what I do 'small' entities do not cast any shadows. You can see this on a screenshot. Small palms are scaled X 200 times. Small ones are X 20.
This does not seem to be relative. Moving camera and/or light source does not influence it a bit. I can employ PCF to diminish this effect, but I actually cannot make it work with X1 scale (original size). Setting ShadowFarDistance to smaller values helps a bit but does not solve the issue. What do I have to do to make it work without having to scale ALL my objects 200 times? :cry:

Here is my code:


Light l = null;
l = sceneMgr.CreateLight("BlueLight");
l.SetDiffuseColour(1.0f, 1.0f, 1.0f);
l.Type = Light.LightTypes.LT_DIRECTIONAL;
Vector3 dir = new Vector3(-0.9f,-0.55f,0f);
dir.Normalise();
l.SetDirection(dir.x,dir.y,dir.z);

sceneMgr.SetShadowCameraSetup(new ShadowCameraSetupPtr(new DefaultShadowCameraSetup()));

sceneMgr.SetShadowTextureCasterMaterial("Ogre/DepthShadowmap/Caster/Float");



sceneMgr.ShadowTextureSelfShadow = (true);
sceneMgr.SetShadowTextureSettings(2048, 2);
sceneMgr.SetShadowTexturePixelFormat(PixelFormat.PF_FLOAT32_R);


sceneMgr.ShadowCasterRenderBackFaces = false;
sceneMgr.ShadowColour = (new ColourValue(0.3f, 0.3f, 0.3f));
sceneMgr.ShadowTechnique = (ShadowTechnique.SHADOWTYPE_TEXTURE_ADDITIVE);
sceneMgr.ShadowFarDistance = 2000;
sceneMgr.SetShadowUseInfiniteFarPlane(true);

lilljohan

20-04-2009 14:11:54

The shadow map get generated by Ogre in _integrated mode as well, you just have to use it manually in all your materials.

How big is your world and what resolution are you using on the shadow maps? Try the LISPSM shadow camera setup and increase the resolution / decrease the far plane a lot.

codo

23-04-2009 10:20:30

Hi! Thank you for your suggestions. I managed to harness depth shadows, at least a bit. I set farDistance to very low value. LiSPSMShadowCameraSetup worked for me but quality of the shadows depend on viewer's angle. All of this could be acceptable, but I'm stuck again. Very strange thing happen. Some of the objects are faded (totally in shadow), other instances (same material and model) look fine. Take a look at the screenshot. I found out that this behaviour happens at certain angles only. If I do "node.Yaw(angle);" the whole object is in shadow!!! Some angles work just fine but others don't. What could be causing this?

Here's the material I'm using for islands:


// Any number of lights, diffuse and specular
material NormalMappedSpecular
{

// This is the preferred technique which uses both vertex and
// fragment programs, supports coloured lights
technique
{
// Base ambient pass
pass
{
// 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 Ogre/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 Ogre/DepthShadowmap/NormalMapReceiverVP
{
}
shadow_receiver_vertex_program_ref Ogre/DepthShadowmap/NormalMapReceiverVP
{
}

// Fragment program
fragment_program_ref Ogre/DepthShadowmap/NormalMapReceiverFP
{
}
shadow_receiver_fragment_program_ref Ogre/DepthShadowmap/NormalMapReceiverFP
{
}

// shadowmap texture will be bound by code

// Base bump map
texture_unit
{
texture_alias NormalMap
texture dummy.bmp
colour_op replace
}
// Normalisation cube map
texture_unit
{
cubic_texture nm.png combinedUVW
tex_coord_set 1
tex_address_mode clamp
}

}

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


texture_unit
{
texture_alias DiffuseMap
texture dummy.bmp
}

}
}
}



EDIT: I tried a couple of things. Now I reckon it's the normal maps that are causing troubles - not shadows itself. I changed my normal map to atheneNormalMap.png. Result was ugly ofcourse, but angle independent (and not completely shadowed). I'm sorry for going off topic, but how do I generate normal maps that can be used with Ogre/DepthShadowmap/NormalMapReceiverFP etc? Up to now I used normal maps generated by Photoshop nvidia addon... Am I missing something?

codo

24-04-2009 13:24:14

Hi, I resolved all problems. I must say that texture shadows are f***ing hard to integrate :lol: I had to redesign most of my materials.
The problem was some of my billboards (clouds) conflicted with some shadows in a mysterious way. I couldn't make LiSPSMShadowCameraSetup work so finally I'm using FocusedShadowCameraSetup (at a cost of lower quality).

codo

19-10-2009 16:05:34

Hi again,
I facing some serious problems with shadows again :) I moved to MOGRE 1.6.4 not long ago, and want to use PSSM shadows available in Ogre 1.6. I use pssm.cg, pssm.hlsl and pssm.material from SVN playpen. This the shadows camera setup I'm employing:



Vector3 dir = new Vector3(2.8f, -1.8f, 3.0f);
dir.Normalise();
light.SetDirection(dir.x, dir.y, dir.z);
light.DiffuseColour = new ColourValue(0.50f, 0.50f, 0.52f);
light.SpecularColour = new ColourValue(0.1f, 0.1f, 0.1f);

light.CastShadows = true;
// Create the camera
camera = sceneMgr.CreateCamera("mainCamera");

camera.NearClipDistance = 5.0f;
camera.FarClipDistance = 500.0f;

sceneMgr.ShadowTechnique = ShadowTechnique.SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED;
sceneMgr.ShadowFarDistance = 100;
sceneMgr.ShadowTextureSelfShadow = (true);
//sceneMgr.ShadowCasterRenderBackFaces = (true);
sceneMgr.SetShadowTextureCasterMaterial("PSSM/shadow_caster");
sceneMgr.SetShadowTextureCountPerLightType(Light.LightTypes.LT_DIRECTIONAL, 3);

sceneMgr.ShadowTextureCount = 3;
sceneMgr.SetShadowTextureConfig(0, 1024, 1024, PixelFormat.PF_X8R8G8B8);
sceneMgr.SetShadowTextureConfig(1, 512, 512, PixelFormat.PF_X8R8G8B8);
sceneMgr.SetShadowTextureConfig(2, 512, 512, PixelFormat.PF_X8R8G8B8);
pssm = new PSSMShadowCameraSetup();
pssm.CalculateSplitPoints(3, camera.NearClipDistance, camera.FarClipDistance);

pssm.SetOptimalAdjustFactor(0, 2);
pssm.SetOptimalAdjustFactor(1, 1);
pssm.SetOptimalAdjustFactor(2, 0.5f);
pssm.SplitPadding = 1.0f;

//pssm.UseAggressiveFocusRegion = false;
//pssm.UseSimpleOptimalAdjust = true;
//pssm.CameraLightDirectionThreshold = 0;
// sceneMgr.ShadowDirectionalLightExtrusionDistance= (100000);
//sceneMgr.ShadowDirLightTextureOffset =0.1f;

PSSMShadowCameraSetup.Const_SplitPointList splitPoints = pssm.GetSplitPoints();
sceneMgr.SetShadowCameraSetup(new ShadowCameraSetupPtr(pssm));

IEnumerator<float> pointsEnu = splitPoints.GetEnumerator();
Vector4 splitPointsVect = new Vector4();
int i = 0;
while(pointsEnu.MoveNext())
{
splitPointsVect[i] = pointsEnu.Current;
i++;
}

MaterialPtr mat = MaterialManager.Singleton.GetByName("PSSM/Knot");
mat.GetTechnique(0).GetPass(0).GetFragmentProgramParameters().SetNamedConstant("pssmSplitPoints", splitPointsVect);



Shadows are very nice and everything. Problem occurs when the light is behind the camera and I move out a bit. The quality of shadows is not decreasing, but at some distance they are "cut out". Changing shadowDistance didn't help to sort this out.

Here https://www.ogre3d.org/forums/viewtopic.php?f=2&t=44959 I've found some info: "there is a 'duelling frusta' problem when the camera is looking back towards the light. "
I'm not sure if that's the same thing...

Any thoughts how to deal with it?

codo

19-10-2009 20:22:18

As usual back to basics is the best way to debug.

Here's the troublemaker:
sceneMgr.SetFog(FogMode.FOG_LINEAR, new ColourValue(0.0f, 0.0f, 1.0f), 0.0f, 100, 1000);

PSSM and fog existance on the single mesh collide with each other. I wish it was written somewhere like in Ogre::PSSMShadowCameraSetup Class Reference :evil:

This solved the issue:
sceneMgr.SetFog(FogMode.FOG_LINEAR, new ColourValue(0.0f, 0.0f, 1.0f), 0.0f, 300, 1500);

I'm gonna integrate Caelum with my project. Somehow I feel it's gonna be funny ;)

UPDATE: add this to your shadow caster to solve the issue of fog+pssm: fog_override true none