/** 平行移動行列 * x, y, z : 各軸の移動量 */ Float4x4 MatrixHelper::translate( float x, float y, float z ) { return Float4x4( 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, x, y, z, 1.0f ); }
/** Y軸回転行列 * rad : ラジアン角度 */ Float4x4 MatrixHelper::rotateY( float rad ) { float c = cosf( rad ); float s = sinf( rad ); return Float4x4( c, 0.0f, -s, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, s, 0.0f, c, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f ); }
Float4x4 MatrixHelper::perspMatrix( const Float2 clientWH, float fovY, float nearZ, float farZ ) { float cot2s = 1.0f / tanf( fovY * 0.5f ); float zVal = farZ / ( farZ - nearZ ); return Float4x4( cot2s * clientWH.y / clientWH.x, 0.0f, 0.0f, 0.0f, 0.0f, cot2s, 0.0f, 0.0f, 0.0f, 0.0f, zVal, 1.0f, 0.0f, 0.0f, -nearZ * zVal, 0.0f ); }
// Renders all meshes using depth-only rendering void MeshRenderer::RenderDepth(ID3D11DeviceContext* context, const Camera& camera, bool noZClip, bool flippedZRange) { PIXEvent event(L"Mesh Depth Rendering"); // Set states float blendFactor[4] = {1, 1, 1, 1}; context->OMSetBlendState(blendStates.ColorWriteDisabled(), blendFactor, 0xFFFFFFFF); context->OMSetDepthStencilState(flippedZRange ? depthStencilStates.ReverseDepthWriteEnabled() : depthStencilStates.DepthWriteEnabled(), 0); if(noZClip) context->RSSetState(noZClipRSState); else context->RSSetState(rasterizerStates.BackFaceCull()); // Set constant buffers meshVSConstants.Data.World = Float4x4(); meshVSConstants.Data.View = Float4x4::Transpose(camera.ViewMatrix()); meshVSConstants.Data.WorldViewProjection = Float4x4::Transpose(camera.ViewProjectionMatrix()); meshVSConstants.ApplyChanges(context); meshVSConstants.SetVS(context, 0); // Set shaders context->VSSetShader(meshDepthVS , nullptr, 0); context->PSSetShader(nullptr, nullptr, 0); context->GSSetShader(nullptr, nullptr, 0); context->DSSetShader(nullptr, nullptr, 0); context->HSSetShader(nullptr, nullptr, 0); for(uint32 meshIdx = 0; meshIdx < sceneModel->Meshes().size(); ++meshIdx) { const Mesh& mesh = sceneModel->Meshes()[meshIdx]; // Set the vertices and indices ID3D11Buffer* vertexBuffers[1] = { mesh.VertexBuffer() }; UINT vertexStrides[1] = { mesh.VertexStride() }; UINT offsets[1] = { 0 }; context->IASetVertexBuffers(0, 1, vertexBuffers, vertexStrides, offsets); context->IASetIndexBuffer(mesh.IndexBuffer(), mesh.IndexBufferFormat(), 0); context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // Set the input layout context->IASetInputLayout(meshDepthInputLayouts[meshIdx]); // Draw all parts for(uint64 partIdx = 0; partIdx < mesh.MeshParts().size(); ++partIdx) { const MeshPart& part = mesh.MeshParts()[partIdx]; context->DrawIndexed(part.IndexCount, part.IndexStart, 0); } } }
Float4x4 MatrixHelper::viewMatrix( const Float3 &pos, const Float3 &target, const Float3 &up ) { Float3 vz = ( target - pos ).normalizeND(); Float3 vx = up.cross( vz ).normalizeND(); Float3 vy = vz.cross( vx ).normalizeND(); float px = -pos.dot( vx ); float py = -pos.dot( vy ); float pz = -pos.dot( vz ); return Float4x4( vx.x, vy.x, vz.x, 0.0f, vx.y, vy.y, vz.y, 0.0f, vx.z, vy.z, vz.z, 0.0f, px, py, pz, 1.0f ); }
Float4x4 Float4x4::operator *(const Float4x4 &rhs) const { return Float4x4(m_value * rhs.m_value); }
Float4x4 Float4x4::Inverted() const { return Float4x4(m_value.Inverted()); }
namespace SMath { Float4x4::Float4x4() : m_value(Impl::zero) {} Float4x4::Float4x4( float _00, float _01, float _02, float _03, float _10, float _11, float _12, float _13, float _20, float _21, float _22, float _23, float _30, float _31, float _32, float _33 ) : m_value( _00, _01, _02, _03, _10, _11, _12, _13, _20, _21, _22, _23, _30, _31, _32, _33 ) {} Float4x4::Float4x4(const Float4x4 &rhs) : m_value(rhs.m_value) {} Float4x4::Float4x4(Float4x4 &&rhs) noexcept : m_value(rhs.m_value) {} Float4x4::~Float4x4() { } void Float4x4::Set( float _00, float _01, float _02, float _03, float _10, float _11, float _12, float _13, float _20, float _21, float _22, float _23, float _30, float _31, float _32, float _33 ) { m_value.Set( _00, _01, _02, _03, _10, _11, _12, _13, _20, _21, _22, _23, _30, _31, _32, _33 ); } bool Float4x4::Inverse(float epsilon) { return m_value.Inverse(epsilon); } Float4x4 Float4x4::Inverted() const { return Float4x4(m_value.Inverted()); } MATH_NAMESPACE_NAME::MatrixProxy<Float4x4::Cols>& Float4x4::operator[](int row) { return m_value[row]; } const MATH_NAMESPACE_NAME::MatrixProxy<Float4x4::Cols>& Float4x4::operator[](int row) const { return m_value[row]; } Float4& Float4x4::Row(int row) { return reinterpret_cast<Float4&>(m_value[row]); } const Float4& Float4x4::Row(int row) const { return reinterpret_cast<const Float4&>(m_value[row]); } void Float4x4::ScaleRow(int row, float scalar) { m_value.ScaleRow(row, scalar); } void Float4x4::SwapRows(int row1, int row2) { m_value.SwapRows(row1, row2); } void Float4x4::SetRow(int row, const Float3 &rowVector, float m_r3) { SetRow( row, rowVector.X(), rowVector.Y(), rowVector.Z(), m_r3 ); } void Float4x4::SetRow(int row, const Float4 &rowVector) { SetRow( row, rowVector.X(), rowVector.Y(), rowVector.Z(), rowVector.W() ); } void Float4x4::SetRow(int row, float m_r0, float m_r1, float m_r2, float m_r3) { m_value.SetRow(row, m_r0, m_r1, m_r2, m_r3 ); } Float4x4 Float4x4::operator *(const Float4x4 &rhs) const { return Float4x4(m_value * rhs.m_value); } Float3 Float4x4::operator *(const Float3 &rhs) const { return TransformPos(rhs); } Float4 Float4x4::operator *(const Float4 &rhs) const { return Transform(rhs); } Float4x4 Float4x4::operator *(float scalar) const { return Float4x4(m_value * scalar); } Float4x4 Float4x4::operator /(float scalar) const { return Float4x4(m_value / scalar); } Float4x4 Float4x4::operator +(const Float4x4 &rhs) const { return Float4x4(m_value + rhs.m_value); } Float4x4 Float4x4::operator -(const Float4x4 &rhs) const { return Float4x4(m_value - rhs.m_value); } Float4x4 Float4x4::operator -() const { return Float4x4(-m_value); } Float4x4 Float4x4::operator +() const { return *this; } Float4x4 &Float4x4::operator *=(float scalar) { m_value *= scalar; return *this; } Float4x4 &Float4x4::operator /=(float scalar) { assert(scalar != 0); m_value /= scalar; return *this; } Float4x4 &Float4x4::operator=(const Float4x4& rhs) { m_value = rhs.m_value; return *this; } Float4x4 &Float4x4::operator +=(const Float4x4 &rhs) { m_value += rhs.m_value; return *this; } Float4x4 &Float4x4::operator -=(const Float4x4 &rhs) { m_value -= rhs.m_value; return *this; } Float4x4 Float4x4::Mul(const Float4x4 &rhs) const { return *this * rhs; } Float3 Float4x4::MulPos(const Float3 &pointVector) const { return TransformPos(pointVector); } Float3 Float4x4::MulDir(const Float3 &directionVector) const { return TransformDir(directionVector); } Float4 Float4x4::Mul(const Float4 &vector) const { return *this * vector; } Float3 Float4x4::TranslatePart() const { return Float3( m_value[0][3], m_value[1][3], m_value[2][3] ); } Float4 Float4x4::Transform(const Float4 &vector) const { return Float4(m_value.Transform(vector.ToImpl())); } Float3 Float4x4::TransformPos(const Float3 &pointVector) const { return TransformPos(pointVector.X(), pointVector.Y(), pointVector.Z()); } Float3 Float4x4::TransformPos(float x, float y, float z) const { return m_value.TransformPos(x, y, z); } Float3 Float4x4::TransformDir(const Float3 &directionVector) const { return TransformDir(directionVector.X(), directionVector.Y(), directionVector.Z()); } Float3 Float4x4::TransformDir(float x, float y, float z) const { return m_value.TransformDir(x, y, z); } void Float4x4::SetTranslatePart(float tx, float ty, float tz) { m_value.SetTranslatePart(tx, ty, tz); } void Float4x4::SetTranslatePart(const Float3 &offset) { m_value.SetTranslatePart(offset.ToImpl()); } Float4x4 Float4x4::D3DOrthoProj(float nearPlaneDistance, float farPlaneDistance, float horizontalViewportSize, float verticalViewportSize) { return D3DOrthoProj(Int2Type<Handedness::This == Handedness::left>(), nearPlaneDistance, farPlaneDistance, horizontalViewportSize, verticalViewportSize); } Float4x4 Float4x4::D3DOrthoProj(TrueType, float nearPlaneDistance, float farPlaneDistance, float horizontalViewportSize, float verticalViewportSize) { return Impl::D3DOrthoProjLH(nearPlaneDistance, farPlaneDistance, horizontalViewportSize, verticalViewportSize); } Float4x4 Float4x4::D3DOrthoProj(FalseType, float nearPlaneDistance, float farPlaneDistance, float horizontalViewportSize, float verticalViewportSize) { return Impl::D3DOrthoProjRH(nearPlaneDistance, farPlaneDistance, horizontalViewportSize, verticalViewportSize); } Float4x4 Float4x4::D3DPerspProj(float nearPlaneDistance, float farPlaneDistance, float horizontalViewportSize, float verticalViewportSize) { return D3DPerspProj(Int2Type<Handedness::This == Handedness::left>(), nearPlaneDistance, farPlaneDistance, horizontalViewportSize, verticalViewportSize); } Float4x4 Float4x4::D3DPerspProj(TrueType, float nearPlaneDistance, float farPlaneDistance, float horizontalViewportSize, float verticalViewportSize) { return Impl::D3DPerspProjLH(nearPlaneDistance, farPlaneDistance, horizontalViewportSize, verticalViewportSize); } Float4x4 Float4x4::D3DPerspProj(FalseType, float nearPlaneDistance, float farPlaneDistance, float horizontalViewportSize, float verticalViewportSize) { return Impl::D3DPerspProjRH(nearPlaneDistance, farPlaneDistance, horizontalViewportSize, verticalViewportSize); } Float4x4 Float4x4::OpenGLOrthoProj(float nearPlaneDistance, float farPlaneDistance, float horizontalViewportSize, float verticalViewportSize) { return OpenGLOrthoProj(Int2Type<Handedness::This == Handedness::left>(), nearPlaneDistance, farPlaneDistance, horizontalViewportSize, verticalViewportSize); } Float4x4 Float4x4::OpenGLOrthoProj(TrueType, float nearPlaneDistance, float farPlaneDistance, float horizontalViewportSize, float verticalViewportSize) { return Impl::OpenGLOrthoProjLH(nearPlaneDistance, farPlaneDistance, horizontalViewportSize, verticalViewportSize); } Float4x4 Float4x4::OpenGLOrthoProj(FalseType, float nearPlaneDistance, float farPlaneDistance, float horizontalViewportSize, float verticalViewportSize) { return Impl::OpenGLOrthoProjRH(nearPlaneDistance, farPlaneDistance, horizontalViewportSize, verticalViewportSize); } Float4x4 Float4x4::OpenGLPerspProj(float nearPlaneDistance, float farPlaneDistance, float horizontalViewportSize, float verticalViewportSize) { return OpenGLPerspProj(Int2Type<Handedness::This == Handedness::left>(), nearPlaneDistance, farPlaneDistance, horizontalViewportSize, verticalViewportSize); } Float4x4 Float4x4::OpenGLPerspProj(TrueType, float nearPlaneDistance, float farPlaneDistance, float horizontalViewportSize, float verticalViewportSize) { return Impl::OpenGLPerspProjLH(nearPlaneDistance, farPlaneDistance, horizontalViewportSize, verticalViewportSize); } Float4x4 Float4x4::OpenGLPerspProj(FalseType, float nearPlaneDistance, float farPlaneDistance, float horizontalViewportSize, float verticalViewportSize) { return Impl::OpenGLPerspProjRH(nearPlaneDistance, farPlaneDistance, horizontalViewportSize, verticalViewportSize); } void Float4x4::Transpose() { m_value.Transpose(); } Float4x4 Float4x4::Transposed() const { return Float4x4(m_value.Transposed()); } Float4x4 Float4x4::RotateX(float angleRadians) { return Float4x4(Impl::RotateX(angleRadians)); } Float4x4 Float4x4::RotateY(float angleRadians) { return Float4x4(Impl::RotateY(angleRadians)); } Float4x4 Float4x4::RotateZ(float angleRadians) { return Float4x4(Impl::RotateZ(angleRadians)); } Float4 operator *(const Float4 &lhs, const Float4x4 &rhs) { return Float4(lhs.ToImpl() * rhs.ToImpl()); } const Float4x4 Float4x4::identity = Float4x4( 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 ); Float4x4::Float4x4(const Impl& rhs) : m_value(rhs) {} }//namespace SMath{
Float4x4 Float4x4::RotateZ(float angleRadians) { return Float4x4(Impl::RotateZ(angleRadians)); }
Float4x4 Float4x4::Transposed() const { return Float4x4(m_value.Transposed()); }
Float4x4 Float4x4::operator -() const { return Float4x4(-m_value); }
Float4x4 Float4x4::operator /(float scalar) const { return Float4x4(m_value / scalar); }
// Renders all meshes in the model, with shadows void MeshRenderer::RenderMainPass(ID3D11DeviceContext* context, const Camera& camera) { PIXEvent event(L"Mesh Rendering"); // Set states float blendFactor[4] = {1, 1, 1, 1}; context->OMSetBlendState(blendStates.BlendDisabled(), blendFactor, 0xFFFFFFFF); context->OMSetDepthStencilState(depthStencilStates.DepthEnabled(), 0); context->RSSetState(rasterizerStates.BackFaceCull()); ID3D11SamplerState* sampStates[] = { samplerStates.Anisotropic(), evsmSampler, samplerStates.LinearClamp(), samplerStates.ReversedShadowMapPCF(), }; context->PSSetSamplers(0, ArraySize_(sampStates), sampStates); // Set constant buffers meshVSConstants.Data.World = Float4x4(); meshVSConstants.Data.View = Float4x4::Transpose(camera.ViewMatrix()); meshVSConstants.Data.WorldViewProjection = Float4x4::Transpose(camera.ViewProjectionMatrix()); meshVSConstants.ApplyChanges(context); meshVSConstants.SetVS(context, 0); meshPSConstants.Data.SunDirectionWS = AppSettings::SunDirection; meshPSConstants.Data.SunIlluminance = AppSettings::SunIlluminance(); meshPSConstants.Data.CosSunAngularRadius = std::cos(DegToRad(AppSettings::SunSize) / 2.0f); meshPSConstants.Data.SinSunAngularRadius = std::sin(DegToRad(AppSettings::SunSize) / 2.0f); meshPSConstants.Data.CameraPosWS = camera.Position(); meshPSConstants.ApplyChanges(context); meshPSConstants.SetPS(context, 0); shadowConstants.Data.PositiveExponent = PositiveExponent; shadowConstants.Data.NegativeExponent = NegativeExponent; shadowConstants.Data.LightBleedingReduction = LightBleedingReduction; shadowConstants.ApplyChanges(context); shadowConstants.SetPS(context, 1); // Set shaders context->DSSetShader(nullptr, nullptr, 0); context->HSSetShader(nullptr, nullptr, 0); context->GSSetShader(nullptr, nullptr, 0); context->VSSetShader(meshVS, nullptr, 0); context->PSSetShader(meshPS, nullptr, 0); // Draw all meshes for(uint64 meshIdx = 0; meshIdx < sceneModel->Meshes().size(); ++meshIdx) { const Mesh& mesh = sceneModel->Meshes()[meshIdx]; // Set the vertices and indices ID3D11Buffer* vertexBuffers[1] = { mesh.VertexBuffer() }; UINT vertexStrides[1] = { mesh.VertexStride() }; UINT offsets[1] = { 0 }; context->IASetVertexBuffers(0, 1, vertexBuffers, vertexStrides, offsets); context->IASetIndexBuffer(mesh.IndexBuffer(), mesh.IndexBufferFormat(), 0); context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // Set the input layout context->IASetInputLayout(meshInputLayouts[meshIdx]); // Draw all parts for(uint64 partIdx = 0; partIdx < mesh.MeshParts().size(); ++partIdx) { const MeshPart& part = mesh.MeshParts()[partIdx]; const MeshMaterial& material = sceneModel->Materials()[part.MaterialIdx]; // Set the textures ID3D11ShaderResourceView* psTextures[] = { material.DiffuseMap, material.NormalMap, sunVSM.SRView, }; context->PSSetShaderResources(0, ArraySize_(psTextures), psTextures); context->DrawIndexed(part.IndexCount, part.IndexStart, 0); } } ID3D11ShaderResourceView* nullSRVs[8] = { NULL }; context->PSSetShaderResources(0, 8, nullSRVs); }
Float4x4 Float4x4::operator*(const Float4x4& other) const { XMMATRIX result = this->ToSIMD() * other.ToSIMD(); return Float4x4(result); }
Float4x4 Quaternion::ToFloat4x4() const { return Float4x4(XMMatrixRotationQuaternion(ToSIMD())); }