Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
TerrainRenderer.cs
浏览该文件的文档.
1using Engine;
3
4namespace Game {
5 public class TerrainRenderer : IDisposable {
7
9
11
12 public static Shader m_opaqueShader;
13
15
17
19 AddressModeU = TextureAddressMode.Clamp, AddressModeV = TextureAddressMode.Clamp, FilterMode = TextureFilterMode.Point, MaxLod = 0f
20 };
21
23 AddressModeU = TextureAddressMode.Clamp,
24 AddressModeV = TextureAddressMode.Clamp,
25 FilterMode = TextureFilterMode.PointMipLinear,
26 MaxLod = 4f
27 };
28
29 public DynamicArray<TerrainChunk> m_chunksToDraw = [];
30
31 public static DynamicArray<int> m_tmpIndices = [];
32 public static DynamicArray<TerrainVertex> m_tmpVertices = [];
33
34 public static bool DrawChunksMap;
35
36 public static int ChunksDrawn;
37
38 public static int ChunkDrawCalls;
39
40 public static int ChunkTrianglesDrawn;
41
42 public virtual string ChunksGpuMemoryUsage {
43 get {
44 long num = 0L;
45 TerrainChunk[] allocatedChunks = m_subsystemTerrain.Terrain.AllocatedChunks;
46 foreach (TerrainChunk terrainChunk in allocatedChunks) {
47 if (terrainChunk.Geometry != null) {
48 foreach (TerrainChunkGeometry.Buffer buffer in terrainChunk.Buffers) {
49 num += buffer.VertexBuffer?.GetGpuMemoryUsage() ?? 0;
50 num += buffer.IndexBuffer?.GetGpuMemoryUsage() ?? 0;
51 }
52 }
53 }
54 return $"{num / 1024 / 1024:0.0}MB";
55 }
56 }
57
58 public TerrainRenderer() { }
59
60 public TerrainRenderer(SubsystemTerrain subsystemTerrain) {
61 m_subsystemTerrain = subsystemTerrain;
62 m_subsystemSky = subsystemTerrain.Project.FindSubsystem<SubsystemSky>(true);
64 m_opaqueShader ??= new Shader(
65 ShaderCodeManager.GetFast("Shaders/Opaque.vsh"),
66 ShaderCodeManager.GetFast("Shaders/Opaque.psh"),
67 new ShaderMacro("Opaque")
68 );
70 ShaderCodeManager.GetFast("Shaders/AlphaTested.vsh"),
71 ShaderCodeManager.GetFast("Shaders/AlphaTested.psh"),
72 new ShaderMacro("ALPHATESTED")
73 );
75 ShaderCodeManager.GetFast("Shaders/Transparent.vsh"),
76 ShaderCodeManager.GetFast("Shaders/Transparent.psh"),
77 new ShaderMacro("Transparent")
78 );
79 Display.DeviceReset += Display_DeviceReset;
80 }
81
82 public virtual void PrepareForDrawing(Camera camera) {
83 Vector2 xZ = camera.ViewPosition.XZ;
84 float num = MathUtils.Sqr(m_subsystemSky.VisibilityRange);
85 BoundingFrustum viewFrustum = camera.ViewFrustum;
86 int gameWidgetIndex = camera.GameWidget.GameWidgetIndex;
87 m_chunksToDraw.Clear();
88 TerrainChunk[] allocatedChunks = m_subsystemTerrain.Terrain.AllocatedChunks;
89 foreach (TerrainChunk terrainChunk in allocatedChunks) {
90 if (terrainChunk.NewGeometryData) {
91 lock (terrainChunk.Geometry) {
92 if (terrainChunk.NewGeometryData) {
93 terrainChunk.NewGeometryData = false;
95 }
96 }
97 }
98 if (terrainChunk.Buffers.Count > 0
99 && Vector2.DistanceSquared(xZ, terrainChunk.Center) <= (double)num) {
100 if (viewFrustum.Intersection(terrainChunk.BoundingBox)) {
101 m_chunksToDraw.Add(terrainChunk);
102 }
103 if (terrainChunk.State != TerrainChunkState.Valid) {
104 continue;
105 }
106 float num2 = terrainChunk.HazeEnds[gameWidgetIndex];
107 if (num2 != 3.40282347E+38f) {
108 if (num2 == 0f) {
109 StartChunkFadeIn(camera, terrainChunk);
110 }
111 else {
112 RunChunkFadeIn(camera, terrainChunk);
113 }
114 }
115 }
116 else {
117 terrainChunk.HazeEnds[gameWidgetIndex] = 0f;
118 }
119 }
120 ChunksDrawn = 0;
121 ChunkDrawCalls = 0;
123 }
124
125 public virtual void DrawOpaque(Camera camera) {
126 int gameWidgetIndex = camera.GameWidget.GameWidgetIndex;
127 Vector3 viewPosition = camera.InvertedViewMatrix.Translation;
128 Vector3 v = new(MathF.Floor(viewPosition.X), 0f, MathF.Floor(viewPosition.Z));
129 Matrix value = Matrix.CreateTranslation(v - viewPosition) * camera.ViewMatrix.OrientationMatrix * camera.ProjectionMatrix;
130 Display.BlendState = BlendState.Opaque;
131 Display.DepthStencilState = DepthStencilState.Default;
132 Display.RasterizerState = RasterizerState.CullCounterClockwiseScissor;
133 m_opaqueShader.GetParameter("u_origin", true).SetValue(v.XZ);
134 m_opaqueShader.GetParameter("u_viewProjectionMatrix", true).SetValue(value);
135 m_opaqueShader.GetParameter("u_viewPosition", true).SetValue(viewPosition);
136 m_opaqueShader.GetParameter("u_samplerState", true).SetValue(SettingsManager.TerrainMipmapsEnabled ? m_samplerStateMips : m_samplerState);
137 m_opaqueShader.GetParameter("u_fogYMultiplier", true).SetValue(m_subsystemSky.VisibilityRangeYMultiplier);
138 m_opaqueShader.GetParameter("u_fogColor", true).SetValue(new Vector3(m_subsystemSky.ViewFogColor));
139 m_opaqueShader.GetParameter("u_fogBottomTopDensity")
140 .SetValue(new Vector3(m_subsystemSky.ViewFogBottom, m_subsystemSky.ViewFogTop, m_subsystemSky.ViewFogDensity));
141 ShaderParameter parameter = m_opaqueShader.GetParameter("u_hazeStartDensity");
143 "SetShaderParameter",
144 modLoader => {
145 modLoader.SetShaderParameter(m_opaqueShader, camera);
146 return true;
147 }
148 );
149 //Point2 point = Terrain.ToChunk(camera.ViewPosition.XZ);
150 //TerrainChunk chunk = m_subsystemTerrain.Terrain.GetChunkAtCoords(point.X, point.Y);
151 for (int i = 0; i < m_chunksToDraw.Count; i++) {
152 TerrainChunk terrainChunk = m_chunksToDraw[i];
153 float num = MathUtils.Min(terrainChunk.HazeEnds[gameWidgetIndex], m_subsystemSky.ViewHazeStart + 1f / m_subsystemSky.ViewHazeDensity);
154 float num2 = MathUtils.Min(m_subsystemSky.ViewHazeStart, num - 1f);
155 parameter.SetValue(new Vector2(num2, 1f / (num - num2)));
156 int num3 = 16;
157 if (viewPosition.Z > terrainChunk.BoundingBox.Min.Z) {
158 num3 |= 1;
159 }
160 if (viewPosition.X > terrainChunk.BoundingBox.Min.X) {
161 num3 |= 2;
162 }
163 if (viewPosition.Z < terrainChunk.BoundingBox.Max.Z) {
164 num3 |= 4;
165 }
166 if (viewPosition.X < terrainChunk.BoundingBox.Max.X) {
167 num3 |= 8;
168 }
170 ChunksDrawn++;
171 }
172 }
173
174 public virtual void DrawAlphaTested(Camera camera) {
175 int gameWidgetIndex = camera.GameWidget.GameWidgetIndex;
176 Vector3 viewPosition = camera.InvertedViewMatrix.Translation;
177 Vector3 v = new(MathF.Floor(viewPosition.X), 0f, MathF.Floor(viewPosition.Z));
178 Matrix value = Matrix.CreateTranslation(v - viewPosition) * camera.ViewMatrix.OrientationMatrix * camera.ProjectionMatrix;
179 Display.BlendState = BlendState.Opaque;
180 Display.DepthStencilState = DepthStencilState.Default;
181 Display.RasterizerState = RasterizerState.CullCounterClockwiseScissor;
182 m_alphaTestedShader.GetParameter("u_origin", true).SetValue(v.XZ);
183 m_alphaTestedShader.GetParameter("u_viewProjectionMatrix", true).SetValue(value);
184 m_alphaTestedShader.GetParameter("u_viewPosition", true).SetValue(viewPosition);
185 m_alphaTestedShader.GetParameter("u_samplerState", true)
187 m_alphaTestedShader.GetParameter("u_fogYMultiplier", true).SetValue(m_subsystemSky.VisibilityRangeYMultiplier);
188 m_alphaTestedShader.GetParameter("u_fogColor", true).SetValue(new Vector3(m_subsystemSky.ViewFogColor));
189 m_alphaTestedShader.GetParameter("u_fogBottomTopDensity")
190 .SetValue(new Vector3(m_subsystemSky.ViewFogBottom, m_subsystemSky.ViewFogTop, m_subsystemSky.ViewFogDensity));
191 m_alphaTestedShader.GetParameter("u_alphaThreshold").SetValue(0.5f);
192 ShaderParameter parameter = m_alphaTestedShader.GetParameter("u_hazeStartDensity");
194 "SetShaderParameter",
195 modLoader => {
196 modLoader.SetShaderParameter(m_alphaTestedShader, camera);
197 return true;
198 }
199 );
200 for (int i = 0; i < m_chunksToDraw.Count; i++) {
201 TerrainChunk terrainChunk = m_chunksToDraw[i];
202 float num = MathUtils.Min(terrainChunk.HazeEnds[gameWidgetIndex], m_subsystemSky.ViewHazeStart + 1f / m_subsystemSky.ViewHazeDensity);
203 float num2 = MathUtils.Min(m_subsystemSky.ViewHazeStart, num - 1f);
204 parameter.SetValue(new Vector2(num2, 1f / (num - num2)));
205 int subsetsMask = 32;
206 DrawTerrainChunkGeometrySubsets(m_alphaTestedShader, terrainChunk, subsetsMask);
207 }
208 }
209
210 public virtual void DrawTransparent(Camera camera) {
211 int gameWidgetIndex = camera.GameWidget.GameWidgetIndex;
212 Vector3 viewPosition = camera.InvertedViewMatrix.Translation;
213 Vector3 v = new(MathF.Floor(viewPosition.X), 0f, MathF.Floor(viewPosition.Z));
214 Matrix value = Matrix.CreateTranslation(v - viewPosition) * camera.ViewMatrix.OrientationMatrix * camera.ProjectionMatrix;
215 Display.BlendState = BlendState.AlphaBlend;
216 Display.DepthStencilState = DepthStencilState.Default;
217 Display.RasterizerState = m_subsystemSky.ViewUnderWaterDepth > 0f
220 m_transparentShader.GetParameter("u_origin", true).SetValue(v.XZ);
221 m_transparentShader.GetParameter("u_viewProjectionMatrix", true).SetValue(value);
222 m_transparentShader.GetParameter("u_viewPosition", true).SetValue(viewPosition);
223 m_transparentShader.GetParameter("u_samplerState", true)
225 m_transparentShader.GetParameter("u_fogYMultiplier", true).SetValue(m_subsystemSky.VisibilityRangeYMultiplier);
226 m_transparentShader.GetParameter("u_fogColor", true).SetValue(new Vector3(m_subsystemSky.ViewFogColor));
227 m_transparentShader.GetParameter("u_fogBottomTopDensity")
228 .SetValue(new Vector3(m_subsystemSky.ViewFogBottom, m_subsystemSky.ViewFogTop, m_subsystemSky.ViewFogDensity));
229 ShaderParameter parameter = m_transparentShader.GetParameter("u_hazeStartDensity");
231 "SetShaderParameter",
232 modLoader => {
233 modLoader.SetShaderParameter(m_transparentShader, camera);
234 return true;
235 }
236 );
237 for (int i = 0; i < m_chunksToDraw.Count; i++) {
238 TerrainChunk terrainChunk = m_chunksToDraw[i];
239 float num = MathUtils.Min(terrainChunk.HazeEnds[gameWidgetIndex], m_subsystemSky.ViewHazeStart + 1f / m_subsystemSky.ViewHazeDensity);
240 float num2 = MathUtils.Min(m_subsystemSky.ViewHazeStart, num - 1f);
241 parameter.SetValue(new Vector2(num2, 1f / (num - num2)));
242 int subsetsMask = 64;
243 DrawTerrainChunkGeometrySubsets(m_transparentShader, terrainChunk, subsetsMask);
244 }
245 }
246
247 public virtual void Dispose() {
248 Display.DeviceReset -= Display_DeviceReset;
249 }
250
251 public virtual void Display_DeviceReset() {
252 m_subsystemTerrain.TerrainUpdater.DowngradeAllChunksState(TerrainChunkState.InvalidVertices1, false);
253 TerrainChunk[] allocatedChunks = m_subsystemTerrain.Terrain.AllocatedChunks;
254 foreach (TerrainChunk terrainChunk in allocatedChunks) {
255 terrainChunk.DisposeVertexIndexBuffers();
256 }
257 }
258
260 foreach (TerrainChunkGeometry.Buffer buffer in chunk.Buffers) {
261 buffer.Dispose();
262 }
263 chunk.Buffers.Clear();
265 }
266
272
273 public class SubsetStat {
274 public int[] subsetTotalIndexCount = new int[7];
275 public int[] subsetTotalVertexCount = new int[7];
276 public int[] subsetSettedIndexCount = new int[7];
277 public int[] subsetSettedVertexCount = new int[7];
278 public int totalIndexCount;
281 }
282
283 public static Dictionary<Texture2D, SubsetStat> stat = new();
284
285 public static void CompileDrawSubsets(TerrainGeometry[] chunkSliceGeometries,
286 DynamicArray<TerrainChunkGeometry.Buffer> buffers,
287 Func<TerrainVertex, TerrainVertex> vertexTransform = null) {
288 stat.Clear();
289 //按贴图进行分组统计Subset的顶点数与索引数
290 for (int k = 0; k < chunkSliceGeometries.Length; k++) {
291 TerrainGeometry geometry = chunkSliceGeometries[k]; //第k个slice
292 //统计每个subset的indexCount与VertexCount
293 foreach (KeyValuePair<Texture2D, TerrainGeometry> drawItem in geometry.Draws) {
294 TerrainGeometry subGeometry = drawItem.Value;
295 for (int i = 0; i < subGeometry.Subsets.Length; i++) {
296 if (!stat.TryGetValue(drawItem.Key, out SubsetStat subsetStat)) {
297 subsetStat = new SubsetStat();
298 stat.Add(drawItem.Key, subsetStat);
299 }
300 int ic = subGeometry.Subsets[i].Indices.Count;
301 int vc = subGeometry.Subsets[i].Vertices.Count;
302 subsetStat.subsetTotalIndexCount[i] += ic;
303 subsetStat.subsetTotalVertexCount[i] += vc;
304 subsetStat.totalIndexCount += ic;
305 subsetStat.totalVertextCount += vc;
306 }
307 }
308 }
309 //按贴图分组完成,生成buffer
310 foreach (KeyValuePair<Texture2D, SubsetStat> statItem in stat) {
311 if (statItem.Value.totalIndexCount == 0) {
312 continue;
313 }
314 TerrainChunkGeometry.Buffer buffer = new();
315 buffer.IndexBuffer = new IndexBuffer(IndexFormat.ThirtyTwoBits, statItem.Value.totalIndexCount);
316 buffer.VertexBuffer = new VertexBuffer(TerrainVertex.VertexDeclaration, statItem.Value.totalVertextCount);
317 buffer.Texture = statItem.Key;
318 statItem.Value.Buffer = buffer;
319 buffers.Add(buffer);
320 int subsetSettedIndexCount = 0;
321 int subsetSettedVertexCount = 0;
322 for (int i = 0; i < 7; i++) {
323 if (i == 0) {
324 buffer.SubsetIndexBufferStarts[i] = 0;
325 buffer.SubsetIndexBufferEnds[i] = statItem.Value.subsetTotalIndexCount[i];
326 buffer.SubsetVertexBufferStarts[i] = 0;
327 buffer.SubsetVertexBufferEnds[i] = statItem.Value.subsetTotalVertexCount[i];
328 subsetSettedIndexCount = statItem.Value.subsetTotalIndexCount[i];
329 subsetSettedVertexCount = statItem.Value.subsetTotalVertexCount[i];
330 }
331 else {
332 buffer.SubsetIndexBufferStarts[i] = subsetSettedIndexCount;
333 buffer.SubsetIndexBufferEnds[i] = statItem.Value.subsetTotalIndexCount[i] + buffer.SubsetIndexBufferStarts[i];
334 buffer.SubsetVertexBufferStarts[i] = subsetSettedVertexCount;
335 buffer.SubsetVertexBufferEnds[i] = statItem.Value.subsetTotalVertexCount[i] + buffer.SubsetVertexBufferStarts[i];
336 subsetSettedIndexCount += statItem.Value.subsetTotalIndexCount[i];
337 subsetSettedVertexCount += statItem.Value.subsetTotalVertexCount[i];
338 }
339 }
340 }
341 //将顶点列表与索引列表写入buffer
342 for (int k = 0; k < chunkSliceGeometries.Length; k++) {
343 TerrainGeometry geometry = chunkSliceGeometries[k]; //第k个slice
344 //统计每个subset的indexCount与VertexCount
345 foreach (KeyValuePair<Texture2D, TerrainGeometry> drawItem in geometry.Draws) {
346 TerrainGeometry subGeometry = drawItem.Value;
347 for (int i = 0; i < subGeometry.Subsets.Length; i++) {
348 if (stat.TryGetValue(drawItem.Key, out SubsetStat subsetStat)) {
349 if (subsetStat.totalIndexCount == 0) {
350 continue;
351 }
352 TerrainGeometryDynamicArray<int> indices = subGeometry.Subsets[i].Indices;
353 TerrainGeometryDynamicArray<TerrainVertex> vertices = subGeometry.Subsets[i].Vertices;
354 if (indices.Count > 0) {
355 TerrainChunkGeometry.Buffer buffer = subsetStat.Buffer;
356 m_tmpIndices.Count = indices.Count;
358 indices.Array,
359 m_tmpIndices.Array,
360 buffer.SubsetVertexBufferStarts[i] + subsetStat.subsetSettedVertexCount[i],
361 indices.Count
362 );
363 buffer.IndexBuffer.SetData(
364 m_tmpIndices.Array,
365 0,
366 indices.Count,
367 buffer.SubsetIndexBufferStarts[i] + subsetStat.subsetSettedIndexCount[i]
368 );
369 if (vertexTransform != null) {
370 m_tmpVertices.Count = vertices.Count;
371 for (int j = 0; j < vertices.Count; j++) {
372 m_tmpVertices[j] = vertexTransform(vertices[j]);
373 }
374 buffer.VertexBuffer.SetData(
375 m_tmpVertices.Array,
376 0,
377 vertices.Count,
378 buffer.SubsetVertexBufferStarts[i] + subsetStat.subsetSettedVertexCount[i]
379 );
380 }
381 else {
382 buffer.VertexBuffer.SetData(
383 vertices.Array,
384 0,
385 vertices.Count,
386 buffer.SubsetVertexBufferStarts[i] + subsetStat.subsetSettedVertexCount[i]
387 );
388 }
389 subsetStat.subsetSettedIndexCount[i] += indices.Count;
390 subsetStat.subsetSettedVertexCount[i] += vertices.Count;
391 }
392 }
393 }
394 }
395 }
396 }
397
398 public virtual void DrawTerrainChunkGeometrySubsets(Shader shader, TerrainChunk chunk, int subsetsMask, bool ApplyTexture = true) {
399 foreach (TerrainChunkGeometry.Buffer buffer in chunk.Buffers) {
400 int num = 2147483647;
401 int num2 = 0;
402 for (int i = 0; i < 8; i++) {
403 if (i < 7
404 && (subsetsMask & (1 << i)) != 0) {
405 if (buffer.SubsetIndexBufferEnds[i] > 0) {
406 if (num == 2147483647) {
407 num = buffer.SubsetIndexBufferStarts[i];
408 }
409 num2 = buffer.SubsetIndexBufferEnds[i];
410 }
411 }
412 else {
413 if (num2 > num) {
414 if (ApplyTexture) {
415 shader.GetParameter("u_texture", true).SetValue(buffer.Texture);
416 }
417 Display.DrawIndexed(PrimitiveType.TriangleList, shader, buffer.VertexBuffer, buffer.IndexBuffer, num, num2 - num);
418 ChunkTrianglesDrawn += (num2 - num) / 3;
420 }
421 num = 2147483647;
422 }
423 }
424 }
425 }
426
427 public virtual void StartChunkFadeIn(Camera camera, TerrainChunk chunk) {
428 Vector3 viewPosition = camera.ViewPosition;
429 Vector2 v = new(chunk.Origin.X, chunk.Origin.Y);
430 Vector2 v2 = new(chunk.Origin.X + 16, chunk.Origin.Y);
431 Vector2 v3 = new(chunk.Origin.X, chunk.Origin.Y + 16);
432 Vector2 v4 = new(chunk.Origin.X + 16, chunk.Origin.Y + 16);
433 float x = Vector2.Distance(viewPosition.XZ, v);
434 float x2 = Vector2.Distance(viewPosition.XZ, v2);
435 float x3 = Vector2.Distance(viewPosition.XZ, v3);
436 float x4 = Vector2.Distance(viewPosition.XZ, v4);
437 chunk.HazeEnds[camera.GameWidget.GameWidgetIndex] = MathF.Max(Math.Min(Math.Min(Math.Min(x, x2), x3), x4), 0.001f);
438 }
439
440 public virtual void RunChunkFadeIn(Camera camera, TerrainChunk chunk) {
442 if (chunk.HazeEnds[camera.GameWidget.GameWidgetIndex] >= m_subsystemSky.VisibilityRange) {
443 chunk.HazeEnds[camera.GameWidget.GameWidgetIndex] = 3.40282347E+38f;
444 }
445 }
446
447 public static void ShiftIndices(int[] source, int[] destination, int shift, int count) {
448 for (int i = 0; i < count; i++) {
449 destination[i] = source[i] + shift;
450 }
451 }
452 }
453}
Engine.Vector3 Vector3
static readonly BlendState Opaque
static readonly BlendState AlphaBlend
static readonly DepthStencilState Default
static void DrawIndexed(PrimitiveType primitiveType, Shader shader, VertexBuffer vertexBuffer, IndexBuffer indexBuffer, int startIndex, int indicesCount)
static readonly RasterizerState CullClockwiseScissor
static readonly RasterizerState CullCounterClockwiseScissor
virtual ShaderParameter GetParameter(string name, bool allowNull=false)
static int Min(int x1, int x2)
static int Sqr(int x)
static float FrameDuration
定义 Time.cs:46
Vector3 ViewPosition
GameWidget GameWidget
BoundingFrustum ViewFrustum
Matrix InvertedViewMatrix
Matrix ProjectionMatrix
static string GetFast(string fname)
virtual SubsystemAnimatedTextures SubsystemAnimatedTextures
virtual void CopySliceContentsHashes()
volatile bool NewGeometryData
virtual void DisposeVertexIndexBuffers()
TerrainChunkState State
TerrainGeometry[] ChunkSliceGeometries
DynamicArray< TerrainChunkGeometry.Buffer > Buffers
virtual void InvalidateSliceContentsHashes()
TerrainChunkGeometry Geometry
TerrainGeometrySubset[] Subsets
TerrainGeometryDynamicArray< TerrainVertex > Vertices
TerrainGeometryDynamicArray< int > Indices
TerrainChunkGeometry.Buffer Buffer
static void ShiftIndices(int[] source, int[] destination, int shift, int count)
DynamicArray< TerrainChunk > m_chunksToDraw
TerrainRenderer(SubsystemTerrain subsystemTerrain)
virtual void DrawTerrainChunkGeometrySubsets(Shader shader, TerrainChunk chunk, int subsetsMask, bool ApplyTexture=true)
virtual void PrepareForDrawing(Camera camera)
SubsystemAnimatedTextures m_subsystemAnimatedTextures
static DynamicArray< TerrainVertex > m_tmpVertices
virtual void DrawOpaque(Camera camera)
virtual void SetupTerrainChunkGeometryVertexIndexBuffers(TerrainChunk chunk)
static DynamicArray< int > m_tmpIndices
virtual void StartChunkFadeIn(Camera camera, TerrainChunk chunk)
SubsystemTerrain m_subsystemTerrain
static void CompileDrawSubsets(TerrainGeometry[] chunkSliceGeometries, DynamicArray< TerrainChunkGeometry.Buffer > buffers, Func< TerrainVertex, TerrainVertex > vertexTransform=null)
virtual void DrawTransparent(Camera camera)
virtual void RunChunkFadeIn(Camera camera, TerrainChunk chunk)
virtual void DrawAlphaTested(Camera camera)
static Dictionary< Texture2D, SubsetStat > stat
virtual void DisposeTerrainChunkGeometryVertexIndexBuffers(TerrainChunk chunk)
virtual string ChunksGpuMemoryUsage
virtual Subsystem FindSubsystem(Type type, string name, bool throwOnError)
static void HookAction(string HookName, Func< ModLoader, bool > action)
执行Hook
static Matrix CreateTranslation(float x, float y, float z)
Vector3 Translation
static float DistanceSquared(Vector2 v1, Vector2 v2)
static float Distance(Vector2 v1, Vector2 v2)
static readonly VertexDeclaration VertexDeclaration