diff --git a/Code/Game/GameClient/DanBiasGame_Impl.cpp b/Code/Game/GameClient/DanBiasGame_Impl.cpp index 85ea810a..414b9829 100644 --- a/Code/Game/GameClient/DanBiasGame_Impl.cpp +++ b/Code/Game/GameClient/DanBiasGame_Impl.cpp @@ -40,7 +40,7 @@ namespace DanBias { public: WindowShell* window; - Utility::WinTimer timer; + Utility::WinTimer timer, graphicalTimer; UniquePointer state; NetworkClient networkClient; @@ -130,7 +130,7 @@ namespace DanBias Graphics::API::Update( data.capFrame ); if(Render() != S_OK) return DanBiasClientReturn_Error; - data.capFrame -= 0.03f; + data.capFrame = 0.0f; } if(data.networkClient.IsConnected()) @@ -153,11 +153,14 @@ namespace DanBias Oyster::Graphics::API::Option p; p.modelPath = L"..\\Content\\Models\\"; p.texturePath = L"..\\Content\\Textures\\"; - p.Resolution = Oyster::Math::Float2( 1280.0f, 720.0f ); + p.resolution = Oyster::Math::Float2( 1920.0f, 1080.0f ); //! @todo fix proper amb value - p.AmbientValue = 1.3f; + p.ambientValue = 0.3f; + p.globalGlowTint = Math::Float3(1); + p.globalTint = Math::Float3(1); + p.fullscreen = false; - if(Oyster::Graphics::API::Init(data.window->GetHWND(), false, false, p) != Oyster::Graphics::API::Sucsess) + if(Oyster::Graphics::API::Init(data.window->GetHWND(), false, p) != Oyster::Graphics::API::Sucsess) return E_FAIL; return S_OK; } diff --git a/Code/Game/GameClient/GameClientState/GameState.cpp b/Code/Game/GameClient/GameClientState/GameState.cpp index 3a8a004b..d0d38129 100644 --- a/Code/Game/GameClient/GameClientState/GameState.cpp +++ b/Code/Game/GameClient/GameClientState/GameState.cpp @@ -75,13 +75,10 @@ bool GameState::Init( SharedStateContent &shared ) this->privData->lights = &shared.lights; Graphics::API::Option gfxOp = Graphics::API::GetOption(); - Float aspectRatio = gfxOp.Resolution.x / gfxOp.Resolution.y; - this->privData->camera.SetPerspectiveProjection( Utility::Value::Radian(90.0f), aspectRatio, 0.1f, 1000.0f ); + Float aspectRatio = gfxOp.resolution.x / gfxOp.resolution.y; + this->privData->camera.SetPerspectiveProjection( Utility::Value::Radian(90.0f), aspectRatio, 0.5f, 1000.0f ); + Graphics::API::SetProjection( this->privData->camera.GetProjectionMatrix() ); - gfxOp.AmbientValue = 0.5f; - gfxOp.GlobalGlowTint = Math::Float3(1,1,1); - gfxOp.GlobalTint = Math::Float3(1,1,1); - Graphics::API::SetOptions(gfxOp); // DEGUG KEYS this->key_Reload_Shaders = false; diff --git a/Code/Game/GameClient/Include/DanBiasGame.h b/Code/Game/GameClient/Include/DanBiasGame.h index f6f0cdee..8213f879 100644 --- a/Code/Game/GameClient/Include/DanBiasGame.h +++ b/Code/Game/GameClient/Include/DanBiasGame.h @@ -45,6 +45,7 @@ namespace DanBias static DanBiasClientReturn Initiate(DanBiasGameDesc& desc); static DanBiasClientReturn Run(); static void Release(); + static HRESULT Render(); private: enum Result @@ -58,7 +59,6 @@ namespace DanBias static HRESULT InitInput( HWND handle ); static Result Update(float deltaTime); - static HRESULT Render(); static HRESULT CleanUp(); }; diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 47552d27..090656d7 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -74,7 +74,7 @@ void Player::initPlayerData() void Player::BeginFrame() { - if( this->playerState & (PLAYER_STATE_DEAD | PLAYER_STATE_DIED) ) + if( !(this->playerState & (PLAYER_STATE_DEAD | PLAYER_STATE_DIED)) ) { static const Float maxSpeed = 30.0f; diff --git a/Code/Game/LanServer/GameServerDebugEnvironment/Source.cpp b/Code/Game/LanServer/GameServerDebugEnvironment/Source.cpp index 3357f52c..8ec4c9aa 100644 --- a/Code/Game/LanServer/GameServerDebugEnvironment/Source.cpp +++ b/Code/Game/LanServer/GameServerDebugEnvironment/Source.cpp @@ -32,7 +32,7 @@ int WINAPI WinMain( HINSTANCE hinst, HINSTANCE prevInst, PSTR cmdLine, int cmdSh GameServerAPI::GameSetGameMode(L"free-for-all"); GameServerAPI::GameSetGameName(L"DebugServer"); GameServerAPI::GameSetGameTime(15); - GameServerAPI::GameSetMapName(L"erik_250.bias"); + GameServerAPI::GameSetMapName(L"manyLights.bias"); GameServerAPI::GameSetMaxClients(10); if(GameServerAPI::GameStart(true)) diff --git a/Code/Misc/OysterMath/LinearMath.h b/Code/Misc/OysterMath/LinearMath.h index 5b87d83d..c4158035 100644 --- a/Code/Misc/OysterMath/LinearMath.h +++ b/Code/Misc/OysterMath/LinearMath.h @@ -78,7 +78,7 @@ inline ::LinearAlgebra::Vector4 operator * ( const ::LinearAlgebra:: { return ::LinearAlgebra::Vector4( (matrix.m11 * vector.x) + (matrix.m12 * vector.y) + (matrix.m13 * vector.z) + (matrix.m14 * vector.w), (matrix.m21 * vector.x) + (matrix.m22 * vector.y) + (matrix.m23 * vector.z) + (matrix.m24 * vector.w), - (matrix.m23 * vector.x) + (matrix.m32 * vector.y) + (matrix.m33 * vector.z) + (matrix.m34 * vector.w), + (matrix.m31 * vector.x) + (matrix.m32 * vector.y) + (matrix.m33 * vector.z) + (matrix.m34 * vector.w), (matrix.m41 * vector.x) + (matrix.m42 * vector.y) + (matrix.m43 * vector.z) + (matrix.m44 * vector.w) ); } diff --git a/Code/OysterGraphics/Core/Core.cpp b/Code/OysterGraphics/Core/Core.cpp index 8cb4c5e0..0874e2cc 100644 --- a/Code/OysterGraphics/Core/Core.cpp +++ b/Code/OysterGraphics/Core/Core.cpp @@ -36,3 +36,7 @@ ID3D11RenderTargetView* Core::rtvNULL[8] = {0}; ID3D11UnorderedAccessView* Core::uavNULL[8] = {0}; int Core::UsedMem = 0; + +HWND Core::window = 0; + +bool Core::fullscreen = false; \ No newline at end of file diff --git a/Code/OysterGraphics/Core/Core.h b/Code/OysterGraphics/Core/Core.h index ae234ee4..79f63227 100644 --- a/Code/OysterGraphics/Core/Core.h +++ b/Code/OysterGraphics/Core/Core.h @@ -40,7 +40,8 @@ namespace Oyster //ViewPort static D3D11_VIEWPORT* viewPort; - static Oyster::Math::Float2 resolution; + static Oyster::Math::Float2 resolution; + static bool fullscreen; static ID3D11ShaderResourceView* srvNULL[16]; static ID3D11RenderTargetView* rtvNULL[8]; @@ -48,6 +49,8 @@ namespace Oyster static int UsedMem; + static HWND window; + class Buffer { public: @@ -250,11 +253,12 @@ namespace Oyster static State FullInit(HWND Window, bool MSAA_Quality, bool Fullscreen); - static State ReInitialize(HWND Window, bool MSAA_Quality, bool Fullscreen); + static State ReInitialize(bool MSAA_Quality, bool Fullscreen, Math::Float2 Size); static State CreateLinkedShaderResourceFromTexture(ID3D11RenderTargetView** rtv, ID3D11ShaderResourceView** srv, ID3D11UnorderedAccessView** uav); static State CreateLinkedShaderResourceFromStructuredBuffer(Buffer** Structured, ID3D11ShaderResourceView** srv, ID3D11UnorderedAccessView** uav); + static State CreateLinkedShaderResourceFromStructuredBuffer(void* InitData, int numElem, int ElemSize, Buffer** Structured, ID3D11ShaderResourceView** srv, ID3D11UnorderedAccessView** uav); }; diff --git a/Code/OysterGraphics/Core/Init.cpp b/Code/OysterGraphics/Core/Init.cpp index 47731dbf..c9e2e07c 100644 --- a/Code/OysterGraphics/Core/Init.cpp +++ b/Code/OysterGraphics/Core/Init.cpp @@ -110,7 +110,7 @@ namespace Oyster if(Core::swapChain) { Core::swapChain->Release(); - Core::UsedMem -= desc.BufferDesc.Height * desc.BufferDesc.Width * 16; + Core::UsedMem -= Core::resolution.x * Core::resolution.y * 4; delete Core::swapChain; } @@ -168,7 +168,7 @@ namespace Oyster } dxgiFactory->Release(); - Core::UsedMem += desc.BufferDesc.Height * desc.BufferDesc.Width * 16; + Core::UsedMem += desc.BufferDesc.Height * desc.BufferDesc.Width * 4; return Init::Success; } @@ -188,7 +188,7 @@ namespace Oyster if(Core::depthStencil) { Core::depthStencil->Release(); - Core::UsedMem -= desc.Height * desc.Width * 4; + Core::UsedMem -= Core::resolution.x * Core::resolution.y * 4; delete Core::depthStencil; } @@ -327,12 +327,16 @@ namespace Oyster return Init::Fail; } + + Core::window = Window; + Core::fullscreen = Fullscreen; + return Init::Success; } - Core::Init::State Core::Init::ReInitialize(HWND Window, bool MSAA_Quality, bool Fullscreen) + Core::Init::State Core::Init::ReInitialize(bool MSAA_Quality, bool Fullscreen, Math::Float2 Size) { - if(Init::CreateSwapChain(Window, 1, MSAA_Quality, Fullscreen, Core::resolution) == Init::Fail) + if(Init::CreateSwapChain(Core::window, 1, MSAA_Quality, Fullscreen, Size) == Init::Fail) { return Init::Fail; } diff --git a/Code/OysterGraphics/Definitions/GraphicalDefinition.h b/Code/OysterGraphics/Definitions/GraphicalDefinition.h index 77aecdc8..5572be72 100644 --- a/Code/OysterGraphics/Definitions/GraphicalDefinition.h +++ b/Code/OysterGraphics/Definitions/GraphicalDefinition.h @@ -35,9 +35,10 @@ namespace Oyster { Math::Float4x4 InvProj; Math::Float4x4 Proj; - Math::Float2 Pixels; + float FoV; int Lights; float SSAORadius; + float pad; Oyster::Math::Float4x4 View; }; diff --git a/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp b/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp index ee3d9f8a..1a35d408 100644 --- a/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp +++ b/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp @@ -20,6 +20,7 @@ namespace Oyster std::vector Lights; float deltaTime; int MostModel; + float FoV; #ifdef _DEBUG Model::Model* cube; Model::Model* sphere; @@ -30,13 +31,14 @@ namespace Oyster #endif } - API::State API::Init(HWND Window, bool MSAA_Quality, bool Fullscreen, API::Option o) + API::State API::Init(HWND Window, bool MSAA_Quality, API::Option o) { - Core::resolution = o.Resolution; + Core::resolution = o.resolution; Core::modelPath = o.modelPath; Core::texturePath = o.texturePath; + Core::fullscreen = o.fullscreen; - if(Core::Init::FullInit(Window, MSAA_Quality, Fullscreen) == Core::Init::Fail) + if(Core::Init::FullInit(Window, MSAA_Quality, o.fullscreen) == Core::Init::Fail) { return API::Fail; } @@ -44,7 +46,9 @@ namespace Oyster Render::Resources::Init(); Definitions::PostData pd; - pd.Amb = o.AmbientValue; + pd.Amb = o.ambientValue; + pd.GlowTint = o.globalGlowTint; + pd.Tint = o.globalTint; void* data = Render::Resources::Post::Data.Map(); memcpy(data,&pd,sizeof(Definitions::PostData)); @@ -85,6 +89,7 @@ namespace Oyster void API::SetProjection(const Math::Float4x4& projection) { Projection = projection; + FoV = 2 * std::atanf(1/projection.m[1][1]); } void API::SetView(const Math::Float4x4& view) @@ -96,11 +101,11 @@ namespace Oyster { if(Lights.size()) { - Render::DefaultRenderer::NewFrame(View, Projection, &Lights[0], (int)Lights.size()); + Render::DefaultRenderer::NewFrame(View, Projection, &Lights[0], (int)Lights.size(), FoV); } else { - Render::DefaultRenderer::NewFrame(View, Projection, NULL, 0); + Render::DefaultRenderer::NewFrame(View, Projection, NULL, 0, FoV); } } @@ -125,14 +130,22 @@ namespace Oyster Core::texturePath = option.texturePath; Definitions::PostData pd; - pd.Amb = option.AmbientValue; - pd.Tint = option.GlobalTint; - pd.GlowTint = option.GlobalGlowTint; + pd.Amb = option.ambientValue; + pd.Tint = option.globalTint; + pd.GlowTint = option.globalGlowTint; void* data = Render::Resources::Post::Data.Map(); memcpy(data,&pd,sizeof(Definitions::PostData)); Render::Resources::Post::Data.Unmap(); + if(option.resolution != Core::resolution || option.fullscreen != Core::fullscreen) + { + //RESIZE + Core::Init::ReInitialize(false,option.fullscreen,option.resolution); + Core::fullscreen = option.fullscreen; + Core::resolution = option.resolution; + } + return API::Sucsess; } @@ -171,7 +184,8 @@ namespace Oyster Model::Model* m = new Model::Model(); m->WorldMatrix = Oyster::Math::Float4x4::identity; m->Visible = true; - m->Animation.AnimationPlaying = NULL; + m->Animation[0].AnimationPlaying = nullptr; + m->Animation[1].AnimationPlaying = nullptr; m->Tint = Math::Float3(1); m->GlowTint = Math::Float3(1); m->Instanced = true; @@ -300,10 +314,11 @@ namespace Oyster API::Option API::GetOption() { Option o; - o.BytesUsed = Core::UsedMem; + o.bytesUsed = Core::UsedMem; o.modelPath = Core::modelPath; o.texturePath = Core::texturePath; - o.Resolution = Core::resolution; + o.resolution = Core::resolution; + o.fullscreen = Core::fullscreen; return o; } @@ -327,14 +342,20 @@ namespace Oyster Core::loader.ReleaseResource(tex); } - float API::PlayAnimation(Model::Model* m, std::wstring name,bool looping) + float API::PlayAnimation( Model::Model* m, const std::wstring &name, bool looping ) { - if(m==NULL) - return 0; - m->Animation.AnimationPlaying = &(*m->info->Animations.find(name)).second; - m->Animation.AnimationTime=0; - m->Animation.LoopAnimation = looping; - return (float)m->Animation.AnimationPlaying->duration; + if( m ) + { // nasty temp solution by Dan + static int fairSlotLooper = 0; + fairSlotLooper = (fairSlotLooper + 1) & 3; // same as n % 2 + + m->Animation[fairSlotLooper].AnimationPlaying = &(*m->info->Animations.find(name)).second; + m->Animation[fairSlotLooper].AnimationTime=0; + m->Animation[fairSlotLooper].LoopAnimation = looping; + + return (float)m->Animation[fairSlotLooper].AnimationPlaying->duration; + } + return 0; } void API::Update(float dt) diff --git a/Code/OysterGraphics/DllInterfaces/GFXAPI.h b/Code/OysterGraphics/DllInterfaces/GFXAPI.h index 7f338cce..bab46eb6 100644 --- a/Code/OysterGraphics/DllInterfaces/GFXAPI.h +++ b/Code/OysterGraphics/DllInterfaces/GFXAPI.h @@ -28,19 +28,21 @@ namespace Oyster { std::wstring modelPath, texturePath; //between 0-1 - float AmbientValue; + float ambientValue; - Math::Float3 GlobalTint; - Math::Float3 GlobalGlowTint; + Math::Float3 globalTint; + Math::Float3 globalGlowTint; - Math::Float2 Resolution; + Math::Float2 resolution; //Bytes on the GPU - int BytesUsed; + int bytesUsed; + + bool fullscreen; }; typedef void* Texture; - static State Init(HWND Window, bool MSAA_Quality, bool Fullscreen, Option options); + static State Init(HWND Window, bool MSAA_Quality, Option options); static void BeginLoadingModels(); @@ -111,7 +113,7 @@ namespace Oyster static Option GetOption(); //! @brief Starts an animation and returns the time of the animation - static float PlayAnimation(Model::Model* model, std::wstring name, bool looping = false); + static float PlayAnimation(Model::Model* model, const std::wstring &name, bool looping = false); //! @brief Moves all animating models forward the specified time; static void Update(float deltaTime); diff --git a/Code/OysterGraphics/Model/Model.h b/Code/OysterGraphics/Model/Model.h index 6d4e96f2..5fb2aa18 100644 --- a/Code/OysterGraphics/Model/Model.h +++ b/Code/OysterGraphics/Model/Model.h @@ -19,6 +19,7 @@ namespace Oyster float AnimationTime; bool LoopAnimation; }; + struct Model { ModelInfo* info; @@ -27,10 +28,9 @@ namespace Oyster Oyster::Math::Float3 GlowTint; bool Visible; bool Instanced; - AnimationData Animation; + AnimationData Animation[2]; }; } - }; }; diff --git a/Code/OysterGraphics/Model/ModelInfo.h b/Code/OysterGraphics/Model/ModelInfo.h index a53bcb23..7e737dbc 100644 --- a/Code/OysterGraphics/Model/ModelInfo.h +++ b/Code/OysterGraphics/Model/ModelInfo.h @@ -17,11 +17,13 @@ namespace Oyster Math::Matrix Absolute; int Parent; }; + struct Frame { Bone bone; double time; }; + struct Animation { int Bones; @@ -29,6 +31,7 @@ namespace Oyster Frame** Keyframes; //! @brief [Bone][Frame] double duration; }; + struct ModelInfo { std::vector Material; diff --git a/Code/OysterGraphics/Render/DefaultRenderer.cpp b/Code/OysterGraphics/Render/DefaultRenderer.cpp index 4b979be8..2ecbbeeb 100644 --- a/Code/OysterGraphics/Render/DefaultRenderer.cpp +++ b/Code/OysterGraphics/Render/DefaultRenderer.cpp @@ -12,278 +12,435 @@ namespace Oyster { namespace Render { - Definitions::Pointlight pl; + Definitions::Pointlight pl; - void DefaultRenderer::NewFrame(Oyster::Math::Float4x4 View, Oyster::Math::Float4x4 Projection, Definitions::Pointlight* Lights, int numLights) - { - Preparations::Basic::ClearBackBuffer(Oyster::Math::Float4(0,0,0,0)); - Preparations::Basic::ClearDepthStencil(Resources::Gui::depth); - Preparations::Basic::ClearRTV(Resources::GBufferRTV,Resources::GBufferSize,Math::Float4(0,0,0,0)); - Lights[1]; + /******************************************************** + * Private Prototype Methods + ********************************************************/ + void AnimateRelativeBones( const Model::ModelInfo &info, Model::AnimationData &anim, Math::Matrix relativeBuffer[] ); + void MergeAnimatedBones + ( + const Model::Bone raw[], int numBones, Math::Float interpolation, // comparable raw bone data and interpolation value + const Math::Matrix animatedBoneSourceA[], // relative bone animations + Math::Matrix animatedBoneSourceB_Target[] // relative bone animations and targetbuffer + ); + int AnimateAbsoluteBones + ( + const Model::ModelInfo &info, Math::Float deltaTime, + Model::AnimationData &anim, + Math::Matrix SkinTransformBuffer[], + Math::Matrix BoneAnimationBuffer_Relative[], + Math::Matrix BoneAnimationBuffer_Absolute[] + ); + int AnimateAbsoluteBones + ( + const Model::ModelInfo &info, Math::Float deltaTime, + Model::AnimationData anim[], int numAnimations, + Math::Matrix SkinTransformBuffer[], + Math::Matrix BoneAnimationBuffer_Relative[], + Math::Matrix BoneAnimationBuffer_Absolute[] + ); - void* data; + /******************************************************** + * Public Method Implementations + ********************************************************/ - Definitions::LightConstants lc; - lc.InvProj = Projection.GetInverse(); - lc.Pixels = Core::resolution; - lc.Lights = numLights; - lc.View = View; - lc.Proj = Projection; - lc.SSAORadius = 3; + void DefaultRenderer::NewFrame(Oyster::Math::Float4x4 View, Oyster::Math::Float4x4 Projection, Definitions::Pointlight* Lights, int numLights) + { + Preparations::Basic::ClearBackBuffer(Oyster::Math::Float4(0,0,0,0)); + Preparations::Basic::ClearDepthStencil(Resources::Gui::depth); + Preparations::Basic::ClearRTV(Resources::GBufferRTV,Resources::GBufferSize,Math::Float4(0,0,0,0)); + Lights[1]; - data = Resources::Light::LightConstantsData.Map(); - memcpy(data, &lc, sizeof(Definitions::LightConstants)); - Resources::Light::LightConstantsData.Unmap(); + void* data; - data = Resources::Light::PointLightsData.Map(); - memcpy(data, Lights, sizeof(Definitions::Pointlight) * numLights); - Resources::Light::PointLightsData.Unmap(); + Definitions::LightConstants lc; + lc.InvProj = Projection.GetInverse(); + lc.Pixels = Core::resolution; + lc.Lights = numLights; + lc.View = View; + lc.Proj = Projection; + lc.SSAORadius = 3; - for(auto i = Render::Resources::RenderData.begin(); i != Render::Resources::RenderData.end(); i++ ) + data = Resources::Light::LightConstantsData.Map(); + memcpy(data, &lc, sizeof(Definitions::LightConstants)); + Resources::Light::LightConstantsData.Unmap(); + + data = Resources::Light::PointLightsData.Map(); + Definitions::Pointlight* plData = (Definitions::Pointlight*)data; + for(int i=0; i < numLights; ++i) { - (*i).second->Models=0; + plData[i].Pos = (View * Math::Float4(Lights[i].Pos,1)).xyz; + plData[i].Radius = Lights[i].Radius; + plData[i].Color = Lights[i].Color; + plData[i].Bright = Lights[i].Bright; } + //memcpy(data, Lights, sizeof(Definitions::Pointlight) * numLights); + Resources::Light::PointLightsData.Unmap(); - Core::PipelineManager::SetRenderPass(Resources::Gather::AnimatedPass); + for(auto i = Render::Resources::RenderData.begin(); i != Render::Resources::RenderData.end(); i++ ) + { + (*i).second->Models=0; } - void DefaultRenderer::RenderScene(Model::Model* models, int count, Math::Matrix View, Math::Matrix Projection, float deltaTime) + Core::PipelineManager::SetRenderPass(Resources::Gather::AnimatedPass); + } + + void DefaultRenderer::RenderScene(Model::Model* models, int count, Math::Matrix View, Math::Matrix Projection, float deltaTime) + { + for(int i = 0; i < count; ++i) { - for(int i = 0; i < count; ++i) + if(&models[i] == NULL || !models[i].Visible) + continue; + + Model::ModelInfo* info = models[i].info; + if(!info->Animated && models[i].Instanced) { - if(&models[i] == NULL || !models[i].Visible) - continue; + Definitions::RenderInstanceData rid; + Math::Float3x3 normalTransform; + normalTransform = Math::Float3x3(models[i].WorldMatrix.v[0].xyz, models[i].WorldMatrix.v[1].xyz, models[i].WorldMatrix.v[2].xyz); + normalTransform.Transpose().Invert(); + Math::Matrix m = Math::Matrix(Math::Vector4(normalTransform.v[0],0.0f), Math::Vector4(normalTransform.v[1],0.0f), Math::Vector4(normalTransform.v[2],0.0f), Math::Vector4(0.0f)); + rid.WV = View * m; + rid.WVP = Projection * View * models[i].WorldMatrix; - Model::ModelInfo* info = models[i].info; - if(!info->Animated && models[i].Instanced) - { - Definitions::RenderInstanceData rid; - Math::Float3x3 normalTransform; - normalTransform = Math::Float3x3(models[i].WorldMatrix.v[0].xyz, models[i].WorldMatrix.v[1].xyz, models[i].WorldMatrix.v[2].xyz); - normalTransform.Transpose().Invert(); - Math::Matrix m = Math::Matrix(Math::Vector4(normalTransform.v[0],0.0f), Math::Vector4(normalTransform.v[1],0.0f), Math::Vector4(normalTransform.v[2],0.0f), Math::Vector4(0.0f)); - rid.WV = View * m; - rid.WVP = Projection * View * models[i].WorldMatrix; + rid.Tint = models[i].Tint; + rid.GTint = models[i].GlowTint; - rid.Tint = models[i].Tint; - rid.GTint = models[i].GlowTint; - - Resources::RenderData[info]->rid[Resources::RenderData[info]->Models++] = rid; - } - else - { - Definitions::PerModel pm; - Math::Float3x3 normalTransform; - normalTransform = Math::Float3x3(models[i].WorldMatrix.v[0].xyz, models[i].WorldMatrix.v[1].xyz, models[i].WorldMatrix.v[2].xyz); - normalTransform.Transpose().Invert(); - Math::Matrix m = Math::Matrix(Math::Vector4(normalTransform.v[0],0.0f), Math::Vector4(normalTransform.v[1],0.0f), Math::Vector4(normalTransform.v[2],0.0f), Math::Vector4(0.0f)); - pm.WV = View * m; - pm.WVP = Projection * View * models[i].WorldMatrix; - - Model::ModelInfo* info = models[i].info; - - Definitions::AnimationData am; //final - if(info->Animated && models[i].Animation.AnimationPlaying != NULL) - { - models[i].Animation.AnimationTime += deltaTime; - ////store inverse absolut transform - Math::Matrix SkinTransform[100]; - Math::Matrix BoneAnimated[100]; - Math::Matrix BoneAbsAnimated[100]; - - - - for(int b = 0; b BoneCount; ++b) - { - Model::Bone Bone = info->bones[b]; - SkinTransform[b] = Bone.Absolute.GetInverse(); - BoneAnimated[b] = Bone.Relative; - BoneAbsAnimated[b] = Bone.Absolute; - } - int b = 0; - Model::Animation A = *models[i].Animation.AnimationPlaying; - while(models[i].Animation.AnimationTime>A.duration && models[i].Animation.LoopAnimation) - models[i].Animation.AnimationTime -= (float)A.duration; - - float position = models[i].Animation.AnimationTime; - for(int b = 0; b < A.Bones;++b) - { - //find current frame - int nrOfFrames = A.Frames[b]; - Model::Frame PFrame = A.Keyframes[b][nrOfFrames-1]; - Model::Frame NFrame = A.Keyframes[b][nrOfFrames-1]; - bool FrameFound = false; - for (int i = 0; i < nrOfFrames; i++) - { - if(position < A.Keyframes[b][i].time) - { - PFrame = A.Keyframes[b][i-1]; - NFrame = A.Keyframes[b][i]; - break; - } - } - float denominator = (float)(NFrame.time - PFrame.time); - if(denominator == 0) - { - BoneAnimated[PFrame.bone.Parent] = PFrame.bone.Relative; - continue; - } - float inter = (float)((position - PFrame.time) / denominator); - Math3D::InterpolateOrientation_UsingNonRigidNlerp(PFrame.bone.Relative,NFrame.bone.Relative,inter, BoneAnimated[PFrame.bone.Parent]); - } - - ////calculate Absolute Animation Transform - for(int b = 0; b < info->BoneCount; ++b) - { - BoneAbsAnimated[b] = BoneAbsAnimated[info->bones[b].Parent] * BoneAnimated[b]; - } - - //write data to am - for(int b = 0; b < info->BoneCount; ++b) - { - am.AnimatedData[b] = (BoneAbsAnimated[b] * SkinTransform[b]); - } - - - void *data = Resources::Gather::AnimationData.Map(); - memcpy(data,&am,sizeof(Definitions::AnimationData)); - Resources::Gather::AnimationData.Unmap(); - - pm.Animated = 1; - } - else - pm.Animated = 0; - - void* data = Resources::Gather::ModelData.Map(); - memcpy(data,&(pm),sizeof(pm)); - Resources::Gather::ModelData.Unmap(); - - Definitions::TintData td; - td.GlowTint = models[i].GlowTint; - td.Tint = models[i].Tint; - td.PAD = 0; - td.PAD2 = 0; - int s = sizeof(Definitions::TintData); - - data = Render::Resources::Color.Map(); - memcpy(data,&td,sizeof(Definitions::TintData)); - Render::Resources::Color.Unmap(); - - if(info->Material.size()) - { - Core::deviceContext->PSSetShaderResources(0,(UINT)info->Material.size(),&(info->Material[0])); - } - - - info->Vertices->Apply(); - if(info->Indexed) - { - info->Indecies->Apply(); - Oyster::Graphics::Core::deviceContext->DrawIndexed(info->IndexCount,0,0); - } - else - { - Oyster::Graphics::Core::deviceContext->Draw(info->VertexCount,0); - } - } - } - } - - void BlurGlow() - { - Definitions::BlurrData bd; - bd.BlurMask = Math::Float4(1,1,1,1); - bd.StopX = (UINT)Core::resolution.x/2; - bd.StopY = (UINT)Core::resolution.y; - bd.StartX = 0; - bd.StartY = (UINT)Core::resolution.y/2; - - void* data = Resources::Blur::Data.Map(); - memcpy(data,&bd,sizeof(Definitions::BlurrData)); - Resources::Blur::Data.Unmap(); - - Core::PipelineManager::SetRenderPass(Resources::Blur::HorPass); - Core::deviceContext->Dispatch((UINT)((Core::resolution.x/2 + 127U) / 128U), (UINT)(Core::resolution.y/2), 1); - - Core::PipelineManager::SetRenderPass(Resources::Blur::VertPass); - Core::deviceContext->Dispatch((UINT)(Core::resolution.x/2), (UINT)((Core::resolution.y/2 + 127U) / 128U), 1); - } - - void BlurSSAO() - { - Definitions::BlurrData bd; - bd.BlurMask = Math::Float4(0,0,0,1); - bd.StopX = (UINT)Core::resolution.x/2; - bd.StopY = (UINT)Core::resolution.y/2; - bd.StartX = 0; - bd.StartY = 0; - - void* data = Resources::Blur::Data.Map(); - memcpy(data,&bd,sizeof(Definitions::BlurrData)); - Resources::Blur::Data.Unmap(); - - Core::PipelineManager::SetRenderPass(Resources::Blur::HorPass); - Core::deviceContext->Dispatch((UINT)((Core::resolution.x/2 + 127U) / 128U), (UINT)(Core::resolution.y/2), 1); - - Core::PipelineManager::SetRenderPass(Resources::Blur::VertPass); - Core::deviceContext->Dispatch((UINT)(Core::resolution.x/2), (UINT)((Core::resolution.y/2 + 127U) / 128U), 1); - } - - void RenderModel(Model::ModelInfo* info, Definitions::RenderInstanceData* rid , int count) - { - if(count < 1) - return; - if(info->Material.size()) - { - Core::deviceContext->PSSetShaderResources(0,(UINT)info->Material.size(),&(info->Material[0])); - } - info->Vertices->Apply(); - if(info->Indexed) - { - info->Indecies->Apply(); - } - - void* data = Resources::Gather::InstancedData.Map(); - memcpy(data, rid, sizeof(Definitions::RenderInstanceData)*count); - Resources::Gather::InstancedData.Unmap(); - - if(info->Indexed) - { - Core::deviceContext->DrawIndexedInstanced(info->IndexCount,count,0,0,0); - //Core::deviceContext->DrawIndexed(info->IndexCount,0,0); + Resources::RenderData[info]->rid[Resources::RenderData[info]->Models++] = rid; } else { - Core::deviceContext->DrawInstanced(info->VertexCount,count,0,0); - //Core::deviceContext->Draw(info->VertexCount,0); + Definitions::PerModel pm; + Math::Float3x3 normalTransform; + normalTransform = Math::Float3x3(models[i].WorldMatrix.v[0].xyz, models[i].WorldMatrix.v[1].xyz, models[i].WorldMatrix.v[2].xyz); + normalTransform.Transpose().Invert(); + Math::Matrix m = Math::Matrix(Math::Vector4(normalTransform.v[0],0.0f), Math::Vector4(normalTransform.v[1],0.0f), Math::Vector4(normalTransform.v[2],0.0f), Math::Vector4(0.0f)); + pm.WV = View * m; + pm.WVP = Projection * View * models[i].WorldMatrix; + + Model::ModelInfo* info = models[i].info; + + // Bone animation buffers + Math::Matrix SkinTransform[100]; + Math::Matrix BoneAnimated[100]; + Math::Matrix BoneAbsAnimated[100]; + + pm.Animated = AnimateAbsoluteBones + ( + *info, deltaTime, + models[i].Animation, + ::Utility::StaticArray::NumElementsOf( models[i].Animation ), + SkinTransform, BoneAnimated, BoneAbsAnimated + ); + + void* data = Resources::Gather::ModelData.Map(); + memcpy(data,&(pm),sizeof(pm)); + Resources::Gather::ModelData.Unmap(); + + Definitions::TintData td; + td.GlowTint = models[i].GlowTint; + td.Tint = models[i].Tint; + td.PAD = 0; + td.PAD2 = 0; + int s = sizeof(Definitions::TintData); + + data = Render::Resources::Color.Map(); + memcpy(data,&td,sizeof(Definitions::TintData)); + Render::Resources::Color.Unmap(); + + if(info->Material.size()) + { + Core::deviceContext->PSSetShaderResources(0,(UINT)info->Material.size(),&(info->Material[0])); + } + + + info->Vertices->Apply(); + if(info->Indexed) + { + info->Indecies->Apply(); + Oyster::Graphics::Core::deviceContext->DrawIndexed(info->IndexCount,0,0); + } + else + { + Oyster::Graphics::Core::deviceContext->Draw(info->VertexCount,0); + } } - } + } + } + void BlurGlow() + { + Definitions::BlurrData bd; + bd.BlurMask = Math::Float4(1,1,1,1); + bd.StopX = (UINT)Core::resolution.x/2; + bd.StopY = (UINT)Core::resolution.y; + bd.StartX = 0; + bd.StartY = (UINT)Core::resolution.y/2; + + void* data = Resources::Blur::Data.Map(); + memcpy(data,&bd,sizeof(Definitions::BlurrData)); + Resources::Blur::Data.Unmap(); - void DefaultRenderer::EndFrame() + Core::PipelineManager::SetRenderPass(Resources::Blur::HorPass); + Core::deviceContext->Dispatch((UINT)((Core::resolution.x/2 + 127U) / 128U), (UINT)(Core::resolution.y/2), 1); + + Core::PipelineManager::SetRenderPass(Resources::Blur::VertPass); + Core::deviceContext->Dispatch((UINT)(Core::resolution.x/2), (UINT)((Core::resolution.y/2 + 127U) / 128U), 1); + } + + void BlurSSAO() + { + Definitions::BlurrData bd; + bd.BlurMask = Math::Float4(0,0,0,1); + bd.StopX = (UINT)Core::resolution.x/2; + bd.StopY = (UINT)Core::resolution.y/2; + bd.StartX = 0; + bd.StartY = 0; + + void* data = Resources::Blur::Data.Map(); + memcpy(data,&bd,sizeof(Definitions::BlurrData)); + Resources::Blur::Data.Unmap(); + + Core::PipelineManager::SetRenderPass(Resources::Blur::HorPass); + Core::deviceContext->Dispatch((UINT)((Core::resolution.x/2 + 127U) / 128U), (UINT)(Core::resolution.y/2), 1); + + Core::PipelineManager::SetRenderPass(Resources::Blur::VertPass); + Core::deviceContext->Dispatch((UINT)(Core::resolution.x/2), (UINT)((Core::resolution.y/2 + 127U) / 128U), 1); + } + + void RenderModel(Model::ModelInfo* info, Definitions::RenderInstanceData* rid , int count) + { + if(count < 1) + return; + if(info->Material.size()) { - Core::PipelineManager::SetRenderPass(Graphics::Render::Resources::Gather::InstancedPass); - Resources::Gather::InstancedData.Apply(1); + Core::deviceContext->PSSetShaderResources(0,(UINT)info->Material.size(),&(info->Material[0])); + } + info->Vertices->Apply(); + if(info->Indexed) + { + info->Indecies->Apply(); + } - for(auto i = Render::Resources::RenderData.begin(); i != Render::Resources::RenderData.end(); i++ ) + void* data = Resources::Gather::InstancedData.Map(); + memcpy(data, rid, sizeof(Definitions::RenderInstanceData)*count); + Resources::Gather::InstancedData.Unmap(); + + if(info->Indexed) + { + Core::deviceContext->DrawIndexedInstanced(info->IndexCount,count,0,0,0); + //Core::deviceContext->DrawIndexed(info->IndexCount,0,0); + } + else + { + Core::deviceContext->DrawInstanced(info->VertexCount,count,0,0); + //Core::deviceContext->Draw(info->VertexCount,0); + } + } + + + void DefaultRenderer::EndFrame() + { + Core::PipelineManager::SetRenderPass(Graphics::Render::Resources::Gather::InstancedPass); + Resources::Gather::InstancedData.Apply(1); + + for(auto i = Render::Resources::RenderData.begin(); i != Render::Resources::RenderData.end(); i++ ) + { + RenderModel((*i).first,(*i).second->rid, (*i).second->Models); + } + + Core::PipelineManager::SetRenderPass(Resources::Light::Pass); + + Core::deviceContext->Dispatch((UINT)((Core::resolution.x + 15U) / 16U), (UINT)((Core::resolution.y + 15U) / 16U), 1); + + BlurGlow(); + + BlurSSAO(); + + Core::PipelineManager::SetRenderPass(Resources::Post::Pass); + + Core::deviceContext->Dispatch((UINT)((Core::resolution.x + 15U) / 16U), (UINT)((Core::resolution.y + 15U) / 16U), 1); + + Core::swapChain->Present(0,0); + } + + /******************************************************** + * Private Prototype Method Implementations + ********************************************************/ + + void AnimateRelativeBones( const Model::ModelInfo &info, Model::AnimationData &anim, Math::Matrix relativeBuffer[] ) + { + for( int i = 0; i < info.BoneCount; ++i ) + { + Model::Bone Bone = info.bones[i]; + relativeBuffer[i] = Bone.Relative; + } + + const Model::Animation &A = *anim.AnimationPlaying; + + while( anim.AnimationTime > A.duration && anim.LoopAnimation ) + anim.AnimationTime -= (float)A.duration; + + float position = anim.AnimationTime; + for( int i = 0; i < A.Bones; ++i ) + { + //find current frame + int nrOfFrames = A.Frames[i]; + Model::Frame PFrame = A.Keyframes[i][nrOfFrames-1]; + Model::Frame NFrame = A.Keyframes[i][nrOfFrames-1]; + bool FrameFound = false; + + for (int j = 0; j < nrOfFrames; j++) { - RenderModel((*i).first,(*i).second->rid, (*i).second->Models); + if(position < A.Keyframes[i][j].time) + { + PFrame = A.Keyframes[i][j-1]; + NFrame = A.Keyframes[i][j]; + break; + } } - Core::PipelineManager::SetRenderPass(Resources::Light::Pass); - - Core::deviceContext->Dispatch((UINT)((Core::resolution.x + 15U) / 16U), (UINT)((Core::resolution.y + 15U) / 16U), 1); - - BlurGlow(); - - BlurSSAO(); - - Core::PipelineManager::SetRenderPass(Resources::Post::Pass); - - Core::deviceContext->Dispatch((UINT)((Core::resolution.x + 15U) / 16U), (UINT)((Core::resolution.y + 15U) / 16U), 1); - - Core::swapChain->Present(0,0); + float denominator = (float)(NFrame.time - PFrame.time); + + if( denominator != 0.0f ) + { + float inter = (float)((position - PFrame.time) / denominator); + Math3D::InterpolateOrientation_UsingNonRigidNlerp( PFrame.bone.Relative,NFrame.bone.Relative, inter, relativeBuffer[PFrame.bone.Parent] ); + } + else + { + relativeBuffer[PFrame.bone.Parent] = PFrame.bone.Relative; + } } + } + + enum Conflict + { + Conflict_detected, + Conflict_useA, + Conflict_useB + }; + + Conflict DetectBoneAnimationConflict( const Model::Bone &raw, const Math::Matrix &animBoneA, const Math::Matrix &animBoneB ); + + void MergeAnimatedBones( const Model::Bone raw[], int numBones, Math::Float interpolation, const Math::Matrix *animatedBoneSourceA, Math::Matrix animatedBoneSourceB_Target[] ) + { + for( int i = 0; i < numBones; ++i ) + { + switch( DetectBoneAnimationConflict(raw[i], animatedBoneSourceA[i], animatedBoneSourceB_Target[i]) ) + { + case Conflict_detected: + Math3D::InterpolateOrientation_UsingNonRigidNlerp( animatedBoneSourceA[i], animatedBoneSourceB_Target[i], interpolation, animatedBoneSourceB_Target[i] ); + break; + case Conflict_useA: + animatedBoneSourceB_Target[i] = animatedBoneSourceA[i]; + break; + default: case Conflict_useB: break; + } + } + } + + Conflict DetectBoneAnimationConflict( const Model::Bone &raw, const Math::Matrix &animBoneA, const Math::Matrix &animBoneB ) + { + if( animBoneA == raw.Relative ) + return Conflict_useB; + + if( animBoneB == raw.Relative ) + return Conflict_useA; + + return Conflict_detected; + } + + int AnimateAbsoluteBones( const Model::ModelInfo &info, Math::Float deltaTime, Model::AnimationData &anim, Math::Matrix SkinTransformBuffer[], Math::Matrix BoneAnimationBuffer_Relative[], Math::Matrix BoneAnimationBuffer_Absolute[] ) + { + if( !info.Animated || (anim.AnimationPlaying == nullptr) ) + { // no animation + return 0; + } + + anim.AnimationTime += deltaTime; + AnimateRelativeBones( info, anim, BoneAnimationBuffer_Relative ); + + for( int i = 0; i < info.BoneCount; ++i ) + { + Model::Bone Bone = info.bones[i]; + SkinTransformBuffer[i] = Bone.Absolute.GetInverse(); + BoneAnimationBuffer_Absolute[i] = Bone.Absolute; + } + + Definitions::AnimationData am; + + for( int i = 0; i < info.BoneCount; ++i ) + { + //calculate Absolute Animation Transform + BoneAnimationBuffer_Absolute[i] = BoneAnimationBuffer_Absolute[info.bones[i].Parent] * BoneAnimationBuffer_Relative[i]; + + //write data to am + am.AnimatedData[i] = (BoneAnimationBuffer_Absolute[i] * SkinTransformBuffer[i]); + } + + void *data = Resources::Gather::AnimationData.Map(); + memcpy( data, &am, sizeof(Definitions::AnimationData) ); + Resources::Gather::AnimationData.Unmap(); + + return 1; + } + + int AnimateAbsoluteBones( const Model::ModelInfo &info, Math::Float deltaTime, Model::AnimationData anim[], int numAnimations, Math::Matrix SkinTransformBuffer[], Math::Matrix BoneAnimationBuffer_Relative[], Math::Matrix BoneAnimationBuffer_Absolute[] ) + { + if( !info.Animated || (numAnimations < 1) ) + { // no animation + return 0; + } + int isAnimated = 0; + + // for each animation + for( int i = 0; i < numAnimations; ++i ) + { + if( anim[i].AnimationPlaying != nullptr ) + { + anim[i].AnimationTime += deltaTime; + if( isAnimated ) + { + AnimateRelativeBones( info, anim[i], BoneAnimationBuffer_Absolute ); // Borrowing BoneAnimationBuffer_Absolute as interim buffer + MergeAnimatedBones( info.bones, info.BoneCount, 0.5f, BoneAnimationBuffer_Absolute, BoneAnimationBuffer_Relative ); + } + else + { + isAnimated = 1; + AnimateRelativeBones( info, anim[i], BoneAnimationBuffer_Relative ); + } + } + } + + if( isAnimated ) + { + for( int i = 0; i < info.BoneCount; ++i ) + { + Model::Bone Bone = info.bones[i]; + SkinTransformBuffer[i] = Bone.Absolute.GetInverse(); + BoneAnimationBuffer_Absolute[i] = Bone.Absolute; + } + + Definitions::AnimationData am; + + for( int i = 0; i < info.BoneCount; ++i ) + { + //calculate Absolute Animation Transform + BoneAnimationBuffer_Absolute[i] = BoneAnimationBuffer_Absolute[info.bones[i].Parent] * BoneAnimationBuffer_Relative[i]; + + //write data to am + am.AnimatedData[i] = (BoneAnimationBuffer_Absolute[i] * SkinTransformBuffer[i]); + } + + void *data = Resources::Gather::AnimationData.Map(); + memcpy( data, &am, sizeof(Definitions::AnimationData) ); + Resources::Gather::AnimationData.Unmap(); + } + + return isAnimated; + } } } } \ No newline at end of file diff --git a/Code/OysterGraphics/Render/DefaultRenderer.h b/Code/OysterGraphics/Render/DefaultRenderer.h index 1a5cdcc0..74a1e4ff 100644 --- a/Code/OysterGraphics/Render/DefaultRenderer.h +++ b/Code/OysterGraphics/Render/DefaultRenderer.h @@ -13,7 +13,7 @@ namespace Oyster class DefaultRenderer { public: - static void NewFrame(Oyster::Math::Float4x4 View, Oyster::Math::Float4x4 Projection, Definitions::Pointlight* Lights, int numLights); + static void NewFrame(Oyster::Math::Float4x4 View, Oyster::Math::Float4x4 Projection, Definitions::Pointlight* Lights, int numLights, float Fov); static void RenderScene(Model::Model* models, int count, Math::Matrix View, Math::Matrix Projection, float DeltaTime = 0); static void EndFrame(); }; diff --git a/Code/OysterGraphics/Render/Resources.h b/Code/OysterGraphics/Render/Resources.h index fe1393b9..d7f66199 100644 --- a/Code/OysterGraphics/Render/Resources.h +++ b/Code/OysterGraphics/Render/Resources.h @@ -24,7 +24,7 @@ namespace Oyster static const int GBufferSize = 3; static const int LBufferSize = 3; - static const int MaxLightSize = 100; + static const int MaxLightSize = 1024; //! GBuffers //! 0 = Diffuse + Glow diff --git a/Code/OysterGraphics/Shader/Passes/Light/Defines.hlsli b/Code/OysterGraphics/Shader/Passes/Light/Defines.hlsli index fb125b12..0db1b98f 100644 --- a/Code/OysterGraphics/Shader/Passes/Light/Defines.hlsli +++ b/Code/OysterGraphics/Shader/Passes/Light/Defines.hlsli @@ -19,20 +19,24 @@ cbuffer LightConstants : register(b0) { float4x4 InvProj; float4x4 Proj; - float2 Pixels; + float FoV; int Lights; float SSAORadius; + float pad; float4x4 View; } struct FrustrumPoints { - float3 v0; - float3 v1; - float3 v2; - float3 v3; - float3 v4; - float3 v5; + float3 NUL; + float3 NUR; + float3 NDL; + float3 NDR; + + float3 FUL; + float3 FUR; + float3 FDL; + float3 FDR; }; Texture2D DiffuseGlow : register(t0); diff --git a/Code/OysterGraphics/Shader/Passes/Light/LightCalc.hlsli b/Code/OysterGraphics/Shader/Passes/Light/LightCalc.hlsli index 81fa2fa1..36606f01 100644 --- a/Code/OysterGraphics/Shader/Passes/Light/LightCalc.hlsli +++ b/Code/OysterGraphics/Shader/Passes/Light/LightCalc.hlsli @@ -4,10 +4,18 @@ DiffSpec LightCalc(PointLight pl, float3 pos, int2 texCoord) { DiffSpec output; float4 normalSpec = NormalSpec[texCoord]; - float4 LPos = mul(View, float4(pl.Pos, 1)); - float3 lightVec = LPos.xyz - pos.xyz; + float4 LPos = float4(pl.Pos, 1); + float3 lightVec = LPos.xyz - pos; float d = length(lightVec); + lightVec = lightVec/d; + + if(d > pl.Radius) + { + output.Diffuse = float3(0,0,0); + output.Specular = float3(0,0,0); + return output; + } float diffFactor = max(dot(lightVec, normalSpec.xyz), 0.0f); float3 v = reflect(-lightVec, normalSpec.xyz); @@ -15,21 +23,13 @@ DiffSpec LightCalc(PointLight pl, float3 pos, int2 texCoord) //Check att later float att = max( 0, 1 - (d / pl.Radius)); //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; - if(d > pl.Radius) - { - output.Diffuse = float3(0,0,0); - output.Specular = float3(0,0,0); - } + float SpecCo = normalSpec.w < 1 ? 0.0f : 1.0f; + output.Specular = output.Specular * SpecCo; return output; -} - -bool intersects(FrustrumPoints box, int Index) -{ - return true; } \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/Passes/Light/LightPass.hlsl b/Code/OysterGraphics/Shader/Passes/Light/LightPass.hlsl index ddaed99e..adec6575 100644 --- a/Code/OysterGraphics/Shader/Passes/Light/LightPass.hlsl +++ b/Code/OysterGraphics/Shader/Passes/Light/LightPass.hlsl @@ -8,20 +8,18 @@ //Calc Ambience Done //Write Glow -#define EXPAND 1024.0f -#define SHRINK 1.0f/EXPAND #define UINT_MAX 0xFFFFFFFF #define FLOAT_MAX 3.402823466e+38 #define BLOCKSIZE 16 #define NUMTHREADS BLOCKSIZE * BLOCKSIZE -#define MAXLIGHTS 100 +#define MAXLIGHTS 1024 +#define TEXTURESPREAD 1/255 // -- Shared Memory ------------------------------------------------- // -groupshared uint iMinDepth = UINT_MAX, - iMaxDepth = 0; -groupshared uint numVisiblePointLights = 0, +groupshared uint iMinDepth, iMaxDepth; +groupshared uint numVisiblePointLights, visiblePointlightIndex[MAXLIGHTS]; // ------------------------------------------------------------------ // @@ -29,77 +27,104 @@ groupshared uint numVisiblePointLights = 0, [numthreads(BLOCKSIZE, BLOCKSIZE, 1)] void main( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint3 Gid : SV_GroupID, uint GI : SV_GroupIndex ) { - float2 UV = DTid.xy / Pixels; + float2 UV = DTid.xy / (float2)Diffuse.Length.xy; UV.x = UV.x * 2 - 1; UV.y = 1 - 2 * UV.y; float3 posN = float3(UV, DepthTexture[DTid.xy].x); + + float3 ViewPos = ToVpos(DTid.xy, UV); + + if(GI==0) + { + numVisiblePointLights = 0; + iMinDepth = 0x7F7FFFFF; + iMaxDepth = 0; + } + GroupMemoryBarrierWithGroupSync(); // store and load shared minDepth and maxDepth - float minDepth = 0.0f, maxDepth = 0.0f, - depth = posN.z; + float minDepth = 0.0f, maxDepth = 0.0f; { - uint uidepth = (uint)( depth * EXPAND); - InterlockedMin( iMinDepth, uidepth ); - InterlockedMax( iMaxDepth, uidepth ); + InterlockedMin( iMinDepth, asuint(ViewPos.z) ); + InterlockedMax( iMaxDepth, asuint(ViewPos.z) ); GroupMemoryBarrierWithGroupSync(); - minDepth = (float)( iMinDepth ) * SHRINK; - maxDepth = (float)( iMaxDepth ) * SHRINK; + minDepth = asfloat(iMinDepth); + maxDepth = asfloat(iMaxDepth); } // -- Switching to LightCulling ------------------------------------- // //define collision volume - float2 size = BLOCKSIZE / Pixels; - FrustrumPoints tile; - tile.v0 = float3(size * Gid,minDepth); - tile.v1 = float3(tile.v0.xy+size,maxDepth); - tile.v2 = float3(tile.v1.xy, minDepth); - tile.v3 = float3(tile.v0.x,tile.v1.y,minDepth); - tile.v4 = float3(tile.v1.x, tile.v0.y, minDepth); - tile.v5 = float3(tile.v0.xy, maxDepth); + float2 tilescale = float2(Diffuse.Length.xy) * rcp(float(2 * BLOCKSIZE)); + float2 tilebias = tilescale - float2(Gid.xy); + // Now work out composite projection matrix + // Relevant matrix columns for this tile frusta + float4 c1 = float4(Proj._11 * tilescale.x, 0.0f, tilebias.x, 0.0f); + float4 c2 = float4(0.0f, -Proj._22 * tilescale.y, tilebias.y, 0.0f); + float4 c4 = float4(0.0f, 0.0f, 1.0f, 1.0f); + // Derive frustum planes + float4 frustumPlanes[6]; + // Sides + frustumPlanes[0] = c4 - c1; + frustumPlanes[1] = c4 + c1; + frustumPlanes[2] = c4 - c2; + frustumPlanes[3] = c4 + c2; + // Near/far + frustumPlanes[4] = float4(0.0f, 0.0f, 1.0f, -minDepth); + frustumPlanes[5] = float4(0.0f, 0.0f, -1.0f, maxDepth); + + // Normalize frustum planes (near/far already normalized) + [unroll] + for (uint i = 0; i < 4; ++i) + { + frustumPlanes[i] *= rcp(length(frustumPlanes[i].xyz)); + } // culling the tile's near and far to minDepth & maxDepth ( with tolerance ) - uint numPass = (Lights + NUMTHREADS - 1) / NUMTHREADS; - numPass = min( numPass, MAXLIGHTS / NUMTHREADS ); - - for( uint passI = 0; passI < numPass; ++passI ) + for(uint lightIndex = GI; lightIndex < Lights; lightIndex += NUMTHREADS) + { + PointLight pl = Points[lightIndex]; + + bool inFrustrum = true; + [unroll] + for(int i = 0; i < 6; ++i) { - uint lightIndex = (passI * NUMTHREADS) + GI; - lightIndex = min( lightIndex, Lights ); - - if( lightIndex < Lights ) - if( intersects(tile, lightIndex) ) - { - uint offset; - InterlockedAdd( numVisiblePointLights, 1, offset ); - visiblePointlightIndex[offset] = lightIndex; - } + float d = dot(frustumPlanes[i], float4(pl.Pos, 1.0f)); + inFrustrum = inFrustrum && (d >= -pl.Radius); } + [branch] + if(inFrustrum) + { + uint offset; + InterlockedAdd( numVisiblePointLights, 1, offset ); + visiblePointlightIndex[offset] = lightIndex; + } + } + GroupMemoryBarrierWithGroupSync(); - float3 ViewPos = ToVpos(DTid.xy, UV); DiffSpec Shaded; Shaded.Diffuse = float3(0,0,0); Shaded.Specular = float3(0,0,0); - for(int i = 0; i < Lights; ++i) + for(int i = 0; i < numVisiblePointLights; ++i) { - DiffSpec light = LightCalc(Points[i], ViewPos, DTid.xy); + DiffSpec light = LightCalc(Points[visiblePointlightIndex[i]], ViewPos, DTid.xy); Shaded.Diffuse += light.Diffuse; Shaded.Specular += light.Specular; } - Diffuse[DTid.xy] = float4(Shaded.Diffuse * DiffuseGlow[DTid.xy].xyz,0); + Diffuse[DTid.xy] = float4(Shaded.Diffuse * DiffuseGlow[DTid.xy].xyz,1); Specular[DTid.xy] = float4(Shaded.Specular, 0); @@ -113,14 +138,16 @@ void main( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uin DiffBase = DiffBase / 4; float4 DepthBase = DepthTexture[DTid.xy]; - DepthBase = DepthTexture[DTid.xy + uint2(1,0)]; - DepthBase = DepthTexture[DTid.xy + uint2(0,1)]; - DepthBase = DepthTexture[DTid.xy + uint2(1,1)]; + DepthBase += DepthTexture[DTid.xy + uint2(1,0)]; + DepthBase += DepthTexture[DTid.xy + uint2(0,1)]; + DepthBase += DepthTexture[DTid.xy + uint2(1,1)]; DepthBase = DepthBase /4; - Ambient[DTid.xy/2] = float4(DiffBase.xyz, AmbValue); - Ambient[DTid.xy/2 + float2(Pixels.x/2, 0)] = GUI[DTid.xy]; - Ambient[DTid.xy/2 + float2(0, Pixels.y/2)] = float4(DiffBase.xyz * DiffBase.w ,DiffBase.w); - Ambient[DTid.xy/2 + Pixels/2] = float4(NormalSpec[DTid.xy].xyz * float3(1,1,-1),1); + Ambient[DTid.xy/2] = float4(DiffBase.xyz , AmbValue); + //Ambient[DTid.xy/2] = float4(DiffBase.xyz, 1); + Ambient[DTid.xy/2 + float2(Diffuse.Length.x/2, 0)] = GUI[DTid.xy]; + Ambient[DTid.xy/2 + float2(0, Diffuse.Length.y/2)] = float4(DiffBase.xyz * DiffBase.w ,DiffBase.w); + //Ambient[DTid.xy/2 + Diffuse.Length.xy/2] = float4(numVisiblePointLights * (1.0f/Lights), 0, 0 ,1); + Ambient[DTid.xy/2 + Diffuse.Length.xy/2] = float4(NormalSpec[DTid.xy/2].xyz ,1); } } \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/Passes/Light/SSAO.hlsli b/Code/OysterGraphics/Shader/Passes/Light/SSAO.hlsli index c71cb4d5..10cb00f6 100644 --- a/Code/OysterGraphics/Shader/Passes/Light/SSAO.hlsli +++ b/Code/OysterGraphics/Shader/Passes/Light/SSAO.hlsli @@ -23,6 +23,7 @@ float GetSSAO(float3 pos, float2 uv, int2 texCoord2, uint2 rndID) float3 sampled = mul(tbn, SSAOKernel[i].xyz); sampled = sampled * Radius + pos; + //project sample to get uv.xy float4 ProjOffset = float4(sampled,1); ProjOffset = mul(Proj, ProjOffset); @@ -35,7 +36,7 @@ float GetSSAO(float3 pos, float2 uv, int2 texCoord2, uint2 rndID) // get depth from that point in screenspace uint2 texCoord; - texCoord = (uint2)(offset.xy * Pixels); + texCoord = (uint2)(offset.xy * Diffuse.Length.xy); float3 ViewPos = ToVpos(texCoord, UV); float sampleDepth = ViewPos.z; @@ -43,6 +44,8 @@ float GetSSAO(float3 pos, float2 uv, int2 texCoord2, uint2 rndID) //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 += rangeCheck; + } occlusion /= (float)(SSAOKernel.Length.x); occlusion = 1.0f - occlusion; diff --git a/Code/OysterGraphics/Shader/Passes/Post/PostPass.hlsl b/Code/OysterGraphics/Shader/Passes/Post/PostPass.hlsl index c3f7e69e..2a498804 100644 --- a/Code/OysterGraphics/Shader/Passes/Post/PostPass.hlsl +++ b/Code/OysterGraphics/Shader/Passes/Post/PostPass.hlsl @@ -44,4 +44,5 @@ void main( uint3 DTid : SV_DispatchThreadID ) //Output[DTid.xy] = float4(Ambient[DTid.xy/2 + uint2(Output.Length*0.5f)].xyz,1); //Output[DTid.xy] = SSAO * float4(1,1,1,1); //Output[DTid.xy] = Ambient[DTid.xy]; + //Output[DTid.xy] = Diffuse[DTid.xy]; } \ No newline at end of file