From 6152e1fc1a61226beefa9c103558d0322651cc1f Mon Sep 17 00:00:00 2001 From: Timo Eberl Date: Thu, 28 Aug 2025 14:26:50 +0200 Subject: [PATCH 1/8] remove .vsconfig and put it in gitignore --- .gitignore | 1 + .vsconfig | 6 ------ 2 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 .vsconfig diff --git a/.gitignore b/.gitignore index 0f922d1..09d5506 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Custom additions .vscode/ +.vsconfig .idea/ # This .gitignore file should be placed at the root of your Unity project directory diff --git a/.vsconfig b/.vsconfig deleted file mode 100644 index f019fd0..0000000 --- a/.vsconfig +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": "1.0", - "components": [ - "Microsoft.VisualStudio.Workload.ManagedGame" - ] -} From d6c00482715017d2a915105ef91c23395d8ea168 Mon Sep 17 00:00:00 2001 From: Timo Eberl Date: Thu, 28 Aug 2025 17:27:00 +0200 Subject: [PATCH 2/8] Update LODs in Editor --- Assets/Scenes/SampleScene.unity | 22 ++++- Assets/Scripts/GrassField.cs | 98 ++++++++----------- .../Scripts/MainCameraPositionShaderSetter.cs | 17 ++++ .../MainCameraPositionShaderSetter.cs.meta | 11 +++ Assets/Shaders/include/GrassBladePass.hlsl | 27 +++-- 5 files changed, 96 insertions(+), 79 deletions(-) create mode 100644 Assets/Scripts/MainCameraPositionShaderSetter.cs create mode 100644 Assets/Scripts/MainCameraPositionShaderSetter.cs.meta diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index 071391c..3a489f0 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -140790,6 +140790,7 @@ GameObject: - component: {fileID: 963194227} - component: {fileID: 963194226} - component: {fileID: 963194229} + - component: {fileID: 963194230} m_Layer: 0 m_Name: Main Camera m_TagString: MainCamera @@ -140864,14 +140865,26 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 963194225} serializedVersion: 2 - m_LocalRotation: {x: 0.23506844, y: 0.3851214, z: -0.1021131, w: 0.8865649} - m_LocalPosition: {x: 6.34, y: 2.02, z: 3.8} + m_LocalRotation: {x: 0.23339066, y: 0.37273654, z: -0.097438015, w: 0.8928058} + m_LocalPosition: {x: 6.6, y: 3.5, z: 4.2} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_LocalEulerAnglesHint: {x: 29.7, y: 46.96, z: 0} + m_LocalEulerAnglesHint: {x: 29.3, y: 45.32, z: 0} --- !u!114 &963194229 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 78c9485abe801d74184e00172d4b42c4, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &963194230 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -140880,7 +140893,7 @@ MonoBehaviour: m_GameObject: {fileID: 963194225} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 78c9485abe801d74184e00172d4b42c4, type: 3} + m_Script: {fileID: 11500000, guid: d9be733811a3b0342953552aa8d5ab8a, type: 3} m_Name: m_EditorClassIdentifier: --- !u!43 &963631122 @@ -290519,7 +290532,6 @@ MonoBehaviour: numChunks: 20 bladesPerSquareMeter: 100 chunkPrefab: {fileID: 6414307754184109852, guid: abb47bb4e9622f7428302dfa4730d722, type: 3} - ignoreHeightForLOD: 0 grassMaterialLOD0: {fileID: 2100000, guid: d979d9bbf3760d948a452ba192cbf563, type: 2} minDistanceLOD0: 3.5 densityLOD0: 1 diff --git a/Assets/Scripts/GrassField.cs b/Assets/Scripts/GrassField.cs index 0dc2cc4..b057a5b 100644 --- a/Assets/Scripts/GrassField.cs +++ b/Assets/Scripts/GrassField.cs @@ -1,37 +1,30 @@ using System; using System.Collections.Generic; using UnityEngine; -using UnityEngine.Serialization; public class GrassField : MonoBehaviour { public int size = 100; public int numChunks = 20; public int bladesPerSquareMeter = 100; public GrassChunk chunkPrefab; - public bool ignoreHeightForLOD = true; - [Header("LOD 0")] - public Material grassMaterialLOD0; + [Header("LOD 0")] public Material grassMaterialLOD0; public float minDistanceLOD0 = 2f; [Range(0f, 1f)] public float densityLOD0 = 1f; public bool enableShadowsLOD0 = true; - [Header("LOD 1")] - public float distanceLOD1 = 5f; + [Header("LOD 1")] public float distanceLOD1 = 5f; public Material grassMaterialLOD1; [Range(0f, 1f)] public float densityLOD1 = 0.5f; public bool enableShadowsLOD1 = true; - [Header("LOD 2")] - public float distanceLOD2 = 15f; + [Header("LOD 2")] public float distanceLOD2 = 15f; public Material grassMaterialLOD2; [Range(0f, 1f)] public float densityLOD2 = 0.25f; public bool enableShadowsLOD2 = false; - [Header("LOD 3")] - public float distanceLOD3 = 25f; + [Header("LOD 3")] public float distanceLOD3 = 25f; public Material grassMaterialLOD3; [Range(0f, 1f)] public float densityLOD3 = 0.125f; public bool enableShadowsLOD3 = false; - + private const float SQRT_2 = 1.4142135623730f; - private static readonly int pId_WorldSpaceCameraPosEditor = Shader.PropertyToID("_WorldSpaceCameraPosEditor"); private static readonly int pId_TransitionRange = Shader.PropertyToID("_TransitionRange"); // a 2D array would be cleaner, but it can't be serialized @@ -49,12 +42,12 @@ public class GrassField : MonoBehaviour { var camPosWorld = Camera.main ? Camera.main.transform.position : Vector3.zero; UpdateLODs(camPosWorld); - UpdateMaterials(camPosWorld); + UpdateMaterials(); } public void UpdateLODsAndMaterials() { var camPosWorld = Camera.main ? Camera.main.transform.position : Vector3.zero; - UpdateMaterials(camPosWorld); + UpdateMaterials(); UpdateLODs(camPosWorld); } @@ -64,11 +57,12 @@ public class GrassField : MonoBehaviour { if (distanceLOD2 < minDistLOD2) { Debug.LogWarning("It is recommended that minDistLOD2 is greater than " + minDistLOD2 + "."); } + var minDistLOD3 = distanceLOD2 + chunkSize * SQRT_2; if (distanceLOD3 < minDistLOD3) { Debug.LogWarning("It is recommended that minDistLOD3 is greater than " + minDistLOD3 + "."); } - + if (_chunks.Length != numChunks * numChunks) { Debug.LogError(this.name + ": Existing chunks does not match numChunks."); gameObject.SetActive(false); @@ -81,26 +75,21 @@ public class GrassField : MonoBehaviour { UpdateLODsAndMaterials(); } - private void FixedUpdate() { + private void Update() { +#if UNITY_EDITOR + // update LOD distances (might have been changed via inspector) + UpdateLODsAndMaterials(); +#else + if (_chunks.Length != numChunks * numChunks) return; var cam = Camera.main; if (!cam) return; - var camPosWorld = cam.transform.position; - -#if UNITY_EDITOR - // update LOD distances and camera position - UpdateMaterials(camPosWorld); + UpdateLODs(cam.transform.position, false); // while the game is running, only update the chunks near the camera #endif - - if (_chunks.Length != numChunks * numChunks) return; - UpdateLODs(camPosWorld, false); // while the game is running, only the chunks near the camera are updated } private void UpdateLODs(Vector3 camPosWorld, bool forceCompleteCheck = true) { var camPos = camPosWorld - transform.position; // cam position relative to grass field - if (ignoreHeightForLOD) { - camPos.y = 0; - } - + var chunkSize = ((float)size) / numChunks; var bounds = new Bounds( new Vector3(0.5f * chunkSize, 0f, 0.5f * chunkSize), @@ -109,7 +98,7 @@ public class GrassField : MonoBehaviour { // 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 } + ? new GridRange { fromX = 0, toX = numChunks - 1, fromZ = 0, toZ = numChunks - 1 } : GetLODGridRange(camPos, chunkSize); for (int x = range.fromX; x <= range.toX; x++) @@ -142,17 +131,17 @@ public class GrassField : MonoBehaviour { 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 - distanceLOD3 - maxCamMove; var toXWorld = camPos.x + distanceLOD3 + maxCamMove; var fromZWorld = camPos.z - distanceLOD3 - maxCamMove; var toZWorld = camPos.z + distanceLOD3 + 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.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); @@ -161,28 +150,19 @@ public class GrassField : MonoBehaviour { return range; } - private void UpdateMaterials(Vector3 camPosWorld) { + private void UpdateMaterials() { var chunkSize = ((float)size) / numChunks; var chunkDiagonalLength = chunkSize * SQRT_2; var transition0From = minDistanceLOD0; - var transition0To = distanceLOD1; + var transition0To = distanceLOD1; var transition1From = distanceLOD1 + chunkDiagonalLength; - var transition1To = distanceLOD2; + var transition1To = distanceLOD2; var transition2From = distanceLOD2 + chunkDiagonalLength; - var transition2To = distanceLOD3; + var transition2To = distanceLOD3; grassMaterialLOD0.SetVector(pId_TransitionRange, new Vector2(transition0From, transition0To)); grassMaterialLOD1.SetVector(pId_TransitionRange, new Vector2(transition1From, transition1To)); grassMaterialLOD2.SetVector(pId_TransitionRange, new Vector2(transition2From, transition2To)); -#if UNITY_EDITOR - if (ignoreHeightForLOD) { - camPosWorld.y = 0; - } - grassMaterialLOD0.SetVector(pId_WorldSpaceCameraPosEditor, camPosWorld); - grassMaterialLOD1.SetVector(pId_WorldSpaceCameraPosEditor, camPosWorld); - grassMaterialLOD2.SetVector(pId_WorldSpaceCameraPosEditor, camPosWorld); - grassMaterialLOD3.SetVector(pId_WorldSpaceCameraPosEditor, camPosWorld); -#endif } private void CreateChunks( @@ -195,6 +175,7 @@ public class GrassField : MonoBehaviour { // Destroy(obj) does not work in edit mode DestroyImmediate(chunksTransform.gameObject); } + // create GameObject "Chunks" as a container for all GrassChunk objects chunksContainer = new GameObject("Chunks"); chunksContainer.transform.SetParent(this.transform, false); @@ -216,7 +197,7 @@ public class GrassField : MonoBehaviour { var meshLOD3 = GenerateChunkMesh(chunkPos, chunkBounds, bladesLOD3, "grass_chunk_" + x + "_" + y + "_lod3"); var chunk = Instantiate(chunkPrefab, chunksContainer.transform); - chunk.name = "Chunk [" + x + ", " + y +"]"; + chunk.name = "Chunk [" + x + ", " + y + "]"; chunk.transform.localPosition = chunkPos; chunk.MaterialLOD0 = grassMaterialLOD0; @@ -260,6 +241,7 @@ public class GrassField : MonoBehaviour { mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; Debug.LogWarning(meshName + " has more than 65536 grass blades. Mesh.indexFormat set to UInt32."); } + mesh.SetVertices(rootPositions); mesh.SetUVs(0, tipOffsets_missingInNextLOD); // Vector4 UVs // AABB gets calculated automatically (considers all root positions) @@ -272,13 +254,16 @@ public class GrassField : MonoBehaviour { const float height = 1f; // a blade should not be higher than this mesh.bounds = new Bounds( previousBounds.center + new Vector3(0f, height * 0.5f, 0f), - previousBounds.size + new Vector3(2f*width, height, 2f*width) + previousBounds.size + new Vector3(2f * width, height, 2f * width) ); return mesh; } - + private void OnDrawGizmos() { + // when in editor, update LODs every frame. nothing to do with gizmos + UpdateLODsAndMaterials(); + var chunkSize = ((float)size) / numChunks; var tPos = transform.position; @@ -299,17 +284,12 @@ public class GrassField : MonoBehaviour { if (!cam) return; var center = cam.transform.position; var oldMatrix = Gizmos.matrix; - if (ignoreHeightForLOD) { - center.y = 0.01f; - // draw a circle instead of a sphere - Gizmos.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1f, 0.001f, 1f)); - } - + Gizmos.color = new Color(0f, 0.3f, 1f, 1f); Gizmos.DrawWireSphere(center, distanceLOD1); Gizmos.DrawWireSphere(center, distanceLOD2); Gizmos.DrawWireSphere(center, distanceLOD3); - + Gizmos.color = new Color(1.0f, 1.0f, 0.0f, 1f); var minDistLOD0 = minDistanceLOD0; var minDistLOD1 = distanceLOD1 + chunkSize * SQRT_2; @@ -317,7 +297,7 @@ public class GrassField : MonoBehaviour { Gizmos.DrawWireSphere(center, minDistLOD0); Gizmos.DrawWireSphere(center, minDistLOD1); Gizmos.DrawWireSphere(center, minDistLOD2); - + Gizmos.matrix = oldMatrix; } } diff --git a/Assets/Scripts/MainCameraPositionShaderSetter.cs b/Assets/Scripts/MainCameraPositionShaderSetter.cs new file mode 100644 index 0000000..62868c3 --- /dev/null +++ b/Assets/Scripts/MainCameraPositionShaderSetter.cs @@ -0,0 +1,17 @@ +using UnityEngine; +using UnityEditor; + +[ExecuteAlways] +public class MainCameraPositionShaderSetter : MonoBehaviour { + private static readonly int pId_MainCameraPosition = Shader.PropertyToID("_MainCameraPosition"); + + private void OnEnable() { + if (!Camera.main || Camera.main.gameObject != this.gameObject) { + Debug.LogWarning("MainCameraPositionShaderSetter set on object that is not the main camera"); + } + } + + private void Update() { + Shader.SetGlobalVector(pId_MainCameraPosition, this.transform.position); + } +} diff --git a/Assets/Scripts/MainCameraPositionShaderSetter.cs.meta b/Assets/Scripts/MainCameraPositionShaderSetter.cs.meta new file mode 100644 index 0000000..6a685de --- /dev/null +++ b/Assets/Scripts/MainCameraPositionShaderSetter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d9be733811a3b0342953552aa8d5ab8a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Shaders/include/GrassBladePass.hlsl b/Assets/Shaders/include/GrassBladePass.hlsl index 1865a28..9917fb9 100644 --- a/Assets/Shaders/include/GrassBladePass.hlsl +++ b/Assets/Shaders/include/GrassBladePass.hlsl @@ -6,9 +6,9 @@ sampler2D _FrabVarianz, _BladeWidthTex; float2 _TransitionRange; -#if UNITY_EDITOR -float3 _WorldSpaceCameraPosEditor; -#endif +// Custom variable that is set to the position of the main camera in the scene +// (instead of Unity's _WorldSpaceCameraPos, which uses the scene view camera in editor mode) +float3 _MainCameraPosition; struct MeshData { float4 vertex : POSITION; @@ -40,11 +40,7 @@ v2g vert (MeshData v) { } float getCameraDistance(float3 pos) { -#if UNITY_EDITOR - return distance(_WorldSpaceCameraPosEditor, pos); -#else - return distance(_WorldSpaceCameraPos, pos); -#endif + return distance(_MainCameraPosition, pos); } #if _LOD_LOD_0 @@ -92,17 +88,18 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { g2f o; float3 previousSegmentCenter = basePos - float3(0,-1,0); // point beneath the basePos + int numSegments; #if _LOD_LOD_0 - int numSegments = lerp(11.99, 5.0, interpolator); // 11 - 5 + numSegments = lerp(11.99, 5.0, interpolator); // 11 - 5 #elif _LOD_LOD_1 - int numSegments = lerp(5.99, 2.0, interpolator); // 5 - 2 + numSegments = lerp(5.99, 2.0, interpolator); // 5 - 2 #elif _LOD_LOD_2 - int numSegments = 2; + numSegments = 2; #elif _LOD_LOD_3 - int numSegments = 1; + numSegments = 1; #endif - float3 localCameraPos = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos.xyz, 1.0)).xyz; + float3 localCameraPos = mul(unity_WorldToObject, float4(_MainCameraPosition.xyz, 1.0)).xyz; for (int i = 0; i < numSegments; i++) { const float lowerThickness = 0.8; @@ -136,7 +133,7 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { } //normalWS = float3(1,1,1) * lookingFromAbove; - //normalWS = basePosWS - _WorldSpaceCameraPos.xyz; + //normalWS = basePosWS - _MainCameraPosition.xyz; //normalWS = camVec; o.pos = UnityObjectToClipPos(vertLeftBase); @@ -262,7 +259,7 @@ float4 frag(g2f i) : SV_Target{ half3 skyColor = DecodeHDR(skyData, unity_SpecCube0_HDR); float3 lightReflectDirection = reflect(-lightDirection, worldNormal); - float3 viewDirection = normalize(float3(float4(_WorldSpaceCameraPos.xyz, 1.0) - i.worldPos.xyz)); + float3 viewDirection = normalize(float3(float4(_MainCameraPosition.xyz, 1.0) - i.worldPos.xyz)); float atten = 1.0; From 0293a920efebf9fce00d58a6bb1990ef8ede0811 Mon Sep 17 00:00:00 2001 From: Timo Eberl Date: Thu, 28 Aug 2025 17:41:31 +0200 Subject: [PATCH 3/8] comments --- Assets/Scripts/GrassField.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Assets/Scripts/GrassField.cs b/Assets/Scripts/GrassField.cs index b057a5b..adef5a7 100644 --- a/Assets/Scripts/GrassField.cs +++ b/Assets/Scripts/GrassField.cs @@ -77,13 +77,16 @@ public class GrassField : MonoBehaviour { private void Update() { #if UNITY_EDITOR - // update LOD distances (might have been changed via inspector) + // LOD distances might have been changed via Inspector -> Update materials + // Camera might have been moved -> Update LODs UpdateLODsAndMaterials(); #else if (_chunks.Length != numChunks * numChunks) return; var cam = Camera.main; if (!cam) return; - UpdateLODs(cam.transform.position, false); // while the game is running, only update the chunks near the camera + // while the game is running, only update the chunks near the camera + // if the camera moved a great distance since the last frame, this fails + UpdateLODs(cam.transform.position, false); #endif } From e29838536643064b7aeeecf6042ea8a4383af289 Mon Sep 17 00:00:00 2001 From: Timo Eberl Date: Thu, 28 Aug 2025 18:07:57 +0200 Subject: [PATCH 4/8] fix i.worldPos --- Assets/Scenes/SampleScene.unity | 152 ++++++++++----------- Assets/Shaders/include/GrassBladePass.hlsl | 53 ++++--- 2 files changed, 99 insertions(+), 106 deletions(-) diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index 3a489f0..4ebf990 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -14983,7 +14983,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 90233674} - m_Mesh: {fileID: 1781571828} + m_Mesh: {fileID: 1116240434} --- !u!23 &90233677 MeshRenderer: m_ObjectHideFlags: 0 @@ -14992,7 +14992,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 90233674} m_Enabled: 1 - m_CastShadows: 1 + m_CastShadows: 0 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -15004,7 +15004,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -35287,7 +35287,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 238904230} - m_Mesh: {fileID: 1209418183} + m_Mesh: {fileID: 889202062} --- !u!23 &238904233 MeshRenderer: m_ObjectHideFlags: 0 @@ -35308,7 +35308,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -51631,7 +51631,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 346939760} - m_Mesh: {fileID: 687221521} + m_Mesh: {fileID: 1221698654} --- !u!23 &346939763 MeshRenderer: m_ObjectHideFlags: 0 @@ -51640,7 +51640,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 346939760} m_Enabled: 1 - m_CastShadows: 1 + m_CastShadows: 0 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -51652,7 +51652,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -64477,7 +64477,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 434496868} - m_Mesh: {fileID: 1114929778} + m_Mesh: {fileID: 2061544436} --- !u!23 &434496871 MeshRenderer: m_ObjectHideFlags: 0 @@ -64498,7 +64498,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: d979d9bbf3760d948a452ba192cbf563, type: 2} + - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -69694,7 +69694,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 462934790} - m_Mesh: {fileID: 1506421826} + m_Mesh: {fileID: 1420238109} --- !u!23 &462934793 MeshRenderer: m_ObjectHideFlags: 0 @@ -69703,7 +69703,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 462934790} m_Enabled: 1 - m_CastShadows: 1 + m_CastShadows: 0 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -69715,7 +69715,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -74080,7 +74080,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 498600234} - m_Mesh: {fileID: 904888264} + m_Mesh: {fileID: 1142488810} --- !u!23 &498600237 MeshRenderer: m_ObjectHideFlags: 0 @@ -74101,7 +74101,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -84449,7 +84449,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 577417894} - m_Mesh: {fileID: 663755680} + m_Mesh: {fileID: 1253277976} --- !u!23 &577417897 MeshRenderer: m_ObjectHideFlags: 0 @@ -84470,7 +84470,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -86150,7 +86150,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 584577491} - m_Mesh: {fileID: 1763455613} + m_Mesh: {fileID: 871925010} --- !u!23 &584577494 MeshRenderer: m_ObjectHideFlags: 0 @@ -86159,7 +86159,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 584577491} m_Enabled: 1 - m_CastShadows: 1 + m_CastShadows: 0 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -86171,7 +86171,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -93590,7 +93590,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 636344957} - m_Mesh: {fileID: 352436139} + m_Mesh: {fileID: 850473257} --- !u!23 &636344960 MeshRenderer: m_ObjectHideFlags: 0 @@ -93611,7 +93611,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -112719,7 +112719,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 773380413} - m_Mesh: {fileID: 755271470} + m_Mesh: {fileID: 658220888} --- !u!23 &773380416 MeshRenderer: m_ObjectHideFlags: 0 @@ -112740,7 +112740,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -114306,7 +114306,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 787427247} - m_Mesh: {fileID: 475689305} + m_Mesh: {fileID: 1490227190} --- !u!23 &787427250 MeshRenderer: m_ObjectHideFlags: 0 @@ -114315,7 +114315,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 787427247} m_Enabled: 1 - m_CastShadows: 1 + m_CastShadows: 0 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -114327,7 +114327,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -114414,7 +114414,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 789985202} - m_Mesh: {fileID: 1015590501} + m_Mesh: {fileID: 145658542} --- !u!23 &789985205 MeshRenderer: m_ObjectHideFlags: 0 @@ -114435,7 +114435,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -116496,7 +116496,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 808969240} - m_Mesh: {fileID: 557526793} + m_Mesh: {fileID: 1370744454} --- !u!23 &808969243 MeshRenderer: m_ObjectHideFlags: 0 @@ -116505,7 +116505,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 808969240} m_Enabled: 1 - m_CastShadows: 1 + m_CastShadows: 0 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -116517,7 +116517,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -119124,7 +119124,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 830926066} - m_Mesh: {fileID: 1011258362} + m_Mesh: {fileID: 752700172} --- !u!23 &830926069 MeshRenderer: m_ObjectHideFlags: 0 @@ -119145,7 +119145,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -123675,7 +123675,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 859508517} - m_Mesh: {fileID: 869348275} + m_Mesh: {fileID: 1535435504} --- !u!23 &859508520 MeshRenderer: m_ObjectHideFlags: 0 @@ -123684,7 +123684,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 859508517} m_Enabled: 1 - m_CastShadows: 1 + m_CastShadows: 0 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -123696,7 +123696,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -124608,7 +124608,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 862437024} - m_Mesh: {fileID: 271122022} + m_Mesh: {fileID: 1973683947} --- !u!23 &862437027 MeshRenderer: m_ObjectHideFlags: 0 @@ -124629,7 +124629,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -133665,7 +133665,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 921841283} - m_Mesh: {fileID: 547844536} + m_Mesh: {fileID: 272372729} --- !u!23 &921841286 MeshRenderer: m_ObjectHideFlags: 0 @@ -133674,7 +133674,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 921841283} m_Enabled: 1 - m_CastShadows: 1 + m_CastShadows: 0 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -133686,7 +133686,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -136598,7 +136598,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 942140413} - m_Mesh: {fileID: 1671461130} + m_Mesh: {fileID: 601687339} --- !u!23 &942140416 MeshRenderer: m_ObjectHideFlags: 0 @@ -136619,7 +136619,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -171287,7 +171287,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1184864925} - m_Mesh: {fileID: 116625671} + m_Mesh: {fileID: 1842110855} --- !u!23 &1184864928 MeshRenderer: m_ObjectHideFlags: 0 @@ -171296,7 +171296,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1184864925} m_Enabled: 1 - m_CastShadows: 1 + m_CastShadows: 0 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -171308,7 +171308,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -171560,7 +171560,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1186762702} - m_Mesh: {fileID: 811416661} + m_Mesh: {fileID: 1116676414} --- !u!23 &1186762705 MeshRenderer: m_ObjectHideFlags: 0 @@ -171581,7 +171581,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -171998,7 +171998,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1188818393} - m_Mesh: {fileID: 932024252} + m_Mesh: {fileID: 1034374045} --- !u!23 &1188818396 MeshRenderer: m_ObjectHideFlags: 0 @@ -172019,7 +172019,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -176936,7 +176936,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1229489200} - m_Mesh: {fileID: 1790509331} + m_Mesh: {fileID: 547905413} --- !u!23 &1229489203 MeshRenderer: m_ObjectHideFlags: 0 @@ -176957,7 +176957,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -180884,7 +180884,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1252991245} - m_Mesh: {fileID: 659750507} + m_Mesh: {fileID: 474141185} --- !u!23 &1252991248 MeshRenderer: m_ObjectHideFlags: 0 @@ -180905,7 +180905,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -181982,7 +181982,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1259718493} - m_Mesh: {fileID: 773094812} + m_Mesh: {fileID: 426043794} --- !u!23 &1259718496 MeshRenderer: m_ObjectHideFlags: 0 @@ -182003,7 +182003,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -191414,7 +191414,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1314535846} - m_Mesh: {fileID: 671083140} + m_Mesh: {fileID: 322926976} --- !u!23 &1314535849 MeshRenderer: m_ObjectHideFlags: 0 @@ -191435,7 +191435,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -206996,7 +206996,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1430497980} - m_Mesh: {fileID: 1226309064} + m_Mesh: {fileID: 16904396} --- !u!23 &1430497983 MeshRenderer: m_ObjectHideFlags: 0 @@ -207005,7 +207005,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1430497980} m_Enabled: 1 - m_CastShadows: 1 + m_CastShadows: 0 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -207017,7 +207017,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -210341,7 +210341,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1449322683} - m_Mesh: {fileID: 447456844} + m_Mesh: {fileID: 1922265943} --- !u!23 &1449322686 MeshRenderer: m_ObjectHideFlags: 0 @@ -210362,7 +210362,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -227294,7 +227294,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1569035941} - m_Mesh: {fileID: 38118574} + m_Mesh: {fileID: 164772976} --- !u!23 &1569035944 MeshRenderer: m_ObjectHideFlags: 0 @@ -227315,7 +227315,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: d979d9bbf3760d948a452ba192cbf563, type: 2} + - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -236948,7 +236948,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1643991362} - m_Mesh: {fileID: 1268476173} + m_Mesh: {fileID: 686178384} --- !u!23 &1643991365 MeshRenderer: m_ObjectHideFlags: 0 @@ -236969,7 +236969,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: d979d9bbf3760d948a452ba192cbf563, type: 2} + - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -259496,7 +259496,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1786986290} - m_Mesh: {fileID: 20114828} + m_Mesh: {fileID: 1690255161} --- !u!23 &1786986293 MeshRenderer: m_ObjectHideFlags: 0 @@ -259517,7 +259517,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -281051,7 +281051,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1937472215} - m_Mesh: {fileID: 843278902} + m_Mesh: {fileID: 44190719} --- !u!23 &1937472218 MeshRenderer: m_ObjectHideFlags: 0 @@ -281072,7 +281072,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -290958,7 +290958,7 @@ Transform: m_GameObject: {fileID: 2016058935} serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 5.11, y: 0, z: 2.71} + m_LocalPosition: {x: 13.21, y: 0, z: 6.07} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -303123,7 +303123,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2105141257} - m_Mesh: {fileID: 291130702} + m_Mesh: {fileID: 875234253} --- !u!23 &2105141260 MeshRenderer: m_ObjectHideFlags: 0 @@ -303132,7 +303132,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2105141257} m_Enabled: 1 - m_CastShadows: 1 + m_CastShadows: 0 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -303144,7 +303144,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 diff --git a/Assets/Shaders/include/GrassBladePass.hlsl b/Assets/Shaders/include/GrassBladePass.hlsl index 9917fb9..a3dc1e9 100644 --- a/Assets/Shaders/include/GrassBladePass.hlsl +++ b/Assets/Shaders/include/GrassBladePass.hlsl @@ -1,7 +1,8 @@ // Material Properties float _BladeWidth, _BendStrength; float4 _Color0, _Color1, _Color2, _Color3, _InnerColor; -float _SegmentsMinusOne, _FieldSize, _AOStrength, _Translucency, _SSSStrength, _Metallic, _Roughness, _BladeBow, _MaxBladeHeight, _HighlightStrength, _BladeWidthTexStrength; +float _SegmentsMinusOne, _FieldSize, _AOStrength, _Translucency, _SSSStrength, _Metallic, _Roughness, + _BladeBow, _MaxBladeHeight, _HighlightStrength, _BladeWidthTexStrength; sampler2D _FrabVarianz, _BladeWidthTex; float2 _TransitionRange; @@ -143,7 +144,7 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { TRANSFER_SHADOW(o) o.transitionInterpolator = interpolator; o.normal = normalWS; - o.worldPos = mul(unity_ObjectToWorld, vertLeftBase).xyz; + o.worldPos = mul(unity_ObjectToWorld, float4(vertLeftBase,1.0)).xyz; #endif triStream.Append(o); @@ -153,7 +154,7 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { TRANSFER_SHADOW(o) o.transitionInterpolator = interpolator; o.normal = normalWS; - o.worldPos = mul(unity_ObjectToWorld, vertRightBase).xyz; + o.worldPos = mul(unity_ObjectToWorld, float4(vertRightBase,1.0)).xyz; #endif triStream.Append(o); @@ -163,7 +164,7 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { TRANSFER_SHADOW(o) o.transitionInterpolator = interpolator; o.normal = normalWS; - o.worldPos = mul(unity_ObjectToWorld, vertLeftTip).xyz; + o.worldPos = mul(unity_ObjectToWorld, float4(vertLeftTip,1.0)).xyz; #endif triStream.Append(o); @@ -173,7 +174,7 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { TRANSFER_SHADOW(o) o.transitionInterpolator = interpolator; o.normal = normalWS; - o.worldPos = mul(unity_ObjectToWorld, vertRightTip).xyz; + o.worldPos = mul(unity_ObjectToWorld, float4(vertRightTip,1.0)).xyz; #endif triStream.Append(o); } @@ -216,8 +217,8 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { TRANSFER_SHADOW(o) o.transitionInterpolator = interpolator; o.normal = normalize(lerp(normalWS, UnityObjectToWorldNormal(normalize(widthOffset)), _BladeBow)); - o.worldPos = mul(unity_ObjectToWorld, vertLeft).xyz; -#endif + o.worldPos = mul(unity_ObjectToWorld, float4(vertLeft,1.0)).xyz; +#endif triStream.Append(o); o.pos = UnityObjectToClipPos(vertRight); @@ -227,7 +228,7 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { o.transitionInterpolator = interpolator; o.normal = normalize(lerp(normalWS, UnityObjectToWorldNormal(-normalize(widthOffset)), _BladeBow)); - o.worldPos = mul(unity_ObjectToWorld, vertRight).xyz; + o.worldPos = mul(unity_ObjectToWorld, float4(vertRight,1.0)).xyz; #endif triStream.Append(o); previousSegmentCenter = segmentCenterSnapshot; @@ -244,19 +245,16 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { } float4 frag(g2f i) : SV_Target{ - - #ifndef IS_IN_SHADOW_PASS - +#ifndef IS_IN_SHADOW_PASS float3 worldNormal = normalize(i.normal); float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz); - - half3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos)); - half3 worldRefl = reflect(-worldViewDir, worldNormal); + float3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos)); + float3 worldRefl = reflect(-worldViewDir, worldNormal); // same as in previous shader half4 skyData = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, worldRefl, 0); - half3 skyColor = DecodeHDR(skyData, unity_SpecCube0_HDR); + float3 skyColor = DecodeHDR(skyData, unity_SpecCube0_HDR); float3 lightReflectDirection = reflect(-lightDirection, worldNormal); float3 viewDirection = normalize(float3(float4(_MainCameraPosition.xyz, 1.0) - i.worldPos.xyz)); @@ -273,14 +271,14 @@ float4 frag(g2f i) : SV_Target{ lightFinal *= max(.35, shadow); lightFinal *= 1.0; - fixed4 middleCol = min(1, abs(i.uv.x - 0.5) * 1); - fixed4 col = max(0.87, pow(middleCol, .01)); - fixed4 farbvarianz = tex2Dlod(_FrabVarianz, float4(i.worldPos.xz / 40, 0, 3)); - fixed4 farbvarianz2 = tex2Dlod(_FrabVarianz, float4(i.worldPos.xz / 10, 0, 3)); - fixed4 farbvarianz3 = tex2Dlod(_FrabVarianz, float4(i.worldPos.xz / 3, 0, 3)); - fixed4 bladeWidthTex = tex2Dlod(_BladeWidthTex, float4(i.uv.x, 0, 0, 3)); + float4 middleCol = min(1, abs(i.uv.x - 0.5) * 1); + float4 col = max(0.87, pow(middleCol, .01)); + float4 farbvarianz = tex2Dlod(_FrabVarianz, float4(i.worldPos.xz / 40, 0, 3)); + float4 farbvarianz2 = tex2Dlod(_FrabVarianz, float4(i.worldPos.xz / 10, 0, 3)); + float4 farbvarianz3 = tex2Dlod(_FrabVarianz, float4(i.worldPos.xz / 3, 0, 3)); + float4 bladeWidthTex = tex2Dlod(_BladeWidthTex, float4(i.uv.x, 0, 0, 3)); - fixed4 albedo = lerp(farbvarianz2, farbvarianz3, 0.4); + float4 albedo = lerp(farbvarianz2, farbvarianz3, 0.4); albedo = lerp(albedo, farbvarianz, _Metallic) * 0.7; albedo *= 1 + _AOStrength; albedo *= lerp(1, bladeWidthTex.x * 2.5, _BladeWidthTexStrength); @@ -291,12 +289,7 @@ float4 frag(g2f i) : SV_Target{ lightFinal = min(1.4, max(0.4, lightFinal)); - return float4(lightFinal * albedo * 2, 0); - //return float4(worldNormal, 0); dot(worldNormal, lightDirection) - - #endif - - - - return 0; + return float4(worldNormal, 1); +#endif + return 0; // shadow pass } From a3d689bbb2e184a573933e8c461da034aef431ca Mon Sep 17 00:00:00 2001 From: Timo Eberl Date: Sun, 31 Aug 2025 13:28:10 +0200 Subject: [PATCH 5/8] Remove sky stuff --- Assets/Scenes/SampleScene.unity | 148 +++++++++--------- Assets/Shaders/SkyColorTestShader.shader | 46 ------ Assets/Shaders/SkyColorTestShader.shader.meta | 9 -- Assets/Shaders/SkyTest.mat | 83 ---------- Assets/Shaders/SkyTest.mat.meta | 8 - 5 files changed, 74 insertions(+), 220 deletions(-) delete mode 100644 Assets/Shaders/SkyColorTestShader.shader delete mode 100644 Assets/Shaders/SkyColorTestShader.shader.meta delete mode 100644 Assets/Shaders/SkyTest.mat delete mode 100644 Assets/Shaders/SkyTest.mat.meta diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index 4ebf990..97cbab5 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -14983,7 +14983,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 90233674} - m_Mesh: {fileID: 1116240434} + m_Mesh: {fileID: 1781571828} --- !u!23 &90233677 MeshRenderer: m_ObjectHideFlags: 0 @@ -14992,7 +14992,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 90233674} m_Enabled: 1 - m_CastShadows: 0 + m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -15004,7 +15004,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -35287,7 +35287,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 238904230} - m_Mesh: {fileID: 889202062} + m_Mesh: {fileID: 1209418183} --- !u!23 &238904233 MeshRenderer: m_ObjectHideFlags: 0 @@ -35308,7 +35308,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -51631,7 +51631,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 346939760} - m_Mesh: {fileID: 1221698654} + m_Mesh: {fileID: 687221521} --- !u!23 &346939763 MeshRenderer: m_ObjectHideFlags: 0 @@ -51640,7 +51640,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 346939760} m_Enabled: 1 - m_CastShadows: 0 + m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -51652,7 +51652,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -69694,7 +69694,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 462934790} - m_Mesh: {fileID: 1420238109} + m_Mesh: {fileID: 1506421826} --- !u!23 &462934793 MeshRenderer: m_ObjectHideFlags: 0 @@ -69703,7 +69703,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 462934790} m_Enabled: 1 - m_CastShadows: 0 + m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -69715,7 +69715,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -74080,7 +74080,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 498600234} - m_Mesh: {fileID: 1142488810} + m_Mesh: {fileID: 904888264} --- !u!23 &498600237 MeshRenderer: m_ObjectHideFlags: 0 @@ -74101,7 +74101,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -84449,7 +84449,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 577417894} - m_Mesh: {fileID: 1253277976} + m_Mesh: {fileID: 663755680} --- !u!23 &577417897 MeshRenderer: m_ObjectHideFlags: 0 @@ -84470,7 +84470,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -86150,7 +86150,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 584577491} - m_Mesh: {fileID: 871925010} + m_Mesh: {fileID: 1763455613} --- !u!23 &584577494 MeshRenderer: m_ObjectHideFlags: 0 @@ -86159,7 +86159,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 584577491} m_Enabled: 1 - m_CastShadows: 0 + m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -86171,7 +86171,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -93590,7 +93590,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 636344957} - m_Mesh: {fileID: 850473257} + m_Mesh: {fileID: 352436139} --- !u!23 &636344960 MeshRenderer: m_ObjectHideFlags: 0 @@ -93611,7 +93611,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -112719,7 +112719,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 773380413} - m_Mesh: {fileID: 658220888} + m_Mesh: {fileID: 755271470} --- !u!23 &773380416 MeshRenderer: m_ObjectHideFlags: 0 @@ -112740,7 +112740,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -114306,7 +114306,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 787427247} - m_Mesh: {fileID: 1490227190} + m_Mesh: {fileID: 475689305} --- !u!23 &787427250 MeshRenderer: m_ObjectHideFlags: 0 @@ -114315,7 +114315,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 787427247} m_Enabled: 1 - m_CastShadows: 0 + m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -114327,7 +114327,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -114414,7 +114414,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 789985202} - m_Mesh: {fileID: 145658542} + m_Mesh: {fileID: 1015590501} --- !u!23 &789985205 MeshRenderer: m_ObjectHideFlags: 0 @@ -114435,7 +114435,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -116496,7 +116496,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 808969240} - m_Mesh: {fileID: 1370744454} + m_Mesh: {fileID: 557526793} --- !u!23 &808969243 MeshRenderer: m_ObjectHideFlags: 0 @@ -116505,7 +116505,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 808969240} m_Enabled: 1 - m_CastShadows: 0 + m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -116517,7 +116517,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -119124,7 +119124,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 830926066} - m_Mesh: {fileID: 752700172} + m_Mesh: {fileID: 1011258362} --- !u!23 &830926069 MeshRenderer: m_ObjectHideFlags: 0 @@ -119145,7 +119145,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -123675,7 +123675,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 859508517} - m_Mesh: {fileID: 1535435504} + m_Mesh: {fileID: 869348275} --- !u!23 &859508520 MeshRenderer: m_ObjectHideFlags: 0 @@ -123684,7 +123684,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 859508517} m_Enabled: 1 - m_CastShadows: 0 + m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -123696,7 +123696,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -124608,7 +124608,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 862437024} - m_Mesh: {fileID: 1973683947} + m_Mesh: {fileID: 271122022} --- !u!23 &862437027 MeshRenderer: m_ObjectHideFlags: 0 @@ -124629,7 +124629,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -133665,7 +133665,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 921841283} - m_Mesh: {fileID: 272372729} + m_Mesh: {fileID: 547844536} --- !u!23 &921841286 MeshRenderer: m_ObjectHideFlags: 0 @@ -133674,7 +133674,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 921841283} m_Enabled: 1 - m_CastShadows: 0 + m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -133686,7 +133686,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -136598,7 +136598,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 942140413} - m_Mesh: {fileID: 601687339} + m_Mesh: {fileID: 1671461130} --- !u!23 &942140416 MeshRenderer: m_ObjectHideFlags: 0 @@ -136619,7 +136619,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -171287,7 +171287,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1184864925} - m_Mesh: {fileID: 1842110855} + m_Mesh: {fileID: 116625671} --- !u!23 &1184864928 MeshRenderer: m_ObjectHideFlags: 0 @@ -171296,7 +171296,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1184864925} m_Enabled: 1 - m_CastShadows: 0 + m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -171308,7 +171308,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -171560,7 +171560,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1186762702} - m_Mesh: {fileID: 1116676414} + m_Mesh: {fileID: 811416661} --- !u!23 &1186762705 MeshRenderer: m_ObjectHideFlags: 0 @@ -171581,7 +171581,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -171998,7 +171998,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1188818393} - m_Mesh: {fileID: 1034374045} + m_Mesh: {fileID: 932024252} --- !u!23 &1188818396 MeshRenderer: m_ObjectHideFlags: 0 @@ -172019,7 +172019,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -176936,7 +176936,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1229489200} - m_Mesh: {fileID: 547905413} + m_Mesh: {fileID: 1790509331} --- !u!23 &1229489203 MeshRenderer: m_ObjectHideFlags: 0 @@ -176957,7 +176957,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -180884,7 +180884,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1252991245} - m_Mesh: {fileID: 474141185} + m_Mesh: {fileID: 659750507} --- !u!23 &1252991248 MeshRenderer: m_ObjectHideFlags: 0 @@ -180905,7 +180905,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -181982,7 +181982,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1259718493} - m_Mesh: {fileID: 426043794} + m_Mesh: {fileID: 773094812} --- !u!23 &1259718496 MeshRenderer: m_ObjectHideFlags: 0 @@ -182003,7 +182003,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -191414,7 +191414,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1314535846} - m_Mesh: {fileID: 322926976} + m_Mesh: {fileID: 671083140} --- !u!23 &1314535849 MeshRenderer: m_ObjectHideFlags: 0 @@ -191435,7 +191435,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -206996,7 +206996,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1430497980} - m_Mesh: {fileID: 16904396} + m_Mesh: {fileID: 1226309064} --- !u!23 &1430497983 MeshRenderer: m_ObjectHideFlags: 0 @@ -207005,7 +207005,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1430497980} m_Enabled: 1 - m_CastShadows: 0 + m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -207017,7 +207017,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -210341,7 +210341,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1449322683} - m_Mesh: {fileID: 1922265943} + m_Mesh: {fileID: 447456844} --- !u!23 &1449322686 MeshRenderer: m_ObjectHideFlags: 0 @@ -210362,7 +210362,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -227294,7 +227294,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1569035941} - m_Mesh: {fileID: 164772976} + m_Mesh: {fileID: 38118574} --- !u!23 &1569035944 MeshRenderer: m_ObjectHideFlags: 0 @@ -227315,7 +227315,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} + - {fileID: 2100000, guid: d979d9bbf3760d948a452ba192cbf563, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -236948,7 +236948,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1643991362} - m_Mesh: {fileID: 686178384} + m_Mesh: {fileID: 1268476173} --- !u!23 &1643991365 MeshRenderer: m_ObjectHideFlags: 0 @@ -236969,7 +236969,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} + - {fileID: 2100000, guid: d979d9bbf3760d948a452ba192cbf563, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -259496,7 +259496,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1786986290} - m_Mesh: {fileID: 1690255161} + m_Mesh: {fileID: 20114828} --- !u!23 &1786986293 MeshRenderer: m_ObjectHideFlags: 0 @@ -259517,7 +259517,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -281051,7 +281051,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1937472215} - m_Mesh: {fileID: 44190719} + m_Mesh: {fileID: 843278902} --- !u!23 &1937472218 MeshRenderer: m_ObjectHideFlags: 0 @@ -281072,7 +281072,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: b747ca32ff9b8ee408e794d093cbdd54, type: 2} + - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -290958,7 +290958,7 @@ Transform: m_GameObject: {fileID: 2016058935} serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 13.21, y: 0, z: 6.07} + m_LocalPosition: {x: 5.31, y: 0, z: 2.19} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -303123,7 +303123,7 @@ MeshFilter: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2105141257} - m_Mesh: {fileID: 875234253} + m_Mesh: {fileID: 291130702} --- !u!23 &2105141260 MeshRenderer: m_ObjectHideFlags: 0 @@ -303132,7 +303132,7 @@ MeshRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2105141257} m_Enabled: 1 - m_CastShadows: 0 + m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 @@ -303144,7 +303144,7 @@ MeshRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 2100000, guid: ad7fd76c0f67ff04e8f51f21faf1739d, type: 2} + - {fileID: 2100000, guid: 91fb1ec3cf2133a4b931798a8822d055, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 diff --git a/Assets/Shaders/SkyColorTestShader.shader b/Assets/Shaders/SkyColorTestShader.shader deleted file mode 100644 index bb3bcf6..0000000 --- a/Assets/Shaders/SkyColorTestShader.shader +++ /dev/null @@ -1,46 +0,0 @@ -Shader "Unlit/SkyColorTestShader" -{ - SubShader - { - Pass - { - HLSLPROGRAM - #pragma vertex vert - #pragma fragment frag - #include "UnityCG.cginc" - - struct v2f { - half3 worldRefl : TEXCOORD0; - float4 pos : SV_POSITION; - }; - - v2f vert (float4 vertex : POSITION, float3 normal : NORMAL) - { - v2f o; - o.pos = UnityObjectToClipPos(vertex); - // compute world space position of the vertex - float3 worldPos = mul(unity_ObjectToWorld, vertex).xyz; - // compute world space view direction - float3 worldViewDir = normalize(UnityWorldSpaceViewDir(worldPos)); - // world space normal - float3 worldNormal = UnityObjectToWorldNormal(normal); - // world space reflection vector - o.worldRefl = reflect(-worldViewDir, worldNormal); - return o; - } - - fixed4 frag (v2f i) : SV_Target - { - // sample the default reflection cubemap, using the reflection vector - half4 skyData = UNITY_SAMPLE_TEXCUBE(unity_SpecCube0, i.worldRefl); - // decode cubemap data into actual color - half3 skyColor = DecodeHDR (skyData, unity_SpecCube0_HDR); - // output it! - fixed4 c = 0; - c.rgb = skyColor; - return c; - } - ENDHLSL - } - } -} diff --git a/Assets/Shaders/SkyColorTestShader.shader.meta b/Assets/Shaders/SkyColorTestShader.shader.meta deleted file mode 100644 index 6f87980..0000000 --- a/Assets/Shaders/SkyColorTestShader.shader.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 633e3c163a26aee4395de6b81b1aae3b -ShaderImporter: - externalObjects: {} - defaultTextures: [] - nonModifiableTextures: [] - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Shaders/SkyTest.mat b/Assets/Shaders/SkyTest.mat deleted file mode 100644 index a11d4ba..0000000 --- a/Assets/Shaders/SkyTest.mat +++ /dev/null @@ -1,83 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 8 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: SkyTest - m_Shader: {fileID: 4800000, guid: 633e3c163a26aee4395de6b81b1aae3b, type: 3} - m_Parent: {fileID: 0} - m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] - m_InvalidKeywords: [] - m_LightmapFlags: 4 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: {} - disabledShaderPasses: [] - m_LockedProperties: - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _BumpMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailAlbedoMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailMask: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailNormalMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _EmissionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MainTex: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MetallicGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _OcclusionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _ParallaxMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Ints: [] - m_Floats: - - _BumpScale: 1 - - _Cutoff: 0.5 - - _DetailNormalMapScale: 1 - - _DstBlend: 0 - - _GlossMapScale: 1 - - _Glossiness: 0.5 - - _GlossyReflections: 1 - - _Metallic: 0 - - _Mode: 0 - - _OcclusionStrength: 1 - - _Parallax: 0.02 - - _SmoothnessTextureChannel: 0 - - _SpecularHighlights: 1 - - _SrcBlend: 1 - - _UVSec: 0 - - _ZWrite: 1 - m_Colors: - - _Color: {r: 1, g: 1, b: 1, a: 1} - - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - m_BuildTextureStacks: [] diff --git a/Assets/Shaders/SkyTest.mat.meta b/Assets/Shaders/SkyTest.mat.meta deleted file mode 100644 index a379499..0000000 --- a/Assets/Shaders/SkyTest.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 944161d6703f1e244a9216da9f82501b -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 2100000 - userData: - assetBundleName: - assetBundleVariant: From 10f57041f9fe22d0adf62fceb0a9c5cc6b0c5cdd Mon Sep 17 00:00:00 2001 From: Timo Eberl Date: Sun, 31 Aug 2025 14:20:52 +0200 Subject: [PATCH 6/8] correct winding order + cleanup --- Assets/Shaders/GrassBlade.shader | 2 +- Assets/Shaders/include/GrassBladePass.hlsl | 175 ++++++++++----------- 2 files changed, 82 insertions(+), 95 deletions(-) diff --git a/Assets/Shaders/GrassBlade.shader b/Assets/Shaders/GrassBlade.shader index 094ea57..d5cb8f6 100644 --- a/Assets/Shaders/GrassBlade.shader +++ b/Assets/Shaders/GrassBlade.shader @@ -24,7 +24,7 @@ } SubShader { LOD 100 - Cull Off + // Cull Off //Render Pass Pass { diff --git a/Assets/Shaders/include/GrassBladePass.hlsl b/Assets/Shaders/include/GrassBladePass.hlsl index a3dc1e9..9998f3c 100644 --- a/Assets/Shaders/include/GrassBladePass.hlsl +++ b/Assets/Shaders/include/GrassBladePass.hlsl @@ -25,11 +25,11 @@ struct g2f { float4 pos : SV_POSITION; #ifdef IS_IN_BASE_PASS float3 normal : NORMAL; - float3 worldPos : TEXCOORD3; float2 uv : TEXCOORD0; // bottom left 0.0 top right 1.1 (values converge - 0 and 1 meet at the tip) SHADOW_COORDS(1) // put shadows data into TEXCOORD1 - float transitionInterpolator : TEXCOORD2; + float3 worldPos : TEXCOORD2; #endif + float3 debug : TEXCOORD3; }; v2g vert (MeshData v) { @@ -87,6 +87,8 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { #endif g2f o; + o.debug = float3(0,0,0); + float3 previousSegmentCenter = basePos - float3(0,-1,0); // point beneath the basePos int numSegments; @@ -101,86 +103,70 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { #endif float3 localCameraPos = mul(unity_WorldToObject, float4(_MainCameraPosition.xyz, 1.0)).xyz; + const float lowerThickness = 0.8; - for (int i = 0; i < numSegments; i++) { - const float lowerThickness = 0.8; - // LOD 3 has a different algorithm #if _LOD_LOD_3 - { - - - const float segmentWidth = halfWidth * pow(sin(lowerThickness * 3.141), .8); - const float3 widthOffset = getWidthOffset(segmentWidth, tipOffset.xz) * max(1, cameraDistance / 10); - float3 segmentCenterBase = basePos; - float3 segmentCenterTip = basePos + tipOffset; - const float3 vertLeftBase = segmentCenterBase + widthOffset * 2.5; - const float3 vertRightBase = segmentCenterBase - widthOffset * 2.5; - const float3 vertLeftTip = segmentCenterTip + widthOffset * 0.4; - const float3 vertRightTip = segmentCenterTip - widthOffset * 0.4; - - const float3 surfTangent1 = vertLeftBase - vertLeftTip; - const float3 surfTangent2 = vertLeftBase - vertRightBase; - const float3 normal = normalize(cross(surfTangent1, surfTangent2)); // TODO remove normalize - float3 normalWS = UnityObjectToWorldNormal(normal); - + const float segmentWidth = halfWidth * pow(sin(lowerThickness * 3.141), .8); + const float3 widthOffset = getWidthOffset(segmentWidth, tipOffset.xz) * max(1, cameraDistance / 10); + float3 segmentCenterBase = basePos; + float3 segmentCenterTip = basePos + tipOffset; + const float3 vertLeftBase = segmentCenterBase + widthOffset * 2.5; + const float3 vertRightBase = segmentCenterBase - widthOffset * 2.5; + const float3 vertLeftTip = segmentCenterTip + widthOffset * 0.4; + const float3 vertRightTip = segmentCenterTip - widthOffset * 0.4; + + const float3 surfTangent1 = vertRightBase - segmentCenterTip; + const float3 surfTangent2 = vertLeftBase - segmentCenterTip; + const float3 normal = normalize(cross(surfTangent1, surfTangent2)); // TODO remove normalize + float3 normalWS = UnityObjectToWorldNormal(normal); + + const float3 camVec = normalize(segmentCenterTip - localCameraPos); - const float3 camVec = normalize(vertLeftBase - localCameraPos); + // at which side of the blade are we looking? + const bool lookingFromAbove = dot(camVec, normal) > 0; + if (lookingFromAbove) { + // normalWS = -normalWS; + } - // at which side of the blade are we looking? - const bool lookingFromAbove = dot(camVec, normalWS) > 0; - if (lookingFromAbove) { - normalWS = -normalWS; - } - - //normalWS = float3(1,1,1) * lookingFromAbove; - //normalWS = basePosWS - _MainCameraPosition.xyz; - //normalWS = camVec; - - o.pos = UnityObjectToClipPos(vertLeftBase); - #ifndef IS_IN_SHADOW_PASS - - o.uv = float2(0, 0); - TRANSFER_SHADOW(o) - o.transitionInterpolator = interpolator; - o.normal = normalWS; - o.worldPos = mul(unity_ObjectToWorld, float4(vertLeftBase,1.0)).xyz; - #endif - triStream.Append(o); - - o.pos = UnityObjectToClipPos(vertRightBase); - #ifndef IS_IN_SHADOW_PASS - o.uv = float2(1, 0); - TRANSFER_SHADOW(o) - o.transitionInterpolator = interpolator; - o.normal = normalWS; - o.worldPos = mul(unity_ObjectToWorld, float4(vertRightBase,1.0)).xyz; - #endif - triStream.Append(o); - - o.pos = UnityObjectToClipPos(vertLeftTip); - #ifndef IS_IN_SHADOW_PASS - o.uv = float2(0, 1); - TRANSFER_SHADOW(o) - o.transitionInterpolator = interpolator; - o.normal = normalWS; - o.worldPos = mul(unity_ObjectToWorld, float4(vertLeftTip,1.0)).xyz; - #endif - triStream.Append(o); - - o.pos = UnityObjectToClipPos(vertRightTip); - #ifndef IS_IN_SHADOW_PASS - o.uv = float2(1, 1); - TRANSFER_SHADOW(o) - o.transitionInterpolator = interpolator; - o.normal = normalWS; - o.worldPos = mul(unity_ObjectToWorld, float4(vertRightTip,1.0)).xyz; - #endif - triStream.Append(o); - } - continue; + o.pos = UnityObjectToClipPos(vertRightBase); +#ifdef IS_IN_BASE_PASS + o.uv = float2(1, 0); + TRANSFER_SHADOW(o) + o.normal = normalWS; + o.worldPos = mul(unity_ObjectToWorld, float4(vertRightBase,1.0)).xyz; #endif - + triStream.Append(o); + + o.pos = UnityObjectToClipPos(vertLeftBase); +#ifdef IS_IN_BASE_PASS + o.uv = float2(0, 0); + TRANSFER_SHADOW(o) + o.normal = normalWS; + o.worldPos = mul(unity_ObjectToWorld, float4(vertLeftBase,1.0)).xyz; +#endif + triStream.Append(o); + + o.pos = UnityObjectToClipPos(vertRightTip); +#ifdef IS_IN_BASE_PASS + o.uv = float2(1, 1); + TRANSFER_SHADOW(o) + o.normal = normalWS; + o.worldPos = mul(unity_ObjectToWorld, float4(vertRightTip,1.0)).xyz; +#endif + triStream.Append(o); + + o.pos = UnityObjectToClipPos(vertLeftTip); +#ifdef IS_IN_BASE_PASS + o.uv = float2(0, 1); + TRANSFER_SHADOW(o) + o.normal = normalWS; + o.worldPos = mul(unity_ObjectToWorld, float4(vertLeftTip,1.0)).xyz; +#endif + triStream.Append(o); + +#else + for (int i = 0; i < numSegments; i++) { // in "blade space" const float segmentWidth = halfWidth * pow(sin(lowerThickness * 3.141 * (numSegments - i) / numSegments), .8); const float segmentHeightNormalized = i / (float)numSegments; @@ -195,14 +181,13 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { const float3 vertRight = segmentCenter - widthOffset; //const float3 nextSegmentCenter = basePos + bendParabula(tipPos, nextSegmentHeight01); -#ifndef IS_IN_SHADOW_PASS +#ifdef IS_IN_BASE_PASS // calculate normal const float3 surfTangent1 = previousSegmentCenter - segmentCenter; const float3 surfTangent2 = previousSegmentCenter - vertLeft; const float3 normal = normalize(cross(surfTangent1, surfTangent2)); // TODO remove normalize float3 normalWS = UnityObjectToWorldNormal(normal); - const float3 camVec = normalize(segmentCenter - localCameraPos); // at which side of the blade are we looking? @@ -211,41 +196,43 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { normalWS = -normalWS; } #endif - o.pos = UnityObjectToClipPos(vertLeft); -#ifndef IS_IN_SHADOW_PASS - o.uv = float2(0, segmentHeightNormalized); - TRANSFER_SHADOW(o) - o.transitionInterpolator = interpolator; - o.normal = normalize(lerp(normalWS, UnityObjectToWorldNormal(normalize(widthOffset)), _BladeBow)); - o.worldPos = mul(unity_ObjectToWorld, float4(vertLeft,1.0)).xyz; -#endif - triStream.Append(o); - o.pos = UnityObjectToClipPos(vertRight); -#ifndef IS_IN_SHADOW_PASS +#ifdef IS_IN_BASE_PASS o.uv = float2(1, segmentHeightNormalized); TRANSFER_SHADOW(o) - - o.transitionInterpolator = interpolator; o.normal = normalize(lerp(normalWS, UnityObjectToWorldNormal(-normalize(widthOffset)), _BladeBow)); o.worldPos = mul(unity_ObjectToWorld, float4(vertRight,1.0)).xyz; #endif triStream.Append(o); previousSegmentCenter = segmentCenterSnapshot; + + o.pos = UnityObjectToClipPos(vertLeft); +#ifdef IS_IN_BASE_PASS + o.uv = float2(0, segmentHeightNormalized); + TRANSFER_SHADOW(o) + o.normal = normalize(lerp(normalWS, UnityObjectToWorldNormal(normalize(widthOffset)), _BladeBow)); + o.worldPos = mul(unity_ObjectToWorld, float4(vertLeft,1.0)).xyz; +#endif + triStream.Append(o); } + +#endif o.pos = UnityObjectToClipPos(basePos + tipOffset * float3(_BendStrength, 1, _BendStrength)); -#ifndef IS_IN_SHADOW_PASS +#ifdef IS_IN_BASE_PASS o.uv = float2(.5, 1); TRANSFER_SHADOW(o) - o.transitionInterpolator = interpolator; o.normal = o.normal > 0 ? float3(0, 1, 0) : float3(0, -1, 0); #endif triStream.Append(o); } float4 frag(g2f i) : SV_Target{ -#ifndef IS_IN_SHADOW_PASS +#ifdef IS_IN_BASE_PASS + float3 localPos = mul(unity_WorldToObject, float4(i.worldPos, 1)).xyz; + float d = distance(localPos, i.debug) * 5; + return float4(i.debug, 1); + float3 worldNormal = normalize(i.normal); float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz); From 3b1f2d407357c205fba02018d0581c56c154da54 Mon Sep 17 00:00:00 2001 From: Timo Eberl Date: Sun, 31 Aug 2025 16:54:24 +0200 Subject: [PATCH 7/8] fix normals --- Assets/Scenes/SampleScene.unity | 106 ---------------- Assets/Shaders/GrassBlade.shader | 2 +- Assets/Shaders/include/GrassBladePass.hlsl | 135 +++++++++++---------- Assets/Shaders/include/GrassHelpers.hlsl | 4 +- 4 files changed, 73 insertions(+), 174 deletions(-) diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index 97cbab5..e1a64d5 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -241020,111 +241020,6 @@ Mesh: offset: 0 size: 0 path: ---- !u!1 &1663409491 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1663409495} - - component: {fileID: 1663409494} - - component: {fileID: 1663409493} - - component: {fileID: 1663409492} - m_Layer: 0 - m_Name: Cube - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!65 &1663409492 -BoxCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1663409491} - m_Material: {fileID: 0} - m_IncludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_ExcludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_LayerOverridePriority: 0 - m_IsTrigger: 0 - m_ProvidesContacts: 0 - m_Enabled: 1 - serializedVersion: 3 - m_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} ---- !u!23 &1663409493 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1663409491} - 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: 944161d6703f1e244a9216da9f82501b, 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 &1663409494 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1663409491} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!4 &1663409495 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1663409491} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 7.656, y: 0.872, z: 0.544} - 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!43 &1663750196 Mesh: m_ObjectHideFlags: 0 @@ -308734,4 +308629,3 @@ SceneRoots: - {fileID: 2016058937} - {fileID: 513204364} - {fileID: 934953871} - - {fileID: 1663409495} diff --git a/Assets/Shaders/GrassBlade.shader b/Assets/Shaders/GrassBlade.shader index d5cb8f6..094ea57 100644 --- a/Assets/Shaders/GrassBlade.shader +++ b/Assets/Shaders/GrassBlade.shader @@ -24,7 +24,7 @@ } SubShader { LOD 100 - // Cull Off + Cull Off //Render Pass Pass { diff --git a/Assets/Shaders/include/GrassBladePass.hlsl b/Assets/Shaders/include/GrassBladePass.hlsl index 9998f3c..a8dd538 100644 --- a/Assets/Shaders/include/GrassBladePass.hlsl +++ b/Assets/Shaders/include/GrassBladePass.hlsl @@ -24,7 +24,7 @@ struct v2g { struct g2f { float4 pos : SV_POSITION; #ifdef IS_IN_BASE_PASS - float3 normal : NORMAL; + float3 localNormal : NORMAL; float2 uv : TEXCOORD0; // bottom left 0.0 top right 1.1 (values converge - 0 and 1 meet at the tip) SHADOW_COORDS(1) // put shadows data into TEXCOORD1 float3 worldPos : TEXCOORD2; @@ -40,10 +40,6 @@ v2g vert (MeshData v) { return o; } -float getCameraDistance(float3 pos) { - return distance(_MainCameraPosition, pos); -} - #if _LOD_LOD_0 [MaxVertexCount(4 + ( 11 - 1 ) * 2)] #elif _LOD_LOD_1 @@ -56,7 +52,6 @@ float getCameraDistance(float3 pos) { void geom(point v2g IN[1], inout TriangleStream triStream) { const float3 basePos = IN[0].vertex.xyz; const float3 tipOffset = IN[0].tipOffset; - const float3 tipPosObjectSpace = basePos + tipOffset; // const float4 basePosClipSpace = UnityObjectToClipPos(float4(basePos, 1)); // const float4 tipPosClipSpace = UnityObjectToClipPos(float4(tipPosObjectSpace, 1)); @@ -64,9 +59,9 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { const float3 basePosWS = mul(unity_ObjectToWorld, float4(basePos.xyz, 1.0)).xyz; - const float cameraDistance = getCameraDistance(basePosWS); + const float mainCamDist = distance(_MainCameraPosition, basePosWS); - float interpolator = invLerp(_TransitionRange.x, _TransitionRange.y, cameraDistance); + float interpolator = invLerp(_TransitionRange.x, _TransitionRange.y, mainCamDist); float halfWidth = _BladeWidth/2; @@ -78,18 +73,16 @@ void geom(point v2g IN[1], inout TriangleStream 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 +#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 +#endif +#endif g2f o; o.debug = float3(0,0,0); - - float3 previousSegmentCenter = basePos - float3(0,-1,0); // point beneath the basePos int numSegments; #if _LOD_LOD_0 @@ -102,13 +95,12 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { numSegments = 1; #endif - float3 localCameraPos = mul(unity_WorldToObject, float4(_MainCameraPosition.xyz, 1.0)).xyz; const float lowerThickness = 0.8; // LOD 3 has a different algorithm #if _LOD_LOD_3 const float segmentWidth = halfWidth * pow(sin(lowerThickness * 3.141), .8); - const float3 widthOffset = getWidthOffset(segmentWidth, tipOffset.xz) * max(1, cameraDistance / 10); + const float3 widthOffset = getWidthOffset(tipOffset.xz) * segmentWidth * max(1, mainCamDist / 10); float3 segmentCenterBase = basePos; float3 segmentCenterTip = basePos + tipOffset; const float3 vertLeftBase = segmentCenterBase + widthOffset * 2.5; @@ -118,22 +110,13 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { const float3 surfTangent1 = vertRightBase - segmentCenterTip; const float3 surfTangent2 = vertLeftBase - segmentCenterTip; - const float3 normal = normalize(cross(surfTangent1, surfTangent2)); // TODO remove normalize - float3 normalWS = UnityObjectToWorldNormal(normal); - - const float3 camVec = normalize(segmentCenterTip - localCameraPos); - - // at which side of the blade are we looking? - const bool lookingFromAbove = dot(camVec, normal) > 0; - if (lookingFromAbove) { - // normalWS = -normalWS; - } + const float3 normal = cross(surfTangent1, surfTangent2); o.pos = UnityObjectToClipPos(vertRightBase); #ifdef IS_IN_BASE_PASS o.uv = float2(1, 0); TRANSFER_SHADOW(o) - o.normal = normalWS; + o.localNormal = normal; o.worldPos = mul(unity_ObjectToWorld, float4(vertRightBase,1.0)).xyz; #endif triStream.Append(o); @@ -142,7 +125,7 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { #ifdef IS_IN_BASE_PASS o.uv = float2(0, 0); TRANSFER_SHADOW(o) - o.normal = normalWS; + o.localNormal = normal; o.worldPos = mul(unity_ObjectToWorld, float4(vertLeftBase,1.0)).xyz; #endif triStream.Append(o); @@ -151,7 +134,7 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { #ifdef IS_IN_BASE_PASS o.uv = float2(1, 1); TRANSFER_SHADOW(o) - o.normal = normalWS; + o.localNormal = normal; o.worldPos = mul(unity_ObjectToWorld, float4(vertRightTip,1.0)).xyz; #endif triStream.Append(o); @@ -160,83 +143,105 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { #ifdef IS_IN_BASE_PASS o.uv = float2(0, 1); TRANSFER_SHADOW(o) - o.normal = normalWS; + o.localNormal = normal; o.worldPos = mul(unity_ObjectToWorld, float4(vertLeftTip,1.0)).xyz; #endif triStream.Append(o); #else - for (int i = 0; i < numSegments; i++) { - // in "blade space" - const float segmentWidth = halfWidth * pow(sin(lowerThickness * 3.141 * (numSegments - i) / numSegments), .8); - const float segmentHeightNormalized = i / (float)numSegments; - // float nextSegmentHeightNormalized = (i+1) / (float)numSegments; + const float3 widthOffset = getWidthOffset(tipOffset.xz) * max(1, mainCamDist / 10); - // generate new verts - const float3 widthOffset = getWidthOffset(segmentWidth, tipOffset.xz) * max(1, cameraDistance / 10); - float3 segmentCenter = basePos + bendParabula(tipOffset, segmentHeightNormalized, _BendStrength); - const float3 segmentCenterSnapshot = segmentCenter; - - const float3 vertLeft = segmentCenter + widthOffset; - const float3 vertRight = segmentCenter - widthOffset; - //const float3 nextSegmentCenter = basePos + bendParabula(tipPos, nextSegmentHeight01); + // previous vertex positions, used for normal calculation + float3 previousVertLeft; + float3 previousVertRight; + for (int i = 0; i < numSegments; i++) { + const float segmentWidth = halfWidth * pow(sin(lowerThickness * 3.141 * (numSegments - i) / numSegments), .8); + const float3 segmentWidthOffset = widthOffset * segmentWidth; + const float segmentHeightNormalized = i / (float)numSegments; + + const float3 segmentCenter = basePos + bendParabula(tipOffset, segmentHeightNormalized, _BendStrength); + const float3 vertLeft = segmentCenter + segmentWidthOffset; + const float3 vertRight = segmentCenter - segmentWidthOffset; #ifdef IS_IN_BASE_PASS // calculate normal - const float3 surfTangent1 = previousSegmentCenter - segmentCenter; - const float3 surfTangent2 = previousSegmentCenter - vertLeft; - const float3 normal = normalize(cross(surfTangent1, surfTangent2)); // TODO remove normalize - float3 normalWS = UnityObjectToWorldNormal(normal); - - const float3 camVec = normalize(segmentCenter - localCameraPos); - - // at which side of the blade are we looking? - const bool lookingFromAbove = dot(camVec, normalWS) > 0; - if (lookingFromAbove) { - normalWS = -normalWS; + float3 surfTangent1, surfTangent2; + if (i == 0) { + // for the normals at the bottom vertices, use the normals of the next segment + const float nextSegmentHeightNormalized = (i+1) / (float)numSegments; + const float3 nextSegmentCenter = basePos + bendParabula(tipOffset, nextSegmentHeightNormalized, _BendStrength); + surfTangent1 = nextSegmentCenter - vertRight; + surfTangent2 = nextSegmentCenter - vertLeft; } + else { + surfTangent1 = segmentCenter - previousVertRight; + surfTangent2 = segmentCenter - previousVertLeft; + } + const float3 normal = cross(surfTangent1, surfTangent2); + + // TODO fake curvature + // o.localNormal = normalize(lerp(normalWS, UnityObjectToWorldNormal(-normalize(segmentWidthOffset)), _BladeBow)); + + previousVertLeft = vertLeft; + previousVertRight = vertRight; #endif + o.pos = UnityObjectToClipPos(vertRight); #ifdef IS_IN_BASE_PASS o.uv = float2(1, segmentHeightNormalized); TRANSFER_SHADOW(o) - o.normal = normalize(lerp(normalWS, UnityObjectToWorldNormal(-normalize(widthOffset)), _BladeBow)); + o.localNormal = normal; o.worldPos = mul(unity_ObjectToWorld, float4(vertRight,1.0)).xyz; #endif triStream.Append(o); - previousSegmentCenter = segmentCenterSnapshot; o.pos = UnityObjectToClipPos(vertLeft); #ifdef IS_IN_BASE_PASS o.uv = float2(0, segmentHeightNormalized); TRANSFER_SHADOW(o) - o.normal = normalize(lerp(normalWS, UnityObjectToWorldNormal(normalize(widthOffset)), _BladeBow)); + o.localNormal = normal; o.worldPos = mul(unity_ObjectToWorld, float4(vertLeft,1.0)).xyz; #endif triStream.Append(o); } -#endif - - o.pos = UnityObjectToClipPos(basePos + tipOffset * float3(_BendStrength, 1, _BendStrength)); + // tip vertex + const float3 tipPosObjectSpace = basePos + tipOffset; + const float3 surfTangent1 = tipPosObjectSpace - previousVertRight; + const float3 surfTangent2 = tipPosObjectSpace - previousVertLeft; + const float3 normal = cross(surfTangent1, surfTangent2); + o.pos = UnityObjectToClipPos(tipPosObjectSpace * float3(_BendStrength, 1, _BendStrength)); #ifdef IS_IN_BASE_PASS o.uv = float2(.5, 1); TRANSFER_SHADOW(o) - o.normal = o.normal > 0 ? float3(0, 1, 0) : float3(0, -1, 0); + o.localNormal = normal; + o.worldPos = mul(unity_ObjectToWorld, float4(tipPosObjectSpace,1.0)).xyz; #endif triStream.Append(o); + +#endif } float4 frag(g2f i) : SV_Target{ #ifdef IS_IN_BASE_PASS float3 localPos = mul(unity_WorldToObject, float4(i.worldPos, 1)).xyz; - float d = distance(localPos, i.debug) * 5; - return float4(i.debug, 1); + float d = distance(localPos, i.debug) * 50; + float k = frac(d); + // return float4(k,k,k, 1); + // return float4(i.debug,1); + + float3 worldNormal = UnityObjectToWorldNormal(i.localNormal); + float3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos)); + + // at which side of the blade are we looking? + // NOT ACCURATE, because the normals don't exactly match the geometry + const bool lookingFromAbove = dot(worldViewDir, worldNormal) > 0; + if (!lookingFromAbove) { + worldNormal = -worldNormal; + } - float3 worldNormal = normalize(i.normal); float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz); - float3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos)); float3 worldRefl = reflect(-worldViewDir, worldNormal); // same as in previous shader diff --git a/Assets/Shaders/include/GrassHelpers.hlsl b/Assets/Shaders/include/GrassHelpers.hlsl index 269252a..224c9ba 100644 --- a/Assets/Shaders/include/GrassHelpers.hlsl +++ b/Assets/Shaders/include/GrassHelpers.hlsl @@ -1,7 +1,7 @@ // tipPos2D = xz coordinates of tip -float3 getWidthOffset(float width, float2 tipPos2D) { +float3 getWidthOffset(float2 tipPos2D) { float2 dirBaseToTip = normalize(tipPos2D); - return float3(-dirBaseToTip.y * width, 0, dirBaseToTip.x * width); + return float3(-dirBaseToTip.y, 0, dirBaseToTip.x); } float3 bendParabula(float3 tipPos, float posOnBlade, float bendStrength) { From b35f8bd478778af7ca50eff8438f3f59b5d486df Mon Sep 17 00:00:00 2001 From: Timo Eberl Date: Sun, 31 Aug 2025 18:47:57 +0200 Subject: [PATCH 8/8] curved normals and some other stuff. lighting is done, but looks bad still --- Assets/Materials/Grass.mat | 7 ++- .../Scripts/MainCameraPositionShaderSetter.cs | 1 + Assets/Shaders/GrassBlade.shader | 9 +-- Assets/Shaders/include/GrassBladePass.hlsl | 63 ++++++++++--------- 4 files changed, 42 insertions(+), 38 deletions(-) diff --git a/Assets/Materials/Grass.mat b/Assets/Materials/Grass.mat index 2be98ad..5660b27 100644 --- a/Assets/Materials/Grass.mat +++ b/Assets/Materials/Grass.mat @@ -28,6 +28,10 @@ Material: m_Texture: {fileID: 2800000, guid: bbec7f79ed7356243ae0604d95144b77, type: 3} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} + - _FieldColor: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} - _FrabVarianz: m_Texture: {fileID: 2800000, guid: 9bb4e817f09d0ea4cbab03f772e01910, type: 3} m_Scale: {x: 1, y: 1} @@ -38,9 +42,10 @@ Material: - _BendStrength: 1 - _BladeBow: 0.195 - _BladeWidth: 0.0274 - - _BladeWidthTexStrength: 1 + - _BladeWidthTexStrength: 0.74 - _LOD: 0 - _Metallic: 0 + - _NormalCurvature: 1 - _Roughness: 0 - _SSSStrength: 1 - _Translucency: 1.81 diff --git a/Assets/Scripts/MainCameraPositionShaderSetter.cs b/Assets/Scripts/MainCameraPositionShaderSetter.cs index 62868c3..5aaadce 100644 --- a/Assets/Scripts/MainCameraPositionShaderSetter.cs +++ b/Assets/Scripts/MainCameraPositionShaderSetter.cs @@ -1,3 +1,4 @@ +using System; using UnityEngine; using UnityEditor; diff --git a/Assets/Shaders/GrassBlade.shader b/Assets/Shaders/GrassBlade.shader index 094ea57..20adef0 100644 --- a/Assets/Shaders/GrassBlade.shader +++ b/Assets/Shaders/GrassBlade.shader @@ -5,7 +5,7 @@ _BladeWidth("Blade Width", Range(0.003, .1)) = 0.01 _BendStrength("Bend Strength", Range(0, 1)) = 1 - _FrabVarianz("Farb Varianz", 2D) = "white" {} + _FieldColor("Field Color", 2D) = "white" {} _BladeWidthTex("Blade Width Texture", 2D) = "white" {} _AOStrength("Ambient Occlusion Strength", Range(0,2)) = 1 @@ -13,14 +13,9 @@ _SSSStrength("Subsurface Scattering Strength", Range(0,1)) = 1 _Metallic("Metallic", Range(0,1)) = 0 _Roughness("Roughness", Range(0,1)) = 0.3 - _BladeBow("Blade Bow", Range(0,1)) = 0.3 + _NormalCurvature("Normal Curvature", Range(0,1)) = 0.3 _BladeWidthTexStrength("BladeWidthTexStrength", Range(0,1)) = 0.3 _InnerColor("Inner Color", Color) = (1,1,1,1) - - _Color0("Color LOD 0", Color) = (0.3, 1.0, 0.3, 1.0) - _Color1("Color LOD 1", Color) = (1.0, 0.7, 0.3, 1.0) - _Color2("Color LOD 2", Color) = (1.0, 0.3, 0.1, 1.0) - _Color3("Color LOD 3", Color) = (0.8, 0.0, 0.0, 1.0) } SubShader { LOD 100 diff --git a/Assets/Shaders/include/GrassBladePass.hlsl b/Assets/Shaders/include/GrassBladePass.hlsl index a8dd538..3150167 100644 --- a/Assets/Shaders/include/GrassBladePass.hlsl +++ b/Assets/Shaders/include/GrassBladePass.hlsl @@ -1,9 +1,8 @@ // Material Properties float _BladeWidth, _BendStrength; -float4 _Color0, _Color1, _Color2, _Color3, _InnerColor; -float _SegmentsMinusOne, _FieldSize, _AOStrength, _Translucency, _SSSStrength, _Metallic, _Roughness, - _BladeBow, _MaxBladeHeight, _HighlightStrength, _BladeWidthTexStrength; -sampler2D _FrabVarianz, _BladeWidthTex; +float4 _InnerColor; +float _AOStrength, _Translucency, _SSSStrength, _Metallic, _Roughness, _NormalCurvature, _BladeWidthTexStrength; +sampler2D _FieldColor, _BladeWidthTex; float2 _TransitionRange; @@ -179,8 +178,15 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { } const float3 normal = cross(surfTangent1, surfTangent2); - // TODO fake curvature - // o.localNormal = normalize(lerp(normalWS, UnityObjectToWorldNormal(-normalize(segmentWidthOffset)), _BladeBow)); +#if _LOD_LOD_0 + const float curvature = _NormalCurvature; +#elif _LOD_LOD_1 + const float curvature = 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); previousVertLeft = vertLeft; previousVertRight = vertRight; @@ -190,7 +196,7 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { #ifdef IS_IN_BASE_PASS o.uv = float2(1, segmentHeightNormalized); TRANSFER_SHADOW(o) - o.localNormal = normal; + o.localNormal = rightCurvedNormal; o.worldPos = mul(unity_ObjectToWorld, float4(vertRight,1.0)).xyz; #endif triStream.Append(o); @@ -199,7 +205,7 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { #ifdef IS_IN_BASE_PASS o.uv = float2(0, segmentHeightNormalized); TRANSFER_SHADOW(o) - o.localNormal = normal; + o.localNormal = leftCurvedNormal; o.worldPos = mul(unity_ObjectToWorld, float4(vertLeft,1.0)).xyz; #endif triStream.Append(o); @@ -222,7 +228,7 @@ void geom(point v2g IN[1], inout TriangleStream triStream) { #endif } -float4 frag(g2f i) : SV_Target{ +float4 frag(g2f i, bool isFrontFace : SV_IsFrontFace) : SV_Target { #ifdef IS_IN_BASE_PASS float3 localPos = mul(unity_WorldToObject, float4(i.worldPos, 1)).xyz; float d = distance(localPos, i.debug) * 50; @@ -231,57 +237,54 @@ float4 frag(g2f i) : SV_Target{ // return float4(i.debug,1); float3 worldNormal = UnityObjectToWorldNormal(i.localNormal); - float3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos)); // at which side of the blade are we looking? - // NOT ACCURATE, because the normals don't exactly match the geometry - const bool lookingFromAbove = dot(worldViewDir, worldNormal) > 0; - if (!lookingFromAbove) { + // VERY INACCURATE, because the normals don't match the geometry (smoothing, fake curvature) + if (!isFrontFace) { worldNormal = -worldNormal; } float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz); + float3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos)); float3 worldRefl = reflect(-worldViewDir, worldNormal); - // same as in previous shader - half4 skyData = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, worldRefl, 0); + float4 skyData = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, worldRefl, 0); float3 skyColor = DecodeHDR(skyData, unity_SpecCube0_HDR); float3 lightReflectDirection = reflect(-lightDirection, worldNormal); float3 viewDirection = normalize(float3(float4(_MainCameraPosition.xyz, 1.0) - i.worldPos.xyz)); - - float atten = 1.0; - float3 translucency = atten * _LightColor0.xyz * max(0.0, dot(worldNormal, -lightDirection)) * _Translucency; + float3 translucency = _LightColor0.xyz * max(0.0, dot(worldNormal, -lightDirection)) * _Translucency; float3 subsurf = max(0.0, dot(lightReflectDirection, -viewDirection)) * _SSSStrength * _InnerColor; - const fixed shadow = SHADOW_ATTENUATION(i); + const float shadow = max(.35, SHADOW_ATTENUATION(i)); float3 lightFinal = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, worldNormal, 2.0); lightFinal += translucency; lightFinal += subsurf; - lightFinal *= max(.35, shadow); - lightFinal *= 1.0; + lightFinal *= shadow; + + // 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); float4 col = max(0.87, pow(middleCol, .01)); - float4 farbvarianz = tex2Dlod(_FrabVarianz, float4(i.worldPos.xz / 40, 0, 3)); - float4 farbvarianz2 = tex2Dlod(_FrabVarianz, float4(i.worldPos.xz / 10, 0, 3)); - float4 farbvarianz3 = tex2Dlod(_FrabVarianz, float4(i.worldPos.xz / 3, 0, 3)); + float3 c0 = tex2Dlod(_FieldColor, float4(i.worldPos.xz / 40, 0, 3)).xyz; + float3 c1 = tex2Dlod(_FieldColor, float4(i.worldPos.xz / 10, 0, 3)).xyz; + float3 c2 = tex2Dlod(_FieldColor, float4(i.worldPos.xz / 3, 0, 3)).xyz; float4 bladeWidthTex = tex2Dlod(_BladeWidthTex, float4(i.uv.x, 0, 0, 3)); - float4 albedo = lerp(farbvarianz2, farbvarianz3, 0.4); - albedo = lerp(albedo, farbvarianz, _Metallic) * 0.7; + 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); - fixed3 color = fixed3(skyColor * max(.35, shadow) * .2 + lightFinal * albedo * col); - fixed3 highlightedColor = lerp(color, fixed3(2.5, 0.7, 0.5), 0.5); - fixed3 finalTestColor = albedo.xyz ; + 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(worldNormal, 1); + return float4(color, 1); #endif return 0; // shadow pass }