flat shading in webGL

痞子三分冷 提交于 2019-12-04 14:03:37
BrunoLevy

I think 'flat' is not supported by the version of GLSL used in WebGL. If you want flat shading, there are several options:

1) replicate the polygon's normal in each vertex. It is the simplest solution, but I find it a bit unsatisfactory to duplicate data.

2) in the vertex shader, transform the vertex in view coordinates, and in the fragment shader, compute the normal using the dFdx() and dFdy() functions that compute derivatives. These functions are supported by the extension GL_OES_standard_derivatives (you need to check whether it is supported by the GPU before using it), most GPUs, including the ones in smartphones, support the extension.

My vertex shader is as follows:

struct VSUniformState {              
    mat4 modelviewprojection_matrix; 
    mat4 modelview_matrix;           
};

uniform VSUniformState GLUP_VS;     

attribute vec4 vertex_in;
varying vec3 vertex_view_space;

    void main() {                                         
         vertex_view_space = (GLUP_VS.modelview_matrix * vertex_in).xyz;  
         gl_Position = GLUP_VS.modelviewprojection_matrix * vertex_in;  
    }          

and in the associated fragment shader:

#extension GL_OES_standard_derivatives : enable

varying vec3 vertex_view_space;
...
   vec3 U = dFdx(vertex_view_space);                     
   vec3 V = dFdy(vertex_view_space);                 
   N = normalize(cross(U,V));
   ... do the lighting with N    

I like this solution because it makes the setup code simpler. A drawback may be that it gives more work to the fragment shader (but with today's GPUs it should not be a problem). If performance is an issue, it may be a good idea to measure it.

3) another possibility is to have a geometry shader (if supported) that computes the normals. In general it is slower (but again, it may be a good idea to measure performance, it may depend on the specific GPU).

See also answers to this question: How to get flat normals on a cube

My implementation is available here: http://alice.loria.fr/software/geogram/doc/html/index.html

Some online web-GL demos are here (converted from C++ to JavaScript using emscripten): http://homepages.loria.fr/BLevy/GEOGRAM/

Check out webGL 2. Flat shading is supported. For vertex shadder:

#version 300 es
in vec4 vPos; //vertex position from application
flat out vec4 vClr;//color sent to fragment shader
void main(){
    gl_Position = vPos;
    vClr = gl_Position;//for now just using the position as color
}//end main

For fragment shader

#version 300 es
precision mediump float;
flat in vec4 vClr;
out vec4 fragColor;
void main(){
    fragColor = vClr;
}//end main
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!