gbuffer – how to store an integer data

| | August 8, 2015

In a gbuffer I store a diffuse color in following texture:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

I want to store an integer data which represents a pixel type in channel A.
Here is part of the fragment shader:

#version 420
in vec2 tCoord;
layout (location = 2) out vec4 diffuseColorData;
uniform sampler2D texture0;
uniform int pixelType;
void main(void)
{
    diffuseColorData.xyz = texture(texture0, tCoord).xyz;
    diffuseColorData.w = pixelType;
}

Is it possible ? How to decode a pixel type when reading from texture ?

Edit

I use a pixel type to choose a shading function (standard shading – int 1, shading with normal maps – int 2, shading with uniform color – int 3). I need to use additive blending because of multiple light sources (point lights).

I changed the code as you suggested:

diffuseColorData.w = pixelType / 4.0;

In the next fragment shader I read a data this way (I post only relevant part of the code):

uniform sampler2D texture2;
vec4 diffandPixelType = texture(texture2, texCoord);
vec4 diff = vec4(diffandPixelType.xyz, 1.0);
float pixelType = diffandPixelType.w * 4.0;

if(pixelType == 1)
{
    outColor = shadingfun1(/*arguments*/)
}
else if(pixelType == 2)
{
   outColor = shadingfun2(/*arguments*/)
}
else if(pixelType == 3)
{
   outColor = shadingfun3(/*arguments*/)
}

The code doesn’t work properly and I don’t know how to explain that. What is wrong ?

I found other solution which works perfectly, but it require extra integer texture in the gbuffer:

glTexImage2D(GL_TEXTURE_2D, 0, GL_R8I, width, height, 0, GL_RED_INTEGER, GL_INT, NULL);

//fragment shader
layout (location = 4) out int shadingData;
uniform int pixelType;
shadingData = pixelType;

//fragment shader
uniform isampler2D texture6;
int pixelType = texture(texture6, texCoord).x;

if(pixelType == 1)
{
    outColor = shadingfun1(/*arguments*/)
}
else if(pixelType == 2)
{
    outColor = shadingfun2(/*arguments*/)
}
else if(pixelType == 3)
{
    outColor = shadingfun3(/*arguments*/)
}  

One Response to “gbuffer – how to store an integer data”

  1. It is possible, you just need to scale it to the 0-1 range, and make sure to avoid precision issues.

    For example if you have 6 pixel types, you can do

    diffuseColorData.w = pixelType / 5.0;
    

    Of course I would suggest setting up a define in the shader, possibly programatically.

    When reading from the texture just do the exact opposite, multiply it by 5 and round the result to an int. You’re probably safe from rounding and precision issues unless the number of possible pixel types is really high (I’d start worrying above 127).

    You also need to make sure that you write each fragment exactly once (no alpha blending), otherwise you’ll get some kind of interpolation between pixel types, which may not be something you want to achieve.

Leave a Reply