Fla*_*vio 15 shader glsl webgl fragment-shader three.js
我试图让本教程工作,但我遇到了两个问题,其中一个是以下问题.
当我按原样运行代码时,我在片段着色器中得到一个错误:THREE.WebGLShader: gl.getShaderInfoLog() ERROR: 0:2: '' : No precision specified for (float)
.所以我所做的是为我定义的每个浮点数/向量指定精度varying highp vec3 vNormal
.这消除了错误,但我不明白为什么?我找不到任何其他将精度值添加到变量声明的示例.任何人都能解释为什么会这样吗?它与我的浏览器(Chrome 38)有关吗?
Jes*_*ssy 16
WebGL片段着色器中没有默认精度.(顶点着色器的默认值是高精度.)最简单的解决方案是添加
precision highp float;
Run Code Online (Sandbox Code Playgroud)
对于所有的片段着色器,这将消除为所有浮点矢量变量定义精度的需要,但通常情况下,
precision mediump float;
Run Code Online (Sandbox Code Playgroud)
为了表现,将是更可取的.我不建议低音; 今天优秀的移动硬件甚至不再支持它,并且相当于typedeffing lowp to mediump.
Jessy的答案是正确的,大多数片段着色器在片段着色器代码的顶部设置默认精度.
但是,您使用的是Three.js RawShaderMaterial
,它不会添加任何内置的制服,属性和精确声明.所以你必须自己定义它.
另一方面,您链接的教程使用Three.js ShaderMaterial
作为其材质,因此Three.js将自动添加精度声明.
如果从着色器代码中删除默认的制服/属性并使用ShaderMaterial
它,则它将在没有精度代码的情况下工作.
顶点着色器
varying vec3 vNormal;
void main() {
vNormal = normal;
gl_Position = projectionMatrix *
modelViewMatrix *
vec4(position,1.0);
}
Run Code Online (Sandbox Code Playgroud)
片段着色器
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
}
Run Code Online (Sandbox Code Playgroud)
更新材料
// create the sphere's material
var shaderMaterial = new THREE.ShaderMaterial({
vertexShader: document.getElementById('vertex-shader').innerHTML,
fragmentShader: document.getElementById('fragment-shader').innerHTML
});
Run Code Online (Sandbox Code Playgroud)
这是没有精确声明的代码的小提琴.