ソースを参照

Offset occlusion geometry downward to reduce possibility of erroneous occlusion.

Lasse Öörni 13 年 前
コミット
96143733e4

+ 4 - 1
Engine/Graphics/Terrain.cpp

@@ -475,7 +475,6 @@ void Terrain::CreatePatchGeometry(TerrainPatch* patch)
     {
         unsigned lastDrawRange = drawRanges_.Size() - 1;
         
-        patch->ResetLod();
         geometry->SetIndexBuffer(indexBuffer_);
         geometry->SetDrawRange(TRIANGLE_LIST, drawRanges_[0].first_, drawRanges_[0].second_, false);
         geometry->SetRawVertexData(cpuVertexData, sizeof(Vector3), MASK_POSITION);
@@ -486,6 +485,10 @@ void Terrain::CreatePatchGeometry(TerrainPatch* patch)
         minLodGeometry->SetDrawRange(TRIANGLE_LIST, drawRanges_[lastDrawRange].first_, drawRanges_[lastDrawRange].second_, false);
         minLodGeometry->SetRawVertexData(cpuVertexData, sizeof(Vector3), MASK_POSITION);
     }
+    
+    // Offset the occlusion geometry by half vertex spacing to reduce possibility of over-eager occlusion
+    patch->SetOcclusionOffset(0.25f * (spacing_.x_ + spacing_.z_));
+    patch->ResetLod();
 }
 
 void Terrain::UpdatePatchLod(TerrainPatch* patch)

+ 11 - 2
Engine/Graphics/TerrainPatch.cpp

@@ -49,7 +49,8 @@ TerrainPatch::TerrainPatch(Context* context) :
     minLodGeometry_(new Geometry(context)),
     vertexBuffer_(new VertexBuffer(context)),
     coordinates_(IntVector2::ZERO),
-    lodLevel_(0)
+    lodLevel_(0),
+    occlusionOffset_(0.0f)
 {
     drawableFlags_ = DRAWABLE_GEOMETRY;
     
@@ -213,8 +214,11 @@ bool TerrainPatch::DrawOcclusion(OcclusionBuffer* buffer)
     if (!vertexData || !indexData)
         return success;
     
+    Matrix3x4 occlusionTransform(node_->GetWorldPosition() + node_->GetWorldTransform() * Vector4(0.0f, -occlusionOffset_, 0.0f,
+        0.0f), node_->GetWorldRotation(), node_->GetWorldScale());
+    
     // Draw and check for running out of triangles
-    if (!buffer->Draw(node_->GetWorldTransform(), vertexData, vertexSize, indexData, indexSize, minLodGeometry_->GetIndexStart(),
+    if (!buffer->Draw(occlusionTransform, vertexData, vertexSize, indexData, indexSize, minLodGeometry_->GetIndexStart(),
         minLodGeometry_->GetIndexCount()))
         success = false;
     
@@ -250,6 +254,11 @@ void TerrainPatch::SetCoordinates(const IntVector2& coordinates)
     coordinates_ = coordinates;
 }
 
+void TerrainPatch::SetOcclusionOffset(float offset)
+{
+    occlusionOffset_ = offset;
+}
+
 void TerrainPatch::ResetLod()
 {
     lodLevel_ = 0;

+ 6 - 0
Engine/Graphics/TerrainPatch.h

@@ -67,6 +67,8 @@ public:
     void SetBoundingBox(const BoundingBox& box);
     /// Set patch coordinates.
     void SetCoordinates(const IntVector2& coordinates);
+    /// Set vertical offset for occlusion geometry.
+    void SetOcclusionOffset(float offset);
     /// Reset to LOD level 0.
     void ResetLod();
     
@@ -96,6 +98,8 @@ public:
     const IntVector2& GetCoordinates() const { return coordinates_; }
     /// Return current LOD level.
     unsigned GetLodLevel() const { return lodLevel_; }
+    /// Return vertical offset for occlusion geometry..
+    float GetOcclusionOffset() const { return occlusionOffset_; }
     
 protected:
     /// Recalculate the world-space bounding box.
@@ -131,4 +135,6 @@ private:
     IntVector2 coordinates_;
     /// Current LOD level.
     unsigned lodLevel_;
+    /// Vertical offset for occlusion geometry.
+    float occlusionOffset_;
 };