www.jpct.net

jPCT - a 3d engine for Java => Support => Topic started by: Cowbox on January 31, 2012, 08:38:17 am

Title: Shaders and gouraud shading
Post by: Cowbox on January 31, 2012, 08:38:17 am
It's me again, back with another problem. :P

I was doing quite well, understanding the API and finding all the methods and things I needed but this latest problem I feel is not something so easily solved. D:

Essentially I have a simple maze game where the level is made up of boxes positioned all over the place.

Each box has the normal mapping shader (that comes with http://www.jpct.net/wiki/index.php/Advanced_example ) and everything is working basically fine. (Asside from me still being a big noob with collision/2d/animation/sound etc.)

But one thing I'm having tremendous difficulty with is the lighting.

Here's a picture of what I mean:
(http://www.soharix.homestead.com/java/mylair3.png)

Using the setShadingMode method isn't able to solve this because the lighting is in the shader pipeline.

Now that's fine, maybe I should go and find some help with GLSL for that, but what concerns me is that if I turn the shader off, and use setShadingMode with faked flat shading, the effect is still not what I'm after. - It facets the triangles in the flat surfaces of the boxes, where I just wanted it to show them as flat sided. :(

What am I really looking for? - This kind of thing was never an issue when I had to deal with DirectX and HLSL. :( Things were either smoothed to a percentage or flat but squares (i.e. 2 triangles) showed up as flat squares, not flat triangles. :(

Guidance needed. :P
Title: Re: Shaders and gouraud shading
Post by: EgonOlsen on January 31, 2012, 10:02:51 am
If each wall part is a single box, the vertex normals don't match and have a 90° angle between them, so that one normal points away from the light source and the one of the adjacent box points towards it, which is why you get these light/dark-effect at the edges. That's caused by the way in which the vertex normals are calculated. They are the weighted average of the normals of the adjacent faces of that object, so for a box you get something like:

Code: [Select]
         |     |
         | box |
         |     |
         -------
        /       \
       / n1      \ n2

The best solution would be to build the wall by creating one single mesh instead of using a set of single boxes. If that's not an option, you might want to set the normals yourself after calling build() by using an IVertexController.
Title: Re: Shaders and gouraud shading
Post by: Cowbox on January 31, 2012, 10:26:21 am
D:

That all seems awfully complicated. :(

I found a cheesy fix though. :D

Instead of having the previous Wall.3ds (with 4 faces (8 triangles)) pasted everywhere.

I now just have WallH.3ds pasted ontop of a load of WallV.3ds (each with only 2 oposing (and non joined) faces) to force vertex sharing off.

This almost seems like there should be a method for doing that in the engine itself - some kind of "don't share vertices from adjacent faces" config or method.

I couldn't begin to imagine what I was supposed to do with IVertexController. :S
Title: Re: Shaders and gouraud shading
Post by: EgonOlsen on January 31, 2012, 11:13:33 am
The problem isn't the sharing of the vertices...it's actually that they are NOT shared across the single parts of the wall.
Title: Re: Shaders and gouraud shading
Post by: Cowbox on January 31, 2012, 11:18:07 am
I meant that I thought there should be a way to tell each face (of the individual box) to not share the vertices of the adjacent faces. i.e. omit them from the normals calculation and just focus on that face's vertices



Waaaaiiiit a second, ignoring all of that for a minute. - Why is there not just a way to calculate the normals from the overall plane's angle? The same way I seem to remember doing so in maths at school:
(http://www.rockmechs.com/media/2010/11/stress_vector.png)

I'd have thought there should be a setting to tell polygons to get their normals from adjacent vertices and a converse setting available to tell polygons to get their normals from the literal normal of the face angle.
Title: Re: Shaders and gouraud shading
Post by: EgonOlsen on January 31, 2012, 11:28:06 am
You are thinking in reverse...i think... It's not that the polygons get their face normals (which don't matter for gouraud shading anyway) from adjacent vertices (which wouldn't make any sense, because mathematically, there is no such thing as a vertex normal) but the vertices get their "vertex normals" from the normals of the adjacent faces. You could of course just use a face normal as vertex normal...but for almost all meshes it's impossible to decide which one to pick, which is why one uses the average of all of them.
Title: Re: Shaders and gouraud shading
Post by: Marlon on February 01, 2012, 03:40:19 pm
I had exactly the same problem some weeks ago.
Take a look: http://www.forgottenelements.com/wallcompare.jpg

I found out that there are 2 solutions for me to solve this problem:
1. increase the face count of a box, so that it gets a higher resolution.
2. deactivate lighting for the box: Object3D.setLighting(LIGHTING_NO_LIGHTS);

I hope that helps.
Title: Re: Shaders and gouraud shading
Post by: Cowbox on February 02, 2012, 06:34:25 am
Wow, that game looks exactly like a top down version of what I'm going for. xD

However, I don't think these fixes will work as the actual final diffuse of the polygons is defined by a shader, so methods and settings in jPCT probably won't affect anything. :(