Questions about ES2/GL3 shaders

All topics about ZGameEditor goes here.

Moderator: Moderators

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

Re: Questions about ES2/GL3 shaders

Post by Ats »

All right, I think I'm bumping against the logic of all this:
How would you pass the color of a Material to the Shader then? Passing it through a generic Array isn't possible since the Material has to be called specifically per model. For example:

LightColorSpecular[0][0,0] = MaterialWood.SpecularColor.R;
LightColorSpecular[0][0,1] = MaterialWood.SpecularColor.G;
LightColorSpecular[0][0,2] = MaterialWood.SpecularColor.B;

Imagine this with several models and materials. This is just a future nest of errors :|
User avatar
Kjell
Posts: 1876
Joined: Sat Feb 23, 2008 11:15 pm

Re: Questions about ES2/GL3 shaders

Post by Kjell »

Hi Ats,
Ats wrote: Fri Jun 18, 2021 4:38 pmHow would you pass the color of a Material to the Shader then?
The color of a material already gets passed to a ES2/GL3 shader automatically by ZGE ( uniform vec4 globalColor ) :wink: But if you'd for example want to pass the specular color i'd personally use a function. You could either write a function that "replaces" your UseMaterial components / calls, so something like:

Code: Select all

void UseMaterial(Material m)
{
  @UseMaterial(Material: m);

  ShaderData[0][0,0] = m.SpecularColor.R;
  ShaderData[0][0,1] = m.SpecularColor.G;
  ShaderData[0][0,2] = m.SpecularColor.B;
}
.. or you can choose to write & use a accompanying function:

Code: Select all

void UpdateShaderData(Material m)
{
  ShaderData[0][0,0] = m.SpecularColor.R;
  ShaderData[0][0,1] = m.SpecularColor.G;
  ShaderData[0][0,2] = m.SpecularColor.B;
}
Of course you could also take a entirely different route by storing all your material color values in a single texture and then just pass a identifier to your shader .. but it really depends on your project and what you want to do.

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

Re: Questions about ES2/GL3 shaders

Post by Ats »

Thanks. I'll use that in due time. Today I worked a bit on diffuse light shader. Here's where I am.
The weird thing is that the results are different on PC and Android, again.

Here's the result on PC:
Capture d’écran (261).png
Capture d’écran (261).png (77.5 KiB) Viewed 14857 times
And on Android:
Screenshot_20210703-143906.png
Screenshot_20210703-143906.png (70.97 KiB) Viewed 14857 times
I think I did it right, but I'm not sure... Frankly, there are too many parameters that are called more or less the same :lol:

Code: Select all

//
#ifdef GL_ES
  precision mediump float;
#endif

uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform mat3 normalMatrix;
uniform vec4 globalColor;

attribute vec4 position, color; // vertex position & color
attribute vec3 normal;   // vertex normal

varying vec3 N;
varying vec3 v;

void main(void)
{
  v = vec3(modelViewMatrix * position);
  N = normalize(normalMatrix * normal);
  gl_Position = modelViewProjectionMatrix * position;
}

Code: Select all

//
#ifdef GL_ES
  precision mediump float;
#endif

varying vec3 N;
varying vec3 v;

uniform vec4 globalColor; // = Material.Color
uniform mat4 lightPosition;
uniform mat4 lightColorAmbient;

void main (void)
{
  // Light position
  vec3 LPosition = vec3(lightPosition[0][0], lightPosition[0][1], lightPosition[0][2]);
  vec3 L = normalize(LPosition.xyz - v);

  //calculate Diffuse Term
  vec4 LAmbient = vec4(lightColorAmbient[0][0], lightColorAmbient[0][1], lightColorAmbient[0][2], 1.0);
  vec4 LDiffuse = globalColor * LAmbient;
  vec4 Idiff = LDiffuse * max(dot(N,L), 0.0);
  Idiff = clamp(Idiff, 0.0, 1.0);

  gl_FragColor = Idiff;
}
And the whole project:
Attachments
GLES2Showroom.zgeproj
(326.29 KiB) Downloaded 274 times
User avatar
Kjell
Posts: 1876
Joined: Sat Feb 23, 2008 11:15 pm

Re: Questions about ES2/GL3 shaders

Post by Kjell »

Hi Ats,
Ats wrote: Sat Jul 03, 2021 12:50 pmThe weird thing is that the results are different on PC and Android, again.
Looks like the same problem as before .. semi-transparent pixels blending the white background of the Android activity ( or whatever is causing that behavior on Android ). Perhaps you can try re-writing the shader from scratch ( i'd recommend starting with a blank project ) and test it a number of times along the way to see what's causing it to act up?

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

Re: Questions about ES2/GL3 shaders

Post by Ats »

Problem is, since it's the same project, I already set the C.A = 1;
I just verified something: empty project is a black window on PC, while it is a white screen on Android. Wouldn't it be simpler to set the background of the Android Activity to black instead, so it acts the same as PC?
I'm going to experiment with ZgeActivity.java

Edit: results here http://www.emix8.org/forum/viewtopic.php?f=6&t=1560
User avatar
Ats
Posts: 603
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about ES2/GL3 shaders

Post by Ats »

I've almost finished "porting" Omeganaut to ES2/GL3 and I have three last problems:
- I can't display sprites correctly (colors + transparency). It's either one or the other. I tried the fontShader and the TextureShader in my "GLES2ShowRoom"
- Same goes for the particles, but I think this is the exact same problem as above
- And last but not least, the fog. This code don't work anymore:

Code: Select all

if (ANDROID) glFogx(GL_FOG_MODE, GL_LINEAR);
else         glFogi(GL_FOG_MODE, GL_LINEAR);

glFogfv(GL_FOG_COLOR, FogColor);
glFogf(GL_FOG_START, 100);
glFogf(GL_FOG_END, 500);
glEnable(GL_FOG);
Do you have any clues for that?
User avatar
Kjell
Posts: 1876
Joined: Sat Feb 23, 2008 11:15 pm

Re: Questions about ES2/GL3 shaders

Post by Kjell »

Hi Ats,
Ats wrote: Sun Jul 18, 2021 12:30 pmI can't display sprites correctly (colors + transparency).
Perhaps you forgot to multiply the texture coordinates by the texture matrix? In any case, here's a quick GL3 example:

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" GLBase="1" ClearColor="0 0.502 1 1" CameraPosition="0 3 10" FileVersion="2">
  <OnLoaded>
    <SpawnModel Model="Player"/>
  </OnLoaded>
  <Content>
    <Model Name="Player" Scale="0.125 0.125 1">
      <Definitions>
        <Variable Name="PlayerFrame"/>
      </Definitions>
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[//

PlayerFrame += 10*App.DeltaTime;
while(PlayerFrame >= 4)PlayerFrame -= 4;

//

PlayerSprite.SpriteIndex = PlayerFrame;]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
      <OnRender>
        <UseMaterial Material="PlayerMaterial"/>
        <RenderSprite Name="PlayerSprite" SpriteSheet="PlayerSpriteSheet"/>
      </OnRender>
    </Model>
    <SpriteSheet Name="PlayerSpriteSheet" Bitmap="PlayerBitmap">
      <SpriteData>
<![CDATA[78DA636060609067D063E06330645000B24519F419B8190C18CC806C71065D20DB90C10FC816038A81C4013CA402B1]]>
      </SpriteData>
    </SpriteSheet>
    <Bitmap Name="PlayerBitmap" Width="100" Height="48" Filter="1">
      <Producers>
        <BitmapFromFile Transparency="2" HasAlphaLayer="1" DataWidth="100" DataHeight="48">
          <BitmapFile>
<![CDATA[78DAED5C319613310C9D63506E49C931B6A4A4DC9272CB3D022547A0DC724B8EC01128292929D385F5E03FFCF9916DD963E5E5F128FC32C966247D7D49B6E5C99ECFE7E5FC7F4C1B1FDF2CE7AF0F77EBE0EB7F1D2FBFDE926D3F3EBF3F9FBE7D5A477A8FEB5E4ED2BDB784AD645FC2F5EBE5717D4DD86F25F660DBEAFF9FDFFF8CCC45BAEEB113BCDE6A5E71DE272ED248F646C40F78EF8DCF2D378807F8742437107351F88EDC073E12BE682EE0BFDE5A8858613E46EA29E7C66C8C3AB78DCC11161F5175957DD16BB7F251B2B3159F6BCD7B95111173EC47606BE9E07BB86EE0B31E3B7BEA0EB840FEF572B2F19173C3E2033A3C7C8CE69707238F960E8D51ADE718CBE2F3B1D7A7BA36EAE544EF573EBC75086B028E0B4F5C257FD47CA23506185B3659358307DFDFE2C4CB07AFDBB6F5518ECFD6FDB081F38BF9849DD6DC54F2B3C589759F7251E38473036B05D4C552CE421ECF1F5AAFD8466F4CB4626CE74BAC55F31AD5C307DBECE1A35533980FE02DF1A27C401FFBC5CA0DAE8DD65A6E95F1F0F6ACF8583FD7E724DB13138CBF149B6C67B26FDDC7E51C41EC943861BBAD9859FD93FFCEB1657153E384B949F298EB6DBCDCEFF45873AFEE4D753DAE3C3017C0063B387E373EF2BDC5D8155FA97DAC037CE07BD085EB221FC90FAF7A2CFE57FDE427D58D9CB26A8655ABD377579959DFC637F4901DCA39FC57DBD7301EF0A1B9B51BCC07EC781D55D9159E773A724E688CB5D6A9F085FA61E503D80CBE340EAA7E2239EC777E5F8A0BAF8E1227261F54D791731C7B55D986DC0BAEA93EB13D9E75E4F67DE264E7ABFCF79A9F5A3D2EB6E9E974B7E7E075AC9F49DEE81AC5BBDF573EAC3A8BF903730FDBE692BD2C17796F72C13817FFDA5FE374E583FD54885DAE5B1E1D499ECADCF4C87BCDD59EBD8AD608ABCEE26F4917F0B662986B556D9EDBEA5F9639623FD7107EC5357CA63678F77C251C5C7B216FE36719EB4DEA5E5E6398E762F8CBBBB768F1AB3C8CF47838FF70AFCE53255F797B0E2D1C9A0FA3E72F3ACFEEF89075A7E679AD1763F5852113F2C045496EAFFD7CAF550F75FDC56BE31E1FE91A58FB35477A921A4B353ED4167C9FD7B356BE95D6B4163EEDE9D7D6563C6FAA3F4A7CE07B1A833D3E627DB095D72747F96099B04FF9BF8873FAAEF67ED97E8B8F524D518CADFA65ED27C1B7F20F39DC8FF7D613CE25DD035C7C4EFA8EF0A1F3049FB799EB44A901161F5A3BF8FBD6BED0EA27EADEBED417B2E63A6BFDCF71D47DBE427DC05A7D9CC507C72EC70FE28EF7EA5CAFB40E5BFD733D3F5539D67BABFFD1EAD36BADE4A1393FC207F79CB8D766D59323F307EBDACEA3F52C9A7A3AB5BCAFF55BE12B956DCD01DAB3511F96FAEC3BF9744635C245930FCA379EAF46CF4E2EFAABD9C77ADEC631AB734D098375A6E195ABB5D0D263C592FA45E58FC42DF3C15C58F3DC8C73AC9DEFB21E0B8FD5636B9DA5A82CAF5CEF1A9E39660C25D923BEB2F664BCB6B4F689B3CE7675DD669D93F11EA887E71EB93DE7C2B5F5C02C5FE99C57DB0BCEC891DEFDA7F71CD53A6B988D45F7AA11BE2A9D315AFDB059CFA844E82CF5276762511D33E5EBD990EAE2DCD4F9F0483E46E8BC069648F949EEE387A775BCBBBB5F87B9B7E19E00CDF3A3CFD526BDD0374BE735B044D8ADF64336AE2D9E75DDCF39D8FB2C17FB6D96CE6B6089B0BB96DFE0BED437D13372DD977AF9607FCDD4198D25CA6EB51F7C737F7ED76F20DEB75CA43CECE503BA3066E8BC069608BB4B7CE31AFB7FEE316D31403D25AD8D47E68E193AAF8125C26E8B13E69CFB31DC37837C9C8BE9FB5E2E388E67E98CC41269776B8D054E77E71493F8D01ACC757886CE282CD176D7F2DC5AC7F16F4FB85F3AF29CBC6242BC1DD5198D25CAEE5E3DB573ECD13DBAE6FF2C9DD158A2ECAEFD660BF1C57AF859427E3FB23FD7F8E5715467249648BB15C3F3F2770087D503D5E72546FB252C5FF7BB4774466389B2BB860138D2EB298D2F0FD37BBCAC93F14167499FE7F9AB482C5176B73040DF89702896DDF3EF95E79C7BFCB6E9CCBAAC3E6DEB37209158A2ECAEE980DD1738040BDB9F3E7B5E96613E4C9D35BF39FD351B4B94DD251D271917FC1396512EBA7552CC71FC5A711C8D25CAEE929E933512DF16961C07BD5CB8742ABEE433C153D21D8D25CA6E979E6CE73644DF28174D6C864EC6E68DE3282C517697D6EFCF960EB23FE27F3AB4743E0FC471249628BB3DFBAA59CF951CD589DA7D4B588ED8FD1B294F7816]]>
          </BitmapFile>
        </BitmapFromFile>
      </Producers>
    </Bitmap>
    <Shader Name="PlayerShader">
      <VertexShaderSource>
<![CDATA[uniform mat4 modelViewProjectionMatrix;
uniform mat4 textureMatrix;
attribute vec3 position;
attribute vec2 texCoord;
varying vec2 t;

void main()
{
  gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);
  t = (textureMatrix * vec4(texCoord, 0.0, 1.0)).xy;
}]]>
      </VertexShaderSource>
      <FragmentShaderSource>
<![CDATA[uniform sampler2D tex1;
varying vec2 t;

void main()
{
  vec4 c = texture2D(tex1, t);

  if(c.a == 0.0)
  {
    discard;
  }

  gl_FragColor = c;
}]]>
      </FragmentShaderSource>
    </Shader>
    <Material Name="PlayerMaterial" Shading="1" Light="0" Shader="PlayerShader"/>
  </Content>
</ZApplication>
By the way, the "discard" part in the fragment shader ensures that fully transparent pixels get omitted. Since i'm using a spritesheet that only has fully opaque or fully transparent pixels this is faster than using a blending mode.
Ats wrote: Sun Jul 18, 2021 12:30 pmAnd last but not least, the fog.
All of the built-in fog features are deprecated in GL3/ES2, so you should simply use the screen-space depth coordinate ( gl_Position.z ) to calculate the fog depth and use that as a factor in your fragment color calculation.

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

Re: Questions about ES2/GL3 shaders

Post by Ats »

That's what I was doing, but thanks for the "discard" thing, this is neat :wink:
I believe the problem is coming from the RenderParticles.PColor that doesn't seem to be working.

I'm currently working on the fog, this should go relatively easy. Thanks for the explanations.
User avatar
Kjell
Posts: 1876
Joined: Sat Feb 23, 2008 11:15 pm

Re: Questions about ES2/GL3 shaders

Post by Kjell »

Hi Ats,
Ats wrote: Tue Jul 20, 2021 7:35 amI believe the problem is coming from the RenderParticles.PColor that doesn't seem to be working.
Hmm .. i'm not having any trouble with RenderParticles.PColor here. Does the following ES3 example work for you?

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" GLBase="1" FileVersion="2">
  <OnRender>
    <UseMaterial Material="ParticleMaterial"/>
    <RenderParticles ParticlesPerSecond="8" Spread="3.14" ParticleWidth="1" ParticleHeight="1" Speed="2" ParticleLifetime="2" Gravity="0 -8 0">
      <OnEmitExpression>
<![CDATA[//

PColor.R = rnd();
PColor.G = rnd();
PColor.B = rnd();
PColor.A = 1;]]>
      </OnEmitExpression>
    </RenderParticles>
  </OnRender>
  <Content>
    <Bitmap Name="ParticleBitmap">
      <Producers>
        <BitmapExpression>
          <Expression>
<![CDATA[//

float u, v;

u = 0.5-X;
v = 0.5-Y;

Pixel.R = 1;
Pixel.G = 1;
Pixel.B = 1;
Pixel.A = 2-sqrt(u*u+v*v)*4;]]>
          </Expression>
        </BitmapExpression>
      </Producers>
    </Bitmap>
    <Shader Name="ParticleShader">
      <VertexShaderSource>
<![CDATA[uniform mat4 modelViewProjectionMatrix;
attribute vec3 position;
attribute vec2 texCoord;
attribute vec4 color;
varying vec2 t;
varying vec4 c;

void main()
{
  t = texCoord;
  c = color;
  gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);
}]]>
      </VertexShaderSource>
      <FragmentShaderSource>
<![CDATA[uniform sampler2D tex1;
varying vec2 t;
varying vec4 c;

void main()
{
  gl_FragColor = c * texture2D(tex1, t);
}]]>
      </FragmentShaderSource>
    </Shader>
    <Material Name="ParticleMaterial" Blend="1" Shader="ParticleShader">
      <Textures>
        <MaterialTexture Texture="ParticleBitmap" TextureWrapMode="2" TexCoords="1"/>
      </Textures>
    </Material>
  </Content>
</ZApplication>
K
User avatar
Ats
Posts: 603
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about ES2/GL3 shaders

Post by Ats »

Oh, all right, I was missing the "attribute vec4 color;" part...
Thanks for your help :wink:
User avatar
Ats
Posts: 603
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about ES2/GL3 shaders

Post by Ats »

I'm experiencing a new problem with my conversion to ES2/GL3: a Material with DrawBackFace is showing up on Windows, but not on Android. Do I have something to set inside the shader, or do you think it is another problem related to the white background of the Android activity, again?
User avatar
Kjell
Posts: 1876
Joined: Sat Feb 23, 2008 11:15 pm

Re: Questions about ES2/GL3 shaders

Post by Kjell »

Hi Ats,
Ats wrote: Fri Jul 23, 2021 8:36 amI'm experiencing a new problem with my conversion to ES2/GL3: a Material with DrawBackFace is showing up on Windows, but not on Android.
Just double-checked this on Android myself and i'm experiencing no problems. I used the following example to test this:

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" GLBase="1" FileVersion="2">
  <OnRender>
    <ZExpression>
      <Expression>
<![CDATA[//

SingleTransform.Rotate.X = App.Time/3;
SingleTransform.Rotate.Y = App.Time/4;

DoubleTransform.Rotate.X = App.Time/3;
DoubleTransform.Rotate.Y = App.Time/4;]]>
      </Expression>
    </ZExpression>
    <RenderTransformGroup Name="SingleTransform" Translate="-2 0 0">
      <Children>
        <UseMaterial Material="SingleMaterial"/>
        <RenderMesh Mesh="PlaneMesh"/>
      </Children>
    </RenderTransformGroup>
    <RenderTransformGroup Name="DoubleTransform" Translate="2 0 0">
      <Children>
        <UseMaterial Material="DoubleMaterial"/>
        <RenderMesh Mesh="PlaneMesh"/>
      </Children>
    </RenderTransformGroup>
  </OnRender>
  <Content>
    <Mesh Name="PlaneMesh">
      <Producers>
        <MeshBox Grid2DOnly="255"/>
      </Producers>
    </Mesh>
    <Shader Name="SimpleShader">
      <VertexShaderSource>
<![CDATA[#ifdef GL_ES
  precision mediump float;
#endif

uniform mat4 modelViewProjectionMatrix;
attribute vec3 position;

void main()
{
  gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);
}]]>
      </VertexShaderSource>
      <FragmentShaderSource>
<![CDATA[#ifdef GL_ES
  precision mediump float;
#endif

void main()
{
  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}]]>
      </FragmentShaderSource>
    </Shader>
    <Material Name="SingleMaterial" Shader="SimpleShader"/>
    <Material Name="DoubleMaterial" DrawBackFace="255" Shader="SimpleShader"/>
  </Content>
</ZApplication>
K
User avatar
Ats
Posts: 603
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about ES2/GL3 shaders

Post by Ats »

All right. Thanks for the example. This got me tearing down everything until I stumbled on that bug which is now solved. Textures are back !
User avatar
Ats
Posts: 603
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about ES2/GL3 shaders

Post by Ats »

Hello :D

Today, I'm trying to create a simple shadow shader in order to avoid creating/deleting one model per shadow. My problem is that I don't find how to stick the shadow to the ground. Since the gl_Position parameter seems to be relative to the model position, I tried to send the Y position of the model to the shader, using gl_Position.y -= modelPosition[0][1] , but it's not working...

Is it possible to do?
I made a strip down example:

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="GLES2 Showroom" GLBase="1" AmbientLightColor="1 1 0 1" FrameRateStyle="2" FixedFrameRate="60" ScreenMode="0" CameraPosition="0 5 12" ClipFar="200" MouseVisible="255" RenderOrder="1" FileVersion="2" AndroidPackageName="com.GLES2.Showroom" AndroidPortrait="2">
  <OnLoaded>
    <ZExternalLibrary ModuleName="opengl32">
      <BeforeInitExp>
<![CDATA[//
if (ANDROID)
{
  if(App.GLBase==0) this.ModuleName="libGLESv1_CM.so";
  else this.ModuleName="libGLESv2.so";
}
else if (LINUX)
{
  this.ModuleName = "libGL.so";
}
else
{
  this.ModuleName = "opengl32";
}]]>
      </BeforeInitExp>
    </ZExternalLibrary>
    <ZExpression Comment="Initialization" Expression="createModel(ObjectModel);"/>
  </OnLoaded>
  <OnRender>
    <RenderTransformGroup Comment="Sky" Scale="150 100 150" Translate="0 2 0">
      <Children>
        <UseMaterial Material="SkyMaterial"/>
        <RenderMesh Mesh="SphereMesh"/>
      </Children>
    </RenderTransformGroup>
    <RenderTransformGroup Comment="Ground" Scale="80.91 80 1" Translate="0.16 0 -0.45" Rotate="-0.25 0 0">
      <Children>
        <UseMaterial Material="GroundMaterial"/>
        <RenderSprite/>
      </Children>
    </RenderTransformGroup>
  </OnRender>
  <Content>
    <Model Name="ObjectModel" Position="0 3.5 0" Rotation="0.25 0 0.1">
      <OnSpawn>
        <ZExpression Expression="CurrentModel.RotationVelocity.Y = 0.05;"/>
      </OnSpawn>
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[float time = App.Time *0.5;
CurrentModel.Position.Y = 5 + cos(time *10);]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
      <OnRender>
        <ZExpression>
          <Expression>
<![CDATA[ModelPosition[0][0,0] = CurrentModel.Position.X;
ModelPosition[0][0,1] = CurrentModel.Position.Y;
ModelPosition[0][0,2] = CurrentModel.Position.Z;

// Cube

@UseMaterial(Material:VertexColorMaterial);
@RenderMesh(Mesh:CubeMesh);

// Shadow

@UseMaterial(Material:ShadowMaterial);
@RenderMesh(Mesh:CubeMesh);]]>
          </Expression>
        </ZExpression>
      </OnRender>
    </Model>
    <Group Comment="Meshes">
      <Children>
        <Mesh Name="CubeMesh">
          <Producers>
            <MeshBox/>
            <MeshExpression VertexColors="255">
              <Expression>
<![CDATA[// vertex colors

C.R = V.X;
C.G = V.Y;
C.B = -V.X;
C.A = 1;]]>
              </Expression>
            </MeshExpression>
          </Producers>
        </Mesh>
        <Mesh Name="SphereMesh">
          <Producers>
            <MeshBox Scale="1 0.5 1" XCount="32" YCount="32" Grid2DOnly="255"/>
            <MeshExpression AutoNormals="0" VertexColors="255">
              <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;

// vertex colors

C.R = V.X;
C.G = V.Y;
C.B = -V.X;
C.A = 1;]]>
              </Expression>
            </MeshExpression>
          </Producers>
        </Mesh>
        <Mesh Name="PlaneMesh">
          <Producers>
            <MeshBox Grid2DOnly="255"/>
          </Producers>
        </Mesh>
      </Children>
    </Group>
    <Group Comment="Background">
      <Children>
        <Bitmap Name="GroundBitmap" Width="16" Height="16" Filter="2">
          <Producers>
            <BitmapExpression UseBlankSource="1" Expression="pixel = x &gt; 0.98 || y &gt; 0.98 ? 1 : 0;"/>
          </Producers>
        </Bitmap>
        <Material Name="GroundMaterial" Shading="1" Color="0 1 0 0.5" Blend="2" Shader="SpriteShader">
          <Textures>
            <MaterialTexture Texture="GroundBitmap" TextureScale="10 10 1" TextureWrapMode="1" TexCoords="1"/>
          </Textures>
        </Material>
        <Bitmap Name="SkyBitmap" Width="16" Height="128" Filter="2">
          <Producers>
            <BitmapFromFile Comment="Imported from sky.png" DataWidth="16" DataHeight="128">
              <BitmapFile>
<![CDATA[789CB5D8E94604501806E0F69AB6699996B98E2122111189884844442222121189884844C488882111118988480C43242222D1BEEFFB740DCF8F782E609673BEF37E6F38920C932A5359FD6B6A4C452DAAFB31F5A6BCE1DB349AB226D4FC655A4CA8F5D3B499D276D4F1613A4D49D7BBE936C53DA8F7CDF499A2FE573360828368E8C50C9BC29167336A0AC6D0F8939930F9938F66CAE44DA39907336B72A3F766CE04E6D1C29D89999CC55BB364B297D1CA8D5935596BD766DD646EA0CD2BB36532B62FCD8E498FA3C485D935697BE766DFA41EA0C3337364528E4FCDC93FC3CFA3DF977F4FFCBFF43CE879D3F3CCF705EFA3DE779D273AAF781EE2BCD579AEEF85BE47FCDEE17BAAEFB5E601CD1B9C67302F691ED3BCA77992F32AE661CDDB9AE7755FE07D04F71DDDA7745FD37D90F74DDC67755FD67D5CF77DEE13B0AFD03E44FB16ED73B82FC23E4AFB2EEDD3B4AFE33E10FB46ED33B52FD53E96FB5EEC93B5AFD63E5CFB762BF323C93FB9DE52F5]]>
              </BitmapFile>
            </BitmapFromFile>
          </Producers>
        </Bitmap>
        <Material Name="SkyMaterial" WireframeWidth="0" Light="0" SpecularColor="0 0 0 1" EmissionColor="0 0 0 1" DrawBackFace="255" Shader="TextureShader">
          <Textures>
            <MaterialTexture Texture="SkyBitmap" TextureScale="1 1 0" TextureY="0.05" TexCoords="1" Origin="0 0 0"/>
          </Textures>
        </Material>
        <Shader Name="SpriteShader">
          <VertexShaderSource>
<![CDATA[precision mediump float;

varying vec2 t;

uniform mat4 modelViewProjectionMatrix;
uniform mat4 textureMatrix;

attribute vec4 position;  //vertex position
attribute vec2 texCoord;  //vertex texture coordinate

void main()
{
  t = (textureMatrix * vec4(texCoord, 0.0, 1.0)).xy;
  gl_Position = modelViewProjectionMatrix * position;
}]]>
          </VertexShaderSource>
          <FragmentShaderSource>
<![CDATA[precision mediump float;

varying vec2 t;

uniform sampler2D tex1;

void main()
{
  vec4 c = texture2D(tex1, t);

  if(c.a == 0.0)
  {
    discard;
  }

  gl_FragColor = c;
}]]>
          </FragmentShaderSource>
        </Shader>
        <Shader Name="TextureShader">
          <VertexShaderSource>
<![CDATA[//
#ifdef GL_ES
  precision mediump float;
#endif

uniform mat4 modelViewProjectionMatrix;
attribute vec4 position; // vertex position
attribute vec2 texCoord; // texture coordinates
varying vec2 t;

void main()
{
  gl_Position = modelViewProjectionMatrix * position;
  t = texCoord;
}]]>
          </VertexShaderSource>
          <FragmentShaderSource>
<![CDATA[#ifdef GL_ES
  precision mediump float;
#endif

uniform sampler2D tex1;
varying vec2 t;

void main()
{
  gl_FragColor = vec4(texture2D(tex1, t).rgb, 1.0);
}]]>
          </FragmentShaderSource>
        </Shader>
      </Children>
    </Group>
    <Group Comment="Shaders">
      <Children>
        <Material Name="VertexColorMaterial" Shader="VertexColorShader"/>
        <Shader Name="VertexColorShader">
          <VertexShaderSource>
<![CDATA[//
#ifdef GL_ES
  precision mediump float;
#endif

uniform mat4 modelViewProjectionMatrix;
attribute vec4 position, color;

varying vec4 v_Color;

void main()
{
  v_Color = color;
  gl_Position = modelViewProjectionMatrix * position;
}]]>
          </VertexShaderSource>
          <FragmentShaderSource>
<![CDATA[//
#ifdef GL_ES
  precision mediump float;
#endif

varying vec4 v_Color;

void main()
{
  gl_FragColor = v_Color;
}]]>
          </FragmentShaderSource>
        </Shader>
        <Material Name="ShadowMaterial" Shader="ShadowShader"/>
        <Shader Name="ShadowShader">
          <VertexShaderSource>
<![CDATA[//
#ifdef GL_ES
  precision mediump float;
#endif

uniform mat4 modelPosition;

uniform mat4 modelViewProjectionMatrix;
attribute vec4 position; // vertex position

void main()
{
	gl_Position = modelViewProjectionMatrix * position * vec4(1.0 , 0.0, 1.0, 1.0);
  gl_Position.y -= modelPosition[0][1];
}]]>
          </VertexShaderSource>
          <FragmentShaderSource>
<![CDATA[//
#ifdef GL_ES
  precision mediump float;
#endif

void main (void)
{
  gl_FragColor = vec4(0.1, 0.5, 0.5, 1.0);
}]]>
          </FragmentShaderSource>
          <UniformVariables>
            <ShaderVariable VariableName="modelPosition" ValueArrayRef="ModelPosition" ArrayKind="1"/>
          </UniformVariables>
        </Shader>
      </Children>
    </Group>
    <Array Name="ModelPosition" Type="5" SizeDim1="1"/>
  </Content>
</ZApplication>
User avatar
Kjell
Posts: 1876
Joined: Sat Feb 23, 2008 11:15 pm

Re: Questions about ES2/GL3 shaders

Post by Kjell »

Hi Ats,
Ats wrote: Sun Feb 27, 2022 4:18 pmI tried to send the Y position of the model to the shader, using gl_Position.y -= modelPosition[0][1] , but it's not working.
That doesn't work because you're transforming screen-space coordinates. You need to transform the vertices before applying the view & projection matrices.
Ats wrote: Sun Feb 27, 2022 4:18 pmIs it possible to do?
It's possible, but unfortunately it's a little more cumbersome than it should be due to the fact that the matrix of a model isn't exposed in ZGE.

The easiest way to mitigate this is to re-calculate the model matrix yourself, which feels a little silly since ZGE already does this internally, so the same calculations end up being done twice. Anyway, here's a quick & lazy example*

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" ClearColor="0.5 0.5 0.5 1" RenderOrder="1" FileVersion="2">
  <OnLoaded>
    <SpawnModel Model="Box"/>
  </OnLoaded>
  <OnUpdate>
    <ZExpression>
      <Expression>
<![CDATA[// Animate camera

App.CameraRotation.Y = App.Time/8;

float a = App.Time/4*PI;

App.CameraPosition.X = -sin(a)*8;
App.CameraPosition.Z = cos(a)*8;]]>
      </Expression>
    </ZExpression>
  </OnUpdate>
  <OnRender>
    <ZExpression>
      <Expression>
<![CDATA[// Get the current modelViewMatrix ( which contains the viewMatrix at this point )

getMatrix(0, ViewMatrix);]]>
      </Expression>
    </ZExpression>
  </OnRender>
  <Content>
    <Variable Name="ViewMatrix" Type="5"/>
    <Model Name="Box">
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[// Animate the box

Box.Position.Y = abs(sin(App.Time*4))*2+1;
Box.Rotation.X = App.Time/PI;]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
      <OnRender>
        <UseMaterial Material="BoxMaterial"/>
        <RenderMesh Mesh="BoxMesh"/>
        <ZExpression>
          <Expression>
<![CDATA[// Construct transformation matrix ( quick & lazy )
// X0Z translation
// X.. rotation
// 101 scaling

float x = Box.Rotation.X*PI*2;

mat4 m;

m[0,0] = 1;
m[1,2] = sin(x);
m[2,2] = cos(x);
m[3,0] = Box.Position.X;
m[3,2] = Box.Position.Z;
m[3,3] = 1;

// Override modelViewMatrix

setMatrix(0, ViewMatrix * m);]]>
          </Expression>
        </ZExpression>
        <RenderMesh Mesh="BoxMesh"/>
      </OnRender>
    </Model>
    <Mesh Name="BoxMesh">
      <Producers>
        <MeshBox/>
      </Producers>
    </Mesh>
    <Material Name="BoxMaterial" Shading="2" Light="0"/>
  </Content>
</ZApplication>
* Didn't feel like writing all the matrix math so it only takes x/z-translation and x-rotation into account.

K
Post Reply