gl_FragCoord 的含义

article/2025/9/15 14:26:30

gl_FragCoord 表示当前片元着色器处理的候选片元窗口相对坐标信息,是一个 vec4 类型的变量 (x, y, z, 1/w), 其中 x, y 是当前片元的窗口坐标,OpenGL 默认以窗口左下角为原点, 在 着色器中通过布局限定符可以重新设定原点,比如窗口左上角为原点 origin_upper_left,窗口大小由 glViewport() 函数指定。x, y 默认是像素中心 而非 整数, 原点 的窗口坐标值为 (0.5, 0.5), 小数部分恒为 0.5,  当viewport 范围 为(0,0,800,600)时, x, y 的取值范围为(0.5, 0.5, 799.5, 599.5), 当在着色器中布局限定符设置为 pixel_center_integer  时, x, y 取值为整数。

 

第三个分量  z 表示的是当前片元的深度信息,由 vertex shader 处理过后系统插值得到, gl_FragCoord.z 的产生过程:

假设 OpenGL 变换的各坐标系统定义如下: world.xyzw 表示 世界坐标系的坐标, eye.xyzw 表示眼坐标系(也叫观察坐标系,还有叫相机坐标系,呃。。。) 的坐标, clip.xyzw 表示 裁剪坐标系的坐标 , ndc.xyzw 表示 规范化设备坐标系坐标, win.xyzw 表示 窗口坐标系坐标, OpenGL 一个完整的空间变换流水线如下:

world coordinate system --> eye coordinate system --> clip coordinate system --> normalized device coordinate system --> window device coordinate system。

  gl_FragCoord.z 生成过程:

(1)世界坐标系内的坐标乘以观察矩阵变换到眼坐标空间  eye.xyzw = viewMatrix * world.xyzw;

(2)眼坐标系内的坐标通过乘上投影矩阵变换到裁剪空间 clip.xyzw = projectMatrix * eye.xyzw;

(3)裁剪坐标系内的坐标通过透视除法(也就是  w 为 1 化) 到 规范化设备坐标系 ndc.xyz = clip.xyz / clip.w;

(4)设备规范化坐标系到窗口坐标系 win.z = (dfar - dnear)/2 * ndc.z + (dfar+dnear)/2;

可以看出 gl_FragCoord.z 是 win.z 。dnear ,dfar 是由 glDepthRange(dnear, dfar) 给定的,按openGL 默认值 (0,1) , win.z = ndc.z/2 + 0.5

有时候我们需要在 shader 内反算 眼坐标系 或 世界坐标系 内的坐标, 这在后处理或延迟着色中很有用,不需要另外使用颜色缓存保留物体位置信息,减少带宽占用。反算窗口空间内的片元的空间坐标: 

ndc.xyzw =  ( gl_FragCoord.xy/viewport.wh * 2.0  - 1.0,  gl_FragCoord.z * 2.0  - 1.0, 1.0 );

这样我们只需向shader 中传入 矩阵信息 , 就可以获得该片元在指定空间内的坐标 ,例如

  • eye.xyzw    = projectionMatrixInverse * ndc.xyzw;
  • world.xyzw = modelViewProjectionMatrixInverse * ndc.xyzw

注意最终结果要除以 w 分量, eye.xyz = eye.xyz/eye.w;

第四个分量  gl_FragCoord.w

先看看透视投影矩阵的推导:

 

gl_FragCoord.w 是裁剪空间 clip.w 的倒数即 1/clip.w ,  由上面的透视投影矩阵的推导过程可以看出,为了凑透视除法, clip.w 值就是 眼坐标系 z 值的负数,也就是距离相机的距离。 取负数 是因为 眼坐标系 与 规范化设备坐标系 手向性不同, 眼坐标系是右手系, 规范化设备坐标系是左手系。这里暗示我们,对于透视投影, 由 gl_FragCoord.w  可以很方便的知道当前片元在眼坐标系中 距离相机的距离  : gl_FragCoord.w = - 1/Ze  ---------->   Ze = - 1/gl_FragCoord.w;

那么正交投影呢?  没门! 正交投影矩阵的 w 值 恒为 1, 还是乖乖的传矩阵做逆运算吧。当然 用逆矩阵反求 各坐标系的坐标 具有通用性。

总结:

gl_FragCoord 比较有用的是反求各坐标系的空间位置,减少带宽占用。 也可以方便的获取当前片元的窗口坐标和片元深度值。当深度测试开启时, 如果在片元着色器中没有定义 gl_FragDepth 的值, gl_FragCoord.z 即成为默认输出的深度值,并且gl_FragDepth 不会存在未定义输出的情况(因为不是用户定义的值就是系统给定的默认值)。

题外话, 给定一个矩阵,怎样判断投影矩阵 是 透视投影还是正交投影呢?

 

最后给两个函数,在基于延迟着色的fragment shader 中 反求片元在 眼坐标系 或 世界坐标系的位置:

vec3 decodeCameraSpacePositionFromDepthBuffer(in vec2 texCoord){vec4 clipSpaceLocation;	clipSpaceLocation.xy = texCoord*2.0-1.0;clipSpaceLocation.z  = texture(depthTexture, texCoord).r * 2.0-1.0;clipSpaceLocation.w  = 1.0;vec4 homogenousLocation = projectionMatrixInverse * clipSpaceLocation;return homogenousLocation.xyz/homogenousLocation.w;
}vec3 decodeWorldSpacePositionFromDepthBuffer(in vec2 texCoord){vec4 clipSpaceLocation;	clipSpaceLocation.xy = texCoord*2.0-1.0;clipSpaceLocation.z  = texture(depthTexture, texCoord).r * 2.0-1.0;clipSpaceLocation.w  = 1.0;vec4 homogenousLocation = viewProjectionMatrixInverse * clipSpaceLocation;return homogenousLocation.xyz/homogenousLocation.w;
}

 


http://chatgpt.dhexx.cn/article/oH8MwHv5.shtml

相关文章

WebGL着色器内置变量gl_PointSize、gl_Position、gl_FragColor、gl_FragCoord、gl_PointCoord

WebGL着色器内置变量 WebGL中文教程网 本文是WebGL教程(电子书)的2.7节内容 着色器语言在GPU的着色器单元执行,javascript语言、C语言在CPU上执行,任何一种语言的语法规则,整体设计都和它执行的硬件有一定的关系,GPU和CPU执行程…

Unity画线之GL

上一篇中,SetPixel的方法,卡顿严重,暂未解决,又去看了原来的GL画线,自己画图思考了一下适配UI的问题,最终解决。 特此说明,GL画线功能,及Shader均为借鉴,自己做了优化。…

GL823K

下面是另一家SD/TF解码芯片的方案 ![](https://img-blog.csdnimg.cn/20210319145313645.png?x-oss-processimage/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80OTU3MDgwNA,size_16,color_FFFFFF,t_70 13030533945 VX

GL各个表结构总结

NewProgramer EBS GL表结构学习(转) gl_code_combinations:科目组合 字段名 含义 备注 code_combination_id 主键,科目编码ID,自动编号 segment1 分行代码 setgment2 是受益部门 segment3 科目代码 segment4 产品…

初识mapbox GL

一、概述 最近由于项目的需求,借此机会对mapbox GL做了一个系统的学习,同时也对整个学习过程做一个记录,一方面留作自用,另一方面也希望看到此文的人在学习mapbox GL的时候,能够有所启发、有所收获。 二、快速认识 …

支持Genero BDL 4gl语言的编辑器

内测版本出来啦。点此下载: FglDeveloper v1.0 →此版本已下架 还有bug,分享几张截图 模板产生器: 画面产生器: 编辑器各种变量提醒 详细功能小伙伴们下载后体验。

TOPGP5.3:导入jar包并在4GL中引用

查看环境$CLASSPATH 上传引用到的JAR包到以下目录 /u1/topprod/tiptop/ds4gl2/bin/javaad/jar 以上为GP5.3目录,其他版本系统可根据查看到的$CLASSPATH上传到相应目录设置环境变量 GP5.3系统中,$CLASSPATH环境变量的设置存在下图文件中: …

4gl调用WEB API,实现JSON传递(Demo)

测试环境: GP5.25 , fjs版本2.32,解析json所需要的jar依赖包 (PS: 如果没有记错是fjs2.32版本及以上才支持java bridge,所以GP 5.25以下的同学就不要用这种方式去测试) 测试内容: 利用此fjs版本对java bridge的支持,实现4gl调用WEB API,实现json传递 测试步骤如下: 1.下载本…

给大家展示一下4gl编辑器

(正式版已发布点击下载)特地为编辑器开发内置语法解析器,将在代码编辑过程中实时提示代码错误,并且错误提示都是中文显示(楼主英文太垃圾只有做中文了),不再需要频繁上传服务器了哦, 经过楼主努力已经把所有的内置函数…

【实习之T100开发】Genero FGL (TIPTOP4GL) 学习笔记(1)

Genero FGL 学习 Genero FGL 简介Genero FGL 开发(编译、连接、执行)第一个程序 Hello World变量与运算符变量定义(DEFINE)预定义变量变量集合(RECORD )数据结构(TYPE)变量赋值&…

win10忘记密码重置密码,一行代码帮你解决

步骤如下: 1.右击windows图标,选择进入Windows PowerShell(管理员) 2.敲入代码net user 加上你的用户名和新密码,Ok,问题解决,你就可以用你的新密码登陆了

win10 重置登录账户密码

在登陆界面按下强制关机(重复3次)。注意:不能进到登陆界面 出现下图时,选择“高级选项”: 选择“疑难解答”: 选择“高级选项”: 选择“命令提示符”: 在管理员窗口输入diskpart 回车…

服务器2008系统设置密码,win2008服务器设置密码

win2008服务器设置密码 内容精选 换一换 修改服务IP地址,并且将DNS地址指向本机,然后修改计算机名为server。安装AD域服务之后,机器名称会自动变成“主机名域名”的形式,例如server.huawei.com。在命令行下输入dcpromo.exe &#…

Win10系统修改开机密码

愚蠢的人才能进步,对于我这种记忆力差的人,密码这个东东随时忘,今天早上大无语事件,我自己都惊呆了,每天都用的办公电脑,今天死活想不起密码,死活打不开电脑,明明就是那些组合&#…

win10忘记密码_电脑忘记密码没关系,这招教你简单轻松改密码

相信"忘记电脑开机密码"这件事经常发生,忘记密码该怎么办呢?这个问题困扰了许多小伙伴,今天就教大家一种最简单的方法轻松重置电脑开机密码(本方法适用win10、win8、win7系统)。 划重点: 重置电脑开机密码一共分为三个步骤「 制作PE系统」「进入PE系统 」「重置密…

win10计算机默认用户名和密码是什么,win10共享的文件夹需要密码和用户名登陆...

一、共享文件夹所在电脑设置 1、右键我的电脑→管理→系统工具→本地用户和组→用户→中间空白区域右键→新用户; 2、输入自设的用户名和密码,如图勾选→创建; 3、右键需要共享的文件见→安全→编辑; 4、点击添加; 5、…

WIN10取消密码和休眠密码

安装Win10系统之后,发现每次开机都会出现登录密码?有些用户觉得很麻烦,所以想要取消Win10开机密码。那么,该如何操作呢? 按下winx组合键,启动快捷菜单 在弹出菜单选择运行,如下图所示 在运行框…

计算机共享网络的账号密码怎么设置密码,怎样才能给win10共享设置密码的操作方法...

怎样才能给win10共享设置密码呢?一些善于使用win10共享设置的小伙伴们,一定会为了隐私而设置win10的共享设置密码,为了可以完美的设置共享密码,小伙伴们找了好多方法,都没有解决,针对这一问题,小…

win10系统mysql重新配置密码

前言 最近捣鼓自己的破烂笔记本,想着写点玩具项目,想着:写项目不能没有mysql吧,点击mysqlbench开始上号。这个时候发现坏了,登录不上,想着估计mysql没装好呗,于是重装了mysql和mysqlbench&…

win10重置网络命令_Win10怎么重置网络 Win10重置网络命令使用方法

有时候Windows系统出问题的时候,会导致网络异常,无法正常上网,甚至是重新连接网络,依然会出现无法连接的现象。下面就来为大家分享2种重置网络的方法,有需要了解的小伙伴,快来涨知识吧 方法一:使…