Files
davinci2/source/shaders/standard/vs_standard.cpp
T
2025-12-03 23:38:08 +08:00

123 lines
4.3 KiB
C++

#include "vs_standard.h"
#include "device/dvc_buffer_accessor.h"
#include "math/dvc_vector2.h"
#include "math/dvc_vector3.h"
#include "math/dvc_matrix4.h"
#include "pipe/dvc_render_pipe.h"
#include "device/dvc_uniform_buffer.h"
StandardVertexShader::StandardVertexShader(bool withWorldPos, bool withNormal, bool withTexCoord0)
: m_withWorldPos(withWorldPos)
, m_withNormal(withNormal)
, m_withTexCoord0(withTexCoord0)
{
m_name = "standard";
m_inputAccessors[davinci::VET_POSITION_MODEL] = nullptr;
m_outputVertexDesc.addElement("v_ndc_pos", davinci::VET_POSITION_NDC, davinci::CT_Float32, davinci::DT_Vec3);
if (withWorldPos)
{
m_outputVertexDesc.addElement("v_world_pos", davinci::VET_POSITION_WORLD, davinci::CT_Float32, davinci::DT_Vec3);
}
m_name += withWorldPos ? "+worldpos" : "-worldpos";
if (withNormal)
{
m_inputAccessors[davinci::VET_NORMAL] = nullptr;
m_outputVertexDesc.addElement("v_normal", davinci::VET_NORMAL, davinci::CT_Float32, davinci::DT_Vec3);
}
m_name += withNormal ? "+normal" : "-normal";
if (withTexCoord0)
{
m_inputAccessors[davinci::VET_TEXCOORD_0] = nullptr;
m_outputVertexDesc.addElement("v_uv", davinci::VET_TEXCOORD_0, davinci::CT_Float32, davinci::DT_Vec2);
}
m_name += withTexCoord0 ? "+uv0" : "-uv0";
}
StandardVertexShader::~StandardVertexShader()
{
}
void StandardVertexShader::begin(const davinci::RenderPipe* pipe, SetInputAttributeFunc setInputAttributeFunc)
{
m_pipe = pipe;
for (auto& pair : m_inputAccessors)
{
pair.second = setInputAttributeFunc(pair.first);
}
assert(getInputAccessor(davinci::VET_POSITION_MODEL));
assert((!m_withNormal) || getInputAccessor(davinci::VET_NORMAL));
assert((!m_withTexCoord0) || getInputAccessor(davinci::VET_TEXCOORD_0));
}
void StandardVertexShader::process(size_t index, float32_t* outputVertex)
{
static const float DEFAULT_POSITION[] = {0.f, 0.f, 0.f};
static const float32_t DEFAULT_NORMAL[] = { 0.f, 0.f, 0.f };
static const float32_t DEFAULT_TEXCOORD0[] = { 0.f, 0.f};
const davinci::UniformBuffer& uniformBuffer = m_pipe->getUniformBuffer();
davinci::DeviceBufferAccessorConstPtr inputPosition = getInputAccessor(davinci::VET_POSITION_MODEL);
davinci::DeviceBufferAccessorConstPtr inputNormal = m_withNormal ? getInputAccessor(davinci::VET_NORMAL) : nullptr;
davinci::DeviceBufferAccessorConstPtr inputTexcoord0 = m_withTexCoord0 ? getInputAccessor(davinci::VET_TEXCOORD_0) : nullptr;
davinci::fVector3 a_position(inputPosition ? (const float32_t*)(inputPosition->getElement(index)) : DEFAULT_POSITION);
davinci::fVector3 a_normal(inputNormal ? (const float32_t*)(inputNormal->getElement(index)) : DEFAULT_NORMAL);
davinci::fVector2 a_uv(inputTexcoord0 ? (const float32_t*)(inputTexcoord0->getElement(index)) : DEFAULT_TEXCOORD0);
davinci::fMatrix4 mat_world = davinci::fMatrix4::IDENTITY;
if (davinci::fMatrix4* p_mat_world = (davinci::fMatrix4*)(uniformBuffer.getAttribute("self:world_transform")))
{
mat_world = *p_mat_world;
}
davinci::fMatrix4 mat_camera_view_proj = davinci::fMatrix4::IDENTITY;
if (davinci::fMatrix4* p_mat_camera_view_proj = (davinci::fMatrix4*)(uniformBuffer.getAttribute("camera:view_proj_mat")))
{
mat_camera_view_proj = *p_mat_camera_view_proj;
}
davinci::fVector3 vertexWorldPos = mat_world * a_position;
//output NDC position
{
davinci::fVector3 vertexNDCPos = mat_camera_view_proj * vertexWorldPos;
memcpy((char*)outputVertex + m_outputVertexDesc.getElement(davinci::VET_POSITION_NDC)->offset, &vertexNDCPos, sizeof(davinci::fVector3));
}
//output world position
if (m_withWorldPos)
{
memcpy((char*)outputVertex + m_outputVertexDesc.getElement(davinci::VET_POSITION_WORLD)->offset, &vertexWorldPos, sizeof(davinci::fVector3));
}
//output normal
if (m_withNormal)
{
davinci::fMatrix4 matNormal = davinci::fMatrix4::IDENTITY;
if (davinci::fMatrix4* p_mat_normal = (davinci::fMatrix4*)(uniformBuffer.getAttribute("self:world_transform_inverse_trans")))
{
matNormal = *p_mat_normal;
}
davinci::fVector3 v_normal = (matNormal * davinci::fVector4(a_normal, 0)).xyz().normalise();
memcpy((char*)outputVertex + m_outputVertexDesc.getElement(davinci::VET_NORMAL)->offset, &v_normal, sizeof(davinci::fVector3));
}
//output uv0
if (m_withTexCoord0)
{
memcpy((char*)outputVertex + m_outputVertexDesc.getElement(davinci::VET_TEXCOORD_0)->offset, &a_uv, sizeof(float32_t) * 2);
}
}
void StandardVertexShader::end()
{
}