webGL中的平面着色

SSA*_*ndy 3 glsl webgl

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

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

flat varying vec4 fragColor;

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

小智 7

查看 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
Run Code Online (Sandbox Code Playgroud)

对于片段着色器

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


Bru*_*evy 5

我认为WebGL中使用的GLSL版本不支持“ flat”。如果要平面着色,可以使用以下几种方法:

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;  
    }          
Run Code Online (Sandbox Code Playgroud)

并在关联的片段着色器中:

#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    
Run Code Online (Sandbox Code Playgroud)

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

3)另一种可能性是拥有可计算法线的几何着色器(如果支持)。通常,它的速度较慢(不过,再次衡量性能可能是一个好主意,它可能取决于特定的GPU)。

另请参见以下问题的答案: 如何在立方体上获得平坦法线

可在以下位置找到我的实现:http//alice.loria.fr/software/geogram/doc/html/index.html

此处提供了一些在线Web-GL演示(使用emscripten从C ++转换为JavaScript):http ://homepages.loria.fr/BLevy/GEOGRAM/

  • 但是在webGL中,dFdx / dFdy是扩展名,因此需要首先声明它。 (2认同)
  • 模型视图 * 位置不是剪辑空间,而是视图空间 (2认同)