渲染成 3D 纹理

Posted

技术标签:

【中文标题】渲染成 3D 纹理【英文标题】:Render into a 3D Texture 【发布时间】:2016-11-27 18:19:23 【问题描述】:

我想将一组点。但不知何故,我没有写在里面。使用 glGetTexImage() 每个条目我只能得到 0。我将 3D 纹理存储在帧缓冲区中,并且使用不同的渲染通道,我想从存储在帧缓冲区中的 3D 纹理中读出信息。

Initialization of the FrameBuffer.
glGenFramebuffers(1, &_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, _fbo);


glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_3D, texture);

glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, GRID_SIZE, GRID_SIZE, GRID_SIZE, 0, GL_RGBA, GL_FLOAT, NULL);

glFramebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, texture, 0, 0);

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) 
    std::cout << "FBO successfully loadet" << std::endl;
else
    std::cout << "FBO had en ERROR" << std::endl;

顶点着色器:

#version 330 core

layout (location = 0) in vec3 position;

void main()

    gl_PointSize = 1.0;

    gl_Position = vec4(position,1.0);


片段着色器:

#version 330 core

out vec4 fragColor;

void main()

    fragColor = vec4(1.0,1.0,1.0, 1.0);


在此之前,我尝试使用普通渲染通道并将这些点分别存储在 3D 纹理中。这似乎奏效了。但现在使用帧缓冲区它只写入 0。

【问题讨论】:

不清楚你想要达到什么目的。您只能渲染到 3d 纹理的一层,而不是整个纹理。 所以我必须分别为每一层渲染吗?这将是 256 次。以及如何渲染到某个图层? 你已经渲染到一个特定的层,即帽子glFrameBufferTexture3Dlayer参数。您也许可以从使用 layered 帧缓冲区中获得一些东西,但您将无法一次渲染到 256 层。 所以如果我选择第 10 层,例如使用 glFrameBufferTexture3D 然后渲染,我将只渲染 GRID_SIZE*GRID_SIZE 的 2D 纹理。如果选择第 11 层并再次渲染,我的帧缓冲区中有 2 层 2 2D 纹理,位于位置 10 和 11?如何读出缓冲区或纹理中写入的内容?我觉得我有问题 我的意思是我正在加载一个 3DTexture。这是如何运作的?如果我用 GL_TEXTURE_3D 迭代 256 次,他是每次加载 3D 纹理还是必须为每一层加载 GL_TEXTURE_2D? 【参考方案1】:

您可以使用计算着色器通过一次调用 glDispatchCompute 将所有点写入纹理 3D:

在 SSBO 或 texture1D 中写入要更新的点的 3D 坐标 绑定你的 SSBO/texture1D 和你的 texture3D 绑定您的计算着色器,应该如下所示:
#version 430
layout (binding=0, rgba16i) readonly uniform image1D points
layout (binding=1, rgba16f) writeonly uniform image3D tex3D

void main()

    ivec3 point_coords = imageLoad(points, gl_GlobalInvocationID.x).xyz;
    imageStore(tex3D, point_coords, vec4(1.0,1.0,1.0, 1.0));

调用 glDispatchCompute(pointCount, 0, 0); 调用 glMemoryBarrier() 并将参数位域设置为您打算对 texture3D 执行的任何操作(当不确定 GL_ALL_BARRIER_BITS 是否是开始的好方法时)

【讨论】:

以上是关于渲染成 3D 纹理的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Xcode 中渲染具有半透明纹理的 3D 模型?

Windows D3D渲染到纹理

LibGDX 3d 模型纹理未正确渲染

球体在使用纹理渲染时显示多边形

Unity3D纹理贴图 ( 纹理 Texture 简介 | 为 3D 模型设置纹理贴图 )

是否可以在opengl中使用深度缓冲区渲染3D纹理