From 579c7d086f016af2a5440bd3ffa9e163a00980b7 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Mon, 13 Apr 2020 16:26:40 +0200 Subject: [PATCH] Calculate matrices from node-hierarchy and pass via push constant --- data/shaders/mesh/mesh.frag | 2 +- data/shaders/mesh/mesh.frag.spv | Bin 2008 -> 2024 bytes data/shaders/mesh/mesh.vert | 23 +++++++++++------------ data/shaders/mesh/mesh.vert.spv | Bin 2748 -> 3212 bytes examples/mesh/mesh.cpp | 24 +++++++++++++++++++----- 5 files changed, 31 insertions(+), 18 deletions(-) diff --git a/data/shaders/mesh/mesh.frag b/data/shaders/mesh/mesh.frag index 17d4a95b..fb415cef 100644 --- a/data/shaders/mesh/mesh.frag +++ b/data/shaders/mesh/mesh.frag @@ -18,7 +18,7 @@ void main() vec3 L = normalize(inLightVec); vec3 V = normalize(inViewVec); vec3 R = reflect(-L, N); - vec3 diffuse = max(dot(N, L), 0.0) * inColor; + vec3 diffuse = max(dot(N, L), 0.15) * inColor; vec3 specular = pow(max(dot(R, V), 0.0), 16.0) * vec3(0.75); outFragColor = vec4(diffuse * color.rgb + specular, 1.0); } \ No newline at end of file diff --git a/data/shaders/mesh/mesh.frag.spv b/data/shaders/mesh/mesh.frag.spv index 3c870fe52862fce99f79607ec09940cf8e376fee..5cd562653a43a2f4e3575be29980fd2deef432dd 100644 GIT binary patch delta 484 zcmXw#KS~2p5XNVAqfs!VvCve4ji7~92*hj>-KdFwqLqawu=E70h1dyVWo{920I%T% z1g~Hr`1_vkz2yfp-^|W@?|nAEn~gl%uA8~7@J(MEw_eWg>h9&+y+3=o`0*RBX78KD zuGMVW%nm>&)2#nz2^8MU@8Sw>s~9r_j@`Bzr; zNE~*c3o^3C2$|}GYAsNoOuaBj1`a_c)Kf676SW>IR3E`UD3_sQScNGMqWa0dR)qp_ zSR{u}alt9EhNv+O9TRKOW9*p_t55nhnoOU8be*J~6HC)&l6DcawuNW8!lPVXf(GaZ QHEe)xr)N~{mk}NK11u^e#sB~S delta 442 zcmXw!y-q?w5QS&%RnbI3V_~dJY)G`QFor~diz|pfpccl$C$RJh(1OsJ5TC>l--So; z6)X&VXSutZlbJblcFxXkZCMk@pNw;8Yqmjb zs<8J?s@t(H+DCME$O|AYVV`#w)H%S&&dNH>e)2^&I)`#lk1ewk;x9h+KveIa5e={e1cf3s diff --git a/data/shaders/mesh/mesh.vert b/data/shaders/mesh/mesh.vert index 22b6aeb9..2760684e 100644 --- a/data/shaders/mesh/mesh.vert +++ b/data/shaders/mesh/mesh.vert @@ -5,12 +5,16 @@ layout (location = 1) in vec3 inNormal; layout (location = 2) in vec2 inUV; layout (location = 3) in vec3 inColor; -layout (set = 0, binding = 0) uniform UBO +layout (set = 0, binding = 0) uniform UBOScene { mat4 projection; - mat4 model; + mat4 view; vec4 lightPos; -} ubo; +} uboScene; + +layout(push_constant) uniform PushConsts { + mat4 model; +} primitive; layout (location = 0) out vec3 outNormal; layout (location = 1) out vec3 outColor; @@ -18,21 +22,16 @@ layout (location = 2) out vec2 outUV; layout (location = 3) out vec3 outViewVec; layout (location = 4) out vec3 outLightVec; -out gl_PerVertex -{ - vec4 gl_Position; -}; - void main() { outNormal = inNormal; outColor = inColor; outUV = inUV; - gl_Position = ubo.projection * ubo.model * vec4(inPos.xyz, 1.0); + gl_Position = uboScene.projection * uboScene.view * primitive.model * vec4(inPos.xyz, 1.0); - vec4 pos = ubo.model * vec4(inPos, 1.0); - outNormal = mat3(ubo.model) * inNormal; - vec3 lPos = mat3(ubo.model) * ubo.lightPos.xyz; + vec4 pos = uboScene.view * vec4(inPos, 1.0); + outNormal = mat3(uboScene.view) * inNormal; + vec3 lPos = mat3(uboScene.view) * uboScene.lightPos.xyz; outLightVec = lPos - pos.xyz; outViewVec = -pos.xyz; } \ No newline at end of file diff --git a/data/shaders/mesh/mesh.vert.spv b/data/shaders/mesh/mesh.vert.spv index 2d0a79fc927d5ef5a3553d76fa5e729080693ada..cf6fc4ac34758c1159e7f64a2d1acf8dcb20d627 100644 GIT binary patch literal 3212 zcmZ9NYjYG;5Qc}`08tc?i;8ix@s37RKoo&M(2W{NAZEP_*<{=dZe~-v8?^i)RsI6~ zN&YIoQ04Q?Ovf=N)tr9c)3?)ob{HR_kSCC%$kWI($Qk4vq=R&kasI~G|0d8R5$Z7} zVT{w?9o^~=w%2>;a>mW_J*wc$gWW>E*B_w5O%!>vyrjg|fX!OFI=7xIFCg|)$#dXt z@9s)EXs3fw`YRB&`{_ne3NcGtYk82Rzj$ul4R&kj zW!FLu^}7s=_YUB-0?BLYpe6KA|jHlfqOoQDuiD=&tux88ce;hx& zo<=?EV=*u%J}Bi?jd454R$&2-egx?foDoso;`}l614x{U zV~%0(o6%nExo<`v^Em_aS&R9Ov1==@z1TMu`HrLO8|Px*Sj0PtZanXQf`3o3HxSp^ z3ZF*T{tWn8cJ1Y+(R@!4!!yOYo@ciP&#g=BH$%=mFR(Wd7*xY{q#8<%Xk0ZXzt9aW3ah&TR%-`EMn_vM-I zP<)-tv+OS+O~g5CZ!cd)( zm5;l;i|!n66UP~zN90_=T|k#}*1=t@IQzUp$DGUii2mAp?tA!?xSm}?%&(0#`#wHI z{7qQ1{Ss>zy|{wDzZX~G8!dBwHgX9-Rp zMq8Z584_WOJTr%$~P--6{8SNKF9zJs$CV{7ZZ{Pz5acrU+6 z_QrYMMdafS_bN`_6|tjt>u|=uhuFJ2>~hiT4RpDPzlrWUi})$JoZ^c3e^j&i3C+v$MoZ^ajzgOSD`*7MAtIIBagw-YFU!ZBqM*si- literal 2748 zcmZXU*KQP142Fj!8+z}3L+B;+-a<`)KtjpVOMn#&+U%fZ5!`{q6Tlj`AI4n zA z#2n$n<4l(1ToGrD)i|+n!)V0G{fjGddA5FEQR|7`TfhC@f+~Rr3YcTxtoKvg_x*}} zui~dAwm-|crDqLrhFE(QRzGVUU5&rBiQTV*=ajbm=@L7m*q?_TcXD5BZ{@<@ndu+< z&dhz!vwxmvEuOcORbP4i#m+R&TaImP?2Dao8&Y{QI%2H|}&0+u4Y%@ob6p(SM}G`owv6u%n*4rER?DJ8$2R@qv9q;$ysSc4F^9Z{y=EcB67iaC@-jW>vVo zC1<}TxVin^hZ?WH`_A<{dEFaAJzpPdcFqS-->3KT-eUdYPKU8)-suROeAIswyITJ- zu$&V0AIFxf)_N}8&T2Euoto00>ymi=vbEup$&P(*Y zoJZwV#Tuchild tree), no animations, no skins, etc. + * This means no complex materials, no animations, no skins, etc. * For details on how glTF 2.0 works, see the official spec at https://github.com/KhronosGroup/glTF/tree/master/specification/2.0 * * Other samples will load models using a dedicated model loader with more features (see base/VulkanglTFModel.hpp) @@ -203,7 +203,7 @@ public: node.matrix *= glm::mat4(q); } if (inputNode.scale.size() == 3) { - node.matrix = glm::scale(node.matrix, glm::vec3(glm::make_vec3(inputNode.translation.data()))); + node.matrix = glm::scale(node.matrix, glm::vec3(glm::make_vec3(inputNode.scale.data()))); } if (inputNode.matrix.size() == 16) { node.matrix = glm::make_mat4x4(inputNode.matrix.data()); @@ -261,8 +261,6 @@ public: vert.normal = glm::normalize(glm::vec3(normalsBuffer ? glm::make_vec3(&normalsBuffer[v * 3]) : glm::vec3(0.0f))); vert.uv = texCoordsBuffer ? glm::make_vec2(&texCoordsBuffer[v * 2]) : glm::vec3(0.0f); vert.color = glm::vec3(1.0f); - // Flip Y-Axis - vert.pos.y *= -1.0f; vertexBuffer.push_back(vert); } } @@ -329,10 +327,21 @@ public: void drawglTFNode(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout, VulkanglTFModel::Node node) { if (node.mesh.primitives.size() > 0) { + // Pass the node's matrix via push constanst + // Traverse the node hierarchy to the top-most parent to get the final matrix of the current node + glm::mat4 nodeMatrix = node.matrix; + VulkanglTFModel::Node* currentParent = node.parent; + while (currentParent) { + nodeMatrix = currentParent->matrix * nodeMatrix; + currentParent = currentParent->parent; + } + // Pass the final matrix to the vertex shader using push constants + vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &nodeMatrix); for (VulkanglTFModel::Primitive& primitive : node.mesh.primitives) { if (primitive.indexCount > 0) { // Get the texture index for this primitive VulkanglTFModel::Texture texture = textures[materials[primitive.materialIndex].baseColorTextureIndex]; + // Bind the descriptor for the current primitive's texture vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 1, 1, &images[texture.imageIndex].descriptorSet, 0, nullptr); vkCmdDrawIndexed(commandBuffer, primitive.indexCount, 1, primitive.firstIndex, 0, 0); } @@ -392,6 +401,7 @@ public: { title = "glTF model rendering"; camera.type = Camera::CameraType::lookat; + camera.flipY = true; camera.movementSpeed = 2.5f; camera.rotationSpeed = 0.5f; camera.setPosition(glm::vec3(0.1f, 1.1f, -20.0f)); @@ -507,7 +517,6 @@ public: } } else { - // TODO: throw std::cerr << "Could not load gltf file: " << error << std::endl; return; } @@ -616,6 +625,11 @@ public: // Pipeline layout using both descriptor sets (set 0 = matrices, set 1 = material) std::array setLayouts = { descriptorSetLayouts.matrices, descriptorSetLayouts.textures }; VkPipelineLayoutCreateInfo pipelineLayoutCI= vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), static_cast(setLayouts.size())); + // We will use push constants to push the local matrices of a primitive to the vertex shader + VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, sizeof(glm::mat4), 0); + // Push constant ranges are part of the pipeline layout + pipelineLayoutCI.pushConstantRangeCount = 1; + pipelineLayoutCI.pPushConstantRanges = &pushConstantRange; VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayout)); // Descriptor set for scene matrices