[OpenGL] 使用计算着色器进行预烘焙

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

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);

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值