1
votes

I'm relatively new to 3D development and am currently using Actionscript, Stage3D and AGAL to learn. I'm trying to create a scene with a simple procedural mesh that is flat shaded. However, I'm stuck on exactly how I should be passing surface normals to the shader for the lighting. I would really like to just use a single surface normal for each triangle and do flat, even shading for each. I know it's easy to achieve better looking lighting with normals for each vertex, but this is the look I'm after.

Since the shader normally processes every vertex, not every triangle, is it possible for me to just pass a single normal per triangle, rather than one per vertex? Is my thinking completely off here? If anyone had a working example of doing simple, flat shading I'd greatly appreciate it.

1
Shading depends on the per-pixel normal, which itself depends on the interpolation method you're using. I don't know the technology you are using, I can only give you a hint. What you want is simply an interpolation that takes the average of triangle's vertices for each pixel.Yno
Okay, makes sense. I think the question is clearer for me now: given that this is the way a fragment shader deals with the normals, if I want to have flat shading (one shade of a color per face, no gradation) do I need to make sure that none of my vertices are shared between triangles? As it stands I am sharing vertices. If I duplicate the vertices so none are shared then I could be sure that every triangle has the same normal on each vertex, eliminating any interpolation that happens across the pixels.Jake Frederick
Duplicating the vertices would work, but using a proper interpolation is the way to go.Yno
if you use ALternativa engine you can try this nice library with some cool shaders alternativa 3D materialsval
There is no alternative to the interpolation methods used. From Adobe's own docs for Program3d: "Varying: Transfers interpolated data between vertex and fragment shaders. The varying registers from the vertex program are applied as input to the fragment program. Values are interpolated according to the distance from the triangle vertices." See my post below.jordancpaul

1 Answers

2
votes

I'm digging up an old question here since I stumbled on it via google and can see there is no accepted answer.

Stage3D does not have an equivalent "GL_FLAT" option for it's shader engine. What this means is that the fragment shader program always receives a "varying" or interpolated value from the output of the three respective vertices (via the vertex program). If you want flat shading, you have basically only one option:

Create three unique vertices for each triangle and set the normal for each vertex to the face normal of the triangle. This way, each vertex will calculate the same lighting and result in the same vertex color. When the fragment shader interpolates, it will be interpolating three identical values, resulting in flat shading.

This is pretty lame. The requirement of unique vertices per triangle means you can't share vertices between triangles. This will definitely increase your vertex count, causing increased delays during your VertexBuffer3D uploads as well as overall lower frame rates. However, I have not seen a better solution anywhere.