Compare commits

...

3 Commits

Author SHA1 Message Date
Lennart R.
b277bf44ed Changed Liting 2025-09-25 15:22:35 +02:00
Lennart R.
6c260999d0 Merge branch 'main' of https://git.timoeberl.de/Spielwiese/grass-rendering-prototype 2025-09-02 15:43:02 +02:00
Lennart R.
df1a14eb84 Terrain Tool Start 2025-09-02 15:42:46 +02:00
64 changed files with 323623 additions and 290040 deletions

View File

@ -20,12 +20,19 @@ Material:
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_LockedProperties: _Roughness
m_SavedProperties:
serializedVersion: 3
m_TexEnvs: []
m_Ints: []
m_Floats:
- _AOStrength: 2
- _BladeWidthTexStrength: 0.746
- _LOD: 0
m_Colors: []
- _NormalCurvature: 1
- _Roughness: 0
- _SSSStrength: 0.573
- _Translucency: 3.63
m_Colors:
- _TransitionRange: {r: 0, g: 5, b: 1, a: 1}
m_BuildTextureStacks: []

View File

@ -26,7 +26,14 @@ Material:
m_TexEnvs: []
m_Ints: []
m_Floats:
- _AOStrength: 1.605
- _AOStrength: 2
- _BladeWidth: 0.0062
- _BladeWidthTexStrength: 0.746
- _LOD: 1
m_Colors: []
- _NormalCurvature: 0.364
- _Roughness: 0
- _SSSStrength: 0.573
- _Translucency: 3.63
m_Colors:
- _TransitionRange: {r: 5, g: 10, b: 1, a: 1}
m_BuildTextureStacks: []

View File

@ -26,7 +26,14 @@ Material:
m_TexEnvs: []
m_Ints: []
m_Floats:
- _AOStrength: 1.21
- _AOStrength: 2
- _BladeWidth: 0.0057
- _BladeWidthTexStrength: 0.746
- _LOD: 2
m_Colors: []
- _NormalCurvature: 0.364
- _Roughness: 0
- _SSSStrength: 0.573
- _Translucency: 3.63
m_Colors:
- _TransitionRange: {r: 10, g: 20, b: 1, a: 1}
m_BuildTextureStacks: []

View File

@ -26,8 +26,14 @@ Material:
m_TexEnvs: []
m_Ints: []
m_Floats:
- _AOStrength: 1.004
- _BladeWidth: 0.0367
- _AOStrength: 2
- _BladeWidth: 0.0306
- _BladeWidthTexStrength: 0.746
- _LOD: 3
m_Colors: []
- _NormalCurvature: 0.364
- _Roughness: 0
- _SSSStrength: 0.573
- _Translucency: 3.63
m_Colors:
- _TransitionRange: {r: 20, g: 40, b: 1, a: 1}
m_BuildTextureStacks: []

View File

@ -29,7 +29,7 @@ Material:
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _FieldColor:
m_Texture: {fileID: 0}
m_Texture: {fileID: 2800000, guid: 9bb4e817f09d0ea4cbab03f772e01910, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _FrabVarianz:
@ -38,21 +38,22 @@ Material:
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AOStrength: 1.697
- _AOStrength: 1.34
- _BendStrength: 1
- _BladeBow: 0.195
- _BladeWidth: 0.0274
- _BladeWidthTexStrength: 0.74
- _BladeWidth: 0.004
- _BladeWidthTexStrength: 0.616
- _LOD: 0
- _Metallic: 0
- _Metallic: 0.876
- _NormalCurvature: 1
- _Roughness: 0
- _SSSStrength: 1
- _Translucency: 1.81
- _SSSStrength: 0.536
- _Translucency: 1.28
m_Colors:
- _Color0: {r: 0.5882353, g: 1, b: 0.5882353, a: 1}
- _Color1: {r: 1, g: 0.8209069, b: 0.495283, a: 1}
- _Color2: {r: 1, g: 0.49831352, b: 0.21226418, a: 1}
- _Color3: {r: 0.7075472, g: 0.15018693, b: 0.15018693, a: 1}
- _InnerColor: {r: 1, g: 1, b: 1, a: 1}
- _InnerColor: {r: 0.9825151, g: 1, b: 0.96540874, a: 1}
- _TransitionRange: {r: 0, g: 5, b: 1, a: 1}
m_BuildTextureStacks: []

View File

@ -0,0 +1,22 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1953259897 &8574412962073106934
TerrainLayer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: WhiteTerrain
m_DiffuseTexture: {fileID: 0}
m_NormalMapTexture: {fileID: 0}
m_MaskMapTexture: {fileID: 0}
m_TileSize: {x: 2, y: 2}
m_TileOffset: {x: 0, y: 0}
m_Specular: {r: 0, g: 0, b: 0, a: 0}
m_Metallic: 0
m_Smoothness: 0
m_NormalScale: 1
m_DiffuseRemapMin: {x: 0, y: 0, z: 0, w: 0}
m_DiffuseRemapMax: {x: 1, y: 1, z: 1, w: 1}
m_MaskMapRemapMin: {x: 0, y: 0, z: 0, w: 0}
m_MaskMapRemapMax: {x: 1, y: 1, z: 1, w: 1}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 87284c33199f505458f724bf36a6f632
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 8574412962073106934
userData:
assetBundleName:
assetBundleVariant:

View File

@ -96,9 +96,15 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 54ba144eac404724ab9ca2a3e30e101f, type: 3}
m_Name:
m_EditorClassIdentifier:
bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
extendedBounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
_materialLOD0: {fileID: 0}
_meshLOD0: {fileID: 0}
_enableShadowsLOD0: 0
_materialLOD1: {fileID: 0}
_meshLOD1: {fileID: 0}
_enableShadowsLOD1: 0
_materialLOD2: {fileID: 0}
_meshLOD2: {fileID: 0}
_enableShadowsLOD2: 0
_materialLOD3: {fileID: 0}
_meshLOD3: {fileID: 0}
_enableShadowsLOD3: 0

8
Assets/Resources.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 14795812dfe88754ba3b80578b66234b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,116 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &3308125864443600182
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7204760119229604174}
- component: {fileID: 360500368156439639}
- component: {fileID: 733336674874435875}
- component: {fileID: 1720812957132157552}
m_Layer: 0
m_Name: GrasChunk
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &7204760119229604174
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3308125864443600182}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &360500368156439639
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3308125864443600182}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5b944ea6fc62a9642b1d2d2bfa42d1cc, type: 3}
m_Name:
m_EditorClassIdentifier:
grasFeld: {fileID: 0}
pos: {x: 0, y: 0}
DebugGrasTextur: {fileID: 0}
hasChanged: 0
myLOD: 3
childChunks:
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
materials:
- {fileID: 2100000, guid: d979d9bbf3760d948a452ba192cbf563, type: 2}
- {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2}
- {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2}
- {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2}
LOD_a: {fileID: 0}
LOD_b: {fileID: 0}
doUpdate: 0
--- !u!23 &733336674874435875
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3308125864443600182}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 1cd7df4d77cf1ae40ad59a15c2769be9, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!33 &1720812957132157552
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3308125864443600182}
m_Mesh: {fileID: 0}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: fbbfb266ac87f62489e91578d9769aa8
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,47 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &8670885462079861701
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4388420835408116181}
- component: {fileID: 7677349766599539232}
m_Layer: 0
m_Name: GrasJob
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &4388420835408116181
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8670885462079861701}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 47.66464, y: -120.290794, z: 132.91965}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &7677349766599539232
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8670885462079861701}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ff1011c6afd7c2140a44b408bd527fec, type: 3}
m_Name:
m_EditorClassIdentifier:
jobName: temp

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ae88fa343d806fc4faa8eb193dec3a8c
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,46 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &8656756849993837837
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 296919738142889761}
- component: {fileID: 5859714832040713013}
m_Layer: 0
m_Name: GrasManagment
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &296919738142889761
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8656756849993837837}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &5859714832040713013
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8656756849993837837}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4c5815668e75c314cbc2e9448292cec0, type: 3}
m_Name:
m_EditorClassIdentifier:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f351e6e9d89d0fc499a4d50d418cf67a
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5269423ef0e116644a167e7abd7685d5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8d0d9d0fd3d72aa49ab04e9f2f1dbcb4
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 77f1f9f371b8bea45b590e6d9ef47708
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 112000000
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Scenes/TerrainTool/Lightmap-0_comp_dir.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,114 @@
fileFormatVersion: 2
guid: a3128563acd77ca44ad5e5e5fea23135
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 1
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 3
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 12
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Scenes/TerrainTool/Lightmap-0_comp_light.exr (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,114 @@
fileFormatVersion: 2
guid: 25fa794292ee5794e89349b38044c165
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 1
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 3
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 0
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 6
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Scenes/TerrainTool/ReflectionProbe-0.exr (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,114 @@
fileFormatVersion: 2
guid: 264dcb45b62fc6b4ba21e2229b7da2a1
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 1
seamlessCubemap: 1
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 2
aniso: 0
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 2
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Scenes/TerrainTool/ReflectionProbe-1.exr (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,114 @@
fileFormatVersion: 2
guid: fbb8e7eef0cc3fd4fb0b9da29d9ce6bd
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 1
seamlessCubemap: 1
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 2
aniso: 0
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 2
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -16,6 +16,7 @@
_NormalCurvature("Normal Curvature", Range(0,1)) = 0.3
_BladeWidthTexStrength("BladeWidthTexStrength", Range(0,1)) = 0.3
_InnerColor("Inner Color", Color) = (1,1,1,1)
_TransitionRange("Transition", Vector) = (1,1,1,1)
}
SubShader {
LOD 100

View File

@ -65,7 +65,7 @@ void geom(point v2g IN[1], inout TriangleStream<g2f> triStream) {
float halfWidth = _BladeWidth/2;
// randomly shrink blades that will be removed in the next LOD
if (IN[0].missingInNextLOD > 0.0) {
if (IN[0].missingInNextLOD > 0.1) {
float widthMultiplier = remap(N21(basePos.xz) * 0.75, 1, 1, 0, interpolator);
widthMultiplier = max(0, widthMultiplier);
halfWidth *= widthMultiplier;
@ -73,11 +73,13 @@ void geom(point v2g IN[1], inout TriangleStream<g2f> triStream) {
// randomly shrink shadow blades to create a smooth transition between shadowed and non-shadowed area
#ifdef IS_IN_SHADOW_PASS
/*
#if _LOD_LOD_1
float widthMultiplier = remap(N21(basePos.xz) * 0.5, 1, 1, 0, interpolator);
widthMultiplier = max(0, widthMultiplier);
halfWidth *= widthMultiplier;
#endif
*/
#endif
g2f o;
@ -181,12 +183,12 @@ void geom(point v2g IN[1], inout TriangleStream<g2f> triStream) {
#if _LOD_LOD_0
const float curvature = _NormalCurvature;
#elif _LOD_LOD_1
const float curvature = lerp(_NormalCurvature, 0.0, interpolator);
const float curvature = _NormalCurvature; //lerp(_NormalCurvature, 0.0, interpolator);
#else
const float curvature = 0.0;
#endif
float3 leftCurvedNormal = normalize(normalize(normal) + widthOffset * curvature);
float3 rightCurvedNormal = normalize(normalize(normal) - widthOffset * curvature);
float3 leftCurvedNormal = lerp(normalize(normal) , normalize(widthOffset), curvature / 3.0);
float3 rightCurvedNormal = lerp(normalize(normal) , normalize(-widthOffset), curvature / 3.0);
previousVertLeft = vertLeft;
previousVertRight = vertRight;
@ -251,6 +253,7 @@ float4 frag(g2f i, bool isFrontFace : SV_IsFrontFace) : SV_Target {
float4 skyData = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, worldRefl, 0);
float3 skyColor = DecodeHDR(skyData, unity_SpecCube0_HDR);
skyColor = min(float3(1, 1, 1), skyColor / 2);
float3 lightReflectDirection = reflect(-lightDirection, worldNormal);
float3 viewDirection = normalize(float3(float4(_MainCameraPosition.xyz, 1.0) - i.worldPos.xyz));
@ -259,11 +262,12 @@ float4 frag(g2f i, bool isFrontFace : SV_IsFrontFace) : SV_Target {
float3 subsurf = max(0.0, dot(lightReflectDirection, -viewDirection)) * _SSSStrength * _InnerColor;
const float shadow = max(.35, SHADOW_ATTENUATION(i));
float3 lightFinal = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, worldNormal, 2.0);
float3 lightFinal = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, worldNormal, 7.0);
lightFinal += translucency;
lightFinal += subsurf;
lightFinal *= shadow;
lightFinal = min(1.4, max(0.4, lightFinal));
// ATTENTION DO NOT TRY TO UNDERSTAND THE CODE BELOW (or you will go crazy)
float4 middleCol = min(1, abs(i.uv.x - 0.5) * 1);
@ -273,16 +277,17 @@ float4 frag(g2f i, bool isFrontFace : SV_IsFrontFace) : SV_Target {
float3 c2 = tex2Dlod(_FieldColor, float4(i.worldPos.xz / 3, 0, 3)).xyz;
float4 bladeWidthTex = tex2Dlod(_BladeWidthTex, float4(i.uv.x, 0, 0, 3));
float3 albedo = lerp(c1, c2, 0.4);
albedo = lerp(albedo, c0, _Metallic) * 0.7;
albedo *= 1 + _AOStrength;
albedo *= lerp(1, bladeWidthTex.x * 2.5, _BladeWidthTexStrength);
//albedo *= lerp(1, bladeWidthTex.x * 2.5, _BladeWidthTexStrength);
float3 color = float3(skyColor * shadow * .2 + lightFinal * albedo * col);
fixed3 color = fixed3(skyColor * shadow * 0.25 + lightFinal * albedo * col);
//float3 color = float3(skyColor * shadow * .2 + lightFinal * albedo * col);
float3 highlightedColor = lerp(color, float3(2.5, 0.7, 0.5), 0.5);
float3 finalTestColor = albedo.xyz ;
lightFinal = min(1.4, max(0.4, lightFinal));
return float4(color, 1);
#endif

8
Assets/Terrain.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fe2c628676a225141a2a9bb076a9e815
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 22543160dd7de804a8ba3abcfd7398ec
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 15600000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,22 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1953259897 &8574412962073106934
TerrainLayer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: NormalerLayer
m_DiffuseTexture: {fileID: 2800000, guid: 9bb4e817f09d0ea4cbab03f772e01910, type: 3}
m_NormalMapTexture: {fileID: 0}
m_MaskMapTexture: {fileID: 0}
m_TileSize: {x: 2, y: 2}
m_TileOffset: {x: 0, y: 0}
m_Specular: {r: 0, g: 0, b: 0, a: 0}
m_Metallic: 0
m_Smoothness: 0
m_NormalScale: 1
m_DiffuseRemapMin: {x: 0, y: 0, z: 0, w: 0}
m_DiffuseRemapMax: {x: 1, y: 1, z: 1, w: 1}
m_MaskMapRemapMin: {x: 0, y: 0, z: 0, w: 0}
m_MaskMapRemapMax: {x: 1, y: 1, z: 1, w: 1}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2451cadf6239f7b48a1dd0c8308694fb
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 8574412962073106934
userData:
assetBundleName:
assetBundleVariant:

8
Assets/TerrainTool.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ced67708815025d40b2356ff70d9a8e4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,393 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class ChunkGameObject : MonoBehaviour
{
static float basisChunkGroese = 5f;
Renderer meshRenderer;
MeshFilter meshFilter;
List<Vector3> verts = new List<Vector3>();
List<int> indes = new List<int>();
List<Vector4> tipOffsets_missingInNextLOD = new List<Vector4>();
GameObject GrasChunkPrefab;
public GrasFeld grasFeld;
public Vector2Int pos;
public Texture2D DebugGrasTextur;
public bool hasChanged = false;
public int myLOD = 0;
public ChunkGameObject[] childChunks = new ChunkGameObject[4];
[SerializeField] public List<Material> materials = new List<Material>();
public Mesh LOD_a;
public Mesh LOD_b;
public bool doUpdate = false;
private void OnEnable()
{
meshRenderer = GetComponent<Renderer>();
meshFilter = GetComponent<MeshFilter>();
return;
if (myLOD != 0 && transform.childCount == 4)
{
childChunks[0] = transform.GetChild(0).GetComponent<ChunkGameObject>();
childChunks[1] = transform.GetChild(1).GetComponent<ChunkGameObject>();
childChunks[2] = transform.GetChild(2).GetComponent<ChunkGameObject>();
childChunks[3] = transform.GetChild(3).GetComponent<ChunkGameObject>();
}
else
childChunks = null;
}
public void SetUpdate(Vector2Int chunkPos)
{
doUpdate = false;
if (ContainsChunk(chunkPos) == false)
return;
doUpdate = true;
if(myLOD > 0)
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
{
int childLodSize = (int)basisChunkGroese * (int)Mathf.Pow(2, myLOD - 1);
Vector2Int currentChildPos = new Vector2Int((int)transform.position.x + i * childLodSize,
(int)transform.position.z + j * childLodSize);
if (ContainsChunk(chunkPos, currentChildPos, myLOD - 1) == false)
continue;
var currenChild = childChunks[i * 2 + j];
if (currenChild == null)
{
if (GrasChunkPrefab == null)
GrasChunkPrefab = Resources.Load("GrasChunk") as GameObject;
GameObject tempGO = Instantiate(GrasChunkPrefab);
tempGO.transform.position = new Vector3(currentChildPos.x, 0, currentChildPos.y);
tempGO.transform.parent = transform;
tempGO.name = "Chunk LOD" + (myLOD - 1);
var chunkObject = tempGO.GetComponent<ChunkGameObject>();
chunkObject.myLOD = myLOD - 1;
chunkObject.grasFeld = this.grasFeld;
//chunkObject.SetPosToGrid();
childChunks[i * 2 + j] = chunkObject;
currenChild = chunkObject;
}
currenChild.SetUpdate(chunkPos);
}
}
public void SetLOD(Vector3 cameraPosition)
{
if (meshRenderer == null) meshRenderer = GetComponent<MeshRenderer>();
float LODSize = basisChunkGroese * Mathf.Pow(2f, myLOD);
Vector3 nearestPointToCamera = new Vector3(
Mathf.Min(transform.position.x + LODSize, Mathf.Max(transform.position.x, cameraPosition.x)),
Mathf.Min(transform.position.y + LODSize, Mathf.Max(transform.position.y, cameraPosition.y)),
Mathf.Min(transform.position.z + LODSize, Mathf.Max(transform.position.z, cameraPosition.z))
);
float distanceToNearestCameraPosition = Vector3.Distance(nearestPointToCamera, cameraPosition);
if(distanceToNearestCameraPosition < LODSize / 2f)
{
if (distanceToNearestCameraPosition < LODSize)
GetComponent<MeshFilter>().sharedMesh = LOD_a;
else
GetComponent<MeshFilter>().sharedMesh = LOD_b;
if (myLOD == 0)
{
meshRenderer.enabled = true;
return;
}
meshRenderer.enabled = false;
for (int i = 0; i < 4; i++)
{
if (childChunks[i] == null) continue;
childChunks[i].gameObject.SetActive(true);
childChunks[i].SetLOD(cameraPosition);
}
}
else
{
if(distanceToNearestCameraPosition < LODSize)
GetComponent<MeshFilter>().sharedMesh = LOD_a;
else
GetComponent<MeshFilter>().sharedMesh = LOD_b;
meshRenderer.enabled = true;
for (int i = 0; i < 4; i++)
{
if (childChunks[i] == null) continue;
childChunks[i].gameObject.SetActive(false);
}
}
}
public void DoMeshUpdate()
{
if (grasFeld == null) return;
if (doUpdate == false) return;
doUpdate = false;
verts.Clear();
indes.Clear();
tipOffsets_missingInNextLOD.Clear();
if (myLOD > 0)
{
for(int i = 0; i < 4; i++)
{
if (childChunks[i] != null)
childChunks[i].DoMeshUpdate();
}
//Das Gras der Kindobjekte in den aktuellen Chunk hinzufuegen
for (int i = 0; i < 4; i++)
{
if (childChunks[i] != null)
{
foreach (Vector3 v in childChunks[i].LOD_b.vertices)
{
verts.Add(v + childChunks[i].transform.position - transform.position);
}
List<Vector4> tempUvs = new List<Vector4>();
childChunks[i].LOD_b.GetUVs(0, tempUvs);
tipOffsets_missingInNextLOD.AddRange(tempUvs);
}
}
for (int i = 0; i < verts.Count - 1; i++)
{
indes.Add(i);
}
if (LOD_a == null) LOD_a = new Mesh();
LOD_a.Clear();
LOD_a.vertices = verts.ToArray();
LOD_a.SetUVs(0, tipOffsets_missingInNextLOD);
LOD_a.SetIndices(indes.ToArray(), MeshTopology.Points, 0);
LOD_a.RecalculateBounds();
GetComponent<MeshFilter>().sharedMesh = LOD_a;
GetComponent<MeshRenderer>().sharedMaterial = materials[myLOD];
//Die helfte des grases entfernen
int initCount = verts.Count / 2;
for (int i = 0; i < initCount; i++)
{
int randomIndex = Random.Range(0, verts.Count - 1);
verts.RemoveAt(randomIndex);
tipOffsets_missingInNextLOD.RemoveAt(randomIndex);
}
indes.Clear();
for (int i=0; i < verts.Count - 1; i++)
{
indes.Add(i);
}
if (LOD_b == null) LOD_b = new Mesh();
LOD_b.Clear();
LOD_b.vertices = verts.ToArray();
LOD_b.SetUVs(0, tipOffsets_missingInNextLOD);
LOD_b.SetIndices(indes.ToArray(), MeshTopology.Points, 0);
LOD_b.RecalculateBounds();
}
else
CreateMeshForLOD_0();
}
private void CreateMeshForLOD_0()
{
//TODO: Die anderen grassorten (nicht nur index 0) in den submeshes generieren
if (LOD_a == null) LOD_a = new Mesh();
LOD_a.Clear();
verts = new List<Vector3>();
indes = new List<int>();
tipOffsets_missingInNextLOD = new List<Vector4>();
float myLodSize = basisChunkGroese * Mathf.Pow(2, myLOD);
Vector2Int chunckPos = WorldToChunkPos(transform.position);
if (grasFeld.allChunckData.TryGetValue(chunckPos, out var value))
{
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
for(int x =0; x < 3; x++)
{
Vector3 targetCreatePos = new Vector3(i * (basisChunkGroese / 16f), 0, j * (basisChunkGroese / 16f)) + new Vector3(Random.Range(-1f, 1f), 0, Random.Range(-1f, 1f));
byte currenPixelValue = value.Data[i * 16 + j][0];
if (currenPixelValue == 0)
continue;
verts.Add(targetCreatePos);
tipOffsets_missingInNextLOD.Add(new Vector4(Random.Range(-1f, 1f), Random.Range(.7f, 1.4f), Random.Range(-1f, 1f), 0));
indes.Add(verts.Count - 1);
}
}
}
}
LOD_a.vertices = verts.ToArray();
LOD_a.SetIndices(indes.ToArray(), MeshTopology.Points, 0);
LOD_a.SetUVs(0, tipOffsets_missingInNextLOD);
LOD_a.RecalculateBounds();
GetComponent<MeshFilter>().sharedMesh = LOD_a;
GetComponent<MeshRenderer>().sharedMaterial = materials[0];
var otherUV = new List<Vector4>();
otherUV.AddRange(tipOffsets_missingInNextLOD);
int initCount = verts.Count / 2;
for (int i = 0; i < initCount; i++)
{
int randomIndex = Random.Range(0, verts.Count - 1);
verts.RemoveAt(randomIndex);
otherUV.RemoveAt(randomIndex);
tipOffsets_missingInNextLOD[randomIndex] += new Vector4(0,0,0,1f);
}
indes.Clear();
for (int i = 0; i < verts.Count - 1; i++)
{
indes.Add(i);
}
if (LOD_b == null) LOD_b = new Mesh();
LOD_b.vertices = verts.ToArray();
LOD_b.SetUVs(0, otherUV);
LOD_b.SetIndices(indes.ToArray(), MeshTopology.Points, 0);
LOD_b.RecalculateBounds();
}
private Vector2Int WorldToChunkPos(Vector3 pos)
{
return new Vector2Int(Mathf.FloorToInt(pos.x / (int)basisChunkGroese) * (int)basisChunkGroese, Mathf.FloorToInt(pos.z / (int)basisChunkGroese) * (int)basisChunkGroese);
}
private Vector2Int InChunkFromLocalPos(Vector3 pos)
{
return new Vector2Int(Mathf.FloorToInt(pos.x / basisChunkGroese) * 15, Mathf.FloorToInt(pos.z / basisChunkGroese) * 15);
}
public void SetPosToGrid()
{
float myChunkSize = basisChunkGroese * Mathf.Pow(2f, myLOD);
transform.position = new Vector3(Mathf.FloorToInt(transform.position.x / myChunkSize) * (int)myChunkSize
,0
,Mathf.FloorToInt(transform.position.z / myChunkSize) * (int)myChunkSize);
}
public bool ContainsChunk(Vector2Int chunkPos)
{
float myChunkSize = basisChunkGroese * Mathf.Pow(2f, myLOD);
Vector2Int gridChunkPos = new Vector2Int(Mathf.FloorToInt(chunkPos.x / myChunkSize) * (int)myChunkSize,
Mathf.FloorToInt(chunkPos.y / myChunkSize) * (int)myChunkSize);
Vector2Int myGridPos = new Vector2Int(Mathf.FloorToInt(transform.position.x / myChunkSize) * (int)myChunkSize,
Mathf.FloorToInt(transform.position.z / myChunkSize) * (int)myChunkSize);
if(myGridPos == gridChunkPos)
return true;
return false;
}
public bool ContainsChunk(Vector2Int chunkPos, Vector2Int pos, int lod)
{
float myChunkSize = basisChunkGroese * Mathf.Pow(2f, lod);
Vector2Int gridChunkPos = new Vector2Int(Mathf.FloorToInt(chunkPos.x / myChunkSize) * (int)myChunkSize,
Mathf.FloorToInt(chunkPos.y / myChunkSize) * (int)myChunkSize);
Vector2Int myGridPos = new Vector2Int(Mathf.FloorToInt(pos.x / myChunkSize) * (int)myChunkSize,
Mathf.FloorToInt(pos.y / myChunkSize) * (int)myChunkSize);
if (myGridPos == gridChunkPos)
return true;
return false;
}
private void OnDrawGizmos()
{
return;
Vector2Int chukPosInt = WorldToChunkPos(transform.position);
if(false)
for (int i = 0; i < 16; i++)
for (int j = 0; j < 16; j++)
{
if(grasFeld.allChunckData != null && grasFeld.allChunckData.TryGetValue(chukPosInt, out var t))
{
byte b = t.Data[i * 16 + j][0];
Gizmos.color = new Color(b, b, b);
Gizmos.DrawCube(transform.position + new Vector3(i, 0, j) * (basisChunkGroese / 16f), Vector3.one * 0.1f);
}
}
#if UNITY_EDITOR
if(false)
{
Vector3 cameraPosition = SceneView.currentDrawingSceneView.camera.transform.position;
float LODSize = basisChunkGroese * Mathf.Pow(2f, myLOD);
Vector3 nearestPointToCamera = new Vector3(
Mathf.Min(transform.position.x + LODSize, Mathf.Max(transform.position.x, cameraPosition.x)),
Mathf.Min(transform.position.y + LODSize, Mathf.Max(transform.position.y, cameraPosition.y)),
Mathf.Min(transform.position.z + LODSize, Mathf.Max(transform.position.z, cameraPosition.z))
);
Gizmos.color = Color.red;
Gizmos.DrawCube(nearestPointToCamera, Vector3.one);
}
#endif
//if (myLOD != 0)
// return;
float size = basisChunkGroese * Mathf.Pow(2, myLOD);
Gizmos.color = Color.yellow;
Gizmos.DrawWireCube(transform.position + Vector3.one * size / 2f, Vector3.one * size);
if(Vector3.Distance(transform.position, Camera.current.transform.position) < 40)
if(DebugGrasTextur != null)
for(int i = 0; i < 16; i++)
for(int j = 0; j < 16; j++)
{
var pixelColor = DebugGrasTextur.GetPixel(i, j);
Gizmos.color = pixelColor;
Gizmos.DrawCube(transform.position + new Vector3(i, 0, j) * (1f / 16f) * basisChunkGroese - new Vector3(4.75f, 0, 4.75f), Vector3.one * (1f / 16f));
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5b944ea6fc62a9642b1d2d2bfa42d1cc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,330 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Unity.Burst.CompilerServices;
using Unity.Collections;
using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;
public class GrasFeld : MonoBehaviour
{
float grasDichteProMeter = 1.6f;
static float basisChunkGroese = 5f;
public GameObject GrasChunkPrefab;
public Dictionary<Vector2Int, ChunkData> allChunckData;
List<Vector2Int> ChunksModifyed = new List<Vector2Int>();
List<Vector2Int> ActiveChunks;
public List<ChunkGameObject> AlleChunkObjekte = new List<ChunkGameObject>();
#if UNITY_EDITOR
void OnEnable()
{
AssemblyReloadEvents.beforeAssemblyReload += OnBeforeAssemblyReload;
AssemblyReloadEvents.afterAssemblyReload += OnAfterAssemblyReload;
}
void OnDisable()
{
AssemblyReloadEvents.beforeAssemblyReload -= OnBeforeAssemblyReload;
AssemblyReloadEvents.afterAssemblyReload -= OnAfterAssemblyReload;
}
public void OnBeforeAssemblyReload()
{
ClearAllChunkData();
}
public void ClearAllChunkData()
{
if (allChunckData == null) return;
var enumerator = allChunckData.GetEnumerator();
while (enumerator.MoveNext())
{
var pair = enumerator.Current;
pair.Value.Data.Dispose();
}
allChunckData.Clear();
}
#endif
public void OnAfterAssemblyReload()
{
}
private void Update()
{
Vector3 cameraPosition = Camera.main.transform.position;
foreach (var chunk in AlleChunkObjekte)
{
chunk.SetLOD(cameraPosition);
}
}
public void GrasZeichnen(GrassortenScriptableObject sorte, Vector2 pos, float pinselRadius, bool zeichenInverter)
{
if (allChunckData == null) allChunckData = new Dictionary<Vector2Int, ChunkData>();
List<ChunkData> zuÄnderndeChunks = new List<ChunkData>();
//Alle chuncks finden in die Gezeichnet werden könnte
ActiveChunks = GetActiveChunckPositions(pinselRadius, pos);
foreach (var potential in ActiveChunks)
{
if(allChunckData.TryGetValue(potential, out var chunckData))
{
zuÄnderndeChunks.Add(chunckData);
}
else
{
allChunckData.Add(potential, new ChunkData(potential));
if (allChunckData.TryGetValue(potential, out chunckData))
zuÄnderndeChunks.Add(chunckData);
else
Debug.LogError("Konnte Chunk nich adden " + potential);
}
}
ChunksModifyed.Clear();
foreach(ChunkData chunk in zuÄnderndeChunks)
{
allChunckData[chunk.pos] = ZeichneInChunk(chunk, sorte, pos, pinselRadius, zeichenInverter);
ChunksModifyed.Add(chunk.pos);
if (allChunckData[chunk.pos].isEmpty == true)
{
allChunckData[chunk.pos].Data.Dispose();
allChunckData.Remove(chunk.pos);
}
}
MakeChunks();
}
public void MakeChunks()
{
List<ChunkGameObject> ChunkObjectsToRecalculate = new List<ChunkGameObject>();
foreach(Vector2Int chunkPos in ChunksModifyed)
{
ChunkGameObject chunkObject;
foreach (ChunkGameObject currenChunckObject in AlleChunkObjekte)
{
if (currenChunckObject.ContainsChunk(chunkPos))
{
chunkObject = currenChunckObject;
goto ChunkExistiert;
}
}
//Kein Chunk gefunden
GameObject tempGO = Instantiate(GrasChunkPrefab);
tempGO.transform.position = new Vector3(chunkPos.x, 0, chunkPos.y);
tempGO.transform.parent = transform;
tempGO.name = "Chunk LOD3";
chunkObject = tempGO.GetComponent<ChunkGameObject>();
chunkObject.SetPosToGrid();
chunkObject.grasFeld = this;
AlleChunkObjekte.Add(chunkObject);
ChunkExistiert:
chunkObject.SetUpdate(chunkPos);
if(ChunkObjectsToRecalculate.Contains(chunkObject) == false)
ChunkObjectsToRecalculate.Add(chunkObject);
}
foreach(var chunkObj in ChunkObjectsToRecalculate)
{
chunkObj.DoMeshUpdate();
}
return;
int count = 0;
while (transform.childCount > count)
{
var checkPos = transform.GetChild(count).gameObject.GetComponent<ChunkGameObject>().pos;
if (ChunksModifyed.Contains(checkPos))
{
DestroyImmediate(transform.GetChild(count).gameObject);
}
else
count++;
}
foreach (var chunk in allChunckData)
{
if (ChunksModifyed.Contains(chunk.Key) == false)
continue;
Texture2D tempTextur = new Texture2D(16,16);
for (int i = 0; i < 16; i++)
for (int j = 0; j < 16; j++)
{
tempTextur.SetPixel(i, j, new Color(chunk.Value.Data[i * 16 + j][0] * 256, 0, 0));
}
tempTextur.Apply();
GameObject chunkObject = Instantiate(GrasChunkPrefab);
chunkObject.transform.position = new Vector3(chunk.Key.x, 0, chunk.Key.y);
chunkObject.transform.parent = transform;
chunkObject.GetComponent<ChunkGameObject>().DebugGrasTextur = tempTextur;
chunkObject.GetComponent<ChunkGameObject>().pos = chunk.Key;
chunkObject.GetComponent<ChunkGameObject>().hasChanged = ChunksModifyed.Contains(chunk.Key);
chunkObject.name = "" + chunk.Key;
}
ChunksModifyed.Clear();
}
static ChunkData ZeichneInChunk(ChunkData chunk, GrassortenScriptableObject grassorte, Vector2 pos, float brushSize, bool shift)
{
int grassortenIndex = -1;
if (chunk.VerwendeteGrassorten.Contains(grassorte.grassorteId) == false)
chunk.VerwendeteGrassorten.Add(grassorte.grassorteId);
grassortenIndex = chunk.VerwendeteGrassorten.IndexOf(grassorte.grassorteId);
int emptyCount = 0;
for(int i = 0; i < 16; i++)
for(int j = 0; j < 16; j++)
{
var currentValue = chunk.Data[i * 16 + j];
byte val = currentValue[grassortenIndex];
Vector2 inchunckPos = new Vector2(chunk.pos.x + i * (basisChunkGroese / 16f), chunk.pos.y + j * (basisChunkGroese / 16f));
if (Vector2.Distance(inchunckPos, pos) < brushSize)
val = shift ? (byte)0 : (byte)255;
currentValue[grassortenIndex] = val;
if (currentValue[grassortenIndex] == 0)
emptyCount++;
chunk.Data[i * 16 + j] = currentValue;
}
if (emptyCount == (16 * 16))
chunk.isEmpty = true;
return chunk;
}
List<Vector2Int> GetActiveChunckPositions(float brushRadius, Vector2 brushPos)
{
List<Vector2Int> activeChuncksTemp = new List<Vector2Int>();
int minPosX = Mathf.FloorToInt((brushPos.x - brushRadius) / basisChunkGroese) * (int)basisChunkGroese;
int minPosY = Mathf.FloorToInt((brushPos.y - brushRadius) / basisChunkGroese) * (int)basisChunkGroese;
int maxPosX = Mathf.CeilToInt((brushPos.x + brushRadius) / basisChunkGroese) * (int)basisChunkGroese;
int maxPosY = Mathf.CeilToInt((brushPos.y + brushRadius) / basisChunkGroese) * (int)basisChunkGroese;
for (int x = minPosX; x < maxPosX; x += (int)basisChunkGroese)
{
for (int y = minPosY; y < maxPosY; y += (int)basisChunkGroese)
{
Vector2Int chunckPos = new Vector2Int(x, y);
if (chunckPos.x < 0 || chunckPos.x > 1000 || chunckPos.y < 0 || chunckPos.y > 1000)
continue;
if (IsChunckInRadius(brushPos, brushRadius, chunckPos, basisChunkGroese))
activeChuncksTemp.Add(chunckPos);
}
}
return activeChuncksTemp;
}
static bool IsChunckInRadius(Vector2 pos, float radius, Vector2Int chunckPos, float chunckSize)
{
// Find the closest point to the circle within the rectangle
Vector2 closestPosInChunck = new Vector2(Mathf.Clamp(pos.x, chunckPos.x, chunckPos.x + chunckSize), Mathf.Clamp(pos.y, chunckPos.y, chunckPos.y + chunckSize));
// Calculate the distance between the circle's center and this closest point
Vector2 brushToPoint = pos - closestPosInChunck;
return brushToPoint.sqrMagnitude < radius * radius;
}
#if UNITY_EDITOR
private void OnDrawGizmos()
{
if (Application.isEditor)
{
Vector3 cameraPosition = SceneView.lastActiveSceneView.camera.transform.position;
foreach (var chunk in AlleChunkObjekte)
{
chunk.SetLOD(cameraPosition);
}
}
if(false)
if (ActiveChunks != null)
foreach(var p in ActiveChunks)
{
Gizmos.DrawWireCube(new Vector3(p.x + basisChunkGroese / 2f, 0, p.y + basisChunkGroese / 2f), Vector3.one * basisChunkGroese);
}
}
#endif
}
public struct ChunkData
{
public bool isEmpty;
public Vector2Int pos;
public NativeArray<ChunkPixel> Data;
public FixedList32Bytes<int> VerwendeteGrassorten;
public ChunkData(Vector2Int pos)
{
isEmpty = false;
this.pos = pos;
Data = new NativeArray<ChunkPixel>(256, Allocator.Persistent);
VerwendeteGrassorten = new FixedList32Bytes<int>();
}
}
public struct ChunkPixel
{
byte p1, p2, p3, p4;
public byte this[int index]
{
get => index switch
{
0 => p1,
1 => p2,
2 => p3,
3 => p4,
_ => throw new IndexOutOfRangeException()
};
set => _ = index switch
{
0 => (p1 = value),
1 => (p2 = value),
2 => (p3 = value),
3 => (p4 = value),
_ => throw new IndexOutOfRangeException()
};
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: eccbd1cc5d63017499b308512134fd27
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,27 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GrasField2 : MonoBehaviour
{
Texture2D GrasFieldTexture;
// Start is called before the first frame update
void OnEnable()
{
GrasFieldTexture = new Texture2D(16, 16, TextureFormat.Alpha8, false);
}
void PaintOnGrasField(Vector2 pos)
{
}
// Update is called once per frame
void Update()
{
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fd6d3eb680e03db408d96fc00b1064d9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,45 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class GrasFieldManager : MonoBehaviour
{
public List<GrasFeld> alleFelder;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void UpdateChunks()
{
transform.GetChild(0).GetComponent<GrasFeld>().MakeChunks();
}
public void BrushGras(Terrain terrain, GrassortenScriptableObject grassorte, Vector2 pos, float radius, bool shift)
{
if (alleFelder.Count > 0) alleFelder[0].GrasZeichnen(grassorte, pos * new Vector2(terrain.terrainData.size.x, terrain.terrainData.size.z), radius, shift);
}
#if UNITY_EDITOR
public void ClearChunks()
{
while (transform.GetChild(0).childCount > 0)
{
transform.GetChild(0).GetComponent<GrasFeld>().ClearAllChunkData();
transform.GetChild(0).GetComponent<GrasFeld>().AlleChunkObjekte.Clear();
DestroyImmediate(transform.GetChild(0).GetChild(0).gameObject);
}
}
#endif
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4c5815668e75c314cbc2e9448292cec0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1c3c5cc8e2791fd48a09487cb7007e5a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,30 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f565c9ea2c3a9de4e93d55a25bfa14a0, type: 3}
m_Name: GrassSorte
m_EditorClassIdentifier:
sortenName: Normal
grassorteId: 0
material: {fileID: 2100000, guid: 1cd7df4d77cf1ae40ad59a15c2769be9, type: 2}
lod_Stufen:
- material: {fileID: 2100000, guid: d979d9bbf3760d948a452ba192cbf563, type: 2}
start: 0
end: 5
- material: {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2}
start: 5
end: 15
- material: {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2}
start: 15
end: 30
- material: {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2}
start: 30
end: 10000

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7b8cfc9b5904f4044adb2693c4dfbaab
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,18 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f565c9ea2c3a9de4e93d55a25bfa14a0, type: 3}
m_Name: NeueSorte2
m_EditorClassIdentifier:
sortenName:
grassorteId: 1
material: {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2}
lod_Stufen: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 60e9ec60c0268e54586c60be04ed1b13
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 28692abf71f2c1740b57c1abf821ba9d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,77 @@
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
[CreateAssetMenu(fileName = "GrassSorte", menuName = "Grassystem/Grassorte", order = 1)]
public class GrassortenScriptableObject : ScriptableObject
{
public string sortenName;
public int grassorteId;
public Material material;
public List<LOD_Stufe> lod_Stufen;
private void Awake()
{
GeneratePreviewMesh();
}
public static Mesh GeneratePreviewMesh()
{
List<Vector3> verts = new List<Vector3>();
List<int> indes = new List<int>();
List<Vector4> tipPosAndLODVanish = new List<Vector4>();
Mesh mesh = new Mesh();
for(int i=0; i < 100; i++)
{
Vector3 vertexPos = new Vector3(Random.Range(-1f, 1f), 0, Random.Range(-1f, 1f));
verts.Add(vertexPos);
indes.Add(i);
tipPosAndLODVanish.Add(new Vector4(Random.Range(-1f, 1f), 1f, Random.Range(-1f, 1f), 0));
}
mesh.SetVertices(verts);
mesh.SetUVs(0, tipPosAndLODVanish);
mesh.SetIndices(indes.ToArray(), MeshTopology.Points, 0);
mesh.name = "Tubnailmesh";
return mesh;
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(GrassortenScriptableObject))]
public class GrassortenScriptableObjectEditor : Editor
{
public override Texture2D RenderStaticPreview(string assetPath, Object[] subAssets, int width, int height)
{
PreviewRenderUtility previewUtility;
GrassortenScriptableObject grassorte = (GrassortenScriptableObject)target;
Mesh mesh = GrassortenScriptableObject.GeneratePreviewMesh();
previewUtility = new PreviewRenderUtility();
previewUtility.DrawMesh(mesh, Matrix4x4.identity, grassorte.material, 0);
// Camera Settings
previewUtility.camera.transform.position = new Vector3(0f, 1f, -3f);
previewUtility.camera.transform.eulerAngles = new Vector3(12f, 0f, 0f);
previewUtility.camera.nearClipPlane = 0.01f;
previewUtility.camera.farClipPlane = 20f;
Rect rect = new Rect(0, 0, width, height);
previewUtility.BeginStaticPreview(rect);
previewUtility.Render();
var returnTexture = previewUtility.EndStaticPreview();
previewUtility.Cleanup();
DestroyImmediate(mesh);
return returnTexture;
}
}
#endif

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f565c9ea2c3a9de4e93d55a25bfa14a0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
using UnityEngine;
[System.Serializable]
public class LOD_Stufe
{
[SerializeField] public Material material;
[SerializeField] public float start = 0;
[SerializeField] public float end = 1f;
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ab965b102a71a4342a7aee8e2f3e8849
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4565c16a3fdb2894b9c2744e1b62356d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,37 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Collections;
[ExecuteInEditMode]
public class GrasJob : MonoBehaviour
{
public string jobName = "temp";
public Dictionary<ChunkIndexer, ChunkGameObject> test;
GameObject chunkPrefab;
// Start is called before the first frame update
void OnEnable()
{
chunkPrefab = (GameObject)Resources.Load("Assets/Resources/GrasChunk.prefab");
gameObject.name = jobName;
}
void UpdateAllChunks()
{
}
}
public struct ChunkIndexer
{
Vector2Int chunkPos;
GrassortenScriptableObject grasSorte;
public ChunkIndexer(Vector2Int pos, GrassortenScriptableObject sorte)
{
chunkPos = pos;
grasSorte = sorte;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ff1011c6afd7c2140a44b408bd527fec
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,184 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.TerrainTools;
namespace UnityEditor.TerrainTools
{
#if UNITY_EDITOR
public class MyTerrainToolTest : TerrainPaintTool<MyTerrainToolTest>
{
public GrasField2 grassField;
public GrasFieldManager grasFieldManager;
//Grassorten
bool grassortenSichtbar = false;
public List<GrassortenScriptableObject> grassorten;
public GrassortenScriptableObject aktuelleGrassorte;
public int aktuelleGrassorteInt = 0;
public bool isInChunckSelectorMode = false;
override public void OnEnable()
{
AssemblyReloadEvents.beforeAssemblyReload += OnBeforeAssemblyReload;
AssemblyReloadEvents.afterAssemblyReload += OnAfterAssemblyReload;
}
override public void OnDisable()
{
AssemblyReloadEvents.beforeAssemblyReload -= OnBeforeAssemblyReload;
AssemblyReloadEvents.afterAssemblyReload -= OnAfterAssemblyReload;
}
public override string GetName()
{
return "Grass Paint Tool";
}
public override string GetDescription()
{
return "Left click to raise.\n\nHold shift and left click to lower.";
}
public override void OnRenderBrushPreview(Terrain terrain, IOnSceneGUI editContext)
{
//if (isInChunckSelectorMode) return;
TerrainPaintUtilityEditor.ShowDefaultPreviewBrush(terrain, editContext.brushTexture, editContext.brushSize);
}
public override bool OnPaint(Terrain terrain, IOnPaint editContext)
{
Material mat = TerrainPaintUtility.GetBuiltinPaintMaterial();
if (grasFieldManager == null)
return false;
//Normalen Paint Context callen, weil sonst der brush in die Textur gezeichnet wird
float rotationDegrees = 0.0f;
BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, editContext.brushSize, rotationDegrees);
PaintContext paintContext = TerrainPaintUtility.BeginPaintTexture(terrain, brushXform.GetBrushXYBounds(), terrain.terrainData.terrainLayers[0]);
grasFieldManager.BrushGras(terrain, aktuelleGrassorte, editContext.uv, editContext.brushSize / 2f, Event.current.shift);
//grassField.brushGrass(Event.current.shift, editContext.uv * new Vector2(terrain.terrainData.size.x, terrain.terrainData.size.z), editContext.brushSize);
//Der Context wird immer released, weil wir in der anderen Funtion das malen übernemen
TerrainPaintUtility.ReleaseContextResources(paintContext);
return false;
}
public void OnBeforeAssemblyReload()
{
//if(grassField != null) grassField.SaveChuncks();
}
public void OnAfterAssemblyReload()
{
}
public override void OnSceneGUI(Terrain terrain, IOnSceneGUI editContext)
{
base.OnSceneGUI(terrain, editContext);
if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && grassField != null)
{
//grassField.ClearActiveChuncks();
//grassField.UpdateChuncks();
//grassField.SaveChuncks();
}
}
public override void OnInspectorGUI(Terrain terrain, IOnInspectorGUI editContext)
{
base.OnInspectorGUI(terrain, editContext);
editContext.ShowBrushesGUI(1, BrushGUIEditFlags.All);
if (grasFieldManager == null)
{
GameObject grasManagerObject = GameObject.Find("GrasManagment");
if (grasManagerObject == null)
{
Debug.LogError("Kein GrasMangager Gefunden");
GameObject grasMangerPrefab = (GameObject)Resources.Load("GrasManagment");
grasManagerObject = Instantiate(grasMangerPrefab);
grasManagerObject.name = "GrasManagment";
Debug.Log("Neuer Gras Manager Gespawned");
}
grasFieldManager = grasManagerObject.GetComponent<GrasFieldManager>();
}
GrassortenAuswahlZeichnen();
if (GUILayout.Button("UpdateGras"))
{
AssetDatabase.Refresh();
if (grasFieldManager != null)
{
grasFieldManager.UpdateChunks();
}
}
if (GUILayout.Button("Clear Grass Chuncks"))
{
AssetDatabase.Refresh();
if(grasFieldManager != null)
{
grasFieldManager.ClearChunks();
}
}
}
private void GrassortenAuswahlZeichnen()
{
bool warenDieSortenSichtbar = grassortenSichtbar;
grassortenSichtbar = EditorGUILayout.BeginFoldoutHeaderGroup(grassortenSichtbar, "Grassorten");
if (warenDieSortenSichtbar == false && grassortenSichtbar == true)
{
if (grassorten == null) grassorten = new List<GrassortenScriptableObject>();
grassorten.Clear();
var allAssets = AssetDatabase.FindAssets($"t:{typeof(GrassortenScriptableObject).Name}").ToList().Select(AssetDatabase.GUIDToAssetPath);
foreach (var asset in allAssets)
{
grassorten.Add(AssetDatabase.LoadAssetAtPath<GrassortenScriptableObject>(asset));
}
}
if (grassortenSichtbar)
{
var grassortenNamen = new List<string>();
var grassTubnails = new List<Texture2D>();
foreach (var sorte in grassorten)
{
grassortenNamen.Add(sorte.name);
grassTubnails.Add(AssetPreview.GetAssetPreview(sorte));
}
int alteSorte = aktuelleGrassorteInt;
aktuelleGrassorteInt = GUILayout.SelectionGrid(aktuelleGrassorteInt, grassTubnails.ToArray(), 4);
if (aktuelleGrassorteInt != alteSorte)
aktuelleGrassorte = grassorten[aktuelleGrassorteInt];
}
EditorGUILayout.EndFoldoutHeaderGroup();
}
}
#endif
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 42c4a81b0837ac141a3ced23b6ac0cc0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,6 +1,7 @@
{
"dependencies": {
"com.unity.collab-proxy": "2.7.1",
"com.unity.collections": "2.5.7",
"com.unity.feature.development": "1.0.1",
"com.unity.textmeshpro": "3.0.7",
"com.unity.timeline": "1.7.7",

View File

@ -1,5 +1,15 @@
{
"dependencies": {
"com.unity.burst": {
"version": "1.8.21",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.mathematics": "1.2.1",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.collab-proxy": {
"version": "2.7.1",
"depth": 0,
@ -7,6 +17,19 @@
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.collections": {
"version": "2.5.7",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.burst": "1.8.19",
"com.unity.mathematics": "1.3.2",
"com.unity.test-framework": "1.4.6",
"com.unity.nuget.mono-cecil": "1.11.5",
"com.unity.test-framework.performance": "3.0.3"
},
"url": "https://packages.unity.com"
},
"com.unity.editorcoroutines": {
"version": "1.0.0",
"depth": 1,
@ -15,7 +38,7 @@
"url": "https://packages.unity.com"
},
"com.unity.ext.nunit": {
"version": "1.0.6",
"version": "2.0.3",
"depth": 2,
"source": "registry",
"dependencies": {},
@ -60,6 +83,20 @@
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.mathematics": {
"version": "1.3.2",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.nuget.mono-cecil": {
"version": "1.11.5",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.performance.profile-analyzer": {
"version": "1.2.3",
"depth": 1,
@ -91,16 +128,26 @@
"url": "https://packages.unity.com"
},
"com.unity.test-framework": {
"version": "1.1.33",
"version": "1.4.6",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.ext.nunit": "1.0.6",
"com.unity.ext.nunit": "2.0.3",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.test-framework.performance": {
"version": "3.0.3",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.31",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.testtools.codecoverage": {
"version": "1.2.6",
"depth": 1,

View File

@ -4,5 +4,8 @@
EditorBuildSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Scenes: []
m_Scenes:
- enabled: 1
path: Assets/Scenes/TerrainTool.unity
guid: 8d0d9d0fd3d72aa49ab04e9f2f1dbcb4
m_configObjects: {}

View File

@ -77,6 +77,7 @@ PlayerSettings:
androidMinimumWindowHeight: 300
androidFullscreenMode: 1
androidAutoRotationBehavior: 1
androidPredictiveBackSupport: 1
defaultIsNativeResolution: 1
macRetinaSupport: 1
runInBackground: 1
@ -84,6 +85,7 @@ PlayerSettings:
muteOtherAudioSources: 0
Prepare IOS For Recording: 0
Force IOS Speakers When Recording: 0
audioSpatialExperience: 0
deferSystemGesturesMode: 0
hideHomeButton: 0
submitAnalytics: 1
@ -185,8 +187,10 @@ PlayerSettings:
strictShaderVariantMatching: 0
VertexChannelCompressionMask: 4054
iPhoneSdkVersion: 988
iOSSimulatorArchitecture: 0
iOSTargetOSVersionString: 12.0
tvOSSdkVersion: 0
tvOSSimulatorArchitecture: 0
tvOSRequireExtendedGameController: 0
tvOSTargetOSVersionString: 12.0
VisionOSSdkVersion: 0
@ -541,6 +545,7 @@ PlayerSettings:
switchSocketBufferEfficiency: 4
switchSocketInitializeEnabled: 1
switchNetworkInterfaceManagerInitializeEnabled: 1
switchDisableHTCSPlayerConnection: 0
switchUseNewStyleFilepaths: 1
switchUseLegacyFmodPriorities: 0
switchUseMicroSleepForYield: 1