reference: https://www.khronos.org/opengl/wiki/Compute_Shader
一年前此时我做了一个体积云的效果,当时我留了一个坑——我的噪声是实时计算的,因此会带来一定卡顿;正确的做法应该是将噪声烘焙成一张3D纹理。今天趁着稍微有点时间,把这个坑填一填。
其实我很久之前也做过类似的烘焙的工作,比如在IBL效果中,需要烘焙一张环境贴图,但由于所需的结果正好是一张2D纹理,所以可以使用顶点+片元的传统方式通过写入纹理的方式实现,可以侥幸绕过计算着色器。但3D纹理就没有办法套用类似的方案了。
当然,这确实可以通过CPU来完成计算,但考虑到数据大量、离散的特点,使用GPU完成计算是非常合适的。实际上CUDA也提供了类似的功能,不过对于调用图形API的渲染项目而言,既然图形API本身已经整合了计算着色器这一解决方案,我们往往也就更倾向于用计算着色器来实现了。
基本概念
计算着色器不属于渲染管线的一部分,而是一个较为独立的过程。不同于顶点着色器对每顶点执行一次,片段着色器对光栅化的每片元执行一次,而计算着色器的空间是抽象的,它的执行次数由调用计算的函数定义。
整体而言,实现计算着色器大致需要以下几个过程:
1.分配纹理/缓冲区作为输入或输出
2.绑定当前着色器
3.绑定当前输入或输出的纹理/缓冲区
4.请求计算的渲染指令
5.并行运行多次计算着色器,并写入结果
……
输入/输出
最重要的是,计算着色器没有用户定义的输入,也没有输出(注:这里所谓的输入输出对应于glsl代码中in/out)。但是我们可以通过输入输出缓冲区/纹理数据进行读写。
以下为我归纳的几个常见的可用的例子,请注意不同情况下参数的细微差异:
(1) 用计算着色器绑定输出的2D纹理
● 生成2D纹理
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
● 绑定2D纹理(C++部分)
glBindImageTexture(0, texId, 0, GL_FALSE,
0, GL_WRITE_ONLY, GL_RGBA32F);

本文介绍如何使用计算着色器烘焙体积云的3D纹理,以提高实时渲染效率。通过详细步骤和代码示例,展示了创建、绑定和使用3D纹理的过程,以及如何在计算着色器中执行并行计算。
最低0.47元/天 解锁文章
450

被折叠的 条评论
为什么被折叠?



