ADD: emissive, occlusion

This commit is contained in:
2025-12-02 23:32:10 +09:00
parent d5ae159f73
commit f152f26cd1
20 changed files with 219 additions and 25 deletions

View File

@@ -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;

View File

@@ -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{};

View File

@@ -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);
});

View File

@@ -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;

View File

@@ -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()));
}