diff --git a/Code/OysterGraphics/Core/Core.h b/Code/OysterGraphics/Core/Core.h index 7d886dc6..126323eb 100644 --- a/Code/OysterGraphics/Core/Core.h +++ b/Code/OysterGraphics/Core/Core.h @@ -7,6 +7,7 @@ #include "Dx11Includes.h" #include #include "OysterMath.h" +#include namespace Oyster { diff --git a/Code/OysterGraphics/Core/PipelineManager.cpp b/Code/OysterGraphics/Core/PipelineManager.cpp index b9a4df14..ae9e4088 100644 --- a/Code/OysterGraphics/Core/PipelineManager.cpp +++ b/Code/OysterGraphics/Core/PipelineManager.cpp @@ -52,8 +52,15 @@ namespace Oyster data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderV, -1, ForceReload); if(data) { - VSMap[name] = VS.size(); - VS.push_back((ID3D11VertexShader*)data); + if(ForceReload && VSMap.count(name)) + { + VS[VSMap[name]] = (ID3D11VertexShader*)data; + } + else + { + VSMap[name] = VS.size(); + VS.push_back((ID3D11VertexShader*)data); + } } } break; @@ -63,8 +70,16 @@ namespace Oyster { if(data!=0) { - HSMap[name] = HS.size(); - HS.push_back((ID3D11HullShader*)data); + if(ForceReload && HSMap.count(name)) + { + HS[HSMap[name]] = (ID3D11HullShader*)data; + } + else + { + HSMap[name] = HS.size(); + HS.push_back((ID3D11HullShader*)data); + } + } } break; @@ -74,8 +89,15 @@ namespace Oyster { if(data!=0) { - DSMap[name] = DS.size(); - DS.push_back((ID3D11DomainShader*)data); + if(ForceReload && DSMap.count(name)) + { + DS[DSMap[name]] = (ID3D11DomainShader*)data; + } + else + { + DSMap[name] = DS.size(); + DS.push_back((ID3D11DomainShader*)data); + } } } break; @@ -85,8 +107,15 @@ namespace Oyster { if(data!=0) { - GSMap[name] = GS.size(); - GS.push_back((ID3D11GeometryShader*)data); + if(ForceReload && GSMap.count(name)) + { + GS[GSMap[name]] = (ID3D11GeometryShader*)data; + } + else + { + GSMap[name] = GS.size(); + GS.push_back((ID3D11GeometryShader*)data); + } } } break; @@ -96,8 +125,15 @@ namespace Oyster { if(data!=0) { - PSMap[name] = PS.size(); - PS.push_back((ID3D11PixelShader*)data); + if(ForceReload && PSMap.count(name)) + { + PS[PSMap[name]] = (ID3D11PixelShader*)data; + } + else + { + PSMap[name] = PS.size(); + PS.push_back((ID3D11PixelShader*)data); + } } } break; @@ -107,8 +143,16 @@ namespace Oyster { if(data!=0) { - CSMap[name] = CS.size(); - CS.push_back((ID3D11ComputeShader*)data); + if(ForceReload && CSMap.count(name)) + { + CS[CSMap[name]] = (ID3D11ComputeShader*)data; + } + else + { + CSMap[name] = CS.size(); + CS.push_back((ID3D11ComputeShader*)data); + } + } } break; @@ -375,9 +419,9 @@ namespace Oyster void Core::PipelineManager::CleanPipeline() { - deviceContext->VSSetShaderResources(0,16,Core::srvNULL); - deviceContext->GSSetShaderResources(0,16,Core::srvNULL); - deviceContext->PSSetShaderResources(0,16,Core::srvNULL); + //deviceContext->VSSetShaderResources(0,16,Core::srvNULL); + //deviceContext->GSSetShaderResources(0,16,Core::srvNULL); + //deviceContext->PSSetShaderResources(0,16,Core::srvNULL); deviceContext->CSSetShaderResources(0,16,Core::srvNULL); deviceContext->CSSetUnorderedAccessViews(0,8,Core::uavNULL,NULL); deviceContext->OMSetRenderTargets(8,Core::rtvNULL, NULL); diff --git a/Code/OysterGraphics/Definitions/GraphicalDefinition.h b/Code/OysterGraphics/Definitions/GraphicalDefinition.h index e81d787b..d6529c48 100644 --- a/Code/OysterGraphics/Definitions/GraphicalDefinition.h +++ b/Code/OysterGraphics/Definitions/GraphicalDefinition.h @@ -20,6 +20,12 @@ namespace Oyster Oyster::Math::Matrix P; }; + struct PerModel + { + Math::Matrix WV; + Math::Matrix WVP; + }; + struct FinalVertex { Oyster::Math::Float3 pos; @@ -34,9 +40,10 @@ namespace Oyster struct LightConstants { Math::Float4x4 InvProj; + Math::Float4x4 Proj; Math::Float2 Pixels; int Lights; - float Pad; + float SSAORadius; Oyster::Math::Float4x4 View; }; diff --git a/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp b/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp index f02d36a2..4d612513 100644 --- a/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp +++ b/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp @@ -6,6 +6,7 @@ #include "../FileLoader/ObjReader.h" #include "../../Misc/Resource/OysterResource.h" #include "../FileLoader/GeneralLoader.h" +#include namespace Oyster { @@ -26,12 +27,6 @@ namespace Oyster { return API::Fail; } -#ifdef _DEBUG - if(Render::Resources::Debug::Init() == Core::Init::Fail) - { - return API::Fail; - } -#endif Render::Resources::Deffered::Init(); Render::Preparations::Basic::SetViewPort(); @@ -62,12 +57,12 @@ namespace Oyster void API::RenderScene(Model::Model models[], int count) { - Render::Rendering::Basic::RenderScene(models,count); + Render::Rendering::Basic::RenderScene(models,count, View, Projection); } void API::RenderModel(Model::Model& m) { - Render::Rendering::Basic::RenderScene(&m,1); + Render::Rendering::Basic::RenderScene(&m,1, View, Projection); } void API::EndFrame() @@ -103,10 +98,6 @@ namespace Oyster SAFE_DELETE(Core::viewPort); Oyster::Resource::OysterResource::Clean(); Oyster::Graphics::Core::PipelineManager::Clean(); - -#ifdef _DEBUG - Oyster::Graphics::Render::Resources::Debug::Clean(); -#endif Oyster::Graphics::Render::Resources::Deffered::Clean(); SAFE_RELEASE(Core::depthStencil); @@ -128,5 +119,13 @@ namespace Oyster { Lights.clear(); } + +#ifdef _DEBUG + API::State API::ReloadShaders() + { + Render::Resources::Deffered::InitShaders(); + return State::Sucsess; + } +#endif } } \ No newline at end of file diff --git a/Code/OysterGraphics/DllInterfaces/GFXAPI.h b/Code/OysterGraphics/DllInterfaces/GFXAPI.h index e218fb7c..65bffe5a 100644 --- a/Code/OysterGraphics/DllInterfaces/GFXAPI.h +++ b/Code/OysterGraphics/DllInterfaces/GFXAPI.h @@ -4,7 +4,7 @@ #include "..\Model\Model.h" #include "OysterMath.h" #include -//#include +#include #ifdef GFX_DLL_EXPORT #define GFX_DLL_USAGE __declspec(dllexport) @@ -29,23 +29,40 @@ namespace Oyster }; static State Init(HWND Window, bool MSAA_Quality, bool Fullscreen, Oyster::Math::Float2 StartResulotion); +#ifdef _DEBUG + static State ReloadShaders(); +#endif + + //! @todo Memory Leaks + + //! @brief Clean Resources and release all memory static void Clean(); + //! @brief Sets the view matrix to use next frame static void SetView(Oyster::Math::Float4x4& View); + //! @brief Sets the projection matrix to use next frame static void SetProjection(Oyster::Math::Float4x4& Projection); //! @brief will internally use last values from SetView and SetProjection static void NewFrame(); + //! @brief Renders a list of models static void RenderScene(Oyster::Graphics::Model::Model models[], int count); + //! @brief Renders a single model static void RenderModel(Oyster::Graphics::Model::Model& model); + //! @brief Performs light calculations, post effects and presents the scene static void EndFrame(); + //! @brief Creates a model from the supplied file, note: do not include .obj static Oyster::Graphics::Model::Model* CreateModel(std::wstring filename); + //! @brief deletes a model and relases the models resources static void DeleteModel(Oyster::Graphics::Model::Model* model); + //! @brief adds a light to the scene static void AddLight(Definitions::Pointlight light); + //! @brief removes all lights from the scene static void ClearLights(); + //! @brief Sets Options to the graphics, note: currently unused static State SetOptions(Option); }; } diff --git a/Code/OysterGraphics/FileLoader/ModelLoader.cpp b/Code/OysterGraphics/FileLoader/ModelLoader.cpp index 8a2d52b8..cfd61e0d 100644 --- a/Code/OysterGraphics/FileLoader/ModelLoader.cpp +++ b/Code/OysterGraphics/FileLoader/ModelLoader.cpp @@ -39,11 +39,12 @@ void Oyster::Graphics::Loading::UnloadTexture(void* data) void Oyster::Graphics::Loading::LoadOBJ(const wchar_t filename[], Oyster::Resource::CustomData& out) { - FileLoaders::ObjReader* obj = FileLoaders::ObjReader::LoadFile(filename); + FileLoaders::ObjReader obj; + obj.LoadFile(filename); Model::ModelInfo* info = new Model::ModelInfo(); Oyster::FileLoaders::ObjReader::Vertex* vdata; int count; - obj->GetVertexData(&vdata, count); + obj.GetVertexData(&vdata, count); info->Vertices = new Core::Buffer(); Core::Buffer::BUFFER_INIT_DESC desc; desc.ElementSize = sizeof(FileLoaders::ObjReader::Vertex); diff --git a/Code/OysterGraphics/FileLoader/ObjReader.cpp b/Code/OysterGraphics/FileLoader/ObjReader.cpp index e34ca8fd..ccc32fea 100644 --- a/Code/OysterGraphics/FileLoader/ObjReader.cpp +++ b/Code/OysterGraphics/FileLoader/ObjReader.cpp @@ -3,31 +3,16 @@ #include "..\Core\Core.h" #include #include +#include using namespace std; using namespace Oyster::FileLoaders; using namespace Oyster; using namespace Oyster::Math; -ObjReader *ObjReader::LoadFile(std::wstring fileName, Oyster::Math::Float4x4 transform) +void ObjReader::LoadFile(std::wstring fileName, Oyster::Math::Float4x4 transform) { - static std::map cache; - - ObjReader *reader = NULL; - - if (cache.count(fileName)) - { - reader = cache[fileName]; - } - else - { - reader = new ObjReader(); - reader->ParseFile(fileName + L".obj", transform); - - cache[fileName] = reader; - } - - return reader; + this->ParseFile(fileName + L".obj", transform); } ObjReader::ObjReader(void) @@ -37,6 +22,7 @@ ObjReader::ObjReader(void) ObjReader::~ObjReader(void) { + SAFE_DELETE_ARRAY(this->vertices); } void ObjReader::ParseFile(std::wstring fileName, Float4x4 transform) @@ -50,7 +36,6 @@ void ObjReader::ParseFile(std::wstring fileName, Float4x4 transform) } wstring path; - //Utility::String::ExtractDirPath(path,fileName,'\\'); std::vector VertexList; std::vector vList; @@ -74,6 +59,7 @@ void ObjReader::ParseFile(std::wstring fileName, Float4x4 transform) if(c==L"v") { position = readVertex(offset,s); + //position *= 0.001f; vList.push_back(position); } else if(c==L"vt") diff --git a/Code/OysterGraphics/FileLoader/ObjReader.h b/Code/OysterGraphics/FileLoader/ObjReader.h index bb361b07..4ae2bffd 100644 --- a/Code/OysterGraphics/FileLoader/ObjReader.h +++ b/Code/OysterGraphics/FileLoader/ObjReader.h @@ -16,7 +16,7 @@ namespace Oyster Oyster::Math::Float3 Normal; }; - static ObjReader *LoadFile(std::wstring fileName, Oyster::Math::Float4x4 transform = Oyster::Math::Float4x4::identity); + void LoadFile(std::wstring fileName, Oyster::Math::Float4x4 transform = Oyster::Math::Float4x4::identity); ObjReader(void); ~ObjReader(void); diff --git a/Code/OysterGraphics/Render/Rendering/BasicRender.cpp b/Code/OysterGraphics/Render/Rendering/BasicRender.cpp index e61bd656..9950ce76 100644 --- a/Code/OysterGraphics/Render/Rendering/BasicRender.cpp +++ b/Code/OysterGraphics/Render/Rendering/BasicRender.cpp @@ -34,6 +34,8 @@ namespace Oyster lc.Pixels = Core::resolution; lc.Lights = numLights; lc.View = View; + lc.Proj = Projection; + lc.SSAORadius = 3; data = Resources::Deffered::LightConstantsData.Map(); memcpy(data, &lc, sizeof(Definitions::LightConstants)); @@ -44,14 +46,18 @@ namespace Oyster Resources::Deffered::PointLightsData.Unmap(); } - void Basic::RenderScene(Model::Model* models, int count) + void Basic::RenderScene(Model::Model* models, int count, Math::Matrix View, Math::Matrix Projection) { for(int i = 0; i < count; ++i) { if(models[i].Visible) { + Definitions::PerModel pm; + pm.WV = View * models[i].WorldMatrix; + pm.WVP = Projection * pm.WV; + void* data = Resources::Deffered::ModelData.Map(); - memcpy(data,&(models[i].WorldMatrix),sizeof(Math::Float4x4)); + memcpy(data,&(pm),sizeof(pm)); Resources::Deffered::ModelData.Unmap(); @@ -82,6 +88,10 @@ namespace Oyster Core::deviceContext->Dispatch((Core::resolution.x + 15U) / 16U,(Core::resolution.y + 15U) / 16U,1); + Core::PipelineManager::SetRenderPass(Resources::Deffered::PostPass); + + Core::deviceContext->Dispatch((Core::resolution.x + 15U) / 16U,(Core::resolution.y + 15U) / 16U,1); + Core::swapChain->Present(0,0); } } diff --git a/Code/OysterGraphics/Render/Rendering/Render.h b/Code/OysterGraphics/Render/Rendering/Render.h index 62604d6c..48d153d4 100644 --- a/Code/OysterGraphics/Render/Rendering/Render.h +++ b/Code/OysterGraphics/Render/Rendering/Render.h @@ -17,7 +17,7 @@ namespace Oyster public: static void NewFrame(Oyster::Math::Float4x4 View, Oyster::Math::Float4x4 Projection, Definitions::Pointlight* Lights, int numLights); - static void RenderScene(Model::Model* models, int count); + static void RenderScene(Model::Model* models, int count, Math::Matrix View, Math::Matrix Projection); static void EndFrame(); }; } diff --git a/Code/OysterGraphics/Render/Resources/Deffered.cpp b/Code/OysterGraphics/Render/Resources/Deffered.cpp index e14ac812..77bcad09 100644 --- a/Code/OysterGraphics/Render/Resources/Deffered.cpp +++ b/Code/OysterGraphics/Render/Resources/Deffered.cpp @@ -11,6 +11,9 @@ typedef Oyster::Graphics::Core::Buffer Buffer; const std::wstring PathToHLSL = L"..\\..\\Code\\OysterGraphics\\Shader\\HLSL\\Deffered Shaders\\"; const std::wstring PathToCSO = L"..\\Content\\Shaders\\"; +const int KernelSize = 10; +const int SampleSpread = 8; + namespace Oyster { namespace Graphics @@ -20,12 +23,15 @@ namespace Oyster namespace Resources { - ID3D11RenderTargetView* Deffered::GBufferRTV[2] = {0}; - ID3D11ShaderResourceView* Deffered::GBufferSRV[2] = {0}; + ID3D11RenderTargetView* Deffered::GBufferRTV[Deffered::GBufferSize] = {0}; + ID3D11ShaderResourceView* Deffered::GBufferSRV[Deffered::GBufferSize] = {0}; + ID3D11UnorderedAccessView* Deffered::LBufferUAV[Deffered::LBufferSize] = {0}; + ID3D11ShaderResourceView* Deffered::LBufferSRV[Deffered::LBufferSize] = {0}; Shader::RenderPass Deffered::GeometryPass; Shader::RenderPass Deffered::LightPass; + Shader::RenderPass Deffered::PostPass; Buffer Deffered::ModelData = Buffer(); Buffer Deffered::VPData = Buffer(); @@ -34,9 +40,12 @@ namespace Oyster Buffer Deffered::PointLightsData = Buffer(); ID3D11ShaderResourceView* Deffered::PointLightView = NULL; - Core::Init::State Deffered::Init() + ID3D11ShaderResourceView* Deffered::SSAOKernel = NULL; + ID3D11ShaderResourceView* Deffered::SSAORandom = NULL; + + Core::Init::State Deffered::InitShaders() { -#ifdef _DEBUG + #ifdef _DEBUG std::wstring path = PathToHLSL; std::wstring end = L".hlsl"; #else @@ -47,10 +56,17 @@ namespace Oyster Core::PipelineManager::Init(path + L"PixelGatherData" + end, ShaderType::Pixel, L"Geometry"); Core::PipelineManager::Init(path + L"VertexGatherData" + end, ShaderType::Vertex, L"Geometry"); Core::PipelineManager::Init(path + L"LightPass" + end, ShaderType::Compute, L"LightPass"); + Core::PipelineManager::Init(path + L"PostPass" + end, ShaderType::Compute, L"PostPass"); + return Core::Init::State::Success; + } + + Core::Init::State Deffered::Init() + { + InitShaders(); //Create Buffers Buffer::BUFFER_INIT_DESC desc; - desc.ElementSize = sizeof(Oyster::Math::Matrix); + desc.ElementSize = sizeof(Definitions::PerModel); desc.NumElements = 1; desc.InitData = NULL; desc.Type = Buffer::BUFFER_TYPE::CONSTANT_BUFFER_VS; @@ -72,7 +88,7 @@ namespace Oyster desc.Type = Buffer::STRUCTURED_BUFFER; PointLightsData.Init(desc); - //Create States + ////Create States D3D11_RASTERIZER_DESC rdesc; rdesc.CullMode = D3D11_CULL_BACK; rdesc.FillMode = D3D11_FILL_SOLID; @@ -131,11 +147,82 @@ namespace Oyster Core::Init::CreateLinkedShaderResourceFromTexture(&GBufferRTV[i],&GBufferSRV[i],NULL); } + for(int i = 0; i < Resources::Deffered::LBufferSize; ++i) + { + Core::Init::CreateLinkedShaderResourceFromTexture(NULL,&LBufferSRV[i],&LBufferUAV[i]); + } + Buffer* b = &PointLightsData; Core::Init::CreateLinkedShaderResourceFromStructuredBuffer(&b,&PointLightView,NULL); + srand(time(0)); + //SSAO + Math::Vector3 kernel[KernelSize]; + Math::Vector3 random[SampleSpread]; + for(int i = 0;i < KernelSize; ++i) + { + kernel[i] = Oyster::Math::Vector3::null; + while( kernel[i] == Oyster::Math::Vector3::null ) + { + kernel[i] = Oyster::Math::Vector3( + (float)rand() / (RAND_MAX + 1) * (1 - -1) + -1, + (float)rand() / (RAND_MAX + 1) * (1 - -1) + -1, + (float)rand() / (RAND_MAX + 1) * (1 - 0) + 0); + } + kernel[i].Normalize(); - //Create ShaderEffects + float scale = float(i) / float(KernelSize); + + scale = (0.1f*(1 - scale * scale) + 1.0f *( scale * scale)); + kernel[i] *= scale; + + + } + + for( int i = 0; i < SampleSpread; ++i) + { + random[i] = Oyster::Math::Vector3::null; + while( random[i] == Oyster::Math::Vector3::null ) + { + random[i] = Oyster::Math::Vector3( + (float)rand() / (RAND_MAX + 1) * (1 - -1)+ -1, + (float)rand() / (RAND_MAX + 1) * (1 - -1)+ -1, + 0.0f); + } + random[i].Normalize(); + } + //kernel[0] = Math::Vector3(0,1,1); + //kernel[0].Normalize(); + + D3D11_TEXTURE1D_DESC T1desc; + T1desc.Width = KernelSize; + T1desc.MipLevels = T1desc.ArraySize = 1; + T1desc.Format = DXGI_FORMAT_R32G32B32_FLOAT; + T1desc.Usage = D3D11_USAGE_DEFAULT; + T1desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + T1desc.CPUAccessFlags = 0; + T1desc.MiscFlags = 0; + + D3D11_SUBRESOURCE_DATA sphere; + sphere.pSysMem = kernel; + + D3D11_SUBRESOURCE_DATA rnd; + rnd.pSysMem = random; + + ID3D11Texture1D *pTexture1[2]; + + Core::device->CreateTexture1D( &T1desc, &sphere, &pTexture1[0] ); + Core::device->CreateShaderResourceView( pTexture1[0], 0, &SSAOKernel ); + pTexture1[0]->Release(); + + T1desc.Width = SampleSpread; + Core::device->CreateTexture1D( &T1desc, &rnd, &pTexture1[1] ); + Core::device->CreateShaderResourceView( (pTexture1[1]), 0, &SSAORandom ); + pTexture1[1]->Release(); + + ////Create ShaderEffects + + ////---------------- Geometry Pass Setup ---------------------------- GeometryPass.Shaders.Pixel = GetShader::Pixel(L"Geometry"); GeometryPass.Shaders.Vertex = GetShader::Vertex(L"Geometry"); @@ -161,8 +248,12 @@ namespace Oyster } GeometryPass.depth = Core::depthStencil; + ////---------------- Light Pass Setup ---------------------------- LightPass.Shaders.Compute = GetShader::Compute(L"LightPass"); - LightPass.UAV.Compute.push_back(Core::backBufferUAV); + for(int i = 0; i Points : register(t3); -StructuredBuffer Points : register(t3); +Texture1D SSAOKernel : register(t4); +Texture1D SSAORand : register(t5); -RWTexture2D Output : register(u0); +RWTexture2D Diffuse : register(u0); +RWTexture2D Specular : register(u1); +RWTexture2D Ambient : register(u2); #endif \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/GBufferHeader.hlsli b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/GBufferHeader.hlsli index 49c42127..2f5a4a01 100644 --- a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/GBufferHeader.hlsli +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/GBufferHeader.hlsli @@ -39,5 +39,6 @@ cbuffer PerFrame : register(b0) cbuffer PerModel : register(b1) { - matrix World; + matrix WV; + matrix WVP; } \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightCalc.hlsli b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightCalc.hlsli index 64c3c98c..bd449209 100644 --- a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightCalc.hlsli +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightCalc.hlsli @@ -14,9 +14,8 @@ DiffSpec LightCalc(PointLight pl, float3 pos, int2 texCoord) float specFactor = pow(max(dot(v,normalize(-pos)), 0.0f),normalSpec.w); //Check att later float att = max( 0, 1 - (d / pl.Radius)); - //att = 1; //fix Ilum calcs instead of PhongBlinn - output.Diffuse = pl.Bright * att * diffFactor * pl.Color; + output.Diffuse = pl.Bright * att * diffFactor * pl.Color; output.Specular = pl.Bright * att * specFactor * pl.Color; if(diffFactor == 0) output.Specular * 0; diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightPass.hlsl b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightPass.hlsl index 268c3365..98b2887e 100644 --- a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightPass.hlsl +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightPass.hlsl @@ -1,31 +1,40 @@ #include "Defines.hlsli" #include "LightCalc.hlsli" #include "PosManipulation.hlsli" +#include "SSAO.hlsli" //todo //LightCulling -//Calc Diff + Spec -//Calc Ambience +//Calc Diff + Spec Done +//Calc Ambience Done //Write Glow [numthreads(16, 16, 1)] -void main( uint3 DTid : SV_DispatchThreadID ) +void main( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID ) { - float3 ViewPos = ToVpos(DTid.xy); + float2 UV = DTid / Pixels; + UV.x = UV.x * 2 - 1; + UV.y = 1 - 2 * UV.y; + float3 ViewPos = ToVpos(DTid.xy, UV); DiffSpec Shaded; Shaded.Diffuse = float4(0,0,0,0); Shaded.Specular = float4(0,0,0,0); + for(int i = 0; i < Lights; ++i) { DiffSpec light = LightCalc(Points[i], ViewPos, DTid.xy); - Shaded.Diffuse = light.Diffuse; - Shaded.Specular = light.Specular; + Shaded.Diffuse += light.Diffuse; + Shaded.Specular += light.Specular; } - //Output[DTid.xy] = float4(ViewPos,1); - //Output[DTid.xy] = DepthTexture[DTid.xy].x; - //Output[DTid.xy] = float4(DTid.xy/ Pixels,1,1); - //Output[DTid.xy] = NormalSpec[DTid.xy]; - //Output[DTid.xy] = float4(light.Diffuse, 1); - //Output[DTid.xy] = float4(light.Specular, 1); - Output[DTid.xy] = float4( Shaded.Diffuse * DiffuseGlow[DTid.xy].xyz + Shaded.Specular + DiffuseGlow[DTid.xy].xyz * 0.2f, 1); + + Diffuse[DTid.xy] = float4(Shaded.Diffuse * DiffuseGlow[DTid.xy].xyz,1); + Specular[DTid.xy] = float4(Shaded.Specular, 1); + + + if((DTid.x + DTid.y) %4 == 0 ) + { + float AmbValue = GetSSAO(ViewPos, UV, DTid.xy, GTid.xy); + Ambient[DTid.xy/4] = AmbValue; + } + } \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/PosManipulation.hlsli b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/PosManipulation.hlsli index 8c4b2e48..5393655e 100644 --- a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/PosManipulation.hlsli +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/PosManipulation.hlsli @@ -1,22 +1,23 @@ +#ifndef PosHelper +#define PosHelper #include "Defines.hlsli" //assumes ProperfloatTexCoords -float3 ToVpos(float2 texCoord) +float3 ToVpos(int2 texCoord, float2 UV) { - //Get proper UV - float2 UV = texCoord / Pixels; float4 ViewPos = float4(0,0,0,0); // Get the depth value for this pixel ViewPos.z= DepthTexture[texCoord].x; //Get X/w - ViewPos.x = UV.x * 2 - 1; + ViewPos.x = UV.x; //Get Y/w //ViewPos.y = -(UV.y * 2) + 1; - ViewPos.y = 1 - 2 * UV.y; + ViewPos.y = UV.y; ViewPos.w = 1; //Un project ViewPos = mul(InvProj, ViewPos); return ViewPos.xyz / ViewPos.w; -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/PostPass.hlsl b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/PostPass.hlsl new file mode 100644 index 00000000..1c52e5bf --- /dev/null +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/PostPass.hlsl @@ -0,0 +1,12 @@ +Texture2D Diffuse : register(t0); +Texture2D Specular : register(t1); +Texture2D Ambient : register(t2); + +RWTexture2D Output; + +[numthreads(16, 16, 1)] +void main( uint3 DTid : SV_DispatchThreadID ) +{ + //Output[DTid.xy] = Diffuse[DTid.xy] + Specular[DTid.xy] + Diffuse[DTid.xy] * Ambient[DTid.xy/4].w;// + float4(Ambient[DTid.xy/4].xyz,1); GLOW + Output[DTid.xy] = Diffuse[DTid.xy]; +} \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/SSAO.hlsli b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/SSAO.hlsli new file mode 100644 index 00000000..32f84f90 --- /dev/null +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/SSAO.hlsli @@ -0,0 +1,49 @@ +#include "Defines.hlsli" +#include "PosManipulation.hlsli" + +static float Radius =5; + +float GetSSAO(float3 pos, float2 uv, int2 texCoord2, uint2 rndID) +{ + + float occlusion = 0.0f; + //create sample coordinate system + float4 rnd = float4( SSAORand[(rndID.x + rndID.y) % SSAORand.Length.x].xyz, 0.0f ); + rnd = normalize(rnd); + float3 normal = NormalSpec[uv].xyz; + float4 tangent = float4( normalize(rnd.xyz - (normal * dot(rnd.xyz, normal))), 0.0f ); + float4 biTangent = float4( cross(tangent.xyz, normal), 0.0f ); + + float4x4 tbn = float4x4(tangent, biTangent, float4(normal,0), float4(pos*Radius,1)); + + for( uint i = 0; i < SSAOKernel.Length.x; ++i ) + { + //take sample from localspace to viewspace + float4 sampled = mul(tbn, float4(SSAOKernel[i].xyz,1)); + //project sample to get uv.xy + float4 ProjOffset = sampled; + ProjOffset = mul(Proj, ProjOffset); + float4 offset = ProjOffset; + float2 UV = offset; + offset /= offset.w; + offset.xyz = offset.xyz * 0.5f + 0.5f; + //extra invert y axis, DX11 + offset.y = 1.0f - offset.y; + + // get depth from that point in screenspace + uint2 texCoord; + texCoord = (uint2)(offset.xy * Pixels); + float3 ViewPos = ToVpos(texCoord, UV); + + float sampleDepth = ViewPos.z; + + //compare to depth from sample + float rangeCheck = (abs(pos.z - sampleDepth) < Radius) ? 1.0f : 0.0f; + occlusion += (sampleDepth >= sampled.z ? 1.0f : 0.0f) * rangeCheck; + } + occlusion /= (float)(SSAOKernel.Length.x); + occlusion = 1.0f - occlusion; + + return occlusion; +} + diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/VertexGatherData.hlsl b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/VertexGatherData.hlsl index d713408f..e0cf21c3 100644 --- a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/VertexGatherData.hlsl +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/VertexGatherData.hlsl @@ -3,15 +3,8 @@ VertexOut main( VertexIn input ) { VertexOut output; - float4 WorldPos = mul(World, float4(input.pos,1)); - float4 ViewPos = mul(View, WorldPos); - output.pos = mul(Projection, ViewPos); - float4 WorldNor = mul(World, float4(input.normal,0)); - float4 ViewNor = mul(View, WorldNor); - output.normal = ViewNor; - //output.normal.z *= -1; - + output.pos = mul(WVP, float4(input.pos,1)); + output.normal = mul(WV, float4(input.normal,0)); output.UV = input.UV; - //output.normal = ViewNor; return output; } \ No newline at end of file diff --git a/Code/Tester/MainTest.cpp b/Code/Tester/MainTest.cpp index 4a684915..cfa3b8b6 100644 --- a/Code/Tester/MainTest.cpp +++ b/Code/Tester/MainTest.cpp @@ -70,8 +70,11 @@ int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdL __int64 prevTimeStamp = 0; QueryPerformanceCounter((LARGE_INTEGER*)&prevTimeStamp); + std::string fps = "FPS:"; + char count[100]; // Main message loop MSG msg = {0}; + float fpsCounter = 0; while(WM_QUIT != msg.message) { if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE) ) @@ -88,13 +91,20 @@ int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdL //render Update(dt); Render(dt); - + fpsCounter += dt; + if(fpsCounter>0.1f) + { + sprintf_s(count, "%f",1/dt); + SetWindowTextA(g_hWnd, (fps + count).c_str()); + fpsCounter = 0; + } prevTimeStamp = currTimeStamp; } } Oyster::Graphics::API::DeleteModel(m); Oyster::Graphics::API::DeleteModel(m2); + Oyster::Graphics::API::DeleteModel(m3); Oyster::Graphics::API::Clean(); return (int) msg.wParam; } @@ -160,57 +170,25 @@ HRESULT InitDirect3D() { return E_FAIL; } - -#pragma region Triangle - //Oyster::Graphics::Definitions::ObjVertex mesh[] = - //{ - // {Oyster::Math::Vector3(-1,1,0),Oyster::Math::Vector2(0,0),Oyster::Math::Vector3(1,1,0)}, - // {Oyster::Math::Vector3(1,-1,0),Oyster::Math::Vector2(0,0),Oyster::Math::Vector3(1,1,0)}, - // {Oyster::Math::Vector3(1,1,0),Oyster::Math::Vector2(0,0),Oyster::Math::Vector3(1,1,0)}, - //}; - - //Oyster::Graphics::Buffer::BUFFER_INIT_DESC desc; - //desc.ElementSize= sizeof(Oyster::Graphics::Definitions::ObjVertex); - //desc.NumElements = 3; - //desc.InitData=mesh; - //desc.Type = Oyster::Graphics::Buffer::BUFFER_TYPE::VERTEX_BUFFER; - //desc.Usage = Oyster::Graphics::Buffer::BUFFER_USAGE::BUFFER_USAGE_IMMUTABLE; - - //Oyster::Graphics::Buffer *b = new Oyster::Graphics::Buffer();; - //b->Init(desc); - - ////b.Apply(0); - //Oyster::Graphics::Render::ModelInfo* mi = new Oyster::Graphics::Render::ModelInfo(); - //mi->Indexed = false; - //mi->VertexCount = 3; - //mi->Vertices = b; - //m->info = mi; -#pragma endregion - -#pragma region Obj - m = Oyster::Graphics::API::CreateModel(L"orca_dummy"); + m = Oyster::Graphics::API::CreateModel(L"christmastree"); m2 = Oyster::Graphics::API::CreateModel(L"worldDummy"); m2->WorldMatrix = Oyster::Math3D::OrientationMatrix(Oyster::Math::Float3::null,Oyster::Math::Float3(0,5,0),Oyster::Math::Float3::null); m3 = Oyster::Graphics::API::CreateModel(L"worldDummy"); m3->WorldMatrix = Oyster::Math3D::OrientationMatrix(Oyster::Math::Float3::null,Oyster::Math::Float3(0,5,0),Oyster::Math::Float3::null); -#pragma endregion - P = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/2,1024.0f/768.0f,.1f,1000); + P = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/2,1024.0f/768.0f,.1f,100); Oyster::Graphics::API::SetProjection(P); - P.Invert(); - V = Oyster::Math3D::OrientationMatrix_LookAtDirection(Oyster::Math::Float3(0,0,-1),Oyster::Math::Float3(0,1,0),Oyster::Math::Float3(0,0,5.4f)); - //V = Oyster::Math3D::OrientationMatrix_LookAtPos(Oyster::Math::Float3(0,0,0), Oyster::Math::Float3(0,1,0), Oyster::Math::Float3(0,0,-5.4f)); - //V.v[3][2] *= -1; + V = Oyster::Math3D::OrientationMatrix_LookAtDirection(Oyster::Math::Float3(0,0,-1),Oyster::Math::Float3(0,1,0),Oyster::Math::Float3(0,0,15.4f)); V = V.GetInverse(); Oyster::Graphics::Definitions::Pointlight pl; pl.Color = Oyster::Math::Float3(1,1,1); pl.Bright = 1; - pl.Pos = Oyster::Math::Float3(0,0,5.4f); + pl.Pos = Oyster::Math::Float3(0,5,5.4f); pl.Radius = 15; Oyster::Graphics::API::AddLight(pl); @@ -222,7 +200,7 @@ float angle = 0; HRESULT Update(float deltaTime) { - angle += Oyster::Math::pi/10000; + angle += Oyster::Math::pi/8 * deltaTime; m->WorldMatrix = Oyster::Math3D::RotationMatrix_AxisY(angle); m2->WorldMatrix = Oyster::Math3D::OrientationMatrix(Oyster::Math::Float3(1,0,0)*-angle,Oyster::Math::Float3(0,-4,0),Oyster::Math::Float3::null); m3->WorldMatrix = Oyster::Math3D::OrientationMatrix(Oyster::Math::Float3(1,0,0)*-0,Oyster::Math::Float3(3,4,-1*angle),Oyster::Math::Float3::null); @@ -269,6 +247,12 @@ LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam case VK_ESCAPE: PostQuitMessage(0); break; + //R + case 0x52: +#ifdef _DEBUG + Oyster::Graphics::API::ReloadShaders(); +#endif + break; } break;