Improve chunk bounds calculation + better gizmos
This commit is contained in:
parent
268a22ad63
commit
253bdbf854
File diff suppressed because one or more lines are too long
@ -3,10 +3,10 @@ using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(MeshRenderer)), RequireComponent(typeof(MeshFilter))]
|
||||
public class GrassChunk : MonoBehaviour {
|
||||
void OnDrawGizmos() {
|
||||
Gizmos.color = Color.yellow;
|
||||
|
||||
var renderer = GetComponent<MeshRenderer>();
|
||||
Gizmos.DrawWireCube(renderer.bounds.center, renderer.bounds.size);
|
||||
private void OnDrawGizmos() {
|
||||
Gizmos.color = new Color(1f, 0.7f, 0f, 0.5f);
|
||||
var meshRenderer = GetComponent<MeshRenderer>();
|
||||
var bounds = meshRenderer.bounds;
|
||||
Gizmos.DrawWireCube(bounds.center, bounds.size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
public class GrassField : MonoBehaviour {
|
||||
public int size = 100;
|
||||
@ -16,13 +19,26 @@ public class GrassField : MonoBehaviour {
|
||||
public void GenerateGrassField() {
|
||||
Debug.Log("Generating grass field... ");
|
||||
|
||||
var blades = GenerateBlades();
|
||||
var blades = GenerateBladesRandom(100000);
|
||||
CreateChunks(blades);
|
||||
|
||||
Debug.Log("Generating grass field done");
|
||||
}
|
||||
|
||||
private BladeData[] GenerateBlades() {
|
||||
private BladeData[] GenerateBladesRandom(int num) {
|
||||
var blades = new BladeData[num];
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
blades[i].rootPosition = new Vector3(
|
||||
Random.Range(0f, size), Random.Range(-0.5f, 0.5f), Random.Range(0f, size)
|
||||
);
|
||||
blades[i].tipOffset = new Vector3(0.01f, 1.0f, 0.01f);
|
||||
}
|
||||
|
||||
return blades;
|
||||
}
|
||||
|
||||
private BladeData[] GenerateBladesEven() {
|
||||
var blades = new BladeData[size * size * 100];
|
||||
|
||||
for (int x = 0; x < size * 10; x++)
|
||||
@ -48,21 +64,22 @@ public class GrassField : MonoBehaviour {
|
||||
chunks.transform.SetParent(this.transform, false);
|
||||
|
||||
var chunkSize = ((float)size) / numChunks;
|
||||
// bounds of the chunk (relative to chunk) - do not consider y position
|
||||
var chunkBounds = new Bounds(
|
||||
new Vector3(0.5f * chunkSize, 0.0f, 0.5f * chunkSize),
|
||||
new Vector3(chunkSize, 10000f, chunkSize)
|
||||
);
|
||||
for (int x = 0; x < numChunks; x++)
|
||||
for (int y = 0; y < numChunks; y++) {
|
||||
var chunkPos = new Vector3(x, 0.0f, y) * chunkSize;
|
||||
// bounds in local space of grass field
|
||||
var bounds = new Bounds(
|
||||
new Vector3(0.5f * chunkSize, 0.5f, 0.5f * chunkSize),
|
||||
new Vector3(chunkSize, 1.01f, chunkSize)
|
||||
);
|
||||
|
||||
List<Vector3> rootPositions = new();
|
||||
List<Vector3> tipOffsets = new();
|
||||
List<int> indices = new();
|
||||
foreach (var blade in blades) {
|
||||
// position relative to chunk
|
||||
var localRootPos = blade.rootPosition - chunkPos;
|
||||
if (bounds.Contains(localRootPos)) {
|
||||
if (chunkBounds.Contains(localRootPos)) {
|
||||
rootPositions.Add(localRootPos);
|
||||
tipOffsets.Add(blade.tipOffset);
|
||||
indices.Add(rootPositions.Count - 1);
|
||||
@ -74,10 +91,19 @@ public class GrassField : MonoBehaviour {
|
||||
mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
|
||||
mesh.name = "grass_chunk[" + x + "," + y + "]";
|
||||
mesh.SetVertices(rootPositions);
|
||||
// do not calculate bounding box - will be set manually
|
||||
mesh.SetIndices(indices, MeshTopology.Points, 0, false);
|
||||
// Vector3 UVs are possible
|
||||
mesh.SetUVs(0, tipOffsets);
|
||||
mesh.SetUVs(0, tipOffsets); // Vector3 UVs
|
||||
// AABB gets calculated automatically (considers all root positions)
|
||||
mesh.SetIndices(indices, MeshTopology.Points, 0);
|
||||
// update the AABB to match the actual grass (not just the root positions)
|
||||
// use mesh.bounds rather than meshRenderer.localBounds,
|
||||
// because the latter gets overwritten automatically
|
||||
var previousBounds = mesh.bounds;
|
||||
float width = 1f;
|
||||
float height = 1f;
|
||||
mesh.bounds = new Bounds(
|
||||
previousBounds.center + new Vector3(0f, height * 0.5f, 0f),
|
||||
previousBounds.size + new Vector3(width, height, width)
|
||||
);
|
||||
|
||||
var chunk = Instantiate(chunkPrefab, chunks.transform);
|
||||
chunk.name = "Chunk [" + x + ", " + y +"]";
|
||||
@ -86,9 +112,24 @@ public class GrassField : MonoBehaviour {
|
||||
var meshFilter = chunk.GetComponent<MeshFilter>();
|
||||
meshFilter.sharedMesh = mesh;
|
||||
|
||||
|
||||
var meshRenderer = chunk.GetComponent<MeshRenderer>();
|
||||
meshRenderer.localBounds = bounds;
|
||||
meshRenderer.sharedMaterial = grassMaterial;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDrawGizmos() {
|
||||
Gizmos.color = new Color(0f, 0.2f, 1f, 1f);
|
||||
var chunkSize = ((float)size) / numChunks;
|
||||
var bounds = new Bounds(
|
||||
new Vector3(0.5f * chunkSize, 0.0f, 0.5f * chunkSize),
|
||||
new Vector3(chunkSize, 0f, chunkSize)
|
||||
);
|
||||
|
||||
for (int x = 0; x < numChunks; x++)
|
||||
for (int y = 0; y < numChunks; y++) {
|
||||
var chunkPos = new Vector3(x, 0.0f, y) * chunkSize;
|
||||
Gizmos.DrawWireCube(bounds.center + chunkPos + transform.position, bounds.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,7 +160,8 @@ PlayerSettings:
|
||||
resetResolutionOnWindowResize: 0
|
||||
androidSupportedAspectRatio: 1
|
||||
androidMaxAspectRatio: 2.1
|
||||
applicationIdentifier: {}
|
||||
applicationIdentifier:
|
||||
Standalone: com.DefaultCompany.GrassRenderingPrototype
|
||||
buildNumber:
|
||||
Standalone: 0
|
||||
VisionOS: 0
|
||||
|
||||
@ -6,7 +6,7 @@ QualitySettings:
|
||||
serializedVersion: 5
|
||||
m_CurrentQuality: 5
|
||||
m_QualitySettings:
|
||||
- serializedVersion: 2
|
||||
- serializedVersion: 3
|
||||
name: Very Low
|
||||
pixelLightCount: 0
|
||||
shadows: 0
|
||||
@ -18,17 +18,21 @@ QualitySettings:
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 0
|
||||
blendWeights: 1
|
||||
textureQuality: 1
|
||||
skinWeights: 1
|
||||
globalTextureMipmapLimit: 1
|
||||
textureMipmapLimitSettings: []
|
||||
anisotropicTextures: 0
|
||||
antiAliasing: 0
|
||||
softParticles: 0
|
||||
softVegetation: 0
|
||||
realtimeReflectionProbes: 0
|
||||
billboardsFaceCameraPosition: 0
|
||||
useLegacyDetailDistribution: 1
|
||||
vSyncCount: 0
|
||||
realtimeGICPUUsage: 25
|
||||
lodBias: 0.3
|
||||
maximumLODLevel: 0
|
||||
enableLODCrossFade: 1
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
@ -40,8 +44,18 @@ QualitySettings:
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
terrainQualityOverrides: 0
|
||||
terrainPixelError: 1
|
||||
terrainDetailDensityScale: 1
|
||||
terrainBasemapDistance: 1000
|
||||
terrainDetailDistance: 80
|
||||
terrainTreeDistance: 5000
|
||||
terrainBillboardStart: 50
|
||||
terrainFadeLength: 5
|
||||
terrainMaxTrees: 50
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
- serializedVersion: 3
|
||||
name: Low
|
||||
pixelLightCount: 0
|
||||
shadows: 0
|
||||
@ -53,17 +67,21 @@ QualitySettings:
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 0
|
||||
blendWeights: 2
|
||||
textureQuality: 0
|
||||
skinWeights: 2
|
||||
globalTextureMipmapLimit: 0
|
||||
textureMipmapLimitSettings: []
|
||||
anisotropicTextures: 0
|
||||
antiAliasing: 0
|
||||
softParticles: 0
|
||||
softVegetation: 0
|
||||
realtimeReflectionProbes: 0
|
||||
billboardsFaceCameraPosition: 0
|
||||
useLegacyDetailDistribution: 1
|
||||
vSyncCount: 0
|
||||
realtimeGICPUUsage: 25
|
||||
lodBias: 0.4
|
||||
maximumLODLevel: 0
|
||||
enableLODCrossFade: 1
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
@ -75,8 +93,18 @@ QualitySettings:
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
terrainQualityOverrides: 0
|
||||
terrainPixelError: 1
|
||||
terrainDetailDensityScale: 1
|
||||
terrainBasemapDistance: 1000
|
||||
terrainDetailDistance: 80
|
||||
terrainTreeDistance: 5000
|
||||
terrainBillboardStart: 50
|
||||
terrainFadeLength: 5
|
||||
terrainMaxTrees: 50
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
- serializedVersion: 3
|
||||
name: Medium
|
||||
pixelLightCount: 1
|
||||
shadows: 1
|
||||
@ -88,17 +116,21 @@ QualitySettings:
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 0
|
||||
blendWeights: 2
|
||||
textureQuality: 0
|
||||
skinWeights: 2
|
||||
globalTextureMipmapLimit: 0
|
||||
textureMipmapLimitSettings: []
|
||||
anisotropicTextures: 1
|
||||
antiAliasing: 0
|
||||
softParticles: 0
|
||||
softVegetation: 0
|
||||
realtimeReflectionProbes: 0
|
||||
billboardsFaceCameraPosition: 0
|
||||
useLegacyDetailDistribution: 1
|
||||
vSyncCount: 1
|
||||
realtimeGICPUUsage: 25
|
||||
lodBias: 0.7
|
||||
maximumLODLevel: 0
|
||||
enableLODCrossFade: 1
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
@ -110,8 +142,18 @@ QualitySettings:
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
terrainQualityOverrides: 0
|
||||
terrainPixelError: 1
|
||||
terrainDetailDensityScale: 1
|
||||
terrainBasemapDistance: 1000
|
||||
terrainDetailDistance: 80
|
||||
terrainTreeDistance: 5000
|
||||
terrainBillboardStart: 50
|
||||
terrainFadeLength: 5
|
||||
terrainMaxTrees: 50
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
- serializedVersion: 3
|
||||
name: High
|
||||
pixelLightCount: 2
|
||||
shadows: 2
|
||||
@ -123,17 +165,21 @@ QualitySettings:
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 1
|
||||
blendWeights: 2
|
||||
textureQuality: 0
|
||||
skinWeights: 2
|
||||
globalTextureMipmapLimit: 0
|
||||
textureMipmapLimitSettings: []
|
||||
anisotropicTextures: 1
|
||||
antiAliasing: 0
|
||||
softParticles: 0
|
||||
softVegetation: 1
|
||||
realtimeReflectionProbes: 1
|
||||
billboardsFaceCameraPosition: 1
|
||||
useLegacyDetailDistribution: 1
|
||||
vSyncCount: 1
|
||||
realtimeGICPUUsage: 50
|
||||
lodBias: 1
|
||||
maximumLODLevel: 0
|
||||
enableLODCrossFade: 1
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
@ -145,8 +191,18 @@ QualitySettings:
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
terrainQualityOverrides: 0
|
||||
terrainPixelError: 1
|
||||
terrainDetailDensityScale: 1
|
||||
terrainBasemapDistance: 1000
|
||||
terrainDetailDistance: 80
|
||||
terrainTreeDistance: 5000
|
||||
terrainBillboardStart: 50
|
||||
terrainFadeLength: 5
|
||||
terrainMaxTrees: 50
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
- serializedVersion: 3
|
||||
name: Very High
|
||||
pixelLightCount: 3
|
||||
shadows: 2
|
||||
@ -158,17 +214,21 @@ QualitySettings:
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 1
|
||||
blendWeights: 4
|
||||
textureQuality: 0
|
||||
skinWeights: 4
|
||||
globalTextureMipmapLimit: 0
|
||||
textureMipmapLimitSettings: []
|
||||
anisotropicTextures: 2
|
||||
antiAliasing: 2
|
||||
softParticles: 1
|
||||
softVegetation: 1
|
||||
realtimeReflectionProbes: 1
|
||||
billboardsFaceCameraPosition: 1
|
||||
useLegacyDetailDistribution: 1
|
||||
vSyncCount: 1
|
||||
realtimeGICPUUsage: 50
|
||||
lodBias: 1.5
|
||||
maximumLODLevel: 0
|
||||
enableLODCrossFade: 1
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
@ -180,8 +240,18 @@ QualitySettings:
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
terrainQualityOverrides: 0
|
||||
terrainPixelError: 1
|
||||
terrainDetailDensityScale: 1
|
||||
terrainBasemapDistance: 1000
|
||||
terrainDetailDistance: 80
|
||||
terrainTreeDistance: 5000
|
||||
terrainBillboardStart: 50
|
||||
terrainFadeLength: 5
|
||||
terrainMaxTrees: 50
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
- serializedVersion: 3
|
||||
name: Ultra
|
||||
pixelLightCount: 4
|
||||
shadows: 2
|
||||
@ -193,17 +263,21 @@ QualitySettings:
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 1
|
||||
blendWeights: 4
|
||||
textureQuality: 0
|
||||
skinWeights: 4
|
||||
globalTextureMipmapLimit: 0
|
||||
textureMipmapLimitSettings: []
|
||||
anisotropicTextures: 2
|
||||
antiAliasing: 2
|
||||
softParticles: 1
|
||||
softVegetation: 1
|
||||
realtimeReflectionProbes: 1
|
||||
billboardsFaceCameraPosition: 1
|
||||
vSyncCount: 1
|
||||
useLegacyDetailDistribution: 1
|
||||
vSyncCount: 0
|
||||
realtimeGICPUUsage: 100
|
||||
lodBias: 2
|
||||
maximumLODLevel: 0
|
||||
enableLODCrossFade: 1
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
@ -215,16 +289,28 @@ QualitySettings:
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
terrainQualityOverrides: 0
|
||||
terrainPixelError: 1
|
||||
terrainDetailDensityScale: 1
|
||||
terrainBasemapDistance: 1000
|
||||
terrainDetailDistance: 80
|
||||
terrainTreeDistance: 5000
|
||||
terrainBillboardStart: 50
|
||||
terrainFadeLength: 5
|
||||
terrainMaxTrees: 50
|
||||
excludedTargetPlatforms: []
|
||||
m_TextureMipmapLimitGroupNames: []
|
||||
m_PerPlatformDefaultQuality:
|
||||
Android: 2
|
||||
Lumin: 5
|
||||
GameCoreScarlett: 5
|
||||
GameCoreXboxOne: 5
|
||||
Lumin: 5
|
||||
Nintendo 3DS: 5
|
||||
Nintendo Switch: 5
|
||||
PS4: 5
|
||||
PS5: 5
|
||||
Server: 0
|
||||
Stadia: 5
|
||||
Standalone: 5
|
||||
WebGL: 3
|
||||
|
||||
Loading…
Reference in New Issue
Block a user