Glow shader ES2/GL3

All topics about ZGameEditor goes here.

Moderator: Moderators

Post Reply
User avatar
Ats
Posts: 770
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Glow shader ES2/GL3

Post by Ats »

Hello. I'm still trying to make "simple" shaders from time to time :lol:
So today I'm trying to port that one to ZGE: https://stackoverflow.com/questions/816 ... ngl-es-2-0

Since I'm not using textures, I was trying to do that directly with the vertex colors. But the only thing I can get is to make the colors more white with the u_glowIntensity. It doesn't glow outside the mesh. Is that a restriction due to me not using a texture, or is there something else that I don't understand in the logic?

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" GLBase="1" FileVersion="2">
  <OnLoaded>
    <SpawnModel Model="ModelCube"/>
  </OnLoaded>
  <Content>
    <Model Name="ModelCube" Rotation="0 0.01 0" RotationVelocity="0.02 0.01 0">
      <OnRender>
        <UseMaterial Material="MaterialGlow"/>
        <RenderMesh Mesh="MeshCube"/>
      </OnRender>
    </Model>
    <Mesh Name="MeshCube">
      <Producers>
        <MeshBox/>
        <MeshExpression VertexColors="255">
          <Expression>
<![CDATA[
C.R = rnd();
C.G = rnd();
C.B = rnd();]]>
          </Expression>
        </MeshExpression>
      </Producers>
    </Mesh>
    <Material Name="MaterialGlow" Shader="ShaderGlow"/>
    <Shader Name="ShaderGlow">
      <VertexShaderSource>
<![CDATA[#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#endif

uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform mat3 normalMatrix;

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

varying vec3 N;
varying vec3 v_position; // View-space position to pass to the fragment shader
varying vec4 v_color;

void main(void)
{
    // Calculate view-space position
    v_position = vec3(modelViewMatrix * position);

    // Calculate view-space normal
    N = normalize(normalMatrix * normal);

    // Pass vertex color to fragment shader
    v_color = color;

    // Calculate position of the vertex in clip space
    gl_Position = modelViewProjectionMatrix * position;
}]]>
      </VertexShaderSource>
      <FragmentShaderSource>
<![CDATA[#ifdef GL_ES
precision mediump float;
#endif

varying vec4 v_color; // Vertex color from the vertex shader
varying vec3 v_position; // View-space position to pass to the fragment shader

//uniform vec2 u_resolution; // Resolution of the screen
//uniform float u_glowIntensity; // Glow intensity
//uniform float u_sigma; // Sigma value for Gaussian blur
//uniform int u_width; // Width value for Gaussian blur

const vec2 u_resolution = vec2(800.0, 600.0);
const float u_glowIntensity = 0.5; // 0 = no color variation, 1 = white
const float u_sigma = 1.0; // Adjust the sigma value for Gaussian blur
const int u_width = 5; // Adjust the width for Gaussian blur

// Function to apply Gaussian blur for glow effect
vec4 gaussianBlur(vec2 coord) {
    vec4 blurColor = vec4(0.0);
    float weightSum = 0.0;
    vec2 texSize = u_resolution; // Texture size based on screen resolution

    // Sample around the current coordinate
    for (int i = -u_width; i <= u_width; i++) {
        for (int j = -u_width; j <= u_width; j++) {
            vec2 offset = vec2(i, j) / texSize;
            float distance = length(offset);
            float weight = exp(-distance * distance / (2.0 * u_sigma * u_sigma));

            // Sample the color from the offset position and apply the weight
            vec2 sampleCoord = coord + offset;
            blurColor += v_color * weight;
            weightSum += weight;
        }
    }

    // Normalize the blur color
    return blurColor / weightSum;
}

void main() {


    // Calculate the screen coordinates
  vec2 screenCoord = gl_FragCoord.xy / u_resolution;

  // Apply Gaussian blur
  vec4 glowColor = gaussianBlur(screenCoord);

  // Combine the vertex color and the glow effect
  gl_FragColor = v_color + glowColor * u_glowIntensity;

  // For debug
  //gl_FragColor = v_color;
}]]>
      </FragmentShaderSource>
    </Shader>
  </Content>
</ZApplication>
User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: Glow shader ES2/GL3

Post by Kjell »

Hi Ats,
Ats wrote: Wed Apr 24, 2024 10:13 amIt doesn't glow outside the mesh. Is that a restriction due to me not using a texture, or is there something else that I don't understand in the logic?
It doesn't have anything to do with whether you're using vertex-colors or a texture or not. A fragment shader will only process the pixels that make up the triangles / lines / points set by your vertex shader. In other words, pixels that reside outside of your cube ( the red area ) won't get affected by your fragment shader.

Image

So the most common way to realize glow is to first render your scene to a RenderTarget and then use a glow shader on that ... in that case every pixel will get processed, since you're rendering on a fullscreen quad.

K
Post Reply