Skip to content

[#191] integrate IBL ambient lighting in PBR fragment shader (#191)#230

Open
FriedricNietzsche wants to merge 17 commits into
mainfrom
191-pbr-ibl-ambient-lighting
Open

[#191] integrate IBL ambient lighting in PBR fragment shader (#191)#230
FriedricNietzsche wants to merge 17 commits into
mainfrom
191-pbr-ibl-ambient-lighting

Conversation

@FriedricNietzsche
Copy link
Copy Markdown
Collaborator

  • Add IBL texture descriptors (bindings 13-18) to shader_pbr.slang: irradiance cubemap, prefilter cubemap, and BRDF LUT with samplers
  • Implement indirect diffuse lighting by sampling irradiance map with surface normal
  • Implement indirect specular lighting using split-sum approximation: prefilter map sampled at reflection direction/roughness mip level, combined with BRDF LUT scale+bias
  • Add fresnelSchlickRoughness() for roughness-aware IBL Fresnel
  • Replace constant ambient (0.03) with mathematically combined direct Cook-Torrance + indirect IBL lighting
  • Update Renderer.hpp descriptor set layout to include IBL bindings
  • Create default black cubemap + linear-clamp sampler as IBL fallbacks
  • Add setIBLMaps() method to update descriptors with real IBL maps

- Add IBL texture descriptors (bindings 13-18) to shader_pbr.slang:
  irradiance cubemap, prefilter cubemap, and BRDF LUT with samplers
- Implement indirect diffuse lighting by sampling irradiance map with
  surface normal
- Implement indirect specular lighting using split-sum approximation:
  prefilter map sampled at reflection direction/roughness mip level,
  combined with BRDF LUT scale+bias
- Add fresnelSchlickRoughness() for roughness-aware IBL Fresnel
- Replace constant ambient (0.03) with mathematically combined
  direct Cook-Torrance + indirect IBL lighting
- Update Renderer.hpp descriptor set layout to include IBL bindings
- Create default black cubemap + linear-clamp sampler as IBL fallbacks
- Add setIBLMaps() method to update descriptors with real IBL maps
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Integrates image-based lighting (IBL) into the existing Cook–Torrance PBR fragment shader and wires the necessary Vulkan descriptors/resources in the renderer so ambient lighting comes from irradiance/prefilter/BRDF LUT maps instead of a constant.

Changes:

  • Added IBL texture/sampler bindings (13–18) to the PBR shader and implemented split-sum indirect diffuse/specular.
  • Extended Renderer descriptor set layout/pool/writes to include the IBL bindings.
  • Added default fallback IBL resources (black cubemap + linear clamp sampler) and a setIBLMaps() method to update descriptors with generated IBL maps.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
shaders/shader_pbr.slang Adds IBL bindings and computes indirect diffuse/specular lighting (replaces constant ambient).
include/app/Renderer.hpp Adds descriptor bindings 13–18, allocates default IBL resources, and provides setIBLMaps() to update descriptors.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread shaders/shader_pbr.slang Outdated
Comment thread include/app/Renderer.hpp
Comment on lines +668 to +675
ImageUtils::createImage(
physicalDevice, logicalDevice, 1, 1,
vk::Format::eR8G8B8A8Unorm, vk::ImageTiling::eOptimal,
vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled,
vk::MemoryPropertyFlagBits::eDeviceLocal,
defaultCubemap, defaultCubemapMemory,
1, 6, vk::ImageCreateFlagBits::eCubeCompatible
);
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fallback cubemap is created with only 1 mip level (mipLevels = 1), but the PBR shader samples the prefilter map with explicit LOD up to 4 (SampleLevel(..., roughness * 4)). When IBL maps haven’t been set yet and the fallback is bound, this can result in sampling non-existent mip levels (undefined results / validation errors). Either create the default prefilter cubemap with 5 mip levels (and initialize all mips to black), or ensure the shader never requests LOD > 0 for the fallback.

Copilot uses AI. Check for mistakes.
Comment thread include/app/Renderer.hpp
Comment on lines +734 to +745
// IBL sampler: linear filtering, clamp-to-edge
vk::SamplerCreateInfo iblSamplerInfo {
.magFilter = vk::Filter::eLinear,
.minFilter = vk::Filter::eLinear,
.mipmapMode = vk::SamplerMipmapMode::eLinear,
.addressModeU = vk::SamplerAddressMode::eClampToEdge,
.addressModeV = vk::SamplerAddressMode::eClampToEdge,
.addressModeW = vk::SamplerAddressMode::eClampToEdge,
.minLod = 0.0f,
.maxLod = 4.0f, // prefilter map has 5 mip levels
};
iblSampler = vk::raii::Sampler{ *logicalDevice, iblSamplerInfo };
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iblSamplerInfo.maxLod is set to 4.0 with a comment stating the prefilter map has 5 mip levels, but createDefaultIBLTextures() currently creates the default cubemap with only 1 mip. This mismatch can hide problems during development and contributes to invalid LOD sampling for the fallback. Update the default cubemap’s mip count (or clamp the sampler/shader LOD) so these values stay consistent.

Copilot uses AI. Check for mistakes.
@FriedricNietzsche FriedricNietzsche changed the title feat: integrate IBL ambient lighting in PBR fragment shader (#191) [#191] integrate IBL ambient lighting in PBR fragment shader (#191) Mar 10, 2026
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@rowel-eshan
Copy link
Copy Markdown
Collaborator

The descriptor sets that you are working with here needs to be changed to reflect the new multiset descriptors. Merge main into your branch.

…escriptors

Resolve conflicts to align IBL ambient lighting with the new multiset
descriptor layout from main (Set 0: per-frame, Set 1: environment/IBL,
Set 2: material). Updated shader to use combined image samplers
(SamplerCube/Sampler2D) instead of separate Texture+SamplerState pairs.
Updated Renderer IBL fallbacks to use proper cubemap views and rewrote
setIBLMaps() to write to environmentDescriptorSets with combined image
sampler descriptors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@FriedricNietzsche
Copy link
Copy Markdown
Collaborator Author

FriedricNietzsche commented Mar 16, 2026

Merged with main and fixed conflicts in shader_pbr.slang and Renderer.hpp. Also fixed some things that needed updating to match the new archetek. Should be good now.

Shader:

  • Adopted the multiset descriptor layout (Set 0: Global, Set 1: IBL, Set 2: Material)
  • Removed duplicate single-set bindings (old bindings 3-18 in set 0)
  • Updated IBL sampling to use combined image samplers (irradianceMap.Sample(N) instead of irradianceMap.Sample(irradianceSampler, N), etc.)
  • Kept all IBL lighting logic (fresnelSchlickRoughness, indirect diffuse/specular)

Renderer

  • Took main's multiset descriptor layout and pool sizes (combined image samplers)
  • Fixed IBL fallback to use proper cubemap views (defaultCubemapView + iblSampler) for irradiance/prefilter, and 2D view for - BRDF LUT
  • Rewrote setIBLMaps() to write 3 combined image sampler descriptors to environmentDescriptorSets[0] (bindings 0-2) instead of 6 separate image/sampler writes to the old single set
  • Kept default cubemap resources and offscreen/post-process resources from both branches

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 88 out of 92 changed files in this pull request and generated 11 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread src/physics/SphereBVH.cpp Outdated
}

// Combine every BVH into a large one or the scene
return SphereBVH(buildBVH(spheres, 0, entities.size()));
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Comment thread include/app/ui/components/SettingsWindow.hpp Outdated
Comment on lines +368 to +370
const uint32_t lightCount = 0;
cmd.pushConstants<uint32_t>(pRenderer->getPipeline().getLayout(),
vk::ShaderStageFlagBits::eFragment, 0, lightCount);
Comment thread src/physics/SphereBVH.cpp Outdated
Comment on lines +296 to +298
bool SphereBVHNode::isLeaf() const {
return left == nullptr && right == nullptr;
}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Comment thread src/physics/SphereBVH.cpp Outdated
Comment on lines +138 to +145
bool SphereBVHNode::checkCollision(const Collider& collider, std::vector<ContactInfo>& info) const {
if (!this->sphere.checkCollision(collider, info)) {
return false;
}

return this->left->sphere.checkCollision(collider, info)
|| this->right->sphere.checkCollision(collider, info);
}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

@@ -0,0 +1,155 @@
{
Comment thread include/editor/EditorApp.hpp Outdated
Comment on lines +11 to +42
#include <string>
#include <vector>

#include <memory>
#include <chrono>
#include <filesystem>
#include <string>
#include <vector>


#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <app/Instance.hpp>
#include <app/PhysicalDevice.hpp>
#include <app/LogicalDevice.hpp>
#include <app/RenderSurface.hpp>
#include <app/Renderer.hpp>
#include <app/Scene.hpp>
#include <app/ImGuiRenderer.hpp>

#include <editor/SelectionManager.hpp>
#include <editor/EditorCamera.hpp>
#include <editor/OffscreenFramebuffer.hpp>
#include <editor/gizmos/Gizmo.hpp>

#include <app/Settings.hpp>
#include <app/Log.hpp>

#include <memory>
#include <chrono>
#include <filesystem>
Comment thread src/physics/SphereBVH.cpp
const auto &indices = mesh.getIndices();

if (indices.empty() || vertices.empty()) {
return;
Comment thread src/physics/SphereBVH.cpp Outdated
Comment on lines +338 to +358
};

glm::vec3 extent = centroidMax - centroidMin;
int axis = 0;
if (extent.y > extent.x) axis = 1;
if (extent.z > extent[axis]) axis = 2;

size_t mid = start + count / 2;
std::nth_element(triangles.begin() + start,
triangles.begin() + mid,
triangles.begin() + end,
[axis](const TriangleInfo &a, const TriangleInfo &b) {
return a.centroid[axis] < b.centroid[axis];
});

node->left = buildRecursive(triangles, start, mid);
node->right = buildRecursive(triangles, mid, end);

return node;
}
};
Copy link
Copy Markdown

Copilot AI commented Mar 16, 2026

@FriedricNietzsche I've opened a new pull request, #233, to work on those changes. Once the pull request is ready, I'll request review from you.

FriedricNietzsche and others added 3 commits March 16, 2026 18:13
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…ze()

Co-authored-by: FriedricNietzsche <142739679+FriedricNietzsche@users.noreply.github.com>
Copy link
Copy Markdown

Copilot AI commented Mar 16, 2026

@FriedricNietzsche I've opened a new pull request, #234, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Copy Markdown

Copilot AI commented Mar 16, 2026

@FriedricNietzsche I've opened a new pull request, #235, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Copy Markdown

Copilot AI commented Mar 16, 2026

@FriedricNietzsche I've opened a new pull request, #236, to work on those changes. Once the pull request is ready, I'll request review from you.

FriedricNietzsche and others added 2 commits March 16, 2026 18:14
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: FriedricNietzsche <142739679+FriedricNietzsche@users.noreply.github.com>
Copilot AI and others added 6 commits March 16, 2026 22:18
…olve

Co-authored-by: FriedricNietzsche <142739679+FriedricNietzsche@users.noreply.github.com>
Co-authored-by: FriedricNietzsche <142739679+FriedricNietzsche@users.noreply.github.com>
Fix out-of-bounds end index in SphereBVH::fromScene
Remove duplicate `SphereBVHNode::isLeaf()` definition
Fix SphereBVHNode::checkCollision null deref crash on leaf nodes
Fix BendConstraint::solve signature mismatch with base class
@P0k3rf4ce P0k3rf4ce changed the base branch from pbr-dev to main March 16, 2026 22:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants