0

I am currently implementing Shadow Mapping and I came accross a part of weird logic in my program, I use the following program:

light.vs.glsl

#version 440 core

layout(location = 4) uniform mat4 light_mvp;

layout(location = 0) in vec4 position;

void main(void) {
    gl_Position = light_mvp * position;
}

light.fs.glsl

#version 440 core

layout(location = 0) out vec4 color;

void main(void) {
    color = vec4(gl_FragCoord.z);
}

However I came to the conclusion that I am actually doing Tesselation, so I do not really have a clue what is going on now, in Terrain.java:

public class Terrain implements Drawable {
    //<editor-fold defaultstate="collapsed" desc="keep-imports">
    static {
        int KEEP_LWJGL_IMPORTS = GL_2_BYTES | GL_ALIASED_LINE_WIDTH_RANGE | GL_ACTIVE_TEXTURE | GL_BLEND_COLOR | GL_ARRAY_BUFFER | GL_ACTIVE_ATTRIBUTE_MAX_LENGTH | GL_COMPRESSED_SLUMINANCE | GL_ALPHA_INTEGER | GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH | GL_ALREADY_SIGNALED | GL_ANY_SAMPLES_PASSED | GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH | GL_ACTIVE_PROGRAM | GL_ACTIVE_ATOMIC_COUNTER_BUFFERS | GL_ACTIVE_RESOURCES | GL_BUFFER_IMMUTABLE_STORAGE;
        int KEEP_OWN_IMPORTS = UNIFORM_PROJECTION_MATRIX.getLocation() | VS_POSITION.getLocation();
    }
//</editor-fold>
    private static final float EPSILON = 0.0001f;

    private FloatBuffer data;
    private Program program;

    private final int width;
    private final int depth;

    private final Random random = new Random();
    private final float maxHeight = 8f;
    private final int maxDecayFactor = 5;
    private final float factor = 4f;

    public Terrain(final int width, final int depth) {
        this.width = width;
        this.depth = depth;
        data = generateRandomTerrain();
        data.clear();
    }

    @Override
    public void compileProgram() {
        program = new Program(
                new VertexShader("data/shaders/terrain.vs.glsl").compile(),
                new TessellationControlShader("data/shaders/terrain.tcs.glsl").compile(),
                new TessellationEvaluationShader("data/shaders/terrain.tes.glsl").compile(),
                new FragmentShader("data/shaders/terrain.fs.glsl").compile()
        ).compile().setUniforms(
                        UNIFORM_MODEL_MATRIX,
                        UNIFORM_VIEW_MATRIX,
                        UNIFORM_PROJECTION_MATRIX,
                        UNIFORM_SHADOW_MATRIX
                        );
    }

    @Override
    public Program getProgram() {
        return program;
    }

    @Override
    public int getDataSize() {
        return width * depth * 16;
    }

    @Override
    public FloatBuffer putData(final FloatBuffer dataBuffer) {
        return dataBuffer.put(data);
    }

    @Override
    public int getDataMode() {
        return GL_PATCHES;
    }

    @Override
    public void drawLightPass(final int offset, final Program lightProgram) {
        lightProgram.drawArrays(getDataMode(), offset, getDataSize());
    }

    @Override
    public void draw(final int offset) {
        program.use();
        program.drawArrays(getDataMode(), offset, getDataSize());
    }

    @Override
    public void delete() {
        program.delete();
    }

    public void refresh() {
        data.clear();
        data = generateRandomTerrain();
    }

    //...
}

Also for the lightProgram that gets passed to drawLightPass, it has been ensured that lightProgram.use() has been called before that, this may not seem obvious from the code.

As you can see I am calling drawArrays in drawLightPass with as argument GL_PATCHES, now this really ought to go wrong, as a result in my whole program I get that every part is considered to be in the shadow, so I have these questions:

1) Is my current setup an issue? (I think personally it is.)

2) How can OpenGL not give an error if I pass in GL_PATCHES when the attached shader has no Tesselation enabled?

3) How do I fix it such that it also works with Tesselation?

If any more code is required, then I'll post it, I just do not want to clutter the post too much with unnecessary code.

skiwi
  • 66,971
  • 31
  • 131
  • 216
  • **Unrelated:** Is there a reason you are writing the window-space Z coordinate to a 4 component color ouput? This is pretty wasteful for shadow mapping, because that is actually the exact same value that is already automatically written to the depth buffer. You could save ***a lot*** of memory bandwidth/storage if you did not write/attach anything to the color buffer and instead used a depth texture attachment. – Andon M. Coleman Feb 02 '14 at 18:41
  • @AndonM.Coleman It was done like this in the tutorial (OpenGL Superbible Sixth Edition), I am actually using a `GL_DEPTH_ATTACHMENT` with `GL_DEPTH_COMPONENT32F`. – skiwi Feb 02 '14 at 18:55
  • Wow, that comes as a surprise to me. That does not seem like something a reputable book like that should be doing. At any rate, are you saying that your tessellated geometry is not appearing in your shadow map, or that you cannot apply your shadow map to the tessellated geometry? In other words, is the tessellated geometry supposed to be casting or receiving shadows in this situation? – Andon M. Coleman Feb 02 '14 at 19:13
  • @AndonM.Coleman I got it so far that it appears now, after fixing a bug (normalizing a zero vector resulted in a `NaN` being passed to the shader), however it still has loads of artifacts. I am going to focus on that first on a simple XZ plane, however my concerns about the logic are still valid. I think the tesselated geometry is supposed to both cast and receive shadows. – skiwi Feb 02 '14 at 19:57

0 Answers0