فهرست منبع

Optimized away unnecessary structures from View.

Lasse Öörni 13 سال پیش
والد
کامیت
987a168d9e
5فایلهای تغییر یافته به همراه72 افزوده شده و 70 حذف شده
  1. 8 0
      Engine/Graphics/Drawable.cpp
  2. 10 0
      Engine/Graphics/Drawable.h
  3. 6 6
      Engine/Graphics/Renderer.cpp
  4. 22 27
      Engine/Graphics/View.cpp
  5. 26 37
      Engine/Graphics/View.h

+ 8 - 0
Engine/Graphics/Drawable.cpp

@@ -57,6 +57,8 @@ Drawable::Drawable(Context* context) :
     drawDistance_(0.0f),
     drawDistance_(0.0f),
     shadowDistance_(0.0f),
     shadowDistance_(0.0f),
     sortValue_(0.0f),
     sortValue_(0.0f),
+    minZ_(0.0f),
+    maxZ_(0.0f),
     lodBias_(1.0f),
     lodBias_(1.0f),
     basePassFlags_(0),
     basePassFlags_(0),
     maxLights_(0),
     maxLights_(0),
@@ -222,6 +224,12 @@ void Drawable::SetSortValue(float value)
     sortValue_ = value;
     sortValue_ = value;
 }
 }
 
 
+void Drawable::SetMinMaxZ(float minZ, float maxZ)
+{
+    minZ_ = minZ;
+    maxZ_ = maxZ;
+}
+
 void Drawable::MarkInView(const FrameInfo& frame, bool mainView)
 void Drawable::MarkInView(const FrameInfo& frame, bool mainView)
 {
 {
     if (mainView)
     if (mainView)

+ 10 - 0
Engine/Graphics/Drawable.h

@@ -171,6 +171,8 @@ public:
     void SetZone(Zone* zone, bool temporary = false);
     void SetZone(Zone* zone, bool temporary = false);
     /// %Set sorting value.
     /// %Set sorting value.
     void SetSortValue(float value);
     void SetSortValue(float value);
+    /// %Set view-space depth bounds.
+    void SetMinMaxZ(float minZ, float maxZ);
     /// Mark in view (either the main camera, or a shadow camera view) this frame.
     /// Mark in view (either the main camera, or a shadow camera view) this frame.
     void MarkInView(const FrameInfo& frame, bool mainView = true);
     void MarkInView(const FrameInfo& frame, bool mainView = true);
     /// Clear lights and base pass flags for a new frame.
     /// Clear lights and base pass flags for a new frame.
@@ -209,6 +211,10 @@ public:
     const PODVector<Light*>& GetVertexLights() const { return vertexLights_; }
     const PODVector<Light*>& GetVertexLights() const { return vertexLights_; }
     /// Return the first added per-pixel light.
     /// Return the first added per-pixel light.
     Light* GetFirstLight() const { return firstLight_; }
     Light* GetFirstLight() const { return firstLight_; }
+    /// Return the minimum view-space depth.
+    float GetMinZ() const { return minZ_; }
+    /// Return the maximum view-space depth.
+    float GetMaxZ() const { return maxZ_; }
     
     
 protected:
 protected:
     /// Handle node being assigned.
     /// Handle node being assigned.
@@ -262,6 +268,10 @@ protected:
     float shadowDistance_;
     float shadowDistance_;
     /// Current sort value.
     /// Current sort value.
     float sortValue_;
     float sortValue_;
+    /// Current minimum view space depth.
+    float minZ_;
+    /// Current maximum view space depth.
+    float maxZ_;
     /// LOD bias.
     /// LOD bias.
     float lodBias_;
     float lodBias_;
     /// Base pass flags.
     /// Base pass flags.

+ 6 - 6
Engine/Graphics/Renderer.cpp

@@ -761,8 +761,8 @@ Texture2D* Renderer::GetShadowMap(Light* light, Camera* camera, unsigned viewWid
     // Automatically reduce shadow map size when far away
     // Automatically reduce shadow map size when far away
     if (parameters.autoSize_ && type != LIGHT_DIRECTIONAL)
     if (parameters.autoSize_ && type != LIGHT_DIRECTIONAL)
     {
     {
-        Matrix3x4 view(camera->GetInverseWorldTransform());
-        Matrix4 projection(camera->GetProjection());
+        const Matrix3x4& view = camera->GetInverseWorldTransform();
+        const Matrix4& projection = camera->GetProjection();
         BoundingBox lightBox;
         BoundingBox lightBox;
         float lightPixels;
         float lightPixels;
         
         
@@ -1249,8 +1249,8 @@ void Renderer::OptimizeLightByStencil(Light* light, Camera* camera)
         }
         }
         
         
         Geometry* geometry = GetLightGeometry(light);
         Geometry* geometry = GetLightGeometry(light);
-        Matrix3x4 view(camera->GetInverseWorldTransform());
-        Matrix4 projection(camera->GetProjection());
+        const Matrix3x4& view = camera->GetInverseWorldTransform();
+        const Matrix4& projection = camera->GetProjection();
         float lightDist;
         float lightDist;
         
         
         if (type == LIGHT_POINT)
         if (type == LIGHT_POINT)
@@ -1313,8 +1313,8 @@ const Rect& Renderer::GetLightScissor(Light* light, Camera* camera)
     if (i != lightScissorCache_.End())
     if (i != lightScissorCache_.End())
         return i->second_;
         return i->second_;
     
     
-    Matrix3x4 view(camera->GetInverseWorldTransform());
-    Matrix4 projection(camera->GetProjection());
+    const Matrix3x4& view = camera->GetInverseWorldTransform();
+    const Matrix4& projection = camera->GetProjection();
     
     
     switch (light->GetLightType())
     switch (light->GetLightType())
     {
     {

+ 22 - 27
Engine/Graphics/View.cpp

@@ -396,7 +396,6 @@ void View::Update(const FrameInfo& frame)
     screenBuffers_.Clear();
     screenBuffers_.Clear();
     geometries_.Clear();
     geometries_.Clear();
     allGeometries_.Clear();
     allGeometries_.Clear();
-    geometryDepthBounds_.Clear();
     lights_.Clear();
     lights_.Clear();
     zones_.Clear();
     zones_.Clear();
     occluders_.Clear();
     occluders_.Clear();
@@ -622,9 +621,9 @@ void View::GetDrawables()
     // Sort into geometries & lights, and build visible scene bounding boxes in world and view space
     // Sort into geometries & lights, and build visible scene bounding boxes in world and view space
     sceneBox_.min_ = sceneBox_.max_ = Vector3::ZERO;
     sceneBox_.min_ = sceneBox_.max_ = Vector3::ZERO;
     sceneBox_.defined_ = false;
     sceneBox_.defined_ = false;
-    sceneViewBox_.min_ = sceneViewBox_.max_ = Vector3::ZERO;
-    sceneViewBox_.defined_ = false;
-    Matrix3x4 view(camera_->GetInverseWorldTransform());
+    minZ_ = M_INFINITY;
+    maxZ_ = 0.0f;
+    const Matrix3x4& view = camera_->GetInverseWorldTransform();
     
     
     for (unsigned i = 0; i < tempDrawables.Size(); ++i)
     for (unsigned i = 0; i < tempDrawables.Size(); ++i)
     {
     {
@@ -642,15 +641,13 @@ void View::GetDrawables()
             if (drawable->GetType() != Skybox::GetTypeStatic())
             if (drawable->GetType() != Skybox::GetTypeStatic())
             {
             {
                 sceneBox_.Merge(geomBox);
                 sceneBox_.Merge(geomBox);
-                sceneViewBox_.Merge(geomViewBox);
+                minZ_ = Min(minZ_, geomViewBox.min_.z_);
+                maxZ_ = Max(maxZ_, geomViewBox.max_.z_);
             }
             }
             
             
             // Store depth info for split directional light queries
             // Store depth info for split directional light queries
-            GeometryDepthBounds bounds;
-            bounds.min_ = geomViewBox.min_.z_;
-            bounds.max_ = geomViewBox.max_.z_;
+            drawable->SetMinMaxZ(geomViewBox.min_.z_, geomViewBox.max_.z_);
             
             
-            geometryDepthBounds_.Push(bounds);
             geometries_.Push(drawable);
             geometries_.Push(drawable);
             allGeometries_.Push(drawable);
             allGeometries_.Push(drawable);
         }
         }
@@ -663,8 +660,6 @@ void View::GetDrawables()
         }
         }
     }
     }
     
     
-    sceneFrustum_ = camera_->GetSplitFrustum(sceneViewBox_.min_.z_, sceneViewBox_.max_.z_);
-    
     // Sort the lights to brightest/closest first
     // Sort the lights to brightest/closest first
     for (unsigned i = 0; i < lights_.Size(); ++i)
     for (unsigned i = 0; i < lights_.Size(); ++i)
     {
     {
@@ -1796,9 +1791,9 @@ void View::ProcessLight(LightQueryResult& query, unsigned threadIndex)
         // For directional light check that the split is inside the visible scene: if not, can skip the split
         // For directional light check that the split is inside the visible scene: if not, can skip the split
         if (type == LIGHT_DIRECTIONAL)
         if (type == LIGHT_DIRECTIONAL)
         {
         {
-            if (sceneViewBox_.min_.z_ > query.shadowFarSplits_[i])
+            if (minZ_ > query.shadowFarSplits_[i])
                 continue;
                 continue;
-            if (sceneViewBox_.max_.z_ < query.shadowNearSplits_[i])
+            if (maxZ_ < query.shadowNearSplits_[i])
                 continue;
                 continue;
         }
         }
         
         
@@ -1823,13 +1818,11 @@ void View::ProcessLight(LightQueryResult& query, unsigned threadIndex)
 void View::ProcessShadowCasters(LightQueryResult& query, const PODVector<Drawable*>& drawables, unsigned splitIndex)
 void View::ProcessShadowCasters(LightQueryResult& query, const PODVector<Drawable*>& drawables, unsigned splitIndex)
 {
 {
     Light* light = query.light_;
     Light* light = query.light_;
-    Matrix3x4 lightView;
-    Matrix4 lightProj;
     
     
     Camera* shadowCamera = query.shadowCameras_[splitIndex];
     Camera* shadowCamera = query.shadowCameras_[splitIndex];
     const Frustum& shadowCameraFrustum = shadowCamera->GetFrustum();
     const Frustum& shadowCameraFrustum = shadowCamera->GetFrustum();
-    lightView = shadowCamera->GetInverseWorldTransform();
-    lightProj = shadowCamera->GetProjection();
+    const Matrix3x4& lightView = shadowCamera->GetInverseWorldTransform();
+    const Matrix4& lightProj = shadowCamera->GetProjection();
     LightType type = light->GetLightType();
     LightType type = light->GetLightType();
     
     
     query.shadowCasterBox_[splitIndex].defined_ = false;
     query.shadowCasterBox_[splitIndex].defined_ = false;
@@ -1839,10 +1832,10 @@ void View::ProcessShadowCasters(LightQueryResult& query, const PODVector<Drawabl
     // frustum, so that shadow casters do not get rendered into unnecessary splits
     // frustum, so that shadow casters do not get rendered into unnecessary splits
     Frustum lightViewFrustum;
     Frustum lightViewFrustum;
     if (type != LIGHT_DIRECTIONAL)
     if (type != LIGHT_DIRECTIONAL)
-        lightViewFrustum = sceneFrustum_.Transformed(lightView);
+        lightViewFrustum = camera_->GetSplitFrustum(minZ_, maxZ_).Transformed(lightView);
     else
     else
-        lightViewFrustum = camera_->GetSplitFrustum(Max(sceneViewBox_.min_.z_, query.shadowNearSplits_[splitIndex]),
-            Min(sceneViewBox_.max_.z_, query.shadowFarSplits_[splitIndex])).Transformed(lightView);
+        lightViewFrustum = camera_->GetSplitFrustum(Max(minZ_, query.shadowNearSplits_[splitIndex]),
+            Min(maxZ_, query.shadowFarSplits_[splitIndex])).Transformed(lightView);
     
     
     BoundingBox lightViewFrustumBox(lightViewFrustum);
     BoundingBox lightViewFrustumBox(lightViewFrustum);
      
      
@@ -2057,8 +2050,8 @@ void View::SetupDirLightShadowCamera(Camera* shadowCamera, Light* light, float n
     // Use the scene Z bounds to limit frustum size if applicable
     // Use the scene Z bounds to limit frustum size if applicable
     if (parameters.focus_)
     if (parameters.focus_)
     {
     {
-        nearSplit = Max(sceneViewBox_.min_.z_, nearSplit);
-        farSplit = Min(sceneViewBox_.max_.z_, farSplit);
+        nearSplit = Max(minZ_, nearSplit);
+        farSplit = Min(maxZ_, farSplit);
     }
     }
     
     
     Frustum splitFrustum = camera_->GetSplitFrustum(nearSplit, farSplit);
     Frustum splitFrustum = camera_->GetSplitFrustum(nearSplit, farSplit);
@@ -2070,13 +2063,15 @@ void View::SetupDirLightShadowCamera(Camera* shadowCamera, Light* light, float n
         BoundingBox litGeometriesBox;
         BoundingBox litGeometriesBox;
         for (unsigned i = 0; i < geometries_.Size(); ++i)
         for (unsigned i = 0; i < geometries_.Size(); ++i)
         {
         {
+            Drawable* drawable = geometries_[i];
+            
             // Skip skyboxes as they have undefinedly large bounding box size
             // Skip skyboxes as they have undefinedly large bounding box size
-            if (geometries_[i]->GetType() == Skybox::GetTypeStatic())
+            if (drawable->GetType() == Skybox::GetTypeStatic())
                 continue;
                 continue;
             
             
-            if (geometryDepthBounds_[i].min_ <= farSplit && geometryDepthBounds_[i].max_ >= nearSplit &&
-                (GetLightMask(geometries_[i]) & light->GetLightMask()))
-                litGeometriesBox.Merge(geometries_[i]->GetWorldBoundingBox());
+            if (drawable->GetMinZ() <= farSplit && drawable->GetMaxZ() >= nearSplit &&
+                (GetLightMask(drawable) & light->GetLightMask()))
+                litGeometriesBox.Merge(drawable->GetWorldBoundingBox());
         }
         }
         if (litGeometriesBox.defined_)
         if (litGeometriesBox.defined_)
         {
         {
@@ -2088,7 +2083,7 @@ void View::SetupDirLightShadowCamera(Camera* shadowCamera, Light* light, float n
     }
     }
     
     
     // Transform frustum volume to light space
     // Transform frustum volume to light space
-    Matrix3x4 lightView(shadowCamera->GetInverseWorldTransform());
+    const Matrix3x4& lightView = shadowCamera->GetInverseWorldTransform();
     frustumVolume.Transform(lightView);
     frustumVolume.Transform(lightView);
     
     
     // Fit the frustum volume inside a bounding box. If uniform size, use a sphere instead
     // Fit the frustum volume inside a bounding box. If uniform size, use a sphere instead

+ 26 - 37
Engine/Graphics/View.h

@@ -42,15 +42,6 @@ class Viewport;
 class Zone;
 class Zone;
 struct WorkItem;
 struct WorkItem;
 
 
-/// %Geometry view space depth minimum and maximum values.
-struct GeometryDepthBounds
-{
-    /// Minimum value.
-    float min_;
-    /// Maximum value.
-    float max_;
-};
-
 /// Intermediate light processing result.
 /// Intermediate light processing result.
 struct LightQueryResult
 struct LightQueryResult
 {
 {
@@ -210,12 +201,26 @@ private:
     IntVector2 rtSize_;
     IntVector2 rtSize_;
     /// Information of the frame being rendered.
     /// Information of the frame being rendered.
     FrameInfo frame_;
     FrameInfo frame_;
-    /// Scene-bounded camera frustum.
-    Frustum sceneFrustum_;
     /// Combined bounding box of visible geometries.
     /// Combined bounding box of visible geometries.
     BoundingBox sceneBox_;
     BoundingBox sceneBox_;
-    /// Combined bounding box of visible geometries in view space.
-    BoundingBox sceneViewBox_;
+    /// Minimum Z value of the visible scene.
+    float minZ_;
+    /// Maximum Z value of the visible scene.
+    float maxZ_;
+    /// Rendering mode.
+    RenderMode renderMode_;
+    /// Material quality level.
+    int materialQuality_;
+    /// Maximum number of occluder triangles.
+    int maxOccluderTriangles_;
+    /// Highest zone priority currently visible.
+    int highestZonePriority_;
+    /// Camera zone's override flag.
+    bool cameraZoneOverride_;
+    /// Draw shadows flag.
+    bool drawShadows_;
+    /// Whether objects with zero lightmask exist. In light pre-pass mode this means skipping some optimizations.
+    bool hasZeroLightMask_;
     /// Post-processing effects.
     /// Post-processing effects.
     Vector<SharedPtr<PostProcess> > postProcesses_;
     Vector<SharedPtr<PostProcess> > postProcesses_;
     /// Intermediate screen buffers used in postprocessing and OpenGL deferred framebuffer blit.
     /// Intermediate screen buffers used in postprocessing and OpenGL deferred framebuffer blit.
@@ -234,40 +239,24 @@ private:
     PODVector<Drawable*> threadedGeometries_;
     PODVector<Drawable*> threadedGeometries_;
     /// Occluder objects.
     /// Occluder objects.
     PODVector<Drawable*> occluders_;
     PODVector<Drawable*> occluders_;
-    /// Depth minimum and maximum values for visible geometries.
-    PODVector<GeometryDepthBounds> geometryDepthBounds_;
     /// Lights.
     /// Lights.
     PODVector<Light*> lights_;
     PODVector<Light*> lights_;
     /// Drawables that limit their maximum light count.
     /// Drawables that limit their maximum light count.
     HashSet<Drawable*> maxLightsDrawables_;
     HashSet<Drawable*> maxLightsDrawables_;
+    /// Intermediate light processing results.
+    Vector<LightQueryResult> lightQueryResults_;
+    /// Per-pixel light queues.
+    Vector<LightBatchQueue> lightQueues_;
+    /// Per-vertex light queues.
+    HashMap<unsigned long long, LightBatchQueue> vertexLightQueues_;
     /// Base pass batches.
     /// Base pass batches.
     BatchQueue baseQueue_;
     BatchQueue baseQueue_;
-    /// Pre-transparent pass batches.
-    BatchQueue preAlphaQueue_;
     /// Deferred rendering G-buffer batches.
     /// Deferred rendering G-buffer batches.
     BatchQueue gbufferQueue_;
     BatchQueue gbufferQueue_;
+    /// Pre-transparent pass batches.
+    BatchQueue preAlphaQueue_;
     /// Transparent geometry batches.
     /// Transparent geometry batches.
     BatchQueue alphaQueue_;
     BatchQueue alphaQueue_;
     /// Post-transparent pass batches.
     /// Post-transparent pass batches.
     BatchQueue postAlphaQueue_;
     BatchQueue postAlphaQueue_;
-    /// Intermediate light processing results.
-    Vector<LightQueryResult> lightQueryResults_;
-    /// Per-pixel light queues.
-    Vector<LightBatchQueue> lightQueues_;
-    /// Per-vertex light queues.
-    HashMap<unsigned long long, LightBatchQueue> vertexLightQueues_;
-    /// Material quality level.
-    int materialQuality_;
-    /// Maximum number of occluder triangles.
-    int maxOccluderTriangles_;
-    /// Highest zone priority currently visible.
-    int highestZonePriority_;
-    /// Rendering mode.
-    RenderMode renderMode_;
-    /// Camera zone's override flag.
-    bool cameraZoneOverride_;
-    /// Draw shadows flag.
-    bool drawShadows_;
-    /// Whether objects with zero lightmask exist. In light pre-pass mode this means skipping some optimizations.
-    bool hasZeroLightMask_;
 };
 };