Browse Source

Use lowest terrain LOD for occlusion. This can possibly result in over-aggressive occlusion, so needs to be used with care.

Lasse Öörni 13 years ago
parent
commit
1c95a5b007

+ 1 - 0
Bin/Data/Scripts/Terrain.as

@@ -158,6 +158,7 @@ void InitScene()
         terrain.spacing = Vector3(2, 0.5, 2);
         terrain.heightMap = cache.GetResource("Image", "Textures/HeightMap.png");
         terrain.material = cache.GetResource("Material", "Materials/Terrain.xml");
+        terrain.occluder = true;
 
         RigidBody@ body = terrainNode.CreateComponent("RigidBody");
         CollisionShape@ shape = terrainNode.CreateComponent("CollisionShape");

+ 6 - 0
Engine/Graphics/Terrain.cpp

@@ -412,6 +412,7 @@ void Terrain::CreatePatchGeometry(TerrainPatch* patch)
     VertexBuffer* vertexBuffer = patch->GetVertexBuffer();
     Geometry* geometry = patch->GetGeometry();
     Geometry* maxLodGeometry = patch->GetMaxLodGeometry();
+    Geometry* minLodGeometry = patch->GetMinLodGeometry();
     
     if (vertexBuffer->GetVertexCount() != row * row)
         vertexBuffer->SetSize(row * row, MASK_POSITION | MASK_NORMAL | MASK_TEXCOORD1 | MASK_TANGENT);
@@ -472,6 +473,8 @@ void Terrain::CreatePatchGeometry(TerrainPatch* patch)
     
     if (drawRanges_.Size())
     {
+        unsigned lastDrawRange = drawRanges_.Size() - 1;
+        
         patch->ResetLod();
         geometry->SetIndexBuffer(indexBuffer_);
         geometry->SetDrawRange(TRIANGLE_LIST, drawRanges_[0].first_, drawRanges_[0].second_, false);
@@ -479,6 +482,9 @@ void Terrain::CreatePatchGeometry(TerrainPatch* patch)
         maxLodGeometry->SetIndexBuffer(indexBuffer_);
         maxLodGeometry->SetDrawRange(TRIANGLE_LIST, drawRanges_[0].first_, drawRanges_[0].second_, false);
         maxLodGeometry->SetRawVertexData(cpuVertexData, sizeof(Vector3), MASK_POSITION);
+        minLodGeometry->SetIndexBuffer(indexBuffer_);
+        minLodGeometry->SetDrawRange(TRIANGLE_LIST, drawRanges_[lastDrawRange].first_, drawRanges_[lastDrawRange].second_, false);
+        minLodGeometry->SetRawVertexData(cpuVertexData, sizeof(Vector3), MASK_POSITION);
     }
 }
 

+ 12 - 5
Engine/Graphics/TerrainPatch.cpp

@@ -46,6 +46,7 @@ TerrainPatch::TerrainPatch(Context* context) :
     Drawable(context),
     geometry_(new Geometry(context)),
     maxLodGeometry_(new Geometry(context)),
+    minLodGeometry_(new Geometry(context)),
     vertexBuffer_(new VertexBuffer(context)),
     coordinates_(IntVector2::ZERO),
     lodLevel_(0)
@@ -54,6 +55,7 @@ TerrainPatch::TerrainPatch(Context* context) :
     
     geometry_->SetVertexBuffer(0, vertexBuffer_, MASK_POSITION | MASK_NORMAL | MASK_TEXCOORD1 | MASK_TANGENT);
     maxLodGeometry_->SetVertexBuffer(0, vertexBuffer_, MASK_POSITION | MASK_NORMAL | MASK_TEXCOORD1 | MASK_TANGENT);
+    minLodGeometry_->SetVertexBuffer(0, vertexBuffer_, MASK_POSITION | MASK_NORMAL | MASK_TEXCOORD1 | MASK_TANGENT);
     
     batches_.Resize(1);
     batches_[0].geometry_ = geometry_;
@@ -182,7 +184,7 @@ unsigned TerrainPatch::GetNumOccluderTriangles()
     if (mat && !mat->GetOcclusion())
         return 0;
     else
-        return geometry_->GetIndexCount() / 3;
+        return minLodGeometry_->GetIndexCount() / 3;
 }
 
 bool TerrainPatch::DrawOcclusion(OcclusionBuffer* buffer)
@@ -206,14 +208,14 @@ bool TerrainPatch::DrawOcclusion(OcclusionBuffer* buffer)
     unsigned indexSize;
     unsigned elementMask;
     
-    geometry_->GetRawData(vertexData, vertexSize, indexData, indexSize, elementMask);
+    minLodGeometry_->GetRawData(vertexData, vertexSize, indexData, indexSize, elementMask);
     // Check for valid geometry data
     if (!vertexData || !indexData)
         return success;
-
+    
     // Draw and check for running out of triangles
-    if (!buffer->Draw(node_->GetWorldTransform(), vertexData, vertexSize, indexData, indexSize, geometry_->GetIndexStart(),
-        geometry_->GetIndexCount()))
+    if (!buffer->Draw(node_->GetWorldTransform(), vertexData, vertexSize, indexData, indexSize, minLodGeometry_->GetIndexStart(),
+        minLodGeometry_->GetIndexCount()))
         success = false;
     
     return success;
@@ -263,6 +265,11 @@ Geometry* TerrainPatch::GetMaxLodGeometry() const
     return maxLodGeometry_;
 }
 
+Geometry* TerrainPatch::GetMinLodGeometry() const
+{
+    return minLodGeometry_;
+}
+
 VertexBuffer* TerrainPatch::GetVertexBuffer() const
 {
     return vertexBuffer_;

+ 4 - 0
Engine/Graphics/TerrainPatch.h

@@ -74,6 +74,8 @@ public:
     Geometry* GetGeometry() const;
     /// Return max LOD geometry.
     Geometry* GetMaxLodGeometry() const;
+    /// Return min LOD geometry.
+    Geometry* GetMinLodGeometry() const;
     /// Return vertex buffer.
     VertexBuffer* GetVertexBuffer() const;
     /// Return owner terrain.
@@ -107,6 +109,8 @@ private:
     SharedPtr<Geometry> geometry_;
     /// Geometry that is locked to the max LOD level. Used for decals.
     SharedPtr<Geometry> maxLodGeometry_;
+    /// Geometry that is locked to the minimum LOD level. Used for occlusion.
+    SharedPtr<Geometry> minLodGeometry_;
     /// Vertex buffer.
     SharedPtr<VertexBuffer> vertexBuffer_;
     /// Parent terrain.