Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将浮点数组作为3D纹理传递给GLSL片段着色器_C++_Opengl - Fatal编程技术网

C++ 将浮点数组作为3D纹理传递给GLSL片段着色器

C++ 将浮点数组作为3D纹理传递给GLSL片段着色器,c++,opengl,C++,Opengl,我正在尝试实现基于光线投射的体渲染,因此需要将浮点数组作为纹理(Sampler3D)传递给片段着色器。 我有一个包含所有体素的体积数据结构。每个体素包含一个密度值。因此,为了进行处理,我将这些值存储到一个浮点数组中 //initialize glew, initialize glfw, create window, etc. float* density; density = new float[volume->size()]; for (int i = 0; i < volum

我正在尝试实现基于光线投射的体渲染,因此需要将浮点数组作为纹理(Sampler3D)传递给片段着色器。 我有一个包含所有体素的体积数据结构。每个体素包含一个密度值。因此,为了进行处理,我将这些值存储到一个浮点数组中

//initialize glew, initialize glfw, create window, etc.

float* density;
density = new float[volume->size()];

for (int i = 0; i < volume->size(); i++){
    density[i] = volume->voxel(i).getValue();
}
在我的渲染循环中,我尝试将纹理加载到均匀采样3D

glClearColor(0.4f, 0.2f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glActiveTexture(GL_TEXTURE0);
GLint gSampler = glGetUniformLocation(shader->shaderProgram, "volume");
glUniform1i(gSampler, 0);

cube->draw();
因此,基本思想是在顶点着色器中计算光线投射的当前位置和方向

in vec3 position;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

uniform vec4 cameraPos;

out vec3 pos;
out vec3 dir;

void main(){
gl_Position = projection * view * model * vec4(position, 1.0);
pos = position;
dir = pos - (inverse(model) * cameraPos).xyz;
}
到目前为止,这似乎效果不错。片段着色器如下所示。我沿着光线采集了一些样本,其中密度值最大的样本将作为红色、绿色和蓝色的颜色

#version 330 core

in vec3 pos;
in vec3 dir;

uniform sampler3D volume;

out vec4 color;

const float stepSize = 0.008;
const float iterations = 1000;

void main(){

vec3 rayDir = normalize(dir);
vec3 rayPos = pos;

float src;
float dst = 0;
float density = 0;

for(int i = 0; i < iterations; i++){

src = texture(volume, rayPos).r;
if(src > density){
    density = src;
}

rayPos += rayDir * stepSize;

//check whether rays are within bounds. if not -> break.

    }
color = vec4(density, density, density, 1.0f);
}
但是src在每个像素的每次迭代中似乎都是0。这让我得出结论,采样器没有正确设置。在我把它传递给着色器之前,调试C++代码时我得到密度数组的正确值,所以我猜一定有一些OpenGL函数丢失了。提前谢谢

glTexImage3D(GL_TEXTURE_3D, 0, GL_LUMINANCE, volume->width(), volume->height(), volume->depth(), 0, GL_LUMINANCE, GL_FLOAT, density);
除非这个密度在[0,1]范围内,否则这几乎肯定不是你想要的

glu LUMINANCE
,当用作
glTexImage3D
的第三个参数时,意味着OpenGL纹理数据中的每个像素都将包含一个值。因此,如果你想要一个浮点值,你就有点运气不好了

正确的方法是明确声明数据的类型和像素大小。早在3.1中,亮度就从核心OpenGL配置文件中删除了,因此今天的方法是使用
GL_R32F
作为内部格式。这声明每个像素包含一个值,该值是32位浮点值

如果您确实需要在RGB通道中广播该值,您可以使用来完成该操作。您可以设置旋转遮罩,将红色分量广播到您喜欢的任何其他通道

glActiveTexture(GL_TEXTURE0);
GLint gSampler = glGetUniformLocation(shader->shaderProgram, "volume");
glUniform1i(gSampler, 0);

我听说绑定纹理也是一个好主意。你知道,如果你真的想阅读它;)

谢谢你的快速回复。密度已在[0,1]上标准化。好的,正常的整数值当然不起作用。不绑定纹理。。。愚蠢的我。。。好的,非常感谢!我会尽力让它工作的
glTexImage3D(GL_TEXTURE_3D, 0, GL_LUMINANCE, volume->width(), volume->height(), volume->depth(), 0, GL_LUMINANCE, GL_FLOAT, density);
glActiveTexture(GL_TEXTURE0);
GLint gSampler = glGetUniformLocation(shader->shaderProgram, "volume");
glUniform1i(gSampler, 0);