GLSL Compute Shader生成Worley纹理出现块状损坏问题求助
GLSL Compute Shader实现Worley纹理出现块状损坏纹理
我在实现Worley纹理生成时遇到问题:HLSL版本的算法运行完全正常,但GLSL Compute Shader版本生成的纹理出现异常的块状损坏。
以下是相关代码:
GLSL Compute Shader代码
#version 450 core layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in; layout(rgba32f, binding = 0) uniform image3D imgOutput; uniform float resolution; uniform uint num_blocks_A; layout(std140, binding = 3) buffer points_A{ vec3 points[]; }points; const vec3 offset[] = { // center vec3(0,0,0), // front face vec3(-1, -1, 1), vec3(-1, 0, 1), vec3(-1, 1, 1), vec3(0, -1, 1), vec3(0, 0, 1), vec3(0, 1, 1), vec3(1, -1, 1), vec3(1, 0, 1), vec3(1, 1, 1), vec3(-1, -1, 0), vec3(-1, 0, 0), vec3(-1, 1, 0), vec3(0, -1, 0), vec3(0, 1, 0), vec3(1, -1, 0), vec3(1, 0, 0), vec3(1, 1, 0), vec3(-1, -1, -1), vec3(-1, 0, -1), vec3(-1, 1, -1), vec3(0, -1, -1), vec3(0, 0, -1), vec3(0, 1, -1), vec3(1, -1, -1), vec3(1, 0, -1), vec3(1, 1, -1) }; float max_component(vec3 vec) { return max(vec.x, max(vec.y, vec.z)); } float min_component(vec3 vec) { return min(vec.x, min(vec.y, vec.z)); } float Worley( uint num_blocks, vec3 pos) { vec3 block_pos = floor(pos * num_blocks); float min_distance_square = 1; for (int i = 0; i < 27; i++){ vec3 neighbor_block_pos = block_pos + offset[i]; if (min_component(neighbor_block_pos) == -1 || max_component(neighbor_block_pos) == num_blocks) { vec3 wrap_block_pos = mod(neighbor_block_pos + num_blocks, num_blocks); int wrap_block_id = int(wrap_block_pos.x + num_blocks * (wrap_block_pos.y + num_blocks * wrap_block_pos.z)); vec3 wrap_point = points.points[wrap_block_id]; for (int j = 0; j < 27; j++){ vec3 distance_vector = pos - (wrap_point + offset[j]); min_distance_square = min(min_distance_square, dot(distance_vector, distance_vector)); } } else { int neighbor_block_id = int(neighbor_block_pos.x + num_blocks * (neighbor_block_pos.y + num_blocks * neighbor_block_pos.z)); vec3 neighbor_block_point = points.points[neighbor_block_id]; vec3 distance_vector = pos - neighbor_block_point; min_distance_square = min(min_distance_square, dot(distance_vector, distance_vector)); } } return sqrt(min_distance_square); } void main() { vec4 value = vec4(1.0, 0.0, 0.0, 1.0); ivec3 texelCoord = ivec3(gl_GlobalInvocationID.xyz); float u = gl_GlobalInvocationID.x / resolution; float v = gl_GlobalInvocationID.y / resolution; float w = gl_GlobalInvocationID.z / resolution; vec3 pos = vec3(u,v,w); float min_distance_A = 1 - Worley(num_blocks_A, pos) * 4; float final_color = min_distance_A; value = vec4(vec3(min_distance_A), 1.0f); imageStore(imgOutput, texelCoord, value); }
C++/OpenGL相关代码
纹理生成方法
void GenWorleyCloudBaseTexture(int width, int height, int depth) { texture3D->SetDim(width, height, depth, GL_RGBA32F, GL_RGBA); unsigned int num_blocks_A = 8; auto points_A = GenWorleyPoints(num_blocks_A); std::unique_ptr<StorageBuffer> buffer = std::make_unique<StorageBuffer>(points_A.data(), sizeof(glm::vec3) * points_A.size(), 3); buffer->Bind(); compute_program->uniform("num_blocks_A", num_blocks_A); compute_program->uniform("resolution", (float) width); compute_program->Dispatch(texture3D.get(), width/8 , height/8, depth/8, GL_RGBA32F); }
Compute Shader类的Dispatch方法
void Dispatch(tex3D* t, int num_groups_x, int num_groups_y, int num_groups_z, GLuint internalFormat = GL_RGBA32F) { use(); glBindImageTexture(0, t->ogl_texture_3D, 0, GL_TRUE, 0, GL_WRITE_ONLY, internalFormat); glDispatchCompute((unsigned int)num_groups_x, (unsigned int)num_groups_y, (unsigned int)num_groups_z); glMemoryBarrier(GL_ALL_BARRIER_BITS); }
内容的提问来源于stack exchange,提问作者John1337
相关产品推荐
相关产品推荐

