为什么我们要在OpenGL管道的片段阶段使用眼空间坐标
why should we go in eye-space coordinates during fragment stage in the OpenGL pipeline?
我目前正在编写一个小型3D引擎,我想知道为什么我应该在片段着色器中使用眼空间坐标。要做到这一点,我必须把我的相机矩阵放在一个统一的,以转换光的位置在眼睛的坐标,和相机法线矩阵,把光的方向在眼睛的坐标。
为什么每个人都用这些坐标?
使用眼距有几个原因:
- 这是方便的。这是一个存在的定义良好的空间,并且无论如何都要在转换位置的过程中计算。
- 它具有与世界空间相同的规模,但不存在世界空间所存在的问题。眼空间总是(相对地)接近于零(因为眼在0处),所以对于具有显式变换矩阵的空间是合理的。尺度很重要,因为您可以提供在世界空间中计算的距离(如光衰减项)。距离不会随着眼距而改变。
- 你需要把它转换成一个线性空间。在一个非线性的空间,比如后投影空间中进行照明,尤其是有衰减的照明……棘手。所以你必须在某种线性空间中提供法线和位置,所以它也可能是眼空间。
- 它需要最少的转换。眼空间是投影变换之前的空间。如果你必须反向转换到线性空间(例如延迟渲染),眼空间是需要最少操作的。
你不需要向着色器提供相机矩阵并在那里进行光的位置和方向转换。实际上这样做效率很低,因为你对每个顶点都在对同样的数字做同样的操作。
只是转换光的位置和方向CPU侧,并提供容易转换的光参数到着色器。然而,在眼空间照明计算仍然更简洁,特别是如果涉及法线映射。但是无论如何,您必须将所有内容转换为眼空间,因为法线不会通过透视转换进行转换(尽管顶点位置可以直接转换为剪辑空间)。
相关文章:
- C++:对不存在的命名空间使用命名空间指令
- 通过继承类使用来自不同命名空间的运算符
- 使用命名空间时出现多个定义错误
- 当字段可以为null时,如何使用C++接口在Avro中写入数据
- 在命名空间中使用全局命名空间中的函数
- '使用命名空间{嵌套在另一个命名空间中的某个命名空间}"
- 如何使用 soong 命名空间来有条件地编译模块
- 使用 Clang++ 有没有办法将文件作为命名空间等包含?
- 为什么这两段使用 constexpr、__PRETTY_FUNCTION__ 和 char * 的代码有不同的结果?
- 在C 中读取文本文件时避免使用空间和行
- 使用空间indexex库将r*树的散装
- 使用空间indexex库选择r*树的参数
- 对C++中的字节字段使用char*或void*或其他什么
- 为什么这段使用 printf 和 cout 的代码没有预期的输出?
- 字段名称与使用未命名命名空间的字段类型相同
- 在C++构造函数中,我必须为实例字段分配空间吗
- C++14标准布局类型是否可以对字段使用“alignas”
- 请解释这段使用std::ignore的代码
- 如何为未在协议中赋值的可选字段分配空间
- 我想从这段代码中删除使用命名空间std,但我不确定什么都需要用std::作为前缀