Trouble with AMD OpenGL ES SDK 3.1 Fragment Shader

593 Views Asked by At

The fragment shader in the AMD OpenGL ES SDK for 3.1 (as of 5/13/2016) is this:

precision highp float;
uniform vec4 lightVec;
uniform sampler2D textureUnit0;
varying vec2 vTexCoord;
varying vec3 vNormal;
void main()
{
    vec4 diff = vec4(dot(lightVec.xyz,normalize(vNormal)).xxx, 1);
    gl_FragColor =  diff * texture(textureUnit0, vTexCoord);
}

Which is is flat out wrong. The closest I have gotten to correcting it is:

precision highp float;
uniform vec4 lightVec;
uniform sampler2D textureUnit0;
varying vec2 vTexCoord;
varying vec3 vNormal;
void main()
{
    vec4 diff = vec4(dot(lightVec.xyz,normalize(vNormal)).xxx, 1);
    gl_FragColor =  diff * texture2D(textureUnit0, vTexCoord);
}

Which is just turning the texture into texture2D on the last line.

No clue what is going on with trying to compute the diffuse shader. It's using dot to get a float, and calling a swizzle (I think that's what you call the .xxx operator) on the float to try and duplicate it?

How does someone learn more about shaders easily? It seems like a very tough area to become skilled at.

2

There are 2 best solutions below

0
On BEST ANSWER

Are you saying that this line:

vec4 diff = vec4(dot(lightVec.xyz,normalize(vNormal)).xxx, 1);

Doesn't compile because of the swizzle on the result of the dot? Try:

float fDot = dot(lightVec.xyz,normalize(vNormal));
vec4 diff = vec4(fDot, fDot, fDot, 1);

As for learning to write shaders better, I'd search up for tutorials on any flavour of GLSL and see if you can find one you like, the desktop versions are different but not that different, and you'll be able to find a better tutorial if you don't restrict your search to one specific revision.

Then arm yourself with the GLSLES 3.1 spec so you can refer to anything that you don't understand/can't translate to your chosen dialect. And get the PowerVR shader tools or something similar which lets you type shader code and get instant feedback about whether it compiles and how many cycles it takes.

0
On

Using the texture() function to sample textures is actually correct for an ES 3.1 shader. The texture2D() function was used in the GLSL version that goes along with ES 2.0, but not with current versions.

The reason you had to change it is that your shader code is missing the version directive. It should have this as the first line if you actually want to use ES 3.1 features in the shader code:

#version 310 es

The shader is invalid, however. The official name for the .xxx in the shader code is component selection operator. It applies only to vectors, which is clearly spelled out in the GLSL ES 3.10 spec:

Note that scalars are not considered to be single-component vectors and therefore the use of component selection operators on scalars is illegal.

The dot() function returns a float, which is a scalar value. So this construct is not valid:

dot(...).xxx

The most elegant (IMHO) way of rewriting that line correctly is:

vec4 diff = vec4(vec3(dot(lightVec.xyz, normalize(vNormal))), 1.0);