diff --git a/Code/Game/GameClient/GameClientState/GameState.cpp b/Code/Game/GameClient/GameClientState/GameState.cpp index d08b1101..b608a4f3 100644 --- a/Code/Game/GameClient/GameClientState/GameState.cpp +++ b/Code/Game/GameClient/GameClientState/GameState.cpp @@ -114,8 +114,8 @@ void GameState::InitiatePlayer( int id, const std::string &modelName, const floa modelData.position = position; modelData.rotation = ArrayToQuaternion( rotation ); modelData.scale = scale; - StringToWstring( modelName, modelData.modelPath ); modelData.id = id; + StringToWstring(modelName,modelData.modelPath); // RB DEBUG RBInitData RBData; @@ -141,8 +141,8 @@ void GameState::InitiatePlayer( int id, const std::string &modelName, const floa this->privData->camera.SetPosition( p->getPos() ); Float3 offset = Float3( 0.0f ); // DEBUG position of camera so we can see the player model - //offset.y = p->getScale().y * 5.0f; - //offset.z = p->getScale().z * -5.0f; + offset.y = p->getScale().y * 5.0f; + offset.z = p->getScale().z * -5.0f; // !DEBUG this->privData->camera.SetHeadOffset( offset ); this->privData->camera.UpdateOrientation(); @@ -186,7 +186,7 @@ bool GameState::Render() { if(playerObject->second) { - if( this->privData->myId != playerObject->second->GetId() ) + //if( this->privData->myId != playerObject->second->GetId() ) { playerObject->second->Render(); } diff --git a/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp b/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp index d4c48957..ee3d9f8a 100644 --- a/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp +++ b/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp @@ -58,9 +58,11 @@ namespace Oyster debugSRV = (ID3D11ShaderResourceView*)API::CreateTexture(L"color_white.png"); cube = CreateModel(L"generic_cube.dan"); - cube->Tint = Math::Float3(0.0f,0.0f,1.0f); + cube->Tint = Math::Float3(1.0f,0.0f,0.0f); + cube->Instanced = false; sphere = CreateModel(L"generic_sphere.dan"); sphere->Tint = Math::Float3(1.0f,0.5f,182/255.0f); + sphere->Instanced = false; D3D11_RASTERIZER_DESC desc; @@ -158,7 +160,7 @@ namespace Oyster desc.Type = Core::Buffer::VERTEX_BUFFER; desc.Usage = Core::Buffer::BUFFER_CPU_WRITE_DISCARD; desc.InitData = 0; - desc.NumElements = maxModels; + desc.NumElements = maxModels+1; Render::Resources::Gather::InstancedData.Init(desc); } @@ -172,6 +174,7 @@ namespace Oyster m->Animation.AnimationPlaying = NULL; m->Tint = Math::Float3(1); m->GlowTint = Math::Float3(1); + m->Instanced = true; m->info = (Model::ModelInfo*)Core::loader.LoadResource((Core::modelPath + filename).c_str(),Oyster::Graphics::Loading::LoadDAN, Oyster::Graphics::Loading::UnloadDAN); Model::ModelInfo* mi = (Model::ModelInfo*)m->info; @@ -256,9 +259,9 @@ namespace Oyster void API::StartRenderWireFrame() { - Core::deviceContext->OMSetRenderTargets((UINT)Render::Resources::Gather::AnimatedPass.RTV.size(),&Render::Resources::Gather::AnimatedPass.RTV[0],NULL); + //Core::deviceContext->OMSetRenderTargets((UINT)Render::Resources::Gather::AnimatedPass.RTV.size(),&Render::Resources::Gather::AnimatedPass.RTV[0],NULL); Core::deviceContext->RSSetState(wire); - Core::deviceContext->OMSetRenderTargets((UINT)Render::Resources::Gather::AnimatedPass.RTV.size(),&Render::Resources::Gather::AnimatedPass.RTV[0],NULL); + //Core::deviceContext->OMSetRenderTargets((UINT)Render::Resources::Gather::AnimatedPass.RTV.size(),&Render::Resources::Gather::AnimatedPass.RTV[0],NULL); } void API::RenderDebugCube(Math::Matrix world) diff --git a/Code/OysterGraphics/Model/Model.h b/Code/OysterGraphics/Model/Model.h index 5985dbcd..6d4e96f2 100644 --- a/Code/OysterGraphics/Model/Model.h +++ b/Code/OysterGraphics/Model/Model.h @@ -26,6 +26,7 @@ namespace Oyster Oyster::Math::Float3 Tint; Oyster::Math::Float3 GlowTint; bool Visible; + bool Instanced; AnimationData Animation; }; } diff --git a/Code/OysterGraphics/Render/DefaultRenderer.cpp b/Code/OysterGraphics/Render/DefaultRenderer.cpp index a735f4b3..4b979be8 100644 --- a/Code/OysterGraphics/Render/DefaultRenderer.cpp +++ b/Code/OysterGraphics/Render/DefaultRenderer.cpp @@ -43,6 +43,8 @@ namespace Oyster { (*i).second->Models=0; } + + Core::PipelineManager::SetRenderPass(Resources::Gather::AnimatedPass); } void DefaultRenderer::RenderScene(Model::Model* models, int count, Math::Matrix View, Math::Matrix Projection, float deltaTime) @@ -53,7 +55,7 @@ namespace Oyster continue; Model::ModelInfo* info = models[i].info; - if(!info->Animated) + if(!info->Animated && models[i].Instanced) { Definitions::RenderInstanceData rid; Math::Float3x3 normalTransform; @@ -229,6 +231,8 @@ namespace Oyster 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])); @@ -263,10 +267,7 @@ namespace Oyster for(auto i = Render::Resources::RenderData.begin(); i != Render::Resources::RenderData.end(); i++ ) { - for(int m = 0; m <(*i).second->Models; ++m) - { - RenderModel((*i).first,(*i).second->rid, (*i).second->Models); - } + RenderModel((*i).first,(*i).second->rid, (*i).second->Models); } Core::PipelineManager::SetRenderPass(Resources::Light::Pass); diff --git a/Code/OysterGraphics/Render/Resources.cpp b/Code/OysterGraphics/Render/Resources.cpp index 91317114..cced13e9 100644 --- a/Code/OysterGraphics/Render/Resources.cpp +++ b/Code/OysterGraphics/Render/Resources.cpp @@ -366,8 +366,8 @@ namespace Oyster ////---------------- Geometry Pass Setup ---------------------------- #pragma region Animated Pass - Gather::AnimatedPass.Shaders.Pixel = GetShader::Pixel(L"Gather"); - Gather::AnimatedPass.Shaders.Vertex = GetShader::Vertex(L"Gather"); + Gather::AnimatedPass.Shaders.Pixel = GetShader::Pixel(L"AGather"); + Gather::AnimatedPass.Shaders.Vertex = GetShader::Vertex(L"AGather"); D3D11_INPUT_ELEMENT_DESC AnimInDesc[] = { @@ -378,7 +378,7 @@ namespace Oyster { "BONEWEIGHT", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 48, D3D11_INPUT_PER_VERTEX_DATA, 0 } }; - Shader::CreateInputLayout(AnimInDesc,5,GetShader::Vertex(L"Gather"),Gather::AnimatedPass.IAStage.Layout); + Shader::CreateInputLayout(AnimInDesc,5,GetShader::Vertex(L"AGather"),Gather::AnimatedPass.IAStage.Layout); Gather::AnimatedPass.IAStage.Topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; Gather::AnimatedPass.CBuffers.Vertex.push_back(Gather::AnimationData); Gather::AnimatedPass.CBuffers.Vertex.push_back(Gather::ModelData); @@ -525,9 +525,6 @@ namespace Oyster Shader::CreateInputLayout(InstInDesc,15,GetShader::Vertex(L"IGather"),Gather::InstancedPass.IAStage.Layout); Gather::InstancedPass.IAStage.Topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - Gather::InstancedPass.CBuffers.Vertex.push_back(Gather::AnimationData); - Gather::InstancedPass.CBuffers.Vertex.push_back(Gather::ModelData); - Gather::InstancedPass.CBuffers.Pixel.push_back(Color); Gather::InstancedPass.RenderStates.Rasterizer = RenderStates::rs; Gather::InstancedPass.RenderStates.SampleCount = 1; Gather::InstancedPass.RenderStates.SampleState = RenderStates::ss; diff --git a/Code/OysterGraphics/Shader/Passes/Light/Defines.hlsli b/Code/OysterGraphics/Shader/Passes/Light/Defines.hlsli index adf01e9d..fb125b12 100644 --- a/Code/OysterGraphics/Shader/Passes/Light/Defines.hlsli +++ b/Code/OysterGraphics/Shader/Passes/Light/Defines.hlsli @@ -25,6 +25,16 @@ cbuffer LightConstants : register(b0) float4x4 View; } +struct FrustrumPoints +{ + float3 v0; + float3 v1; + float3 v2; + float3 v3; + float3 v4; + float3 v5; +}; + Texture2D DiffuseGlow : register(t0); Texture2D NormalSpec : register(t1); Texture2D GUI : register(t2); diff --git a/Code/OysterGraphics/Shader/Passes/Light/LightCalc.hlsli b/Code/OysterGraphics/Shader/Passes/Light/LightCalc.hlsli index 3dc2b45e..81fa2fa1 100644 --- a/Code/OysterGraphics/Shader/Passes/Light/LightCalc.hlsli +++ b/Code/OysterGraphics/Shader/Passes/Light/LightCalc.hlsli @@ -27,4 +27,9 @@ DiffSpec LightCalc(PointLight pl, float3 pos, int2 texCoord) 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 89ed06d3..ddaed99e 100644 --- a/Code/OysterGraphics/Shader/Passes/Light/LightPass.hlsl +++ b/Code/OysterGraphics/Shader/Passes/Light/LightPass.hlsl @@ -8,13 +8,85 @@ //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 -[numthreads(16, 16, 1)] -void main( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID ) + +// -- Shared Memory ------------------------------------------------- // + +groupshared uint iMinDepth = UINT_MAX, + iMaxDepth = 0; +groupshared uint numVisiblePointLights = 0, + visiblePointlightIndex[MAXLIGHTS]; + +// ------------------------------------------------------------------ // + +[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; UV.x = UV.x * 2 - 1; UV.y = 1 - 2 * UV.y; + + float3 posN = float3(UV, DepthTexture[DTid.xy].x); + + // store and load shared minDepth and maxDepth + float minDepth = 0.0f, maxDepth = 0.0f, + depth = posN.z; + { + uint uidepth = (uint)( depth * EXPAND); + InterlockedMin( iMinDepth, uidepth ); + InterlockedMax( iMaxDepth, uidepth ); + + GroupMemoryBarrierWithGroupSync(); + minDepth = (float)( iMinDepth ) * SHRINK; + maxDepth = (float)( iMaxDepth ) * SHRINK; + } + + + // -- 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); + + + + // 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 ) + { + 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; + } + } + + GroupMemoryBarrierWithGroupSync(); + + + float3 ViewPos = ToVpos(DTid.xy, UV); DiffSpec Shaded; Shaded.Diffuse = float3(0,0,0); @@ -47,7 +119,7 @@ void main( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID ) 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 /* * (2-DepthBase) */,DiffBase.w); + 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); }