为什么我需要在webgl着色器中定义一个精度值?[英] Why do I need to define a precision value in webgl shaders?

本文是小编为大家收集整理的关于为什么我需要在webgl着色器中定义一个精度值?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我正在尝试获得此教程工作,但我遇到了两个问题,其中之一是以下问题.

当我运行代码时,我会在片段着色器中遇到错误:THREE.WebGLShader: gl.getShaderInfoLog() ERROR: 0:2: '' : No precision specified for (float).因此,我所做的是为我定义的每个浮点/向量指定精度.这消除了错误,但我不明白为什么?我找不到任何其他示例,其中将精确值添加到可变声明中.有人可以解释为什么会发生这种情况吗?它与我的浏览器有关(Chrome 38)?

推荐答案

Jessy的答案是正确的,因为大多数片段着色器都设置了片段着色器代码顶部的默认精度.

但是,您使用的是三分.因此,您必须自己定义它.

另一方面,您链接到的教程是使用three.js的ShaderMaterial用于其材料,因此三个.

如果您从着色器代码中删除默认的制服/属性并使用ShaderMaterial,则可以在没有精确代码的情况下工作.

顶点着色器

varying vec3 vNormal;

void main() {
    vNormal = normal;
    gl_Position = projectionMatrix *
                modelViewMatrix *
                vec4(position,1.0);
}

片段着色器

varying vec3 vNormal;

void main() {
    vec3 light = vec3(0.5, 0.2, 1.0);

    // ensure it's normalized
    light = normalize(light);

    // calculate the dot product of
    // the light to the vertex normal
    float dProd = max(0.0, dot(vNormal, light));

    // feed into our frag colour
    gl_FragColor = vec4(dProd, // R
                        dProd, // G
                        dProd, // B
                        1.0);  // A
}

更新材料

// create the sphere's material
var shaderMaterial = new THREE.ShaderMaterial({
    vertexShader:   document.getElementById('vertex-shader').innerHTML,
    fragmentShader: document.getElementById('fragment-shader').innerHTML
});

在这里是您的代码小提琴,没​​有精确声明.

其他推荐答案

WebGL片段着色器中没有默认精度. (对于顶点着色器的高精度是默认的.)最简单的解决方案是添加

precision highp float;

到所有片段着色器,这将消除为所有浮点矢量变量定义精度的需求,但通常,

precision mediump float;

对于性能,将是可取的.我不建议LOWP;今天的良好移动硬件甚至不再支持它,并且相当于将lowp键入中等程度.

.

本文地址:https://www.itbaoku.cn/post/2091102.html

问题描述

I'm trying to get this tutorial to work but I ran into two issues, one of which is the following.

When I run the code as is I get an error in the fragment shader saying: THREE.WebGLShader: gl.getShaderInfoLog() ERROR: 0:2: '' : No precision specified for (float). So what I did was specifying a precision for every float/vector I define like so varying highp vec3 vNormal. This eliminates the error but I don't get why? I can't find any other example where precision values are added to variable declarations. Can anybody explain why this occurs? Does it have something to do with my Browser (Chrome 38)?

推荐答案

Jessy's answer is correct that most fragment shaders set a default precision at the top of the fragment shader code.

However you are using Three.js's RawShaderMaterial which does not prepend any of the built-in uniforms, attributes, and precision declarations. So you have to define it yourself.

On the other hand the tutorial you linked to is using Three.js's ShaderMaterial for its material so Three.js will have the precision declaration prepended automatically.

If you remove the default uniforms/attributes from your shader code and use ShaderMaterial instead it will work without the precision code.

Vertex Shader

varying vec3 vNormal;

void main() {
    vNormal = normal;
    gl_Position = projectionMatrix *
                modelViewMatrix *
                vec4(position,1.0);
}

Fragment Shader

varying vec3 vNormal;

void main() {
    vec3 light = vec3(0.5, 0.2, 1.0);

    // ensure it's normalized
    light = normalize(light);

    // calculate the dot product of
    // the light to the vertex normal
    float dProd = max(0.0, dot(vNormal, light));

    // feed into our frag colour
    gl_FragColor = vec4(dProd, // R
                        dProd, // G
                        dProd, // B
                        1.0);  // A
}

Update to the material

// create the sphere's material
var shaderMaterial = new THREE.ShaderMaterial({
    vertexShader:   document.getElementById('vertex-shader').innerHTML,
    fragmentShader: document.getElementById('fragment-shader').innerHTML
});

Here is a fiddle of your code without the precision declarations.

其他推荐答案

There is no default precision in WebGL fragment shaders. (High precision is default for vertex shaders.) The easiest solution is to add

precision highp float;

to all of your fragment shaders, which will eliminate the need to define the precision for all floating point vector variables, but generally,

precision mediump float;

will be preferable, for performance. I do not advise lowp; the good mobile hardware of today doesn't even support it anymore, and does the equivalent of typedeffing lowp to mediump.