From 51534da4315930b259435c68a3af6cca64ab1a90 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sun, 31 Aug 2025 00:30:15 -0700 Subject: [PATCH] Shader reflection now using ShaderValueType --- kraken/KRModelView.cpp | 127 +++++++++++++++++----------------- kraken/KRModelView.h | 3 +- kraken/KRPipeline.cpp | 25 +++---- kraken/KRShaderReflection.cpp | 80 +++++++++++++++++++++ kraken/KRShaderReflection.h | 17 ++++- kraken/KRViewport.cpp | 53 +++++++------- kraken/KRViewport.h | 3 +- 7 files changed, 201 insertions(+), 107 deletions(-) diff --git a/kraken/KRModelView.cpp b/kraken/KRModelView.cpp index b4250c3..2654096 100644 --- a/kraken/KRModelView.cpp +++ b/kraken/KRModelView.cpp @@ -51,84 +51,81 @@ KRModelView::~KRModelView() } -bool KRModelView::getShaderValue(ShaderValue value, void* buffer, size_t size) const +bool KRModelView::getShaderValue(ShaderValue value, Vector3* output) const { - if (size == sizeof(Vector3)) { + switch (value) { case ShaderValue::camerapos_model_space: { // Transform location of camera to object space for calculation of specular halfVec - Vector3 cameraPosObject = Matrix4::Dot(m_matModelInverse, m_viewport->getCameraPosition()); - memcpy(buffer, &cameraPosObject, sizeof(Vector3)); + *output = Matrix4::Dot(m_matModelInverse, m_viewport->getCameraPosition()); return true; } case ShaderValue::view_space_model_origin: { // Origin point of model space is the light source position. No perspective, so no w divide required - Vector3 viewSpaceModelOrigin = Matrix4::Dot(m_matModelView, Vector3::Zero()); - memcpy(buffer, &viewSpaceModelOrigin, sizeof(Vector3)); + *output = Matrix4::Dot(m_matModelView, Vector3::Zero()); return true; } } - } - - if (size == sizeof(Matrix4)) { - switch (value) { - case ShaderValue::model_matrix: - { - memcpy(buffer, &m_matModel, sizeof(Matrix4)); - return true; - } - case ShaderValue::model_view: - { - memcpy(buffer, &m_matModelView, sizeof(Matrix4)); - return true; - } - case ShaderValue::model_view_inverse_transpose: - { - Matrix4 matModelViewInverseTranspose = m_matModelView; - matModelViewInverseTranspose.transpose(); - matModelViewInverseTranspose.invert(); - memcpy(buffer, &matModelViewInverseTranspose, sizeof(Matrix4)); - return true; - } - case ShaderValue::model_inverse_transpose: - { - Matrix4 matModelInverseTranspose = m_matModel; - matModelInverseTranspose.transpose(); - matModelInverseTranspose.invert(); - memcpy(buffer, &matModelInverseTranspose, sizeof(Matrix4)); - return true; - } - case ShaderValue::invmvp_no_translate: - { - Matrix4 matInvMVPNoTranslate = m_matModelView; - // Remove the translation - matInvMVPNoTranslate.getPointer()[3] = 0; - matInvMVPNoTranslate.getPointer()[7] = 0; - matInvMVPNoTranslate.getPointer()[11] = 0; - matInvMVPNoTranslate.getPointer()[12] = 0; - matInvMVPNoTranslate.getPointer()[13] = 0; - matInvMVPNoTranslate.getPointer()[14] = 0; - matInvMVPNoTranslate.getPointer()[15] = 1.0; - matInvMVPNoTranslate = matInvMVPNoTranslate * m_viewport->getProjectionMatrix(); - matInvMVPNoTranslate.invert(); - memcpy(buffer, &matInvMVPNoTranslate, sizeof(Matrix4)); - return true; - } - case ShaderValue::mvp: - { - Matrix4 mvpMatrix = m_matModel * m_viewport->getViewProjectionMatrix(); - memcpy(buffer, &mvpMatrix, sizeof(Matrix4)); - return true; - } - case ShaderValue::invmvp: - { - Matrix4 mvpMatrix = m_matModel * m_viewport->getViewProjectionMatrix(); - Matrix4 invMVP = Matrix4::Invert(mvpMatrix); - memcpy(buffer, &invMVP, sizeof(Matrix4)); - return true; - } +} +bool KRModelView::getShaderValue(ShaderValue value, Matrix4* output) const +{ + switch (value) { + case ShaderValue::model_matrix: + { + *output = m_matModel; + return true; + } + case ShaderValue::model_view: + { + *output = m_matModelView; + return true; + } + case ShaderValue::model_view_inverse_transpose: + { + Matrix4 matModelViewInverseTranspose = m_matModelView; + matModelViewInverseTranspose.transpose(); + matModelViewInverseTranspose.invert(); + *output = matModelViewInverseTranspose; + return true; + } + case ShaderValue::model_inverse_transpose: + { + Matrix4 matModelInverseTranspose = m_matModel; + matModelInverseTranspose.transpose(); + matModelInverseTranspose.invert(); + *output = matModelInverseTranspose; + return true; + } + case ShaderValue::invmvp_no_translate: + { + Matrix4 matInvMVPNoTranslate = m_matModelView; + // Remove the translation + matInvMVPNoTranslate.getPointer()[3] = 0; + matInvMVPNoTranslate.getPointer()[7] = 0; + matInvMVPNoTranslate.getPointer()[11] = 0; + matInvMVPNoTranslate.getPointer()[12] = 0; + matInvMVPNoTranslate.getPointer()[13] = 0; + matInvMVPNoTranslate.getPointer()[14] = 0; + matInvMVPNoTranslate.getPointer()[15] = 1.0; + matInvMVPNoTranslate = matInvMVPNoTranslate * m_viewport->getProjectionMatrix(); + matInvMVPNoTranslate.invert(); + *output = matInvMVPNoTranslate; + return true; + } + case ShaderValue::mvp: + { + Matrix4 mvpMatrix = m_matModel * m_viewport->getViewProjectionMatrix(); + *output = mvpMatrix; + return true; + } + case ShaderValue::invmvp: + { + Matrix4 mvpMatrix = m_matModel * m_viewport->getViewProjectionMatrix(); + Matrix4 invMVP = Matrix4::Invert(mvpMatrix); + *output = invMVP; + return true; } } diff --git a/kraken/KRModelView.h b/kraken/KRModelView.h index d3ac7e7..5782e7d 100644 --- a/kraken/KRModelView.h +++ b/kraken/KRModelView.h @@ -46,7 +46,8 @@ public: KRModelView(KRViewport* viewport, const hydra::Matrix4& matModel); ~KRModelView(); - bool getShaderValue(ShaderValue value, void* buffer, size_t size) const final; + bool getShaderValue(ShaderValue value, hydra::Vector3* output) const final; + bool getShaderValue(ShaderValue value, hydra::Matrix4* output) const final; private: KRViewport* m_viewport; diff --git a/kraken/KRPipeline.cpp b/kraken/KRPipeline.cpp index a0b58b2..48615ef 100644 --- a/kraken/KRPipeline.cpp +++ b/kraken/KRPipeline.cpp @@ -456,21 +456,22 @@ void KRPipeline::initPushConstantStage(ShaderStage stage, const SpvReflectShader pushConstants.type[iUniform] = ShaderValueType::type_vector4; break; } - } - if (member.type_description->op == SpvOpTypeFloat && member.numeric.scalar.width == 32) { + } else if (member.type_description->op == SpvOpTypeFloat && member.numeric.scalar.width == 32) { pushConstants.type[iUniform] = ShaderValueType::type_float32; - } - if (member.type_description->op == SpvOpTypeFloat && member.numeric.scalar.width == 64) { + } else if (member.type_description->op == SpvOpTypeFloat && member.numeric.scalar.width == 64) { pushConstants.type[iUniform] = ShaderValueType::type_float64; - } - if (member.type_description->op == SpvOpTypeInt && member.numeric.scalar.width == 32) { + } else if (member.type_description->op == SpvOpTypeInt && member.numeric.scalar.width == 32) { pushConstants.type[iUniform] = ShaderValueType::type_int32; - } - if (member.type_description->op == SpvOpTypeInt && member.numeric.scalar.width == 64) { + } else if (member.type_description->op == SpvOpTypeInt && member.numeric.scalar.width == 64) { pushConstants.type[iUniform] = ShaderValueType::type_int64; - } - if (member.type_description->op == SpvOpTypeMatrix && member.numeric.scalar.width == 32 && member.numeric.matrix.column_count == 4 && member.numeric.matrix.row_count == 4) { - pushConstants.type[iUniform] = ShaderValueType::type_matrix4; + } else if (member.type_description->op == SpvOpTypeMatrix && member.numeric.scalar.width == 32) { + if (member.numeric.matrix.column_count == 2 && member.numeric.matrix.row_count == 2) { + pushConstants.type[iUniform] = ShaderValueType::type_matrix2; + } else if (member.numeric.matrix.column_count == 2 && member.numeric.matrix.row_count == 3) { + pushConstants.type[iUniform] = ShaderValueType::type_matrix2x3; + } else if (member.numeric.matrix.column_count == 4 && member.numeric.matrix.row_count == 4) { + pushConstants.type[iUniform] = ShaderValueType::type_matrix4; + } } // TODO: Support unsigned integer binding? } @@ -539,7 +540,7 @@ void KRPipeline::setPushConstants(const std::vector ob if (size != 0) { void* constant = (pushConstants.buffer + pushConstants.offset[static_cast(i)]); for (const KRReflectedObject* object : objects) { - if (object->getShaderValue(static_cast(i), constant, size)) { + if (object->getShaderValue(static_cast(i), pushConstants.type[static_cast(i)], constant)) { break; } } diff --git a/kraken/KRShaderReflection.cpp b/kraken/KRShaderReflection.cpp index 2893ddb..5a926ee 100644 --- a/kraken/KRShaderReflection.cpp +++ b/kraken/KRShaderReflection.cpp @@ -31,6 +31,8 @@ #include "KRShaderReflection.h" +using namespace hydra; + const char* SHADER_VALUE_NAMES[] = { "material_ambient", // PushConstant::material_ambient "material_diffuse", // PushConstant::material_diffuse @@ -100,3 +102,81 @@ const char* SHADER_VALUE_NAMES[] = { "rim_power", // PushConstant::rim_power "fade_color", // PushConstant::fade_color }; + +bool KRReflectedObject::getShaderValue(ShaderValue value, ShaderValueType type, void* output) const +{ + switch (type) { + case ShaderValueType::type_int32: + return getShaderValue(value, static_cast(output)); + case ShaderValueType::type_int64: + return getShaderValue(value, static_cast(output)); + case ShaderValueType::type_float32: + return getShaderValue(value, static_cast(output)); + case ShaderValueType::type_float64: + return getShaderValue(value, static_cast(output)); + case ShaderValueType::type_vector2: + return getShaderValue(value, static_cast(output)); + case ShaderValueType::type_vector3: + return getShaderValue(value, static_cast(output)); + case ShaderValueType::type_vector4: + return getShaderValue(value, static_cast(output)); + case ShaderValueType::type_matrix2: + return getShaderValue(value, static_cast(output)); + case ShaderValueType::type_matrix2x3: + return getShaderValue(value, static_cast(output)); + case ShaderValueType::type_matrix4: + return getShaderValue(value, static_cast(output)); + default: + return false; + } +} + +bool KRReflectedObject::getShaderValue(ShaderValue value, int32_t* output) const +{ + return false; +} + +bool KRReflectedObject::getShaderValue(ShaderValue value, int64_t* output) const +{ + return false; +} + +bool KRReflectedObject::getShaderValue(ShaderValue value, float* output) const +{ + return false; +} + +bool KRReflectedObject::getShaderValue(ShaderValue value, double* output) const +{ + return false; +} + +bool KRReflectedObject::getShaderValue(ShaderValue value, hydra::Vector2* output) const +{ + return false; +} + +bool KRReflectedObject::getShaderValue(ShaderValue value, hydra::Vector3* output) const +{ + return false; +} + +bool KRReflectedObject::getShaderValue(ShaderValue value, hydra::Vector4* output) const +{ + return false; +} + +bool KRReflectedObject::getShaderValue(ShaderValue value, hydra::Matrix2* output) const +{ + return false; +} + +bool KRReflectedObject::getShaderValue(ShaderValue value, hydra::Matrix2x3* output) const +{ + return false; +} + +bool KRReflectedObject::getShaderValue(ShaderValue value, hydra::Matrix4* output) const +{ + return false; +} diff --git a/kraken/KRShaderReflection.h b/kraken/KRShaderReflection.h index b402dab..824ca8c 100644 --- a/kraken/KRShaderReflection.h +++ b/kraken/KRShaderReflection.h @@ -33,6 +33,7 @@ #pragma once #include +#include "hydra.h" enum class ShaderValueType : uint8_t { @@ -44,6 +45,8 @@ enum class ShaderValueType : uint8_t type_vector2, type_vector3, type_vector4, + type_matrix2, + type_matrix2x3, type_matrix4, NUM_SHADER_VALUE_TYPES }; @@ -125,5 +128,17 @@ const char* SHADER_VALUE_NAMES[]; class KRReflectedObject { public: - virtual bool getShaderValue(ShaderValue value, void* buffer, size_t size) const = 0; + bool getShaderValue(ShaderValue value, ShaderValueType type, void* output) const; +private: + virtual bool getShaderValue(ShaderValue value, int32_t* output) const; + virtual bool getShaderValue(ShaderValue value, int64_t* output) const; + virtual bool getShaderValue(ShaderValue value, float* output) const; + virtual bool getShaderValue(ShaderValue value, double* output) const; + virtual bool getShaderValue(ShaderValue value, hydra::Vector2* output) const; + virtual bool getShaderValue(ShaderValue value, hydra::Vector3* output) const; + virtual bool getShaderValue(ShaderValue value, hydra::Vector4* output) const; + virtual bool getShaderValue(ShaderValue value, hydra::Matrix2* output) const; + virtual bool getShaderValue(ShaderValue value, hydra::Matrix2x3* output) const; + virtual bool getShaderValue(ShaderValue value, hydra::Matrix4* output) const; + }; diff --git a/kraken/KRViewport.cpp b/kraken/KRViewport.cpp index e0f2618..6652934 100755 --- a/kraken/KRViewport.cpp +++ b/kraken/KRViewport.cpp @@ -55,36 +55,35 @@ KRViewport::KRViewport(const Vector2& size, const Matrix4& matView, const Matrix calculateDerivedValues(); } -bool KRViewport::getShaderValue(ShaderValue value, void* buffer, size_t size) const +bool KRViewport::getShaderValue(ShaderValue value, Matrix4* output) const { - if (size == sizeof(Matrix4)) { - switch (value) { - case ShaderValue::projection_matrix: - { - memcpy(buffer, &m_matProjection, sizeof(Matrix4)); - return true; - } - case ShaderValue::invp: - { - memcpy(buffer, &m_matInverseProjection, sizeof(Matrix4)); - return true; - } - } + switch (value) { + case ShaderValue::projection_matrix: + { + *output = m_matProjection; + return true; } + case ShaderValue::invp: + { + *output = m_matInverseProjection; + return true; + } + return false; + } +} - if (size == sizeof(Vector4)) { - switch (value) { - case ShaderValue::viewport: - { - Vector4 viewport = Vector4::Create( - 0.0f, - 0.0f, - getSize().x, - getSize().y - ); - memcpy(buffer, &viewport, sizeof(Vector4)); - return true; - } +bool KRViewport::getShaderValue(ShaderValue value, Vector4* output) const +{ + switch (value) { + case ShaderValue::viewport: + { + *output = Vector4::Create( + 0.0f, + 0.0f, + getSize().x, + getSize().y + ); + return true; } } diff --git a/kraken/KRViewport.h b/kraken/KRViewport.h index 10f7ca4..e0e6272 100755 --- a/kraken/KRViewport.h +++ b/kraken/KRViewport.h @@ -47,7 +47,8 @@ public: KRViewport(const hydra::Vector2& size, const hydra::Matrix4& matView, const hydra::Matrix4& matProjection); ~KRViewport(); - bool getShaderValue(ShaderValue value, void* buffer, size_t size) const final; + bool getShaderValue(ShaderValue value, hydra::Vector4* output) const final; + bool getShaderValue(ShaderValue value, hydra::Matrix4* output) const final; const hydra::Vector2& getSize() const; const hydra::Matrix4& getViewMatrix() const;