Questions about ES2/GL3 shaders

All topics about ZGameEditor goes here.

Moderator: Moderators

User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: Questions about GLES2 shaders

Post by Kjell »

Hi Ats,
Ats wrote: Thu May 27, 2021 10:52 amLet's say, the phong one.
That phong shader is written for legacy OpenGL ( GLBase = compatible ). I suspect you changed the "gl_ModelViewProjectionMatrix" part in the fragment shader, but that's not nearly enough to convert it to a modern shader ( GLBase = GL3/ES2 ). Anyway, here's what the shader is supposed to look like. It's a per-pixel phong shader that supports a single point-light.

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" AmbientLightColor="0 0 0 1" LightPosition="0 0 0" FileVersion="2">
  <OnLoaded>
    <SpawnModel Model="Box"/>
  </OnLoaded>
  <Lights>
    <Light Position="2 2 4" Color="1 1 1 1" Kind="1" SpotDirection="0 0 0"/>
  </Lights>
  <Content>
    <Model Name="Box" RotationVelocity="0.1 0.1 0">
      <OnRender>
        <UseMaterial Material="PhongMaterial"/>
        <RenderMesh Mesh="BoxMesh"/>
      </OnRender>
    </Model>
    <Mesh Name="BoxMesh">
      <Producers>
        <MeshBox/>
      </Producers>
    </Mesh>
    <Shader Name="PhongShader">
      <VertexShaderSource>
<![CDATA[//

varying vec3 N;
varying vec3 v;

void main(void)
{
   v = vec3(gl_ModelViewMatrix * gl_Vertex);
   N = normalize(gl_NormalMatrix * gl_Normal);
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
   gl_FrontColor = gl_Color;
}]]>
      </VertexShaderSource>
      <FragmentShaderSource>
<![CDATA[//

varying vec3 N;
varying vec3 v;

void main (void)
{
   vec3 L = normalize(gl_LightSource[0].position.xyz - v);
   vec3 E = normalize(-v); // we are in Eye Coordinates, so EyePos is (0,0,0)
   vec3 R = normalize(-reflect(L,N));

   //calculate Ambient Term:
   vec4 Iamb = gl_FrontLightProduct[0].ambient;

   //calculate Diffuse Term:
   vec4 Idiff = gl_Color * gl_FrontLightProduct[0].diffuse * max(dot(N,L), 0.0);
   Idiff = clamp(Idiff, 0.0, 1.0);

   // calculate Specular Term:
   vec4 Ispec = gl_FrontLightProduct[0].specular
                * pow(max(dot(R,E),0.0),0.3*gl_FrontMaterial.shininess);
   Ispec = clamp(Ispec, 0.0, 1.0);
   // write Total Color:
   gl_FragColor = gl_FrontLightModelProduct.sceneColor + Iamb + Idiff + Ispec;
}]]>
      </FragmentShaderSource>
    </Shader>
    <Material Name="PhongMaterial" Color="1 0.502 0.251 1" SpecularColor="1 1 0 1" Shininess="4" Shader="PhongShader"/>
  </Content>
</ZApplication>
+ For some reason that shader didn't take the material diffuse color into account, so i added that.
Ats wrote: Thu May 27, 2021 10:52 amI was sure I had to stick to version 120 because of the name ES2/GL3... But now I realize my mistake.
No, it's just a switch to choose between "legacy" OpenGL ( up to OpenGL 3.2 or OpenGL ES 1.1 ) or "modern" OpenGL.
Ats wrote: Thu May 27, 2021 10:52 amBut if I target Android phones (recent ones, not dinosaurs), should I stick to version 120, or more recent ones, such as 330?
Personally i'd always target the lowest version i absolutely need. When you target ES 3.2 it won't work on 30% of Android phones out there.

Image

OpenGL ES version

K
User avatar
Ats
Posts: 764
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about GLES2 shaders

Post by Ats »

Thanks for the explanations.
I was looking at your phong shader, and while it's really showing the use of Specular and Emission colors, it doesn't show up on ES2/GL3.
I'm going to start over again, and searching for examples that work precisely on PC and Android.

Edit:
This is really helpful: https://docs.gl/
Last edited by Ats on Thu Jun 03, 2021 10:56 am, edited 1 time in total.
User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: Questions about GLES2 shaders

Post by Kjell »

Hi Ats,
Ats wrote: Thu Jun 03, 2021 10:27 amI was looking at your phong shader, and while it's really showing the use of Specular and Emission colors, it doesn't show up on ES2/GL3.
Right, as mentioned .. it's a shader for legacy OpenGL so it doesn't work ( properly ) with ES2/GL3.
Ats wrote: Thu Jun 03, 2021 10:27 amI'm going to start over again, and searching for examples that work precisely on 2.0 for PC and Android.
It's not that complicated to convert a shader from legacy to modern OpenGL though. The primary hurdle is that they removed a bunch of features in modern OpenGL, so you can't use a lot of the built-in variables that were available in legacy GLSL ( including gl_ModelViewProjectionMatrix / gl_NormalMatrix / gl_LightSource / gl_FrontMaterial etc. ). ZGE provides built-in alternatives for some of these .. but not all, so some you'll have to feed into your shader using ShaderVariable components yourself.
Ats wrote: Thu Jun 03, 2021 10:27 amThis is really helpful: https://docs.gl/
I'd recommend this page instead as it also lists features & built-in variables from legacy GLSL.

K
User avatar
Ats
Posts: 764
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about ES2/GL3 shaders

Post by Ats »

I started all over from the GLES2Demo. At least, it's not crashing on Android like before.
But I really don't understand why the noise bitmap is working on PC, but not on Android. It's just white.

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="GLES2 Showroom" GLBase="1" MouseVisible="255" RenderOrder="1" FileVersion="2" AndroidPackageName="com.GLES2.Showroom">
  <OnLoaded>
    <ZLibrary Comment="Variables" HasInitializer="1">
      <Source>
<![CDATA[
// to pass the mesh shape to the model
string shapeTemp = "";]]>
      </Source>
    </ZLibrary>
    <ZExpression Comment="Initialization">
      <Expression>
<![CDATA[// Create models

shapeTemp = "cube";
model m1 = createModel(ObjectModel);
m1.Position.X = -2;

shapeTemp = "sphere";
model m2 = createModel(ObjectModel);
m2.Position.X = 2;]]>
      </Expression>
    </ZExpression>
  </OnLoaded>
  <OnRender>
    <RenderTransformGroup Comment="background" Translate="0 0 -4">
      <Children>
        <UseMaterial Material="ZCellMaterial"/>
        <RenderMesh Mesh="PlaneMesh"/>
      </Children>
    </RenderTransformGroup>
  </OnRender>
  <Content>
    <Model Name="ObjectModel">
      <Definitions>
        <Variable Name="shape" Type="2"/>
      </Definitions>
      <OnSpawn>
        <ZExpression>
          <Expression>
<![CDATA[CurrentModel.Rotation = rnd();
CurrentModel.RotationVelocity.Y = 0.05;
CurrentModel.shape = shapeTemp;]]>
          </Expression>
        </ZExpression>
      </OnSpawn>
      <OnRender>
        <ZExpression>
          <Expression>
<![CDATA[// Material

@UseMaterial(Material:ZNoiseMaterial);

// Mesh

if (CurrentModel.shape == "sphere") { @RenderMesh(Mesh:SphereMesh); }
if (CurrentModel.shape == "cube") { @RenderMesh(Mesh:CubeMesh); }]]>
          </Expression>
        </ZExpression>
      </OnRender>
    </Model>
    <Group Comment="Meshes">
      <Children>
        <Mesh Name="SphereMesh">
          <Producers>
            <MeshBox Scale="1 0.5 1" XCount="32" YCount="32" Grid2DOnly="255"/>
            <MeshExpression AutoNormals="0">
              <Expression>
<![CDATA[//

        float E, A, K, X, Y, Z;

        // Convert range to radians

        E = v.Y*PI; // Elevation
        A = v.X*PI; // Azimuth

        // Convert spherical coordinates into cartesian

        K = cos(E);

        X = sin(A)*K;
        Y = sin(E);
        Z = cos(A)*K;

        // Assign coordinates

        v.X = X;
        v.Y = Y;
        v.Z = Z;

        n.X = X;
        n.Y = Y;
        n.Z = Z;]]>
              </Expression>
            </MeshExpression>
          </Producers>
        </Mesh>
        <Mesh Name="PlaneMesh">
          <Producers>
            <MeshBox Scale="10 10 1" Grid2DOnly="255"/>
          </Producers>
        </Mesh>
        <Mesh Name="CubeMesh">
          <Producers>
            <MeshBox/>
          </Producers>
        </Mesh>
      </Children>
    </Group>
    <Group Comment="Bitmaps">
      <Children>
        <Bitmap Name="NoiseBitmap" Width="256" Height="256" Filter="2">
          <Producers>
            <BitmapNoise StartingOctaves="2" Octaves="4" Offset="0.4" Persistence="0.5" Tile="255"/>
          </Producers>
        </Bitmap>
        <Bitmap Name="CellBitmap" Width="256" Height="256" Filter="2">
          <Producers>
            <BitmapCells PointsPlacement="2" BorderPixels="0" PointCount="6"/>
          </Producers>
        </Bitmap>
      </Children>
    </Group>
    <Group Comment="Shaders">
      <Children>
        <Group Comment="Texture">
          <Children>
            <Material Name="ZNoiseMaterial" Shader="TextureShader">
              <Textures>
                <MaterialTexture Texture="NoiseBitmap" TextureScale="2 2 1" TextureWrapMode="1" TexCoords="1"/>
              </Textures>
            </Material>
            <Material Name="ZCellMaterial" Comment="Why so blue?" Shader="TextureShader">
              <Textures>
                <MaterialTexture Texture="CellBitmap" TextureScale="4 4 1" TextureWrapMode="1" TexCoords="1"/>
              </Textures>
            </Material>
            <Shader Name="TextureShader">
              <VertexShaderSource>
<![CDATA[precision mediump float;

varying vec2 tc;

//The variables below are predefined in ZGE
uniform mat4 modelViewProjectionMatrix;
uniform mat4 textureMatrix;

attribute vec3 position;    //vertex position
attribute vec2 texCoord;  //vertex texture coordinate
//attribute vec3 normal;    //vertex normal

void main() {
  tc=(textureMatrix * vec4(texCoord,0,1)).xy;

  // project the transformed position
  vec4 p = modelViewProjectionMatrix * vec4(position, 1.0);
  gl_Position = p;
}]]>
              </VertexShaderSource>
              <FragmentShaderSource>
<![CDATA[precision mediump float;

varying vec2 tc;

uniform sampler2D tex1;

void main() {
  gl_FragColor = texture2D(tex1,tc);
}]]>
              </FragmentShaderSource>
            </Shader>
          </Children>
        </Group>
      </Children>
    </Group>
  </Content>
</ZApplication>
I'm this close to move on to Godot... :roll:
User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: Questions about ES2/GL3 shaders

Post by Kjell »

Hi Ats,
Ats wrote: Thu Jun 03, 2021 12:54 pmBut I really don't understand why the noise bitmap is working on PC, but not on Android. It's just white.
Could you try adding a BitmapExpression containing "Pixel.A = 1" to your NoiseBitmap? So, like this:

Code: Select all

ZZDC<?xml version="1.0" encoding="iso-8859-1" ?>
<Bitmap Name="NoiseBitmap" Width="256" Height="256" Filter="2">
  <Producers>
    <BitmapNoise StartingOctaves="2" Octaves="4" Offset="0.4" Persistence="0.5" Tile="255"/>
    <BitmapExpression Expression="Pixel.A = 1;"/>
  </Producers>
</Bitmap>
The BitmapNoise component doesn't affect the alpha channel so it ends up being 0 .. not 100% if that's causing the Android problem though.

K
User avatar
Ats
Posts: 764
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about ES2/GL3 shaders

Post by Ats »

Oh, nice one. I keep forgetting about that... So now it is displaying, but it's a weird cell bitmap instead of the noise bitmap :shock:

Screenshot_20210603-154818.png
Screenshot_20210603-154818.png (85.41 KiB) Viewed 17658 times

Edit:
And if I add the directive #version 330 (I tried from 100 to 330), the whole screen is white on Android.
User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: Questions about ES2/GL3 shaders

Post by Kjell »

Hi Ats,
Ats wrote: Thu Jun 03, 2021 1:51 pmSo now it is displaying, but it's a weird cell bitmap instead of the noise bitmap :shock:
No idea what's causing that .. maybe Ville can chime in?
Ats wrote: Thu Jun 03, 2021 1:51 pmAnd if I add the directive #version 330 (I tried from 100 to 330), the whole screen is white on Android.
GLSL ES 3.3 doesn't exist ( yet ). The latest version is 3.2 released in 2019. And if you want to target that you should use "#version 320 es".

Perhaps it would be good to decide which OpenGL / OpenGL ES version you want to target first? What kind of shader features / effects do you want to use in your game?

K
User avatar
Ats
Posts: 764
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about ES2/GL3 shaders

Post by Ats »

I'd like basic stuff to display correctly on computer and Android. And as I get it, compatible mode isn't working on Android.

But when ES2/GL3 is activated, everything gets complicated to display: shapes, textures, light ... That's why I'm experimenting.

So right now, I'm just trying to make a little library of basic shaders that are working on most devices.

And if I manage to get how this work, the ultimate goal would be to handle shadow mapping.
User avatar
VilleK
Site Admin
Posts: 2356
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Re: Questions about ES2/GL3 shaders

Post by VilleK »

Kjell wrote: Thu Jun 03, 2021 3:39 pm No idea what's causing that .. maybe Ville can chime in?
Never seen anything like that. It is almost like the OpenGL driver itself chooses to display a test-mode texture instead of everything appearing black which is what usually happens when something goes wrong. I follow this thread but so far I have not been able to contribute. Finding a good set of OpenGL features to stick to for maximum compatibility is hard.
User avatar
Ats
Posts: 764
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about ES2/GL3 shaders

Post by Ats »

If I add the directive #version 300 es to the shader, I get a white screen on the phone too.
I even tried to play with different combinations in the horrible AndroidManifest.xml file such as:
<uses-feature android:glEsVersion="0x00030000" android:required="true" />

Before, that setting was <uses-feature android:glEsVersion="0x00020000" android:required="true" />
Which should correspond to #version 100 ???
https://fr.wikipedia.org/wiki/OpenGL_Shading_Language

I found another *hidden* interesting document: https://www.fsynth.com/pdf/webgl2_glsl_1.pdf
Which says: “#version 300 es” must appear in the first line of a shader program written in GLSL ES version 3.00. If omitted, the shader will be treated as targeting version 1.00.

Maybe its common knowledge, but it's the first time I see this capital information.
This is a complete mess. Tutorials are talking about "ES" version numbers without telling if it's OpenGL ES or GLSL ES, which have scrambled versioning number before 330. That and my simple example not working... I can't tell if it's a version problem, a hardware problem, a ZGE problem... This is even worse than the API version thing to create Android packages...

Even though old Android devices are still here, they have a 100% tendency to die from dropping to the floor or dead battery in the long term.
https://developer.android.com/guide/top ... ics/opengl
There is no point in supporting dead devices.

So I really don't know if I should stick to :
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
and no version (or #version 100 ?)
and get a broken texture.

or if I should jump to something more recent (5 years already for #version 300 es)
and get a white screen.

or, I don't know, #version 320 es
and try to overcome those error messages :

Code: Select all

0(5) : warning C7555: 'varying' is deprecated, use 'in/out' instead
0(11) : warning C7555: 'attribute' is deprecated, use 'in/out' instead
0(11) : error C7614: GLSL ES doesn't allow use of reserved word attribute
0(12) : warning C7555: 'attribute' is deprecated, use 'in/out' instead
0(12) : error C7614: GLSL ES doesn't allow use of reserved word attribute
0(5) : warning C7555: 'varying' is deprecated, use 'in/out' instead
0(11) : warning C7555: 'attribute' is deprecated, use 'in/out' instead
0(11) : error C7614: GLSL ES doesn't allow use of reserved word attribute
0(12) : warning C7555: 'attribute' is deprecated, use 'in/out' instead
0(12) : error C7614: GLSL ES doesn't allow use of reserved word attribute
Since it supposed to be backward compatible, maybe I should stick to #version 100 ... But then again, documentation and examples for that old version have a tendency to die too on the internet.
User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: Questions about ES2/GL3 shaders

Post by Kjell »

Hi Ats,

The error messages are caused by the fact that the "varying" and "attribute" keywords have been deprecated & replaced by "in" and "out" since GLSL ES 3.0. By the way, all of the official documentation on OpenGL ES can be found here. And in case you're just looking for the reference cards of various GLSL ES versions:

OpenGL ES 2.0 / OpenGL ES Shading Language 1.0 ( Page 3 )
OpenGL ES 3.0 / OpenGL ES Shading Language 3.0 ( Page 4 )
OpenGL ES 3.1 / OpenGL ES Shading Language 3.1 ( Page 5 )
OpenGL ES 3.2 / OpenGL ES Shading Language 3.2 ( Page 6 )

Which version you want to target is ultimately up to you but personally i'd always target the lowest version that has all the features i need.

K
User avatar
Ats
Posts: 764
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about ES2/GL3 shaders

Post by Ats »

I choose you, OpenGL ES 2.0 / OpenGL ES Shading Language 1.0 :lol:

Thanks for the cheat sheets. Those are really handy!

So I'm back to the texture problem on Android. Ville, where in the ZGE source code could I check how shaders are handled differently from computer to Android?
User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: Questions about ES2/GL3 shaders

Post by Kjell »

Hi Ats,
Ats wrote: Fri Jun 04, 2021 12:01 pmwhere in the ZGE source code could I check how shaders are handled differently from computer to Android?
There's no difference. Shader sources are send to the OpenGL driver in plain-text and compiled by the driver itself. So it just depends on which OpenGL driver a device uses.

K
User avatar
Ats
Posts: 764
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about ES2/GL3 shaders

Post by Ats »

Then it has to come from the ZGE generated bitmaps.
I tried displaying a BitmapFromFile with it, and it's working perfectly fine.

BitmapCells appears blueish on computer and android
BitmapNoise doesn't show up on Android
BitmapPixels crashes on Android
BitmapRect appears twice smaller and white on computer and crashes on Android
Last edited by Ats on Fri Jun 04, 2021 1:05 pm, edited 1 time in total.
User avatar
VilleK
Site Admin
Posts: 2356
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Re: Questions about ES2/GL3 shaders

Post by VilleK »

Ats wrote: Fri Jun 04, 2021 12:53 pm BitmapCells appears blueish on computer and android
BitmapNoise doesn't show up on android
BitmapPixels crashes on android
If this is on 64-bit Android then I wonder if there could be some 64-bit specific bug. Can you please try the 64-bit ZGE build that I posted in the "classes" thread and check if you can reproduce any problem on computer?
Post Reply