I am trying to figure out if there is a way to achieve facet lighting in OpenGL ES 2.0 without extensions. I know it is possible if I don't used indexed vertices but I don't really want to do that because it is a bit wasteful. I have seen people use dFdx and dFdy to achieve this in the shader but unfortunately they are only avaible with extensions here. Are the other options or is there perhaps a way to implement these functions manually?
-
\$\begingroup\$ For the avoidance of doubt, could you explain what you call facet lighting and maybe add a picture of the expected result ? \$\endgroup\$– elenfoiro78Commented Jan 13, 2016 at 8:13
-
\$\begingroup\$ @elenfoiro78 I am referening to "flat" where each part of a specific triangle has the same shading \$\endgroup\$– GerharddcCommented Jan 13, 2016 at 8:20
-
\$\begingroup\$ What kind of light sources will you use (directional, ponctual, spot... )? \$\endgroup\$– elenfoiro78Commented Jan 13, 2016 at 9:25
-
\$\begingroup\$ I would like to use whatever light model is simplest and I guess that is directional. \$\endgroup\$– GerharddcCommented Jan 13, 2016 at 9:42
-
\$\begingroup\$ Last question, what is "wastefull" from your perspective ? Having some vertices repeated on a vbo because of different normals ? \$\endgroup\$– elenfoiro78Commented Jan 13, 2016 at 10:10
1 Answer
Unfortunately, when it comes to lighting, some way or another, you'll need some normals.
As you mentioned, for flat shading, you need per triangle normals, which implies vertices duplication, compared to smooth shading.
The most often used techniques to compute normals in an OpenGL shader (using dfx/dfy or geometry shader) are not available in gles 2.0.
Still, there could be another more exotic technique that you could use. This technique consist in storing per triangle normals in CPU memory and construct an array of these to send to the GPU before drawing the mesh.
Let's say you have a 4 triangle tetrahedron (4 vertices). You could the construct an array of 12 normals based on the normals for the 4 triangles repeated 3 times for each vertex involved in the triangle. You can then bind this array to a specific attribute of your shader before each rendering, separately from your non redundant indexed array. In the shader, you'll then get the same normal for the three vertices of a triangle so you'll be able to do flat shading.
Anyway, this technique will eat up some CPU cycles and also some memory bandwidth as you'll have to transfer data between CPU and GPU memory before each mesh rendering.
Indeed, other techniques like dfx/dfy will consume some GPU cycles.
Then, in the end, my advice would be to profile your rendering time in order to find the best solution for you app.
For example, if you are short in GPU cycles, it's better to have pre-computed normals in a vbo even if this leads to vertices duplication. If you are short in the CPU, again, pre-computed normals are a better choice. If you're short in GPU memory, then on the fly GPU normals computation could be a good solution...
Hope this helps.