Ent*_*lpi 2 opengl compute-shader
获得统一的"均匀球体球体[10]"的位置(通过glGetUniformLocation(程序,名称)).返回-1,即使程序中有其他制服(frustum_planes)有效.
frustum_planes和球体制服也在相同的地方使用,这使得奇怪的是两者中只有一个存在.
什么想法可能会出错?
着色器
#version 460 core
// Required by compute shaders apparently
// Process one object per shader invocation (optimisation?)
layout (local_size_x = 1) in;
struct Sphere {
vec3 center;
float radius;
};
uniform Sphere spheres[10];
// Plane defined as: Ax + By + Cz = D
uniform vec4 frustum_planes[6];
uint test(Sphere obj, vec4 plane) {
const float distance = plane.x * obj.center.x + plane.y * obj.center.y + plane.z * obj.center.z + plane.w;
if (distance < -obj.radius) {
return 0; // Negative halfspace
}
return 1; // Positive halfspace or on the plane
}
/// Same as the OpenGL provided struct: DrawElementsIndirectCommand
struct DrawCommand {
uint count; // Num elements (vertices)
uint instanceCount; // Number of instances to draw (a.k.a primcount)
uint firstIndex; // Specifies a byte offset (cast to a pointer type) into the buffer bound to GL_ELEMENT_ARRAY_BUFFER to start reading indices from.
uint baseVertex; // Specifies a constant that should be added to each element of indices? when chosing elements from the enabled vertex arrays.
uint baseInstance; // Specifies the base instance for use in fetching instanced vertex attributes.
// 20 bytes
uint padding0;
uint padding1;
uint padding2;
// 32 bytes (multiple of 16)
};
// One draw command per object
// Command buffer backed by Shader Storage Object Buffer (SSBO)
layout(std140, binding = 0) writeonly buffer DrawCommandsBlock {
DrawCommand draw_commands[];
};
void main() {
const uint idx = gl_GlobalInvocationID.x;
uint inside = 0;
for (int i = 0; i < 6; i++) {
inside += test(spheres[idx], frustum_planes[i]) << i;
}
const uint INSIDE_ALL_PLANES = 63; // = 0b111111;
const bool visible = inside == INSIDE_ALL_PLANES;
draw_commands[idx].count = 25350; // sphere.indices.size();
draw_commands[idx].instanceCount = visible ? 1 : 0; // This is the trick right here
draw_commands[idx].baseInstance = 0;
draw_commands[idx].baseVertex = 0;
draw_commands[idx].padding0 = 0; // Avoid optimisation
draw_commands[idx].padding1 = 0;
draw_commands[idx].padding2 = 0;
}
Run Code Online (Sandbox Code Playgroud)
正在进行glGetUniformLocation调用
glGetUniformLocation(gl_state.cull_shader.gl_program, "spheres[0].center");
Run Code Online (Sandbox Code Playgroud)
main.cpp中
glUseProgram(gl_state.cull_shader.gl_program);
if (glGetUniformLocation(gl_state.cull_shader.gl_program, "frustum_planes") == -1) {
std::cerr << "Work!" << std::endl;
}
if (glGetUniformLocation(gl_state.cull_shader.gl_program, "spheres") == -1) {
std::cerr << "Does not work?!" << std::endl;
}
glUniform4fv(glGetUniformLocation(gl_state.cull_shader.gl_program, "spheres"), NUM_OBJECTS, &bounding_volumes[0].pos.x);
glUniform4fv(glGetUniformLocation(gl_state.cull_shader.gl_program, "frustum_planes"), 6, glm::value_ptr(frustum[0]));
glDispatchCompute(NUM_OBJECTS, 1, 1);
glMemoryBarrier(GL_COMMAND_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT); // Buffer objects affected by this bit are derived from the GL_DRAW_INDIRECT_BUFFER binding.
Run Code Online (Sandbox Code Playgroud)
无法查询非基本类型或基本类型数组的制服位置.在OpenGL的维基状态:
内省API通常会使GLSL中的单个"变量"定义看起来好像是多个变量.这适用于非基本类型的变量或基本类型的数组(请注意,在GLSL中,"基本类型"包括向量和矩阵类型).
...
相反,作为基本类型的结构的每个子元素都是可见的.
这意味着,您无法查询spheres(或spheres[0]).您需要做的是分别查询每个结构的每个成员.为了获得第一个Sphere中心的位置,您必须查询spheres[0].center.
请注意,查询frustum_planes按预期工作,因为它是一个vec4数组(这是一个基本类型).
| 归档时间: |
|
| 查看次数: |
122 次 |
| 最近记录: |