Page 1 of 2

Helping with GLES 2.0 shaders

Posted: Sun May 05, 2013 7:56 pm
by Rado1
Dear OpenGL gurus,

I tried to simplify and rewrite a previously written shader working on Windows (GLSL 1.2) to GLES 2.0 with the desire to use it on Android. Unfortunately without success :cry:. The attached project contains Shader1 - a version working on Windows, and Shader2 - not working variant of Shader1 for Android. Could you please have a look at Shader2 and tell me what's wrong please?

Another question: is there any chance to test/emulate GLSL 1.3 (OpenGL 3.0) shaders on a GPU supporting only GLSL 1.2 (OpenGL 2.1)?

Posted: Mon May 06, 2013 7:35 am
by VilleK
Hi,

In Shader2 I see the texture if I change the line like this:

// vec4 col = vec4(max(dot(N,L), 0.0));
vec4 col = vec4(1,1,1,1);

I'm guessing the normal calculations are wrong? And that vertex shader needs a normalMatrix that should be predefined from ZGE. Anyone knows how I should calculate such a matrix?

Posted: Mon May 06, 2013 7:54 am
by Rado1
VilleK wrote:In Shader2 I see the texture if I change the line like this:

// vec4 col = vec4(max(dot(N,L), 0.0));
vec4 col = vec4(1,1,1,1);
That's strange that in GLES 1.* it works on Windows without problems. BTW also with vec4(1,1,1,1) I see only black color put on rotating cube on my devices.
VilleK wrote:I'm guessing the normal calculations are wrong? And that vertex shader needs a normalMatrix that should be predefined from ZGE. Anyone knows how I should calculate such a matrix?
I think that for computation of normals modelViewMatrix can be used if model scaling is not used (just rotations and changing position). Of course normal matrix would be better. It can be computed as:
normalMatrix = transpose(inverse(modelViewMatrix))

I have another suspicion: modelViewMatrix is not computed correctly, it seems like it takes into account also projection.

Posted: Mon May 06, 2013 9:58 am
by VilleK
Also, not sure if it matters but

uniform sampler2D texture;

should be:

uniform sampler2D tex1;

To follow the naming used in ZGE.

Posted: Mon May 06, 2013 11:42 am
by Rado1
Did not help :-(

I also tried very simple shader:

Code: Select all

// Vertex

precision mediump float;

varying vec2 tcoord;

//The variables below are predefined in ZGE
uniform mat4 modelViewProjectionMatrix;
attribute vec3 position;    //vertex position
attribute vec2 texCoord;  //vertex texture coordinate

void main(void)
{
  tcoord = texCoord;
  gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);
}

// Fragment

precision mediump float;

varying vec2 tcoord;
uniform sampler2D tex1;

void main (void)
{
  gl_FragColor = texture2D(tex1,tcoord);
}
But again, black surface.

Posted: Mon May 06, 2013 3:39 pm
by VilleK
Try setting Tile1Bitmap.Filter to Linear. Any difference?

Posted: Mon May 06, 2013 4:45 pm
by Rado1
Setting Tile1Bitmap.Filter to Linear helped. Now I can see the texture. Does it mean that mipmap is not supported? Still the question is what happens with modelViewMatrix (?), or how is it different from gl_ModelViewMatrix?

BTW I see "E/ZgeAndroid(6504): Non-implemented GL function called" in the LogCat.

Posted: Mon May 06, 2013 5:21 pm
by Kjell
Hmm,
Rado1 wrote:Does it mean that mipmap is not supported?
ZGameEditor currently uses the GL_GENERATE_MIPMAP flag ( set using glTexParameter ) to automatically generate mipmaps. This feature however is deprecated in ES 2.0 .. ( glGenerateMipmap should be used instead ).
Rado1 wrote:Still the question is what happens with modelViewMatrix
Works just fine for me :?

K

Posted: Mon May 06, 2013 11:47 pm
by Rado1
Finally, I made the shader with ambient, diffuse, specular, and texture colors working on GLES 2. It is not very flexible, because does not take material/light/environment color properties into account, but will work for my purpose. The solution was in constructing position vector as vec4(position, 1.0) and normal vector as vec4(normal, 0.0). Then transformation by modelViewMatrix works as expected. Thank you all for help.

Code: Select all

ZZDC<?xml version="1.0" encoding="iso-8859-1" ?>
<Shader Name="LightShaderES">
  <VertexShaderSource>
<![CDATA[precision mediump float;

varying vec3 N;
varying vec3 v;
varying vec2 tcoord;

//The variables below are predefined in ZGE
uniform mat4 modelViewProjectionMatrix;
uniform mat4 modelViewMatrix;
attribute vec3 position;    //vertex position
attribute vec3 normal;    //vertex normal

void main()
{
  // position and normal
  vec4 p = vec4(position, 1.0);
  v = vec3(modelViewMatrix * p);
  N = normalize(vec3(modelViewMatrix * vec4(normal, 0.0)));

  // texture coords
  if(abs(normal.x) > 0.001) tcoord = position.zy;
  else if(abs(normal.y) > 0.001) tcoord = position.xz;
  else tcoord = position.xy;
  //tcoord = texCoord;

  gl_Position = modelViewProjectionMatrix * p;
}]]>
  </VertexShaderSource>
  <FragmentShaderSource>
<![CDATA[precision mediump float;

varying vec3 N;
varying vec3 v;
varying vec2 tcoord;

uniform float shininess;
uniform sampler2D tex1;

void main()
{
  vec3 L = normalize(-v); // light position = player position
  float dist = length(v); // distance factor
  dist = min(1.0, shininess / (dist*dist));
  vec3 R = normalize(-reflect(L,N)); // reflection

  // ambient color
  vec4 col = vec4(0.05);

  // diffuse color
  col += vec4(max(dot(N,L), 0.0));

  // specular color
  col += vec4(clamp(pow(max(dot(R,L), 0.0), 70.0)/5.0, 0.0, 1.0));

  // texture color
  col *= texture2D(tex1,tcoord);

  // result
  gl_FragColor = clamp(col * dist, 0.0, 1.0);
}]]>
  </FragmentShaderSource>
  <UniformVariables>
    <ShaderVariable Name="A" VariableName="shininess" Value="70"/>
  </UniformVariables>
</Shader>
BTW cannot be position of type vec4? Ville if you decide to create normal matrix, it should be of type mat3.

Posted: Tue May 07, 2013 7:23 am
by VilleK
Glad you got it working. I'll fix the mipmap bug for next update.

Posted: Tue May 07, 2013 7:54 am
by Rado1
Ville, would it be problem to add also mat3 normalMatrix uniform variable to next update?

Posted: Tue May 07, 2013 11:20 am
by Kjell
Hi guys,
Rado1 wrote:BTW cannot be position of type vec4?
You should be able to define the attribute as vec4 in your shader. The OpenGL driver will automatically set the w property to 1.0.
Rado1 wrote:Ville, would it be problem to add also mat3 normalMatrix uniform variable to next update?
I suggest caching / copying the matrix / 3x3 component of the modelView matrix just after the rotation part of the matrix has been constructed ( but before scaling ). That's allot faster then transposing the inverse of the resulting modelView matrix.

K

Posted: Tue May 07, 2013 11:33 am
by Rado1
Kjell wrote:You should be able to define the attribute as vec4 in your shader. The OpenGL driver will automatically set the w property to 1.0.
Thanks for this hint. That's great to have somebody who really knows :-)

Posted: Tue May 07, 2013 11:51 am
by VilleK
Kjell wrote:I suggest caching / copying the matrix / 3x3 component of the modelView matrix just after the rotation part of the matrix has been constructed ( but before scaling ). That's allot faster then transposing the inverse of the resulting modelView matrix.
Ok, I agree with Rado1, good with someone who knows :)

Posted: Tue May 28, 2013 10:31 pm
by Rado1
During my learning of GLSL I visited GLSL Sandbox page, which is very good source of shader examples. I tried many of the presented shaders with ZGE and worked fine in Compatible GLBase mode. Unfortunately, I was not able to run them on Android (in ES2/GL3 mode), because many of them crashed with "Non-implemented GL function called" followed by "Fatal signal 11 (SIGSEGV) at 0x0000001c (code=1)" messages in logcat.

Since I have only an old GPU supporting only GLSL v1.2, I'm not able to debug the shaders properly. Could you please give me an advice what's wrong with the attached example if ES2/GL3 mode is used?