Flat shading

In GLSL there is a word called “flat” for vertex shaders which makes the interpolation “flat”. Is there a similar way to do it in JME shaders system?

Yes. Duplicate the vertices with different normals.

The blender importer will do this for you automatically if you use flat shading on the object in blender…

It would also be possible to set GL_FLAT instead of GL_SMOOTH, but i don’t know if JME lets you do that…

If using JOGL maybe you could overwrite some render method and then use

[java]

GLContext.getCurrentGL().getGL2ES2().glDisable(GL2ES2.GL_SMOOTH);
//or
GLContext.getCurrentGL().getGL2ES2().glEnable(GL2ES2.GL_FLAT);
//or both

[/java]

that would be the hacky way if you really don’t need any shader interpolation at all. Never.

Thank You for answers. The problem is that the mesh I want to use is not an imported one - it’s a terrain mesh actually.

<cite>@luke1985 said:</cite> Thank You for answers. The problem is that the mesh I want to use is not an imported one - it's a terrain mesh actually.

Actually the GL solution would affect any mesh because it influences ALL fragment interpolations.

The GL solution won’t work when using shaders. The mesh has to be processed and additional faces generated to contain averaged normals for the entire triangle.

1 Like

Really? I always tought that command would influence how the values are interpolated when passed from vertex to fragment shader.

Well I can’t make all the scene “flat shaded”. I don’t want to use the method with duplicating vertices.

Whats your targeting open gl version? AFAIK in new versions you can use the modifier ‘flat’ in glsl.

@luke1985 said: Well I can't make all the scene "flat shaded". I don't want to use the method with duplicating vertices.
You can use the "flat" keyword in GLSL 1.3, so if you're willing to limit your users only to those with GLSL 1.3 or higher GPUs then you can use it. Otherwise you will need to look into other ways like the aformentioned duplication of triangles. Another way is using the derivative functions dFdx and dFdy over the vertex position to obtain the triangle's uninterpolated normal: [java]normalize(cross(dFdx(ec_pos), dFdy(ec_pos)); [/java]
@luke1985 said: In GLSL there is a word called "flat" for vertex shaders which makes the interpolation "flat". Is there a similar way to do it in JME shaders system?

Maybe we are misunderstanding what you mean. Can you show us an example of what you are talking about?

Usually I think of “flat” as relating to “flat shaded”… which is 100% a function of the vertex normals.

@zzuegg

Whats your targeting open gl version? AFAIK in new versions you can use the modifier ‘flat’ in glsl.
I'm talking exactly about that. A modifier prepended to varying name. "Interpolation qualifier" To be even more strict, I mean this: http://www.arcsynthesis.org/gltut/Basics/Tut02%20Glossary.html

What effect are you trying to achieve?

You can just use the “flat” qualifier if you want in your shader. It won’t interpolate then and just stretch the vertex normal it happened to pick. The default JME shaders wouldn’t really work well with these since they are designed to process normals in the normal way. Randomly picking one to stretch across the triangle would make for ugly visuals.

The effect I’m trying to achieve is to render the terrain with it’s faces flat, so the user will be able to see the slope of a face more easily.
This is intended to be used in a simulation game, where grids composed of terrain faces could be built upon.

I’ve figured out that the qualifiers are available in GLSL 1.30 and above only as @Momoko_Fan said.

Now I think it’ll be possible to do this the way I want it.

I’ve got some problems porting from glsl 1.00 to 1.30. Are there any rules of thumb that I should follow not to get in trouble?

Ok, but you do realize that the normal it picks for the surface is just one of the random corners of the triangle. It’s not the flat normal for the triangle. So the faces will be lit as if they are pointing in strange directions and it will potentially change as the camera moves.

@pspeed said: Ok, but you do realize that the normal it picks for the surface is just one of the random corners of the triangle. It's not the flat normal for the triangle. So the faces will be lit as if they are pointing in strange directions and it will potentially change as the camera moves.
Why would it change with camera motion? The provoking vertex for a triangle is always the last vertex, unless changed via glProvokingVertex() function.
@Momoko_Fan said: Why would it change with camera motion? The provoking vertex for a triangle is always the last vertex, unless changed via glProvokingVertex() function.

I knew it could be changed but I forget it was under user control. One of my software rasterizers used to pick the first vertex handed to the rasterizer, which would change depending on orientation. I mistakenly thought OpenGL would work the same way.

At any rate, for dramatic terrain it might look strange to arbitrarily pick one vertex’s normal to smear over the whole triangle.