From b5b3aa028e87099b723e798f008ab94f6ffc7ab6 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sun, 31 Aug 2025 16:17:21 -0700 Subject: [PATCH] WIP Implementing Reflection for lighting and particle systems --- kraken/KRShaderReflection.cpp | 2 + kraken/KRShaderReflection.h | 2 + kraken/nodes/KRDirectionalLight.cpp | 6 ++- kraken/nodes/KRLight.cpp | 47 +++++++++++++++++++--- kraken/nodes/KRLight.h | 7 +++- kraken/nodes/KRParticleSystemNewtonian.cpp | 5 ++- kraken/nodes/KRPointLight.cpp | 17 +++++--- kraken/nodes/KRPointLight.h | 4 ++ 8 files changed, 75 insertions(+), 15 deletions(-) diff --git a/kraken/KRShaderReflection.cpp b/kraken/KRShaderReflection.cpp index d7a0365..c7565f6 100644 --- a/kraken/KRShaderReflection.cpp +++ b/kraken/KRShaderReflection.cpp @@ -48,6 +48,8 @@ const char* SHADER_VALUE_NAMES[] = { "light_cutoff", // PushConstant::light_cutoff "light_intensity", // PushConstant::light_intensity "flare_size", // PushConstant::flare_size + "dust_particle_size", // PushConstant::dust_particle_size + "dust_particle_color", // PushConstant::dust_particle_color "view_space_model_origin", // PushConstant::view_space_model_origin "mvp_matrix", // PushConstant::mvp "inv_projection_matrix", // PushConstant::invp diff --git a/kraken/KRShaderReflection.h b/kraken/KRShaderReflection.h index 2269099..2a01cd3 100644 --- a/kraken/KRShaderReflection.h +++ b/kraken/KRShaderReflection.h @@ -67,6 +67,8 @@ enum class ShaderValue : uint8_t light_cutoff, light_intensity, flare_size, + dust_particle_size, + dust_particle_color, view_space_model_origin, mvp, invp, diff --git a/kraken/nodes/KRDirectionalLight.cpp b/kraken/nodes/KRDirectionalLight.cpp index b7121c0..02c1e11 100755 --- a/kraken/nodes/KRDirectionalLight.cpp +++ b/kraken/nodes/KRDirectionalLight.cpp @@ -130,6 +130,8 @@ void KRDirectionalLight::render(RenderInfo& ri) if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; + ri.reflectedObjects.push_back(this); + KRLight::render(ri); if (ri.renderPass->getType() == RenderPassType::RENDER_PASS_DEFERRED_LIGHTS) { @@ -161,14 +163,14 @@ void KRDirectionalLight::render(RenderInfo& ri) KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); pShader->setPushConstant(ShaderValue::light_direction_view_space, light_direction_view_space); - pShader->setPushConstant(ShaderValue::light_color, m_color); - pShader->setPushConstant(ShaderValue::light_intensity, m_intensity * 0.01f); pShader->bind(ri, getModelMatrix()); // TODO: Need to pass in the light index to the shader // Render a full screen quad m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &vertices, 1.0f); vkCmdDraw(ri.commandBuffer, 4, 1, 0, 0); } + + ri.reflectedObjects.pop_back(); } AABB KRDirectionalLight::getBounds() diff --git a/kraken/nodes/KRLight.cpp b/kraken/nodes/KRLight.cpp index b95539c..11c9eb0 100755 --- a/kraken/nodes/KRLight.cpp +++ b/kraken/nodes/KRLight.cpp @@ -200,7 +200,7 @@ void KRLight::setIntensity(float intensity) { m_intensity = intensity; } -float KRLight::getIntensity() +float KRLight::getIntensity() const { return m_intensity; } @@ -220,7 +220,7 @@ void KRLight::setDecayStart(float decayStart) m_decayStart = decayStart; } -float KRLight::getDecayStart() +float KRLight::getDecayStart() const { return m_decayStart; } @@ -232,6 +232,8 @@ void KRLight::render(RenderInfo& ri) KRNode::render(ri); + ri.reflectedObjects.push_back(this); + if (ri.renderPass->getType() == RenderPassType::RENDER_PASS_SHADOWMAP && (ri.camera->settings.volumetric_environment_enable || ri.camera->settings.dust_particle_enable || (ri.camera->settings.m_cShadowBuffers > 0 && m_casts_shadow))) { allocateShadowBuffers(configureShadowBufferViewports(*ri.viewport)); renderShadowBuffers(ri); @@ -284,9 +286,8 @@ void KRLight::render(RenderInfo& ri) info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; KRPipeline* pParticleShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info); - pParticleShader->setPushConstant(ShaderValue::light_color, m_color * ri.camera->settings.dust_particle_intensity * m_dust_particle_intensity * m_intensity); + pParticleShader->setPushConstant(ShaderValue::dust_particle_color, m_color * ri.camera->settings.dust_particle_intensity * m_dust_particle_intensity * m_intensity); pParticleShader->setPushConstant(ShaderValue::particle_origin, Matrix4::DotWDiv(Matrix4::Invert(particleModelMatrix), Vector3::Zero())); - pParticleShader->setPushConstant(ShaderValue::flare_size, m_dust_particle_size); pParticleShader->bind(ri, particleModelMatrix); // TODO: Pass light index to shader m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &m_pContext->getMeshManager()->KRENGINE_VBO_DATA_RANDOM_PARTICLES, 1.0f); @@ -427,7 +428,6 @@ void KRLight::render(RenderInfo& ri) KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); pShader->setPushConstant(ShaderValue::material_alpha, 1.0f); - pShader->setPushConstant(ShaderValue::flare_size, m_flareSize); pShader->setImageBinding("diffuseTexture", m_pFlareTexture, getContext().getSamplerManager()->DEFAULT_CLAMPED_SAMPLER); pShader->bind(ri, getModelMatrix()); @@ -439,6 +439,7 @@ void KRLight::render(RenderInfo& ri) } } + ri.reflectedObjects.pop_back(); } void KRLight::allocateShadowBuffers(int cBuffers) @@ -575,3 +576,39 @@ KRViewport* KRLight::getShadowViewports() { return m_shadowViewports; } + +bool KRLight::getShaderValue(ShaderValue value, float* output) const +{ + switch (value) { + case ShaderValue::light_intensity: + *output = m_intensity * 0.01f; + return true; + case ShaderValue::light_decay_start: + *output = getDecayStart(); + return true; + case ShaderValue::light_cutoff: + *output = KRLIGHT_MIN_INFLUENCE; + return true; + case ShaderValue::flare_size: + *output = m_flareSize; + return true; + case ShaderValue::dust_particle_size: + *output = m_dust_particle_size; + return true; + + } + return KRNode::getShaderValue(value, output); +} + +bool KRLight::getShaderValue(ShaderValue value, hydra::Vector3* output) const +{ + switch (value) { + case ShaderValue::light_position: + *output = m_localTranslation; + return true; + case ShaderValue::light_color: + *output = m_color; + return true; + } + return KRNode::getShaderValue(value, output); +} diff --git a/kraken/nodes/KRLight.h b/kraken/nodes/KRLight.h index bd9fe68..c04575f 100755 --- a/kraken/nodes/KRLight.h +++ b/kraken/nodes/KRLight.h @@ -53,9 +53,9 @@ public: virtual void loadXML(tinyxml2::XMLElement* e); void setIntensity(float intensity); - float getIntensity(); + float getIntensity() const; void setDecayStart(float decayStart); - float getDecayStart(); + float getDecayStart() const; const hydra::Vector3& getColor(); void setColor(const hydra::Vector3& color); @@ -74,6 +74,9 @@ public: protected: KRLight(KRScene& scene, std::string name); + bool getShaderValue(ShaderValue value, float* output) const override; + bool getShaderValue(ShaderValue value, hydra::Vector3* output) const override; + float m_intensity; float m_decayStart; hydra::Vector3 m_color; diff --git a/kraken/nodes/KRParticleSystemNewtonian.cpp b/kraken/nodes/KRParticleSystemNewtonian.cpp index e6943ba..273da46 100755 --- a/kraken/nodes/KRParticleSystemNewtonian.cpp +++ b/kraken/nodes/KRParticleSystemNewtonian.cpp @@ -85,6 +85,8 @@ void KRParticleSystemNewtonian::render(RenderInfo& ri) if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; + ri.reflectedObjects.push_back(this); + KRNode::render(ri); if (ri.renderPass->getType() == RenderPassType::RENDER_PASS_ADDITIVE_PARTICLES) { @@ -105,7 +107,7 @@ void KRParticleSystemNewtonian::render(RenderInfo& ri) info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; KRPipeline* pParticleShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info); - pParticleShader->setPushConstant(ShaderValue::flare_size, 1.0f); + pParticleShader->setPushConstant(ShaderValue::dust_particle_size, 1.0f); pParticleShader->bind(ri, getModelMatrix()); m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &m_pContext->getMeshManager()->KRENGINE_VBO_DATA_RANDOM_PARTICLES, 1.0f); @@ -113,4 +115,5 @@ void KRParticleSystemNewtonian::render(RenderInfo& ri) vkCmdDraw(ri.commandBuffer, particle_count * 3, 1, 0, 0); } } + ri.reflectedObjects.pop_back(); } diff --git a/kraken/nodes/KRPointLight.cpp b/kraken/nodes/KRPointLight.cpp index 50421de..21029d9 100755 --- a/kraken/nodes/KRPointLight.cpp +++ b/kraken/nodes/KRPointLight.cpp @@ -77,6 +77,8 @@ void KRPointLight::render(RenderInfo& ri) { if (m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; + ri.reflectedObjects.push_back(this); + KRLight::render(ri); bool bVisualize = ri.renderPass->getType() == RenderPassType::RENDER_PASS_FORWARD_TRANSPARENT && ri.camera->settings.bShowDeferred; @@ -116,11 +118,6 @@ void KRPointLight::render(RenderInfo& ri) info.modelFormat = bInsideLight ? ModelFormat::KRENGINE_MODEL_FORMAT_STRIP : ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info); - pShader->setPushConstant(ShaderValue::light_color, m_color); - pShader->setPushConstant(ShaderValue::light_intensity, m_intensity * 0.01f); - pShader->setPushConstant(ShaderValue::light_decay_start, getDecayStart()); - pShader->setPushConstant(ShaderValue::light_cutoff, KRLIGHT_MIN_INFLUENCE); - pShader->setPushConstant(ShaderValue::light_position, light_position); pShader->bind(ri, sphereModelMatrix); // TODO: Pass light index to shader if (bInsideLight) { @@ -138,6 +135,16 @@ void KRPointLight::render(RenderInfo& ri) } } + ri.reflectedObjects.pop_back(); +} + +bool KRPointLight::getShaderValue(ShaderValue value, float* output) const +{ + return KRLight::getShaderValue(value, output); +} +bool KRPointLight::getShaderValue(ShaderValue value, hydra::Vector3* output) const +{ + return KRLight::getShaderValue(value, output); } void KRPointLight::generateMesh() diff --git a/kraken/nodes/KRPointLight.h b/kraken/nodes/KRPointLight.h index 30f4c77..2ecd83a 100755 --- a/kraken/nodes/KRPointLight.h +++ b/kraken/nodes/KRPointLight.h @@ -45,6 +45,10 @@ public: virtual void render(RenderInfo& ri) override; +protected: + bool getShaderValue(ShaderValue value, float* output) const override; + bool getShaderValue(ShaderValue value, hydra::Vector3* output) const override; + private: void generateMesh();