views:

43

answers:

2

Is there any fast(for performance) way to detect in glsl if fragment has been multisampled, but in second(light) pass using textures where been 1st pass rendered. Or how is opengl storing informations about multisampling?

A: 

Multisampling is activated at contex creation when choosing the pixel format. After that you can't turn it off or on. But when you render to a texture OpenGL will not use multisampling regardless what the setting for the contex is.

http://www.opengl.org/wiki/Multisampling

Daniel
OpenGL supports multisampling to texture, there are multisampled texture formats. chceck newest versions :)
Miro
Oh, should have figured that was in a seperate extension :) (GL_EXT_framebuffer_multisample)
Daniel
+1  A: 

They are several. The usual one is to check is the current's coordinates (gl_FragCoord) are (0.5, 0.5). If it is, it means that you're in the middle of a polygon : it's sampled only once.

It it's not, it's probably one of the 4 (for 4xMSAA) rotated-square-corners : You're on an edge, and openGL has detected that one sample only isn't enough.

See also http://www.opengl.org/pipeline/article/vol003_6/

In order to have this information in a second pass, you'll have to store it in a g-buffer, though.

EDIT : Here is a code snippet that I've just done. Tested on gtx 470 with a 1024x1024 4xMSAA texture.

Vertex shader :

    #version 400 core

uniform mat4 MVP;
noperspective centroid out vec2 posCentroid;

layout(location = 0) in vec4 Position;

void main(){    
    gl_Position = MVP * Position;
    posCentroid = (gl_Position.xy / gl_Position.w)*512; // there is a factor two compared to 1024 because normalized coordinates have range [-1,1], not [0,1]
}

Fragment shader :

#version 400 core

out vec4 color;
noperspective centroid in  vec2 posCentroid;

void main()
{
    if (abs(fract(posCentroid.x) - 0.5) < 0.01 && abs(fract(posCentroid.y) - 0.5) < 0.01){
        color = vec4(1,0,0,0);
    }else{
        color = vec4(0,1,0,0);
    }
}

Edges are green, center of polygon is red.

For your original question, I recommend you this article : http://www.gamasutra.com/view/feature/3591/resolve_your_resolves.php

Calvin1602
gl_FragCoord is position [0,screen_size]. I've tried to detect relative position by this code (vec2 a = gl_FragCoord.xy - floor(gl_FragCoord.xy); if(a.x != 0.5 else { gl_FragColor= vec4(0,1,0,1); }), but it haven't work
Miro
That's normal. You have to use a centroid varying (gl_FragCoord is not centroid). I have to check this out, I'll get back to you when I know how to do it.
Calvin1602
@Miro http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat main(){fragcoord = MVP *in_Position; fragcoord.xy/=fragcoord.w;} and FS -> what you did but with fragcoord
Calvin1602
@Miro : edited answer with actual GLSL code
Calvin1602