#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() { }