From 7ebdce5e42aaf3512c69a9f8313060ba541940a4 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 29 Jun 2022 23:28:03 +0200 Subject: [PATCH] More work for large worlds --- .../Editor/MaterialTemplates/Surface.shader | 4 +-- Content/Engine/DefaultMaterial.flax | 4 +-- Source/Engine/Core/Math/BoundingBox.cpp | 9 +++++++ Source/Engine/Core/Math/BoundingBox.h | 8 ++++++ Source/Engine/Level/Actors/Decal.cpp | 23 ++++++----------- Source/Engine/Level/Actors/Decal.h | 10 -------- .../Renderer/Editor/MaterialComplexity.cpp | 4 ++- .../Renderer/Editor/QuadOverdrawPass.cpp | 4 ++- Source/Engine/Renderer/GBufferPass.cpp | 22 ++++++++-------- Source/Engine/UI/TextRender.cpp | 25 +++++++++---------- Source/Engine/UI/TextRender.h | 1 - 11 files changed, 58 insertions(+), 56 deletions(-) diff --git a/Content/Editor/MaterialTemplates/Surface.shader b/Content/Editor/MaterialTemplates/Surface.shader index ebf020597..ff88f1b40 100644 --- a/Content/Editor/MaterialTemplates/Surface.shader +++ b/Content/Editor/MaterialTemplates/Surface.shader @@ -617,14 +617,14 @@ void PS_Depth(PixelInput input) #if _PS_QuadOverdraw -//#include "./Flax/Editor/QuadOverdraw.hlsl" +#include "./Flax/Editor/QuadOverdraw.hlsl" // Pixel Shader function for Quad Overdraw Pass (editor-only) [earlydepthstencil] META_PS(USE_EDITOR, FEATURE_LEVEL_SM5) void PS_QuadOverdraw(float4 svPos : SV_Position, uint primId : SV_PrimitiveID) { - //DoQuadOverdraw(svPos, primId); + DoQuadOverdraw(svPos, primId); } #endif diff --git a/Content/Engine/DefaultMaterial.flax b/Content/Engine/DefaultMaterial.flax index 3c2476654..07b24bb9a 100644 --- a/Content/Engine/DefaultMaterial.flax +++ b/Content/Engine/DefaultMaterial.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:476755a18369bc6a56792f56f3dfcf1b7c9c1e4b999881af86423ad778875b74 -size 32155 +oid sha256:abc637eb5d9f7ee6c3ab6c1fd06e45307f8b41013082cc4d3c434c585d14d057 +size 31667 diff --git a/Source/Engine/Core/Math/BoundingBox.cpp b/Source/Engine/Core/Math/BoundingBox.cpp index 0082b62f8..7c35fbe80 100644 --- a/Source/Engine/Core/Math/BoundingBox.cpp +++ b/Source/Engine/Core/Math/BoundingBox.cpp @@ -3,6 +3,7 @@ #include "BoundingBox.h" #include "BoundingSphere.h" #include "Matrix.h" +#include "Transform.h" #include "../Types/String.h" const BoundingBox BoundingBox::Empty(Vector3(MAX_float), Vector3(MIN_float)); @@ -147,3 +148,11 @@ void BoundingBox::Transform(const BoundingBox& box, const Matrix& matrix, Boundi result = FromPoints(corners, 8); */ } + +void BoundingBox::Transform(const BoundingBox& box, const ::Transform& transform, BoundingBox& result) +{ + // TODO: optimize it and support large worlds without using Matrix + Matrix matrix; + transform.GetWorld(matrix); + Transform(box, matrix, result); +} diff --git a/Source/Engine/Core/Math/BoundingBox.h b/Source/Engine/Core/Math/BoundingBox.h index f4d7ef158..e0785edfb 100644 --- a/Source/Engine/Core/Math/BoundingBox.h +++ b/Source/Engine/Core/Math/BoundingBox.h @@ -296,6 +296,14 @@ public: /// The result transformed box. static void Transform(const BoundingBox& box, const Matrix& matrix, BoundingBox& result); + /// + /// Transforms the bounding box using the specified transformation. + /// + /// The box. + /// The transformation. + /// The result transformed box. + static void Transform(const BoundingBox& box, const ::Transform& transform, BoundingBox& result); + public: /// /// Determines if there is an intersection between the current object and a Ray. diff --git a/Source/Engine/Level/Actors/Decal.cpp b/Source/Engine/Level/Actors/Decal.cpp index fb78110a1..998e2bfad 100644 --- a/Source/Engine/Level/Actors/Decal.cpp +++ b/Source/Engine/Level/Actors/Decal.cpp @@ -13,9 +13,8 @@ Decal::Decal(const SpawnParams& params) : Actor(params) , _size(100.0f) { - _world = Matrix::Scaling(_size); - _bounds.Extents = Vector3::Half; - _world.Decompose(_bounds.Transformation); + _bounds.Extents = _size * 0.5f; + _bounds.Transformation = _transform; _bounds.GetBoundingBox(_box); BoundingSphere::FromBox(_box, _sphere); } @@ -26,12 +25,7 @@ void Decal::SetSize(const Vector3& value) if (v != _size) { _size = v; - - Transform t = _transform; - t.Scale *= _size; - t.GetWorld(_world); - - _bounds.Transformation = t; + _bounds.Extents = v * 0.5f; _bounds.GetBoundingBox(_box); BoundingSphere::FromBox(_box, _sphere); } @@ -81,7 +75,7 @@ void Decal::Draw(RenderContext& renderContext) Material->IsDecal()) { const auto lodView = (renderContext.LodProxyView ? renderContext.LodProxyView : &renderContext.View); - const float screenRadiusSquared = RenderTools::ComputeBoundsScreenRadiusSquared(_sphere.Center, (float)_sphere.Radius, *lodView) * renderContext.View.ModelLODDistanceFactorSqrt; + const float screenRadiusSquared = RenderTools::ComputeBoundsScreenRadiusSquared(_sphere.Center - renderContext.View.Origin, (float)_sphere.Radius, *lodView) * renderContext.View.ModelLODDistanceFactorSqrt; // Check if decal is being culled if (Math::Square(DrawMinScreenSize * 0.5f) > screenRadiusSquared) @@ -113,6 +107,8 @@ void Decal::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) DESERIALIZE_MEMBER(Size, _size); DESERIALIZE(SortOrder); DESERIALIZE(DrawMinScreenSize); + + _bounds.Extents = _size * 0.5f; } bool Decal::IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) @@ -147,12 +143,7 @@ void Decal::OnTransformChanged() // Base Actor::OnTransformChanged(); - Transform t = _transform; - t.Scale *= _size; - t.GetWorld(_world); - - _bounds.Extents = Vector3::Half; - _bounds.Transformation = t; + _bounds.Transformation = _transform; _bounds.GetBoundingBox(_box); BoundingSphere::FromBox(_box, _sphere); diff --git a/Source/Engine/Level/Actors/Decal.h b/Source/Engine/Level/Actors/Decal.h index d6e608f6e..8cc6c2df7 100644 --- a/Source/Engine/Level/Actors/Decal.h +++ b/Source/Engine/Level/Actors/Decal.h @@ -17,7 +17,6 @@ API_CLASS() class FLAXENGINE_API Decal : public Actor private: Vector3 _size; OrientedBoundingBox _bounds; - Matrix _world; int32 _sceneRenderingKey = -1; public: @@ -61,15 +60,6 @@ public: /// The created virtual material instance. API_FUNCTION() MaterialInstance* CreateAndSetVirtualMaterialInstance(); - /// - /// Gets the decal world matrix used to transform the 1x1x1 cube from the mesh space to world space. - /// - /// The result value container. - FORCE_INLINE void GetWorld(Matrix* result) const - { - *result = _world; - } - public: // [Actor] #if USE_EDITOR diff --git a/Source/Engine/Renderer/Editor/MaterialComplexity.cpp b/Source/Engine/Renderer/Editor/MaterialComplexity.cpp index e8e1feb97..4db975cf8 100644 --- a/Source/Engine/Renderer/Editor/MaterialComplexity.cpp +++ b/Source/Engine/Renderer/Editor/MaterialComplexity.cpp @@ -145,7 +145,9 @@ void MaterialComplexityMaterialShader::Draw(RenderContext& renderContext, GPUCon { const auto decal = decals[i]; ASSERT(decal && decal->Material); - decal->GetWorld(&drawCall.World); + Transform transform = decal->GetTransform(); + transform.Scale *= decal->GetSize(); + renderContext.View.GetWorldMatrix(transform, drawCall.World); drawCall.ObjectPosition = drawCall.World.GetTranslation(); drawCall.Material = decal->Material; drawCall.PerInstanceRandom = decal->GetPerInstanceRandom(); diff --git a/Source/Engine/Renderer/Editor/QuadOverdrawPass.cpp b/Source/Engine/Renderer/Editor/QuadOverdrawPass.cpp index 63f6bfb4e..e0ed4ae31 100644 --- a/Source/Engine/Renderer/Editor/QuadOverdrawPass.cpp +++ b/Source/Engine/Renderer/Editor/QuadOverdrawPass.cpp @@ -60,7 +60,9 @@ void QuadOverdrawPass::Render(RenderContext& renderContext, GPUContext* context, { const auto decal = renderContext.List->Decals[i]; ASSERT(decal && decal->Material); - decal->GetWorld(&drawCall.World); + Transform transform = decal->GetTransform(); + transform.Scale *= decal->GetSize(); + renderContext.View.GetWorldMatrix(transform, drawCall.World); drawCall.ObjectPosition = drawCall.World.GetTranslation(); drawCall.PerInstanceRandom = decal->GetPerInstanceRandom(); defaultMaterial->Bind(bindParams); diff --git a/Source/Engine/Renderer/GBufferPass.cpp b/Source/Engine/Renderer/GBufferPass.cpp index c424eb951..7603a3c0f 100644 --- a/Source/Engine/Renderer/GBufferPass.cpp +++ b/Source/Engine/Renderer/GBufferPass.cpp @@ -401,7 +401,7 @@ void GBufferPass::DrawDecals(RenderContext& renderContext, GPUTextureView* light // Cache data auto device = GPUDevice::Instance; - auto gpuContext = device->GetMainContext(); + auto context = device->GetMainContext(); auto& view = renderContext.View; auto model = _boxModel.Get(); auto buffers = renderContext.Buffers; @@ -415,7 +415,7 @@ void GBufferPass::DrawDecals(RenderContext& renderContext, GPUTextureView* light // Prepare DrawCall drawCall; - MaterialBase::BindParameters bindParams(gpuContext, renderContext, drawCall); + MaterialBase::BindParameters bindParams(context, renderContext, drawCall); drawCall.Material = nullptr; drawCall.WorldDeterminantSign = 1.0f; @@ -424,10 +424,12 @@ void GBufferPass::DrawDecals(RenderContext& renderContext, GPUTextureView* light { const auto decal = decals[i]; ASSERT(decal && decal->Material); - decal->GetWorld(&drawCall.World); + Transform transform = decal->GetTransform(); + transform.Scale *= decal->GetSize(); + renderContext.View.GetWorldMatrix(transform, drawCall.World); drawCall.ObjectPosition = drawCall.World.GetTranslation(); - gpuContext->ResetRenderTarget(); + context->ResetRenderTarget(); // Bind output const MaterialInfo& info = decal->Material->GetInfo(); @@ -455,22 +457,22 @@ void GBufferPass::DrawDecals(RenderContext& renderContext, GPUTextureView* light count++; targetBuffers[2] = buffers->GBuffer1->View(); } - gpuContext->SetRenderTarget(nullptr, ToSpan(targetBuffers, count)); + context->SetRenderTarget(nullptr, ToSpan(targetBuffers, count)); break; } case MaterialDecalBlendingMode::Stain: { - gpuContext->SetRenderTarget(buffers->GBuffer0->View()); + context->SetRenderTarget(buffers->GBuffer0->View()); break; } case MaterialDecalBlendingMode::Normal: { - gpuContext->SetRenderTarget(buffers->GBuffer1->View()); + context->SetRenderTarget(buffers->GBuffer1->View()); break; } case MaterialDecalBlendingMode::Emissive: { - gpuContext->SetRenderTarget(lightBuffer); + context->SetRenderTarget(lightBuffer); break; } } @@ -478,8 +480,8 @@ void GBufferPass::DrawDecals(RenderContext& renderContext, GPUTextureView* light // Draw decal drawCall.PerInstanceRandom = decal->GetPerInstanceRandom(); decal->Material->Bind(bindParams); - model->Render(gpuContext); + model->Render(context); } - gpuContext->ResetSR(); + context->ResetSR(); } diff --git a/Source/Engine/UI/TextRender.cpp b/Source/Engine/UI/TextRender.cpp index 753c4231b..02ccb3f07 100644 --- a/Source/Engine/UI/TextRender.cpp +++ b/Source/Engine/UI/TextRender.cpp @@ -30,7 +30,6 @@ TextRender::TextRender(const SpawnParams& params) , _vb1(0, sizeof(VB1ElementType)) , _vb2(0, sizeof(VB2ElementType)) { - _world = Matrix::Identity; _color = Color::White; _localBox = BoundingBox(Vector3::Zero); _layoutOptions.Bounds = Rectangle(-100, -100, 200, 200); @@ -106,7 +105,7 @@ void TextRender::UpdateLayout() _vb1.Clear(); _vb2.Clear(); _localBox = BoundingBox(Vector3::Zero); - BoundingBox::Transform(_localBox, _world, _box); + BoundingBox::Transform(_localBox, _transform, _box); BoundingSphere::FromBox(_box, _sphere); #if USE_PRECISE_MESH_INTERSECTS _collisionProxy.Clear(); @@ -327,7 +326,7 @@ void TextRender::UpdateLayout() box = BoundingBox(_transform.Translation); } _localBox = box; - BoundingBox::Transform(_localBox, _world, _box); + BoundingBox::Transform(_localBox, _transform, _box); BoundingSphere::FromBox(_box, _sphere); if (_sceneRenderingKey != -1) GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); @@ -348,8 +347,9 @@ void TextRender::Draw(RenderContext& renderContext) { UpdateLayout(); } - - GEOMETRY_DRAW_STATE_EVENT_BEGIN(_drawState, _world); + Matrix world; + renderContext.View.GetWorldMatrix(_transform, world); + GEOMETRY_DRAW_STATE_EVENT_BEGIN(_drawState, world); const DrawPass drawModes = (DrawPass)(DrawModes & renderContext.View.Pass & (int32)renderContext.View.GetShadowsDrawPassMask(ShadowsMode)); if (_vb0.Data.Count() > 0 && drawModes != DrawPass::None) @@ -357,7 +357,7 @@ void TextRender::Draw(RenderContext& renderContext) #if USE_EDITOR // Disable motion blur effects in editor without play mode enabled to hide minor artifacts on objects moving if (!Editor::IsPlayMode) - _drawState.PrevWorld = _world; + _drawState.PrevWorld = world; #endif // Flush buffers @@ -372,7 +372,7 @@ void TextRender::Draw(RenderContext& renderContext) // Setup draw call DrawCall drawCall; - drawCall.World = _world; + drawCall.World = world; drawCall.ObjectPosition = drawCall.World.GetTranslation(); drawCall.Surface.GeometrySize = _localBox.GetSize(); drawCall.Surface.PrevWorld = _drawState.PrevWorld; @@ -380,7 +380,7 @@ void TextRender::Draw(RenderContext& renderContext) drawCall.Surface.LightmapUVsArea = Rectangle::Empty; drawCall.Surface.Skinning = nullptr; drawCall.Surface.LODDitherFactor = 0.0f; - drawCall.WorldDeterminantSign = Math::FloatSelect(_world.RotDeterminant(), 1, -1); + drawCall.WorldDeterminantSign = Math::FloatSelect(world.RotDeterminant(), 1, -1); drawCall.PerInstanceRandom = GetPerInstanceRandom(); drawCall.Geometry.IndexBuffer = _ib.GetBuffer(); drawCall.Geometry.VertexBuffers[0] = _vb0.GetBuffer(); @@ -401,7 +401,7 @@ void TextRender::Draw(RenderContext& renderContext) } } - GEOMETRY_DRAW_STATE_EVENT_END(_drawState, _world); + GEOMETRY_DRAW_STATE_EVENT_END(_drawState, world); } #if USE_EDITOR @@ -413,7 +413,7 @@ void TextRender::OnDebugDrawSelected() // Draw text bounds and layout bounds DEBUG_DRAW_WIRE_BOX(_box, Color::Orange, 0, true); OrientedBoundingBox layoutBox(Vector3(-_layoutOptions.Bounds.GetUpperLeft(), 0), Vector3(-_layoutOptions.Bounds.GetBottomRight(), 0)); - layoutBox.Transform(_world); + layoutBox.Transform(_transform); DEBUG_DRAW_WIRE_BOX(layoutBox, Color::BlueViolet, 0, true); // Base @@ -433,7 +433,7 @@ bool TextRender::IntersectsItself(const Ray& ray, Real& distance, Vector3& norma #if USE_PRECISE_MESH_INTERSECTS if (_box.Intersects(ray)) { - return _collisionProxy.Intersects(ray, _world, distance, normal); + return _collisionProxy.Intersects(ray, _transform, distance, normal); } return false; #else @@ -522,8 +522,7 @@ void TextRender::OnTransformChanged() // Base Actor::OnTransformChanged(); - _transform.GetWorld(_world); - BoundingBox::Transform(_localBox, _world, _box); + BoundingBox::Transform(_localBox, _transform, _box); BoundingSphere::FromBox(_box, _sphere); if (_sceneRenderingKey != -1) GetSceneRendering()->UpdateActor(this, _sceneRenderingKey); diff --git a/Source/Engine/UI/TextRender.h b/Source/Engine/UI/TextRender.h index cf4030903..9c2626590 100644 --- a/Source/Engine/UI/TextRender.h +++ b/Source/Engine/UI/TextRender.h @@ -42,7 +42,6 @@ private: int32 _sceneRenderingKey = -1; BoundingBox _localBox; - Matrix _world; GeometryDrawStateData _drawState; DynamicIndexBuffer _ib; DynamicVertexBuffer _vb0;