timi-liuliang / echo

A New Cross-Platform 2D 3D Game Engine
MIT License
938 stars 107 forks source link

How to calculate gl_FragCoord #1214

Closed timi-liuliang closed 1 year ago

timi-liuliang commented 1 year ago

Make sure shadow depth color and depth have same value

timi-liuliang commented 1 year ago

https://registry.khronos.org/OpenGL-Refpages/gl4/html/gl_FragCoord.xhtml gl_FragCoord — contains the window-relative coordinates of the current fragment

https://zhuanlan.zhihu.com/p/102068376 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 );