光线行进曲面在GLSL中的实现
Implementation of raymarching surfaces in GLSL
我已经阅读了很多关于GLSL着色器中光线行进的文章(比如这篇文章:http://www.iquilezles.org/www/articles/rmshadows/rmshadows.htm)它提出了一些我想问的问题。
在我的应用程序中,我正在用几个网格渲染一个场景,我想尝试阴影。虽然我似乎有点理解raymarching如何工作的概念,但我不太明白如何在GLSL中正确实现这一点。我知道如何计算光线和平面的交点,但如何通过GLSL着色器处理?
根据这里的线索:(https://gamedev.stackexchange.com/questions/67719/how-do-raymarch-shaders-work)它提到你正在测量光线的起点和"表面"之间的距离。他所指的表面是网格吗?为了计算光线相交测试,我是否需要将组成网格的平面/点阵列发送到着色器?我需要使用深度缓冲区来确定曲面的距离吗?
这取决于着色器的作用与渲染引擎的作用。在像shadertoy这样的纯演示着色器中(请参见其阴影示例),整个场景都在着色器中编码,因此拍摄二次光线或更多光线(除了perfs)没有问题。
如果场景不是由着色器管理的,则需要引擎进行一些协作。至少,第一次生成阴影贴图(存在许多不同的算法)。请注意,使用SVO表示,场景首先被转换为稀疏体素,然后可以由着色器进行二次光线的行进。甚至可以用于主光线,但您可以在此处使用常规Z缓冲区,并对所有类型的次光线使用体素圆锥体跟踪(例如)(请参见此处的*使用体素锥体跟踪的交互式间接照明*:http://gigavoxels.imag.fr/publications.html(好吧,在您的简单应用程序中,您可能会发现它有些过头了)。有关软阴影和景深,请参阅开创性论文GigaVoxels:Ray Guided Streaming For Efficient and Detailed Voxel Rendering。请注意,该树甚至可能是三角形的规则BSP,而不是体素的八叉树。但随后你失去了SVO的许多优势(性能,为柔和的阴影增加)。
iq/RGBA(Inigo Quilezles)解释的光线行进方式是符号距离函数("SDF"s)的光线行进。这是一种描述场景的完全数学方法。
我们只渲染一个屏幕四边形,要显示的整个世界由片段着色器代码组成,这些代码要么操纵空间,要么计算到某个数学定义实体的符号距离,甚至组合不同对象的距离。
例如:
float fTorus(vec3 p, float smallRadius, float largeRadius)
{
return length(vec2(length(p.xz) - largeRadius, p.y)) - smallRadius;
}
vec2 pR( inout vec2 p, in float radians )
{
p = cos( radians ) * p + sin( radians ) * vec2( p.y, -p.x ) );
return p;
}
vec2 world( in vec3 p )
{
pR( p.xz, radians( -45 ) ); // manipulate Space - rotate around Y
p -= vec3( 0.0, 0.0, 10.0 ); // manipulate Space - move (after rot)
return vec2( fTorus( p ), float( 1 ) );
// finally return distance to torus in x and the material number in y
}
这个世界代码描述了在世界中的一个位置上的环面,该环面是由给定的旋转和平移产生的;p〃;在";世界;作用注意,我们反向修改空间,就像在相机空间中一样,所以要移动到空间中的一个点,我们必须从p中减去它的矢量。
无论如何,这就是iq提出的纯分析方法中几何的来源。也许可以进一步阅读:http://mercury.sexy/hg_sdf/
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 如何在编译器C++不智能的情况下实现 GLSL vec* 构造语法?
- 如何实现纹理采样功能,例如GLSL中的纹理
- GLSL截断符号距离表示(TSDF)实现
- 光线行进曲面在GLSL中的实现