Page 1 of 6

Questions about ES2/GL3 shaders

Posted: Tue May 25, 2021 10:01 am
by Ats
Hi. I'm currently pushing Omeganaut to GLES2. I managed to display almost everything but I have questions regarding shaders.

Here's a little example:

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" GLBase="1" FileVersion="2">
  <OnLoaded>
    <ZExternalLibrary ModuleName="opengl32">
      <BeforeInitExp>
<![CDATA[//

if(ANDROID)
{
  this.ModuleName = "libGLESv1_CM.so";
}
else if(LINUX)
{
  this.ModuleName = "libGL.so";
}
else
{
  this.ModuleName = "opengl32";
}]]>
      </BeforeInitExp>
      <Source>
<![CDATA[//

const int GL_BLEND = 0x0BE2;
const int GL_SRC_ALPHA = 0x0302;
const int GL_ONE_MINUS_SRC_ALPHA = 0x0303;

void glEnable(int cap){}
void glBlendFunc(int sfactor, int dfactor){}]]>
      </Source>
    </ZExternalLibrary>
    <ZExpression>
      <Expression>
<![CDATA[//

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);]]>
      </Expression>
    </ZExpression>
  </OnLoaded>
  <OnRender>
    <RenderTransformGroup Comment="ground" Translate="0 -1 0" Rotate="-0.2 0 0">
      <Children>
        <UseMaterial Material="GroundMaterial"/>
        <RenderMesh Mesh="GoundMesh"/>
      </Children>
    </RenderTransformGroup>
    <RenderTransformGroup Comment="sphere basic" Translate="-4 0 0">
      <Children>
        <UseMaterial Material="BasicMaterial"/>
        <RenderMesh Mesh="SphereMesh"/>
      </Children>
    </RenderTransformGroup>
    <RenderTransformGroup Comment="sphere flat shadow">
      <Children>
        <UseMaterial Material="FlatShadowMaterial"/>
        <RenderMesh Mesh="SphereMesh"/>
      </Children>
    </RenderTransformGroup>
    <RenderTransformGroup Comment="sphere alpha" Translate="4 0 0">
      <Children>
        <UseMaterial Material="AlphaMaterial"/>
        <RenderMesh Mesh="SphereMesh"/>
      </Children>
    </RenderTransformGroup>
  </OnRender>
  <Content>
    <Mesh Name="SphereMesh">
      <Producers>
        <MeshSphere ZSamples="32" RadialSamples="32"/>
      </Producers>
    </Mesh>
    <Mesh Name="GoundMesh">
      <Producers>
        <MeshBox Scale="10 10 1" Grid2DOnly="255"/>
      </Producers>
    </Mesh>
    <Bitmap Name="GroundBitmap">
      <Producers>
        <BitmapCells/>
      </Producers>
    </Bitmap>
    <Material Name="GroundMaterial" Shader="TextureShader">
      <Textures>
        <MaterialTexture Texture="GroundBitmap" TextureScale="10 10 1" TextureWrapMode="1"/>
      </Textures>
    </Material>
    <Material Name="AlphaMaterial" Shader="AlphaShader"/>
    <Material Name="BasicMaterial" Shader="TextureShader">
      <Textures>
        <MaterialTexture Texture="GroundBitmap"/>
      </Textures>
    </Material>
    <Material Name="FlatShadowMaterial" Shading="1" EmissionColor="1 1 1 1" Shader="FlatShadowShader"/>
    <Shader Name="BasicShader">
      <VertexShaderSource>
<![CDATA[//

precision mediump float;

varying vec4 colorVar;

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

void main()
{
  colorVar = color;

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

precision mediump float;

varying vec4 colorVar;

void main() {
  gl_FragColor = colorVar;
}]]>
      </FragmentShaderSource>
    </Shader>
    <Shader Name="FlatShadowShader">
      <VertexShaderSource>
<![CDATA[//

precision mediump float;

varying vec4 colorVar;

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

void main()
{
  colorVar = color;

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

precision mediump float;

varying vec4 colorVar;

void main() {
  gl_FragColor = colorVar;
}]]>
      </FragmentShaderSource>
    </Shader>
    <Shader Name="AlphaShader">
      <VertexShaderSource>
<![CDATA[//

precision mediump float;

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

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

void main() {
  gl_FragColor = vec4(0.0, 0.0, 0.0, 0.6);
}]]>
      </FragmentShaderSource>
    </Shader>
    <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>
  </Content>
</ZApplication>
Here's my three spheres:
1- The first should display the same texture as the ground, but it is black instead.
2- I don't get how to display flat shadow on the sphere as it is rendered in normal ZGE.
3- I managed to make the third sphere semi transparent, so I'm quite happy with that 8)

I have a few other questions, but let's do that one per one :lol:

Thanks

Re: Questions about GLES2 shaders

Posted: Tue May 25, 2021 11:07 am
by Kjell
Hi Ats,
Ats wrote: Tue May 25, 2021 10:01 amThe first should display the same texture as the ground, but it is black instead.
You can't use "Generated" TexCoords ( which uses glTexGen ) in OpenGL ES, you have to use "ModelDefined". However, a MeshSphere doesn't generate texture coordinates for the mesh ( not sure why ) so you need to generate those using a MeshExpression.
Ats wrote: Tue May 25, 2021 10:01 amI don't get how to display flat shadow on the sphere as it is rendered in normal ZGE.
Not exactly sure what you mean, can you post a example / screenshot of what you're referring to made with "normal" ZGE?

K

Re: Questions about GLES2 shaders

Posted: Tue May 25, 2021 2:58 pm
by Ats
You can't use "Generated" TexCoords ( which uses glTexGen ) in OpenGL ES
All right, I didn't know that. But putting it to ModelDefined doesn't light up the sphere. It's still black in preview, and white in release. No texture.
Not exactly sure what you mean
Sorry, I was talking about flat shading on the Material for compatible GLBase. But I reckon that a sphere isn't the best object to test that... :lol:
Capture d’écran (241).png
Capture d’écran (241).png (10.41 KiB) Viewed 17471 times
My guess is that it has to be calculated within the shader?


Oh, and there's also this weird taint on the whole scene in release mode:
Capture d’écran (240).png
Capture d’écran (240).png (377.69 KiB) Viewed 17471 times

Re: Questions about GLES2 shaders

Posted: Tue May 25, 2021 3:42 pm
by Kjell
Hi Ats,
Ats wrote: Tue May 25, 2021 2:58 pmBut putting it to ModelDefined doesn't light up the sphere. It's still black in preview, and white in release. No texture.
As mentioned, that's because MeshSphere doesn't generate any texture coordinates, so the bottom-left pixel ( texCoord 0,0 ) of your texture ends up being used for the entire mesh. You need to add a MeshExpression and assign texture coordinates yourself .. or alternatively do the equivalent of glTexGen in your vertex shader.
Ats wrote: Tue May 25, 2021 2:58 pmSorry, I was talking about flat shading on the Material for compatible GLBase.
Flat shading is actually a little cumbersome in ES 2.0 because glShadeModel isn't available. The most common approach is to just have 3 normals for each flat triangle, even though that increases the amount of vertex data a bit.
Ats wrote: Tue May 25, 2021 2:58 pmOh, and there's also this weird taint on the whole scene in release mode
Your BitmapCells texture is different in each of those 2 screenshots :wink:

K

Re: Questions about GLES2 shaders

Posted: Tue May 25, 2021 4:35 pm
by Ats
That's because MeshSphere doesn't generate any texture coordinates
Oh. So MeshSphere can't do that, but rounded MeshCube can. Maybe that should be mentioned in the ZGameEditor Help :lol:
The most common approach is to just have 3 normals for each flat triangle
Thanks for the hint. I'm currently reading some tutorials about that technique.
Your BitmapCells texture is different in each of those 2 screenshots
And I really don't get what's going on. I tried with BitmapNoise, and it doesn't have that problem. Although I had to apply BitmapBlur on BitmapNoise, otherwise it was invisible... I don't get the logic.

Re: Questions about GLES2 shaders

Posted: Tue May 25, 2021 5:10 pm
by Kjell
Hi Ats,
Ats wrote: Tue May 25, 2021 4:35 pmOh. So MeshSphere can't do that, but rounded MeshCube can.
You can still use MeshSphere if you want .. you just need to add a MeshExpression where you assign the texture coordinates yourself. Here's a simple example:

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" CameraPosition="0 4 10" CameraRotation="0.05 0 0" LightPosition="1 0 1" FileVersion="2">
  <OnLoaded>
    <SpawnModel Model="Top"/>
  </OnLoaded>
  <Content>
    <Model Name="Top">
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[//

Top.Rotation.X = sin(App.Time*2)/32-0.25;
Top.Rotation.Z = cos(App.Time*2)/32;

//

TopTransform.Rotate.Z = App.Time*1.5;]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
      <OnRender>
        <UseMaterial Material="TopMaterial"/>
        <RenderTransform Name="TopTransform"/>
        <RenderMesh Mesh="TopMesh"/>
      </OnRender>
    </Model>
    <Mesh Name="TopMesh">
      <Producers>
        <MeshSphere ZSamples="3" RadialSamples="16"/>
        <MeshExpression AutoNormals="0" HasTexCoords="255">
          <Expression>
<![CDATA[//

float a = atan2(V.X, V.Y);

TexCoord.X = frac(a/PI*4)*2;
TexCoord.Y = V.Z;

//

V.Z += 1;]]>
          </Expression>
        </MeshExpression>
      </Producers>
    </Mesh>
    <Bitmap Name="TopBitmap" Width="32">
      <Producers>
        <BitmapCells PointsPlacement="1" UsedMetrics="1" RandomSeed="9" BorderPixels="0" PointCount="1"/>
      </Producers>
    </Bitmap>
    <Material Name="TopMaterial">
      <Textures>
        <MaterialTexture Texture="TopBitmap" TexCoords="1" Origin="0 0 0"/>
      </Textures>
    </Material>
  </Content>
</ZApplication>
K

Re: Questions about GLES2 shaders

Posted: Wed May 26, 2021 7:11 am
by VilleK
Indeed the MeshSphere does not generate tex coords automatically because I was not sure of the correct way to do this. @Kjell: I can use your method if you think it is generic enough?

Re: Questions about GLES2 shaders

Posted: Wed May 26, 2021 1:03 pm
by Ats
That would be nice, indeed :)

I have another question before going further: why the alpha transparency shader is working on App.OnRender, but not in Model.Onrender?
I made a quick example out of it:

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" GLBase="1" FileVersion="2">
  <OnLoaded>
    <ZExternalLibrary ModuleName="opengl32">
      <BeforeInitExp>
<![CDATA[//

if(ANDROID)
{
  this.ModuleName = "libGLESv1_CM.so";
}
else if(LINUX)
{
  this.ModuleName = "libGL.so";
}
else
{
  this.ModuleName = "opengl32";
}]]>
      </BeforeInitExp>
      <Source>
<![CDATA[//

const int GL_BLEND = 0x0BE2;
const int GL_SRC_ALPHA = 0x0302;
const int GL_ONE_MINUS_SRC_ALPHA = 0x0303;

void glEnable(int cap){}
void glBlendFunc(int sfactor, int dfactor){}]]>
      </Source>
    </ZExternalLibrary>
    <ZExpression>
      <Expression>
<![CDATA[//

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

model m = createModel(SphereModel);
m.Position.X = 3;]]>
      </Expression>
    </ZExpression>
  </OnLoaded>
  <OnRender>
    <RenderTransformGroup Comment="ground" Translate="0 -1 0" Rotate="-0.2 0 0">
      <Children>
        <UseMaterial Material="GroundMaterial"/>
        <RenderMesh Mesh="GoundMesh"/>
      </Children>
    </RenderTransformGroup>
    <RenderTransformGroup Comment="sphere alpha" Translate="-3 0 0">
      <Children>
        <UseMaterial Material="AlphaMaterial"/>
        <RenderMesh Mesh="SphereMesh"/>
      </Children>
    </RenderTransformGroup>
  </OnRender>
  <Content>
    <Mesh Name="SphereMesh">
      <Producers>
        <MeshSphere ZSamples="32" RadialSamples="32"/>
      </Producers>
    </Mesh>
    <Mesh Name="GoundMesh">
      <Producers>
        <MeshBox Scale="10 10 1" Grid2DOnly="255"/>
      </Producers>
    </Mesh>
    <Bitmap Name="GroundBitmap">
      <Producers>
        <BitmapCells/>
      </Producers>
    </Bitmap>
    <Material Name="GroundMaterial" Shader="TextureShader">
      <Textures>
        <MaterialTexture Texture="GroundBitmap" TextureScale="10 10 1" TextureWrapMode="1"/>
      </Textures>
    </Material>
    <Material Name="AlphaMaterial" Shader="AlphaShader"/>
    <Shader Name="AlphaShader">
      <VertexShaderSource>
<![CDATA[//

precision mediump float;

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

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

void main() {
  gl_FragColor = vec4(0.0, 0.0, 0.0, 0.6);
}]]>
      </FragmentShaderSource>
    </Shader>
    <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>
    <Model Name="SphereModel">
      <OnRender>
        <UseMaterial Material="AlphaMaterial"/>
        <RenderMesh Mesh="SphereMesh"/>
      </OnRender>
    </Model>
  </Content>
</ZApplication>
Edit: Ok, it seems to come from App.RenderOrder (ModelsBeforeApp / AppBeforeModels)
ModelsBeforeApp : Only the App.OnRender is transparent.
AppBeforeModels : Both are transparents.

Re: Questions about GLES2 shaders

Posted: Wed May 26, 2021 1:25 pm
by Kjell
Hi guys,
Ats wrote: Wed May 26, 2021 1:03 pmwhy the alpha transparency shader is working on App.OnRender, but not in Model.Onrender?
You mean when previewing SphereModel? Transparency does actually work, but it's not very "pronounced" due to the background color and your alpha value.

Image
VilleK wrote: Wed May 26, 2021 7:11 amI can use your method if you think it is generic enough?
It's not generic, it only works for a "UFO" shape with a repeating texture. I can whip up a standard UV sphere example if you want though.

K

Re: Questions about GLES2 shaders

Posted: Wed May 26, 2021 1:35 pm
by Ats
You mean when previewing SphereModel?
No, I mean when rendering the sphere directly on App.OnRender, or rendering it inside a Model on Model.OnRender


Here's where I am now (I had to attach it, as bitmap font is too long for the forum)
GLES2Showroom.zgeproj
(244.54 KiB) Downloaded 335 times

And another weird thing is happening: when you press SPACEBAR to display the text, alpha shader cease to work. I'd really like to understand why... :?

Re: Questions about GLES2 shaders

Posted: Wed May 26, 2021 2:03 pm
by Kjell
Hi Ats,
Ats wrote: Wed May 26, 2021 1:35 pmAnd another weird thing is happening: when you press SPACEBAR to display the text, alpha shader cease to work. I'd really like to understand why... :?
It's because you're enabling blending once in your App.OnLoaded and then RenderText overrides the OpenGL blend state and doesn't restore it properly ( similar problem to the other thread ). Also because all Materials in your "showroom" use no blending ( and ZGE doesn't know about your OpenGL call ) it doesn't do anything about the blending state when switching Materials.

However, since it's unlikely that everything in your project will use the same blending mode you shouldn't set the blending mode in App.OnLoaded to begin with.

K

Re: Questions about GLES2 shaders

Posted: Wed May 26, 2021 2:26 pm
by Ats
Oh, all right, that make perfect sense now. Thanks :wink:

Re: Questions about GLES2 shaders

Posted: Thu May 27, 2021 9:27 am
by Ats
What would be the logic to update the light shader, so the cube doesn't rotate with his shadows stuck on it?
I've read many explanations, but since GLES2 is aging from 2006, they are not for the same GLES version, or engine, and most of all, they are very different one from another.

Re: Questions about GLES2 shaders

Posted: Thu May 27, 2021 10:41 am
by Kjell
Hi Ats,
Ats wrote: Thu May 27, 2021 9:27 amWhat would be the logic to update the light shader, so the cube doesn't rotate with his shadows stuck on it?
What light shader are you referring to? I looked at all the examples you posted in this thread but i can't find a light shader.
Ats wrote: Thu May 27, 2021 9:27 amI've read many explanations, but since GLES2 is aging from 2006, they are not for the same GLES version, or engine, and most of all, they are very different one from another.
You can target any OpenGL version you want with ZGE. So if you want to use features from OpenGL 4.6 or OpenGL ES 3.2 that's entirely up to you. However, GLSL hasn't changed all that much over the years .. so any major differences are likely due to people just using a different approach.

K

Re: Questions about GLES2 shaders

Posted: Thu May 27, 2021 10:52 am
by Ats
Let's say, the phong one. The light isn't moving, the cube is rotating, and the light (maybe I don't have the correct vocabulary) on the cube is rotating with it instead of staying under the cube.
You can target any OpenGL version you want with ZGE.
No way :lol:...
I'll try other things then. I was sure I had to stick to version 120 because of the name ES2/GL3... But now I realize my mistake.
But if I target Android phones (recent ones, not dinosaurs), should I stick to version 120, or more recent ones, such as 330?

Edit: 330 seems to work with GLES3: https://en.wikipedia.org/wiki/OpenGL_Shading_Language
Would it work? This is so confusing.

Wow, GLES2 is aging from Android 2.2: https://developer.android.com/guide/top ... ics/opengl