Commits (23)
......@@ -16,6 +16,8 @@ App::App()
wnd( 1280,720,"The Donkey Fart Box" ),
light( wnd.Gfx() )
{
wall.SetRootTransform( dx::XMMatrixTranslation( -1.5f,0.0f,0.0f ) );
tp.SetPos( { 1.5f,0.0f,0.0f } );
wnd.Gfx().SetProjection( dx::XMMatrixPerspectiveLH( 1.0f,9.0f / 16.0f,0.5f,40.0f ) );
}
......@@ -26,8 +28,9 @@ void App::DoFrame()
wnd.Gfx().SetCamera( cam.GetMatrix() );
light.Bind( wnd.Gfx(),cam.GetMatrix() );
nano.Draw( wnd.Gfx() );
nano2.Draw( wnd.Gfx() );
wall.Draw( wnd.Gfx() );
tp.Draw( wnd.Gfx() );
//nano.Draw( wnd.Gfx() );
light.Draw( wnd.Gfx() );
while( const auto e = wnd.kbd.ReadKey() )
......@@ -97,8 +100,9 @@ void App::DoFrame()
cam.SpawnControlWindow();
light.SpawnControlWindow();
ShowImguiDemoWindow();
nano.ShowWindow( "Model 1" );
nano2.ShowWindow( "Model 2" );
wall.ShowWindow( "Wall" );
tp.SpawnControlWindow( wnd.Gfx() );
//nano.ShowWindow( "Model 1" );
// present
wnd.Gfx().EndFrame();
......
......@@ -4,6 +4,7 @@
#include "ImguiManager.h"
#include "Camera.h"
#include "PointLight.h"
#include "TestPlane.h"
#include "Mesh.h"
#include <set>
......@@ -25,6 +26,7 @@ private:
float speed_factor = 1.0f;
Camera cam;
PointLight light;
Model nano{ wnd.Gfx(),"Models\\nano_textured\\nanosuit.obj" };
Model nano2{ wnd.Gfx(),"Models\\nano_textured\\nanosuit.obj" };
Model wall{ wnd.Gfx(),"Models\\brick_wall\\brick_wall.obj" };
TestPlane tp{ wnd.Gfx(),1.0 };
//Model nano{ wnd.Gfx(),"Models\\nano_textured\\nanosuit.obj" };
};
\ No newline at end of file
......@@ -47,7 +47,7 @@ void Camera::SpawnControlWindow() noexcept
void Camera::Reset() noexcept
{
pos = { 0.0f,7.5f,-18.0f };
pos = { 0.0f,0.0f,-10.0f };
pitch = 0.0f;
yaw = 0.0f;
}
......
#pragma once
#include <optional>
#include "Vertex.h"
#include "IndexedTriangleList.h"
#include <DirectXMath.h>
#include "ChiliMath.h"
#include <array>
class Cube
{
public:
static IndexedTriangleList MakeIndependent( Dvtx::VertexLayout layout )
{
using namespace Dvtx;
using Type = Dvtx::VertexLayout::ElementType;
constexpr float side = 1.0f / 2.0f;
VertexBuffer vertices( std::move( layout ),24u );
vertices[0].Attr<Type::Position3D>() = { -side,-side,-side };// 0 near side
vertices[1].Attr<Type::Position3D>() = { side,-side,-side };// 1
vertices[2].Attr<Type::Position3D>() = { -side,side,-side };// 2
vertices[3].Attr<Type::Position3D>() = { side,side,-side };// 3
vertices[4].Attr<Type::Position3D>() = { -side,-side,side };// 4 far side
vertices[5].Attr<Type::Position3D>() = { side,-side,side };// 5
vertices[6].Attr<Type::Position3D>() = { -side,side,side };// 6
vertices[7].Attr<Type::Position3D>() = { side,side,side };// 7
vertices[8].Attr<Type::Position3D>() = { -side,-side,-side };// 8 left side
vertices[9].Attr<Type::Position3D>() = { -side,side,-side };// 9
vertices[10].Attr<Type::Position3D>() = { -side,-side,side };// 10
vertices[11].Attr<Type::Position3D>() = { -side,side,side };// 11
vertices[12].Attr<Type::Position3D>() = { side,-side,-side };// 12 right side
vertices[13].Attr<Type::Position3D>() = { side,side,-side };// 13
vertices[14].Attr<Type::Position3D>() = { side,-side,side };// 14
vertices[15].Attr<Type::Position3D>() = { side,side,side };// 15
vertices[16].Attr<Type::Position3D>() = { -side,-side,-side };// 16 bottom side
vertices[17].Attr<Type::Position3D>() = { side,-side,-side };// 17
vertices[18].Attr<Type::Position3D>() = { -side,-side,side };// 18
vertices[19].Attr<Type::Position3D>() = { side,-side,side };// 19
vertices[20].Attr<Type::Position3D>() = { -side,side,-side };// 20 top side
vertices[21].Attr<Type::Position3D>() = { side,side,-side };// 21
vertices[22].Attr<Type::Position3D>() = { -side,side,side };// 22
vertices[23].Attr<Type::Position3D>() = { side,side,side };// 23
return{
std::move( vertices ),{
0,2, 1, 2,3,1,
4,5, 7, 4,7,6,
8,10, 9, 10,11,9,
12,13,15, 12,15,14,
16,17,18, 18,17,19,
20,23,21, 20,22,23
}
};
}
static IndexedTriangleList MakeIndependentTextured()
{
using namespace Dvtx;
using Type = Dvtx::VertexLayout::ElementType;
auto itl = MakeIndependent( std::move( VertexLayout{}
.Append( Type::Position3D )
.Append( Type::Normal )
.Append( Type::Texture2D )
) );
itl.vertices[0].Attr<Type::Texture2D>() = { 0.0f,0.0f };
itl.vertices[1].Attr<Type::Texture2D>() = { 1.0f,0.0f };
itl.vertices[2].Attr<Type::Texture2D>() = { 0.0f,1.0f };
itl.vertices[3].Attr<Type::Texture2D>() = { 1.0f,1.0f };
itl.vertices[4].Attr<Type::Texture2D>() = { 0.0f,0.0f };
itl.vertices[5].Attr<Type::Texture2D>() = { 1.0f,0.0f };
itl.vertices[6].Attr<Type::Texture2D>() = { 0.0f,1.0f };
itl.vertices[7].Attr<Type::Texture2D>() = { 1.0f,1.0f };
itl.vertices[8].Attr<Type::Texture2D>() = { 0.0f,0.0f };
itl.vertices[9].Attr<Type::Texture2D>() = { 1.0f,0.0f };
itl.vertices[10].Attr<Type::Texture2D>() = { 0.0f,1.0f };
itl.vertices[11].Attr<Type::Texture2D>() = { 1.0f,1.0f };
itl.vertices[12].Attr<Type::Texture2D>() = { 0.0f,0.0f };
itl.vertices[13].Attr<Type::Texture2D>() = { 1.0f,0.0f };
itl.vertices[14].Attr<Type::Texture2D>() = { 0.0f,1.0f };
itl.vertices[15].Attr<Type::Texture2D>() = { 1.0f,1.0f };
itl.vertices[16].Attr<Type::Texture2D>() = { 0.0f,0.0f };
itl.vertices[17].Attr<Type::Texture2D>() = { 1.0f,0.0f };
itl.vertices[18].Attr<Type::Texture2D>() = { 0.0f,1.0f };
itl.vertices[19].Attr<Type::Texture2D>() = { 1.0f,1.0f };
itl.vertices[20].Attr<Type::Texture2D>() = { 0.0f,0.0f };
itl.vertices[21].Attr<Type::Texture2D>() = { 1.0f,0.0f };
itl.vertices[22].Attr<Type::Texture2D>() = { 0.0f,1.0f };
itl.vertices[23].Attr<Type::Texture2D>() = { 1.0f,1.0f };
return itl;
}
};
\ No newline at end of file
......@@ -27,26 +27,26 @@ public:
);
}
}
//// asserts face-independent vertices w/ normals cleared to zero
//void SetNormalsIndependentFlat() noxnd
//{
// using namespace DirectX;
// for( size_t i = 0; i < indices.size(); i += 3 )
// {
// auto& v0 = vertices[indices[i]];
// auto& v1 = vertices[indices[i + 1]];
// auto& v2 = vertices[indices[i + 2]];
// const auto p0 = XMLoadFloat3( &v0.pos );
// const auto p1 = XMLoadFloat3( &v1.pos );
// const auto p2 = XMLoadFloat3( &v2.pos );
void SetNormalsIndependentFlat() noxnd
{
using namespace DirectX;
using Type = Dvtx::VertexLayout::ElementType;
for( size_t i = 0; i < indices.size(); i += 3 )
{
auto v0 = vertices[indices[i]];
auto v1 = vertices[indices[i + 1]];
auto v2 = vertices[indices[i + 2]];
const auto p0 = XMLoadFloat3( &v0.Attr<Type::Position3D>() );
const auto p1 = XMLoadFloat3( &v1.Attr<Type::Position3D>() );
const auto p2 = XMLoadFloat3( &v2.Attr<Type::Position3D>() );
// const auto n = XMVector3Normalize( XMVector3Cross( (p1 - p0),(p2 - p0) ) );
//
// XMStoreFloat3( &v0.n,n );
// XMStoreFloat3( &v1.n,n );
// XMStoreFloat3( &v2.n,n );
// }
//}
const auto n = XMVector3Normalize( XMVector3Cross( (p1 - p0),(p2 - p0) ) );
XMStoreFloat3( &v0.Attr<Type::Normal>(),n );
XMStoreFloat3( &v1.Attr<Type::Normal>(),n );
XMStoreFloat3( &v2.Attr<Type::Normal>(),n );
}
}
public:
Dvtx::VertexBuffer vertices;
......
......@@ -192,7 +192,8 @@ Model::Model( Graphics& gfx,const std::string fileName )
aiProcess_Triangulate |
aiProcess_JoinIdenticalVertices |
aiProcess_ConvertToLeftHanded |
aiProcess_GenNormals
aiProcess_GenNormals |
aiProcess_CalcTangentSpace
);
if( pScene == nullptr )
......@@ -223,6 +224,11 @@ void Model::ShowWindow( const char* windowName ) noexcept
pWindow->Show( windowName,*pRoot );
}
void Model::SetRootTransform( DirectX::FXMMATRIX tf ) noexcept
{
pRoot->SetAppliedTransform( tf );
}
Model::~Model() noexcept
{}
......@@ -235,6 +241,8 @@ std::unique_ptr<Mesh> Model::ParseMesh( Graphics& gfx,const aiMesh& mesh,const a
VertexLayout{}
.Append( VertexLayout::Position3D )
.Append( VertexLayout::Normal )
.Append( VertexLayout::Tangent )
.Append( VertexLayout::Bitangent )
.Append( VertexLayout::Texture2D )
) );
......@@ -243,6 +251,8 @@ std::unique_ptr<Mesh> Model::ParseMesh( Graphics& gfx,const aiMesh& mesh,const a
vbuf.EmplaceBack(
*reinterpret_cast<dx::XMFLOAT3*>(&mesh.mVertices[i]),
*reinterpret_cast<dx::XMFLOAT3*>(&mesh.mNormals[i]),
*reinterpret_cast<dx::XMFLOAT3*>(&mesh.mTangents[i]),
*reinterpret_cast<dx::XMFLOAT3*>(&mesh.mBitangents[i]),
*reinterpret_cast<dx::XMFLOAT2*>(&mesh.mTextureCoords[0][i])
);
}
......@@ -261,7 +271,7 @@ std::unique_ptr<Mesh> Model::ParseMesh( Graphics& gfx,const aiMesh& mesh,const a
std::vector<std::shared_ptr<Bindable>> bindablePtrs;
using namespace std::string_literals;
const auto base = "Models\\nano_textured\\"s;
const auto base = "Models\\brick_wall\\"s;
bool hasSpecularMap = false;
float shininess = 35.0f;
......@@ -284,6 +294,9 @@ std::unique_ptr<Mesh> Model::ParseMesh( Graphics& gfx,const aiMesh& mesh,const a
material.Get( AI_MATKEY_SHININESS,shininess );
}
material.GetTexture( aiTextureType_NORMALS,0,&texFileName );
bindablePtrs.push_back( Texture::Resolve( gfx,base + texFileName.C_Str(),2 ) );
bindablePtrs.push_back( Bind::Sampler::Resolve( gfx ) );
}
......@@ -293,7 +306,7 @@ std::unique_ptr<Mesh> Model::ParseMesh( Graphics& gfx,const aiMesh& mesh,const a
bindablePtrs.push_back( IndexBuffer::Resolve( gfx,meshTag,indices ) );
auto pvs = VertexShader::Resolve( gfx,"PhongVS.cso" );
auto pvs = VertexShader::Resolve( gfx,"PhongVSNormalMap.cso" );
auto pvsbc = pvs->GetBytecode();
bindablePtrs.push_back( std::move( pvs ) );
......@@ -301,17 +314,27 @@ std::unique_ptr<Mesh> Model::ParseMesh( Graphics& gfx,const aiMesh& mesh,const a
if( hasSpecularMap )
{
bindablePtrs.push_back( PixelShader::Resolve( gfx,"PhongPSSpecMap.cso" ) );
bindablePtrs.push_back( PixelShader::Resolve( gfx,"PhongPSSpecNormalMap.cso" ) );
struct PSMaterialConstant
{
BOOL normalMapEnabled = TRUE;
float padding[3];
} pmc;
// this is CLEARLY an issue... all meshes will share same mat const, but may have different
// Ns (specular power) specified for each in the material properties... bad conflict
bindablePtrs.push_back( PixelConstantBuffer<PSMaterialConstant>::Resolve( gfx,pmc,1u ) );
}
else
{
bindablePtrs.push_back( PixelShader::Resolve( gfx,"PhongPS.cso" ) );
bindablePtrs.push_back( PixelShader::Resolve( gfx,"PhongPSNormalMap.cso" ) );
struct PSMaterialConstant
{
float specularIntensity = 0.8f;
float specularIntensity = 0.18f;
float specularPower;
float padding[2];
BOOL normalMapEnabled = TRUE;
float padding[1];
} pmc;
pmc.specularPower = shininess;
// this is CLEARLY an issue... all meshes will share same mat const, but may have different
......
......@@ -56,6 +56,7 @@ public:
Model( Graphics& gfx,const std::string fileName );
void Draw( Graphics& gfx ) const noxnd;
void ShowWindow( const char* windowName = nullptr ) noexcept;
void SetRootTransform( DirectX::FXMMATRIX tf ) noexcept;
~Model() noexcept;
private:
static std::unique_ptr<Mesh> ParseMesh( Graphics& gfx,const aiMesh& mesh,const aiMaterial* const* pMaterials );
......
newmtl Brick
Ns 18.0000
illum 2
Ka 0.0000 0.0000 0.0000
Kd 0.5880 0.5880 0.5880
Ks 0.1800 0.1800 0.1800
map_Kd brick_wall_diffuse.jpg
map_Kn brick_wall_normal.jpg
\ No newline at end of file
mtllib brick_wall.mtl
o BrickWall
v 1.000000 -1.000000 0.000000
v 1.000000 1.000000 0.000000
v -1.000000 1.000000 0.000000
v -1.000000 -1.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
usemtl Brick
s off
f 1/1 2/2 3/3
f 1/1 3/3 4/4
......@@ -9,7 +9,7 @@ Ni 1.000000
d 1.000000
illum 2
map_Kd arm_dif.png
map_Bump arm_showroom_ddn.png
map_Kn arm_showroom_ddn.png
map_Ks arm_showroom_spec.png
......@@ -22,7 +22,7 @@ Ni 1.000000
d 1.000000
illum 2
map_Kd body_dif.png
map_Bump body_showroom_ddn.png
map_Kn body_showroom_ddn.png
map_Ks body_showroom_spec.png
......@@ -35,7 +35,7 @@ Ni 1.000000
d 1.000000
illum 2
map_Kd glass_dif.png
map_Bump glass_ddn.png
map_Kn glass_ddn.png
newmtl Hand
......@@ -47,7 +47,7 @@ Ni 1.000000
d 1.000000
illum 2
map_Kd hand_dif.png
map_Bump hand_showroom_ddn.png
map_Kn hand_showroom_ddn.png
map_Ks hand_showroom_spec.png
......@@ -60,7 +60,7 @@ Ni 1.000000
d 1.000000
illum 2
map_Kd helmet_diff.png
map_Bump helmet_showroom_ddn.png
map_Kn helmet_showroom_ddn.png
map_Ks helmet_showroom_spec.png
......@@ -73,7 +73,7 @@ Ni 1.000000
d 1.000000
illum 2
map_Kd leg_dif.png
map_Bump leg_showroom_ddn.png
map_Kn leg_showroom_ddn.png
map_Ks leg_showroom_spec.png
......@@ -21,10 +21,10 @@ Texture2D tex;
SamplerState splr;
float4 main(float3 worldPos : Position, float3 n : Normal, float2 tc : Texcoord) : SV_Target
float4 main(float3 viewPos : Position, float3 n : Normal, float2 tc : Texcoord) : SV_Target
{
// fragment to light vector data
const float3 vToL = lightPos - worldPos;
const float3 vToL = lightPos - viewPos;
const float distToL = length(vToL);
const float3 dirToL = vToL / distToL;
// attenuation
......@@ -35,7 +35,7 @@ float4 main(float3 worldPos : Position, float3 n : Normal, float2 tc : Texcoord)
const float3 w = n * dot(vToL, n);
const float3 r = w * 2.0f - vToL;
// calculate specular intensity based on angle between viewing vector and reflection vector, narrow with power function
const float3 specular = att * (diffuseColor * diffuseIntensity) * specularIntensity * pow(max(0.0f, dot(normalize(-r), normalize(worldPos))), specularPower);
const float3 specular = att * (diffuseColor * diffuseIntensity) * specularIntensity * pow(max(0.0f, dot(normalize(-r), normalize(viewPos))), specularPower);
// final color
return float4(saturate((diffuse + ambient) * tex.Sample(splr, tc).rgb + specular), 1.0f);
}
\ No newline at end of file
cbuffer LightCBuf
{
float3 lightPos;
float3 ambient;
float3 diffuseColor;
float diffuseIntensity;
float attConst;
float attLin;
float attQuad;
};
cbuffer ObjectCBuf
{
float specularIntensity;
float specularPower;
bool normalMapEnabled;
float padding[1];
};
Texture2D tex;
Texture2D nmap : register(t2);
SamplerState splr;
float4 main(float3 viewPos : Position, float3 n : Normal, float3 tan : Tangent, float3 bitan : Bitangent, float2 tc : Texcoord) : SV_Target
{
// sample normal from map if normal mapping enabled
if( normalMapEnabled )
{
// build the tranform (rotation) into tangent space
const float3x3 tanToView = float3x3(
normalize(tan),
normalize(bitan),
normalize(n)
);
// unpack the normal from map into tangent space
const float3 normalSample = nmap.Sample(splr, tc).xyz;
n = normalSample * 2.0f - 1.0f;
n.y = -n.y;
// bring normal from tanspace into view space
n = mul(n, tanToView);
}
// fragment to light vector data
const float3 vToL = lightPos - viewPos;
const float distToL = length(vToL);
const float3 dirToL = vToL / distToL;
// attenuation
const float att = 1.0f / (attConst + attLin * distToL + attQuad * (distToL * distToL));
// diffuse intensity
const float3 diffuse = diffuseColor * diffuseIntensity * att * max(0.0f, dot(dirToL, n));
// reflected light vector
const float3 w = n * dot(vToL, n);
const float3 r = w * 2.0f - vToL;
// calculate specular intensity based on angle between viewing vector and reflection vector, narrow with power function
const float3 specular = att * (diffuseColor * diffuseIntensity) * specularIntensity * pow(max(0.0f, dot(normalize(-r), normalize(viewPos))), specularPower);
// final color
return float4(saturate((diffuse + ambient) * tex.Sample(splr, tc).rgb + specular), 1.0f);
}
\ No newline at end of file
cbuffer LightCBuf
{
float3 lightPos;
float3 ambient;
float3 diffuseColor;
float diffuseIntensity;
float attConst;
float attLin;
float attQuad;
};
cbuffer ObjectCBuf
{
float specularIntensity;
float specularPower;
bool normalMapEnabled;
float padding[1];
};
cbuffer TransformCBuf
{
matrix modelView;
matrix modelViewProj;
};
Texture2D tex;
Texture2D nmap : register(t2);
SamplerState splr;
float4 main( float3 viewPos : Position,float3 n : Normal,float2 tc : Texcoord ) : SV_Target
{
// sample normal from map if normal mapping enabled
if (normalMapEnabled)
{
// unpack normal data
const float3 normalSample = nmap.Sample(splr, tc).xyz;
n.x = normalSample.x * 2.0f - 1.0f;
n.y = -normalSample.y * 2.0f + 1.0f;
n.z = -normalSample.z * 2.0f + 1.0f;
n = mul(n, (float3x3) modelView);
}
// fragment to light vector data
const float3 vToL = lightPos - viewPos;
const float distToL = length( vToL );
const float3 dirToL = vToL / distToL;
// attenuation
const float att = 1.0f / (attConst + attLin * distToL + attQuad * (distToL * distToL));
// diffuse intensity
const float3 diffuse = diffuseColor * diffuseIntensity * att * max( 0.0f, dot( dirToL, n ) );
// reflected light vector
const float3 w = n * dot( vToL, n );
const float3 r = w * 2.0f - vToL;
// calculate specular intensity based on angle between viewing vector and reflection vector, narrow with power function
const float3 specular = att * (diffuseColor * diffuseIntensity) * specularIntensity * pow( max( 0.0f, dot( normalize( -r ), normalize( viewPos ) ) ), specularPower );
// final color
return float4( saturate( (diffuse + ambient) * tex.Sample( splr, tc ).rgb + specular ), 1.0f );
}
\ No newline at end of file
......@@ -9,16 +9,38 @@ cbuffer LightCBuf
float attQuad;
};
cbuffer ObjectCBuf
{
bool normalMapEnabled;
float padding[3];
};
Texture2D tex;
Texture2D spec;
Texture2D nmap;
SamplerState splr;
float4 main(float3 worldPos : Position, float3 n : Normal, float2 tc : Texcoord) : SV_Target
float4 main(float3 viewPos : Position, float3 n : Normal, float3 tan : Tangent, float3 bitan : Bitangent, float2 tc : Texcoord) : SV_Target
{
// sample normal from map if normal mapping enabled
if (normalMapEnabled)
{
// build the tranform (rotation) into tangent space
const float3x3 tanToView = float3x3(
normalize(tan),
normalize(bitan),
normalize(n)
);
// unpack normal data
const float3 normalSample = nmap.Sample(splr, tc).xyz;
n = normalSample * 2.0f - 1.0f;
// bring normal from tanspace into view space
n = mul(n, tanToView);
}
// fragment to light vector data
const float3 vToL = lightPos - worldPos;
const float3 vToL = lightPos - viewPos;
const float distToL = length(vToL);
const float3 dirToL = vToL / distToL;
// attenuation
......@@ -32,7 +54,7 @@ float4 main(float3 worldPos : Position, float3 n : Normal, float2 tc : Texcoord)
const float4 specularSample = spec.Sample(splr, tc);
const float3 specularReflectionColor = specularSample.rgb;
const float specularPower = pow(2.0f, specularSample.a * 13.0f);
const float3 specular = att * (diffuseColor * diffuseIntensity) * pow(max(0.0f, dot(normalize(-r), normalize(worldPos))), specularPower);
const float3 specular = att * (diffuseColor * diffuseIntensity) * pow(max(0.0f, dot(normalize(-r), normalize(viewPos))), specularPower);
// final color
return float4(saturate((diffuse + ambient) * tex.Sample(splr, tc).rgb + specular * specularReflectionColor), 1.0f);
}
\ No newline at end of file
......@@ -6,7 +6,7 @@ cbuffer CBuf
struct VSOut
{
float3 worldPos : Position;
float3 viewPos : Position;
float3 normal : Normal;
float2 tc : Texcoord;
float4 pos : SV_Position;
......@@ -15,7 +15,7 @@ struct VSOut
VSOut main(float3 pos : Position, float3 n : Normal, float2 tc : Texcoord)
{
VSOut vso;
vso.worldPos = (float3) mul(float4(pos, 1.0f), modelView);
vso.viewPos = (float3) mul(float4(pos, 1.0f), modelView);
vso.normal = mul(n, (float3x3) modelView);
vso.pos = mul(float4(pos, 1.0f), modelViewProj);
vso.tc = tc;
......
cbuffer CBuf
{
matrix modelView;
matrix modelViewProj;
};
struct VSOut
{
float3 viewPos : Position;
float3 normal : Normal;
float3 tan : Tangent;
float3 bitan : Bitangent;
float2 tc : Texcoord;
float4 pos : SV_Position;
};
VSOut main(float3 pos : Position, float3 n : Normal, float3 tan : Tangent, float3 bitan : Bitangent, float2 tc : Texcoord)
{
VSOut vso;
vso.viewPos = (float3) mul(float4(pos, 1.0f), modelView);
vso.normal = mul(n, (float3x3) modelView);
vso.tan = mul(tan, (float3x3) modelView);
vso.bitan = mul(bitan, (float3x3) modelView);
vso.pos = mul(float4(pos, 1.0f), modelViewProj);
vso.tc = tc;
return vso;
}
\ No newline at end of file