From 1c6f3f66904abd3d04f82d184f3e2f5f88440f41 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sun, 31 May 2026 14:56:12 -0700 Subject: [PATCH] Added primary directional light values to KRModelView Eliminated more direct calls to setPushConstant --- kraken/KRModelView.cpp | 40 +++++++++++++++++- kraken/KRModelView.h | 4 +- kraken/KRPipeline.cpp | 93 +++++------------------------------------- 3 files changed, 52 insertions(+), 85 deletions(-) diff --git a/kraken/KRModelView.cpp b/kraken/KRModelView.cpp index 1fa2077..15b8f20 100644 --- a/kraken/KRModelView.cpp +++ b/kraken/KRModelView.cpp @@ -33,12 +33,14 @@ #include "KRModelView.h" #include "KRViewport.h" +#include "nodes/KRDirectionalLight.h" using namespace hydra; -KRModelView::KRModelView(KRViewport* viewport, const hydra::Matrix4& matModel) +KRModelView::KRModelView(KRViewport* viewport, const hydra::Matrix4& matModel, KRDirectionalLight* directionalLight) : m_viewport(viewport) , m_matModel(matModel) + , m_directionalLight(directionalLight) { m_matModelInverse = matModel; m_matModelInverse.invert(); @@ -53,6 +55,24 @@ KRModelView::~KRModelView() bool KRModelView::getShaderValue(ShaderValue value, Vector3* output) const { + if (m_directionalLight) { + switch (value) { + case ShaderValue::light_direction_model_space: + { + Matrix4 inverseModelMatrix = m_matModel; + inverseModelMatrix.invert(); + + // Bind the light direction vector + Vector3 lightDirObject = Matrix4::Dot(inverseModelMatrix, m_directionalLight->getWorldLightDirection()); + lightDirObject.normalize(); + *output = lightDirObject; + return true; + } + default: + break; + } + } + switch (value) { case ShaderValue::camerapos_model_space: { @@ -72,6 +92,24 @@ bool KRModelView::getShaderValue(ShaderValue value, Vector3* output) const } bool KRModelView::getShaderValue(ShaderValue value, Matrix4* output) const { + if (m_directionalLight) { + switch (value) { + case ShaderValue::shadow_mvp1: + case ShaderValue::shadow_mvp2: + case ShaderValue::shadow_mvp3: + { + Matrix4 matBias; + matBias.translate(1.0, 1.0, 1.0); + matBias.scale(0.5); + int iShadow = static_cast(value) - static_cast(ShaderValue::shadow_mvp1); + *output = m_matModel * m_directionalLight->getShadowViewports()[iShadow].getViewProjectionMatrix() * matBias; + return true; + } + default: + break; + } + } + switch (value) { case ShaderValue::model_matrix: { diff --git a/kraken/KRModelView.h b/kraken/KRModelView.h index 556c712..375dfa6 100644 --- a/kraken/KRModelView.h +++ b/kraken/KRModelView.h @@ -38,12 +38,13 @@ #include "KRShaderReflection.h" class KRViewport; +class KRDirectionalLight; class KRModelView : public KRReflectedObject { public: - KRModelView(KRViewport* viewport, const hydra::Matrix4& matModel); + KRModelView(KRViewport* viewport, const hydra::Matrix4& matModel, KRDirectionalLight* directionalLight); ~KRModelView(); bool getShaderValue(ShaderValue value, hydra::Vector3* output) const final; @@ -52,6 +53,7 @@ public: private: KRViewport* m_viewport; hydra::Matrix4 m_matModel; + KRDirectionalLight* m_directionalLight; // Derived values hydra::Matrix4 m_matModelInverse; diff --git a/kraken/KRPipeline.cpp b/kraken/KRPipeline.cpp index a014400..0474b71 100644 --- a/kraken/KRPipeline.cpp +++ b/kraken/KRPipeline.cpp @@ -639,7 +639,15 @@ void KRPipeline::updateDescriptorBinding() void KRPipeline::updatePushConstants(KRNode::RenderInfo& ri, const Matrix4& matModel) { - KRModelView modelView(ri.viewport, matModel); + KRDirectionalLight* directionalLight = nullptr; + if (ri.renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_LIGHTS && ri.renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_GBUFFER && ri.renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_OPAQUE && ri.renderPass->getType() != RenderPassType::RENDER_PASS_SHADOWMAP) { + if (!ri.directional_lights.empty()) + { + directionalLight = ri.directional_lights.front(); + } + } + + KRModelView modelView(ri.viewport, matModel, directionalLight); ri.reflectedObjects.push_back(&modelView); ri.reflectedObjects.push_back(ri.viewport); @@ -652,88 +660,7 @@ void KRPipeline::updatePushConstants(KRNode::RenderInfo& ri, const Matrix4& matM ri.reflectedObjects.pop_back(); setPushConstant(ShaderValue::absolute_time, getContext().getAbsoluteTime()); - - int light_directional_count = 0; - //int light_point_count = 0; - //int light_spot_count = 0; - // TODO - Need to support multiple lights and more light types in forward rendering - if (ri.renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_LIGHTS && ri.renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_GBUFFER && ri.renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_OPAQUE && ri.renderPass->getType() != RenderPassType::RENDER_PASS_SHADOWMAP) { - - for (std::vector::const_iterator light_itr = ri.directional_lights.begin(); light_itr != ri.directional_lights.end(); light_itr++) { - KRDirectionalLight* directional_light = (*light_itr); - if (light_directional_count == 0) { - int cShadowBuffers = directional_light->getShadowBufferCount(); - if (hasPushConstant(ShaderValue::shadowtexture1) && cShadowBuffers > 0) { - // TODO - Vulkan Refactoring. Note: Sampler needs clamp-to-edge and linear filtering - if (m_pContext->getTextureManager()->selectTexture(0 /*GL_TEXTURE_2D*/, 3, directional_light->getShadowTextures()[0])) { - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); - } - } - - if (hasPushConstant(ShaderValue::shadowtexture2) && cShadowBuffers > 1 && ri.camera->settings.m_cShadowBuffers > 1) { - // TODO - Vulkan Refactoring. Note: Sampler needs clamp-to-edge and linear filtering - if (m_pContext->getTextureManager()->selectTexture(0 /*GL_TEXTURE_2D*/, 4, directional_light->getShadowTextures()[1])) { - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); - } - } - - if (hasPushConstant(ShaderValue::shadowtexture3) && cShadowBuffers > 2 && ri.camera->settings.m_cShadowBuffers > 2) { - // TODO - Vulkan Refactoring. Note: Sampler needs clamp-to-edge and linear filtering - if (m_pContext->getTextureManager()->selectTexture(0 /*GL_TEXTURE_2D*/, 5, directional_light->getShadowTextures()[2])) { - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); - } - } - - Matrix4 matBias; - matBias.translate(1.0, 1.0, 1.0); - matBias.scale(0.5); - for (int iShadow = 0; iShadow < cShadowBuffers; iShadow++) { - setPushConstant(static_cast(static_cast(ShaderValue::shadow_mvp1) + iShadow), matModel * directional_light->getShadowViewports()[iShadow].getViewProjectionMatrix() * matBias); - } - - if (hasPushConstant(ShaderValue::light_direction_model_space)) { - Matrix4 inverseModelMatrix = matModel; - inverseModelMatrix.invert(); - - // Bind the light direction vector - Vector3 lightDirObject = Matrix4::Dot(inverseModelMatrix, directional_light->getWorldLightDirection()); - lightDirObject.normalize(); - setPushConstant(ShaderValue::light_direction_model_space, lightDirObject); - } - } - - light_directional_count++; - } - - //light_point_count = point_lights.size(); - //light_spot_count = spot_lights.size(); - } - - // Sets the diffuseTexture variable to the first texture unit - setPushConstant(ShaderValue::diffusetexture, 0); - - // Sets the specularTexture variable to the second texture unit - setPushConstant(ShaderValue::speculartexture, 1); - - // Sets the normalTexture variable to the third texture unit - setPushConstant(ShaderValue::material_normal_map_texture, 2); - - // Sets the shadowTexture variable to the fourth texture unit - setPushConstant(ShaderValue::shadowtexture1, 3); - setPushConstant(ShaderValue::shadowtexture2, 4); - setPushConstant(ShaderValue::shadowtexture3, 5); - setPushConstant(ShaderValue::reflectioncubetexture, 4); - setPushConstant(ShaderValue::lightmaptexture, 5); - setPushConstant(ShaderValue::gbuffer_frame, 6); - setPushConstant(ShaderValue::gbuffer_depth, 7); // Texture unit 7 is used for reading the depth buffer in gBuffer pass #2 and in post-processing pass - // setPushConstant(ShaderValue::reflectiontexture, 7); // Texture unit 7 is used for the reflection map textures in gBuffer pass #3 and when using forward rendering - setPushConstant(ShaderValue::depth_frame, 0); - setPushConstant(ShaderValue::render_frame, 1); - setPushConstant(ShaderValue::volumetric_environment_frame, 2); - + for (StageInfo& stageInfo : m_stages) { PushConstantInfo& pushConstants = stageInfo.pushConstants; if (pushConstants.buffer) {