GLSL fragment shader output type

Suppose I'm having a problem like this: now I have a framebuffer and a texture only contains one color component(for example, GL_RED) has already binded to it. What will fragment shader looks like? I guess the answer is:

... out float ex_color;

ex_color = ...;

Here comes my question : will the shader automatically detect the format of framebuffer and write values to it? What if fragment shader outputs float values but framebuffer format is GL_RGBA?

By the way, what is the correct approach to create a texture only has one component? I read examples from g-truc which has a sample like this:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RED,GLsizei(Texture.dimensions().x), GLsizei(Texture.dimensions().y), 0,GL_RGB, GL_UNSIGNED_BYTE, 0);

What's the meaning of assign GL_RGB as pixel data format?


Just like vertex shader inputs don't have to match the exact size of the data specified by glVertexAttribPointer, fragment shader outputs don't have to match the exact size of the image they're being written to. If the output provides more components than the destination image format, then the extra components are ignored. If it provides fewer, then the other components have undefined values (unlike vertex inputs, where unspecified values have well-defined values).

What's the meaning of assign GL_RGB as pixel data format?

That's the pixel transfer format. That describes the format of pixels you're providing to OpenGL, not the format that OpenGL will store them as.

You should always use sized internal formats, not unsized ones like GL_RED .


For a decent explanation of the internal format and format, see:

http://opengl.org/wiki/Image_Format and http://opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml.

You basically want GL_RED for format and likely want GL_R8 (unsigned normalized 8-bit fixed-point) for the internal format.

A long time ago, luminance textures were the norm for single-channel, but that is a deprecated format in modern GL and red is now the logical "drawable" texture format for single-channels, just as red/green is the most logical format for two-channel.

As for your shader, there are rules for component expansion defined by the core specification. If you have a texture with 1 channel as an input, but sample it as a vec4, it will be equivalent to: vec4 (RED, 0.0, 0.0, 1.0).

Writing to the texture is a little bit different.

From the OpenGL 4.4 Spec, section 15.2 (Shader Execution), pp. 262 -- http://www.opengl.org/registry/doc/glspec44.core.pdf

When a fragment shader terminates, the value of each active user-defined output variable is written to components of the fragment color output to which it is bound. The set of fragment color components written is determined according to the variable's data type and component index binding, using the mappings in table 11.1 [pp. 340].

By default, if your fragment shader's output is a float, it is going to write to the x (red) component of your texture. You could use a layout qualifier (eg layout (component=1) out float color;) to specify that it should write to y (green), z (blue) or w (alpha) (assuming you have an RGBA texture).

链接地址: http://www.djcxy.com/p/38538.html

上一篇: openGL渲染纹理渲染总是黑色的几何

下一篇: GLSL片段着色器输出类型