I am writing an isometric game engine on OpenGL (version 3.3 specifically). For each wall tileset i have volume mask tileset for the wall relative volume coordinates.

Volume mask looks like this:

enter image description here

Now i am trying to write a simple lighting system (it kinda looks like that old game, Nox):

The idea is simple - i generate one-dimensional z-buffer for each light source (in the example i use only one test light spot), in the fragment shader for each fragment i'm figuring out is it lit or not etc.

Here's the vertex shader:

attribute vec3 scenePosition;
attribute vec3 screenPosition;
attribute vec2 screenTexCoord;
attribute vec2 volTexCoord;
attribute vec2 normalMaskTexCoord;
const int MAX_LIGHTS = 12;
uniform mat4 projectionMatrix;
uniform mat4 scrollingMatrixScreen;
out vec2 texCoordFrag;
out vec2 volTexCoordFrag;
out vec2 normalMaskTexCoordFrag;
out vec3 scenePosFrag;

void main(){
    texCoordFrag = screenTexCoord;
    volTexCoordFrag = volTexCoord;
    normalMaskTexCoordFrag = normalMaskTexCoord;
    scenePosFrag = scenePosition;
    gl_Position = projectionMatrix * scrollingMatrixScreen * vec4(screenPosition, 1.0);

Fragment shader:

const float specificLength = 0.177469939;
const float M_PI = 3.14159265358979323846;
const int LIGHT_Z_BUFFER_SIZE = 1024;

uniform sampler2D tex;
uniform sampler2D volumeMask;
uniform sampler2D normalMask;
uniform samplerBuffer testLightZBuffer;
uniform vec3 changingVec;

in vec2 texCoordFrag;
in vec3 scenePosFrag;
in vec3 testColorFrag;
in vec2 volTexCoordFrag;
in vec2 normalMaskTexCoordFrag;
in float wallLengthFrag;

out vec4 fragColor;

void main(){
    vec4 trueColor = texture(tex, texCoordFrag);
    if (trueColor == vec4(0.0, 0.0, 0.0, 0.0))\

    float testLightRadius = 4.0;
    vec2 testLightCenter = vec2(2.0, 2.0);
    float lightBrightness = 0.0;
    float lightHeight = 2.0;

    vec3 volCoords = vec3(texture(volumeMask, volTexCoordFrag));
    vec3 trueSceneCoords = vec3(volCoords.x/specificLength, volCoords.y/specificLength, volCoords.z/specificLength) + scenePosFrag;
    vec3 normalCoords = normalize(vec3(texture(normalMask, normalMaskTexCoordFrag)));
    vec2 lightTangentRel = vec2(trueSceneCoords) - testLightCenter;

    if (length(lightTangentRel) <= testLightRadius)
        float angle = acos(dot(normalize(lightTangentRel), vec2(1.0, 0.0)));
        float currentZBufferPoint = angle / (2*M_PI);
        int currentTexelId = int(round(LIGHT_Z_BUFFER_SIZE * currentZBufferPoint));
        vec4 obstRad = texelFetch(testLightZBuffer, currentTexelId);

        if (length(lightTangentRel) < testLightRadius)
            float lightIntensity = cos((length(lightTangentRel)*M_PI/2)/(testLightRadius));
            lightBrightness = lightIntensity;


    vec4 nightColor = vec4(trueColor.x*0.1, trueColor.y*0.1, trueColor.z*0.2, trueColor.w);
    vec4 lightColor = trueColor;
    if (0.0 <= lightBrightness && lightBrightness <= 1.0)
        fragColor = mix(lightColor, nightColor, 0.0);

The problem is, texelFetch can't handle currentZBufferPoint variable, it just doesn't draw ANYTHING, but lightBrightness should be at least 0, therefore it must draw at least black pixels. Looks like shader program crashes somewhere, but it compiles completely fine.

So, after several hours i figured out where is the problem - it is here:

vec3 volCoords = vec3(texture(volumeMask, volTexCoordFrag));

If i replace texture(volumeMask, volTexCoordFrag) with anything else, it works. Pls help.


1 Answer 1


Well, i just figured it out - i just set uniform samplers variables incorrectly.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .