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.