diff --git a/engine/Sandbox.Engine/Scene/Components/Terrain/Terrain.Rendering.cs b/engine/Sandbox.Engine/Scene/Components/Terrain/Terrain.Rendering.cs
index d1868da6..5b32815a 100644
--- a/engine/Sandbox.Engine/Scene/Components/Terrain/Terrain.Rendering.cs
+++ b/engine/Sandbox.Engine/Scene/Components/Terrain/Terrain.Rendering.cs
@@ -1,4 +1,5 @@
-using System.Runtime.InteropServices;
+using ExCSS;
+using System.Runtime.InteropServices;
using static Sandbox.ModelRenderer;
namespace Sandbox;
@@ -17,11 +18,54 @@ public partial class Terrain
private SceneObject _so { get; set; }
+ ///
+ /// Create buffers needed for terrain rendering, set sane empties, always bound
+ ///
+ void CreateBuffers()
+ {
+ TerrainBuffer ??= new( 1 );
+ MaterialsBuffer ??= new( 64 );
+
+ var gpuTerrain = new GPUTerrain()
+ {
+ Transform = Matrix.Identity,
+ TransformInv = Matrix.Identity,
+ HeightMapTextureID = 0,
+ ControlMapTextureID = 0,
+ Resolution = 1024,
+ HeightScale = 1024,
+ HeightBlending = false,
+ HeightBlendSharpness = 0
+ };
+
+ var gpuMaterials = new GPUTerrainMaterial[64];
+ for ( int i = 0; i < 64; i++ )
+ {
+ gpuMaterials[i] = new GPUTerrainMaterial
+ {
+ BCRTextureID = 0,
+ NHOTextureID = 0,
+ UVScale = 1.0f,
+ Metalness = 0.0f,
+ NormalStrength = 1.0f,
+ HeightBlendStrength = 1.0f,
+ DisplacementScale = 0.0f,
+ Flags = TerrainFlags.None,
+ };
+ }
+
+ TerrainBuffer.SetData( new List() { gpuTerrain } );
+ MaterialsBuffer.SetData( gpuMaterials );
+ }
+
void CreateClipmapSceneObject()
{
if ( !Active || Application.IsHeadless )
return;
+ // These get created once
+ CreateBuffers();
+
Assert.NotNull( Scene );
_so?.Delete();
@@ -48,6 +92,13 @@ public partial class Terrain
// If we have no textures, push a grid texture (SUCKS)
_so.Attributes.SetCombo( "D_GRID", Storage?.Materials.Count == 0 );
+ _so.Attributes.Set( "Terrain", TerrainBuffer );
+ _so.Attributes.Set( "TerrainMaterials", MaterialsBuffer );
+
+ // We want these accessible globally too, probably
+ Scene.RenderAttributes.Set( "Terrain", TerrainBuffer );
+ Scene.RenderAttributes.Set( "TerrainMaterials", MaterialsBuffer );
+
_clipMapLodLevels = ClipMapLodLevels;
_clipMapLodExtentTexels = ClipMapLodExtentTexels;
_subdivisionFactor = SubdivisionFactor;
@@ -98,9 +149,6 @@ public partial class Terrain
if ( Storage is null )
return;
- if ( TerrainBuffer is null )
- TerrainBuffer = new( 1 );
-
var transform = Matrix.FromTransform( WorldTransform );
var gpuTerrain = new GPUTerrain()
@@ -116,10 +164,7 @@ public partial class Terrain
};
// Upload to the GPU buffer
- TerrainBuffer?.SetData( new List() { gpuTerrain } );
-
- _so.Attributes.Set( "Terrain", TerrainBuffer );
- Scene.RenderAttributes.Set( "Terrain", TerrainBuffer );
+ TerrainBuffer.SetData( new List() { gpuTerrain } );
}
///
@@ -134,17 +179,8 @@ public partial class Terrain
if ( Storage is null )
return;
- // Support up to 32 materials for indexed splatmap
- int materialCount = Math.Max( 4, Math.Min( Storage.Materials.Count, 32 ) );
-
- if ( MaterialsBuffer is null || MaterialsBuffer.ElementCount != materialCount )
- {
- MaterialsBuffer?.Dispose();
- MaterialsBuffer = new( materialCount );
- }
-
- var gpuMaterials = new GPUTerrainMaterial[materialCount];
- for ( int i = 0; i < materialCount; i++ )
+ var gpuMaterials = new GPUTerrainMaterial[64];
+ for ( int i = 0; i < 64; i++ )
{
var layer = Storage.Materials.ElementAtOrDefault( i );
@@ -161,12 +197,9 @@ public partial class Terrain
};
}
- MaterialsBuffer?.SetData( gpuMaterials );
-
- _so.Attributes.Set( "TerrainMaterials", MaterialsBuffer );
- Scene.RenderAttributes.Set( "TerrainMaterials", MaterialsBuffer );
+ MaterialsBuffer.SetData( gpuMaterials );
// If we have no textures, push a grid texture (SUCKS)
- _so.Attributes.SetCombo( "D_GRID", Storage?.Materials.Count == 0 );
+ _so.Attributes.SetCombo( "D_GRID", Storage.Materials.Count == 0 );
}
}