www.jpct.net

jPCT - a 3d engine for Java => Support => Topic started by: raft on March 11, 2013, 01:33:00 am

Title: A few questions about shadows
Post by: raft on March 11, 2013, 01:33:00 am
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?

(http://s21.postimage.org/hn40t1y93/shadow_1.jpg)
Title: Re: A few questions about shadows
Post by: raft on March 11, 2013, 02:25:43 am
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:

(http://s2.postimage.org/jpb9bkzbt/shadow_2.jpg)

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?
Title: Re: A few questions about shadows
Post by: EgonOlsen on March 11, 2013, 07:37:43 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.
Title: Re: A few questions about shadows
Post by: EgonOlsen on March 11, 2013, 07:40:21 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.
Title: Re: A few questions about shadows
Post by: Thomas. on March 11, 2013, 10:28:40 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.
Title: Re: A few questions about shadows
Post by: EgonOlsen on March 11, 2013, 11:03:57 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.
Title: Re: A few questions about shadows
Post by: raft on March 11, 2013, 01:36:35 pm
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.

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?

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.

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 ;)
Title: Re: A few questions about shadows
Post by: raft on March 11, 2013, 02:15:28 pm
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?

(http://s18.postimage.org/izaltb5rt/shadow_3.jpg)
Title: Re: A few questions about shadows
Post by: EgonOlsen on March 11, 2013, 09:01:40 pm
Here's a version that add a getShadowMap()-method to the ShadowHelper: http://jpct.de/download/beta/jpct.jar (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.
Title: Re: A few questions about shadows
Post by: raft on March 11, 2013, 09:46:38 pm
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.

Code: [Select]
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.

Title: Re: A few questions about shadows
Post by: EgonOlsen on March 12, 2013, 07:26:13 am
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.
Title: Re: A few questions about shadows
Post by: raft on March 12, 2013, 03:41:22 pm
..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 :)

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)

Code: [Select]
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?

Title: Re: A few questions about shadows
Post by: EgonOlsen on March 12, 2013, 08:13:43 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...


the second one...


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:


...and what won't work:


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.
Title: Re: A few questions about shadows
Post by: raft on March 12, 2013, 08:47:23 pm
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?
You have to hide the ball, render depth texture from projector and check the depth when you project the shadow texture.
Title: Re: A few questions about shadows
Post by: EgonOlsen on March 12, 2013, 10:26:04 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.
Title: Re: A few questions about shadows
Post by: raft on March 12, 2013, 11:33:14 pm
I'm reading about shadow maps. please correct me if I'm wrong:

what ShadowHelper does:
1. first and once add a second layer texture to all receivers
2. render the world from projector's point into shadow texture
3. update second layer uv's according to projector's space*

rest is basic multi-texture rendering

if this is the case, after step 3, I can change 2nd layer uv's of tiles which I dont want to receive shadows. possible?

*btw, how do you do that? there is no setTextureUV or getTextureInfo method in PolygonManager. since ShadowHelper is in another package, it must be doing this via public API.
Title: Re: A few questions about shadows
Post by: EgonOlsen on March 13, 2013, 07:16:03 am
if this is the case, after step 3, I can change 2nd layer uv's of tiles which I dont want to receive shadows. possible?
No, because the projection happens inside the graphics chip. It's nothing that is done in Java code. You just issue a gl command and the chip does some magic when rendering the polygons.
Title: Re: A few questions about shadows
Post by: raft on March 14, 2013, 04:57:33 am
I've implemented as I described. it's not perfect as seen in the video below but i'm satisfied with the result. there are many few scenes where this flaw will be noticable:

http://www.aptalkarga.com/tmp/shadow-shortcoming.avi (http://www.aptalkarga.com/tmp/shadow-shortcoming.avi)

however, with the current api this implementation is not heap friendly.

this is how to disable shadows for a polygon:
Code: [Select]
SimpleVector uv0 = pm.getTextureUV(i, 0);
SimpleVector uv1 = pm.getTextureUV(i, 1);
SimpleVector uv2 = pm.getTextureUV(i, 2);

TextureInfo ti = new TextureInfo(pm.getPolygonTexture(i), uv0.x, uv0.y, uv1.x, uv1.y, uv2.x, uv2.y);
pm.setPolygonTexture(i, ti);

and to re-enable it:
Code: [Select]
SimpleVector uv0 = pm.getTextureUV(i, 0);
SimpleVector uv1 = pm.getTextureUV(i, 1);
SimpleVector uv2 = pm.getTextureUV(i, 2);

TextureInfo ti = new TextureInfo(pm.getPolygonTexture(i), uv0.x, uv0.y, uv1.x, uv1.y, uv2.x, uv2.y);
ti.add(shadowTexture, TextureInfo.MODE_MODULATE);

pm.setPolygonTexture(i, ti);

as can be seen, many objects are created during this process. same TextureInfo can be used many times but I suppose a method like PolygonManager.getTextureUV(polyID, vertexNumber, SimpleVector) is required (unless of course there is another way)

another detail is, there is no direct way of retrieving texture id of shadow map. I get it via a receiver object's polygon manager as: pm.getPolygonTextures(i)[1]. A dedicated method may be nice, although not strictly necessary.

-- o --

please see the image below. shadow of the ball is visible on the bottom side of tile. is this the way it's supposed to be? there is a culling setting in ShadowHelper which makes me think shadows should not be visible on culled faces. (it has no effect on this)

thanks..

(http://s1.postimage.org/opz9mahwv/shadow_culling.jpg)
Title: Re: A few questions about shadows
Post by: EgonOlsen on March 14, 2013, 11:51:08 am
Can't you store the SimpleVectors returned by getTextureUV()? Or are they supposed to change at runtime?

About the shadow on back faces: That's caused by the way the texture projection works. There's no way around this. The culling setting in the ShadowHelper only specifies which part of the object will write into the depth map, the front faces or the back faces.
Title: Re: A few questions about shadows
Post by: raft on March 14, 2013, 04:07:29 pm
Can't you store the SimpleVectors returned by getTextureUV()? Or are they supposed to change at runtime?

no, they dont change. sure I can do that, but I guess it will be a waste of memory. and the other way will be much easy ;D also I suppose someone will eventually need it ;)
Title: Re: A few questions about shadows
Post by: raft on March 14, 2013, 06:45:32 pm
I've found that shadows are rendered weird or not rendered at all when caster is close to receiver, as seen in the videos below. I just move ball temporarily up to overcome this, is there another setting?

http://aptalkarga.com/tmp/shadow-caster-too-close-1.avi (http://aptalkarga.com/tmp/shadow-caster-too-close-1.avi)
http://aptalkarga.com/tmp/shadow-caster-too-close-2.avi (http://aptalkarga.com/tmp/shadow-caster-too-close-2.avi)

there is Config.glShadowZBias but not sure if related to this.
Title: Re: A few questions about shadows
Post by: EgonOlsen on March 14, 2013, 06:57:46 pm
no, they dont change. sure I can do that, but I guess it will be a waste of memory. and the other way will be much easy ;D also I suppose someone will eventually need it ;)
Ok. here you go: http://jpct.de/download/beta/jpct.jar (http://jpct.de/download/beta/jpct.jar) and http://jpct.de/download/beta/jpct_ae.jar (http://jpct.de/download/beta/jpct_ae.jar)
Title: Re: A few questions about shadows
Post by: EgonOlsen on March 14, 2013, 06:59:44 pm
I've found that shadows are rendered weird or not rendered at all when caster is close to receiver, as seen in the videos below. I just move ball temporarily up to overcome this, is there another setting?

there is Config.glShadowZBias but not sure if related to this.
It's either the offset (just play around with that value), the culling (try another culling mode for the ShadowHelper) or some inaccuracy of the GPU.
Title: Re: A few questions about shadows
Post by: raft on March 14, 2013, 07:03:34 pm
Ok. here you go: http://jpct.de/download/beta/jpct.jar (http://jpct.de/download/beta/jpct.jar) and http://jpct.de/download/beta/jpct_ae.jar (http://jpct.de/download/beta/jpct_ae.jar)
thanks, you are a lifesaver :)