本文介绍了webGL中的平面着色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to implement flat-shading in webgl,
I knew that varying keyword in vertex shader will interpolation that value and pass it to fragment shader.

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

I'm trying to disable interpolation, and I found that flat keyword can do this, but it seems cannot use in webgl?

flat varying vec4 fragColor;

flat varying vec4 fragColor;

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

推荐答案

我认为WebGL中使用的GLSL版本不支持"flat".如果您想使用平面阴影,则有以下几种选择:

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

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

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)在顶点着色器中,将顶点转换为视图坐标,然后在片段着色器中,使用计算导数的dFdx()和dFdy()函数来计算法线.扩展名GL_OES_standard_derivatives支持这些功能(使用前需要检查GPU是否支持该功能),大多数GPU(包括智能手机中的GPU)都支持该扩展.

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.

我的顶点着色器如下:

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

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

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)另一种可能性是使用几何着色器(如果支持)来计算法线.一般来说,它的速度较慢(但是,再次衡量性能可能是一个好主意,它可能取决于特定的GPU).

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

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

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

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

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

这篇关于webGL中的平面着色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 02:11