gl_FragCoord 的含义

2023-05-16

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

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

原文地址:OpenGL 投影矩阵

眼坐标空间到规范化设备坐标系空间

透视除法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 不会存在未定义输出的情况(因为不是用户定义的值就是系统给定的默认值)。

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

正交投影矩阵公式

透视投影矩阵公式

答案: 判断 projectionMatrix[3][2] 是否不等于 零。

最后给两个函数,在基于延迟着色的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; 
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

gl_FragCoord 的含义 的相关文章

随机推荐

  • STC12C5A60S2_LCD1602驱动

    文章目录 LCD1602 HLCD1602 cmain c LCD1602 H 代码如下 xff1a span class token macro property span class token directive hash span
  • 猿创征文|机器学习实战(8)——随机森林

    目录 1 随机森林 2 极端随机树 3 特征重要性 4 提升法 4 1 AdaBoost 4 2 梯度提升 机器学习实战 xff08 7 xff09 中我们已经提到 xff0c 随机森林是决策树的集成 xff0c 通常用bagging方法训
  • 总结2014——迷茫以及迷茫过后的坚持

    首先 xff0c 借用一句话和大家共勉 xff1a 少一些功利主义的追求 xff0c 多一些不为什么的坚持 xff01 xff01 不知不觉15年也快过了1个月了 xff0c 还是想着要为14年做一下总结 xff1a 记录一下自己的历程 今
  • 汇编总结:lea指令

    ea指令变种 按大小分类 leaw 2个字节 leal 4个字节 leaq 8个字节 lea的用法 leaq a b c d rax 首先lea指令是mov指令的变种 xff0c 据说 xff0c lea指令是x86体系结构中 xff0c
  • CMake语法—选项(option)

    CMake语法 选项 xff08 option xff09 1 选项 1 1 定义 1 2 说明 variable 选项名help text 描述 解释 备注value 选项初始化值 xff08 除ON而外全为OFF xff09 2 应用注
  • C++工程:总结 CMake 添加第三方库依赖方式git submodule、 find_library、FetchContent、CPM等

    CMake 已经成为了C 43 43 工程管理的主流方式 xff0c 功能非常强大 xff0c 现在大多数的 C 43 43 库都已经支持CMake xff0c 下面以 jsoncpp 为例 xff0c 介绍几种引入第三方库的方式 1 代码
  • 医学图像——DCMTK、VTK、ITK、RTK、SimpleITK

    1 引言 https github com SINTEFMedtek ITK VTK xff0c 相关童鞋应该很熟悉的 xff0c 而CTK是一个较新的界面库 xff0c 主要用于方便前面两个 TK的界面设计 xff0c 当然也可以作为通用
  • C++中的volatile

    volatile的本意是 易变的 volatile关键字是一种类型修饰符 xff0c 用它声明的类型变量表示可以被某些编译器未知的因素更改 xff0c 比如操作系统 硬件或者其它线程等 遇到这个关键字声明的变量 xff0c 编译器对访问该变
  • 3DTiles】关于GeometricError几何度量误差

    在 3DTiles 的官方文档中详细介绍了关于几何度量误差 Geometric Error 的一些理念和内涵 xff0c 概括来说可以翻译为如下定义 xff1a 几何度量误差 xff0c Geometric Error xff0c 简称 G
  • glPixelStorei 详解 包括像素传输

    3 glPixelStore 像glPixelStorei GL PACK ALIGNMENT 1 这样的调用 xff0c 通常会用于像素传输 PACK UNPACK 的场合 尤其是导入纹理 glTexImage2D 的时候 xff1a C
  • ESLint 简介

    ESLint简介 ESLint是一个用来识别 ECMAScript 并且按照规则给出报告的代码检测工具 xff0c 使用它可以避免低级错误和统一代码的风格 如果每次在代码提交之前都进行一次eslint代码检查 xff0c 就不会因为某个字段
  • IOS VasSonic 粗略见解

    因为项目需求需要在本地缓存html页面 xff0c 优化用户体验 了解到VasSonic 百度了下源码解析但是没有发现IOS的所以只有自己慢慢摸索了 一 类的简单关系 1 SonicEngine 引擎类 代理为 UIWebViewContr
  • axios的详细讲解

    一 axios的特性 axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端 xff0c 简单的理解就是ajax的封装 特性 xff1a 从浏览器中创建 XMLHttpRequests从 node js 创建
  • 无人机飞控算法-姿态估计-欧拉角-旋转矩阵-四元数

    无人机飞控算法 姿态估计 此系列记录了我理解的卡尔曼滤波从0到1的过程 xff0c 从姿态估计到位置估计 xff0c 我们从核心点一个个出发 xff0c 并结合实际模块的应用来一一揭开卡尔曼滤波的神秘面纱 提示 xff1a 在系列文章中 x
  • BMP格式详解

    介绍 数字图像在外存储器设备中的存储形式是图像文件 xff0c 图像必须按照某个已知的 公认的数据存储顺序和结构进行存储 xff0c 才能使不同的程序对图像文件顺利进行打开或存盘操作 xff0c 实现数据共享 图像数据在文件中的存储顺序和结
  • WinHex使用方法详解

    WinHex是由X Ways软件技术公司 xff08 官方网站http www x ways net xff09 开发的一款专业的磁盘编辑工具 xff0c 该工具文如其名 xff0c 是在Windows下运行的十六进制 xff08 hex
  • three.js流动线

    效果 xff1a 先看最基本的 function initThree el options options 61 options const t 61 this appInstance 61 this const width 61 el o
  • OpenGL之FBO(Frame Buffer Object)和多次离屏渲染

    第一次听到离屏渲染的时候觉得很高级 xff0c 遥不可及 xff0c 直到后来做高斯模糊的时候 xff0c 需要通过两次处理来节省性能 xff0c 一直玩一次渲染处理的我这时候才认识FBO xff0c 继而明白了离屏渲染 xff0c 今天抽
  • Android驱动(一)硬件访问服务学习之(四)Android应用程序APP编写

    硬件平台 xff1a tiny4412系统 xff1a Android 5 0 2编译器 xff1a arm linux gcc 4 5 1 xff08 一 xff09 Android通过JNI访问硬件 http blog csdn net
  • gl_FragCoord 的含义

    gl FragCoord 表示当前片元着色器处理的候选片元窗口相对坐标信息 xff0c 是一个 vec4 类型的变量 x y z 1 w xff0c 其中 x y 是当前片元的窗口坐标 xff0c OpenGL 默认以窗口左下角为原点 xf