Begin adding shadow mapping and a few vulkan fixes

This commit is contained in:
bailehuni 2024-03-23 21:16:30 +00:00
parent 8aa8085f69
commit f04c516d2b
12 changed files with 254 additions and 132 deletions

View File

@ -119,8 +119,8 @@ struct PipelineInfo {
std::string vert_shader_path;
std::string frag_shader_path;
VertexFormat vertex_format;
CullMode face_cull_mode;
bool alpha_blending;
bool backface_culling;
bool write_z;
bool line_primitives; // false for triangles, true for lines
std::vector<const DescriptorSetLayout*> descriptor_set_layouts;

View File

@ -85,8 +85,12 @@ class Renderer : private ApplicationComponent {
*/
// in vertex shader
UniformDescriptor<glm::mat4> global_uniform; // rarely updates; set 0
UniformDescriptor<glm::mat4> frame_uniform; // updates once per frame; set 1
struct GlobalUniformData {
glm::mat4 proj;
glm::mat4 lightSpaceMatrix;
};
UniformDescriptor<GlobalUniformData> global_uniform; // rarely updates; set 0 binding 0
UniformDescriptor<glm::mat4> frame_uniform; // updates once per frame; set 1 binding 0
// in fragment shader
const gfx::DescriptorSetLayout* material_set_layout; // set 2; set bound per material
@ -106,6 +110,9 @@ class Renderer : private ApplicationComponent {
const gfx::Pipeline* skybox_pipeline = nullptr;
const gfx::Buffer* skybox_buffer = nullptr;
gfx::Image* shadow_map = nullptr;
const gfx::Sampler* shadow_map_sampler = nullptr;
void DrawRenderList(gfx::DrawBuffer* draw_buffer, const RenderList& render_list);
};

View File

@ -4,6 +4,7 @@
#define PI_INV 0.31830988618379067153776752674503
layout(set = 0, binding = 1) uniform samplerCube globalSetSkybox;
layout(set = 0, binding = 2) uniform sampler2D globalSetShadowmap;
layout(set = 2, binding = 0) uniform sampler2D materialSetAlbedoSampler;
layout(set = 2, binding = 1) uniform sampler2D materialSetNormalSampler;
@ -16,6 +17,7 @@ layout(location = 3) in vec3 fragLightPosTangentSpace;
layout(location = 4) in vec3 fragNormWorldSpace;
layout(location = 5) in vec3 fragViewPosWorldSpace;
layout(location = 6) in vec3 fragPosWorldSpace;
layout(location = 7) in vec4 fragPosLightSpace;
layout(location = 0) out vec4 outColor;
@ -81,5 +83,13 @@ void main() {
vec3 ambient_light = vec3(0.09082, 0.13281, 0.18164);
lighting += mix(ambient_light, texture(globalSetSkybox, R).rgb, metallic) * ao * diffuse_brdf; // this is NOT physically-based, it just looks cool
// perform perspective divide
vec3 projCoords = fragPosLightSpace.xyz;
projCoords.x = projCoords.x * 0.5 + 0.5;
projCoords.y = projCoords.y * 0.5 + 0.5;
float closestDepth = texture(globalSetShadowmap, projCoords.xy).r;
float currentDepth = projCoords.z;
float shadow = currentDepth > closestDepth ? 1.0 : 0.0;
outColor = vec4(min(emission + lighting, 1.0), 1.0);
//outColor = vec4(shadow, 0.0, 0.0, 1.0);
}

View File

@ -2,6 +2,7 @@
layout(set = 0, binding = 0) uniform GlobalSetUniformBuffer {
mat4 proj;
mat4 lightSpaceMatrix;
} globalSetUniformBuffer;
layout(set = 1, binding = 0) uniform FrameSetUniformBuffer {
@ -24,6 +25,7 @@ layout(location = 3) out vec3 fragLightPosTangentSpace;
layout(location = 4) out vec3 fragNormWorldSpace;
layout(location = 5) out vec3 fragViewPosWorldSpace;
layout(location = 6) out vec3 fragPosWorldSpace;
layout(location = 7) out vec4 fragPosLightSpace;
void main() {
vec4 worldPosition = constants.model * vec4(inPosition, 1.0);
@ -43,5 +45,7 @@ void main() {
fragViewPosWorldSpace = vec3(inverse(frameSetUniformBuffer.view) * vec4(0.0, 0.0, 0.0, 1.0));
fragPosWorldSpace = worldPosition.xyz;
fragPosLightSpace = globalSetUniformBuffer.lightSpaceMatrix * vec4(worldPosition.xyz, 1.0);
gl_Position.y *= -1.0;
}

View File

@ -2,6 +2,7 @@
layout(set = 0, binding = 0) uniform GlobalSetUniformBuffer {
mat4 proj;
mat4 lightSpaceMatrix;
} globalSetUniformBuffer;
layout(set = 1, binding = 0) uniform FrameSetUniformBuffer {

View File

@ -176,12 +176,12 @@ static VkBufferUsageFlagBits getBufferUsageFlag(gfx::BufferType type)
[[maybe_unused]] static VkSamplerAddressMode getSamplerAddressMode(gfx::WrapMode mode)
{
switch (mode) {
case gfx::WrapMode::kRepeat:
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
case gfx::WrapMode::kMirroredRepeat:
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
case gfx::WrapMode::kClampToEdge:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
case gfx::WrapMode::kRepeat:
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
case gfx::WrapMode::kMirroredRepeat:
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
case gfx::WrapMode::kClampToEdge:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
}
throw std::runtime_error("Unknown wrap mode");
}
@ -189,10 +189,10 @@ static VkBufferUsageFlagBits getBufferUsageFlag(gfx::BufferType type)
[[maybe_unused]] static VkSamplerMipmapMode getSamplerMipmapMode(gfx::Filter filter)
{
switch (filter) {
case gfx::Filter::kLinear:
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
case gfx::Filter::kNearest:
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
case gfx::Filter::kLinear:
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
case gfx::Filter::kNearest:
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
}
throw std::runtime_error("Unknown filter");
}
@ -235,7 +235,7 @@ static VkShaderStageFlags getShaderStageFlags(gfx::ShaderStageFlags::Flags flags
return out;
}
[[maybe_unused]] static VkCullModeFlags getCullModeFlags(gfx::CullMode mode)
static VkCullModeFlags getCullModeFlags(gfx::CullMode mode)
{
switch (mode) {
case gfx::CullMode::kCullNone:
@ -254,12 +254,12 @@ static VkShaderStageFlags getShaderStageFlags(gfx::ShaderStageFlags::Flags flags
static VkFormat getImageFormat(gfx::ImageFormat format)
{
switch (format) {
case gfx::ImageFormat::kLinear:
return VK_FORMAT_R8G8B8A8_UNORM;
case gfx::ImageFormat::kSRGB:
return VK_FORMAT_R8G8B8A8_SRGB;
default:
throw std::runtime_error("Unknown image format");
case gfx::ImageFormat::kLinear:
return VK_FORMAT_R8G8B8A8_UNORM;
case gfx::ImageFormat::kSRGB:
return VK_FORMAT_R8G8B8A8_SRGB;
default:
throw std::runtime_error("Unknown image format");
}
}
@ -646,7 +646,7 @@ gfx::DrawBuffer* GFXDevice::BeginRender()
VKCHECK(res);
/* perform any pending uniform buffer writes */
VKCHECK(vkResetCommandPool(pimpl->device.device, frameData.transferPool, 0));
VKCHECK(vkResetCommandPool(pimpl->device.device, frameData.transferPool, 0)); // TODO: possibly delete this
VkCommandBufferBeginInfo transferBeginInfo{
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
@ -658,36 +658,64 @@ gfx::DrawBuffer* GFXDevice::BeginRender()
// transfer cmds...
std::vector<VkBufferMemoryBarrier2> barriers{};
for (gfx::UniformBuffer* uniformBuffer : pimpl->write_queues[currentFrameIndex].uniform_buffer_writes) {
VkBufferCopy copyRegion{};
copyRegion.srcOffset = 0;
copyRegion.dstOffset = 0;
copyRegion.size = uniformBuffer->stagingBuffer.size;
vkCmdCopyBuffer(frameData.transferBuf, uniformBuffer->stagingBuffer.buffer, uniformBuffer->gpuBuffers[currentFrameIndex].buffer, 1, &copyRegion);
VkBufferMemoryBarrier2& barrier = barriers.emplace_back();
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2;
barrier.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
barrier.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
barrier.dstAccessMask = 0;
barrier.srcQueueFamilyIndex = pimpl->device.queues.transferQueueFamily;
barrier.dstQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
barrier.buffer = uniformBuffer->gpuBuffers[currentFrameIndex].buffer;
barrier.offset = 0;
barrier.size = uniformBuffer->gpuBuffers[currentFrameIndex].size;
if (pimpl->FRAMECOUNT >= FRAMES_IN_FLIGHT) { // cannot (and don't need to) do ownership transfer on first frame[s]
// acquire ownership of buffers
std::vector<VkBufferMemoryBarrier2> acquireBarriers{};
for (gfx::UniformBuffer* uniformBuffer : pimpl->write_queues[currentFrameIndex].uniform_buffer_writes) {
VkBufferMemoryBarrier2& barrier = acquireBarriers.emplace_back();
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2;
barrier.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT;
barrier.srcAccessMask = 0;
barrier.dstStageMask = VK_PIPELINE_STAGE_2_COPY_BIT;
barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
barrier.srcQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
barrier.dstQueueFamilyIndex = pimpl->device.queues.transferQueueFamily;
barrier.buffer = uniformBuffer->gpuBuffers[currentFrameIndex].buffer;
barrier.offset = 0;
barrier.size = uniformBuffer->gpuBuffers[currentFrameIndex].size;
}
VkDependencyInfo dependencyInfo{};
dependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
dependencyInfo.bufferMemoryBarrierCount = (uint32_t)acquireBarriers.size();
dependencyInfo.pBufferMemoryBarriers = acquireBarriers.data();
vkCmdPipelineBarrier2(frameData.transferBuf, &dependencyInfo);
}
pimpl->write_queues[currentFrameIndex].uniform_buffer_writes.clear();
VkDependencyInfo dependencyInfo{};
dependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
dependencyInfo.bufferMemoryBarrierCount = (uint32_t)barriers.size();
dependencyInfo.pBufferMemoryBarriers = barriers.data();
vkCmdPipelineBarrier2(frameData.transferBuf, &dependencyInfo);
{
// copy stagings buffers to GPU buffer
for (gfx::UniformBuffer* uniformBuffer : pimpl->write_queues[currentFrameIndex].uniform_buffer_writes) {
VkBufferCopy copyRegion{};
copyRegion.srcOffset = 0;
copyRegion.dstOffset = 0;
copyRegion.size = uniformBuffer->stagingBuffer.size;
vkCmdCopyBuffer(frameData.transferBuf, uniformBuffer->stagingBuffer.buffer, uniformBuffer->gpuBuffers[currentFrameIndex].buffer, 1, &copyRegion);
}
}
{
// release buffers to graphics queue
std::vector<VkBufferMemoryBarrier2> releaseBarriers{};
for (gfx::UniformBuffer* uniformBuffer : pimpl->write_queues[currentFrameIndex].uniform_buffer_writes) {
VkBufferMemoryBarrier2& barrier = releaseBarriers.emplace_back();
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2;
barrier.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT;
barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
barrier.dstStageMask = VK_PIPELINE_STAGE_2_COPY_BIT;
barrier.dstAccessMask = 0;
barrier.srcQueueFamilyIndex = pimpl->device.queues.transferQueueFamily;
barrier.dstQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
barrier.buffer = uniformBuffer->gpuBuffers[currentFrameIndex].buffer;
barrier.offset = 0;
barrier.size = uniformBuffer->gpuBuffers[currentFrameIndex].size;
}
VkDependencyInfo dependencyInfo{};
dependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
dependencyInfo.bufferMemoryBarrierCount = (uint32_t)releaseBarriers.size();
dependencyInfo.pBufferMemoryBarriers = releaseBarriers.data();
vkCmdPipelineBarrier2(frameData.transferBuf, &dependencyInfo);
}
VKCHECK(vkEndCommandBuffer(frameData.transferBuf));
VkSubmitInfo transferSubmitInfo{
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pNext = nullptr,
@ -733,13 +761,25 @@ gfx::DrawBuffer* GFXDevice::BeginRender()
{ // RECORDING
/* change barriers to perform a queue ownership acquire operation */
for (VkBufferMemoryBarrier2& barrier : barriers) {
// acquire ownership of buffers
std::vector<VkBufferMemoryBarrier2> acquireBarriers{};
for (gfx::UniformBuffer* uniformBuffer : pimpl->write_queues[currentFrameIndex].uniform_buffer_writes) {
VkBufferMemoryBarrier2& barrier = acquireBarriers.emplace_back();
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2;
barrier.srcStageMask = VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT;
barrier.srcAccessMask = 0;
barrier.dstStageMask = VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT;
barrier.dstAccessMask = VK_ACCESS_2_UNIFORM_READ_BIT;
barrier.srcQueueFamilyIndex = pimpl->device.queues.transferQueueFamily;
barrier.dstQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
barrier.buffer = uniformBuffer->gpuBuffers[currentFrameIndex].buffer;
barrier.offset = 0;
barrier.size = uniformBuffer->gpuBuffers[currentFrameIndex].size;
}
VkDependencyInfo dependencyInfo{};
dependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
dependencyInfo.bufferMemoryBarrierCount = (uint32_t)acquireBarriers.size();
dependencyInfo.pBufferMemoryBarriers = acquireBarriers.data();
vkCmdPipelineBarrier2(frameData.drawBuf, &dependencyInfo);
std::array<VkClearValue, 2> clearValues{}; // Using same value for all components enables
@ -801,6 +841,27 @@ void GFXDevice::FinishRender(gfx::DrawBuffer* drawBuffer)
vkCmdEndRenderPass(drawBuffer->frameData.drawBuf);
// transfer ownership of uniform buffers back to transfer queue
std::vector<VkBufferMemoryBarrier2> releaseBarriers{};
for (gfx::UniformBuffer* uniformBuffer : pimpl->write_queues[drawBuffer->currentFrameIndex].uniform_buffer_writes) {
VkBufferMemoryBarrier2& barrier = releaseBarriers.emplace_back();
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2;
barrier.srcStageMask = VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT;
barrier.srcAccessMask = VK_ACCESS_2_UNIFORM_READ_BIT;
barrier.dstStageMask = VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT;
barrier.dstAccessMask = 0;
barrier.srcQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
barrier.dstQueueFamilyIndex = pimpl->device.queues.transferQueueFamily;
barrier.buffer = uniformBuffer->gpuBuffers[drawBuffer->currentFrameIndex].buffer;
barrier.offset = 0;
barrier.size = uniformBuffer->gpuBuffers[drawBuffer->currentFrameIndex].size;
}
VkDependencyInfo dependencyInfo{};
dependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
dependencyInfo.bufferMemoryBarrierCount = (uint32_t)releaseBarriers.size();
dependencyInfo.pBufferMemoryBarriers = releaseBarriers.data();
vkCmdPipelineBarrier2(drawBuffer->frameData.drawBuf, &dependencyInfo);
res = vkEndCommandBuffer(drawBuffer->frameData.drawBuf);
VKCHECK(res);
@ -846,6 +907,9 @@ void GFXDevice::FinishRender(gfx::DrawBuffer* drawBuffer)
else if (res != VK_SUCCESS)
throw std::runtime_error("Failed to queue present! Code: " + std::to_string(res));
// clear write queue
pimpl->write_queues[drawBuffer->currentFrameIndex].uniform_buffer_writes.clear();
pimpl->FRAMECOUNT++;
delete drawBuffer;
@ -1011,12 +1075,7 @@ gfx::Pipeline* GFXDevice::CreatePipeline(const gfx::PipelineInfo& info)
rasterizer.rasterizerDiscardEnable = VK_FALSE; // enabling this will not run the fragment shaders at all
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
rasterizer.lineWidth = 1.0f;
if (info.backface_culling == true) {
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
}
else {
rasterizer.cullMode = VK_CULL_MODE_NONE;
}
rasterizer.cullMode = converters::getCullModeFlags(info.face_cull_mode);
rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
rasterizer.depthBiasEnable = VK_FALSE;
rasterizer.depthBiasConstantFactor = 0.0f; // ignored
@ -1488,8 +1547,8 @@ gfx::Image* GFXDevice::CreateImage(uint32_t w, uint32_t h, gfx::ImageFormat inpu
beforeCopyBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
beforeCopyBarrier.srcStageMask = VK_PIPELINE_STAGE_2_NONE;
beforeCopyBarrier.srcAccessMask = VK_ACCESS_2_NONE;
beforeCopyBarrier.dstStageMask = VK_PIPELINE_STAGE_2_COPY_BIT;
beforeCopyBarrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
beforeCopyBarrier.dstStageMask = VK_PIPELINE_STAGE_2_COPY_BIT | VK_PIPELINE_STAGE_2_BLIT_BIT; // all subresources will be COPYed or BLITed to next
beforeCopyBarrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT; // Image must be TRANSFER_DST_OPTIMAL before either stage performs a TRANSFER_WRITE
beforeCopyBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
beforeCopyBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
beforeCopyBarrier.srcQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
@ -1528,10 +1587,11 @@ gfx::Image* GFXDevice::CreateImage(uint32_t w, uint32_t h, gfx::ImageFormat inpu
// Must happen after TRANSFER_WRITE in the COPY stage and BLIT stage.
VkImageMemoryBarrier2 beforeBlitBarrier{};
beforeBlitBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
beforeBlitBarrier.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT | VK_PIPELINE_STAGE_2_BLIT_BIT;
beforeBlitBarrier.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
beforeBlitBarrier.dstStageMask = VK_PIPELINE_STAGE_2_BLIT_BIT;
beforeBlitBarrier.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT;
beforeBlitBarrier.srcStageMask =
VK_PIPELINE_STAGE_2_COPY_BIT | VK_PIPELINE_STAGE_2_BLIT_BIT; // previous mip level was either just COPYed to or just BLITed to
beforeBlitBarrier.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT; // these actions were TRANSFER_WRITEs
beforeBlitBarrier.dstStageMask = VK_PIPELINE_STAGE_2_BLIT_BIT; // the image will be BLITed from next
beforeBlitBarrier.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT; // this is a TRANSFER_READ
beforeBlitBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
beforeBlitBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
beforeBlitBarrier.srcQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
@ -1570,9 +1630,9 @@ gfx::Image* GFXDevice::CreateImage(uint32_t w, uint32_t h, gfx::ImageFormat inpu
VkImageMemoryBarrier2 afterBlitBarrier{};
afterBlitBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
afterBlitBarrier.srcStageMask = VK_PIPELINE_STAGE_2_BLIT_BIT;
afterBlitBarrier.srcAccessMask = 0;
afterBlitBarrier.srcAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT; // previous mip level was just READ from in a BLIT
afterBlitBarrier.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT;
afterBlitBarrier.dstAccessMask = VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_2_SHADER_READ_BIT;
afterBlitBarrier.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT; // it will next be sampled in a frag shader
afterBlitBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
afterBlitBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
afterBlitBarrier.srcQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
@ -1597,10 +1657,17 @@ gfx::Image* GFXDevice::CreateImage(uint32_t w, uint32_t h, gfx::ImageFormat inpu
// barrier: (mipLevels - 1) TRANSFER_DST_OPTIMAL -> SHADER_READ_ONLY_OPTIMAL
VkImageMemoryBarrier2 finalBlitBarrier{};
finalBlitBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
finalBlitBarrier.srcStageMask = VK_PIPELINE_STAGE_2_BLIT_BIT | VK_PIPELINE_STAGE_2_COPY_BIT;
if (mipLevels == 1) {
// if no mipmaps were generated, the image was just COPYed to with a WRITE
finalBlitBarrier.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT; // the final mip level was BLITed to with a WRITE
}
else {
// mips were generated, therefore last mip level was just BLITed to
finalBlitBarrier.srcStageMask = VK_PIPELINE_STAGE_2_BLIT_BIT;
}
finalBlitBarrier.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
finalBlitBarrier.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT;
finalBlitBarrier.dstAccessMask = VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_2_SHADER_READ_BIT;
finalBlitBarrier.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT;
finalBlitBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
finalBlitBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
finalBlitBarrier.srcQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
@ -1733,7 +1800,7 @@ gfx::Image* GFXDevice::CreateImageCubemap(uint32_t w, uint32_t h, gfx::ImageForm
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
VKCHECK(vkBeginCommandBuffer(commandBuffer, &beginInfo));
// barrier: (all mip levels): UNDEFINED -> TRANSFER_DST_OPTIMAL
// barrier: (all mip levels, all faces): UNDEFINED -> TRANSFER_DST_OPTIMAL
// Used for copying staging buffer AND blitting mipmaps
// Must happen before vkCmdCopyBufferToImage performs a TRANSFER_WRITE in
// the COPY stage.
@ -1741,7 +1808,8 @@ gfx::Image* GFXDevice::CreateImageCubemap(uint32_t w, uint32_t h, gfx::ImageForm
beforeCopyBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
beforeCopyBarrier.srcStageMask = VK_PIPELINE_STAGE_2_NONE;
beforeCopyBarrier.srcAccessMask = VK_ACCESS_2_NONE;
beforeCopyBarrier.dstStageMask = VK_PIPELINE_STAGE_2_COPY_BIT;
beforeCopyBarrier.dstStageMask =
VK_PIPELINE_STAGE_2_COPY_BIT | VK_PIPELINE_STAGE_2_BLIT_BIT; // all parts of the image will be either TRANSFERed to or BLITed to next
beforeCopyBarrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
beforeCopyBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
beforeCopyBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
@ -1782,10 +1850,12 @@ gfx::Image* GFXDevice::CreateImageCubemap(uint32_t w, uint32_t h, gfx::ImageForm
// Must happen after TRANSFER_WRITE in the COPY stage and BLIT stage.
VkImageMemoryBarrier2 beforeBlitBarrier{};
beforeBlitBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
beforeBlitBarrier.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT | VK_PIPELINE_STAGE_2_BLIT_BIT;
beforeBlitBarrier.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
beforeBlitBarrier.dstStageMask = VK_PIPELINE_STAGE_2_BLIT_BIT;
beforeBlitBarrier.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT;
beforeBlitBarrier.srcStageMask =
VK_PIPELINE_STAGE_2_COPY_BIT | VK_PIPELINE_STAGE_2_BLIT_BIT; // subresource was either just copied to or just blitted to
beforeBlitBarrier.srcAccessMask =
VK_ACCESS_2_TRANSFER_WRITE_BIT; // wait until CopyBufferToImage and BlitImage have performed TRANSFER_WRITE on subresource
beforeBlitBarrier.dstStageMask = VK_PIPELINE_STAGE_2_BLIT_BIT; // subresource is going to be blitted from
beforeBlitBarrier.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT; // subresource will be READ from during the blit
beforeBlitBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
beforeBlitBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
beforeBlitBarrier.srcQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
@ -1807,16 +1877,16 @@ gfx::Image* GFXDevice::CreateImageCubemap(uint32_t w, uint32_t h, gfx::ImageForm
blit.srcSubresource.mipLevel = i - 1;
blit.srcSubresource.baseArrayLayer = face;
blit.srcSubresource.layerCount = 1;
blit.srcOffsets[0] = { 0, 0, 0 };
blit.srcOffsets[1] = { mipWidth, mipHeight, 1 };
blit.srcOffsets[0] = {0, 0, 0};
blit.srcOffsets[1] = {mipWidth, mipHeight, 1};
blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
blit.dstSubresource.mipLevel = i;
blit.dstSubresource.baseArrayLayer = face;
blit.dstSubresource.layerCount = 1;
blit.dstOffsets[0] = { 0, 0, 0 };
blit.dstOffsets[1] = { mipWidth > 1 ? mipWidth / 2 : 1, mipHeight > 1 ? mipHeight / 2 : 1, 1 };
blit.dstOffsets[0] = {0, 0, 0};
blit.dstOffsets[1] = {mipWidth > 1 ? mipWidth / 2 : 1, mipHeight > 1 ? mipHeight / 2 : 1, 1};
vkCmdBlitImage(commandBuffer, out->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, out->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit,
VK_FILTER_LINEAR);
VK_FILTER_LINEAR); // WRITE-AFTER-WRITE error here
// barrier: (i - 1) TRANSFER_SRC_OPTIMAL -> SHADER_READ_ONLY_OPTIMALs
// Must happen after usage in the BLIT stage.
@ -1824,9 +1894,9 @@ gfx::Image* GFXDevice::CreateImageCubemap(uint32_t w, uint32_t h, gfx::ImageForm
VkImageMemoryBarrier2 afterBlitBarrier{};
afterBlitBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
afterBlitBarrier.srcStageMask = VK_PIPELINE_STAGE_2_BLIT_BIT;
afterBlitBarrier.srcAccessMask = 0;
afterBlitBarrier.srcAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT;
afterBlitBarrier.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT;
afterBlitBarrier.dstAccessMask = VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_2_SHADER_READ_BIT;
afterBlitBarrier.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT;
afterBlitBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
afterBlitBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
afterBlitBarrier.srcQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
@ -1851,10 +1921,10 @@ gfx::Image* GFXDevice::CreateImageCubemap(uint32_t w, uint32_t h, gfx::ImageForm
// barrier: (mipLevels - 1) TRANSFER_DST_OPTIMAL -> SHADER_READ_ONLY_OPTIMAL
VkImageMemoryBarrier2 finalBlitBarrier{};
finalBlitBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
finalBlitBarrier.srcStageMask = VK_PIPELINE_STAGE_2_BLIT_BIT | VK_PIPELINE_STAGE_2_COPY_BIT;
finalBlitBarrier.srcStageMask = VK_PIPELINE_STAGE_2_BLIT_BIT;
finalBlitBarrier.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
finalBlitBarrier.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT;
finalBlitBarrier.dstAccessMask = VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_2_SHADER_READ_BIT;
finalBlitBarrier.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT;
finalBlitBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
finalBlitBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
finalBlitBarrier.srcQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
@ -1870,7 +1940,6 @@ gfx::Image* GFXDevice::CreateImageCubemap(uint32_t w, uint32_t h, gfx::ImageForm
afterBlitDependency.imageMemoryBarrierCount = 1;
afterBlitDependency.pImageMemoryBarriers = &finalBlitBarrier;
vkCmdPipelineBarrier2(commandBuffer, &afterBlitDependency);
}
VKCHECK(vkEndCommandBuffer(commandBuffer));
@ -1893,7 +1962,6 @@ gfx::Image* GFXDevice::CreateImageCubemap(uint32_t w, uint32_t h, gfx::ImageForm
return out;
}
void GFXDevice::DestroyImage(const gfx::Image* image)
{
assert(image != nullptr);

View File

@ -26,13 +26,21 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati
auto& binding1 = globalSetBindings.emplace_back();
binding1.descriptor_type = gfx::DescriptorType::kCombinedImageSampler;
binding1.stage_flags = gfx::ShaderStageFlags::kFragment;
auto& binding2 = globalSetBindings.emplace_back();
binding2.descriptor_type = gfx::DescriptorType::kCombinedImageSampler;
binding2.stage_flags = gfx::ShaderStageFlags::kFragment;
}
global_uniform.layout = device_->CreateDescriptorSetLayout(globalSetBindings);
global_uniform.set = device_->AllocateDescriptorSet(global_uniform.layout);
global_uniform.uniform_buffer_data.data = glm::mat4{1.0f};
global_uniform.uniform_buffer_data.data.proj = glm::mat4{1.0f};
const glm::vec3 light_location{ -0.4278, 0.7923, 0.43502 };
const glm::mat4 light_proj = glm::orthoRH_ZO(-32.0f, 32.0f, -32.0f, 32.0f, -100.0f, 100.0f);
const glm::mat4 light_view = glm::lookAtRH(light_location, glm::vec3{ 0.0f, 0.0f, 0.0f }, glm::vec3{ 0.0f, 0.0f, 1.0f });
global_uniform.uniform_buffer_data.data.lightSpaceMatrix = light_proj * light_view;
global_uniform.uniform_buffer = device_->CreateUniformBuffer(sizeof(global_uniform.uniform_buffer_data), &global_uniform.uniform_buffer_data);
device_->UpdateDescriptorUniformBuffer(global_uniform.set, 0, global_uniform.uniform_buffer, 0, sizeof(global_uniform.uniform_buffer_data));
// binding1 is updated towards the end of the constructor once the skybox texture is loaded
// binding2 is updated just after that
std::vector<gfx::DescriptorSetLayoutBinding> frameSetBindings;
{
@ -68,15 +76,15 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati
debug_pipeline_info.frag_shader_path = GetResourcePath("engine/shaders/debug.frag");
debug_pipeline_info.vertex_format = debug_vertex_format;
debug_pipeline_info.alpha_blending = false;
debug_pipeline_info.backface_culling = false; // probably ignored for line rendering
debug_pipeline_info.write_z = false; // lines don't need the depth buffer
debug_pipeline_info.face_cull_mode = gfx::CullMode::kCullNone; // probably ignored for line rendering
debug_pipeline_info.write_z = false; // lines don't need the depth buffer
// debug_pipeline_info.descriptor_set_layouts = empty;
debug_pipeline_info.line_primitives = true;
debug_rendering_things_.pipeline = device_->CreatePipeline(debug_pipeline_info);
}
// create the skybox cubemap
// create the skybox cubemap and update global skybox combined-image-sampler
{
constexpr uint32_t cubemap_w = 2048;
constexpr uint32_t cubemap_h = 2048;
@ -91,7 +99,6 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati
face_unsafe_ptrs[face] = face_unq_ptrs[face]->data();
}
skybox_cubemap = device_->CreateImageCubemap(cubemap_w, cubemap_h, gfx::ImageFormat::kSRGB, face_unsafe_ptrs);
gfx::SamplerInfo sampler_info{};
sampler_info.magnify = gfx::Filter::kLinear;
@ -102,6 +109,8 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati
sampler_info.wrap_w = gfx::WrapMode::kClampToEdge;
sampler_info.anisotropic_filtering = true;
skybox_sampler = device_->CreateSampler(sampler_info);
device_->UpdateDescriptorCombinedImageSampler(global_uniform.set, 1, skybox_cubemap, skybox_sampler);
}
// create skybox shader
@ -115,15 +124,13 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati
pipeline_info.frag_shader_path = GetResourcePath("engine/shaders/skybox.frag");
pipeline_info.vertex_format = vertex_format;
pipeline_info.alpha_blending = false;
pipeline_info.backface_culling = true;
pipeline_info.face_cull_mode = gfx::CullMode::kCullBack;
pipeline_info.write_z = false;
pipeline_info.line_primitives = false;
pipeline_info.descriptor_set_layouts.push_back(GetGlobalSetLayout());
pipeline_info.descriptor_set_layouts.push_back(GetFrameSetLayout());
skybox_pipeline = device_->CreatePipeline(pipeline_info);
device_->UpdateDescriptorCombinedImageSampler(global_uniform.set, 1, skybox_cubemap, skybox_sampler);
}
// create skybox vertex buffer
@ -136,40 +143,40 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati
v.push_back({2.0f, 0.0f, 2.0f});
v.push_back({0.0f, 0.0f, 2.0f});
// back
v.push_back({2.0f, 2.0f, 2.0f });
v.push_back({ 2.0f, 2.0f, 0.0f});
v.push_back({2.0f, 2.0f, 2.0f});
v.push_back({2.0f, 2.0f, 0.0f});
v.push_back({0.0f, 2.0f, 0.0f});
v.push_back({0.0f, 2.0f, 0.0f});
v.push_back({0.0f, 2.0f, 2.0f });
v.push_back({ 2.0f, 2.0f, 2.0f });
v.push_back({0.0f, 2.0f, 2.0f});
v.push_back({2.0f, 2.0f, 2.0f});
// left
v.push_back({0.0f, 2.0f, 2.0f });
v.push_back({0.0f, 2.0f, 2.0f});
v.push_back({0.0f, 2.0f, 0.0f});
v.push_back({0.0f, 0.0f, 0.0f});
v.push_back({0.0f, 0.0f, 0.0f});
v.push_back({0.0f, 0.0f, 2.0f });
v.push_back({0.0f, 2.0f, 2.0f });
v.push_back({0.0f, 0.0f, 2.0f});
v.push_back({0.0f, 2.0f, 2.0f});
// right
v.push_back({ 2.0f, 0.0f, 2.0f });
v.push_back({ 2.0f, 0.0f, 0.0f});
v.push_back({ 2.0f, 2.0f, 0.0f});
v.push_back({ 2.0f, 2.0f, 0.0f});
v.push_back({ 2.0f, 2.0f, 2.0f });
v.push_back({ 2.0f, 0.0f, 2.0f });
v.push_back({2.0f, 0.0f, 2.0f});
v.push_back({2.0f, 0.0f, 0.0f});
v.push_back({2.0f, 2.0f, 0.0f});
v.push_back({2.0f, 2.0f, 0.0f});
v.push_back({2.0f, 2.0f, 2.0f});
v.push_back({2.0f, 0.0f, 2.0f});
// top
v.push_back({0.0f, 2.0f, 2.0f });
v.push_back({0.0f, 0.0f, 2.0f });
v.push_back({ 2.0f, 0.0f, 2.0f });
v.push_back({ 2.0f, 0.0f, 2.0f });
v.push_back({ 2.0f, 2.0f, 2.0f });
v.push_back({0.0f, 2.0f, 2.0f });
v.push_back({0.0f, 2.0f, 2.0f});
v.push_back({0.0f, 0.0f, 2.0f});
v.push_back({2.0f, 0.0f, 2.0f});
v.push_back({2.0f, 0.0f, 2.0f});
v.push_back({2.0f, 2.0f, 2.0f});
v.push_back({0.0f, 2.0f, 2.0f});
// bottom
v.push_back({ 2.0f, 2.0f, 0.0f});
v.push_back({ 2.0f, 0.0f, 0.0f});
v.push_back({2.0f, 2.0f, 0.0f});
v.push_back({2.0f, 0.0f, 0.0f});
v.push_back({0.0f, 0.0f, 0.0f});
v.push_back({0.0f, 0.0f, 0.0f});
v.push_back({0.0f, 2.0f, 0.0f});
v.push_back({ 2.0f, 2.0f, 0.0f});
v.push_back({2.0f, 2.0f, 0.0f});
for (glm::vec3& pos : v) {
pos.x -= 1.0f;
pos.y -= 1.0f;
@ -181,10 +188,31 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati
skybox_buffer = device_->CreateBuffer(gfx::BufferType::kVertex, v.size() * sizeof(glm::vec3), v.data());
}
// shadow mapping...
{
int w{}, h{};
auto shadowmap_image = util::ReadImageFile(GetResourcePath("textures/shadow_map.png"), w, h);
shadow_map = device_->CreateImage(w, h, gfx::ImageFormat::kLinear, shadowmap_image->data());
gfx::SamplerInfo sampler_info{};
sampler_info.magnify = gfx::Filter::kLinear;
sampler_info.minify = gfx::Filter::kLinear;
sampler_info.mipmap = gfx::Filter::kLinear; // trilinear is apparently good for shadow maps
sampler_info.wrap_u = gfx::WrapMode::kClampToEdge;
sampler_info.wrap_v = gfx::WrapMode::kClampToEdge;
sampler_info.wrap_w = gfx::WrapMode::kClampToEdge;
sampler_info.anisotropic_filtering = false; // Copilot says not to use aniso for shadow maps
shadow_map_sampler = device_->CreateSampler(sampler_info);
device_->UpdateDescriptorCombinedImageSampler(global_uniform.set, 2, shadow_map, shadow_map_sampler);
}
};
Renderer::~Renderer()
{
device_->DestroySampler(shadow_map_sampler);
device_->DestroyImage(shadow_map);
device_->DestroyBuffer(skybox_buffer);
device_->DestroyPipeline(skybox_pipeline);
device_->DestroySampler(skybox_sampler);
@ -213,15 +241,19 @@ void Renderer::PreRender(bool window_is_resized, glm::mat4 camera_transform)
const glm::mat4 proj_matrix =
glm::perspectiveRH_ZO(camera_settings_.vertical_fov_radians, viewport_aspect_ratio_, camera_settings_.clip_near, camera_settings_.clip_far);
/* update SET 0 (rarely changing uniforms)*/
global_uniform.uniform_buffer_data.data = proj_matrix;
global_uniform.uniform_buffer_data.data.proj = proj_matrix;
device_->WriteUniformBuffer(global_uniform.uniform_buffer, 0, sizeof(global_uniform.uniform_buffer_data), &global_uniform.uniform_buffer_data);
}
// set camera view matrix uniform
/* update SET 1 (per frame uniforms) */
const glm::mat4 view_matrix = glm::inverse(camera_transform);
frame_uniform.uniform_buffer_data.data = view_matrix;
device_->WriteUniformBuffer(frame_uniform.uniform_buffer, 0, sizeof(frame_uniform.uniform_buffer_data), &frame_uniform.uniform_buffer_data);
// override with light matrix
frame_uniform.uniform_buffer_data.data = glm::mat4{1.0f};
device_->WriteUniformBuffer(frame_uniform.uniform_buffer, 0, sizeof(frame_uniform.uniform_buffer_data), &frame_uniform.uniform_buffer_data);
global_uniform.uniform_buffer_data.data.proj = global_uniform.uniform_buffer_data.data.lightSpaceMatrix;
device_->WriteUniformBuffer(global_uniform.uniform_buffer, 0, sizeof(global_uniform.uniform_buffer_data), &global_uniform.uniform_buffer_data);
}
void Renderer::Render(const RenderList* static_list, const RenderList* dynamic_list, const std::vector<Line>& debug_lines)
@ -260,8 +292,8 @@ void Renderer::Render(const RenderList* static_list, const RenderList* dynamic_l
device_->CmdBindPipeline(draw_buffer, debug_rendering_things_.pipeline);
DebugPush push{};
for (const Line& l : debug_lines) {
push.pos1 = global_uniform.uniform_buffer_data.data * frame_uniform.uniform_buffer_data.data * glm::vec4(l.pos1, 1.0f);
push.pos2 = global_uniform.uniform_buffer_data.data * frame_uniform.uniform_buffer_data.data * glm::vec4(l.pos2, 1.0f);
push.pos1 = global_uniform.uniform_buffer_data.data.proj * frame_uniform.uniform_buffer_data.data * glm::vec4(l.pos1, 1.0f);
push.pos2 = global_uniform.uniform_buffer_data.data.proj * frame_uniform.uniform_buffer_data.data * glm::vec4(l.pos2, 1.0f);
push.color = l.color;
device_->CmdPushConstants(draw_buffer, debug_rendering_things_.pipeline, 0, sizeof(DebugPush), &push);
device_->CmdDraw(draw_buffer, 2, 1, 0, 0);

View File

@ -48,7 +48,7 @@ Shader::Shader(Renderer* renderer, const std::string& vertPath, const std::strin
info.frag_shader_path = fragPath;
info.vertex_format = vertFormat;
info.alpha_blending = settings.alpha_blending;
info.backface_culling = settings.cull_backface;
info.face_cull_mode = settings.cull_backface ? gfx::CullMode::kCullBack : gfx::CullMode::kCullNone;
info.write_z = settings.write_z;
info.line_primitives = false;
info.descriptor_set_layouts.push_back(renderer->GetGlobalSetLayout());

View File

@ -555,12 +555,12 @@ engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic)
// get AABB
AABB box{};
box.min.x = pos_accessor.minValues.at(0);
box.min.y = pos_accessor.minValues.at(1);
box.min.z = pos_accessor.minValues.at(2);
box.max.x = pos_accessor.maxValues.at(0);
box.max.y = pos_accessor.maxValues.at(1);
box.max.z = pos_accessor.maxValues.at(2);
box.min.x = static_cast<float>(pos_accessor.minValues.at(0));
box.min.y = static_cast<float>(pos_accessor.minValues.at(1));
box.min.z = static_cast<float>(pos_accessor.minValues.at(2));
box.max.x = static_cast<float>(pos_accessor.maxValues.at(0));
box.max.y = static_cast<float>(pos_accessor.maxValues.at(1));
box.max.z = static_cast<float>(pos_accessor.maxValues.at(2));
primitive_array.emplace_back(engine_mesh, engine_material, box);
}

View File

@ -204,17 +204,17 @@ namespace engine {
.srcStageMask = VK_PIPELINE_STAGE_NONE,
.dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dependencyFlags = 0,
},
{
// Image Layout Transition
.srcSubpass = VK_SUBPASS_EXTERNAL,
.dstSubpass = 0,
.srcStageMask = VK_PIPELINE_STAGE_NONE,
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.dependencyFlags = 0,
},
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 KiB

View File

@ -89,7 +89,7 @@ void PlayGame(GameSettings settings)
/* floor */
engine::Entity floor = engine::util::LoadGLTF(*main_scene, app.GetResourcePath("models/floor.glb"));
main_scene->GetComponent<engine::MeshRenderableComponent>(main_scene->GetEntity("Cube", floor))->visible = false;
//main_scene->GetComponent<engine::MeshRenderableComponent>(main_scene->GetEntity("Cube", floor))->visible = false;
engine::Entity monke = engine::util::LoadGLTF(*main_scene, app.GetResourcePath("models/monke.glb"));
main_scene->GetComponent<engine::TransformComponent>(monke)->position.y += 10.0f;