engine icon indicating copy to clipboard operation
engine copied to clipboard

Flat shading

Open willeastcott opened this issue 10 years ago • 5 comments

It would be good if there was an easy way to enable flat shading on a mesh.

willeastcott avatar Apr 19 '15 23:04 willeastcott

I dont know if this feature is really missing, see my post here: http://answers.playcanvas.com/questions/1403/flat-shading

I would close this if I could

detzt avatar Apr 20 '15 14:04 detzt

In WebGL 2.0 it is possible to define shading smooth or flat for in/out. It means it will be possible by altering shader to enable flat shading for just normals. Although this will not work for WebGL 1.0. Due to inability of making this shader shading approach backwards compatible without affecting a vertex buffer, the only way would be to preceduraly edit vertex and index buffers splitting vertices into separate triangles.

Maksims avatar Feb 24 '17 14:02 Maksims

Closing mainly due to age. Since I originally submitted this and I no longer think this is much of an issue, I'm going to close.

willeastcott avatar Dec 25 '21 17:12 willeastcott

Due to inability of making this shader shading approach backwards compatible without affecting a vertex buffer, the only way would be to preceduraly edit vertex and index buffers splitting vertices into separate triangles.

Not really, you can use GL_OES_standard_derivatives. Based on this it is OpenGL ES 2.0 (aka WebGL 1.0).

Normal, "non flat":

Image

Standard derivative flat shading:

Image

PlayCanvas version 2 code:

  const material = new pc.ShaderMaterial({
    attributes: {
      aPosition: pc.SEMANTIC_POSITION
    },
    vertexGLSL: `
      attribute vec3 aPosition;
      uniform mat4 matrix_model;
      uniform mat4 matrix_viewProjection;
      varying vec3 vWorldPos;
      void main(void) {
        vec4 worldPos = matrix_model * vec4(aPosition, 1.0);
        vWorldPos = worldPos.xyz;
        gl_Position = matrix_viewProjection * worldPos;
      }
    `,
    fragmentGLSL: `
      varying vec3 vWorldPos;
      void main(void) {
        vec3 dx = dFdx(vWorldPos);
        vec3 dy = dFdy(vWorldPos);
        vec3 normal = normalize(cross(dx, dy));
        gl_FragColor = vec4(normal * 0.5 + 0.5, 1.0);
      }
    `
  });

I know this issue is old, but... there is still no builtin solution? Or at least I can't find anything. Maybe we can reopen @willeastcott ?

This feature is quite nice for debugging meshes or just make a quick viz (reason I'm working on this flat normal material). Without flat shading, it doesn't offer so much "triangle" insights.

Maybe the standard derivative flat shading could be automatically added somehow integrated into the engine via a flatShading property on Material or something?

Edit: added full examples for testing here: https://github.com/kungfooman/playcanvas-snippets/tree/main/MeshNormalMaterial

kungfooman avatar Jun 02 '25 15:06 kungfooman

Reopening to get @mvaligursky's thoughts.

willeastcott avatar Jun 02 '25 16:06 willeastcott