diff options
Diffstat (limited to 'Scripts')
| -rw-r--r--[-rwxr-xr-x] | Scripts/DataDecoder.asset | 0 | ||||
| -rwxr-xr-x | Scripts/Fold/Editor/FoldEditorWindow.cs | 180 | ||||
| -rwxr-xr-x | Scripts/Fold/Editor/FoldPipelineBuilder.cs | 58 | ||||
| -rwxr-xr-x[-rw-r--r--] | Scripts/GrassGridBlit.shader | 0 | ||||
| -rw-r--r--[-rwxr-xr-x] | Scripts/InstanceGrass.asset | 348 | ||||
| -rwxr-xr-x | Scripts/InstanceGrass.cs | 70 |
6 files changed, 434 insertions, 222 deletions
diff --git a/Scripts/DataDecoder.asset b/Scripts/DataDecoder.asset index b8be961..b8be961 100755..100644 --- a/Scripts/DataDecoder.asset +++ b/Scripts/DataDecoder.asset diff --git a/Scripts/Fold/Editor/FoldEditorWindow.cs b/Scripts/Fold/Editor/FoldEditorWindow.cs index ab02781..b174b54 100755 --- a/Scripts/Fold/Editor/FoldEditorWindow.cs +++ b/Scripts/Fold/Editor/FoldEditorWindow.cs @@ -18,11 +18,6 @@ public class FoldEditorWindow : EditorWindow window.minSize = new Vector2(400, 300); } - void OnEnable() - { - // Operations list is restored via SerializeReference - } - void OnGUI() { EditorGUILayout.Space(5); @@ -86,9 +81,6 @@ public class FoldEditorWindow : EditorWindow liveUpdate = GUILayout.Toggle(liveUpdate, "Live", EditorStyles.toolbarButton, GUILayout.Width(40)); - if (GUILayout.Button("Load Presets", EditorStyles.toolbarDropDown, GUILayout.Width(100))) - ShowPresetsMenu(); - EditorGUILayout.EndHorizontal(); } @@ -217,6 +209,7 @@ public class FoldEditorWindow : EditorWindow menu.AddItem(new GUIContent("Point Align"), false, () => AddOperation(new PointAlignOp())); menu.AddItem(new GUIContent("Axis Align"), false, () => AddOperation(new AxisAlignOp())); menu.AddSeparator(""); + menu.AddItem(new GUIContent("Scale"), false, () => AddOperation(new ScaleOp())); menu.AddItem(new GUIContent("Norm Conversion"), false, () => AddOperation(new NormConversionOp())); menu.AddItem(new GUIContent("Seal"), false, () => AddOperation(new SealOp())); menu.AddSeparator(""); @@ -226,23 +219,6 @@ public class FoldEditorWindow : EditorWindow menu.ShowAsContext(); } - void ShowPresetsMenu() - { - var menu = new GenericMenu(); - - menu.AddItem(new GUIContent("Tube to Plane"), false, () => LoadPreset_TubeToPlane()); - menu.AddItem(new GUIContent("Plane to Tube"), false, () => LoadPreset_PlaneToTube()); - menu.AddItem(new GUIContent("Plane to Hemi-Octahedron"), false, () => LoadPreset_PlaneToHemiOct()); - menu.AddSeparator(""); - menu.AddItem(new GUIContent("Norm: L1→L2 (Diamond→Sphere)"), false, () => LoadPreset_NormL1L2()); - menu.AddItem(new GUIContent("Norm: L2→L1 (Sphere→Diamond)"), false, () => LoadPreset_NormL2L1()); - menu.AddItem(new GUIContent("Norm: L2→L∞ (Sphere→Cube)"), false, () => LoadPreset_NormL2Linf()); - menu.AddSeparator(""); - menu.AddItem(new GUIContent("Complex/Tube→Plane + Norm Conv"), false, () => LoadPreset_TubePlaneNorm()); - - menu.ShowAsContext(); - } - void AddOperation(DeformOperation op) { if (operations.Count >= 16) @@ -251,68 +227,6 @@ public class FoldEditorWindow : EditorWindow expandedOps.Add(operations.Count - 1); } - void LoadPreset_TubeToPlane() - { - operations.Clear(); - expandedOps.Clear(); - AddOperation(new TubeToPlaneOp()); - } - - void LoadPreset_PlaneToTube() - { - operations.Clear(); - expandedOps.Clear(); - AddOperation(new PlaneToTubeOp()); - } - - void LoadPreset_PlaneToHemiOct() - { - operations.Clear(); - expandedOps.Clear(); - AddOperation(new PlaneToHemiOctahedronOp()); - } - - void LoadPreset_NormL1L2() - { - operations.Clear(); - expandedOps.Clear(); - var op = new NormConversionOp(); - op.inputK = 1f; - op.outputK = 2f; - AddOperation(op); - } - - void LoadPreset_NormL2L1() - { - operations.Clear(); - expandedOps.Clear(); - var op = new NormConversionOp(); - op.inputK = 2f; - op.outputK = 1f; - AddOperation(op); - } - - void LoadPreset_NormL2Linf() - { - operations.Clear(); - expandedOps.Clear(); - var op = new NormConversionOp(); - op.inputK = 2f; - op.outputK = float.PositiveInfinity; - AddOperation(op); - } - - void LoadPreset_TubePlaneNorm() - { - operations.Clear(); - expandedOps.Clear(); - AddOperation(new TubeToPlaneOp()); - var norm = new NormConversionOp(); - norm.inputK = 2f; - norm.outputK = 1f; - AddOperation(norm); - } - void ApplyToMaterial() { var builder = FoldPipelineBuilder.Create().For(targetMaterial); @@ -325,10 +239,53 @@ public class FoldEditorWindow : EditorWindow void LoadFromMaterial() { - // Could potentially read back from material properties here - // For now, just clear the list operations.Clear(); expandedOps.Clear(); + + for (int i = 0; i < 16; i++) + { + var prefix = $"_Vertex_Deformation_Slot_{i}_"; + if (targetMaterial.GetFloat(prefix + "Enabled") < 0.5f) + break; + + int opcode = targetMaterial.GetInteger(prefix + "Opcode"); + if (opcode == FoldPipelineBuilder.Opcodes.None) + break; + + var slot = new FoldSlot + { + opcode = opcode, + float0 = targetMaterial.GetFloat(prefix + "Float_0"), + float1 = targetMaterial.GetFloat(prefix + "Float_1"), + float2 = targetMaterial.GetFloat(prefix + "Float_2"), + float3 = targetMaterial.GetFloat(prefix + "Float_3"), + vec0 = targetMaterial.GetVector(prefix + "Vector_0"), + vec1 = targetMaterial.GetVector(prefix + "Vector_1"), + vec2 = targetMaterial.GetVector(prefix + "Vector_2"), + vec3 = targetMaterial.GetVector(prefix + "Vector_3"), + }; + + DeformOperation op = opcode switch + { + FoldPipelineBuilder.Opcodes.TubeToPlane => new TubeToPlaneOp(slot), + FoldPipelineBuilder.Opcodes.PlaneToTube => new PlaneToTubeOp(slot), + FoldPipelineBuilder.Opcodes.PlaneToHemiOctahedron => new PlaneToHemiOctahedronOp(slot), + FoldPipelineBuilder.Opcodes.HemiOctahedronToPlane => new HemiOctahedronToPlaneOp(slot), + FoldPipelineBuilder.Opcodes.Scale => new ScaleOp(slot), + FoldPipelineBuilder.Opcodes.PointAlign => new PointAlignOp(slot), + FoldPipelineBuilder.Opcodes.AxisAlign => new AxisAlignOp(slot), + FoldPipelineBuilder.Opcodes.NormConversion => new NormConversionOp(slot), + FoldPipelineBuilder.Opcodes.Seal => new SealOp(slot), + FoldPipelineBuilder.Opcodes.SineWaves => new SineWavesOp(), + FoldPipelineBuilder.Opcodes.FBM => new FBMOp(), + _ => null + }; + + if (op == null) + break; + + operations.Add(op); + } } } @@ -349,6 +306,9 @@ public class TubeToPlaneOp : DeformOperation public Vector3 s = Vector3.forward; public float t = 1f; + public TubeToPlaneOp() { } + public TubeToPlaneOp(FoldSlot slot) { p = slot.vec0; r = slot.vec1; s = slot.vec2; t = slot.float0; } + public override string GetDisplayName() => "Tube to Plane"; public override void DrawParameters() @@ -371,6 +331,9 @@ public class PlaneToTubeOp : DeformOperation public Vector3 s = Vector3.forward; public float t = 1f; + public PlaneToTubeOp() { } + public PlaneToTubeOp(FoldSlot slot) { p = slot.vec0; r = slot.vec1; s = slot.vec2; t = slot.float0; } + public override string GetDisplayName() => "Plane to Tube"; public override void DrawParameters() @@ -393,6 +356,9 @@ public class PlaneToHemiOctahedronOp : DeformOperation public Vector3 s = Vector3.forward; public float t = 1f; + public PlaneToHemiOctahedronOp() { } + public PlaneToHemiOctahedronOp(FoldSlot slot) { p = slot.vec0; r = slot.vec1; s = slot.vec2; t = slot.float0; } + public override string GetDisplayName() => "Plane to Hemi-Octahedron"; public override void DrawParameters() @@ -408,6 +374,27 @@ public class PlaneToHemiOctahedronOp : DeformOperation } [System.Serializable] +public class ScaleOp : DeformOperation +{ + public Vector3 k = Vector3.one; + public float t = 1f; + + public ScaleOp() { } + public ScaleOp(FoldSlot slot) { k = slot.vec0; t = slot.float0; } + + public override string GetDisplayName() => "Scale"; + + public override void DrawParameters() + { + k = EditorGUILayout.Vector3Field("Scale", k); + t = EditorGUILayout.Slider("Interpolation (t)", t, 0f, 1f); + } + + public override void ApplyTo(FoldPipelineBuilder builder) => + builder.Scale(k, t); +} + +[System.Serializable] public class HemiOctahedronToPlaneOp : DeformOperation { public Vector3 p = Vector3.zero; @@ -415,6 +402,9 @@ public class HemiOctahedronToPlaneOp : DeformOperation public Vector3 s = Vector3.forward; public float t = 1f; + public HemiOctahedronToPlaneOp() { } + public HemiOctahedronToPlaneOp(FoldSlot slot) { p = slot.vec0; r = slot.vec1; s = slot.vec2; t = slot.float0; } + public override string GetDisplayName() => "Hemi-Octahedron to Plane"; public override void DrawParameters() @@ -437,6 +427,9 @@ public class PointAlignOp : DeformOperation public Vector3 r = Vector3.right; public float t = 1f; + public PointAlignOp() { } + public PointAlignOp(FoldSlot slot) { po = slot.vec0; pp = slot.vec1; r = slot.vec2; t = slot.float0; } + public override string GetDisplayName() => "Point Align"; public override void DrawParameters() @@ -459,6 +452,9 @@ public class AxisAlignOp : DeformOperation public Vector3 r = Vector3.right; public float t = 1f; + public AxisAlignOp() { } + public AxisAlignOp(FoldSlot slot) { po = slot.vec0; pp = slot.vec1; r = slot.vec2; t = slot.float0; } + public override string GetDisplayName() => "Axis Align"; public override void DrawParameters() @@ -480,6 +476,9 @@ public class NormConversionOp : DeformOperation public float outputK = 1f; public float t = 1f; + public NormConversionOp() { } + public NormConversionOp(FoldSlot slot) { inputK = slot.float0; outputK = slot.float1; t = slot.float2; } + public override string GetDisplayName() => $"Norm Conversion (L{FormatNorm(inputK)}→L{FormatNorm(outputK)})"; string FormatNorm(float k) @@ -521,6 +520,9 @@ public class SealOp : DeformOperation public float st = 0.8f; public float t = 1f; + public SealOp() { } + public SealOp(FoldSlot slot) { A = slot.float0; k = slot.float1; st = slot.float2; t = slot.float3; } + public override string GetDisplayName() => "Seal"; public override void DrawParameters() diff --git a/Scripts/Fold/Editor/FoldPipelineBuilder.cs b/Scripts/Fold/Editor/FoldPipelineBuilder.cs index 3731cf8..85a7a4f 100755 --- a/Scripts/Fold/Editor/FoldPipelineBuilder.cs +++ b/Scripts/Fold/Editor/FoldPipelineBuilder.cs @@ -58,6 +58,7 @@ public class FoldPipelineBuilder public const int FBM = 8; public const int PlaneToHemiOctahedron = 9; public const int HemiOctahedronToPlane = 10; + public const int Scale = 11; } FoldPipelineBuilder() { } @@ -109,6 +110,17 @@ public class FoldPipelineBuilder return this; } + public FoldPipelineBuilder Scale(Vector3 k, float t) + { + slots.Add(new FoldSlot + { + opcode = Opcodes.Scale, + vec0 = k, + float0 = t + }); + return this; + } + public FoldPipelineBuilder HemiOctahedronToPlane(Vector3 p, Vector3 r, Vector3 s, float t) { slots.Add(new FoldSlot @@ -236,49 +248,3 @@ public class FoldPipelineBuilder public int Count => slots.Count; } - -public static class FoldPresets -{ - public static void TubeToPlaneFull(Material mat) => - FoldPipelineBuilder.Create() - .For(mat) - .TubeToPlane(Vector3.zero, Vector3.right, Vector3.forward, 1f) - .Apply(); - - public static void PlaneToTubeFull(Material mat) => - FoldPipelineBuilder.Create() - .For(mat) - .PlaneToTube(Vector3.zero, Vector3.right, Vector3.forward, 1f) - .Apply(); - - public static void PlaneToHemiOctahedronFull(Material mat) => - FoldPipelineBuilder.Create() - .For(mat) - .PlaneToHemiOctahedron(Vector3.zero, Vector3.right, Vector3.forward, 1f) - .Apply(); - - public static void TubeToPlaneThenNormConv(Material mat) => - FoldPipelineBuilder.Create() - .For(mat) - .TubeToPlane(Vector3.zero, Vector3.right, Vector3.forward, 1f) - .NormConversion(2f, 1f, 1f) - .Apply(); - - public static void NormConvL1ToL2(Material mat) => - FoldPipelineBuilder.Create() - .For(mat) - .NormConversion(1f, 2f, 1f) - .Apply(); - - public static void NormConvL2ToL1(Material mat) => - FoldPipelineBuilder.Create() - .For(mat) - .NormConversion(2f, 1f, 1f) - .Apply(); - - public static void NormConvL2ToLinf(Material mat) => - FoldPipelineBuilder.Create() - .For(mat) - .NormConversion(2f, float.PositiveInfinity, 1f) - .Apply(); -} diff --git a/Scripts/GrassGridBlit.shader b/Scripts/GrassGridBlit.shader index f4dc872..f4dc872 100644..100755 --- a/Scripts/GrassGridBlit.shader +++ b/Scripts/GrassGridBlit.shader diff --git a/Scripts/InstanceGrass.asset b/Scripts/InstanceGrass.asset index 3dd3bc4..8d50781 100755..100644 --- a/Scripts/InstanceGrass.asset +++ b/Scripts/InstanceGrass.asset @@ -44,7 +44,7 @@ MonoBehaviour: Data: - Name: Entry: 12 - Data: 23 + Data: 27 - Name: Entry: 7 Data: @@ -230,12 +230,66 @@ MonoBehaviour: Data: - Name: $k Entry: 1 - Data: angle_randomization_ + Data: min_distance_ - Name: $v Entry: 7 Data: 14|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 + Data: min_distance_ + - Name: <UserType>k__BackingField + Entry: 9 + Data: 7 + - Name: <SystemType>k__BackingField + Entry: 9 + Data: 7 + - Name: <SyncMode>k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: <IsSerialized>k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 15|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: 16|UnityEngine.SerializeField, UnityEngine.CoreModule + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: angle_randomization_ + - Name: $v + Entry: 7 + Data: 17|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: <Name>k__BackingField + Entry: 1 Data: angle_randomization_ - Name: <UserType>k__BackingField Entry: 9 @@ -257,13 +311,13 @@ MonoBehaviour: Data: true - Name: _fieldAttributes Entry: 7 - Data: 15|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 18|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 1 - Name: Entry: 7 - Data: 16|UnityEngine.SerializeField, UnityEngine.CoreModule + Data: 19|UnityEngine.SerializeField, UnityEngine.CoreModule - Name: Entry: 8 Data: @@ -287,7 +341,7 @@ MonoBehaviour: Data: scale_randomization_ - Name: $v Entry: 7 - Data: 17|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 20|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: scale_randomization_ @@ -311,13 +365,13 @@ MonoBehaviour: Data: true - Name: _fieldAttributes Entry: 7 - Data: 18|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 21|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 1 - Name: Entry: 7 - Data: 19|UnityEngine.SerializeField, UnityEngine.CoreModule + Data: 22|UnityEngine.SerializeField, UnityEngine.CoreModule - Name: Entry: 8 Data: @@ -341,13 +395,13 @@ MonoBehaviour: Data: max_grid_size_ - Name: $v Entry: 7 - Data: 20|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 23|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: max_grid_size_ - Name: <UserType>k__BackingField Entry: 7 - Data: 21|System.RuntimeType, mscorlib + Data: 24|System.RuntimeType, mscorlib - Name: Entry: 1 Data: UnityEngine.Vector3Int, UnityEngine.CoreModule @@ -356,7 +410,7 @@ MonoBehaviour: Data: - Name: <SystemType>k__BackingField Entry: 9 - Data: 21 + Data: 24 - Name: <SyncMode>k__BackingField Entry: 7 Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib @@ -371,13 +425,13 @@ MonoBehaviour: Data: true - Name: _fieldAttributes Entry: 7 - Data: 22|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 25|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 1 - Name: Entry: 7 - Data: 23|UnityEngine.SerializeField, UnityEngine.CoreModule + Data: 26|UnityEngine.SerializeField, UnityEngine.CoreModule - Name: Entry: 8 Data: @@ -401,13 +455,13 @@ MonoBehaviour: Data: blit_material_ - Name: $v Entry: 7 - Data: 24|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 27|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: blit_material_ - Name: <UserType>k__BackingField Entry: 7 - Data: 25|System.RuntimeType, mscorlib + Data: 28|System.RuntimeType, mscorlib - Name: Entry: 1 Data: UnityEngine.Material, UnityEngine.CoreModule @@ -416,7 +470,7 @@ MonoBehaviour: Data: - Name: <SystemType>k__BackingField Entry: 9 - Data: 25 + Data: 28 - Name: <SyncMode>k__BackingField Entry: 7 Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib @@ -431,13 +485,13 @@ MonoBehaviour: Data: true - Name: _fieldAttributes Entry: 7 - Data: 26|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 29|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 1 - Name: Entry: 7 - Data: 27|UnityEngine.SerializeField, UnityEngine.CoreModule + Data: 30|UnityEngine.SerializeField, UnityEngine.CoreModule - Name: Entry: 8 Data: @@ -461,13 +515,13 @@ MonoBehaviour: Data: mesh_ - Name: $v Entry: 7 - Data: 28|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 31|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: mesh_ - Name: <UserType>k__BackingField Entry: 7 - Data: 29|System.RuntimeType, mscorlib + Data: 32|System.RuntimeType, mscorlib - Name: Entry: 1 Data: UnityEngine.Mesh, UnityEngine.CoreModule @@ -476,7 +530,7 @@ MonoBehaviour: Data: - Name: <SystemType>k__BackingField Entry: 9 - Data: 29 + Data: 32 - Name: <SyncMode>k__BackingField Entry: 7 Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib @@ -491,7 +545,7 @@ MonoBehaviour: Data: false - Name: _fieldAttributes Entry: 7 - Data: 30|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 33|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 0 @@ -515,16 +569,16 @@ MonoBehaviour: Data: instance_material_ - Name: $v Entry: 7 - Data: 31|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 34|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: instance_material_ - Name: <UserType>k__BackingField Entry: 9 - Data: 25 + Data: 28 - Name: <SystemType>k__BackingField Entry: 9 - Data: 25 + Data: 28 - Name: <SyncMode>k__BackingField Entry: 7 Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib @@ -539,7 +593,7 @@ MonoBehaviour: Data: false - Name: _fieldAttributes Entry: 7 - Data: 32|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 35|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 0 @@ -563,13 +617,13 @@ MonoBehaviour: Data: base_transform_ - Name: $v Entry: 7 - Data: 33|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 36|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: base_transform_ - Name: <UserType>k__BackingField Entry: 7 - Data: 34|System.RuntimeType, mscorlib + Data: 37|System.RuntimeType, mscorlib - Name: Entry: 1 Data: UnityEngine.Transform, UnityEngine.CoreModule @@ -578,7 +632,7 @@ MonoBehaviour: Data: - Name: <SystemType>k__BackingField Entry: 9 - Data: 34 + Data: 37 - Name: <SyncMode>k__BackingField Entry: 7 Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib @@ -593,7 +647,7 @@ MonoBehaviour: Data: false - Name: _fieldAttributes Entry: 7 - Data: 35|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 38|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 0 @@ -617,7 +671,7 @@ MonoBehaviour: Data: cell_dim_ - Name: $v Entry: 7 - Data: 36|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 39|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: cell_dim_ @@ -641,7 +695,7 @@ MonoBehaviour: Data: false - Name: _fieldAttributes Entry: 7 - Data: 37|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 40|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 0 @@ -665,7 +719,7 @@ MonoBehaviour: Data: inv_cell_dim_ - Name: $v Entry: 7 - Data: 38|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 41|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: inv_cell_dim_ @@ -689,7 +743,7 @@ MonoBehaviour: Data: false - Name: _fieldAttributes Entry: 7 - Data: 39|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 42|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 0 @@ -713,16 +767,16 @@ MonoBehaviour: Data: count_ - Name: $v Entry: 7 - Data: 40|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 43|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: count_ - Name: <UserType>k__BackingField Entry: 9 - Data: 21 + Data: 24 - Name: <SystemType>k__BackingField Entry: 9 - Data: 21 + Data: 24 - Name: <SyncMode>k__BackingField Entry: 7 Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib @@ -737,7 +791,7 @@ MonoBehaviour: Data: false - Name: _fieldAttributes Entry: 7 - Data: 41|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 44|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 0 @@ -761,13 +815,13 @@ MonoBehaviour: Data: total_instances_ - Name: $v Entry: 7 - Data: 42|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 45|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: total_instances_ - Name: <UserType>k__BackingField Entry: 7 - Data: 43|System.RuntimeType, mscorlib + Data: 46|System.RuntimeType, mscorlib - Name: Entry: 1 Data: System.Int32, mscorlib @@ -776,7 +830,7 @@ MonoBehaviour: Data: - Name: <SystemType>k__BackingField Entry: 9 - Data: 43 + Data: 46 - Name: <SyncMode>k__BackingField Entry: 7 Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib @@ -791,7 +845,7 @@ MonoBehaviour: Data: false - Name: _fieldAttributes Entry: 7 - Data: 44|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 47|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 0 @@ -815,13 +869,13 @@ MonoBehaviour: Data: initialized_ - Name: $v Entry: 7 - Data: 45|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 48|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: initialized_ - Name: <UserType>k__BackingField Entry: 7 - Data: 46|System.RuntimeType, mscorlib + Data: 49|System.RuntimeType, mscorlib - Name: Entry: 1 Data: System.Boolean, mscorlib @@ -830,7 +884,7 @@ MonoBehaviour: Data: - Name: <SystemType>k__BackingField Entry: 9 - Data: 46 + Data: 49 - Name: <SyncMode>k__BackingField Entry: 7 Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib @@ -845,7 +899,7 @@ MonoBehaviour: Data: false - Name: _fieldAttributes Entry: 7 - Data: 47|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 50|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 0 @@ -869,7 +923,7 @@ MonoBehaviour: Data: density_live_ - Name: $v Entry: 7 - Data: 48|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 51|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: density_live_ @@ -893,7 +947,7 @@ MonoBehaviour: Data: false - Name: _fieldAttributes Entry: 7 - Data: 49|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 52|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 0 @@ -917,7 +971,7 @@ MonoBehaviour: Data: extent_meters_live_ - Name: $v Entry: 7 - Data: 50|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 53|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: extent_meters_live_ @@ -941,7 +995,55 @@ MonoBehaviour: Data: false - Name: _fieldAttributes Entry: 7 - Data: 51|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 54|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: min_distance_live_ + - Name: $v + Entry: 7 + Data: 55|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: <Name>k__BackingField + Entry: 1 + Data: min_distance_live_ + - Name: <UserType>k__BackingField + Entry: 9 + Data: 7 + - Name: <SystemType>k__BackingField + Entry: 9 + Data: 7 + - Name: <SyncMode>k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: <IsSerialized>k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 56|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 0 @@ -965,7 +1067,7 @@ MonoBehaviour: Data: angle_randomization_live_ - Name: $v Entry: 7 - Data: 52|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 57|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: angle_randomization_live_ @@ -989,7 +1091,7 @@ MonoBehaviour: Data: false - Name: _fieldAttributes Entry: 7 - Data: 53|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 58|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 0 @@ -1013,7 +1115,7 @@ MonoBehaviour: Data: scale_randomization_live_ - Name: $v Entry: 7 - Data: 54|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 59|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: scale_randomization_live_ @@ -1037,7 +1139,7 @@ MonoBehaviour: Data: false - Name: _fieldAttributes Entry: 7 - Data: 55|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 60|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 0 @@ -1061,13 +1163,13 @@ MonoBehaviour: Data: instance_data_tex_ - Name: $v Entry: 7 - Data: 56|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 61|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: instance_data_tex_ - Name: <UserType>k__BackingField Entry: 7 - Data: 57|System.RuntimeType, mscorlib + Data: 62|System.RuntimeType, mscorlib - Name: Entry: 1 Data: UnityEngine.RenderTexture, UnityEngine.CoreModule @@ -1076,7 +1178,7 @@ MonoBehaviour: Data: - Name: <SystemType>k__BackingField Entry: 9 - Data: 57 + Data: 62 - Name: <SyncMode>k__BackingField Entry: 7 Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib @@ -1091,7 +1193,7 @@ MonoBehaviour: Data: false - Name: _fieldAttributes Entry: 7 - Data: 58|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 63|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 0 @@ -1115,13 +1217,13 @@ MonoBehaviour: Data: identity_transforms_ - Name: $v Entry: 7 - Data: 59|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 64|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: identity_transforms_ - Name: <UserType>k__BackingField Entry: 7 - Data: 60|System.RuntimeType, mscorlib + Data: 65|System.RuntimeType, mscorlib - Name: Entry: 1 Data: UnityEngine.Matrix4x4[], UnityEngine.CoreModule @@ -1130,7 +1232,7 @@ MonoBehaviour: Data: - Name: <SystemType>k__BackingField Entry: 9 - Data: 60 + Data: 65 - Name: <SyncMode>k__BackingField Entry: 7 Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib @@ -1145,7 +1247,115 @@ MonoBehaviour: Data: false - Name: _fieldAttributes Entry: 7 - Data: 61|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 66|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: instance_ids_ + - Name: $v + Entry: 7 + Data: 67|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: <Name>k__BackingField + Entry: 1 + Data: instance_ids_ + - Name: <UserType>k__BackingField + Entry: 7 + Data: 68|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: System.Single[], mscorlib + - Name: + Entry: 8 + Data: + - Name: <SystemType>k__BackingField + Entry: 9 + Data: 68 + - Name: <SyncMode>k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: <IsSerialized>k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 69|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: instance_properties_ + - Name: $v + Entry: 7 + Data: 70|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: <Name>k__BackingField + Entry: 1 + Data: instance_properties_ + - Name: <UserType>k__BackingField + Entry: 7 + Data: 71|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: UnityEngine.MaterialPropertyBlock, UnityEngine.CoreModule + - Name: + Entry: 8 + Data: + - Name: <SystemType>k__BackingField + Entry: 9 + Data: 71 + - Name: <SyncMode>k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: <IsSerialized>k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 72|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 0 @@ -1169,16 +1379,16 @@ MonoBehaviour: Data: tex_width_ - Name: $v Entry: 7 - Data: 62|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 73|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: tex_width_ - Name: <UserType>k__BackingField Entry: 9 - Data: 43 + Data: 46 - Name: <SystemType>k__BackingField Entry: 9 - Data: 43 + Data: 46 - Name: <SyncMode>k__BackingField Entry: 7 Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib @@ -1193,7 +1403,7 @@ MonoBehaviour: Data: false - Name: _fieldAttributes Entry: 7 - Data: 63|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 74|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 0 @@ -1217,16 +1427,16 @@ MonoBehaviour: Data: tex_height_ - Name: $v Entry: 7 - Data: 64|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + Data: 75|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor - Name: <Name>k__BackingField Entry: 1 Data: tex_height_ - Name: <UserType>k__BackingField Entry: 9 - Data: 43 + Data: 46 - Name: <SystemType>k__BackingField Entry: 9 - Data: 43 + Data: 46 - Name: <SyncMode>k__BackingField Entry: 7 Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib @@ -1241,7 +1451,7 @@ MonoBehaviour: Data: false - Name: _fieldAttributes Entry: 7 - Data: 65|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + Data: 76|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib - Name: Entry: 12 Data: 0 diff --git a/Scripts/InstanceGrass.cs b/Scripts/InstanceGrass.cs index 3c0d8f6..d6a1eab 100755 --- a/Scripts/InstanceGrass.cs +++ b/Scripts/InstanceGrass.cs @@ -15,6 +15,7 @@ public class InstanceGrass : UdonSharpBehaviour // The extent along each cardinal axis where instances will be rendered, in // meters. I.e. render inside a cube with edges this long. [SerializeField] public Vector3 extent_meters_; + [SerializeField] public float min_distance_; [SerializeField] public Vector3 angle_randomization_; [SerializeField] public float scale_randomization_; @@ -34,12 +35,15 @@ public class InstanceGrass : UdonSharpBehaviour // Track fields to detect runtime changes. private float density_live_; private Vector3 extent_meters_live_; + private float min_distance_live_; private Vector3 angle_randomization_live_; private float scale_randomization_live_; // GPU-specific resources private RenderTexture instance_data_tex_; private Matrix4x4[] identity_transforms_; // All identity matrices + private float[] instance_ids_; + private MaterialPropertyBlock instance_properties_; private int tex_width_; private int tex_height_; @@ -67,6 +71,7 @@ public class InstanceGrass : UdonSharpBehaviour Material[] materials = mesh_renderer.sharedMaterials; if (materials != null && materials.Length > 0) { instance_material_ = materials[0]; + instance_material_.enableInstancing = true; } else { Debug.LogError("[Grass::Debug] MeshRenderer has no materials."); } @@ -117,26 +122,29 @@ public class InstanceGrass : UdonSharpBehaviour instance_data_tex_.filterMode = FilterMode.Point; instance_data_tex_.Create(); - // Create transform array with encoded instance IDs - must match actual draw count - int actual_draw_count = tex_width_ * tex_height_; - if (identity_transforms_ == null || identity_transforms_.Length != actual_draw_count) { - identity_transforms_ = new Matrix4x4[actual_draw_count]; - for (int i = 0; i < actual_draw_count; i++) { - // Encode instance ID in the matrix translation component - // We'll put the ID in the X component, which the shader will read - Matrix4x4 m = Matrix4x4.identity; - m.m03 = i; // Store instance ID in translation.x - identity_transforms_[i] = m; + // Create transform array and per-instance IDs. + if (identity_transforms_ == null || identity_transforms_.Length != total_instances_) { + identity_transforms_ = new Matrix4x4[total_instances_]; + for (int i = 0; i < total_instances_; i++) { + identity_transforms_[i] = Matrix4x4.identity; + } + } + + if (instance_ids_ == null || instance_ids_.Length != total_instances_) { + instance_ids_ = new float[total_instances_]; + for (int i = 0; i < total_instances_; i++) { + instance_ids_[i] = i; } } if (mesh_ != null) { - // Set huge bounds so culling doesn't interfere - mesh_.bounds = new Bounds(Vector3.zero, Vector3.one * 10000f); + // Prevent frustum culling from clipping instanced draws that move in-shader. + mesh_.bounds = new Bounds(Vector3.zero, Vector3.one * 100000f); } density_live_ = density_; extent_meters_live_ = extent_meters_; + min_distance_live_ = min_distance_; angle_randomization_live_ = angle_randomization_; scale_randomization_live_ = scale_randomization_; @@ -182,6 +190,7 @@ public class InstanceGrass : UdonSharpBehaviour // Reinitialize if any config changed at runtime. if (density_ != density_live_ || extent_meters_ != extent_meters_live_ || + min_distance_ != min_distance_live_ || angle_randomization_ != angle_randomization_live_ || scale_randomization_ != scale_randomization_live_) { Init(); @@ -194,9 +203,12 @@ public class InstanceGrass : UdonSharpBehaviour VRCPlayerApi lcl_player = Networking.LocalPlayer; Vector3 player_pos = lcl_player.GetPosition(); - int grid_x = Mathf.FloorToInt(player_pos.x * inv_cell_dim_.x); - int grid_y = Mathf.FloorToInt(player_pos.y * inv_cell_dim_.y); - int grid_z = Mathf.FloorToInt(player_pos.z * inv_cell_dim_.z); + + // Only update grid position on axes with extent >= 1cm + // For axes with smaller extent, keep grid at 0 (don't move with player) + int grid_x = extent_meters_.x >= 0.01f ? Mathf.FloorToInt(player_pos.x * inv_cell_dim_.x) : 0; + int grid_y = extent_meters_.y >= 0.01f ? Mathf.FloorToInt(player_pos.y * inv_cell_dim_.y) : 0; + int grid_z = extent_meters_.z >= 0.01f ? Mathf.FloorToInt(player_pos.z * inv_cell_dim_.z) : 0; int half_x = count_.x / 2; int half_y = count_.y / 2; @@ -222,20 +234,24 @@ public class InstanceGrass : UdonSharpBehaviour Quaternion rot = base_transform_.localRotation; instance_material_.SetVector("_Instance_Texture_Offset_Base_Rotation", new Vector4(rot.x, rot.y, rot.z, rot.w)); + // Distance culling parameters + instance_material_.SetFloat("_Instance_Distance_Culling_Min_Distance", min_distance_); + float max_distance = Mathf.Max(extent_meters_.x, Mathf.Max(extent_meters_.y, extent_meters_.z)); + instance_material_.SetFloat("_Instance_Distance_Culling_Max_Distance", max_distance * 0.5f); + if (Time.frameCount % 300 == 0) { Debug.Log($"[Grass::Debug] Drawing {total_instances_} GPU instances"); Debug.Log($"[Grass::Debug] GridCount={count_}, TexDim={tex_width_}x{tex_height_}, CellDim={cell_dim_}"); } // Draw instances with identity transforms - GPU handles everything - // Must draw tex_width * tex_height instances to match texture VRCGraphics.DrawMeshInstanced( mesh_, 0, instance_material_, identity_transforms_, total_instances_, - null, + GetInstanceProperties(), UnityEngine.Rendering.ShadowCastingMode.Off, true, 0, @@ -246,6 +262,15 @@ public class InstanceGrass : UdonSharpBehaviour initialized_ = true; } + private MaterialPropertyBlock GetInstanceProperties() { + if (instance_properties_ == null) { + instance_properties_ = new MaterialPropertyBlock(); + } + + instance_properties_.SetFloatArray("_Instance_ID", instance_ids_); + return instance_properties_; + } + void OnDestroy() { if (instance_data_tex_ != null) { instance_data_tex_.Release(); @@ -288,7 +313,16 @@ public class InstanceGrassEditor : Editor return; } - string assetPath = "Assets/yum_food/3ner/Grass_Generated/Grass_generated.mat"; + // Get hierarchy path + Transform current = script.transform; + string hierarchyPath = current.name; + while (current.parent != null) + { + current = current.parent; + hierarchyPath = current.name + "/" + hierarchyPath; + } + + string assetPath = $"Assets/yum_food/3ner/Grass_Generated/{hierarchyPath}/Grass_generated.mat"; // Create or load existing material Material blitMat = AssetDatabase.LoadAssetAtPath<Material>(assetPath); |
