OpenGL 片元着色及输出

片元着色器处理光栅化后的产生片元并输出一系列的颜色和一个深度值。片元着色器是图元光栅化后,OpenGL显示管线的下一阶段,被图元覆盖的像素将产生输出。每一个片元着色器都具有窗口空间的位置和一系列在前一阶段顶点着色器输出的逐顶点插值。

片元着色器将输出一个深度值(depth value 范围 0 - 1),也可能包含一个模版值(看定义的深度缓冲格式是否包含模版 GL_DEPTH_COMPONENT24 ,GL_DEPTH_COMPONENT32, 模版缓存被启用,该值在着色器中不会被修改),零 到 多个 颜色值,这些值将被写入到帧缓存中。

 

特性:

  • 该阶段是可选的

片元着色器是可选阶段,如果不使用片元着色器,颜色输出是未定义的,且不会改变深度、模版缓存值。可以利用这一特性,在顶点着色器中计算深度值, (没有片元着色器,不改变其值)直接刷新深度缓冲区, 实现阴影绘制和 预处理深度通道 等技法。

  • 特殊操作

  1. 输出偏导数,在着色器中使用诸如dFdx(), dFdy() 这一类函数。
  2. 使用discard 命令终止 颜色、图像 、着色器存储缓存对象的写入及原子操作。
  3. 使用【layout(early_fragment_tests) in 】限定符执行 预逐像素处理, 好处是只有像素可见,才执行图像读写等消耗系统资源的操作, 是OpenGL4.2 加入的新特性 。

The following Per-Sample Processing steps can be performed before the fragment shader:

The pixel ownership test

The scissor test

The stencil test

The depth test

Occlusion query updating

Note that with OpenGL 4.2 or ARB_shader_image_load_store, the pixel ownership and scissor tests will always be performed early.

  • 片元着色器的输入 

片元着色器的输入是早期固定管线系统输入及图元表面的插值。 

   1. 系统输入

     in bool gl_FrontFacing;    //双面光照

     in vec2 gl_PointCoord;

in vec4 gl_FragCoord ; //这个输入有用的多,多用在后处理。

      gl_FragCoord 在片元着色器阶段很有用, x, y 是窗口空间的值,单位是像素。如果用户没有写入gl_FragDepth, z 值将被写入, gl_FragCoord 是  1/Wclip , Wclip 透视除法 其值是 VclipCoord = PVM_matrix * Vertex 的 w值。

 裁剪空间坐标直接用乘上 gl_FragCoord.w 即做了透视除法了。

   OpenGL 4.0 加入 的  gl_SampleID,gl_SamplePosition,gl_SampleMaskIn。

   -------------------------------------------------------------------------------

   gl_ClipDistance,gl_PrimitiveID

   OpenGL4.3 加入的

   gl_Layer,gl_ViewportIndex。

   2. 顶点着色器阶段的输入

   out 出的各种属性值。

  • 片元着色器输出

 用户自定义输出,只能是 浮点数 floats, 整数 integers,和向量 vectors, 相同类型可以成组输出,不能输出接口块 interface blocks

有三种方法可以将输出变量与颜色号关联起来:

1. 在着色器中指定 In-shader specification

layout(location = 3) out vec4 diffuseColor;

 2.在shader链接前指定 Pre-link specification

  glBindFragDataLocation(GLuint program​, GLuint colorNumber​, const char * name​);

3. 系统自动设置 Automatic assignment

   正如顶点属性输入一样,颜色输出的索引号也是连续的, 自动分配输出并不是什么好主意,不同的片元着色器,即使输出名字相同,分配的输出也可能不同,你每次都需要验证其有效性。

 

1. 在着色器中控制 gl_FragDepth 输出值。

 GLSL 4.20 or ARB_conservative_depth 定义输出值 

 

  •  其它输出

layout (depth_<condition>) out float gl_FragDepth;

any

The default. You may freely change the depth, but you lose the most potential performance.

greater

You will only make the depth larger, compared to gl_FragCoord.z.

less

You will only make the depth smaller, compared to gl_FragCoord.z.

unchanged

If you write to gl_FragDepth, you will write exactly gl_FragCoord.z.

2. GLSL 4.00 or ARB_sample_shading  定义多重采样掩码:

out int gl_SampleMask[];

gl_SampleMask

 

  • MRTT 示例 

首先指定输出缓存:

const GLenum buffers[] = {GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT2, GL_NONE, GL_COLOR_ATTACHMENT0};
glDrawBuffers(4, buffers);

其次,在shader 中关联输出位置 location 及定义输出格式 int, vec3, vec4...:


layout(location = 1) out int materialID;
layout(location = 4) out vec3 normal;
layout(location = 0) out vec4 diffuseColor;
layout(location = 3) out vec3 position;
layout(location = 2) out vec4 specularColor;

Output nameColor attachment
materialIDGL_COLOR_ATTACHMENT2
normalGL_NONE
diffuseColorGL_COLOR_ATTACHMENT4
positionGL_COLOR_ATTACHMENT0
specularColorGL_NONE

当指定的索引号超出范围时,输出无效 GL_NONE 。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值