0
\$\begingroup\$

so for a game I am developing I am giving a go at deferred shading. I have only implemented entity rendering and an initial deferred shader and rendering the scene using OpenGLs FBO multiple render targets. I am facing an issue where the entity fragment positions do not stay in the FBO, or load the data correctly and I do not know. The code I have is open source on git but the two shaders I am working with are attached below. https://github.com/EquilibriumGames/4Space-Game Thank you for any help!

// entityFragment.glsl
#version 130

layout(location = 0) out vec4 out_colour;
layout(location = 1) out vec4 out_position;
layout(location = 2) out vec4 out_normal;
layout(location = 3) out vec4 out_additonal;

layout(binding = 0) uniform sampler2D colourTexture;
layout(binding = 1) uniform sampler2D normalMapTexture;

varying vec2 textureCoords;
varying vec4 entityPosition;
varying vec3 surfaceNormal;
varying vec4 positionRelativeToCam;
varying vec3 toCameraVector;

uniform bool useNormalMap;
uniform float transparency;

void main(void) {
    vec4 textureColour = texture(colourTexture, textureCoords);
    vec3 unitNormal = normalize(surfaceNormal);

    if (textureColour.a < 0.5){
        discard;
    }

    if (useNormalMap) {
        vec4 normalMapValue = 2.0 * texture(normalMapTexture, textureCoords, -1.0) - 1.0;
        unitNormal = normalize(normalMapValue.xyz);
    }

    out_colour = textureColour;
    out_colour.a = min(out_colour.a, transparency);
    out_position = entityPosition;
    out_normal = vec4(unitNormal, 0.0);
    out_additonal = vec4(0.2, 0.0, 0.0, 0.0);
}


// deferredFragment.glsl
#version 130

layout(location = 0) out vec4 out_colour;

varying vec2 pass_textureCoords;

layout(binding = 0) uniform sampler2D colourTexture;
layout(binding = 1) uniform sampler2D positionTexture;
layout(binding = 2) uniform sampler2D normalsTexture;
layout(binding = 3) uniform sampler2D additonalTexture;
layout(binding = 4) uniform sampler2D shadowMapTexture;

const int NUMBER_LIGHTS = 32;

uniform mat4 viewMatrix;
uniform vec3 cameraPosition;
uniform mat4 shadowSpaceMatrix;
uniform float shadowMapSize;
uniform float shadowDistance;

uniform vec3 lightsColour[NUMBER_LIGHTS];
uniform vec3 lightsPosition[NUMBER_LIGHTS];
uniform vec3 lightsAttenuation[NUMBER_LIGHTS];

uniform vec3 fogColour;
uniform float fogDensity;
uniform float fogGradient;

const float transitionDistance = 85.0;
const float tileAmount = 50.0;
const float shadowDarkness = 0.6;

void main(void) {
    vec4 colour = texture2D(colourTexture, pass_textureCoords);
    vec4 position = texture2D(positionTexture, pass_textureCoords);
    vec4 normal = texture2D(normalsTexture, pass_textureCoords);
    vec4 additonal = texture2D(additonalTexture, pass_textureCoords);
    float specular = additonal.r; // g, b, a

    vec4 positionRelativeToCam = viewMatrix * position;
    vec4 shadowCoords = shadowSpaceMatrix * position;
    float distanceAway = length(positionRelativeToCam.xyz);
    distanceAway = distanceAway - ((shadowDistance * 2.0) - (transitionDistance));
    distanceAway = distanceAway / transitionDistance;
    shadowCoords.w = clamp(1.0 - distanceAway, 0.0, 1.0);

    float shadowTexelSize = 1.0 / shadowMapSize;
    float shadowHalfw = shadowTexelSize * 0.5;
    float shadowTotal = 0.0;
    float shadowValue = 0.0;
    float shadowShadeFactor;
    shadowValue = texture(shadowMapTexture, shadowCoords.xy + vec2(0 + shadowHalfw, 0 + shadowHalfw)).r;

    if (shadowCoords.x > 0.0 && shadowCoords.x < 1.0 && shadowCoords.y > 0.0 && shadowCoords.y < 1.0 && shadowCoords.z > 0.0 && shadowCoords.z < 1.0) {
        if (shadowValue < shadowCoords.z) {
            shadowTotal += shadowDarkness * shadowCoords.w;
        }

        shadowValue = texture(shadowMapTexture, shadowCoords.xy + vec2(shadowTexelSize + shadowHalfw, 0 + shadowHalfw)).r;

        if (shadowValue < shadowCoords.z) {
            shadowTotal += shadowDarkness * shadowCoords.w;
        }

        shadowValue = texture(shadowMapTexture, shadowCoords.xy + vec2(0 + shadowHalfw, shadowTexelSize + shadowHalfw)).r;

        if (shadowValue < shadowCoords.z) {
            shadowTotal += shadowDarkness * shadowCoords.w;
        }

        shadowValue = texture(shadowMapTexture, shadowCoords.xy + vec2(shadowTexelSize + shadowHalfw, shadowTexelSize + shadowHalfw)).r;

        if (shadowValue < shadowCoords.z) {
            shadowTotal += shadowDarkness * shadowCoords.w;
        }

        shadowShadeFactor = 1.0 - (shadowTotal / 4.0);
    } else {
        shadowShadeFactor = 1.0;
    }

    float visibility = clamp(exp(-pow((length(positionRelativeToCam.xyz) * fogDensity), fogGradient)), 0.0, 1.0);

    out_colour = vec4((colour * shadowShadeFactor).xyz, colour.a);
    out_colour = mix(vec4(fogColour, 1.0), out_colour, visibility);
}
\$\endgroup\$
-1
\$\begingroup\$

As far as I know, a FBO is basically a texture, not a shader stage. This means, it can only contain pixel data. All the other values you emmit from you fragment shader are just ignored. If you'd really want to keep all the data, you would need to draw a FBO for each attribute you want to save, which means that you have to draw 4 FBOs, one for color, position, normal and additional. Since all of those attributes are vec4, you can use them as "colors".

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.