Soft Shadows (w/o EA) Demo (99% done, released)

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
Post Reply

Is there demand for a soft shadows + non-Example Application demo?

Yes
243
98%
No
5
2%
 
Total votes: 248

User avatar
Evak
Orc Shaman
Posts: 707
Joined: Sun Apr 02, 2006 7:51 pm
Location: Sacramento, CA
x 1
Contact:

Post by Evak »

I'm not a coder and am having a hard time figuring out what is required in a scene to get shadows to work. From the thread it appears that I need :

An extra camera to project the shadows?

A second set of UV's to get the shadow texture on.

A light preferably spot or direct.

Our coder has tried to get the shadows to work in our Ogre wrapper, and has got everything compiling without errors but the full screen looks as though it is all shadow. I don't understand the code, but I am concerned that the media isn't valid. It's just the standard robot Ogre robot positioned on a cube.

Image

Our C++ coder for some reason shies away from posting on any forums, so I'm having to ask without really having much technical knowledge. Maybe someone will be able to see where the problem lies from the info and screenshot provided.

here's the source code:

I'm hoping someone can take a quick look at it, and let me know if theres something obvious missing. I suspect it may be the media since they are usualy on top of things on the coding front, the media hasn't to my knowledge been changed in any way from the Ogre SDK

Code: Select all

SuperStrict
Include "Headers/Flow_header.BMX"

AppTitle = "fG - Getting Started [Press ESC to Exit]"
'fG.init(False, 1024, 768, 16, False, fG.RS_OPENGL) 
fG.init() 
fG._viewport.setClearEveryFrame(True) 

'Robot
	Global robot:TEntity = fG.LoadMesh("robot", "robot.mesh") 
	
'Cube
	Global cube:TEntity = fG.createCube("Cube") 
	cube.getParentSceneNode().setPosition(0.0, - 50, 0.0) 
	cube.getParentSceneNode().SetScale(5, 1, 5) 
	
'Light
	Global light:TLight = fG.createLight("light", TLight.LT_SPOTLIGHT) 
	light.setDiffuseColour(1, 1, 1) 
	light.setSpotlightInnerAngle(TRadian.Create(1)) 
	light.setSpotlightOuterAngle(TRadian.Create(2)) 
	light.setAttenuation(5000, 1, 1, 1) 
	light.setPosition(0, 800, 100) 
	light.setDirection(0, - 1, - 1) 
	

'Camera
	Global Camera:TCamera = fG.getDefaultCamera() 
	Camera.setPosition(200, 150, 0) 
	Camera.lookAtWithVector3(robot.getParentNode().getWorldPosition()) 
	Camera.setNearClipDistance(light.getAttenuationRange() * 0.01) 
	Camera.setFarClipDistance(light.getAttenuationRange()) 
'/Camera

'Set up soft shadows
	fG._scene.setShadowTextureSelfShadow(True) 
	fG._scene.setShadowTextureCasterMaterial("shadow_caster") 
	fG._scene.setShadowTextureCount(1) 
	fG._scene.setShadowTextureSize(1024) 
	fG._scene.setShadowTexturePixelFormat(PF_FLOAT16_RGB) 
	fG._scene.setShadowCasterRenderBackFaces(False) 
	
	'That loop for setting bg colour, etc, goes here.
	Global numShadowRTTs:Int = fG._scene.getShadowTextureCount() 
	For Local i:Int = 0 To numShadowRTTs - 1
		Local tex:TTexture = fG._scene.getShadowTexture(i) 
		Local vp:TViewport = tex.getBuffer().getRenderTarget().GetViewport(0) 
		vp.setBackgroundColour(TColourValue.Create(1, 1, 1, 1)) 
		vp.setClearEveryFrame(True) 
	Next
	
	fG._scene.setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED)


Repeat
	fG.TurnEntity(robot, 0, 1, 0) 
	fG.renderWorld() 
	fG.Flip() 
	Delay 16.6666667
Until KeyDown(KEY_ESCAPE) 
Any help would be much appreciated.
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Post by nullsquared »

Well, you need to integrate the VSM shaders ;). Other than that, all the executable-side code does is set up the textures themselves to be usable and what-not.

Did you copy the shadow_caster CG and material file to your media directory? (and load that directory _before_ setting the shadow caster?) You need these two shaders, they do all of the "casting shadows" work. That's what setShadowCasterMaterial(...) does in the code :).

What about diffuse.cg, and 00diffuse.material? These contain the vertex/fragment definitions for the diffuse_vs and diffuse_ps shaders. The best thing to "try out" with would be one of the materials that inherits from diffuse_template (or whatever 00diffuse.material named it). You can already find some of these in the demo. Though, for this to work, you'll need to add the previously mentioned diffuse material and shader files to your media, as well.

Once you get the shadows working, it's just a matter of integrating it into your own shaders (see my previous post). Note that this is a shader-only technique - you don't need any extra cameras or anything like that, but you can't use it with the fixed function pipeline (well, you can mix, but the FFP won't receive shadows).
User avatar
Evak
Orc Shaman
Posts: 707
Joined: Sun Apr 02, 2006 7:51 pm
Location: Sacramento, CA
x 1
Contact:

Post by Evak »

heh, ok thanks for the reply. I have a feeling that the media is all fixed function. So thats a good place to start. Hopefully with the new info we can figure it out :)
User avatar
iloseall
Gremlin
Posts: 156
Joined: Sun Sep 14, 2003 3:54 am
Location: Beijing China
Contact:

Post by iloseall »

In the example,the spotlight work great.
Can I make direction light make soft shadow like this?
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Post by nullsquared »

The problem with directional lights is that they have no position. But the shader (in it's current state) needs a position to calculate a linear depth (instead of the post-projection non-linear depth). Linear depth is good for VSM since it's more numerically stable.

Anyways, a quick "hack" around this to make directional lights work (untested with actual directional lights!), is to use post-projection depth:
shadow_caster.cg

Code: Select all

// find OUT.depth = fp; and comment it out (using "//")
// find OUT.p = mul(pMat, fp); and RIGHT UNDER it write
OUT.depth = OUT.p;

// find float d = (length(IN.depth.xyz) - depthRange.x) * depthRange.w;
// replay with
d = IN.depth.z;
diffuse.cg:

Code: Select all

// find shadow()
// in here, find float2 suv = shadowMapPos.xy / shadowMapPos.w;
// RIGHT UNDER, type
ourDepth = shadowMapPos.z;
See if this works, and report back :)

I warn you, though, VSM is bad enough with 16-bit linear depths - changing the depth as such warrants numerical instability. If you use this, might as well try 32-bit floating points.
Romz
Gnoblar
Posts: 22
Joined: Wed Mar 26, 2008 4:53 pm
Location: Paris, France
Contact:

Post by Romz »

I tried your code but it doesn't work (same effect as before) :

Image

Without the directional and without these modifications in the code I got something nice :

Image

You asked me in your other thread about my SM resolution, well it's not 256, but 1024.
User avatar
tuan kuranes
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2653
Joined: Wed Sep 24, 2003 8:07 am
Location: Haute Garonne, France
x 4
Contact:

Post by tuan kuranes »

nice work, nullsquared !

Now, about precision gdc2006 lauritzen paper (slide32) has a nice trick on distributing value on 16bits RGBA

Example encoding in shadow caster:

Code: Select all

// Stability Four-component floating-point formats
// Store extra precision in extra components
// Must still filter linearly!!!
float2 moments = (...);
float4  output;
const float factor = 64.0f; // Try to gain 6 more bits

output.xy = frac(moments* factor) / factor;
output.zw = moments - output.xy;
Example decoding in shadow receiver:

Code: Select all

float4  input = shadow_map(tex_coord);
float2 moments = output.xy + output.zw;
You can try even 8bits with a factor of 256.

Did you try lodded material on receiving shadows (no blur or lower blur) so that distant small meshes get benefits?

Don't know if it was posted before but GDC08 softshadow mapping is a nice recap an review of possibilities and improvement (PCSS+VSM), including hints on next-gen VSM : layered VSM... which seems to be a winner.

@Romz&iloseall: about directional light there's much parameters than spotlight to tweak, check ogre manual on that. (maxdistance, offset, etc...) before getting same results.
Last edited by tuan kuranes on Thu Apr 10, 2008 5:52 pm, edited 1 time in total.
User avatar
iloseall
Gremlin
Posts: 156
Joined: Sun Sep 14, 2003 3:54 am
Location: Beijing China
Contact:

Post by iloseall »

thanks tuan kuranes and nullsquared .
@Romz&iloseall: about directional light there's much parameters than spotlight to tweak, check ogre manual on that. (maxdistance, offset, etc...) before getting same results.
yes,it is not enough tha only modify the shader code.
the shadow camera for directional is big problem too.

I has modified the shader code just like varianceshadow(in ogre example) to use post-projection,I get bad result .
ApostropheST
Gnoblar
Posts: 6
Joined: Mon Apr 07, 2008 3:31 am

Post by ApostropheST »

Great work, nullsquared.

I'm playing around with it implemented in a test program of my own. I was trying to get a day/night cycle thing going just to test how the shadow stuff works out.

The shadowing and lighting looks great for close lights (say, distance < 50 or so). I tried using a spotlight orbiting 500 units out on a large terrain to act as a sun, always pointed at the origin, but it doesn't cast a shadow and obscures just about all other shadows. I imagine this is due to its brightness and distance, which both contribute to fainter shadows.

Under the VSM model, what should I be looking for to get both strong global lighting and defined daytime shadows? It's a bit hard to show examples but something like this http://www.wonderwallweb.com/Two_Worlds_Ashos.jpg where there are clear shadows being cast all over the place make me wonder how I can achieve an effect on that scale.

I imagine I'll either have to "fake" the effect by using a different light setup, or play with the shader settings. I've taken a look at the latter and nothing has quite popped out at me yet. If someone could point me in the right direction or share some wisdom about using lighting like this, that would be great. :)

By the way, your fix for directional lights does result in cast shadows, but the artifacts are still too bothersome under most of the conditions I tried to be worth using, even at 1024x1024 and float32 shadow maps. At extreme angles between the light and geometry, it's pretty bad.
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Post by nullsquared »

Sorry, it's just that this technique was originally aimed for my close-range lighting in Portalized (*cough*lightingripfromportalized*cough*), so I didn't do extensive (read: any at all) testing with big-scale lighting.
ApostropheST wrote: By the way, your fix for directional lights does result in cast shadows, but the artifacts are still too bothersome under most of the conditions I tried to be worth using, even at 1024x1024 and float32 shadow maps. At extreme angles between the light and geometry, it's pretty bad.
Excellent, then, we'll be working off of this. First thing I can think of is to linearize the post-projection Z depth.

Code: Select all

// shadow_caster_ps
// find float d = IN.depth.z;
// replace with
float d = IN.depth.z * IN.depth.w / far;
(you'll need a uniform, param_named_auto far far_clip_distance)
This is important: you need to register the shadow listener:

Code: Select all

mgr.sceneMgr->addShadowListener(mgr);
I know this was bugged in the original (though since it wasn't used, it didn't make a difference).

Now, all else we need to do is do the same thing in the diffuse shader within the shadow function. The above "far" is equal to the light's attenuation range (lightAtt0.r or lightAtt0.x) because of the shadow listener, so just replicate this code for ourDepth (in shadow()):

Code: Select all

ourDepth = shadowMapPos.z * shadowMapPos.w / lightAtt0.r;
I know I didn't explain everything, but if you've managed to do the old post-Z hack, then this should be self-explanatory.

EDIT: Quick self-test didn't show too good results, so no guarantees, we're all learning here as we go :D
Substatic
Gnoblar
Posts: 18
Joined: Wed Feb 06, 2008 12:46 am

Post by Substatic »

OMG YES! Getting this to work in my project was so damn easy! Awesome awesome awesome!

My next step will be get this working with the other crazy material shaders (per pixel lighting with normal, specular, ambient and emissive maps) I have, so that they can self-shadow. If that happens relatively painlessly, I'll move on to implement what you guys said about directional lights.

Great stuff nullsquared! Woohoo! :D
Substatic
Gnoblar
Posts: 18
Joined: Wed Feb 06, 2008 12:46 am

Post by Substatic »

I'm going crazy integrating this with another shader. I think I'm on the right track but now I'm getting the following error:

Code: Select all

14:40:27: OGRE EXCEPTION(7:InternalErrorException): Unable to compile Cg program PPL/diffuse_and_specular_fast_PPL_fp: CG ERROR : The compile returned an error.
(0) : error C6001: Temporary register limit of 12 exceeded; 18 registers needed to compile program
What does this mean? Should I try a different profile?

nullsquared, you know how you've used structures in your shader? I'm integrating your shader into one that does not have structures. As a result the fragment program has ALOT of parameters! Could that be the issue?

Here's the fragment program (I know it's a mess. I'm new to shaders. =])

Code: Select all

void diffuse_and_specular_fast_PPL_fp(
				    float2 uv1		   : TEXCOORD0,
				    float4 worldPosition   : TEXCOORD1,
				    float3 iNormal          : TEXCOORD2,
				    float4 ilightPosition   : TEXCOORD3,
				    float3 spotLightDirection : TEXCOORD4,
				    
				    float3 TSlightPos   : TEXCOORD5,
				    float3 TSeyePos     : TEXCOORD6,

				    out float4 colour	: COLOR,

				    uniform float3 lightDiffuse,
				    uniform float4 lightSpecular,
				    uniform float exponent,
				    
				    uniform float4 lightPos0,
				    uniform float4 lightAtt0,
				    uniform float4 depthRange,
				    uniform float4 invSMSize,
				    uniform float4 spotlightParams,

				    uniform sampler2D   normalMap : register(s0),
				    uniform sampler2D   diffuseCol : register(s1),
				    uniform sampler2D   specularCol : register(s2),
				    uniform samplerCUBE normalCubeMap : register(s3),

				    //uniform sampler2D dMap : TEXUNIT0,
				    uniform sampler2D shadowMap : TEXUNIT4
					    )
{  
   

	// Calculate half-angle in tangent space
	float3 lightVec = expand(texCUBE(normalCubeMap, TSlightPos).xyz);
	float3 eyeDir = expand(texCUBE(normalCubeMap, TSeyePos).xyz);
	float3 halfAngle = expand(texCUBE(normalCubeMap, eyeDir + lightVec).xyz);

	// Get bump map vector, expand from range-compressed
	float3 bumpVec = expand(tex2D(normalMap, uv1).xyz);

	float specFactor = pow( saturate(dot(bumpVec, halfAngle)), exponent );

	// Direction
	//float3 ld0 = expand(texCUBE(normalCubeMap, lightPos0 - (lightPos0.w * worldPosition)).xyz);
	float3 ld0 = normalize(lightPos0.xyz - (lightPos0.w * worldPosition.xyz));
	
	// Attenuation
	half ila = length(lightPos0.xyz - worldPosition.xyz) / lightAtt0.r;
	ila *= ila;
	half la = 1.0 - ila;

	float3 normal = expand(texCUBE(normalCubeMap, iNormal).xyz);

	float3 LdotN0 = max(dot(ld0, normal), 0);
	
	float4 materialDiffuse = tex2D(diffuseCol, uv1);

	float4 materialSpecular = tex2D(specularCol, uv1);

	// Calculate the spotlight effect
	float spot = dot(ld0,expand(texCUBE(normalCubeMap, -spotLightDirection).xyz));

	spot = saturate((spot - spotlightParams.y) / (spotlightParams.x - spotlightParams.y));

	float3 light0C = 

	( LdotN0 * lightDiffuse * materialDiffuse.xyz * la * spot * saturate(dot(bumpVec, lightVec)) *
	 shadow(
		shadowMap,
		ilightPosition,
		(length(lightPos0.xyz - worldPosition.xyz) - depthRange.x) * depthRange.w,
		3,
		invSMSize.xy
		)
	
	)
	
	+ (materialSpecular.xyz * (lightSpecular.xyz * specFactor));

	colour = float4(light0C,1);

	
	//colour =   (materialDiffuse * lightDiffuse * saturate(dot(bumpVec, lightVec)) )
	//         + (materialSpecular * (lightSpecular * specFactor));
}
Can you see something wrong here just by glancing at the program guys? Like, I should be using structures for the input and output. Too many texture coords (it's unclear to me how they work exactly)? Or anything else? Thanks in advance!
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Post by nullsquared »

Not exactly sure (never got this error). Reading the error, though, looks like you have too many temporary variables. What profile are you compiling for? Try ps_2_x (if under Direct3D, GL should be fine with arbfp1; only if your card supports ps 2.a/2.b or 3.0 or greater).

As for integrating, don't do it piece of code for code - just copy shadow() over, and get the right parameters with your own code (I see you're using exactly TEXUNIT4 and exactly lightAtt0 and so on).
ApostropheST
Gnoblar
Posts: 6
Joined: Mon Apr 07, 2008 3:31 am

Post by ApostropheST »

Yeah, the linearized depth isn't working out too well. I'm going to have to postpone taking a crack at it until the weekend.

Just to show the difference in behavior in a known-working case (nearby point light).

Before the fix:
Image

After the fix:
Image

I'll try playing with the depth and distance calculations to get something like passable shadows from directional lights or sun stand-in.
Substatic
Gnoblar
Posts: 18
Joined: Wed Feb 06, 2008 12:46 am

Post by Substatic »

Changing it to ps_2_x worked! I was so going to try that, but thought that wouldn't work. Was so close to writing a brand new shader (using structures this time)! Damn, lol. Glad I posted here first.

Null, I DID do exactly what you just said btw. I made sure the necessary parameters went to the shader so that both ur shadows and the PPL with specular etc. would work. I left some variable names the same on purpose for my own reference, coz I'm just using a text editor and the ogre log to do it. I don't know if a Cg debugger even exists. I'm totally new to it.

Either way, the above shader does need a thorough clean up so it'll work on the lower profiles, I guess. I'll implement it into the parallax shader as well. Sweetness. I can't believe it's actually working, will have to do some thorough testing.
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Post by nullsquared »

ApostropheST wrote:Yeah, the linearized depth isn't working out too well. I'm going to have to postpone taking a crack at it until the weekend.

Just to show the difference in behavior in a known-working case (nearby point light).

Before the fix:
Image

After the fix:
Image

I'll try playing with the depth and distance calculations to get something like passable shadows from directional lights or sun stand-in.
Wait, point light? That's the first problem, you should be using lights with a direction (best case, spot lights) for shadow mapping (unless you use a cube map/atlas/paraboloid map for the shadow map).

@ Substatic: This is really basic, so don't expect a miracle ;). As I go along, there are many things I could've improved in the demo, but I'm working more on Portalized right now. For example, there's layered variance shadow mapping, exponentional shadow mapping, and so on.
Substatic
Gnoblar
Posts: 18
Joined: Wed Feb 06, 2008 12:46 am

Post by Substatic »

No no, I wasn't talking about your shader! I was talking about the resultant shader I constructed from integration of yours and the per pixel shader with various maps.

Here's a screenshot of what it looks like so far.

Image

The materials on the floor, policeman and hoodie guy all have normal, specular, emissive, ambient map capability (some are disabled but worry not I've tested them). And as you can see, they're receiving the shadows.

Thanks alot nullsquared!
Substatic
Gnoblar
Posts: 18
Joined: Wed Feb 06, 2008 12:46 am

Post by Substatic »

As I go along, there are many things I could've improved in the demo, but I'm working more on Portalized right now. For example, there's layered variance shadow mapping, exponentional shadow mapping, and so on.
Great. Looking forward to your future implementations!

So, you made this one only keeping spotlights in mind, right? For point lights it behaves weird (clipping) and directional lights it doesn't work at all. I think one could make the sacrifice of not using directional lights in a scene, but it would be really helpful if it worked with point lights as expected.

Any plans on implementing these 2 light types? If not, any tips for doing so would be great. I see you and ApostropheST were trying something. Any luck?
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Post by nullsquared »

Substatic wrote:
As I go along, there are many things I could've improved in the demo, but I'm working more on Portalized right now. For example, there's layered variance shadow mapping, exponentional shadow mapping, and so on.
Great. Looking forward to your future implementations!

So, you made this one only keeping spotlights in mind, right? For point lights it behaves weird (clipping) and directional lights it doesn't work at all. I think one could make the sacrifice of not using directional lights in a scene, but it would be really helpful if it worked with point lights as expected.

Any plans on implementing these 2 light types? If not, any tips for doing so would be great. I see you and ApostropheST were trying something. Any luck?
Well, like mentioned, directional lights need to use the post-projection Z, since there is no way to get a linear distance between the light and the surface (directional lights are "infinitely far away"). Except, this doesn't work too good without hacking it up, so that's what I stay away from directional lights.

As for point lights, it's not that easy. Think about how shadow mapping works - you project a depth map onto the scene in the light's direction, and check if anything is closer to the light than the current object. If so, then the current object is already occluded by something. This works easily for spot lights since they have 1 direction. Point lights, though, have 6 directions - forward/back/up/down/left/right. So, to fully shadow a point light, you need 6 shadow maps - or, more simply, a cube map. Cube-map shadow mapping is definitely slower (6 renders per light instead of 1), and way beyond the scope of this simple "example". There's also other methods, like 2-map paraboloid mapping, but that needs very high tessellation of the geometry, and (to me) is quite complex to implement the math.
shaill
Greenskin
Posts: 103
Joined: Wed Mar 12, 2008 5:12 pm

Post by shaill »

Hello nullsquared,
I have several question about your depth geting.

In your shadow_caster.cg,

Code: Select all

float d = (length(IN.depth.xyz) - depthRange.x) * depthRange.w;
Why do u get depth in this way?
It's in linear space. --> I can get it.

But why do u use the length from camera minus the minimun-depth and finally multiply the 1/range?

Is it work better ?Could u give me some ideas?

Thanks!!!
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Post by nullsquared »

shaill wrote:Hello nullsquared,
I have several question about your depth geting.

In your shadow_caster.cg,

Code: Select all

float d = (length(IN.depth.xyz) - depthRange.x) * depthRange.w;
Why do u get depth in this way?
It's in linear space. --> I can get it.

But why do u use the length from camera minus the minimun-depth and finally multiply the 1/range?

Is it work better ?Could u give me some ideas?

Thanks!!!
The length of the view space vector is equal to the distance from the camera - since we're rendering from the "light's point of view", the camera position is equal to the light's position. Thus, this is just an easy way to get the distance from the light without passing any lighting information (the camera is already synced up with the light).

The reason I map it to the depth range is to normalize the depth within [0, 1] (multiplying by 1/range is just a small optimization from directly dividing by the range). Note that I do the same thing in the diffuse shadowing shader, I take the shadow_scene_depth_range and map out the "current" depth just the same way. Anyways, the reason I map the depth to [0, 1] is simply to not overflow things. VSM needs both depth and depth², so the numbers can get rather big for FLOAT16 if they are not normalized.
shaill
Greenskin
Posts: 103
Joined: Wed Mar 12, 2008 5:12 pm

Post by shaill »

I got it, nullsquared!!

THanks for answering my stupid question. :wink:
User avatar
jingjie
Kobold
Posts: 35
Joined: Mon Jul 18, 2005 5:00 am

Post by jingjie »

nullsquared wrote: As for point lights, it's not that easy. Think about how shadow mapping works - you project a depth map onto the scene in the light's direction, and check if anything is closer to the light than the current object. If so, then the current object is already occluded by something. This works easily for spot lights since they have 1 direction. Point lights, though, have 6 directions - forward/back/up/down/left/right. So, to fully shadow a point light, you need 6 shadow maps - or, more simply, a cube map. Cube-map shadow mapping is definitely slower (6 renders per light instead of 1), and way beyond the scope of this simple "example". There's also other methods, like 2-map paraboloid mapping, but that needs very high tessellation of the geometry, and (to me) is quite complex to implement the math.
I think that we must definitely support some popular shadow productions method
of point lights even if its performance is very slow so that shadows of ogre3d would be more robust than another 3d engines.:lol:
I founds some useful references about these challenge.

Cubic Shadow Mapping in Direct3D
http://www.gamedev.net/reference/articl ... le2457.asp

Generating Soft Shadows Using Occlusion Interval Maps
http://developer.download.nvidia.com/bo ... _ch13.html

Omnidirectional Shadow Mapping
http://developer.download.nvidia.com/bo ... _ch12.html
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Post by nullsquared »

It's not that it's hard to do, it's just that it's long to do. There are 2 options:

1) use Ogre's integrated shadow mapping techniques, but then you have to hack up extremely ugly code to make cube maps for point lights and still keep regular textures for spot/directional lights.

2) ignore most (read: all) of Ogre's lighting/shadowing methods and recreate the whole pipeline on your own side. There is no point in this with forward rendering, and thus is this most suited for a deferred lighting. With deferred lighting, you automatically get a pass for each light.

In this case, you don't even need multiple shadow textures - keep a shadow textures for spotlights, and a cube shadow texture for point lights. Depending on the current lighting pass, use either and then it all "Just Works" since you can separate the deferred point light shader from the deferred spot light shader. Understand what I'm getting at?
User avatar
Jallen
Halfling
Posts: 61
Joined: Sat Dec 29, 2007 8:34 pm

Post by Jallen »

nullsquared wrote:You're right - it does get the job done. However, when newbies come and see it, they think "that's how Ogre works". Then they leave because they thought, for example, that only a static scene could be created because of the createScene() method. Or, for example, that the only way to do the game loop was using frame listeners. And so on. And when they _do_ start going lower and implementing the boot strap Ogre code, they get randomly "stuck".
I fell in to that trap, and when trying to write it at the lower level i was a bit confused as all the tutorials i looked at were ExampleApplication.h

Then however i looked at Xadeck's tutorials, and they explained everything really well. I would recommend them to anyone. Rather than throw me in with some crazy half OOP half not OOP design, it's simple and straightforward (mostly everything is in main) - i know how to use OOP, i don't need it to be shown to me in what is supposed to be a simple to use tutorial.
Post Reply