diff --git a/Assets/Textures/Skies/planets/AllSkyFree_Readme.txt b/Assets/Textures/Skies/planets/AllSkyFree_Readme.txt
new file mode 100644
index 0000000..31a5299
--- /dev/null
+++ b/Assets/Textures/Skies/planets/AllSkyFree_Readme.txt
@@ -0,0 +1,60 @@
+Welcome to AllSky Free!
+
+This is a small sample edition of the full version of Allsky.
+It contains a set of 10 skyboxes for use in your environments.
+I hope you find them useful!
+
+You can Buy the full version of AllSky here :
+
+https://assetstore.unity.com/packages/2d/textures-materials/sky/allsky-200-sky-skybox-set-10109
+
+The full version has 200 skies for Unity! Provided as 6 sided cubemaps sized from x1024 to x2048 per-side along with an equirectangular cubemap texture ranging from 4k to 16k in size. Each has an example lighting setup scene!
+
+Various styles: Day, Night, Cartoon, Fantasy, Hazy, Epic, Space, Sunless and Moonless!
+
+For lighting artists, environment artists and indie developers looking for a wide suite of skies to light their environments.
+
+Lighting from day to night: Twilight, sunset, multiple times of day, multiple times of night, skyglow.
+
+Many weather and cloud types: Clear, overcast, summery, stormy, autumnal, hazy, epic, foggy, cumulus.
+
+
+TECHNICAL
+
+ Texture format: Each sky is a 6 sided cubemap. Source PNG texture resolution per-side ranges from x1024 to x2048. Equirectangular images vary in size up to 16k textures.
+
+ Skies are sorted by time of day or style in folders.
+ Each individual sky has a folder which contains the textures and a material with those textures assigned.
+ There is also a demo scene with example lighting and fog pass for reference.
+
+ Each sky has its own 6 sided skybox material which you can set to your scene's current skybox.
+ Please consult the Unity documentation if you are unsure how to do this.
+ http://docs.unity3d.com/Manual/HOWTO-UseSkybox.html
+
+ There is also an equirectangular material. Some users report that this is preferable in their use-case or build platform.
+
+ The materials are mostly set as /mobile/skyboxes shaders - which should be fastest - but you can change them to the other skybox shaders that ship with Unity and set the required textures. Some add tint, exposure and rotation controls.
+
+ The import resolution and type of compression used on the sky textures is entirely up to you. It should be set at a level which you feel utilises appropriate amounts of memory for your game amd platform, taking into account the amount of compression artifacts that you feel are acceptable.
+
+DEMO SCENE
+
+ Each sky folder also has a demo scene. This shows a simple low-poly environment to demonstrate lighting and fog settings for that sky.
+
+ It was lit in the Forward Lighting Rendering Path with Linear lighting Color Space.
+ For intended demo scene lighting values and fog to be visible you will need a project with those settings.
+ (Under Edit->Project Settings->Player)
+ If you have to change these settings it may be necessary to re-import the sky textures.
+
+ The demo scene can benefit from increasing the Pixel light count in quality settings, and the Shadow Distance.
+
+WHO
+
+ This asset pack is by Richard Whitelock.
+ A game developer, digital artist & photographer.
+ 15+ years in the games industry working in a variety of senior art roles on 20+ titles.
+ Particularly experienced in environment art, lighting & special FX.
+ Currently working on various indie game & personal projects.
+
+ http://www.richardwhitelock.com
+
diff --git a/Assets/Textures/Skies/planets/back.png b/Assets/Textures/Skies/planets/back.png
new file mode 100644
index 0000000..5230d4b
Binary files /dev/null and b/Assets/Textures/Skies/planets/back.png differ
diff --git a/Assets/Textures/Skies/planets/down.png b/Assets/Textures/Skies/planets/down.png
new file mode 100644
index 0000000..3f16de5
Binary files /dev/null and b/Assets/Textures/Skies/planets/down.png differ
diff --git a/Assets/Textures/Skies/planets/front.png b/Assets/Textures/Skies/planets/front.png
new file mode 100644
index 0000000..16c9d85
Binary files /dev/null and b/Assets/Textures/Skies/planets/front.png differ
diff --git a/Assets/Textures/Skies/planets/left.png b/Assets/Textures/Skies/planets/left.png
new file mode 100644
index 0000000..39cd6e2
Binary files /dev/null and b/Assets/Textures/Skies/planets/left.png differ
diff --git a/Assets/Textures/Skies/planets/right.png b/Assets/Textures/Skies/planets/right.png
new file mode 100644
index 0000000..2e3e966
Binary files /dev/null and b/Assets/Textures/Skies/planets/right.png differ
diff --git a/Assets/Textures/Skies/planets/up.png b/Assets/Textures/Skies/planets/up.png
new file mode 100644
index 0000000..e9cd2c1
Binary files /dev/null and b/Assets/Textures/Skies/planets/up.png differ
diff --git a/Assets/Textures/WithNormals/cobblestone.png b/Assets/Textures/WithNormals/cobblestone.png
new file mode 100644
index 0000000..14f72ab
Binary files /dev/null and b/Assets/Textures/WithNormals/cobblestone.png differ
diff --git a/Assets/Textures/WithNormals/cobblestone_normals.png b/Assets/Textures/WithNormals/cobblestone_normals.png
new file mode 100644
index 0000000..e58bde8
Binary files /dev/null and b/Assets/Textures/WithNormals/cobblestone_normals.png differ
diff --git a/Assets/Textures/WithNormals/cobblestone_specular.png b/Assets/Textures/WithNormals/cobblestone_specular.png
new file mode 100644
index 0000000..9d46404
Binary files /dev/null and b/Assets/Textures/WithNormals/cobblestone_specular.png differ
diff --git a/Assets/Textures/WithNormals/cushion.png b/Assets/Textures/WithNormals/cushion.png
new file mode 100644
index 0000000..8a789b1
Binary files /dev/null and b/Assets/Textures/WithNormals/cushion.png differ
diff --git a/Assets/Textures/WithNormals/cushion_normals.png b/Assets/Textures/WithNormals/cushion_normals.png
new file mode 100644
index 0000000..d8ca474
Binary files /dev/null and b/Assets/Textures/WithNormals/cushion_normals.png differ
diff --git a/Assets/Textures/WithNormals/cushion_specular.png b/Assets/Textures/WithNormals/cushion_specular.png
new file mode 100644
index 0000000..394d361
Binary files /dev/null and b/Assets/Textures/WithNormals/cushion_specular.png differ
diff --git a/Assets/Textures/WithNormals/rock.png b/Assets/Textures/WithNormals/rock.png
new file mode 100644
index 0000000..e8858a3
Binary files /dev/null and b/Assets/Textures/WithNormals/rock.png differ
diff --git a/Assets/Textures/WithNormals/rock_normals.png b/Assets/Textures/WithNormals/rock_normals.png
new file mode 100644
index 0000000..ee5a435
Binary files /dev/null and b/Assets/Textures/WithNormals/rock_normals.png differ
diff --git a/Assets/Textures/WithNormals/rock_specular.png b/Assets/Textures/WithNormals/rock_specular.png
new file mode 100644
index 0000000..a6bc227
Binary files /dev/null and b/Assets/Textures/WithNormals/rock_specular.png differ
diff --git a/DX11Starter.vcxproj b/DX11Starter.vcxproj
index 5d29ec5..c06c975 100644
--- a/DX11Starter.vcxproj
+++ b/DX11Starter.vcxproj
@@ -144,6 +144,7 @@
+
@@ -156,6 +157,7 @@
+
@@ -186,6 +188,18 @@
Pixel
Pixel
+
+ Pixel
+ Pixel
+ Pixel
+ Pixel
+
+
+ Vertex
+ Vertex
+ Vertex
+ Vertex
+
Vertex
5.0
@@ -309,6 +323,7 @@
+
@@ -685,6 +700,220 @@
$(OutDir)/Assets/Textures/HQGame
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+ $(OutDir)/Assets/Textures/WithNormals
+
+
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+ $(OutDir)/Assets/Textures/Skies/planets
+
+
diff --git a/DX11Starter.vcxproj.filters b/DX11Starter.vcxproj.filters
index ba641ac..9ad1d9c 100644
--- a/DX11Starter.vcxproj.filters
+++ b/DX11Starter.vcxproj.filters
@@ -28,6 +28,15 @@
{347d5c70-73d2-4716-b28c-06526433d151}
+
+ {7476640e-6b46-49e4-a478-c3ce10b2ddca}
+
+
+ {343d3538-c075-4c73-8ca8-f919b5ba231b}
+
+
+ {f0ccea00-427b-47f7-8fce-7110b649b668}
+
@@ -60,6 +69,9 @@
Source Files
+
+ Source Files
+
@@ -95,6 +107,9 @@
Header Files
+
+ Header Files
+
@@ -109,6 +124,12 @@
Shaders
+
+ Shaders
+
+
+ Shaders
+
@@ -210,6 +231,51 @@
Assets\Textures\HQGame
+
+ Assets\Textures\WithNormals
+
+
+ Assets\Textures\WithNormals
+
+
+ Assets\Textures\WithNormals
+
+
+ Assets\Textures\WithNormals
+
+
+ Assets\Textures\WithNormals
+
+
+ Assets\Textures\WithNormals
+
+
+ Assets\Textures\WithNormals
+
+
+ Assets\Textures\WithNormals
+
+
+ Assets\Textures\WithNormals
+
+
+ Assets\Textures\Skies\planets
+
+
+ Assets\Textures\Skies\planets
+
+
+ Assets\Textures\Skies\planets
+
+
+ Assets\Textures\Skies\planets
+
+
+ Assets\Textures\Skies\planets
+
+
+ Assets\Textures\Skies\planets
+
@@ -225,5 +291,8 @@
Shaders
+
+ Shaders
+
\ No newline at end of file
diff --git a/Defines.hlsli b/Defines.hlsli
index e31b1ae..19e0c25 100644
--- a/Defines.hlsli
+++ b/Defines.hlsli
@@ -16,6 +16,7 @@ struct VertexToPixel
float2 uv : TEXCOORD;
float3 normal : NORMAL;
float3 worldPosition : POSITION;
+ float3 tangent : TANGENT;
};
// Struct representing a single vertex worth of data
@@ -29,6 +30,7 @@ struct VertexShaderInput
// v v v
float3 localPosition : POSITION;
float3 normal : NORMAL;
+ float3 tangent : TANGENT;
float2 uv : TEXCOORD;
};
diff --git a/Game.cpp b/Game.cpp
index 1381f94..04b19dd 100644
--- a/Game.cpp
+++ b/Game.cpp
@@ -80,6 +80,8 @@ void Game::LoadShadersAndMaterials()
materials = {
std::make_shared(white, 0, vertexShader, pixelShader),
std::make_shared(white, 0, vertexShader, pixelShader),
+ std::make_shared(white, 0, vertexShader, pixelShader),
+ std::make_shared(white, 0, vertexShader, pixelShader),
};
}
@@ -88,8 +90,6 @@ void Game::LoadShadersAndMaterials()
// --------------------------------------------------------
void Game::LoadTextures()
{
- Microsoft::WRL::ComPtr sampler;
-
D3D11_SAMPLER_DESC sampDesc = {};
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
@@ -99,15 +99,44 @@ void Game::LoadTextures()
sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
device->CreateSamplerState(&sampDesc, sampler.GetAddressOf());
+ demoCubemap = CreateCubemap(
+ device,
+ context,
+ L"Assets/Textures/Skies/planets/right.png",
+ L"Assets/Textures/Skies/planets/left.png",
+ L"Assets/Textures/Skies/planets/up.png",
+ L"Assets/Textures/Skies/planets/down.png",
+ L"Assets/Textures/Skies/planets/front.png",
+ L"Assets/Textures/Skies/planets/back.png"
+ );
+
materials[0]->PushSampler("BasicSampler", sampler);
+ materials[0]->PushTexture(TEXTYPE_REFLECTION, demoCubemap);
+ materials[0]->hasReflectionMap = true;
materials[0]->LoadTexture(L"Assets/Textures/HQGame/structure-endgame-deepfloor_albedo.png", TEXTYPE_ALBEDO, device.Get(), context.Get());
materials[0]->LoadTexture(L"Assets/Textures/HQGame/structure-endgame-deepfloor_specular.png", TEXTYPE_SPECULAR, device.Get(), context.Get());
materials[0]->LoadTexture(L"Assets/Textures/HQGame/structure-endgame-deepfloor_emissive.png", TEXTYPE_EMISSIVE, device.Get(), context.Get());
materials[1]->PushSampler("BasicSampler", sampler);
- materials[1]->LoadTexture(L"Assets/Textures/HQGame/structure-endgame-floor_albedo.png", TEXTYPE_ALBEDO, device.Get(), context.Get());
- materials[1]->LoadTexture(L"Assets/Textures/HQGame/structure-endgame-floor_specular.png", TEXTYPE_SPECULAR, device.Get(), context.Get());
- materials[1]->LoadTexture(L"Assets/Textures/HQGame/structure-endgame-floor_emissive.png", TEXTYPE_EMISSIVE, device.Get(), context.Get());
+ materials[1]->PushTexture(TEXTYPE_REFLECTION, demoCubemap);
+ materials[1]->hasReflectionMap = true;
+ materials[1]->LoadTexture(L"Assets/Textures/WithNormals/cobblestone.png", TEXTYPE_ALBEDO, device.Get(), context.Get());
+ materials[1]->LoadTexture(L"Assets/Textures/WithNormals/cobblestone_specular.png", TEXTYPE_SPECULAR, device.Get(), context.Get());
+ materials[1]->LoadTexture(L"Assets/Textures/WithNormals/cobblestone_normals.png", TEXTYPE_NORMAL, device.Get(), context.Get());
+
+ materials[2]->PushSampler("BasicSampler", sampler);
+ materials[2]->PushTexture(TEXTYPE_REFLECTION, demoCubemap);
+ materials[2]->hasReflectionMap = true;
+ materials[2]->LoadTexture(L"Assets/Textures/WithNormals/rock.png", TEXTYPE_ALBEDO, device.Get(), context.Get());
+ materials[2]->LoadTexture(L"Assets/Textures/WithNormals/rock_specular.png", TEXTYPE_SPECULAR, device.Get(), context.Get());
+ materials[2]->LoadTexture(L"Assets/Textures/WithNormals/rock_normals.png", TEXTYPE_NORMAL, device.Get(), context.Get());
+
+ materials[3]->PushSampler("BasicSampler", sampler);
+ materials[3]->PushTexture(TEXTYPE_REFLECTION, demoCubemap);
+ materials[3]->hasReflectionMap = true;
+ materials[3]->LoadTexture(L"Assets/Textures/WithNormals/cushion.png", TEXTYPE_ALBEDO, device.Get(), context.Get());
+ materials[3]->LoadTexture(L"Assets/Textures/WithNormals/cushion_specular.png", TEXTYPE_SPECULAR, device.Get(), context.Get());
+ materials[3]->LoadTexture(L"Assets/Textures/WithNormals/cushion_normals.png", TEXTYPE_NORMAL, device.Get(), context.Get());
}
// --------------------------------------------------------
@@ -118,12 +147,13 @@ void Game::LoadLighting()
ambient = XMFLOAT3(0.1f, 0.1f, 0.15f);
lights = {
- Light::Directional(XMFLOAT3(1, 0.5f, 0.5f), XMFLOAT3(1, 1, 1), 0.5f),
- Light::Directional(XMFLOAT3(-0.25f, -1, 0.75f), XMFLOAT3(1, 1, 1), 0.5f),
- Light::Directional(XMFLOAT3(-1, 1, -0.5f), XMFLOAT3(1, 1, 1), 0.5f),
+ Light::Directional(XMFLOAT3(1, 0.5f, 0.5f), XMFLOAT3(1, 1, 1), 0.75f),
+ Light::Directional(XMFLOAT3(-0.25f, -1, 0.75f), XMFLOAT3(1, 1, 1), 0.75f),
+ Light::Directional(XMFLOAT3(-1, 1, -0.5f), XMFLOAT3(1, 1, 1), 0.75f),
Light::Point(XMFLOAT3(-1.5f, 0, 0), XMFLOAT3(1, 1, 1), 0.5f, 10),
Light::Point(XMFLOAT3(1.5f, 0, 0), XMFLOAT3(1, 1, 1), 0.25f, 10),
Light::Point(XMFLOAT3(0, 2, 0), XMFLOAT3(1, 0, 0), 0.25f, 10),
+ Light::Point(XMFLOAT3(-27.5f, 0, 0), XMFLOAT3(1, 1, 0.5f), 5, 20),
};
}
@@ -157,20 +187,31 @@ void Game::CreateBasicGeometry()
};
entities = {
- std::make_shared(materials[0], shapes[0]),
- std::make_shared(materials[0], shapes[1]),
- std::make_shared(materials[0], shapes[2]),
- std::make_shared(materials[0], shapes[3]),
+ std::make_shared(materials[1], shapes[0]),
+ std::make_shared(materials[2], shapes[1]),
+ std::make_shared(materials[3], shapes[2]),
+ std::make_shared(materials[2], shapes[3]),
std::make_shared(materials[1], shapes[4]),
- std::make_shared(materials[1], shapes[5]),
- std::make_shared(materials[1], shapes[6]),
+ std::make_shared(materials[0], shapes[5]),
+ std::make_shared(materials[0], shapes[6]),
};
+ entities[6]->GetMaterial()->SetEmitAmount(0.75f);
+
for (int i = 0; i < entities.size(); ++i)
{
entities[i]->GetTransform()->SetPosition((-(int)(entities.size() / 2) + i) * 5, 0, 0);
- entities[i]->GetMaterial()->SetEmitAmount((entities.size() - i) * 0.25f);
+ entities[i]->GetMaterial()->SetRoughness(0.60f);
}
+
+ skybox = std::make_shared(
+ shapes[0],
+ std::make_shared(device, context, GetFullPathTo_Wide(L"SkyboxVertexShader.cso").c_str()),
+ std::make_shared(device, context, GetFullPathTo_Wide(L"SkyboxPixelShader.cso").c_str()),
+ demoCubemap,
+ sampler,
+ device
+ );
}
@@ -226,6 +267,8 @@ void Game::Draw(float deltaTime, float totalTime)
entity->Draw(camera, ambient, lights);
}
+ skybox->Draw(context, camera);
+
// Present the back buffer to the user
// - Puts the final frame we're drawing into the window so the user can see it
// - Do this exactly ONCE PER FRAME (always at the very end of the frame)
@@ -234,4 +277,113 @@ void Game::Draw(float deltaTime, float totalTime)
// Due to the usage of a more sophisticated swap chain,
// the render target must be re-bound after every call to Present()
context->OMSetRenderTargets(1, backBufferRTV.GetAddressOf(), depthStencilView.Get());
-}
\ No newline at end of file
+}
+
+// --------------------------------------------------------
+// Loads six individual textures (the six faces of a cube map), then
+// creates a blank cube map and copies each of the six textures to
+// another face. Afterwards, creates a shader resource view for
+// the cube map and cleans up all of the temporary resources.
+// --------------------------------------------------------
+Microsoft::WRL::ComPtr Game::CreateCubemap(
+ Microsoft::WRL::ComPtr device,
+ Microsoft::WRL::ComPtr context,
+ const wchar_t* right,
+ const wchar_t* left,
+ const wchar_t* up,
+ const wchar_t* down,
+ const wchar_t* front,
+ const wchar_t* back)
+{
+
+// --------------------------------------------------------
+// Author: Chris Cascioli
+// Purpose: Creates a cube map on the GPU from 6 individual textures
+//
+// - You are allowed to directly copy/paste this into your code base
+// for assignments, given that you clearly cite that this is not
+// code of your own design.
+//
+// - Note: This code assumes you’re putting the function in Game.cpp,
+// you’ve included WICTextureLoader.h and you have an ID3D11Device
+// ComPtr called “device”. Make any adjustments necessary for
+// your own implementation.
+// --------------------------------------------------------
+
+ // Load the 6 textures into an array.
+ // - We need references to the TEXTURES, not the SHADER RESOURCE VIEWS!
+ // - Specifically NOT generating mipmaps, as we usually don't need them for the sky!
+ // - Order matters here! +X, -X, +Y, -Y, +Z, -Z
+ ID3D11Texture2D* textures[6] = {};
+ CreateWICTextureFromFile(device.Get(), right, (ID3D11Resource**)&textures[0], 0);
+ CreateWICTextureFromFile(device.Get(), left, (ID3D11Resource**)&textures[1], 0);
+ CreateWICTextureFromFile(device.Get(), up, (ID3D11Resource**)&textures[2], 0);
+ CreateWICTextureFromFile(device.Get(), down, (ID3D11Resource**)&textures[3], 0);
+ CreateWICTextureFromFile(device.Get(), front, (ID3D11Resource**)&textures[4], 0);
+ CreateWICTextureFromFile(device.Get(), back, (ID3D11Resource**)&textures[5], 0);
+
+ // We'll assume all of the textures are the same color format and resolution,
+ // so get the description of the first shader resource view
+ D3D11_TEXTURE2D_DESC faceDesc = {};
+ textures[0]->GetDesc(&faceDesc);
+
+ // Describe the resource for the cube map, which is simply
+ // a "texture 2d array". This is a special GPU resource format,
+ // NOT just a C++ array of textures!!!
+ D3D11_TEXTURE2D_DESC cubeDesc = {};
+ cubeDesc.ArraySize = 6; // Cube map!
+ cubeDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; // We'll be using as a texture in a shader
+ cubeDesc.CPUAccessFlags = 0; // No read back
+ cubeDesc.Format = faceDesc.Format; // Match the loaded texture's color format
+ cubeDesc.Width = faceDesc.Width; // Match the size
+ cubeDesc.Height = faceDesc.Height; // Match the size
+ cubeDesc.MipLevels = 1; // Only need 1
+ cubeDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; // A CUBE MAP, not 6 separate textures
+ cubeDesc.Usage = D3D11_USAGE_DEFAULT; // Standard usage
+ cubeDesc.SampleDesc.Count = 1;
+ cubeDesc.SampleDesc.Quality = 0;
+
+ // Create the actual texture resource
+ ID3D11Texture2D* cubeMapTexture = 0;
+ device->CreateTexture2D(&cubeDesc, 0, &cubeMapTexture);
+
+ // Loop through the individual face textures and copy them,
+ // one at a time, to the cube map texure
+ for (int i = 0; i < 6; i++)
+ {
+ // Calculate the subresource position to copy into
+ unsigned int subresource = D3D11CalcSubresource(
+ 0, // Which mip (zero, since there's only one)
+ i, // Which array element?
+ 1); // How many mip levels are in the texture?
+
+ // Copy from one resource (texture) to another
+ context->CopySubresourceRegion(
+ cubeMapTexture, // Destination resource
+ subresource, // Dest subresource index (one of the array elements)
+ 0, 0, 0, // XYZ location of copy
+ textures[i], // Source resource
+ 0, // Source subresource index (we're assuming there's only one)
+ 0); // Source subresource "box" of data to copy (zero means the whole thing)
+ }
+
+ // At this point, all of the faces have been copied into the
+ // cube map texture, so we can describe a shader resource view for it
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
+ srvDesc.Format = cubeDesc.Format; // Same format as texture
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; // Treat this as a cube!
+ srvDesc.TextureCube.MipLevels = 1; // Only need access to 1 mip
+ srvDesc.TextureCube.MostDetailedMip = 0; // Index of the first mip we want to see
+
+ // Make the SRV
+ Microsoft::WRL::ComPtr cubeSRV;
+ device->CreateShaderResourceView(cubeMapTexture, &srvDesc, cubeSRV.GetAddressOf());
+
+ // Now that we're done, clean up the stuff we don't need anymore
+ cubeMapTexture->Release(); // Done with this particular reference (the SRV has another)
+ for (int i = 0; i < 6; i++)
+ textures[i]->Release();
+
+ // Send back the SRV, which is what we need for our shaders
+ return cubeSRV;
+}
diff --git a/Game.h b/Game.h
index f62f3f3..ceed40c 100644
--- a/Game.h
+++ b/Game.h
@@ -7,6 +7,7 @@
#include "SimpleShader.h"
#include "Material.h"
#include "Lights.h"
+#include "Sky.h"
#include
#include // Used for ComPtr - a smart pointer for COM objects
#include
@@ -19,10 +20,20 @@ public:
Game(HINSTANCE hInstance);
~Game();
- void Init();
- void OnResize();
- void Update(float deltaTime, float totalTime);
- void Draw(float deltaTime, float totalTime);
+ void Init();
+ void OnResize();
+ void Update(float deltaTime, float totalTime);
+ void Draw(float deltaTime, float totalTime);
+
+ static Microsoft::WRL::ComPtr CreateCubemap(
+ Microsoft::WRL::ComPtr _device,
+ Microsoft::WRL::ComPtr _context,
+ const wchar_t* _right,
+ const wchar_t* _left,
+ const wchar_t* _up,
+ const wchar_t* _down,
+ const wchar_t* _front,
+ const wchar_t* _back);
private:
// Should we use vsync to limit the frame rate?
@@ -48,6 +59,10 @@ private:
// A7 Lights
std::vector lights;
DirectX::XMFLOAT3 ambient;
+ // A9 Normalmaps & Cubemaps
+ std::shared_ptr skybox;
+ Microsoft::WRL::ComPtr sampler;
+ Microsoft::WRL::ComPtr demoCubemap;
Microsoft::WRL::ComPtr constantBufferVS;
};
diff --git a/Helpers.hlsli b/Helpers.hlsli
index f674ce4..4e9a634 100644
--- a/Helpers.hlsli
+++ b/Helpers.hlsli
@@ -1,6 +1,9 @@
#ifndef __SHADER_HELPERS__
#define __SHADER_HELPERS__
+// from environment map demo
+static const float F0_NON_METAL = 0.04f;
+
// gets view vector, needed once per shader
float3 getView(float3 cameraPosition, float3 pixelWorldPosition)
{
@@ -44,4 +47,11 @@ float getAttenuation(float3 pointPosition, float3 worldPosition, float3 range)
return attn * attn;
}
+// from environment map demo
+// gets fresnel (Schlick approx.): f0 + (1-f0)(1 - (n dot v))^5
+float getFresnel(float3 normal, float3 view, float specularValue)
+{
+ return specularValue + (1 - specularValue) * pow(1 - saturate(dot(normal, view)), 5);
+}
+
#endif
diff --git a/Lights.hlsli b/Lights.hlsli
index 3fd4973..633e801 100644
--- a/Lights.hlsli
+++ b/Lights.hlsli
@@ -22,4 +22,35 @@ struct Light
float3 Padding;
};
+// Gets the specular value for any light
+float calculateSpecular(float3 normal, float3 direction, float3 view, float roughness, float diffuse)
+{
+ return getSpecular(
+ view,
+ getReflection(direction, normal),
+ getSpecularExponent(roughness, MAX_SPECULAR_EXPONENT)
+ ) * any(diffuse);
+}
+
+// Gets the RGB value of a pixel with a directional light
+float3 calculateDirectionalLight(Light light, float3 normal, float3 view, float roughness, float3 surfaceColor, float specularValue)
+{
+ float3 lightDirection = normalize(light.Direction);
+ float diffuse = getDiffuse(normal, -lightDirection);
+ float specular = calculateSpecular(normal, lightDirection, view, roughness, diffuse) * specularValue;
+
+ return (diffuse * surfaceColor + specular) * light.Intensity * light.Color;
+}
+
+// Gets the RGB value of a pixel with a point light
+float3 calculatePointLight(Light light, float3 normal, float3 view, float3 worldPosition, float roughness, float3 surfaceColor, float specularValue)
+{
+ float3 lightDirection = normalize(light.Position - worldPosition);
+ float attenuation = getAttenuation(light.Position, worldPosition, light.Range);
+ float diffuse = getDiffuse(normal, lightDirection);
+ float specular = calculateSpecular(normal, lightDirection, view, roughness, diffuse) * specularValue;
+
+ return (diffuse * surfaceColor + specular) * attenuation * light.Intensity * light.Color;
+}
+
#endif
diff --git a/Material.cpp b/Material.cpp
index dc99ff6..9ca9fbd 100644
--- a/Material.cpp
+++ b/Material.cpp
@@ -13,6 +13,10 @@ Material::Material(
uvOffset = DirectX::XMFLOAT2(0, 0);
uvScale = DirectX::XMFLOAT2(1, 1);
emitAmount = 0;
+ hasEmissiveMap = false;
+ hasSpecularMap = false;
+ hasNormalMap = false;
+ hasReflectionMap = false;
}
Material::~Material()
@@ -36,6 +40,10 @@ void Material::Activate(Transform* _transform, std::shared_ptr _camera,
pixelShader->SetFloat("emitAmount", GetEmitAmount());
pixelShader->SetFloat3("tint", GetTint());
pixelShader->SetFloat("lightCount", (int)_lights.size());
+ pixelShader->SetInt("hasEmissiveMap", (int)hasEmissiveMap);
+ pixelShader->SetInt("hasSpecularMap", (int)hasSpecularMap);
+ pixelShader->SetInt("hasNormalMap", (int)hasNormalMap);
+ pixelShader->SetInt("hasReflectionMap", (int)hasReflectionMap);
pixelShader->SetData("lights", &_lights[0], sizeof(Light) * (int)_lights.size());
pixelShader->CopyAllBufferData();
pixelShader->SetShader();
@@ -136,6 +144,11 @@ void Material::LoadTexture(const wchar_t* _path, const char* _type, ID3D11Device
Microsoft::WRL::ComPtr shaderResourceView;
DirectX::CreateWICTextureFromFile(_device, _context, DXCore::GetFullPathTo_Wide(_path).c_str(), 0, shaderResourceView.GetAddressOf());
PushTexture(_type, shaderResourceView);
+
+ if (_type == TEXTYPE_EMISSIVE) hasEmissiveMap = true;
+ else if (_type == TEXTYPE_SPECULAR) hasSpecularMap = true;
+ else if (_type == TEXTYPE_NORMAL) hasNormalMap = true;
+ else if (_type == TEXTYPE_REFLECTION) hasReflectionMap = true;
}
void Material::PushSampler(std::string _name, Microsoft::WRL::ComPtr _sampler)
diff --git a/Material.h b/Material.h
index cdbd90b..3375880 100644
--- a/Material.h
+++ b/Material.h
@@ -13,6 +13,7 @@ constexpr auto TEXTYPE_ALBEDO = "Albedo";
constexpr auto TEXTYPE_NORMAL = "Normal";
constexpr auto TEXTYPE_EMISSIVE = "Emissive";
constexpr auto TEXTYPE_SPECULAR = "Specular";
+constexpr auto TEXTYPE_REFLECTION = "Reflection";
class Material
{
@@ -50,6 +51,10 @@ public:
void PushSampler(std::string _name, Microsoft::WRL::ComPtr _sampler);
void PushTexture(std::string _name, Microsoft::WRL::ComPtr _texture);
+ bool hasEmissiveMap;
+ bool hasSpecularMap;
+ bool hasNormalMap;
+ bool hasReflectionMap;
private:
DirectX::XMFLOAT3 tint;
float roughness;
diff --git a/Mesh.cpp b/Mesh.cpp
index f1a0bbd..78e5fa1 100644
--- a/Mesh.cpp
+++ b/Mesh.cpp
@@ -230,9 +230,100 @@ Mesh::Mesh(const char* _file, Microsoft::WRL::ComPtr _device, Micr
// sophisticated model loading library like TinyOBJLoader or AssImp (yes, that's its name)
/// END OBJLOADER ///
+ CalculateTangents(&verts[0], verts.size(), &indices[0], indices.size());
CreateMesh(&verts[0], verts.size(), &indices[0], indices.size(), _device, _context);
}
+// --------------------------------------------------------
+// Author: Chris Cascioli
+// Purpose: Calculates the tangents of the vertices in a mesh
+//
+// - You are allowed to directly copy/paste this into your code base
+// for assignments, given that you clearly cite that this is not
+// code of your own design.
+//
+// - Code originally adapted from: http://www.terathon.com/code/tangent.html
+// - Updated version now found here: http://foundationsofgameenginedev.com/FGED2-sample.pdf
+// - See listing 7.4 in section 7.5 (page 9 of the PDF)
+//
+// - Note: For this code to work, your Vertex format must
+// contain an XMFLOAT3 called Tangent
+//
+// - Be sure to call this BEFORE creating your D3D vertex/index buffers
+// --------------------------------------------------------
+void Mesh::CalculateTangents(Vertex* verts, int numVerts, unsigned int* indices, int numIndices)
+{
+ // Reset tangents
+ for (int i = 0; i < numVerts; i++)
+ {
+ verts[i].Tangent = XMFLOAT3(0, 0, 0);
+ }
+
+ // Calculate tangents one whole triangle at a time
+ for (int i = 0; i < numIndices;)
+ {
+ // Grab indices and vertices of first triangle
+ unsigned int i1 = indices[i++];
+ unsigned int i2 = indices[i++];
+ unsigned int i3 = indices[i++];
+ Vertex* v1 = &verts[i1];
+ Vertex* v2 = &verts[i2];
+ Vertex* v3 = &verts[i3];
+
+ // Calculate vectors relative to triangle positions
+ float x1 = v2->Position.x - v1->Position.x;
+ float y1 = v2->Position.y - v1->Position.y;
+ float z1 = v2->Position.z - v1->Position.z;
+
+ float x2 = v3->Position.x - v1->Position.x;
+ float y2 = v3->Position.y - v1->Position.y;
+ float z2 = v3->Position.z - v1->Position.z;
+
+ // Do the same for vectors relative to triangle uv's
+ float s1 = v2->UV.x - v1->UV.x;
+ float t1 = v2->UV.y - v1->UV.y;
+
+ float s2 = v3->UV.x - v1->UV.x;
+ float t2 = v3->UV.y - v1->UV.y;
+
+ // Create vectors for tangent calculation
+ float r = 1.0f / (s1 * t2 - s2 * t1);
+
+ float tx = (t2 * x1 - t1 * x2) * r;
+ float ty = (t2 * y1 - t1 * y2) * r;
+ float tz = (t2 * z1 - t1 * z2) * r;
+
+ // Adjust tangents of each vert of the triangle
+ v1->Tangent.x += tx;
+ v1->Tangent.y += ty;
+ v1->Tangent.z += tz;
+
+ v2->Tangent.x += tx;
+ v2->Tangent.y += ty;
+ v2->Tangent.z += tz;
+
+ v3->Tangent.x += tx;
+ v3->Tangent.y += ty;
+ v3->Tangent.z += tz;
+ }
+
+ // Ensure all of the tangents are orthogonal to the normals
+ for (int i = 0; i < numVerts; i++)
+ {
+ // Grab the two vectors
+ XMVECTOR normal = XMLoadFloat3(&verts[i].Normal);
+ XMVECTOR tangent = XMLoadFloat3(&verts[i].Tangent);
+
+ // Use Gram-Schmidt orthonormalize to ensure
+ // the normal and tangent are exactly 90 degrees apart
+ tangent = XMVector3Normalize(
+ tangent - normal * XMVector3Dot(normal, tangent));
+
+ // Store the tangent
+ XMStoreFloat3(&verts[i].Tangent, tangent);
+ }
+}
+
void Mesh::CreateMesh(Vertex* _vertices, int _vertexCount, unsigned int* _indices, int _indexCount, Microsoft::WRL::ComPtr _device, Microsoft::WRL::ComPtr _context)
{
// Create the VERTEX BUFFER description
diff --git a/Mesh.h b/Mesh.h
index ad90b4d..c912c4a 100644
--- a/Mesh.h
+++ b/Mesh.h
@@ -31,6 +31,11 @@ private:
Microsoft::WRL::ComPtr deviceContext;
int countIndex;
+ void CalculateTangents(
+ Vertex* _verts,
+ int _numVerts,
+ unsigned int* _indices,
+ int _numIndices);
void CreateMesh(
Vertex* _vertices,
int _vertexCount,
diff --git a/SimplePixelShader.hlsl b/SimplePixelShader.hlsl
index a7c90d2..7c986d6 100644
--- a/SimplePixelShader.hlsl
+++ b/SimplePixelShader.hlsl
@@ -18,58 +18,45 @@ cbuffer ExternalData : register(b0)
float3 tint;
float lightCount;
+ int hasEmissiveMap;
+ int hasSpecularMap;
+ int hasNormalMap;
+ int hasReflectionMap;
+
Light lights[MAX_LIGHTS];
}
Texture2D Albedo : register(t0);
Texture2D Specular : register(t1);
Texture2D Emissive : register(t2);
+Texture2D Normal : register(t3);
+TextureCube Reflection : register(t4);
SamplerState BasicSampler : register(s0);
-// Gets the specular value for any light
-float calculateSpecular(float3 normal, float3 direction, float3 view, float roughness)
-{
- return getSpecular(
- view,
- getReflection(direction, normal),
- getSpecularExponent(roughness, MAX_SPECULAR_EXPONENT)
- );
-}
-
-// Gets the RGB value of a pixel with a directional light
-float3 calculateDirectionalLight(Light light, float3 normal, float3 view, float roughness, float3 surfaceColor, float specularValue)
-{
- float3 lightDirection = normalize(light.Direction);
- float diffuse = getDiffuse(normal, -lightDirection);
- float specular = calculateSpecular(normal, lightDirection, view, roughness) * specularValue;
-
- return (diffuse * surfaceColor + specular) * light.Intensity * light.Color;
-}
-
-// Gets the RGB value of a pixel with a point light
-float3 calculatePointLight(Light light, float3 normal, float3 view, float3 worldPosition, float roughness, float3 surfaceColor, float specularValue)
-{
- float3 lightDirection = normalize(light.Position - worldPosition);
- float attenuation = getAttenuation(light.Position, worldPosition, light.Range);
- float diffuse = getDiffuse(normal, lightDirection);
- float specular = calculateSpecular(normal, lightDirection, view, roughness) * specularValue;
-
- return (diffuse * surfaceColor + specular) * attenuation * light.Intensity * light.Color;
-}
-
// shader entry point
float4 main(VertexToPixel input) : SV_TARGET
{
// ensure input normals are normalized
input.normal = normalize(input.normal);
+ input.tangent = normalize(input.tangent);
+ if (hasNormalMap > 0)
+ {
+ float3 unpackedNormal = Normal.Sample(BasicSampler, input.uv).rgb * 2 - 1;
+ float3 T = normalize(input.tangent - input.normal * dot(input.tangent, input.normal));
+ float3 B = cross(T, input.normal);
+ float3x3 TBN = float3x3(T, B, input.normal);
+ input.normal = mul(unpackedNormal, TBN);
+ }
input.uv = input.uv * scale + offset;
// view only needs calculated once, so pre-calculate here and pass it to lights
float3 view = getView(cameraPosition, input.worldPosition);
float4 albedo = Albedo.Sample(BasicSampler, input.uv).rgba;
- float specular = Specular.Sample(BasicSampler, input.uv).r;
- float3 emit = Emissive.Sample(BasicSampler, input.uv).rgb;
+ float specular = 1;
+ if (hasSpecularMap > 0) specular = Specular.Sample(BasicSampler, input.uv).r;
+ float3 emit = float3(1, 1, 1);
+ if (hasEmissiveMap > 0) emit = Emissive.Sample(BasicSampler, input.uv).rgb;
float3 surface = albedo.rgb * tint;
float3 light = ambient * surface;
@@ -87,5 +74,14 @@ float4 main(VertexToPixel input) : SV_TARGET
}
}
- return float4(light + (emit * emitAmount), albedo.a);
+ float3 final = float3(light + (emit * emitAmount));
+
+ if (hasReflectionMap > 0)
+ {
+ float3 reflVec = getReflection(view, input.normal);
+ float3 reflCol = Reflection.Sample(BasicSampler, reflVec).rgba;
+ final = lerp(final, reflCol, getFresnel(input.normal, view, F0_NON_METAL));
+ }
+
+ return float4(final, albedo.a);
}
diff --git a/Sky.cpp b/Sky.cpp
new file mode 100644
index 0000000..8a54ed2
--- /dev/null
+++ b/Sky.cpp
@@ -0,0 +1,51 @@
+#include "Sky.h"
+
+Sky::Sky(
+ std::shared_ptr _mesh,
+ std::shared_ptr _vertexShader,
+ std::shared_ptr _pixelShader,
+ Microsoft::WRL::ComPtr _cubemap,
+ Microsoft::WRL::ComPtr _sampler,
+ Microsoft::WRL::ComPtr _device)
+{
+ mesh = _mesh;
+ cubemap = _cubemap;
+ sampler = _sampler;
+ vertexShader = _vertexShader;
+ pixelShader = _pixelShader;
+
+ D3D11_RASTERIZER_DESC rDesc = {};
+ rDesc.FillMode = D3D11_FILL_SOLID;
+ rDesc.CullMode = D3D11_CULL_FRONT;
+ _device->CreateRasterizerState(&rDesc, rasterizerState.GetAddressOf());
+
+ D3D11_DEPTH_STENCIL_DESC dDesc = {};
+ dDesc.DepthEnable = true;
+ dDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
+ _device->CreateDepthStencilState(&dDesc, depthState.GetAddressOf());
+}
+
+Sky::~Sky()
+{
+}
+
+void Sky::Draw(Microsoft::WRL::ComPtr _context, std::shared_ptr _camera)
+{
+ _context->RSSetState(rasterizerState.Get());
+ _context->OMSetDepthStencilState(depthState.Get(), 0);
+
+ vertexShader->SetMatrix4x4("view", _camera->GetViewMatrix());
+ vertexShader->SetMatrix4x4("projection", _camera->GetProjectionMatrix());
+ vertexShader->CopyAllBufferData();
+ vertexShader->SetShader();
+
+ pixelShader->SetShaderResourceView("SkyTexture", cubemap.Get());
+ pixelShader->SetSamplerState("Sampler", sampler.Get());
+ pixelShader->CopyAllBufferData();
+ pixelShader->SetShader();
+
+ mesh->Draw();
+
+ _context->RSSetState(0);
+ _context->OMSetDepthStencilState(0, 0);
+}
diff --git a/Sky.h b/Sky.h
new file mode 100644
index 0000000..b0bb454
--- /dev/null
+++ b/Sky.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include
+#include
+#include
+#include "Mesh.h"
+#include "SimpleShader.h"
+#include "Camera.h"
+
+class Sky
+{
+public:
+ Sky(
+ std::shared_ptr _mesh,
+ std::shared_ptr _vertexShader,
+ std::shared_ptr _pixelShader,
+ Microsoft::WRL::ComPtr _cubemap,
+ Microsoft::WRL::ComPtr _sampler,
+ Microsoft::WRL::ComPtr _device);
+ ~Sky();
+
+ void Draw(
+ Microsoft::WRL::ComPtr _context,
+ std::shared_ptr _camera);
+
+private:
+ Microsoft::WRL::ComPtr sampler;
+ Microsoft::WRL::ComPtr depthState;
+ Microsoft::WRL::ComPtr rasterizerState;
+ Microsoft::WRL::ComPtr cubemap;
+ std::shared_ptr mesh;
+ std::shared_ptr vertexShader;
+ std::shared_ptr pixelShader;
+};
diff --git a/SkyboxDefines.hlsli b/SkyboxDefines.hlsli
new file mode 100644
index 0000000..f70fc71
--- /dev/null
+++ b/SkyboxDefines.hlsli
@@ -0,0 +1,20 @@
+#ifndef __SKYBOX_DEFINES__
+#define __SKYBOX_DEFINES__
+
+struct SkyboxVertexToPixel
+{
+ float4 screenPosition : SV_POSITION;
+ float3 sampleDir : DIRECTION;
+};
+
+// Struct representing a single vertex worth of data
+// - This should match Vertex.h
+struct SkyboxVertexShaderInput
+{
+ float3 localPosition : POSITION;
+ float3 normal : NORMAL;
+ float3 tangent : TANGENT;
+ float2 uv : TEXCOORD;
+};
+
+#endif
diff --git a/SkyboxPixelShader.hlsl b/SkyboxPixelShader.hlsl
new file mode 100644
index 0000000..cf63c2a
--- /dev/null
+++ b/SkyboxPixelShader.hlsl
@@ -0,0 +1,9 @@
+#include "SkyboxDefines.hlsli"
+
+TextureCube SkyTexture : register(t0);
+SamplerState Sampler : register(s0);
+
+float4 main(SkyboxVertexToPixel input) : SV_TARGET
+{
+ return SkyTexture.Sample(Sampler, input.sampleDir);
+}
diff --git a/SkyboxVertexShader.hlsl b/SkyboxVertexShader.hlsl
new file mode 100644
index 0000000..0b822ec
--- /dev/null
+++ b/SkyboxVertexShader.hlsl
@@ -0,0 +1,25 @@
+#include "SkyboxDefines.hlsli"
+
+cbuffer ExternalData : register(b0)
+{
+ matrix view;
+ matrix projection;
+}
+
+matrix RemoveTranslation(matrix m)
+{
+ m._14 = 0;
+ m._24 = 0;
+ m._34 = 0;
+ return m;
+}
+
+SkyboxVertexToPixel main(SkyboxVertexShaderInput input)
+{
+ SkyboxVertexToPixel output;
+ matrix worldViewProjection = mul(projection, RemoveTranslation(view));
+ output.screenPosition = mul(worldViewProjection, float4(input.localPosition, 1.0f));
+ output.screenPosition.z = output.screenPosition.w;
+ output.sampleDir = input.localPosition;
+ return output;
+}
diff --git a/Vertex.h b/Vertex.h
index fe94c18..eef37ea 100644
--- a/Vertex.h
+++ b/Vertex.h
@@ -11,5 +11,6 @@ struct Vertex
{
DirectX::XMFLOAT3 Position;
DirectX::XMFLOAT3 Normal;
+ DirectX::XMFLOAT3 Tangent;
DirectX::XMFLOAT2 UV;
};
\ No newline at end of file
diff --git a/VertexShader.hlsl b/VertexShader.hlsl
index 85973ee..30950f7 100644
--- a/VertexShader.hlsl
+++ b/VertexShader.hlsl
@@ -40,6 +40,7 @@ VertexToPixel main( VertexShaderInput input )
// Pass normal and world position throuh
output.normal = normalize(mul((float3x3)worldInvTranspose, input.normal));
+ output.tangent = normalize(mul((float3x3)worldInvTranspose, input.tangent));
output.worldPosition = mul(world, float4(input.localPosition, 1)).xyz;
// Whatever we return will make its way through the pipeline to the