【问题标题】:flat shading in webGLwebGL中的平面着色
【发布时间】:2016-10-18 06:28:29
【问题描述】:

我正在尝试在 webgl 中实现平面着色,
我知道顶点着色器中的varying 关键字会对该值进行插值并将其传递给片段着色器。

我正在尝试禁用插值,发现flat关键字可以做到这一点,但在webgl中似乎无法使用?

flat varying vec4 fragColor;

总是出错:Illegal use of reserved word 'flat'

【问题讨论】:

    标签: glsl webgl


    【解决方案1】:

    查看 webGL 2。支持平面着色。 对于顶点着色器:

    #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
    

    对于片段着色器

    #version 300 es
    precision mediump float;
    flat in vec4 vClr;
    out vec4 fragColor;
    void main(){
        fragColor = vClr;
    }//end main
    

    【讨论】:

      【解决方案2】:

      我认为 WebGL 中使用的 GLSL 版本不支持“平面”。如果你想要平面阴影,有几种选择:

      1) 在每个顶点复制多边形的法线。这是最简单的解决方案,但是我觉得复制数据有点不满意。

      2) 在顶点着色器中,在视图坐标中变换顶点,在片段着色器中,使用计算导数的 dFdx() 和 dFdy() 函数计算法线。这些功能由扩展GL_OES_standard_derivatives支持(使用前需要检查GPU是否支持),大多数GPU,包括智能手机中的GPU,都支持该扩展。

      我的顶点着色器如下:

      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;  
          }          
      

      在相关的片段着色器中:

      #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    
      

      我喜欢这个解决方案,因为它使设置代码更简单。一个缺点可能是它为片段着色器提供了更多工作(但对于今天的 GPU,这应该不是问题)。如果性能是一个问题,那么衡量它可能是个好主意。

      3) 另一种可能性是拥有一个计算法线的几何着色器(如果支持)。一般来说它比较慢(但同样,衡量性能可能是个好主意,这可能取决于特定的 GPU)。

      另请参阅此问题的答案: How to get flat normals on a cube

      我的实现在这里可用: http://alice.loria.fr/software/geogram/doc/html/index.html

      这里有一些在线 web-GL 演示(使用 emscripten 从 C++ 转换为 JavaScript): http://homepages.loria.fr/BLevy/GEOGRAM/

      【讨论】:

      • 谢谢,通过使用dFdx/dFdy函数,我终于得到了表面法线~!
      • 但是在webGL中,dFdx/dFdy在扩展中,所以需要先声明。
      • modelview * 位置不是剪辑空间而是视图空间
      猜你喜欢
      • 1970-01-01
      • 2014-03-24
      • 1970-01-01
      • 1970-01-01
      • 2017-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多