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,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;
}
}

View File

@@ -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;

View File

@@ -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<const KRReflectedObject*> ob
if (size != 0) {
void* constant = (pushConstants.buffer + pushConstants.offset[static_cast<size_t>(i)]);
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;
}
}

View File

@@ -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<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
#include <map>
#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;
};

View File

@@ -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;
}
}

View File

@@ -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;