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 plain copy

  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基本一致。

关于GLSL的gl_FragCoord、gl_FragDepth以及深度计算相关推荐

  1. OpenGL-GLSL语言入门教程(1)

    目录 GLSL简介 GLSL的内建变量 顶点着色器变量 gl_PointSize gl_VertexID 片段着色器变量 gl_FragCoord gl_FragDepth 参考网站:LearnOpe ...

  2. opengl 投影矩阵和深度测试

    写在前面  上一节我们使用AssImp加载了3d模型,效果已经令人激动了.但是绘制效率和场景真实感还存在不足,接下来我们还是要保持耐心,继续学习一些高级主题,等学完后面的高级主题,我们再次来改进我们加 ...

  3. 有关GLSL中的gl_FragCoord

    有关GLSL中的gl_FragCoord 在研究阴影映射的时候,我发现了一个很有意思的变量,它可以代替我们自己使用的varying变量,给我们带来方便.但是我们也需要了解它是如何计算的. 蒋彩阳原创文 ...

  4. glsl gl_FragCoord 与 屏幕关系

    转载链接:  http://blog.csdn.net/jinghouxiang/article/details/50751125 原创  2016年02月26日 17:06:01 标签: OpenG ...

  5. Lesson2 Hello,GLSL

    2019独角兽企业重金招聘Python工程师标准>>> OpenGL着色语言(OpenGL Shading Language)是用来在OpenGL中着色编程的语言,也即开发人员写的短 ...

  6. GLSL. 语法基础

    GLSL语法跟C语言非常相似: 1.数据类型: GLSL包含下面几种简单的数据类型 float  bool :false or ture int 向量: vec   {2,3,4}     长度为2, ...

  7. OpenGL基础39:GLSL内建变量与接口块

    GLSL有几个以gl_为前缀的变量(内建变量),它们在着色器中能直接获取和使用,并且都有着很重要的意义,gl_Position 和 gl_FragCoord 就是两个典型的内建变量 一.顶点着色器变量 ...

  8. GLSL到HLSL参考

    GLSL到HLSL参考 2017年2月8日 11分钟阅读 贡献者 当您将图形架构从OpenGL ES 2.0移植到Direct3D 11以创建通用Windows平台(UWP)游戏时,可以将OpenGL ...

  9. 【AR\VR开发基础】GLSL初步学习①

    可能看到这很多人就会认为跑偏了,我们明明是来学AR/VR的为啥要搞 GLSL ?这是神马鬼? 其实在图形学中,我们要学的东西很多,就比如说一些专业术语,还有线性代数... 所以今天就带大家先来认识一下 ...

最新文章

  1. linux c 编译警告 warning: this decimal constant is unsigned only in ISO C90
  2. Java jvisualvm简要说明
  3. js中null和undefined
  4. python 爬虫 音乐下载 歌手_python爬虫批量下载全民K歌音乐
  5. public static void main(String[] args)的理解
  6. 【高等数学】一元函数微分学
  7. 爬虫python怎么下载_在网上下了一个 python 爬虫程序,怎么运行?
  8. 华南理工大学计算机科学与工程学院篡改,华南理工大学涉嫌篡改成绩人员已被停职调查...
  9. 因系统因配置问题报错,如何调整(两类 【与外界其他环境相关联】 【★自身配置★】(★关注web.xml★))
  10. java文件字节流和文件字符流的使用
  11. 记一次spring5源码完整编译过程
  12. 3月编程排行榜来了~有哪些新看点?
  13. 微信公众号自定义消息模板(处理数据)
  14. KingbaseES R6 集群手工配置VIP案例
  15. Hinton最新访谈丨他如何看待谷歌胶囊网络专利、神经科学以及下一代AI?
  16. pyd文件逆向(二)
  17. 【最新面试技巧分享】面试官想看到的以及面试者需要准备的!
  18. android 进程被回收,Android开发进阶:Activity和进程的回收和状态恢复
  19. 根据GEOHASH,查找附近的人,判断距离远
  20. Menu键_subMenu设置

热门文章

  1. 分水岭算法java,C++实现分水岭算法(Watershed Algorithm)
  2. UBI文件系统(转)
  3. html贝塞尔曲线在线,【HTML+js+纯前端】三次方贝塞尔曲线手工拟合小工具
  4. Raid磁盘阵列重建后如何恢复原来的数据
  5. office起动缓慢_怎么解决Office2016启动特别慢?
  6. 阿里巴巴实习生负一天
  7. 蚁群算法(详解)python
  8. Windows静默安装
  9. 微信小程序:微信零钱模拟器微信小程序源码下载查收充电器自动充钱
  10. aac格式怎么转换为MP3格式