博客
关于我
关于GLSL的gl_FragCoord、gl_FragDepth以及深度计算
阅读量:496 次
发布时间:2019-03-07

本文共 1535 字,大约阅读时间需要 5 分钟。

gl_FragCoord和gl_FragDepth分别是片元着色器的输入和输出变量。

gl_FragCoord是个vec4,四个分量分别对应x, y, z和1/w。其中,x和y是当前片元的窗口相对坐标,不过它们不是整数,小数部分恒为0.5。x - 0.5和y - 0.5分别位于[0, windowWidth - 1]和[0, windowHeight - 1]内。windowWidth和windowHeight都以像素为单位,亦即用glViewPort指定的宽高。w即为乘过了投影矩阵之后点坐标的w,用于perspective divide的那个值。gl_FragCoord.z / gl_FragCoord.w可以得到当前片元和camera之间的距离。参见。

gl_FragCoord.z是固定管线计算出的当前片元的深度。它已经考虑了多边形偏移,并经过了投影变换。它位于[0.0, 1.0]之间。如果用gl_FragColor = vec4(vec3(gl_FragCoord.z), 1.0)将其可视化,多半会看到一片白。这是由于变换的非线性,大多数点的深度都非常接近于1。用gl_FragColor = vec4(vec3(pow(gl_FragColor.z, exp)), 1.0)并将exp取为合适的值,就能看到从黑到白的深度变化了。距离观察者近的颜色深,接近0.0;距离观察者远的颜色浅,接近1.0;这说明一直以来的右手坐标系在投影变换后变成了左手坐标系。关于深度的变换和精确性参见。

根据GLSLangSpec.Full.1.30.08(p61),gl_FragCoord.z是固定功能计算所得的结果。如果片元着色器不写gl_FragDepth,那么这个值将用在后续处理中。提到(p104),即使将gl_FragCoord.z赋值给gl_FragDepth也不能保证产生和固定功能完全相同的值。但是,可以保证相对正确。加之片元着色器一旦写入gl_FragDepth,就必须保证在每个分支都有写入。因此,如果一个着色器需要在某些条件下自己计算深度,其它条件下的正确做法就是gl_FragDepth = gl_FragCoord.z。

在OpenGL的固定管线中,深度坐标是在视口变换期间变换到glDepthRange指定的范围之内(OpenGL编程指南-原书第五版,88页)。视口变换也就是光栅化(Rasterization),在进行到片元着色器的时候自然已经编码完毕了。

自行计算片元深度可以用下面的方法(参考):

 

[cpp]  

  1. // Vertex Shader  
  2. varying vec4 position;  
  3. void main(void)  
  4. {  
  5.     position = gl_ModelViewMatrix * gl_Vertex;  
  6.     gl_Position = ftransform();  
  7. }  
  8. // Fragment Shader  
  9. uniform float zFar;  
  10. uniform float zNear;  
  11. varying vec4 position;  
  12. void main()  
  13. {  
  14.     float zDiff = zFar - zNear;  
  15.     float interpolatedDepth = (position.w / position.z) * zFar * zNear / zDiff + 0.5 * (zFar + zNear) / zDiff + 0.5;  
  16.     gl_FragColor = vec4(vec3(pow(interpolatedDepth, 15.0)), 1.0);  
  17. }  

 

这样计算出的深度与gl_FragCoord.z基本一致。

转载地址:http://gsedz.baihongyu.com/

你可能感兴趣的文章
MySQL 存储过程参数:in、out、inout
查看>>
mysql 存储过程每隔一段时间执行一次
查看>>
mysql 存在update不存在insert
查看>>
Mysql 学习总结(86)—— Mysql 的 JSON 数据类型正确使用姿势
查看>>
Mysql 学习总结(87)—— Mysql 执行计划(Explain)再总结
查看>>
Mysql 学习总结(88)—— Mysql 官方为什么不推荐用雪花 id 和 uuid 做 MySQL 主键
查看>>
Mysql 学习总结(89)—— Mysql 库表容量统计
查看>>
mysql 实现主从复制/主从同步
查看>>
mysql 审核_审核MySQL数据库上的登录
查看>>
mysql 导入 sql 文件时 ERROR 1046 (3D000) no database selected 错误的解决
查看>>
mysql 导入导出大文件
查看>>
mysql 将null转代为0
查看>>
mysql 常用
查看>>
MySQL 常用列类型
查看>>
mysql 常用命令
查看>>
Mysql 常见ALTER TABLE操作
查看>>
MySQL 常见的 9 种优化方法
查看>>
MySQL 常见的开放性问题
查看>>
Mysql 常见错误
查看>>
MYSQL 幻读(Phantom Problem)不可重复读
查看>>