Shader reflection now using ShaderValueType
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user