ADD: emissive, occlusion
This commit is contained in:
@@ -208,12 +208,16 @@ std::shared_ptr<MeshAsset> AssetManager::createMesh(const MeshCreateInfo &info)
|
||||
AllocatedBuffer matBuffer = createMaterialBufferWithConstants(opt.constants);
|
||||
|
||||
GLTFMetallic_Roughness::MaterialResources res{};
|
||||
res.colorImage = _engine->_errorCheckerboardImage; // visible fallback for albedo
|
||||
res.colorImage = _engine->_errorCheckerboardImage;
|
||||
res.colorSampler = _engine->_samplerManager->defaultLinear();
|
||||
res.metalRoughImage = _engine->_whiteImage;
|
||||
res.metalRoughSampler = _engine->_samplerManager->defaultLinear();
|
||||
res.normalImage = _engine->_flatNormalImage;
|
||||
res.normalSampler = _engine->_samplerManager->defaultLinear();
|
||||
res.occlusionImage = _engine->_whiteImage;
|
||||
res.occlusionSampler = _engine->_samplerManager->defaultLinear();
|
||||
res.emissiveImage = _engine->_blackImage;
|
||||
res.emissiveSampler = _engine->_samplerManager->defaultLinear();
|
||||
res.dataBuffer = matBuffer.buffer;
|
||||
res.dataBufferOffset = 0;
|
||||
|
||||
@@ -267,6 +271,27 @@ std::shared_ptr<MeshAsset> AssetManager::createMesh(const MeshCreateInfo &info)
|
||||
cache->watchBinding(handle, mat->data.materialSet, 3u, samp, _engine->_flatNormalImage.imageView);
|
||||
}
|
||||
}
|
||||
if (!opt.occlusionPath.empty())
|
||||
{
|
||||
auto key = buildKey(opt.occlusionPath, opt.occlusionSRGB);
|
||||
key.channels = TextureCache::TextureKey::ChannelsHint::R;
|
||||
if (key.hash != 0)
|
||||
{
|
||||
VkSampler samp = _engine->_samplerManager->defaultLinear();
|
||||
auto handle = cache->request(key, samp);
|
||||
cache->watchBinding(handle, mat->data.materialSet, 4u, samp, _engine->_whiteImage.imageView);
|
||||
}
|
||||
}
|
||||
if (!opt.emissivePath.empty())
|
||||
{
|
||||
auto key = buildKey(opt.emissivePath, opt.emissiveSRGB);
|
||||
if (key.hash != 0)
|
||||
{
|
||||
VkSampler samp = _engine->_samplerManager->defaultLinear();
|
||||
auto handle = cache->request(key, samp);
|
||||
cache->watchBinding(handle, mat->data.materialSet, 5u, samp, _engine->_blackImage.imageView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mesh = createMesh(info.name, vertsSpan, indsSpan, mat);
|
||||
@@ -466,6 +491,10 @@ AllocatedBuffer AssetManager::createMaterialBufferWithConstants(
|
||||
{
|
||||
matConstants->extra[0].x = 1.0f; // normal scale default
|
||||
}
|
||||
if (matConstants->extra[0].y == 0.0f)
|
||||
{
|
||||
matConstants->extra[0].y = 1.0f;
|
||||
}
|
||||
// Ensure writes are visible on non-coherent memory
|
||||
vmaFlushAllocation(_engine->_deviceManager->allocator(), matBuffer.allocation, 0,
|
||||
sizeof(GLTFMetallic_Roughness::MaterialConstants));
|
||||
@@ -525,6 +554,10 @@ std::shared_ptr<MeshAsset> AssetManager::createMesh(const std::string &name,
|
||||
matResources.metalRoughSampler = _engine->_samplerManager->defaultLinear();
|
||||
matResources.normalImage = _engine->_flatNormalImage;
|
||||
matResources.normalSampler = _engine->_samplerManager->defaultLinear();
|
||||
matResources.occlusionImage = _engine->_whiteImage;
|
||||
matResources.occlusionSampler = _engine->_samplerManager->defaultLinear();
|
||||
matResources.emissiveImage = _engine->_blackImage;
|
||||
matResources.emissiveSampler = _engine->_samplerManager->defaultLinear();
|
||||
|
||||
AllocatedBuffer matBuffer = createMaterialBufferWithConstants({});
|
||||
matResources.dataBuffer = matBuffer.buffer;
|
||||
@@ -569,6 +602,10 @@ std::shared_ptr<GLTFMaterial> AssetManager::createMaterialFromConstants(
|
||||
res.metalRoughSampler = _engine->_samplerManager->defaultLinear();
|
||||
res.normalImage = _engine->_flatNormalImage;
|
||||
res.normalSampler = _engine->_samplerManager->defaultLinear();
|
||||
res.occlusionImage = _engine->_whiteImage;
|
||||
res.occlusionSampler = _engine->_samplerManager->defaultLinear();
|
||||
res.emissiveImage = _engine->_blackImage;
|
||||
res.emissiveSampler = _engine->_samplerManager->defaultLinear();
|
||||
|
||||
AllocatedBuffer buf = createMaterialBufferWithConstants(constants);
|
||||
res.dataBuffer = buf.buffer;
|
||||
|
||||
@@ -28,10 +28,14 @@ public:
|
||||
// Optional tangent-space normal map for PBR (placeholder; not wired yet)
|
||||
// When enabled later, this will be sampled in shaders and requires tangents.
|
||||
std::string normalPath;
|
||||
std::string occlusionPath;
|
||||
std::string emissivePath;
|
||||
|
||||
bool albedoSRGB = true;
|
||||
bool metalRoughSRGB = false;
|
||||
bool normalSRGB = false; // normal maps are typically non-sRGB
|
||||
bool occlusionSRGB = false;
|
||||
bool emissiveSRGB = true;
|
||||
|
||||
GLTFMetallic_Roughness::MaterialConstants constants{};
|
||||
|
||||
|
||||
@@ -70,6 +70,8 @@ void SwapchainManager::init_swapchain()
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
_gBufferAlbedo = _resourceManager->create_image(drawImageExtent, VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
_gBufferExtra = _resourceManager->create_image(drawImageExtent, VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
_idBuffer = _resourceManager->create_image(drawImageExtent, VK_FORMAT_R32_UINT,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
|
||||
@@ -85,6 +87,7 @@ void SwapchainManager::init_swapchain()
|
||||
_resourceManager->destroy_image(_gBufferPosition);
|
||||
_resourceManager->destroy_image(_gBufferNormal);
|
||||
_resourceManager->destroy_image(_gBufferAlbedo);
|
||||
_resourceManager->destroy_image(_gBufferExtra);
|
||||
_resourceManager->destroy_image(_idBuffer);
|
||||
});
|
||||
};
|
||||
@@ -196,6 +199,8 @@ void SwapchainManager::resize_swapchain(struct SDL_Window *window)
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
_gBufferAlbedo = _resourceManager->create_image(drawImageExtent, VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
_gBufferExtra = _resourceManager->create_image(drawImageExtent, VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
_idBuffer = _resourceManager->create_image(drawImageExtent, VK_FORMAT_R32_UINT,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
|
||||
@@ -211,6 +216,7 @@ void SwapchainManager::resize_swapchain(struct SDL_Window *window)
|
||||
_resourceManager->destroy_image(_gBufferPosition);
|
||||
_resourceManager->destroy_image(_gBufferNormal);
|
||||
_resourceManager->destroy_image(_gBufferAlbedo);
|
||||
_resourceManager->destroy_image(_gBufferExtra);
|
||||
_resourceManager->destroy_image(_idBuffer);
|
||||
});
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ public:
|
||||
AllocatedImage gBufferPosition() const { return _gBufferPosition; }
|
||||
AllocatedImage gBufferNormal() const { return _gBufferNormal; }
|
||||
AllocatedImage gBufferAlbedo() const { return _gBufferAlbedo; }
|
||||
AllocatedImage gBufferExtra() const { return _gBufferExtra; }
|
||||
AllocatedImage idBuffer() const { return _idBuffer; }
|
||||
VkExtent2D windowExtent() const { return _windowExtent; }
|
||||
|
||||
@@ -51,6 +52,7 @@ private:
|
||||
AllocatedImage _gBufferPosition = {};
|
||||
AllocatedImage _gBufferNormal = {};
|
||||
AllocatedImage _gBufferAlbedo = {};
|
||||
AllocatedImage _gBufferExtra = {};
|
||||
AllocatedImage _idBuffer = {};
|
||||
|
||||
DeletionQueue _deletionQueue;
|
||||
|
||||
@@ -613,6 +613,7 @@ void VulkanEngine::draw()
|
||||
RGImageHandle hGBufferPosition = _renderGraph->import_gbuffer_position();
|
||||
RGImageHandle hGBufferNormal = _renderGraph->import_gbuffer_normal();
|
||||
RGImageHandle hGBufferAlbedo = _renderGraph->import_gbuffer_albedo();
|
||||
RGImageHandle hGBufferExtra = _renderGraph->import_gbuffer_extra();
|
||||
RGImageHandle hSwapchain = _renderGraph->import_swapchain_image(swapchainImageIndex);
|
||||
// For debug overlays (IBL volumes), re-use HDR draw image as a color target.
|
||||
RGImageHandle hDebugColor = hDraw;
|
||||
@@ -656,7 +657,7 @@ void VulkanEngine::draw()
|
||||
if (auto *geometry = _renderPassManager->getPass<GeometryPass>())
|
||||
{
|
||||
RGImageHandle hID = _renderGraph->import_id_buffer();
|
||||
geometry->register_graph(_renderGraph.get(), hGBufferPosition, hGBufferNormal, hGBufferAlbedo, hID, hDepth);
|
||||
geometry->register_graph(_renderGraph.get(), hGBufferPosition, hGBufferNormal, hGBufferAlbedo, hGBufferExtra, hID, hDepth);
|
||||
|
||||
// If ID-buffer picking is enabled and a pick was requested this frame,
|
||||
// add a small transfer pass to read back 1 pixel from the ID buffer.
|
||||
@@ -719,7 +720,7 @@ void VulkanEngine::draw()
|
||||
}
|
||||
if (auto *lighting = _renderPassManager->getPass<LightingPass>())
|
||||
{
|
||||
lighting->register_graph(_renderGraph.get(), hDraw, hGBufferPosition, hGBufferNormal, hGBufferAlbedo,
|
||||
lighting->register_graph(_renderGraph.get(), hDraw, hGBufferPosition, hGBufferNormal, hGBufferAlbedo, hGBufferExtra,
|
||||
std::span<RGImageHandle>(hShadowCascades.data(), hShadowCascades.size()));
|
||||
}
|
||||
|
||||
|
||||
@@ -956,6 +956,18 @@ RGImageHandle RenderGraph::import_gbuffer_albedo()
|
||||
return import_image(d);
|
||||
}
|
||||
|
||||
RGImageHandle RenderGraph::import_gbuffer_extra()
|
||||
{
|
||||
RGImportedImageDesc d{};
|
||||
d.name = "gBuffer.extra";
|
||||
d.image = _context->getSwapchain()->gBufferExtra().image;
|
||||
d.imageView = _context->getSwapchain()->gBufferExtra().imageView;
|
||||
d.format = _context->getSwapchain()->gBufferExtra().imageFormat;
|
||||
d.extent = _context->getDrawExtent();
|
||||
d.currentLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
return import_image(d);
|
||||
}
|
||||
|
||||
RGImageHandle RenderGraph::import_id_buffer()
|
||||
{
|
||||
RGImportedImageDesc d{};
|
||||
|
||||
@@ -56,6 +56,7 @@ struct Pass; // fwd
|
||||
RGImageHandle import_gbuffer_position();
|
||||
RGImageHandle import_gbuffer_normal();
|
||||
RGImageHandle import_gbuffer_albedo();
|
||||
RGImageHandle import_gbuffer_extra();
|
||||
RGImageHandle import_id_buffer();
|
||||
RGImageHandle import_swapchain_image(uint32_t index);
|
||||
void add_present_chain(RGImageHandle sourceDraw,
|
||||
|
||||
@@ -20,6 +20,8 @@ void GLTFMetallic_Roughness::build_pipelines(VulkanEngine *engine)
|
||||
layoutBuilder.add_binding(1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
layoutBuilder.add_binding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
layoutBuilder.add_binding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
layoutBuilder.add_binding(4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
layoutBuilder.add_binding(5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
|
||||
materialLayout = layoutBuilder.build(engine->_deviceManager->device(),
|
||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
@@ -93,9 +95,10 @@ void GLTFMetallic_Roughness::build_pipelines(VulkanEngine *engine)
|
||||
engine->_swapchainManager->gBufferPosition().imageFormat,
|
||||
engine->_swapchainManager->gBufferNormal().imageFormat,
|
||||
engine->_swapchainManager->gBufferAlbedo().imageFormat,
|
||||
engine->_swapchainManager->idBuffer().imageFormat
|
||||
engine->_swapchainManager->idBuffer().imageFormat,
|
||||
engine->_swapchainManager->gBufferExtra().imageFormat
|
||||
};
|
||||
b.set_color_attachment_formats(std::span<VkFormat>(gFormats, 4));
|
||||
b.set_color_attachment_formats(std::span<VkFormat>(gFormats, 5));
|
||||
b.set_depth_format(engine->_swapchainManager->depthImage().imageFormat);
|
||||
};
|
||||
engine->_pipelineManager->registerGraphics("mesh.gbuffer", gbufferInfo);
|
||||
@@ -139,6 +142,10 @@ MaterialInstance GLTFMetallic_Roughness::write_material(VkDevice device, Materia
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
writer.write_image(3, resources.normalImage.imageView, resources.normalSampler,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
writer.write_image(4, resources.occlusionImage.imageView, resources.occlusionSampler,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
writer.write_image(5, resources.emissiveImage.imageView, resources.emissiveSampler,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
|
||||
writer.update_set(device, matData.materialSet);
|
||||
|
||||
|
||||
@@ -30,6 +30,10 @@ struct GLTFMetallic_Roughness
|
||||
VkSampler metalRoughSampler;
|
||||
AllocatedImage normalImage;
|
||||
VkSampler normalSampler;
|
||||
AllocatedImage occlusionImage;
|
||||
VkSampler occlusionSampler;
|
||||
AllocatedImage emissiveImage;
|
||||
VkSampler emissiveSampler;
|
||||
VkBuffer dataBuffer;
|
||||
uint32_t dataBufferOffset;
|
||||
};
|
||||
|
||||
@@ -69,10 +69,12 @@ void GeometryPass::register_graph(RenderGraph *graph,
|
||||
RGImageHandle gbufferPosition,
|
||||
RGImageHandle gbufferNormal,
|
||||
RGImageHandle gbufferAlbedo,
|
||||
RGImageHandle gbufferExtra,
|
||||
RGImageHandle idHandle,
|
||||
RGImageHandle depthHandle)
|
||||
{
|
||||
if (!graph || !gbufferPosition.valid() || !gbufferNormal.valid() || !gbufferAlbedo.valid() ||
|
||||
!gbufferExtra.valid() ||
|
||||
!idHandle.valid() || !depthHandle.valid())
|
||||
{
|
||||
return;
|
||||
@@ -81,7 +83,7 @@ void GeometryPass::register_graph(RenderGraph *graph,
|
||||
graph->add_pass(
|
||||
"Geometry",
|
||||
RGPassType::Graphics,
|
||||
[gbufferPosition, gbufferNormal, gbufferAlbedo, idHandle, depthHandle](RGPassBuilder &builder, EngineContext *ctx)
|
||||
[gbufferPosition, gbufferNormal, gbufferAlbedo, gbufferExtra, idHandle, depthHandle](RGPassBuilder &builder, EngineContext *ctx)
|
||||
{
|
||||
VkClearValue clear{};
|
||||
clear.color = {{0.f, 0.f, 0.f, 0.f}};
|
||||
@@ -89,6 +91,9 @@ void GeometryPass::register_graph(RenderGraph *graph,
|
||||
builder.write_color(gbufferPosition, true, clear);
|
||||
builder.write_color(gbufferNormal, true, clear);
|
||||
builder.write_color(gbufferAlbedo, true, clear);
|
||||
VkClearValue clearExtra{};
|
||||
clearExtra.color = {{1.f, 0.f, 0.f, 0.f}}; // AO=1, emissive=0
|
||||
builder.write_color(gbufferExtra, true, clearExtra);
|
||||
VkClearValue clearID{};
|
||||
clearID.color.uint32[0] = 0u;
|
||||
builder.write_color(idHandle, true, clearID);
|
||||
@@ -123,11 +128,11 @@ void GeometryPass::register_graph(RenderGraph *graph,
|
||||
builder.read_buffer(b, RGBufferUsage::StorageRead, 0, "geom.vertex");
|
||||
}
|
||||
},
|
||||
[this, gbufferPosition, gbufferNormal, gbufferAlbedo, idHandle, depthHandle](VkCommandBuffer cmd,
|
||||
[this, gbufferPosition, gbufferNormal, gbufferAlbedo, gbufferExtra, idHandle, depthHandle](VkCommandBuffer cmd,
|
||||
const RGPassResources &res,
|
||||
EngineContext *ctx)
|
||||
{
|
||||
draw_geometry(cmd, ctx, res, gbufferPosition, gbufferNormal, gbufferAlbedo, idHandle, depthHandle);
|
||||
draw_geometry(cmd, ctx, res, gbufferPosition, gbufferNormal, gbufferAlbedo, gbufferExtra, idHandle, depthHandle);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -137,6 +142,7 @@ void GeometryPass::draw_geometry(VkCommandBuffer cmd,
|
||||
RGImageHandle gbufferPosition,
|
||||
RGImageHandle gbufferNormal,
|
||||
RGImageHandle gbufferAlbedo,
|
||||
RGImageHandle /*gbufferExtra*/,
|
||||
RGImageHandle /*idHandle*/,
|
||||
RGImageHandle depthHandle) const
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ public:
|
||||
RGImageHandle gbufferPosition,
|
||||
RGImageHandle gbufferNormal,
|
||||
RGImageHandle gbufferAlbedo,
|
||||
RGImageHandle gbufferExtra,
|
||||
RGImageHandle idHandle,
|
||||
RGImageHandle depthHandle);
|
||||
|
||||
@@ -30,6 +31,7 @@ private:
|
||||
RGImageHandle gbufferPosition,
|
||||
RGImageHandle gbufferNormal,
|
||||
RGImageHandle gbufferAlbedo,
|
||||
RGImageHandle gbufferExtra,
|
||||
RGImageHandle idHandle,
|
||||
RGImageHandle depthHandle) const;
|
||||
};
|
||||
|
||||
@@ -39,6 +39,7 @@ void LightingPass::init(EngineContext *context)
|
||||
builder.add_binding(0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
builder.add_binding(1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
builder.add_binding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
builder.add_binding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
_gBufferInputDescriptorLayout = builder.build(
|
||||
_context->getDevice()->device(), VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
nullptr, VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT);
|
||||
@@ -55,6 +56,8 @@ void LightingPass::init(EngineContext *context)
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
writer.write_image(2, _context->getSwapchain()->gBufferAlbedo().imageView, _context->getSamplers()->defaultLinear(),
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
writer.write_image(3, _context->getSwapchain()->gBufferExtra().imageView, _context->getSamplers()->defaultLinear(),
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
writer.update_set(_context->getDevice()->device(), _gBufferInputDescriptorSet);
|
||||
}
|
||||
|
||||
@@ -136,9 +139,11 @@ void LightingPass::register_graph(RenderGraph *graph,
|
||||
RGImageHandle gbufferPosition,
|
||||
RGImageHandle gbufferNormal,
|
||||
RGImageHandle gbufferAlbedo,
|
||||
RGImageHandle gbufferExtra,
|
||||
std::span<RGImageHandle> shadowCascades)
|
||||
{
|
||||
if (!graph || !drawHandle.valid() || !gbufferPosition.valid() || !gbufferNormal.valid() || !gbufferAlbedo.valid())
|
||||
if (!graph || !drawHandle.valid() || !gbufferPosition.valid() || !gbufferNormal.valid() || !gbufferAlbedo.valid() ||
|
||||
!gbufferExtra.valid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -146,11 +151,12 @@ void LightingPass::register_graph(RenderGraph *graph,
|
||||
graph->add_pass(
|
||||
"Lighting",
|
||||
RGPassType::Graphics,
|
||||
[drawHandle, gbufferPosition, gbufferNormal, gbufferAlbedo, shadowCascades](RGPassBuilder &builder, EngineContext *)
|
||||
[drawHandle, gbufferPosition, gbufferNormal, gbufferAlbedo, gbufferExtra, shadowCascades](RGPassBuilder &builder, EngineContext *)
|
||||
{
|
||||
builder.read(gbufferPosition, RGImageUsage::SampledFragment);
|
||||
builder.read(gbufferNormal, RGImageUsage::SampledFragment);
|
||||
builder.read(gbufferAlbedo, RGImageUsage::SampledFragment);
|
||||
builder.read(gbufferExtra, RGImageUsage::SampledFragment);
|
||||
for (size_t i = 0; i < shadowCascades.size(); ++i)
|
||||
{
|
||||
if (shadowCascades[i].valid()) builder.read(shadowCascades[i], RGImageUsage::SampledFragment);
|
||||
|
||||
@@ -19,7 +19,9 @@ public:
|
||||
RGImageHandle drawHandle,
|
||||
RGImageHandle gbufferPosition,
|
||||
RGImageHandle gbufferNormal,
|
||||
RGImageHandle gbufferAlbedo, std::span<RGImageHandle> shadowCascades);
|
||||
RGImageHandle gbufferAlbedo,
|
||||
RGImageHandle gbufferExtra,
|
||||
std::span<RGImageHandle> shadowCascades);
|
||||
|
||||
private:
|
||||
EngineContext *_context = nullptr;
|
||||
|
||||
@@ -353,9 +353,7 @@ std::optional<std::shared_ptr<LoadedGLTF> > loadGltf(VulkanEngine *engine, std::
|
||||
materials.push_back(newMat);
|
||||
file.materials[mat.name.c_str()] = newMat;
|
||||
|
||||
GLTFMetallic_Roughness::MaterialConstants constants;
|
||||
// Defaults
|
||||
constants.extra[0].x = 1.0f; // normalScale
|
||||
GLTFMetallic_Roughness::MaterialConstants constants{};
|
||||
constants.colorFactors.x = mat.pbrData.baseColorFactor[0];
|
||||
constants.colorFactors.y = mat.pbrData.baseColorFactor[1];
|
||||
constants.colorFactors.z = mat.pbrData.baseColorFactor[2];
|
||||
@@ -363,6 +361,11 @@ std::optional<std::shared_ptr<LoadedGLTF> > loadGltf(VulkanEngine *engine, std::
|
||||
|
||||
constants.metal_rough_factors.x = mat.pbrData.metallicFactor;
|
||||
constants.metal_rough_factors.y = mat.pbrData.roughnessFactor;
|
||||
constants.extra[0].x = 1.0f;
|
||||
constants.extra[0].y = mat.occlusionTexture.has_value() ? mat.occlusionTexture->strength : 1.0f;
|
||||
constants.extra[1].x = mat.emissiveFactor[0];
|
||||
constants.extra[1].y = mat.emissiveFactor[1];
|
||||
constants.extra[1].z = mat.emissiveFactor[2];
|
||||
// write material parameters to buffer
|
||||
sceneMaterialConstants[data_index] = constants;
|
||||
|
||||
@@ -380,6 +383,10 @@ std::optional<std::shared_ptr<LoadedGLTF> > loadGltf(VulkanEngine *engine, std::
|
||||
materialResources.metalRoughSampler = engine->_samplerManager->defaultLinear();
|
||||
materialResources.normalImage = engine->_flatNormalImage;
|
||||
materialResources.normalSampler = engine->_samplerManager->defaultLinear();
|
||||
materialResources.occlusionImage = engine->_whiteImage;
|
||||
materialResources.occlusionSampler = engine->_samplerManager->defaultLinear();
|
||||
materialResources.emissiveImage = engine->_blackImage;
|
||||
materialResources.emissiveSampler = engine->_samplerManager->defaultLinear();
|
||||
|
||||
// set the uniform buffer for the material data
|
||||
materialResources.dataBuffer = file.materialDataBuffer.buffer;
|
||||
@@ -389,6 +396,8 @@ std::optional<std::shared_ptr<LoadedGLTF> > loadGltf(VulkanEngine *engine, std::
|
||||
TextureCache::TextureHandle hColor = TextureCache::InvalidHandle;
|
||||
TextureCache::TextureHandle hMRO = TextureCache::InvalidHandle;
|
||||
TextureCache::TextureHandle hNorm = TextureCache::InvalidHandle;
|
||||
TextureCache::TextureHandle hOcc = TextureCache::InvalidHandle;
|
||||
TextureCache::TextureHandle hEmissive = TextureCache::InvalidHandle;
|
||||
|
||||
if (cache && mat.pbrData.baseColorTexture.has_value())
|
||||
{
|
||||
@@ -418,6 +427,35 @@ std::optional<std::shared_ptr<LoadedGLTF> > loadGltf(VulkanEngine *engine, std::
|
||||
}
|
||||
}
|
||||
|
||||
if (cache && mat.occlusionTexture.has_value())
|
||||
{
|
||||
const auto &tex = gltf.textures[mat.occlusionTexture->textureIndex];
|
||||
const size_t imgIndex = tex.imageIndex.value();
|
||||
const bool hasSampler = tex.samplerIndex.has_value();
|
||||
const VkSampler sampler = hasSampler ? file.samplers[tex.samplerIndex.value()] : engine->_samplerManager->defaultLinear();
|
||||
auto key = buildTextureKey(imgIndex, false);
|
||||
key.channels = TextureCache::TextureKey::ChannelsHint::R;
|
||||
if (key.hash != 0)
|
||||
{
|
||||
hOcc = cache->request(key, sampler);
|
||||
materialResources.occlusionSampler = sampler;
|
||||
}
|
||||
}
|
||||
|
||||
if (cache && mat.emissiveTexture.has_value())
|
||||
{
|
||||
const auto &tex = gltf.textures[mat.emissiveTexture->textureIndex];
|
||||
const size_t imgIndex = tex.imageIndex.value();
|
||||
const bool hasSampler = tex.samplerIndex.has_value();
|
||||
const VkSampler sampler = hasSampler ? file.samplers[tex.samplerIndex.value()] : engine->_samplerManager->defaultLinear();
|
||||
auto key = buildTextureKey(imgIndex, true);
|
||||
if (key.hash != 0)
|
||||
{
|
||||
hEmissive = cache->request(key, sampler);
|
||||
materialResources.emissiveSampler = sampler;
|
||||
}
|
||||
}
|
||||
|
||||
if (cache && mat.normalTexture.has_value())
|
||||
{
|
||||
const auto &tex = gltf.textures[mat.normalTexture.value().textureIndex];
|
||||
@@ -456,6 +494,16 @@ std::optional<std::shared_ptr<LoadedGLTF> > loadGltf(VulkanEngine *engine, std::
|
||||
cache->watchBinding(hNorm, newMat->data.materialSet, 3u, materialResources.normalSampler,
|
||||
engine->_flatNormalImage.imageView);
|
||||
}
|
||||
if (hOcc != TextureCache::InvalidHandle)
|
||||
{
|
||||
cache->watchBinding(hOcc, newMat->data.materialSet, 4u, materialResources.occlusionSampler,
|
||||
engine->_whiteImage.imageView);
|
||||
}
|
||||
if (hEmissive != TextureCache::InvalidHandle)
|
||||
{
|
||||
cache->watchBinding(hEmissive, newMat->data.materialSet, 5u, materialResources.emissiveSampler,
|
||||
engine->_blackImage.imageView);
|
||||
}
|
||||
}
|
||||
|
||||
data_index++;
|
||||
|
||||
Reference in New Issue
Block a user