Optimize LOD checks

This commit is contained in:
Timo Eberl 2024-09-30 23:08:28 +02:00
parent ad66f824ee
commit 794125696f
Signed by: Timo
SSH Key Fingerprint: SHA256:swVjhbVzKCLQZNtwPqMEmtOUG3FTydzVrpIKpUZYTQw
2 changed files with 40715 additions and 221282 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using UnityEngine;
using UnityEngine.Serialization;
using Random = UnityEngine.Random;
public class GrassField : MonoBehaviour {
public int size = 100;
@ -57,10 +54,10 @@ public class GrassField : MonoBehaviour {
}
private void Update() {
UpdateLODs();
UpdateLODs(false);
}
private void UpdateLODs() {
private void UpdateLODs(bool forceCompleteCheck = true) {
var cam = Camera.main;
if (!cam) return;
@ -76,9 +73,14 @@ public class GrassField : MonoBehaviour {
new Vector3(0.5f * chunkSize, 0f, 0.5f * chunkSize),
new Vector3(chunkSize, 0f, chunkSize)
);
for (int x = 0; x < numChunks; x++)
for (int y = 0; y < numChunks; y++) {
// small performance difference (0.13ms vs 0.02ms on a 100m 30x30 grid, LOD dist 26.6, camera at corner)
var range = forceCompleteCheck
? new GridRange{ fromX = 0, toX = numChunks-1, fromZ = 0, toZ = numChunks-1 }
: GetLODGridRange(camPos, chunkSize);
for (int x = range.fromX; x <= range.toX; x++)
for (int y = range.fromZ; y <= range.toZ; y++) {
var chunkPos = new Vector3(x, 0f, y) * chunkSize;
var localCamPos = camPos - chunkPos; // cam position relative to chunk
@ -95,6 +97,34 @@ public class GrassField : MonoBehaviour {
}
}
private struct GridRange {
public int fromX;
public int toX;
public int fromZ;
public int toZ;
}
private GridRange GetLODGridRange(Vector3 camPos, float chunkSize) {
GridRange range;
var maxCamMove = 3f; // assume that the camera did not move further than this distance
var fromXWorld = camPos.x - distanceLOD2 - maxCamMove;
var toXWorld = camPos.x + distanceLOD2 + maxCamMove;
var fromZWorld = camPos.z - distanceLOD2 - maxCamMove;
var toZWorld = camPos.z + distanceLOD2 + maxCamMove;
range.fromX = Math.Max( 0, (int) (fromXWorld / chunkSize) );
range.toX = Math.Max( 0, (int) (toXWorld / chunkSize) );
range.fromZ = Math.Max( 0, (int) (fromZWorld / chunkSize) );
range.toZ = (int) (toZWorld / chunkSize);
range.fromX = Math.Clamp(range.fromX, 0, numChunks - 1);
range.toX = Math.Clamp(range.toX, 0, numChunks - 1);
range.fromZ = Math.Clamp(range.fromZ, 0, numChunks - 1);
range.toZ = Math.Clamp(range.toZ, 0, numChunks - 1);
return range;
}
private void CreateChunks(BladeData[] bladesLOD0, BladeData[] bladesLOD1, BladeData[] bladesLOD2) {
GameObject chunksContainer;
// If a child called "Chunks" exists, destroy it -> children are also destroyed