Shader reflection now using ShaderValueType

This commit is contained in:
2025-08-31 00:30:15 -07:00
parent 97da7eaa94
commit 51534da431
7 changed files with 201 additions and 107 deletions

View File

@@ -51,37 +51,35 @@ 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) { switch (value) {
case ShaderValue::camerapos_model_space: case ShaderValue::camerapos_model_space:
{ {
// Transform location of camera to object space for calculation of specular halfVec // Transform location of camera to object space for calculation of specular halfVec
Vector3 cameraPosObject = Matrix4::Dot(m_matModelInverse, m_viewport->getCameraPosition()); *output = Matrix4::Dot(m_matModelInverse, m_viewport->getCameraPosition());
memcpy(buffer, &cameraPosObject, sizeof(Vector3));
return true; return true;
} }
case ShaderValue::view_space_model_origin: case ShaderValue::view_space_model_origin:
{ {
// Origin point of model space is the light source position. No perspective, so no w divide required // 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()); *output = Matrix4::Dot(m_matModelView, Vector3::Zero());
memcpy(buffer, &viewSpaceModelOrigin, sizeof(Vector3));
return true; return true;
} }
} }
} }
bool KRModelView::getShaderValue(ShaderValue value, Matrix4* output) const
if (size == sizeof(Matrix4)) { {
switch (value) { switch (value) {
case ShaderValue::model_matrix: case ShaderValue::model_matrix:
{ {
memcpy(buffer, &m_matModel, sizeof(Matrix4)); *output = m_matModel;
return true; return true;
} }
case ShaderValue::model_view: case ShaderValue::model_view:
{ {
memcpy(buffer, &m_matModelView, sizeof(Matrix4)); *output = m_matModelView;
return true; return true;
} }
case ShaderValue::model_view_inverse_transpose: case ShaderValue::model_view_inverse_transpose:
@@ -89,7 +87,7 @@ bool KRModelView::getShaderValue(ShaderValue value, void* buffer, size_t size) c
Matrix4 matModelViewInverseTranspose = m_matModelView; Matrix4 matModelViewInverseTranspose = m_matModelView;
matModelViewInverseTranspose.transpose(); matModelViewInverseTranspose.transpose();
matModelViewInverseTranspose.invert(); matModelViewInverseTranspose.invert();
memcpy(buffer, &matModelViewInverseTranspose, sizeof(Matrix4)); *output = matModelViewInverseTranspose;
return true; return true;
} }
case ShaderValue::model_inverse_transpose: case ShaderValue::model_inverse_transpose:
@@ -97,7 +95,7 @@ bool KRModelView::getShaderValue(ShaderValue value, void* buffer, size_t size) c
Matrix4 matModelInverseTranspose = m_matModel; Matrix4 matModelInverseTranspose = m_matModel;
matModelInverseTranspose.transpose(); matModelInverseTranspose.transpose();
matModelInverseTranspose.invert(); matModelInverseTranspose.invert();
memcpy(buffer, &matModelInverseTranspose, sizeof(Matrix4)); *output = matModelInverseTranspose;
return true; return true;
} }
case ShaderValue::invmvp_no_translate: case ShaderValue::invmvp_no_translate:
@@ -113,24 +111,23 @@ bool KRModelView::getShaderValue(ShaderValue value, void* buffer, size_t size) c
matInvMVPNoTranslate.getPointer()[15] = 1.0; matInvMVPNoTranslate.getPointer()[15] = 1.0;
matInvMVPNoTranslate = matInvMVPNoTranslate * m_viewport->getProjectionMatrix(); matInvMVPNoTranslate = matInvMVPNoTranslate * m_viewport->getProjectionMatrix();
matInvMVPNoTranslate.invert(); matInvMVPNoTranslate.invert();
memcpy(buffer, &matInvMVPNoTranslate, sizeof(Matrix4)); *output = matInvMVPNoTranslate;
return true; return true;
} }
case ShaderValue::mvp: case ShaderValue::mvp:
{ {
Matrix4 mvpMatrix = m_matModel * m_viewport->getViewProjectionMatrix(); Matrix4 mvpMatrix = m_matModel * m_viewport->getViewProjectionMatrix();
memcpy(buffer, &mvpMatrix, sizeof(Matrix4)); *output = mvpMatrix;
return true; return true;
} }
case ShaderValue::invmvp: case ShaderValue::invmvp:
{ {
Matrix4 mvpMatrix = m_matModel * m_viewport->getViewProjectionMatrix(); Matrix4 mvpMatrix = m_matModel * m_viewport->getViewProjectionMatrix();
Matrix4 invMVP = Matrix4::Invert(mvpMatrix); Matrix4 invMVP = Matrix4::Invert(mvpMatrix);
memcpy(buffer, &invMVP, sizeof(Matrix4)); *output = invMVP;
return true; return true;
} }
} }
}
return false; return false;
} }

View File

@@ -46,7 +46,8 @@ public:
KRModelView(KRViewport* viewport, const hydra::Matrix4& matModel); KRModelView(KRViewport* viewport, const hydra::Matrix4& matModel);
~KRModelView(); ~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: private:
KRViewport* m_viewport; KRViewport* m_viewport;

View File

@@ -456,22 +456,23 @@ void KRPipeline::initPushConstantStage(ShaderStage stage, const SpvReflectShader
pushConstants.type[iUniform] = ShaderValueType::type_vector4; pushConstants.type[iUniform] = ShaderValueType::type_vector4;
break; break;
} }
} } else if (member.type_description->op == SpvOpTypeFloat && member.numeric.scalar.width == 32) {
if (member.type_description->op == SpvOpTypeFloat && member.numeric.scalar.width == 32) {
pushConstants.type[iUniform] = ShaderValueType::type_float32; pushConstants.type[iUniform] = ShaderValueType::type_float32;
} } else if (member.type_description->op == SpvOpTypeFloat && member.numeric.scalar.width == 64) {
if (member.type_description->op == SpvOpTypeFloat && member.numeric.scalar.width == 64) {
pushConstants.type[iUniform] = ShaderValueType::type_float64; pushConstants.type[iUniform] = ShaderValueType::type_float64;
} } else if (member.type_description->op == SpvOpTypeInt && member.numeric.scalar.width == 32) {
if (member.type_description->op == SpvOpTypeInt && member.numeric.scalar.width == 32) {
pushConstants.type[iUniform] = ShaderValueType::type_int32; pushConstants.type[iUniform] = ShaderValueType::type_int32;
} } else if (member.type_description->op == SpvOpTypeInt && member.numeric.scalar.width == 64) {
if (member.type_description->op == SpvOpTypeInt && member.numeric.scalar.width == 64) {
pushConstants.type[iUniform] = ShaderValueType::type_int64; pushConstants.type[iUniform] = ShaderValueType::type_int64;
} } else if (member.type_description->op == SpvOpTypeMatrix && member.numeric.scalar.width == 32) {
if (member.type_description->op == SpvOpTypeMatrix && member.numeric.scalar.width == 32 && member.numeric.matrix.column_count == 4 && member.numeric.matrix.row_count == 4) { 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; pushConstants.type[iUniform] = ShaderValueType::type_matrix4;
} }
}
// TODO: Support unsigned integer binding? // TODO: Support unsigned integer binding?
} }
} }
@@ -539,7 +540,7 @@ void KRPipeline::setPushConstants(const std::vector<const KRReflectedObject*> ob
if (size != 0) { if (size != 0) {
void* constant = (pushConstants.buffer + pushConstants.offset[static_cast<size_t>(i)]); void* constant = (pushConstants.buffer + pushConstants.offset[static_cast<size_t>(i)]);
for (const KRReflectedObject* object : objects) { for (const KRReflectedObject* object : objects) {
if (object->getShaderValue(static_cast<ShaderValue>(i), constant, size)) { if (object->getShaderValue(static_cast<ShaderValue>(i), pushConstants.type[static_cast<size_t>(i)], constant)) {
break; break;
} }
} }

View File

@@ -31,6 +31,8 @@
#include "KRShaderReflection.h" #include "KRShaderReflection.h"
using namespace hydra;
const char* SHADER_VALUE_NAMES[] = { const char* SHADER_VALUE_NAMES[] = {
"material_ambient", // PushConstant::material_ambient "material_ambient", // PushConstant::material_ambient
"material_diffuse", // PushConstant::material_diffuse "material_diffuse", // PushConstant::material_diffuse
@@ -100,3 +102,81 @@ const char* SHADER_VALUE_NAMES[] = {
"rim_power", // PushConstant::rim_power "rim_power", // PushConstant::rim_power
"fade_color", // PushConstant::fade_color "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<int32_t*>(output));
case ShaderValueType::type_int64:
return getShaderValue(value, static_cast<int64_t*>(output));
case ShaderValueType::type_float32:
return getShaderValue(value, static_cast<float*>(output));
case ShaderValueType::type_float64:
return getShaderValue(value, static_cast<double*>(output));
case ShaderValueType::type_vector2:
return getShaderValue(value, static_cast<Vector2*>(output));
case ShaderValueType::type_vector3:
return getShaderValue(value, static_cast<Vector3*>(output));
case ShaderValueType::type_vector4:
return getShaderValue(value, static_cast<Vector4*>(output));
case ShaderValueType::type_matrix2:
return getShaderValue(value, static_cast<Matrix2*>(output));
case ShaderValueType::type_matrix2x3:
return getShaderValue(value, static_cast<Matrix2x3*>(output));
case ShaderValueType::type_matrix4:
return getShaderValue(value, static_cast<Matrix4*>(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;
}

View File

@@ -33,6 +33,7 @@
#pragma once #pragma once
#include <map> #include <map>
#include "hydra.h"
enum class ShaderValueType : uint8_t enum class ShaderValueType : uint8_t
{ {
@@ -44,6 +45,8 @@ enum class ShaderValueType : uint8_t
type_vector2, type_vector2,
type_vector3, type_vector3,
type_vector4, type_vector4,
type_matrix2,
type_matrix2x3,
type_matrix4, type_matrix4,
NUM_SHADER_VALUE_TYPES NUM_SHADER_VALUE_TYPES
}; };
@@ -125,5 +128,17 @@ const char* SHADER_VALUE_NAMES[];
class KRReflectedObject class KRReflectedObject
{ {
public: 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;
}; };

View File

@@ -55,38 +55,37 @@ KRViewport::KRViewport(const Vector2& size, const Matrix4& matView, const Matrix
calculateDerivedValues(); 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) { switch (value) {
case ShaderValue::projection_matrix: case ShaderValue::projection_matrix:
{ {
memcpy(buffer, &m_matProjection, sizeof(Matrix4)); *output = m_matProjection;
return true; return true;
} }
case ShaderValue::invp: case ShaderValue::invp:
{ {
memcpy(buffer, &m_matInverseProjection, sizeof(Matrix4)); *output = m_matInverseProjection;
return true; return true;
} }
return false;
} }
} }
if (size == sizeof(Vector4)) { bool KRViewport::getShaderValue(ShaderValue value, Vector4* output) const
{
switch (value) { switch (value) {
case ShaderValue::viewport: case ShaderValue::viewport:
{ {
Vector4 viewport = Vector4::Create( *output = Vector4::Create(
0.0f, 0.0f,
0.0f, 0.0f,
getSize().x, getSize().x,
getSize().y getSize().y
); );
memcpy(buffer, &viewport, sizeof(Vector4));
return true; return true;
} }
} }
}
return false; return false;
} }

View File

@@ -47,7 +47,8 @@ public:
KRViewport(const hydra::Vector2& size, const hydra::Matrix4& matView, const hydra::Matrix4& matProjection); KRViewport(const hydra::Vector2& size, const hydra::Matrix4& matView, const hydra::Matrix4& matProjection);
~KRViewport(); ~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::Vector2& getSize() const;
const hydra::Matrix4& getViewMatrix() const; const hydra::Matrix4& getViewMatrix() const;