Questions about ES2/GL3 shaders

All topics about ZGameEditor goes here.

Moderator: Moderators

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

Questions about ES2/GL3 shaders

Post 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
Last edited by Ats on Thu Jun 03, 2021 10:32 am, edited 2 times 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: 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
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about GLES2 shaders

Post 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 20128 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 20128 times
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: 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
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about GLES2 shaders

Post 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.
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: 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
User avatar
VilleK
Site Admin
Posts: 2355
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Re: Questions about GLES2 shaders

Post 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?
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about GLES2 shaders

Post 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.
User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: Questions about GLES2 shaders

Post 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
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about GLES2 shaders

Post 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 524 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... :?
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: 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
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about GLES2 shaders

Post by Ats »

Oh, all right, that make perfect sense now. Thanks :wink:
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about GLES2 shaders

Post 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.
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 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
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about GLES2 shaders

Post 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
Post Reply