博客
关于我
关于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 Server 5.5安装记录
查看>>
mysql slave 停了_slave 停止。求解决方法
查看>>
MySQL SQL 优化指南:主键、ORDER BY、GROUP BY 和 UPDATE 优化详解
查看>>
mysql sum 没返回,如果没有找到任何值,我如何在MySQL中获得SUM函数以返回'0'?
查看>>
mysql Timestamp时间隔了8小时
查看>>
Mysql tinyint(1)与tinyint(4)的区别
查看>>
mysql union orderby 无效
查看>>
mysql where中如何判断不为空
查看>>
mysql workbench6.3.5_MySQL Workbench
查看>>
MySQL Workbench安装教程以及菜单汉化
查看>>
MySQL Xtrabackup 安装、备份、恢复
查看>>
mysql [Err] 1436 - Thread stack overrun: 129464 bytes used of a 286720 byte stack, and 160000 bytes
查看>>
MySQL _ MySQL常用操作
查看>>
MySQL – 导出数据成csv
查看>>
MySQL —— 在CentOS9下安装MySQL
查看>>
mysql 不区分大小写
查看>>
mysql 两列互转
查看>>
MySQL 中开启二进制日志(Binlog)
查看>>
MySQL 中文问题
查看>>
MySQL 中日志的面试题总结
查看>>