关于GLSL的gl_FragCoord、gl_FragDepth以及深度计算
2014-02-25 19:28
375 查看
原帖地址:http://my.oschina.net/lyr/blog/90681
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之间的距离。参见Fog
in GLSL page 4。
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;这说明一直以来的右手坐标系在投影变换后变成了左手坐标系。关于深度的变换和精确性参见OpenGL
FAQ - 12 The Depth Buffer。
根据GLSLangSpec.Full.1.30.08(p61),gl_FragCoord.z是固定功能计算所得的结果。如果片元着色器不写gl_FragDepth,那么这个值将用在后续处理中。OpenGL Shading Language提到(p104),即使将gl_FragCoord.z赋值给gl_FragDepth也不能保证产生和固定功能完全相同的值。但是,可以保证相对正确。加之片元着色器一旦写入gl_FragDepth,就必须保证在每个分支都有写入。因此,如果一个着色器需要在某些条件下自己计算深度,其它条件下的正确做法就是gl_FragDepth
= gl_FragCoord.z。
在OpenGL的固定管线中,深度坐标是在视口变换期间变换到glDepthRange指定的范围之内(OpenGL编程指南-原书第五版,88页)。视口变换也就是光栅化(Rasterization),在进行到片元着色器的时候自然已经编码完毕了。
自行计算片元深度可以用下面的方法(参考OpenGL FAQ - 12 The Depth Buffer):
[cpp] view plaincopy
view
source
print?
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之间的距离。参见Fog
in GLSL page 4。
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;这说明一直以来的右手坐标系在投影变换后变成了左手坐标系。关于深度的变换和精确性参见OpenGL
FAQ - 12 The Depth Buffer。
根据GLSLangSpec.Full.1.30.08(p61),gl_FragCoord.z是固定功能计算所得的结果。如果片元着色器不写gl_FragDepth,那么这个值将用在后续处理中。OpenGL Shading Language提到(p104),即使将gl_FragCoord.z赋值给gl_FragDepth也不能保证产生和固定功能完全相同的值。但是,可以保证相对正确。加之片元着色器一旦写入gl_FragDepth,就必须保证在每个分支都有写入。因此,如果一个着色器需要在某些条件下自己计算深度,其它条件下的正确做法就是gl_FragDepth
= gl_FragCoord.z。
在OpenGL的固定管线中,深度坐标是在视口变换期间变换到glDepthRange指定的范围之内(OpenGL编程指南-原书第五版,88页)。视口变换也就是光栅化(Rasterization),在进行到片元着色器的时候自然已经编码完毕了。
自行计算片元深度可以用下面的方法(参考OpenGL FAQ - 12 The Depth Buffer):
[cpp] view plaincopy
view
source
print?
01 | // Vertex Shader |
02 | varying vec4 position; |
03 | void main( void ) |
04 | { |
05 | position = gl_ModelViewMatrix * gl_Vertex; |
06 | gl_Position = ftransform(); |
07 | } |
08 | // Fragment Shader |
09 | uniform float zFar; |
10 | uniform float zNear; |
11 | varying vec4 position; |
12 | void main() |
13 | { |
14 | float zDiff |
15 | float interpolatedDepth 0.5 * 0.5 ; |
16 | gl_FragColor = vec4(vec3(pow(interpolatedDepth, 15.0 )), 1.0 ); |
17 | } |
相关文章推荐
- 关于GLSL的gl_FragCoord、gl_FragDepth以及深度计算
- 关于GLSL的gl_FragCoord、gl_FragDepth以及深度计算
- 学习ShaderToy第一天: glsl语言内置函数gl_FragCoord
- 有关GLSL中的gl_FragCoord
- 关于OpenGL中深度截取(GL_DEPTH_CLAMP)的讲解
- glsl gl_FragCoord 与 屏幕关系
- 关于OpenGL+GLSL深度贴图采样
- 关于深度冲突(Z-Finghting or Depth Fighting)的解决
- 关于无线数据传输中产生的流量的一些计算方法以及问题!
- gl_FragCoord的xyzw
- 关于js中select的简单操作,以及js前台计算,span简单操作
- 关于FFT的一些理解,以及如何手工计算FFT加深理解和验证正确性
- 关于Linux操作系统中LUN的队列深度(queue_depth)
- 关于Oracle中各个命中率的计算以及相关的调优总结
- leetcode:Maximum Depth of Binary Tree(计算二叉树深度) 【面试算法】
- 深度链接、延迟深度链接、App Links以及关于LinkedME实现深度链接的原理解析
- 关于FIFO深度的计算的讨论
- 关于Z(Depth 深度)和Stencil(模板)两种测试对后台缓存的影响次序
- 关于计算中的“同余式”以及取模等问题
- 百度DMLC分布式深度机器学习开源项目(简称“深盟”)上线了如xgboost(速度快效果好的Boosting模型)、CXXNET(极致的C++深度学习库)、Minerva(高效灵活的并行深度学习引擎)以及Parameter Server(一小时训练600T数据)等产品,在语音识别、OCR识别、人脸识别以及计算效率提升上发布了多个成熟产品。