A few questions about shadows

Started by raft, March 11, 2013, 01:33:00 AM

Previous topic - Next topic

raft

playing with shadows is fun :)

please see the image below, the ball's shadow is casted to tile below it and to tile below that tile. how can I prevent it?


raft

after some shadow rendering, if no more shadows are rendered (shadows disabled) a hole in the last shadow position remains like the one in the image below:



i guess this happens since additional texture stages remains in shadow receivers. how to reset this? I just moved projector to nowhere and rendered shadows one for time. is this the proper way?

EgonOlsen

Quote from: raft on March 11, 2013, 01:33:00 AM
please see the image below, the ball's shadow is casted to tile below it and to tile below that tile. how can I prevent it?
You can't...at least i've no idea ATM how to do that. The depth map gets projected on all objects and in this case, both levels of tiles are below the ball. So technically, it's correct. In the real world, the tiles would cast a shadow too and nobody would notice this.

EgonOlsen

Quote from: raft on March 11, 2013, 02:25:43 AM
i guess this happens since additional texture stages remains in shadow receivers. how to reset this? I just moved projector to nowhere and rendered shadows one for time. is this the proper way?
The proper way would be to reload the assets and reassign all textures. That's the reason why there is no removeReceiver() in the ShadowHelper. Another option might be to make the shadow map accessible in the ShadowHelper and disable it. I'll add such a method this evening and see if that might help.

Thomas.

Quote from: raft on March 11, 2013, 01:33:00 AM
please see the image below, the ball's shadow is casted to tile below it and to tile below that tile. how can I prevent it?

You have to hide the ball, render depth texture from projector and check the depth when you project the shadow texture.

EgonOlsen

Quote from: Thomas. on March 11, 2013, 10:28:40 AM
You have to hide the ball, render depth texture from projector and check the depth when you project the shadow texture.
That would require shaders to be used. The ShadowHelper in desktop jPCT doesn't use/need shaders.

raft

Quote from: EgonOlsen on March 11, 2013, 07:37:43 AM
You can't...at least i've no idea ATM how to do that. The depth map gets projected on all objects and in this case, both levels of tiles are below the ball. So technically, it's correct. In the real world, the tiles would cast a shadow too and nobody would notice this.

mm, how is far plane used in shadows? I noticed it has effect but not the way I expected.

Quote from: EgonOlsen on March 11, 2013, 07:40:21 AM
The proper way would be to reload the assets and reassign all textures. That's the reason why there is no removeReceiver() in the ShadowHelper.

in this case shadow texture will still be in memory and will still be used as additional layer. but it wont be updated (as updateShadowMap() and drawScene() is not called). will there be a performance impact for this?

Quote from: EgonOlsen on March 11, 2013, 07:40:21 AM
Another option might be to make the shadow map accessible in the ShadowHelper and disable it. I'll add such a method this evening and see if that might help.
I guess this will eliminate the performance impact if any.

Quote from: Thomas. on March 11, 2013, 10:28:40 AM
You have to hide the ball, render depth texture from projector and check the depth when you project the shadow texture.
thanks Thomas, but I really do not want to go into shaders ;)

raft

in the image below:

1. is what I have at the moment
2. with a proper use of far plane (if possible of course) i can get 2 (ie: clip shadows to tile below ball, and there will be no shadows in lower layers)
3. if there were a way to disable shadows for some polygons I can get 3. a bit weird look but at least fits the game. in another application, finding which polygons belong to what maybe cumbersome, but the good news is I already have them.

so is 3 indeed possible?



EgonOlsen

Here's a version that add a getShadowMap()-method to the ShadowHelper: http://jpct.de/download/beta/jpct.jar

Regarding your questions:

I first thought that adjusting the far plane might solve it myself, but that's bogus. The projection of the depth map happens for all receivers and it has nothing to do with the far plane. So that doesn't help.

About disabling shadows for single polygons: It might be doable by setting the textures per polygon, but that doesn't sound very efficient and it will definitely stop working once your compile your objects or on Android.

raft

thank you :) I guess all I need to do is call the code below when shadows are disabled. when enabling seems as ShadowHelper automatically enables shadow map again.

shadowHelper.getShadowMap().setEnabled(false);

Quote from: EgonOlsen
I first thought that adjusting the far plane might solve it myself, but that's bogus. The projection of the depth map happens for all receivers and it has nothing to do with the far plane. So that doesn't help.
Yes, forum notifier email said me that ;) in my tries, when far plane is set to a low value shadows just disappear. just for curiosity, how is shadow rendering related with far plane?

Quote from: EgonOlsen
About disabling shadows for single polygons: It might be doable by setting the textures per polygon, but that doesn't sound very efficient and it will definitely stop working once your compile your objects or on Android.
you will remember, I already do something similar to that, it works and performs nice even on Nexus One class devices ;) all my tiles are indeed a couple of large merged objects. to hide a tile or item (quite often) I sent its vertices to nowhere via vertex controller. to change texture of a tile (seldom) set texture of polygons via PolygonManager.

will changing/disabling second layer texture be much different?

but I'm not pretty sure how to do it? I guess I need to use PolygonManager.setPolygonTexture(polyID, TextureInfo) but I don't know how to get the TextureInfo referencing shadow map.


EgonOlsen

#10
Quote
just for curiosity, how is shadow rendering related with far plane?
If you play around with the far plane when rendering the scene, it's the same as if you would do it without using shadows. Closer geometry will be visible and the one farer away will get clipped...as usual. If you set it for the shadow map pass, the same thing happens for rendering into the depth map, i.e. either your ball will write it's depth in the shadow map or it will get clipped and won't write the depth, which leads to no shadows.

Quote
you will remember, I already do something similar to that, it works and performs nice even on Nexus One class devices  all my tiles are indeed a couple of large merged objects. to hide a tile or item (quite often) I sent its vertices to nowhere via vertex controller. to change texture of a tile (seldom) set texture of polygons via PolygonManager.

will changing/disabling second layer texture be much different?
Yes, it's different. Compiled objects' polygons are grouped by state, i.e. for example by texture. If you change the texture of a polygon inside a group, this will have no effect, because the group itself defines another texture (the one used at compile time). To be able to change the texture per polygon on a compiled object, you would have to compile it into a bunch of polygons, i.e. not at all.

Quote
but I'm not pretty sure how to do it? I guess I need to use PolygonManager.setPolygonTexture(polyID, TextureInfo) but I don't know how to get the TextureInfo referencing shadow map.
It's just the shadow map added as a second layer. But as said, this won't work on Android.

raft

Quote from: EgonOlsen on March 12, 2013, 07:26:13 AM
..If you set it for the shadow map pass, the same thing happens for rendering into the depth map, i.e. either your ball will write it's depth in the shadow map or it will get clipped and won't write the depth, which leads to no shadows.
Thanks for clarification :)

Quote from: EgonOlsen on March 12, 2013, 07:26:13 AM
Yes, it's different. Compiled objects' polygons are grouped by state, i.e. for example by texture. If you change the texture of a polygon inside a group, this will have no effect, because the group itself defines another texture (the one used at compile time). To be able to change the texture per polygon on a compiled object, you would have to compiled it into a bunch of polygons, i.e. not at all.

I guess there is a misunderstanding here. The code below works for Android and it's used to change texture of tiles (read polygons). In Android all objects are compiled, besides that one is dynamically compiled (it has an attached vertex controller)

void setTileTexture(int tileId, int textureId) {
int batch = tileBatchIndices[tileId];
int start = tileIndices[batch].polygonLimits[tileId];
int end = tileIndices[batch].polygonLimits[tileId+1];

PolygonManager pm = dynamicTilesMerged[batch].getPolygonManager();

for (int i = start; i < end; i++) {
pm.setPolygonTexture(i, textureId);
}
dynamicTilesMerged[batch].touch();
}


so, if I get you correctly, PolygonManager.setPolygonTexture(polyID, textureID) works on Android but PolygonManager.setPolygonTexture(polyID, TextureInfo) will not?


EgonOlsen

Quote from: raft on March 12, 2013, 03:41:22 PM
...so, if I get you correctly, PolygonManager.setPolygonTexture(polyID, textureID) works on Android but PolygonManager.setPolygonTexture(polyID, TextureInfo) will not?
No, they will both work to a degree. I'll make an example to explain this better:

You have two objects, the first one...


  • ...has 30 triangles
  • ...uses one texture for all these triangles

the second one...


  • ...has also 30 triangles
  • ...uses texture t1 for triangles 0..9, t2 for triangles 10..19 and t3 for triangles 20..29

When compiling these objects, the first one will be compiled to one batch. The second one will be compiled to three batches, one containing the triangles 0..9, the others containing 10..19 and 20..29.

What will work:


  • set a new texture for object 1
  • set a new texture for object 2
  • set a new texture for triangles 10..19 of object 2

...and what won't work:


  • set a new texture for triangle number 10 of object 1
  • set a new texture for triangles 13..17 of object 2
  • set a new texture for triangles 17..25 of object 2

So...as long as you are changing textures of object parts that had their own textures when compiling them, all is fine. But you can't change the texture of sub-parts...or actually you can, but it won't have any visual effect.

raft

ah, thanks :) I understood and also remembered the thing now. sory for taking your time and being a blockhead :-[

that's why I use two methods to change the texture of tiles: one to change all tiles of same type, works since all has same texture, and two is not actually changing texture, there are many copies of same tile with different textures in same place, and I do show/hide tile to show desired texture. I was wondering why there are two methods, I should write more comments ::)

what else option do I have? maybe hiding a tile and putting a non shadow receiver version of it?

jPCT-AE's shadow rendering will be shader based, right? maybe Thomas' suggestion can be possible with it?
Quote from: Thomas. on March 11, 2013, 10:28:40 AM
You have to hide the ball, render depth texture from projector and check the depth when you project the shadow texture.

EgonOlsen

Quote from: raft on March 12, 2013, 08:47:23 PM
jPCT-AE's shadow rendering will be shader based, right? maybe Thomas' suggestion can be possible with it?
Yes...somehow. You might have to use a special shader for that or i have to add it as an option into the default ones. We'll see...but it will be shader based, so in short: Yes, it's possible.