PDA

View Full Version : Multisample textures



debonair
12-25-2012, 11:27 AM
I read some pages on google but still confused about working of multisample textures.
Can anyone explain this concept? If possible please explain it with source code.
Thanks.

tonyo_au
12-25-2012, 05:05 PM
Are you planning to use shaders or immediate mode?

debonair
12-26-2012, 12:22 AM
Are you planning to use shaders or immediate mode?

i am going to use shaders.

tonyo_au
12-26-2012, 03:56 AM
Ok, that easier. You need to supply a uv for each texture in the vertex bindings (you can of course shared one uv for multiple textures. Then bind each texture to a sampler in the fragment shader. Fetch the texture pixels in the fragment shader and apply them as you see fit. I will post a little example - I am off to a boxing day do:D

tonyo_au
12-26-2012, 07:20 PM
example


vertex shader

layout(location = VERTEX_BINDINGS_POSITION) in vec3 Position;
layout(location = VERTEX_BINDINGS_TEXTURE0) in vec2 Texture0;
layout(location = VERTEX_BINDINGS_TEXTURE1) in vec2 Texture1;

out vec2 texture0;
out vec2 texture1;

void main()
{
texture0 = Texture0;
texture1 = Texture1;

gl_Position = CameraProjection * CameraModelView * vec4(Position,1);
}

fragment


in vec2 texture0;
in vec2 texture1;

uniform sampler2D Image0;
uniform sampler2D Image1;

layout(location = 0, index = 0) out vec4 fFragColour;



void main()
{

vec4 c0 = texture2D(Image0,p_Texture0.st);
vec4 c1 = texture2D(Image1,p_Texture1.st);

vec4 colour = mix(c0,c1,c1.a); // some blend function

fFragColour = colour;

}

debonair
12-26-2012, 11:41 PM
example


vertex shader

layout(location = VERTEX_BINDINGS_POSITION) in vec3 Position;
layout(location = VERTEX_BINDINGS_TEXTURE0) in vec2 Texture0;
layout(location = VERTEX_BINDINGS_TEXTURE1) in vec2 Texture1;

out vec2 texture0;
out vec2 texture1;

void main()
{
texture0 = Texture0;
texture1 = Texture1;

gl_Position = CameraProjection * CameraModelView * vec4(Position,1);
}

fragment


in vec2 texture0;
in vec2 texture1;

uniform sampler2D Image0;
uniform sampler2D Image1;

layout(location = 0, index = 0) out vec4 fFragColour;



void main()
{

vec4 c0 = texture2D(Image0,p_Texture0.st);
vec4 c1 = texture2D(Image1,p_Texture1.st);

vec4 colour = mix(c0,c1,c1.a); // some blend function

fFragColour = colour;

}



Thanks for the reply. But the code you have provided is for multi-texturing and not multisample texture :)

debonair
12-27-2012, 02:44 AM
i want to use multisampled textures.

What will be the fragment shader and how to pass multiple samplers to shader?

Also, which API can be used to load texel data ?

I want to use default FBO for this.

Dark Photon
12-27-2012, 12:22 PM
Typically you would pass these into a shader via a sampler2DMS and sample them via texelFetch(). Web search those and you'll come up with some good sample code. There's some in the archives of these forums as well (see the search box above).

And please don't cross-post. I re-merged your threads.

tonyo_au
12-28-2012, 12:39 AM
wops - mis-read that here is a sample


uniform sampler2DMS u_2DMS;
uniform float u_Translucency;

layout(location = 0, index = 0) out vec4 fFragColour;

void main()
{
ivec2 st = ivec2(vData.texture0.st * u_Screen.xy);

vec4 colour = texelFetch(u_2DMS,st,gl_SampleID);

colour.w *= u_Translucency;

fFragColour = colour;

}

debonair
01-01-2013, 09:26 AM
wops - mis-read that here is a sample


uniform sampler2DMS u_2DMS;
uniform float u_Translucency;

layout(location = 0, index = 0) out vec4 fFragColour;

void main()
{
ivec2 st = ivec2(vData.texture0.st * u_Screen.xy);

vec4 colour = texelFetch(u_2DMS,st,gl_SampleID);

colour.w *= u_Translucency;

fFragColour = colour;

}



Thanks for the reply..
as gl_samplerID is supported on after 4.0 versions, what would replace it?

Dark Photon
01-01-2013, 11:27 AM
as gl_samplerID is supported on after 4.0 versions, what would replace it?

You don't need it to access multisample textures. You only need it if you plan to do per-sample rasterization.

And while that is core in GL/GLSL 4.0, you can also get it through the ARB_sample_shading (http://www.opengl.org/registry/specs/ARB/sample_shading.txt) extension.

debonair
01-01-2013, 12:30 PM
You don't need it to access multisample textures. You only need it if you plan to do per-sample rasterization.

And while that is core in GL/GLSL 4.0, you can also get it through the ARB_sample_shading (http://www.opengl.org/registry/specs/ARB/sample_shading.txt) extension.

so, i should pass 3rd parameter as 0 ?
and if i want "per-sample rasterization" then ?

tonyo_au
01-01-2013, 05:47 PM
The 3rd parameter is to select the sample. If for example you wanted to save each sample in a separate texture buffer, you could loop in your cpu code calling a whole screen render and set a uniform to say which sample to fetch. If you just want to merge the samples into a single texture you can use glBlitFramebuffer or do it manually in a shader by fetching all the samples and averaging them.

debonair
01-01-2013, 11:38 PM
The 3rd parameter is to select the sample. If for example you wanted to save each sample in a separate texture buffer, you could loop in your cpu code calling a whole screen render and set a uniform to say which sample to fetch. If you just want to merge the samples into a single texture you can use glBlitFramebuffer or do it manually in a shader by fetching all the samples and averaging them.

Now, if i choose to do it manually in shader with 4 samples, my shader will be:



uniform sampler2DMS tk_diffuseMap;
in vec3 ps_texCoord;
out vec4 fragColor;

void main(void)
{

vec2 iTmp = textureSize(tk_diffuseMap);
vec2 tmp = floor(iTmp * ps_texCoord.xy);

vec4 color;
for(int i = 0; i < 4; ++i)
{
color+ = texelFetch(depthTex, ivec2(tmp), i);


}

fragColor=color;
}

What do you mean by "averaging them" ?
and if i am using texture unit 0 i.e. only 1 texture, uniform will be set to 0.

Correct me if wrong.

tonyo_au
01-02-2013, 01:05 AM
You logic outputs the sum of the samples not the average. To average you need to divide the colour by the number of samples. This is of course the simplest thing you can do. You could convert the rgb to a better colour space to do the averaging.

debonair
01-02-2013, 02:48 AM
You logic outputs the sum of the samples not the average. To average you need to divide the colour by the number of samples. This is of course the simplest thing you can do. You could convert the rgb to a better colour space to do the averaging.
ohh. Thanks for pointing out.

Now, i am rendering white cube with green background in non default FBO and attaching the created multisampled texture to this FBO.
When i render a cube in default FBO using above texture, it gives corruption in texture.

Here is my code:


viewport_width=32;
viewport_height=32;
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureId);
nResult |= GL_ERROR_CHECK((GL_NO_ERROR, "glBindTexture(*target, textureId);"));

glUniform1i(glGetUniformLocation(shader_data.psId,"tk_diffuseMap"), 0);
nResult |= GL_ERROR_CHECK((GL_NO_ERROR, "glUniform1i(glGetUniformLocation(shader_data.psId, \"basetexture\"), 0);"));

glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4 ,GL_RGBA, viewport_width, viewport_height ,true);
nResult |= GL_ERROR_CHECK((GL_NO_ERROR, "glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4 ,GL_RGBA, 32, 32,true);"));

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, Fboid);
nResult |= GL_ERROR_CHECK((GL_NO_ERROR, "glBindFramebuffer(GL_FRAMEBUFFER, Fboid);"));

glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D_MULTISAMPLE,tex tureId,0);
nResult |= GL_ERROR_CHECK((GL_NO_ERROR, "glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D_MULTISAMPLE,tex tureId,0);"));

glEnable(GL_MULTISAMPLE);
nResult |= GL_ERROR_CHECK((GL_NO_ERROR, "glEnable(GL_MULTISAMPLE);"));

draw_cube(viewport_width, viewport_height);

glBindFramebuffer(GL_FRAMEBUFFER, 0);
nResult |= GL_ERROR_CHECK((GL_NO_ERROR, "glBindFramebuffer(GL_FRAMEBUFFER, Fboid);"));

glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureId);
nResult |= GL_ERROR_CHECK((GL_NO_ERROR, "glBindTexture(*target, textureId);"));

glDrawElements ( GL_TRIANGLES, 36,GL_UNSIGNED_INT, indices );


fragment shader



uniform sampler2DMS tk_diffuseMap;
in vec3 ps_texCoord;
out vec4 fragColor;

void main(void)
{

vec2 iTmp = textureSize(tk_diffuseMap);
vec2 tmp = iTmp * ps_texCoord.xy;

vec4 color;
for(int i = 0; i < 4; ++i)
{
color = color + texelFetch(tk_diffuseMap, ivec2(tmp), i);
}

fragColor=vec4(color/4);
}

tonyo_au
01-02-2013, 05:22 AM
Your code looks all back to front.What are you exactly trying to do?

debonair
01-02-2013, 05:31 AM
Your code looks all back to front.What are you exactly trying to do?
I am rendering a cube on non default FBO and creating a multisampled texture attached to this FBO. Now, i am applying this multisampled texture on a cube rendered on default FBO. I am using "render to texture" concept here.

I am getting diagonally half of one of 6 faces green. and rest of the faces black...

tonyo_au
01-02-2013, 05:27 PM
I would look at the uv values you are using to render the cube. Also have you dumped the texture out as an image to be sure your texture is ok since I assume you have created it programmatically. Also why are using a mutlisample for a texture on the cube rather than a mipmap.

debonair
01-02-2013, 11:43 PM
I would look at the uv values you are using to render the cube. Also have you dumped the texture out as an image to be sure your texture is ok since I assume you have created it programmatically. Also why are using a mutlisample for a texture on the cube rather than a mipmap.



GLfloat tex_coords[]={
0.0, 0.0,0.0,
1.0, 0.0,1.0,
1.0, 1.0,1.0,
0.0, 1.0,0.0,

0.0, 0.0,0.0,
1.0, 0.0,1.0,
1.0, 1.0,1.0,
0.0, 1.0,0.0,

0.0, 0.0,0.0,
1.0, 0.0,1.0,
1.0, 1.0,1.0,
0.0, 1.0,0.0,

0.0, 0.0,0.0,
1.0, 0.0,1.0,
1.0, 1.0,1.0,
0.0, 1.0,0.0,

0.0, 0.0,0.0,
1.0, 0.0,1.0,
1.0, 1.0,1.0,
0.0, 1.0,0.0,

0.0, 0.0,0.0,
1.0, 0.0,1.0,
1.0, 1.0,1.0,
0.0, 1.0,0.0
};


I am neglecting a third component of tex cords in a shader.
Yeah, i confirmed my texture is correct when i rendered that to default FBO.

tonyo_au
01-03-2013, 04:45 PM
I assume your vertex shader has the texture coordinate in defined as a vec3?

debonair
01-03-2013, 11:08 PM
I assume your vertex shader has the texture coordinate in defined as a vec3?


yes.
Vertex shader:


in vec3 inputtexcoord;
in vec3 tk_position;
out vec3 ps_texCoord;

uniform mat4 tk_mvpMatrix;
void main(void)
{
ps_texCoord = inputtexcoord;
gl_Position = tk_mvpMatrix * vec4(tk_position, 1.0);
}



fragement



uniform sampler2DMS tk_diffuseMap;
in vec3 ps_texCoord;
out vec4 fragColor;

void main(void)
{

vec2 iTmp = textureSize(tk_diffuseMap);
vec2 tmp =floor(iTmp * ps_texCoord.xy);

vec4 color;
for(int i = 0; i < 4; ++i)
{
color = color + texelFetch(tk_diffuseMap, ivec2(ps_texCoord), i);
}

fragColor=vec4(color/4);
}

tonyo_au
01-04-2013, 02:58 AM
Sorry I should have seen this earlier

texelFetch texture coordinates are in pixels not 0-1; so you need to multiply uv by texture width and height

debonair
01-04-2013, 03:23 AM
Sorry I should have seen this earlier

texelFetch texture coordinates are in pixels not 0-1; so you need to multiply uv by texture width and height

There was a mistake in above frag shader: for
texelFetch(tk_diffuseMap, ivec2(ps_texCoord), i);


Now,
vec2 iTmp = textureSize(tk_diffuseMap);
vec2 tmp =floor(iTmp * ps_texCoord.xy);
color = color + texelFetch(tk_diffuseMap, ivec2(tmp), i);

this also not working.

tonyo_au
01-04-2013, 05:50 AM
When I have errors like this that I can't understand I modify the frag shader to display the uv values, eg



fragColor=vec4(ps_texCoord.xy,0,1);
fragColor=vec4(ps_texCoord.x,0,0,1); // to just see the u values

Now you can see how the texture is being mapped onto the cube. It may give a clue as to what is wrong

debonair
01-04-2013, 10:05 AM
When I have errors like this that I can't understand I modify the frag shader to display the uv values, eg



fragColor=vec4(ps_texCoord.xy,0,1);
fragColor=vec4(ps_texCoord.x,0,0,1); // to just see the u values

Now you can see how the texture is being mapped onto the cube. It may give a clue as to what is wrong

Many thanks for your help..
Got it working..

tonyo_au
01-04-2013, 05:30 PM
Great to here;)

debonair
01-27-2013, 11:44 PM
When using multisampled textures, do i need to set samplers ( to number which i am using in glTexImage2DMultisample ) ? because i am assuming it needs to be set in MSAA. Please correct me if wrong. I have no idea how internally multisampling works..

Dark Photon
01-28-2013, 05:42 AM
When just reading from multisample textures in a shader (what it sounds like you want to do), you can forget anything you might know (or not know) about multisample rasterization -- it doesn't matter. Conceptually you just have a texture where instead of having 1 vector value per pixel you have N vector values per pixel, where N is the number of samples per pixel you allocated for that multisample texture.

To fetch the Nth sample from a particular pixel, just bind the multisample texture handle (what you get from glGenTextures) to a texture unit, and then in the shader, call texelFetch with the integer texcoord ("P") addressing the specific pixel and the "sample" argument being the sample index within that pixel.

debonair
01-28-2013, 05:55 AM
When just reading from multisample textures in a shader (what it sounds like you want to do), you can forget anything you might know (or not know) about multisample rasterization -- it doesn't matter. Conceptually you just have a texture where instead of having 1 vector value per pixel you have N vector values per pixel, where N is the number of samples per pixel you allocated for that multisample texture.

To fetch the Nth sample from a particular pixel, just bind the multisample texture handle (what you get from glGenTextures) to a texture unit, and then in the shader, call texelFetch with the integer texcoord ("P") addressing the specific pixel and the "sample" argument being the sample index within that pixel.

Thanks, I mean to say do i need to set number of samples to 4 or 8 (instead of 1) while creating context in my config attributes?

Dark Photon
01-28-2013, 07:33 PM
Thanks, I mean to say do i need to set number of samples to 4 or 8 (instead of 1) while creating context in my config attributes?

Oh, I see. No. You can create and use multisample textures of any number of samples under-the-hood independent of how many samples per pixel you allocate for your system framebuffer.

Alfonse Reinheart
01-28-2013, 10:50 PM
Oh, I see. No. You can create and use multisample textures of any number of samples under-the-hood independent of how many samples per pixel you allocate for your system framebuffer.

One small point with that. If you want to blit your multisample texture to your system framebuffer that is also multisampled, they must have the same number of samples. If the system framebuffer is not multisampled, then you can use any sample count you want.

Dark Photon
01-29-2013, 05:41 AM
True. I hadn't considered that use case. Typically you want to off-screen render in MSAA and downsample blit to the system FB.

Alfonse Reinheart
01-29-2013, 06:15 AM
This came up at one point because drivers often have a way to let users force multisampling on applications. And this usually manifests as forcing multisampling on the back buffer, thus breaking the blit from the internal FBO to the back buffer.

Dark Photon
01-29-2013, 06:14 PM
Ah! Good point!

debonair
03-07-2013, 10:04 AM
Does GL_RGB32I support for 4x or 8x multisampled textures in call glTeximage2DMultisample? Are there any other formats which do not support 4x or 8x ?