PDA

View Full Version : shader that stores normal values in buffer



ddubuck343
10-07-2010, 08:39 PM
Hello,

I'm supposed to write a shader that can store normals in the buffer and generate texture out of it.
I already have properly rendered output by default so just I need to get normal values based on the output.
I guess it can be done by storing gl_Normal but I'm not sure how to pass these values to application and store them as texture.
Is there a way that shader can pass values to application?

Thank you.

BionicBytes
10-08-2010, 05:43 AM
In Dirext X it's called Multiple render to texture (MRT). In OpenGLyou can setup multiple outputs with a pixel shader. You need a FrameBuffer (FBO) with two or more color texture attachments and use glDrawBuffers to specify which attachments you want the shader to output to.
So, the FBO will usually be specified so that it has GL_COLOR_ATTACHMENT0 and GL_COLOR_ATTACHMENT1 bound and then you'll use glDrawBuffers to tell GL to direct it's output to those attachment points.
The Shader will use gl_FragData[n], where n = 0,1,...15 to match which values were used with glDrawBuffers.

ddubuck343
10-08-2010, 01:38 PM
Thank you for your reply.
However, when I tried doing things based on your advice,
I don't get behavior that I want.
Here are my codes.


norm_data = (unsigned char *)malloc(sizeof(unsigned char) * 4 * w * h);
GLenum buffers[] = {GL_COLOR_ATTACHMENT0_EXT};
glGenTextures(1, &norm_tex);
glGenFramebuffers(1, &frame_buf);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, norm_tex);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, norm_data);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frame_buf);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, norm_tex, 0);

glUseProgramObjectARB(norm_program); // I already attached shader
render(); // given render function
glDrawBuffers(1, buffers);
glUseProgramObjectARB(0);

This is my vert shader


void main() {
gl_FragData[0] = vec4(gl_Normal, 0);
}


Any help? Thank you.

Alfonse Reinheart
10-08-2010, 01:41 PM
This is my vert shader

I don't know how that compiles as a vertex shader. gl_FragData is a built-in variable for fragment shaders.

You must pass your normals from the vertex shader to the fragment shader if you want to write them.

ddubuck343
10-08-2010, 05:18 PM
Oh yeah you're right. I put the wrong shader.



varying vec3 norm;

void main() {
norm = vec3(gl_Normal);
}




varying vec3 norm;

void main() {
gl_FragData[0] = vec4(norm, 0.0);
}


This still doesn't work.

BionicBytes
10-09-2010, 04:30 PM
Normals are between -1 and 1. This is outside the range of the values of a fixed range 8-bit texture (0.0 - 1.0).
What you need to do is convert the normals like this

vec3 Normalmap = (0.5 * norm) + 0.5
gl_FragData[0]=vec4(Normalmap, 1.0)