Hi! I’m trying to draw to the 6 faces of a cubemap, and I’ve a per pixel linked list per face.
Everything works well with opengl and the geometry shaders. But in vulkan, in the second pass, the headptr of my 3D image are always -1 and the gl_ViewIndex is also always 0.
const std::string fragmentShader2 =
R"(
#version 460
#define MAX_FRAGMENTS 20
#extension GL_EXT_debug_printf : enable
#extension GL_EXT_multiview : enable
struct NodeType {
vec4 color;
float depth;
uint next;
};
layout(set = 0, binding = 0) buffer CounterSSBO {
uint count[6];
uint maxNodes;
};
layout(set = 0, binding = 1, r32ui) uniform uimage3D headPointers;
layout(set = 0, binding = 2) buffer linkedLists {
NodeType nodes[];
};
layout (location = 0) out vec4 fcolor;
layout (location = 0) in vec4 frontColor;
layout (location = 1) in vec2 fTexCoords;
layout (location = 2) in flat uint layer;
layout (location = 3) in vec3 normal;
void main() {
NodeType frags[MAX_FRAGMENTS];
int count = 0;
uint n = imageLoad(headPointers, ivec3(gl_FragCoord.xy, gl_ViewIndex)).r;
debugPrintfEXT("layer : %i, nodeIdx : %i\n", gl_ViewIndex, n);
while( n != 0xffffffffu && count < MAX_FRAGMENTS) {
frags[count] = nodes[n+maxNodes*gl_ViewIndex];
n = frags[count].next+maxNodes*gl_ViewIndex;
count++;
}
//Insertion sort.
for (int i = 0; i < count - 1; i++) {
for (int j = i + 1; j > 0; j--) {
if (frags[j - 1].depth > frags[j].depth) {
NodeType tmp = frags[j - 1];
frags[j - 1] = frags[j];
frags[j] = tmp;
}
}
}
vec4 color = vec4(0, 0, 0, 0);
for( int i = 0; i < count; i++)
{
color.rgb = frags[i].color.rgb * frags[i].color.a + color.rgb * (1 - frags[i].color.a);
color.a = frags[i].color.a + color.a * (1 - frags[i].color.a);
}
fcolor = color;
})";
I’ll not set the whole code here because he’s to big but you can find it here :
I draw my second pass here :
math::Matrix4f projMatrices[6];
math::Matrix4f viewMatrices[6];
math::Matrix4f sbProjMatrices[6];
math::Matrix4f sbViewMatrices[6];
environmentMap.setView(reflectView);
for (unsigned int m = 0; m < 6; m++) {
math::Vec3f target = reflectView.getPosition() + dirs[m];
reflectView.lookAt(target.x, target.y, target.z, ups[m]);
projMatrix = reflectView.getProjMatrix().getMatrix()/*.transpose()*/;
viewMatrix = reflectView.getViewMatrix().getMatrix()/*.transpose()*/;
projMatrices[m] = projMatrix;
viewMatrices[m] = viewMatrix;
float zNear = reflectView.getViewport().getPosition().z;
if (!reflectView.isOrtho())
reflectView.setPerspective(80, view.getViewport().getSize().x / view.getViewport().getSize().y, 0.1f, view.getViewport().getSize().z);
viewMatrix = reflectView.getViewMatrix().getMatrix()/*.transpose()*/;
projMatrix = reflectView.getProjMatrix().getMatrix()/*.transpose()*/;
math::Matrix4f sbViewMatrix = math::Matrix4f(math::Matrix3f(viewMatrix));
sbViewMatrices[m] = sbViewMatrix;
sbProjMatrices[m] = projMatrix;
if (!reflectView.isOrtho())
reflectView.setPerspective(80, view.getViewport().getSize().x / view.getViewport().getSize().y, zNear, view.getViewport().getSize().z);
}
environmentMap.clear(sf::Color::Transparent);
VkClearColorValue clearColor;
clearColor.uint32[0] = 0xffffffff;
std::vector<VkCommandBuffer> commandBuffers = environmentMap.getCommandBuffers();
for (unsigned int i = 0; i < commandBuffers.size(); i++) {
VkImageSubresourceRange subresRange = {};
subresRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subresRange.levelCount = 1;
subresRange.layerCount = 1;
vkCmdClearColorImage(commandBuffers[i], headPtrTextureImage, VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresRange);
for (unsigned int j = 0; j < 6; j++) {
vkCmdFillBuffer(commandBuffers[i], counterShaderStorageBuffers[i], j*sizeof(uint32_t), sizeof(uint32_t), 0);
}
}
environmentMap.display();
/*vb.clear();
//vb.name = "SKYBOXVB";
for (unsigned int i = 0; i < m_skyboxInstance.size(); i++) {
if (m_skyboxInstance[i].getAllVertices().getVertexCount() > 0) {
vb.setPrimitiveType(m_skyboxInstance[i].getAllVertices().getPrimitiveType());
for (unsigned int j = 0; j < m_skyboxInstance[i].getAllVertices().getVertexCount(); j++) {
//std::cout<<"append"<<std::endl;
vb.append(m_skyboxInstance[i].getAllVertices()[j]);
}
}
}
currentStates.blendMode = sf::BlendAlpha;
currentStates.shader = &skyboxShader;
currentStates.texture = (skybox == nullptr ) ? nullptr : &static_cast<g3d::Skybox*>(skybox)->getTexture();
vb.update();
environmentMap.drawVertexBuffer(vb, currentStates);*/
UniformBufferObject ubo;
for (unsigned int f = 0; f < 6; f++) {
ubo.projMatrix[f] = projMatrices[f];
ubo.viewMatrix[f] = viewMatrices[f];
}
updateUniformBuffer(environmentMap.getCurrentFrame(), ubo);
drawEnvReflInst();
vb.clear();
vb.setPrimitiveType(sf::Triangles);
Vertex v1 (sf::Vector3f(0, 0, quad.getSize().z));
Vertex v2 (sf::Vector3f(quad.getSize().x,0, quad.getSize().z));
Vertex v3 (sf::Vector3f(quad.getSize().x, quad.getSize().y, quad.getSize().z));
Vertex v4 (sf::Vector3f(0, quad.getSize().y, quad.getSize().z));
vb.append(v1);
vb.append(v2);
vb.append(v3);
vb.append(v1);
vb.append(v3);
vb.append(v4);
vb.update();
math::Matrix4f matrix = quad.getTransform().getMatrix()/*.transpose()*/;
linkedList2PC.worldMat = matrix;
currentStates.shader = &sLinkedList2;
currentStates.texture = nullptr;
createCommandBufferVertexBuffer(currentStates);
buildFrameBufferPC.cameraPos = math::Vec3f(view.getPosition().x, view.getPosition().y, view.getPosition().z);
drawReflInst(entity);
And here is the vertex shader of my second pass :
const std::string linkedListVertexShader2 = R"(#version 460
#extension GL_EXT_multiview : enable
#extension GL_EXT_debug_printf : enable
layout (location = 0) in vec3 position;
layout (location = 1) in vec4 color;
layout (location = 2) in vec2 texCoords;
layout (location = 3) in vec3 normals;
layout (push_constant)uniform PushConsts {
mat4 projectionMatrix;
mat4 viewMatrix;
mat4 worldMat;
} pushConsts;
layout (location = 0) out vec4 frontColor;
layout (location = 1) out vec2 fTexCoords;
layout (location = 2) out uint layer;
layout (location = 3) out vec3 normal;
void main () {
gl_Position = vec4(position, 1.f) * pushConsts.worldMat * pushConsts.viewMatrix * pushConsts.projectionMatrix;
gl_PointSize = 2.0f;
frontColor = color;
fTexCoords = texCoords;
normal = normals;
layer = gl_ViewIndex;
//debugPrintfEXT("view index : %i\n", gl_ViewIndex);
})";
It should draw the fullscreen quad 6 times in the fragment shader 2 but it draw it only once.
And my 3D image is wrong.
Thanks.