From a9c5601566aba22fd3e389d918295668c52f04a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20M=C3=B6rk?= Date: Mon, 24 Apr 2023 14:33:24 +0200 Subject: [PATCH 01/12] Render Cable with DrawMeshInstanced - w/o CableDamage --- AGXUnity/Rendering/CableRenderer.cs | 475 +++++++++++++++++++++------- 1 file changed, 365 insertions(+), 110 deletions(-) diff --git a/AGXUnity/Rendering/CableRenderer.cs b/AGXUnity/Rendering/CableRenderer.cs index f6d9870b..e3c84d06 100644 --- a/AGXUnity/Rendering/CableRenderer.cs +++ b/AGXUnity/Rendering/CableRenderer.cs @@ -1,6 +1,8 @@ -using UnityEngine; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Rendering; using AGXUnity.Utils; -using System.Collections.Generic; +using UnityEditor; namespace AGXUnity.Rendering { @@ -9,11 +11,23 @@ namespace AGXUnity.Rendering [RequireComponent( typeof( Cable ) )] public class CableRenderer : ScriptComponent { - [SerializeField] - private SegmentSpawner m_segmentSpawner = null; - - [HideInInspector] - public SegmentSpawner SegmentSpawner { get { return m_segmentSpawner; } } + /// + /// Shadow casting mode On for casting shadows, Off for no shadows. + /// + public ShadowCastingMode ShadowCastingMode = ShadowCastingMode.On; + + /// + ///True for the cable to receive shadows, false to not receive shadows. + /// + public bool ReceiveShadows = true; + + private List m_segmentSphereMatrices = new List(); + private List m_segmentCylinderMatrices = new List(); + private MaterialPropertyBlock m_meshInstanceProperties = null; + private Mesh m_sphereMeshInstance = null; + private Mesh m_cylinderMeshInstance = null; + private List m_positions = new List(); + private int m_numCylinders = 0; [System.NonSerialized] private Cable m_cable = null; @@ -31,12 +45,19 @@ public Cable Cable private Material m_material = null; public Material Material { - get { return m_material ?? m_segmentSpawner.DefaultMaterial; } + get { return m_material == null ? + m_material = DefaultMaterial() : + m_material; } set { - m_material = value ?? m_segmentSpawner.DefaultMaterial; - m_segmentSpawner.Material = m_material; + m_material = value ?? DefaultMaterial(); } + + } + + private static Material DefaultMaterial() + { + return Resources.Load( "Materials/CableMaterial_01" ); } private CableDamage m_cableDamage = null; @@ -47,27 +68,92 @@ public Material Material private bool m_renderDamages = false, m_previousRenderDamages = false; private Dictionary m_segmentRenderers = new Dictionary(); - public void InitializeRenderer( bool destructLast = false ) + public bool InitializeRenderer( bool destructLast = false ) { - if ( m_segmentSpawner != null ) { - m_segmentSpawner.Destroy(); - m_segmentSpawner = null; + if ( !CreateMeshes() ) { + Debug.LogError( "AGXUnity.Rendering.CableRenderer: Problem initializing one or both meshes!", this); + return false; } - m_segmentSpawner = new SegmentSpawner( Cable, - @"Cable/CableSegment", - @"Cable/CableSegmentBegin" ); - m_segmentSpawner.Initialize( gameObject ); + if ( !Material.enableInstancing ) { + Debug.LogError( "AGXUnity.Rendering.CableRenderer: The cable render material must have instancing enabled for this render mode to work.", + Material ); + return false; + } + + InitMatrices(); + m_positions.Clear(); + m_positions.Capacity = 256; + + return true; } protected override void OnEnable() { - OnEnableDisable( true ); +#if UNITY_EDITOR + // Used to draw in a prefab stage or when the editor is paused. + // It's not possible in OnEnable to check if our gameObject is + // part of a prefab stage. +#if UNITY_2019_1_OR_NEWER + SceneView.duringSceneGui += OnSceneView; +#else + SceneView.onSceneGUIDelegate += OnSceneView; +#endif +#endif } protected override void OnDisable() { - OnEnableDisable( false ); +#if UNITY_EDITOR +#if UNITY_2019_1_OR_NEWER + SceneView.duringSceneGui -= OnSceneView; +#else + SceneView.onSceneGUIDelegate -= OnSceneView; +#endif +#endif + } + + protected override bool Initialize() + { + InitializeRenderer(); + + return true; + } + + protected override void OnDestroy() + { + m_segmentCylinderMatrices = null; + m_segmentSphereMatrices = null; + + base.OnDestroy(); + } + +#if UNITY_EDITOR + // Editing cable prefab in a prefab stage and when the editor is paused + // requires Scene View GUI update callback. + private void OnSceneView( SceneView sceneView ) + { + var inPrefabStage = PrefabUtils.IsPartOfEditingPrefab( gameObject ); + var performDraw = EditorApplication.isPaused || inPrefabStage; + if ( !performDraw ) + return; + + if ( inPrefabStage && m_positions.Count != Cable.Route.NumNodes ) + SynchronizeData( true ); + + // In prefab stage we only want to render the cable in the Scene View. + // If paused, we want to render the cable as if not paused. + var camera = inPrefabStage ? + sceneView.camera : + null; + Draw( camera ); + } +#endif + + public void Update() + { + SynchronizeData( false ); + Draw(); } protected void LateUpdate() @@ -76,35 +162,142 @@ protected void LateUpdate() if ( Application.isPlaying ) return; - Render( Cable.Route, Cable.Radius ); + RenderRoute(); } - private void Render( CableRoute route, float radius ) + void Draw( Camera camera = null ) { - if ( m_segmentSpawner == null ) + if ( Cable == null ) return; - // Let OnDrawGizmos handle rendering when in prefab edit mode. - // It's not possible to use RuntimeObjects while there. - if ( PrefabUtils.IsPartOfEditingPrefab( gameObject ) ) + // In prefab stage we avoid calls from Update, LateUpdate so that we + // don't render the cable in the Game View. Camera is only given as the + // Scene View camera when editing prefabs. + if ( camera == null && PrefabUtils.IsPartOfEditingPrefab( gameObject ) ) return; - if ( !Cable.RoutePointCurveUpToDate ) - Cable.SynchronizeRoutePointCurve(); + if ( !CreateMeshes() ) + return; - m_segmentSpawner.Begin(); - try { - var points = Cable.GetRoutePoints(); - for ( int i = 1; i < points.Length; ++i ) - m_segmentSpawner.CreateSegment( points[ i - 1 ], points[ i ], radius ); + var forceSynchronize = m_positions.Count > 0 && + ( m_segmentSphereMatrices.Count == 0 || + m_segmentCylinderMatrices.Count == 0 ); + if ( forceSynchronize ) + SynchronizeData( Cable.State != States.INITIALIZED ); + + // Spheres + for ( int i = 0; i < m_positions.Count; i += 1023 ) { + int count = Mathf.Min( 1023, m_positions.Count - i ); + Graphics.DrawMeshInstanced( m_sphereMeshInstance, + 0, + Material, + m_segmentSphereMatrices[ i / 1023 ], + count, + m_meshInstanceProperties, + ShadowCastingMode, + ReceiveShadows, + 0, + camera ); } - catch ( System.Exception e ) { - Debug.LogException( e, this ); + + // Cylinders + for ( int i = 0; i < m_numCylinders; i += 1023 ) { + int count = Mathf.Min( 1023, m_numCylinders - i ); + Graphics.DrawMeshInstanced( m_cylinderMeshInstance, + 0, + Material, + m_segmentCylinderMatrices[ i / 1023 ], + count, + m_meshInstanceProperties, + ShadowCastingMode, + ReceiveShadows, + 0, + camera ); } - m_segmentSpawner.End(); } - private void Render() + private static Matrix4x4 CalculateCylinderTransform( Vector3 start, Vector3 end, float radius ) + { + CalculateCylinderTransform( start, + end, + radius, + out var position, + out var rotation, + out var scale ); + return Matrix4x4.TRS( position, rotation, scale ); + } + + private static void CalculateCylinderTransform( Vector3 start, + Vector3 end, + float radius, + out Vector3 position, + out Quaternion rotation, + out Vector3 scale ) + { + var dir = end - start; + var length = dir.magnitude; + position = 0.5f * ( start + end ); + rotation = Quaternion.FromToRotation( Vector3.up, dir ); + scale = new Vector3( 2.0f * radius, 0.5f * length, 2.0f * radius ); + } + + private void RenderRoute() + { + SynchronizeData( true ); + Draw(); + } + + private void SynchronizeData( bool isRoute ) + { + if ( Cable == null ) + return; + + if ( !isRoute && Cable.Native == null ) + return; + + m_positions.Clear(); + + if ( isRoute ) { + foreach ( var node in Cable.Route ) + m_positions.Add( node.Position ); + } + else { + var it = Cable.Native.begin(); + var endIt = Cable.Native.end(); + while ( !it.EqualWith( endIt ) ) { + m_positions.Add( it.getEndPosition().ToHandedVector3() ); // TODO getBeginPosition? + it.inc(); + } + + it.ReturnToPool(); + endIt.ReturnToPool(); + } + + while ( m_positions.Count / 1023 + 1 > m_segmentSphereMatrices.Count ) + m_segmentSphereMatrices.Add(new Matrix4x4[1023]); + + m_numCylinders = 0; + + float radius = Cable.Radius; + var sphereScale = 2.0f * radius * Vector3.one; + for ( int i = 0; i < m_positions.Count; ++i ) { + if ( i > 0 ){ + if (m_numCylinders / 1023 + 1 > m_segmentCylinderMatrices.Count) + m_segmentCylinderMatrices.Add(new Matrix4x4[1023]); + + m_segmentCylinderMatrices[ m_numCylinders / 1023 ][ m_numCylinders % 1023 ] = CalculateCylinderTransform( m_positions[ i - 1 ], + m_positions[ i ], + radius ); + m_numCylinders++; + } + + m_segmentSphereMatrices[ i / 1023 ][ i % 1023 ] = Matrix4x4.TRS( m_positions[ i ], + Quaternion.identity, + sphereScale ); + } + } + +/* private void Render() { if ( m_segmentSpawner == null ) return; @@ -120,97 +313,159 @@ private void Render() else if ( !m_segmentSpawner.IsValid ) InitializeRenderer( true ); - var it = native.begin(); - var endIt = native.end(); - int i = 0; - - MaterialPropertyBlock block = new MaterialPropertyBlock(); - - m_segmentSpawner.Begin(); - try { - float radius = Cable.Radius; - var prevEndPosition = it.EqualWith( endIt ) ? - Vector3.zero : - it.getBeginPosition().ToHandedVector3(); - while ( !it.EqualWith( endIt ) ) { - var endPosition = it.getEndPosition().ToHandedVector3(); - - var go = m_segmentSpawner.CreateSegment( prevEndPosition, endPosition, radius ); - - // If using render damage - if ((m_renderDamages || m_previousRenderDamages)){ - int id = go.GetInstanceID(); - - (MeshRenderer, MeshRenderer) meshRenderers; - if (m_segmentRenderers.TryGetValue(id, out meshRenderers) && meshRenderers.Item1 != null){ - if (m_renderDamages && CableDamage.DamageValueCount == (int)native.getNumSegments()){ // TODO do we need the length check? - float t = CableDamage.DamageValue(i) / CableDamage.MaxDamage; - block.SetColor("_Color", Color.Lerp(CableDamage.Properties.MinColor, CableDamage.Properties.MaxColor, t)); - meshRenderers.Item1.SetPropertyBlock(block); - meshRenderers.Item2.SetPropertyBlock(block); + if(m_renderMode == CableRenderMode.GameObject) + { + var it = native.begin(); + var endIt = native.end(); + int i = 0; + + MaterialPropertyBlock block = new MaterialPropertyBlock(); + + m_segmentSpawner.Begin(); + try { + float radius = Cable.Radius; + var prevEndPosition = it.EqualWith( endIt ) ? + Vector3.zero : + it.getBeginPosition().ToHandedVector3(); + while ( !it.EqualWith( endIt ) ) { + var endPosition = it.getEndPosition().ToHandedVector3(); + + var go = m_segmentSpawner.CreateSegment( prevEndPosition, endPosition, radius ); + + // If using render damage + if ((m_renderDamages || m_previousRenderDamages)){ + int id = go.GetInstanceID(); + + (MeshRenderer, MeshRenderer) meshRenderers; + if (m_segmentRenderers.TryGetValue(id, out meshRenderers) && meshRenderers.Item1 != null){ + if (m_renderDamages && CableDamage.DamageValueCount == (int)native.getNumSegments()){ // TODO do we need the length check? + float t = CableDamage.DamageValue(i) / CableDamage.MaxDamage; + block.SetColor("_Color", Color.Lerp(CableDamage.Properties.MinColor, CableDamage.Properties.MaxColor, t)); + meshRenderers.Item1.SetPropertyBlock(block); + meshRenderers.Item2.SetPropertyBlock(block); + } + else{ + block.SetColor("_Color", Material.color); + meshRenderers.Item1.SetPropertyBlock(block); + meshRenderers.Item2.SetPropertyBlock(block); + } + } + else { + var renderers = go.GetComponentsInChildren(); + m_segmentRenderers.Add(id, (renderers[0], renderers[1])); + } } - else{ - block.SetColor("_Color", Material.color); - meshRenderers.Item1.SetPropertyBlock(block); - meshRenderers.Item2.SetPropertyBlock(block); - } - } - else { - var renderers = go.GetComponentsInChildren(); - m_segmentRenderers.Add(id, (renderers[0], renderers[1])); + + i++; + prevEndPosition = endPosition; + it.inc(); } } + catch ( System.Exception e ) { + Debug.LogException( e, this ); + } + m_segmentSpawner.End(); - i++; - prevEndPosition = endPosition; - it.inc(); + m_previousRenderDamages = m_renderDamages; + + it.ReturnToPool(); + endIt.ReturnToPool(); + } + else if(m_renderMode == CableRenderMode.DrawMeshInstanced) + + + // Create per-segment matrices if not yet created. + ulong numSegments = native.getNumSegments(); + if (m_cylinderMatrices == null || (ulong)m_cylinderMatrices.Length != numSegments) + { + m_cylinderMatrices = new Matrix4x4[numSegments]; + } + if( m_halfSphereMatrices == null || (ulong)m_halfSphereMatrices.Length != numSegments + 1) + { + m_halfSphereMatrices = new Matrix4x4[numSegments + 1]; + } + // Update per-segment matrices. + var it = native.begin(); + var endIt = native.end(); + try + { + int i = 0; + for (; !it.EqualWith(endIt); it.inc(), i++) + { + // TODO: Draw cylinders between segment end-points instead, as GameObject rendering mode does above. + + // TODO: Add support for cable damage color rendering. + // Should be possible by writing the damage factor as an array parameter to the material, + // and then read it from the shader, using instance index as lookup. Check out SetVectorArray, + // of MaterialPropertyBlock, and/or the Graphics.DrawMeshInstancedXXX variants. + + Quaternion rotation = Quaternion.FromToRotation(Vector3.up, it.getDirection().ToHandedVector3()); + m_cylinderMatrices[i] = Matrix4x4.TRS( + it.getCenterPosition().ToHandedVector3(), + rotation, + new Vector3(Cable.Diameter, (float)it.getLength(), Cable.Diameter)); + + m_halfSphereMatrices[i] = Matrix4x4.TRS( + it.getBeginPosition().ToHandedVector3(), + rotation * Quaternion.AngleAxis(180, Vector3.right), + new Vector3(Cable.Diameter, Cable.Diameter, Cable.Diameter)); + + if (i + 2 == m_halfSphereMatrices.Length) + { + m_halfSphereMatrices[i + 1] = Matrix4x4.TRS( + it.getEndPosition().ToHandedVector3(), + rotation, + new Vector3(Cable.Diameter, Cable.Diameter, Cable.Diameter)); + } } } - catch ( System.Exception e ) { - Debug.LogException( e, this ); + finally + { + it.ReturnToPool(); + endIt.ReturnToPool(); } - m_segmentSpawner.End(); + }*/ - m_previousRenderDamages = m_renderDamages; + private bool CreateMeshes() + { + if ( m_sphereMeshInstance == null ) + m_sphereMeshInstance = CreateMesh( @"Debug/LowPolySphereRenderer" ); + if ( m_cylinderMeshInstance == null ) + m_cylinderMeshInstance = CreateMesh( @"Debug/LowPolyCylinderRenderer" ); - it.ReturnToPool(); - endIt.ReturnToPool(); + return m_sphereMeshInstance != null && m_cylinderMeshInstance != null; } - private void OnEnableDisable( bool enable ) + private Mesh CreateMesh( string resource ) { - if ( enable ) { - InitializeRenderer( true ); - if ( Application.isPlaying ) - Simulation.Instance.StepCallbacks.PostStepForward += Render; + GameObject tmp = Resources.Load( resource ); + MeshFilter[] filters = tmp.GetComponentsInChildren(); + MeshRenderer[] renderers = tmp.GetComponentsInChildren(); + CombineInstance[] combine = new CombineInstance[ filters.Length ]; + + for ( int i = 0; i < filters.Length; ++i ) { + combine[ i ].mesh = filters[ i ].sharedMesh; + combine[ i ].transform = filters[ i ].transform.localToWorldMatrix; } - else { - if ( m_segmentSpawner != null ) { - m_segmentSpawner.Destroy(); - m_segmentSpawner = null; - } - if ( Simulation.HasInstance && Application.isPlaying ) - Simulation.Instance.StepCallbacks.PostStepForward -= Render; - } + var mesh = new Mesh(); + mesh.CombineMeshes( combine ); + + return mesh; } - private void DrawGizmos( bool isSelected ) + private void InitMatrices() { - if ( Application.isPlaying ) - return; - - if ( Cable == null || Cable.Route == null || Cable.Route.NumNodes < 2 ) - return; - - if ( !PrefabUtils.IsPartOfEditingPrefab( gameObject ) ) - return; + if ( m_segmentSphereMatrices == null ) + m_segmentSphereMatrices = new List { new Matrix4x4[ 1023 ] }; + if ( m_segmentCylinderMatrices == null ) + m_segmentCylinderMatrices = new List { new Matrix4x4[ 1023 ] }; + if ( m_meshInstanceProperties == null ) + m_meshInstanceProperties = new MaterialPropertyBlock(); + } - var defaultColor = Color.Lerp( Color.black, Color.white, 0.15f ); - var selectedColor = Color.Lerp( defaultColor, Color.green, 0.15f ); - m_segmentSpawner?.DrawGizmos( Cable.GetRoutePoints(), - Cable.Radius, - isSelected ? selectedColor : defaultColor ); + private void DrawGizmos( bool isSelected ) + { } private void OnDrawGizmos() From 8a11dd76ffccd0a5880f4790966a3d4ab0140ad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20M=C3=B6rk?= Date: Mon, 24 Apr 2023 14:34:15 +0200 Subject: [PATCH 02/12] Typo --- AGXUnity/Cable.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AGXUnity/Cable.cs b/AGXUnity/Cable.cs index 4b1a1e47..5030c40a 100644 --- a/AGXUnity/Cable.cs +++ b/AGXUnity/Cable.cs @@ -212,7 +212,7 @@ public CableRoute Route } private PointCurve m_routePointCurve = null; - private float m_routePointResulutionPerUnitLength = -1.0f; + private float m_routePointResolutionPerUnitLength = -1.0f; private Vector3[] m_routePointsCache = new Vector3[] { }; /// @@ -267,7 +267,7 @@ public bool RoutePointCurveUpToDate get { return m_routePointCurve != null && - Utils.Math.Approximately( m_routePointResulutionPerUnitLength, ResolutionPerUnitLength ) && + Utils.Math.Approximately( m_routePointResolutionPerUnitLength, ResolutionPerUnitLength ) && Route.IsSynchronized( m_routePointCurve, 1.0E-4f ); } } @@ -532,7 +532,7 @@ public PointCurve.SegmentationResult SynchronizeRoutePointCurve() var numSegments = Mathf.Max( Mathf.CeilToInt( ResolutionPerUnitLength * Route.TotalLength ), 1 ); var result = m_routePointCurve.FindSegmentLength( numSegments, PointCurve.DefaultErrorFunc, 5.0E-3f, 1.0E-3f ); if ( result.Successful ) { - m_routePointResulutionPerUnitLength = ResolutionPerUnitLength; + m_routePointResolutionPerUnitLength = ResolutionPerUnitLength; var routePoints = new List(); m_routePointCurve.Traverse( ( curr, next, type ) => { From a26d11fe8a95c4fd57fe6b0fc479019eee73fd81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20M=C3=B6rk?= Date: Thu, 4 May 2023 16:55:37 +0200 Subject: [PATCH 03/12] Use instanced color for cable damage --- AGXUnity/Rendering/CableRenderer.cs | 164 ++++-------------- .../InstancedColorSurfaceShader.shader | 56 ++++++ .../InstancedColorSurfaceShader.shader.meta | 10 ++ 3 files changed, 100 insertions(+), 130 deletions(-) create mode 100644 Resources/Materials/InstancedColorSurfaceShader.shader create mode 100644 Resources/Materials/InstancedColorSurfaceShader.shader.meta diff --git a/AGXUnity/Rendering/CableRenderer.cs b/AGXUnity/Rendering/CableRenderer.cs index e3c84d06..320711b5 100644 --- a/AGXUnity/Rendering/CableRenderer.cs +++ b/AGXUnity/Rendering/CableRenderer.cs @@ -23,6 +23,7 @@ public class CableRenderer : ScriptComponent private List m_segmentSphereMatrices = new List(); private List m_segmentCylinderMatrices = new List(); + private List m_segmentColors = new List(); private MaterialPropertyBlock m_meshInstanceProperties = null; private Mesh m_sphereMeshInstance = null; private Mesh m_cylinderMeshInstance = null; @@ -124,6 +125,7 @@ protected override void OnDestroy() { m_segmentCylinderMatrices = null; m_segmentSphereMatrices = null; + m_segmentColors = null; base.OnDestroy(); } @@ -185,9 +187,15 @@ void Draw( Camera camera = null ) if ( forceSynchronize ) SynchronizeData( Cable.State != States.INITIALIZED ); + + // Spheres for ( int i = 0; i < m_positions.Count; i += 1023 ) { int count = Mathf.Min( 1023, m_positions.Count - i ); + + if (m_segmentColors.Count > 0) + m_meshInstanceProperties.SetVectorArray("_Color", m_segmentColors[ i / 1023 ]); + Graphics.DrawMeshInstanced( m_sphereMeshInstance, 0, Material, @@ -202,6 +210,10 @@ void Draw( Camera camera = null ) // Cylinders for ( int i = 0; i < m_numCylinders; i += 1023 ) { + + if (m_segmentColors.Count > 0) + m_meshInstanceProperties.SetVectorArray("_Color", m_segmentColors[ i / 1023 ]); + int count = Mathf.Min( 1023, m_numCylinders - i ); Graphics.DrawMeshInstanced( m_cylinderMeshInstance, 0, @@ -279,7 +291,7 @@ private void SynchronizeData( bool isRoute ) m_numCylinders = 0; float radius = Cable.Radius; - var sphereScale = 2.0f * radius * Vector3.one; + var sphereScale = 2f * radius * Vector3.one; for ( int i = 0; i < m_positions.Count; ++i ) { if ( i > 0 ){ if (m_numCylinders / 1023 + 1 > m_segmentCylinderMatrices.Count) @@ -288,143 +300,33 @@ private void SynchronizeData( bool isRoute ) m_segmentCylinderMatrices[ m_numCylinders / 1023 ][ m_numCylinders % 1023 ] = CalculateCylinderTransform( m_positions[ i - 1 ], m_positions[ i ], radius ); - m_numCylinders++; - } - m_segmentSphereMatrices[ i / 1023 ][ i % 1023 ] = Matrix4x4.TRS( m_positions[ i ], - Quaternion.identity, - sphereScale ); - } - } + // If using render damage + if ((m_renderDamages || m_previousRenderDamages)){ -/* private void Render() - { - if ( m_segmentSpawner == null ) - return; + if (m_numCylinders / 1023 + 1 > m_segmentColors.Count) + m_segmentColors.Add(new Vector4[1023]); - var native = Cable.Native; - if ( native == null ) { - if ( m_segmentSpawner != null ) { - m_segmentSpawner.Destroy(); - m_segmentSpawner = null; - } - return; - } - else if ( !m_segmentSpawner.IsValid ) - InitializeRenderer( true ); - - if(m_renderMode == CableRenderMode.GameObject) - { - var it = native.begin(); - var endIt = native.end(); - int i = 0; - - MaterialPropertyBlock block = new MaterialPropertyBlock(); - - m_segmentSpawner.Begin(); - try { - float radius = Cable.Radius; - var prevEndPosition = it.EqualWith( endIt ) ? - Vector3.zero : - it.getBeginPosition().ToHandedVector3(); - while ( !it.EqualWith( endIt ) ) { - var endPosition = it.getEndPosition().ToHandedVector3(); - - var go = m_segmentSpawner.CreateSegment( prevEndPosition, endPosition, radius ); - - // If using render damage - if ((m_renderDamages || m_previousRenderDamages)){ - int id = go.GetInstanceID(); - - (MeshRenderer, MeshRenderer) meshRenderers; - if (m_segmentRenderers.TryGetValue(id, out meshRenderers) && meshRenderers.Item1 != null){ - if (m_renderDamages && CableDamage.DamageValueCount == (int)native.getNumSegments()){ // TODO do we need the length check? - float t = CableDamage.DamageValue(i) / CableDamage.MaxDamage; - block.SetColor("_Color", Color.Lerp(CableDamage.Properties.MinColor, CableDamage.Properties.MaxColor, t)); - meshRenderers.Item1.SetPropertyBlock(block); - meshRenderers.Item2.SetPropertyBlock(block); - } - else{ - block.SetColor("_Color", Material.color); - meshRenderers.Item1.SetPropertyBlock(block); - meshRenderers.Item2.SetPropertyBlock(block); - } - } - else { - var renderers = go.GetComponentsInChildren(); - m_segmentRenderers.Add(id, (renderers[0], renderers[1])); - } - } - - i++; - prevEndPosition = endPosition; - it.inc(); + if (m_renderDamages) { + float t = CableDamage.DamageValue(i) / CableDamage.MaxDamage; + var color = Color.Lerp(CableDamage.Properties.MinColor, CableDamage.Properties.MaxColor, t); + m_segmentColors[ m_numCylinders / 1023 ][ m_numCylinders % 1023 ] = color; + } + else { + m_segmentColors[ m_numCylinders / 1023 ][ m_numCylinders % 1023 ] = Material.color; } } - catch ( System.Exception e ) { - Debug.LogException( e, this ); - } - m_segmentSpawner.End(); - - m_previousRenderDamages = m_renderDamages; - it.ReturnToPool(); - endIt.ReturnToPool(); - } - else if(m_renderMode == CableRenderMode.DrawMeshInstanced) - - - // Create per-segment matrices if not yet created. - ulong numSegments = native.getNumSegments(); - if (m_cylinderMatrices == null || (ulong)m_cylinderMatrices.Length != numSegments) - { - m_cylinderMatrices = new Matrix4x4[numSegments]; - } - if( m_halfSphereMatrices == null || (ulong)m_halfSphereMatrices.Length != numSegments + 1) - { - m_halfSphereMatrices = new Matrix4x4[numSegments + 1]; - } - // Update per-segment matrices. - var it = native.begin(); - var endIt = native.end(); - try - { - int i = 0; - for (; !it.EqualWith(endIt); it.inc(), i++) - { - // TODO: Draw cylinders between segment end-points instead, as GameObject rendering mode does above. - - // TODO: Add support for cable damage color rendering. - // Should be possible by writing the damage factor as an array parameter to the material, - // and then read it from the shader, using instance index as lookup. Check out SetVectorArray, - // of MaterialPropertyBlock, and/or the Graphics.DrawMeshInstancedXXX variants. - - Quaternion rotation = Quaternion.FromToRotation(Vector3.up, it.getDirection().ToHandedVector3()); - m_cylinderMatrices[i] = Matrix4x4.TRS( - it.getCenterPosition().ToHandedVector3(), - rotation, - new Vector3(Cable.Diameter, (float)it.getLength(), Cable.Diameter)); - - m_halfSphereMatrices[i] = Matrix4x4.TRS( - it.getBeginPosition().ToHandedVector3(), - rotation * Quaternion.AngleAxis(180, Vector3.right), - new Vector3(Cable.Diameter, Cable.Diameter, Cable.Diameter)); - - if (i + 2 == m_halfSphereMatrices.Length) - { - m_halfSphereMatrices[i + 1] = Matrix4x4.TRS( - it.getEndPosition().ToHandedVector3(), - rotation, - new Vector3(Cable.Diameter, Cable.Diameter, Cable.Diameter)); - } + m_numCylinders++; } + + m_segmentSphereMatrices[ i / 1023 ][ i % 1023 ] = Matrix4x4.TRS( m_positions[ i ], + Quaternion.identity, + sphereScale ); } - finally - { - it.ReturnToPool(); - endIt.ReturnToPool(); - } - }*/ + + m_previousRenderDamages = m_renderDamages; + } private bool CreateMeshes() { @@ -460,6 +362,8 @@ private void InitMatrices() m_segmentSphereMatrices = new List { new Matrix4x4[ 1023 ] }; if ( m_segmentCylinderMatrices == null ) m_segmentCylinderMatrices = new List { new Matrix4x4[ 1023 ] }; + if ( m_segmentColors == null ) + m_segmentColors = new List { new Vector4[ 1023 ] }; if ( m_meshInstanceProperties == null ) m_meshInstanceProperties = new MaterialPropertyBlock(); } diff --git a/Resources/Materials/InstancedColorSurfaceShader.shader b/Resources/Materials/InstancedColorSurfaceShader.shader new file mode 100644 index 00000000..04ac3089 --- /dev/null +++ b/Resources/Materials/InstancedColorSurfaceShader.shader @@ -0,0 +1,56 @@ +Shader "Custom/CableDamageShader" +{ + Properties + { + _Color ("Color", Color) = (1,1,1,1) + _MainTex ("Albedo (RGB)", 2D) = "white" {} + _Glossiness ("Smoothness", Range(0,1)) = 0.5 + _Metallic ("Metallic", Range(0,1)) = 0.0 + } + SubShader + { + Tags { "RenderType"="Opaque" } + LOD 200 + + CGPROGRAM + // Physically based Standard lighting model, and enable shadows on all light types + #pragma surface surf Standard fullforwardshadows + + // Use shader model 3.0 target, to get nicer looking lighting + #pragma target 3.0 + + #pragma multi_compile_instancing + + sampler2D _MainTex; + + struct Input + { + float2 uv_MainTex; + }; + + half _Glossiness; + half _Metallic; + + // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader. + // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing. + // #pragma instancing_options assumeuniformscaling + UNITY_INSTANCING_BUFFER_START(Props) + // put more per-instance properties here + UNITY_DEFINE_INSTANCED_PROP(float4, _Color) + UNITY_INSTANCING_BUFFER_END(Props) + + void surf (Input IN, inout SurfaceOutputStandard o) + { + // Albedo comes from a texture tinted by color + fixed4 color = UNITY_ACCESS_INSTANCED_PROP(Props, _Color); + fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * color; + o.Albedo = c.rgb; + // Metallic and smoothness come from slider variables + o.Metallic = _Metallic; + o.Smoothness = _Glossiness; + o.Alpha = c.a; + } + ENDCG + } + FallBack "Diffuse" +} diff --git a/Resources/Materials/InstancedColorSurfaceShader.shader.meta b/Resources/Materials/InstancedColorSurfaceShader.shader.meta new file mode 100644 index 00000000..7f269ffd --- /dev/null +++ b/Resources/Materials/InstancedColorSurfaceShader.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 34bc64bc99ee07b46af4bd2bcf32a03a +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: From 892a879ee9d953ecac426a74cf84157b8dcd5915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20M=C3=B6rk?= Date: Fri, 5 May 2023 13:41:41 +0200 Subject: [PATCH 04/12] Use CylinderCap and HalfSphere for rendering to make cable knees look better --- AGXUnity/Rendering/CableRenderer.cs | 33 +++-- Resources/Cable/CylinderCapRenderer.prefab | 85 +++++++++++++ .../Cable/CylinderCapRenderer.prefab.meta | 7 ++ Resources/Cable/HalfSphereRenderer.prefab | 117 ++++++++++++++++++ .../Cable/HalfSphereRenderer.prefab.meta | 10 ++ Resources/Materials/CableMaterial_01.mat | 10 +- 6 files changed, 240 insertions(+), 22 deletions(-) create mode 100644 Resources/Cable/CylinderCapRenderer.prefab create mode 100644 Resources/Cable/CylinderCapRenderer.prefab.meta create mode 100644 Resources/Cable/HalfSphereRenderer.prefab create mode 100644 Resources/Cable/HalfSphereRenderer.prefab.meta diff --git a/AGXUnity/Rendering/CableRenderer.cs b/AGXUnity/Rendering/CableRenderer.cs index 320711b5..d26c0c2c 100644 --- a/AGXUnity/Rendering/CableRenderer.cs +++ b/AGXUnity/Rendering/CableRenderer.cs @@ -228,17 +228,6 @@ void Draw( Camera camera = null ) } } - private static Matrix4x4 CalculateCylinderTransform( Vector3 start, Vector3 end, float radius ) - { - CalculateCylinderTransform( start, - end, - radius, - out var position, - out var rotation, - out var scale ); - return Matrix4x4.TRS( position, rotation, scale ); - } - private static void CalculateCylinderTransform( Vector3 start, Vector3 end, float radius, @@ -250,7 +239,7 @@ private static void CalculateCylinderTransform( Vector3 start, var length = dir.magnitude; position = 0.5f * ( start + end ); rotation = Quaternion.FromToRotation( Vector3.up, dir ); - scale = new Vector3( 2.0f * radius, 0.5f * length, 2.0f * radius ); + scale = new Vector3( 2.0f * radius, 1f * length, 2.0f * radius ); } private void RenderRoute() @@ -277,7 +266,7 @@ private void SynchronizeData( bool isRoute ) var it = Cable.Native.begin(); var endIt = Cable.Native.end(); while ( !it.EqualWith( endIt ) ) { - m_positions.Add( it.getEndPosition().ToHandedVector3() ); // TODO getBeginPosition? + m_positions.Add( it.getEndPosition().ToHandedVector3() ); it.inc(); } @@ -292,14 +281,20 @@ private void SynchronizeData( bool isRoute ) float radius = Cable.Radius; var sphereScale = 2f * radius * Vector3.one; + // rotation will be set by cylinder calculation and reused by sphere to align edges, first half sphere need its own calculation + var rotation = (m_positions.Count > 1) ? Quaternion.FromToRotation( Vector3.down, m_positions[ 1 ] - m_positions[ 0 ] ) : Quaternion.identity; for ( int i = 0; i < m_positions.Count; ++i ) { if ( i > 0 ){ if (m_numCylinders / 1023 + 1 > m_segmentCylinderMatrices.Count) m_segmentCylinderMatrices.Add(new Matrix4x4[1023]); - m_segmentCylinderMatrices[ m_numCylinders / 1023 ][ m_numCylinders % 1023 ] = CalculateCylinderTransform( m_positions[ i - 1 ], - m_positions[ i ], - radius ); + CalculateCylinderTransform( m_positions[ i - 1 ], + m_positions[ i ], + radius, + out var position, + out rotation, + out var scale ); + m_segmentCylinderMatrices[ m_numCylinders / 1023 ][ m_numCylinders % 1023 ] = Matrix4x4.TRS( position, rotation, scale ); // If using render damage if ((m_renderDamages || m_previousRenderDamages)){ @@ -321,7 +316,7 @@ private void SynchronizeData( bool isRoute ) } m_segmentSphereMatrices[ i / 1023 ][ i % 1023 ] = Matrix4x4.TRS( m_positions[ i ], - Quaternion.identity, + rotation, sphereScale ); } @@ -331,9 +326,9 @@ private void SynchronizeData( bool isRoute ) private bool CreateMeshes() { if ( m_sphereMeshInstance == null ) - m_sphereMeshInstance = CreateMesh( @"Debug/LowPolySphereRenderer" ); + m_sphereMeshInstance = CreateMesh( @"Cable/HalfSphereRenderer" ); if ( m_cylinderMeshInstance == null ) - m_cylinderMeshInstance = CreateMesh( @"Debug/LowPolyCylinderRenderer" ); + m_cylinderMeshInstance = CreateMesh( @"Cable/CylinderCapRenderer" ); return m_sphereMeshInstance != null && m_cylinderMeshInstance != null; } diff --git a/Resources/Cable/CylinderCapRenderer.prefab b/Resources/Cable/CylinderCapRenderer.prefab new file mode 100644 index 00000000..58cfc546 --- /dev/null +++ b/Resources/Cable/CylinderCapRenderer.prefab @@ -0,0 +1,85 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &3195611642692983750 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 83358248443891959} + - component: {fileID: 3457568169110130062} + - component: {fileID: 5123949108297240798} + m_Layer: 0 + m_Name: CylinderCapRenderer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &83358248443891959 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3195611642692983750} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &3457568169110130062 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3195611642692983750} + m_Mesh: {fileID: 4300000, guid: cef6d9e61d53dbd459fe9de6cfc619de, type: 2} +--- !u!23 &5123949108297240798 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3195611642692983750} + 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: a6e00de1ddd256248b50417fd040a41a, 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} diff --git a/Resources/Cable/CylinderCapRenderer.prefab.meta b/Resources/Cable/CylinderCapRenderer.prefab.meta new file mode 100644 index 00000000..9dd68509 --- /dev/null +++ b/Resources/Cable/CylinderCapRenderer.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: edf571246c62f7b48905635a98a0b589 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Resources/Cable/HalfSphereRenderer.prefab b/Resources/Cable/HalfSphereRenderer.prefab new file mode 100644 index 00000000..c2ee2369 --- /dev/null +++ b/Resources/Cable/HalfSphereRenderer.prefab @@ -0,0 +1,117 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &133926 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 493986} + - component: {fileID: 3398180} + - component: {fileID: 2335252} + m_Layer: 0 + m_Name: HalfSphere + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &493986 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 133926} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 431500} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &3398180 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 133926} + m_Mesh: {fileID: 4300000, guid: 70c0dc3be55211946892d8f99ff8366b, type: 2} +--- !u!23 &2335252 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 133926} + 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: 8eead6344c8dbb244a2ec92fd8f4565e, 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: 0 + 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!1 &138476 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 431500} + m_Layer: 0 + m_Name: HalfSphereRenderer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &431500 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 138476} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 493986} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Resources/Cable/HalfSphereRenderer.prefab.meta b/Resources/Cable/HalfSphereRenderer.prefab.meta new file mode 100644 index 00000000..eb66780f --- /dev/null +++ b/Resources/Cable/HalfSphereRenderer.prefab.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3f1a536d76b63624994979f073d81b5c +timeCreated: 1515497587 +licenseType: Pro +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Resources/Materials/CableMaterial_01.mat b/Resources/Materials/CableMaterial_01.mat index 3b33d027..235e8a66 100644 --- a/Resources/Materials/CableMaterial_01.mat +++ b/Resources/Materials/CableMaterial_01.mat @@ -2,14 +2,16 @@ %TAG !u! tag:unity3d.com,2011: --- !u!21 &2100000 Material: - serializedVersion: 6 + serializedVersion: 8 m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: CableMaterial_01 - m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} - m_ShaderKeywords: _EMISSION + m_Shader: {fileID: 4800000, guid: 34bc64bc99ee07b46af4bd2bcf32a03a, type: 3} + m_ValidKeywords: [] + m_InvalidKeywords: + - _EMISSION m_LightmapFlags: 1 m_EnableInstancingVariants: 1 m_DoubleSidedGI: 0 @@ -55,6 +57,7 @@ Material: 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 @@ -75,3 +78,4 @@ Material: m_Colors: - _Color: {r: 0.17647058, g: 0.17647058, b: 0.17647058, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] From e153433655c125c95899d973c33cf5c9e5f3ebd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20M=C3=B6rk?= Date: Tue, 16 May 2023 16:00:25 +0200 Subject: [PATCH 05/12] Better handling of no CD props set --- AGXUnity/CableDamage.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/AGXUnity/CableDamage.cs b/AGXUnity/CableDamage.cs index 99b88acb..9e7d9e54 100644 --- a/AGXUnity/CableDamage.cs +++ b/AGXUnity/CableDamage.cs @@ -46,7 +46,7 @@ public bool RenderCableDamage { if (CableRenderer == null) Debug.LogWarning("No CableRenderer to use for rendering cable damages"); else - CableRenderer.SetRenderDamages(value); + CableRenderer.SetRenderDamages(value && m_properties != null); } } @@ -69,6 +69,11 @@ public CableDamageProperties Properties if ( Native != null && m_properties != null ) m_properties.Register( this ); + + if (CableRenderer == null) + Debug.LogWarning("No CableRenderer to use for rendering cable damages"); + else + CableRenderer.SetRenderDamages(m_properties != null && m_renderCableDamage); } } @@ -119,7 +124,7 @@ void Update() if (m_properties == null) { - Debug.LogError("No CableDamageProperties set!"); + Debug.LogWarning("No CableDamageProperties set - no Cable Damage Calculated!"); return; } From b9200957ca885e1aedf2d2a9349bd77c0a2a11df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20M=C3=B6rk?= Date: Wed, 17 May 2023 16:06:16 +0200 Subject: [PATCH 06/12] WIP HDRP cable shader --- AGXUnity/Rendering/CableRenderer.cs | 8 +- Resources/Materials/CableMaterial_01_HDRP.mat | 166 ++ .../Materials/CableMaterial_01_HDRP.mat.meta | 8 + ...InstancedColorShaderGraph_HDRP.shadergraph | 1575 +++++++++++++++++ ...ncedColorShaderGraph_HDRP.shadergraph.meta | 10 + .../InstancedColorSurfaceShader.shader | 5 +- .../ShaderInstancePropertiesInclude.hlsl | 18 + .../ShaderInstancePropertiesInclude.hlsl.meta | 7 + 8 files changed, 1792 insertions(+), 5 deletions(-) create mode 100644 Resources/Materials/CableMaterial_01_HDRP.mat create mode 100644 Resources/Materials/CableMaterial_01_HDRP.mat.meta create mode 100644 Resources/Materials/InstancedColorShaderGraph_HDRP.shadergraph create mode 100644 Resources/Materials/InstancedColorShaderGraph_HDRP.shadergraph.meta create mode 100644 Resources/Materials/ShaderInstancePropertiesInclude.hlsl create mode 100644 Resources/Materials/ShaderInstancePropertiesInclude.hlsl.meta diff --git a/AGXUnity/Rendering/CableRenderer.cs b/AGXUnity/Rendering/CableRenderer.cs index d26c0c2c..e2f6a32f 100644 --- a/AGXUnity/Rendering/CableRenderer.cs +++ b/AGXUnity/Rendering/CableRenderer.cs @@ -86,6 +86,8 @@ public bool InitializeRenderer( bool destructLast = false ) m_positions.Clear(); m_positions.Capacity = 256; + m_previousRenderDamages = true; // Inits the color vectors + return true; } @@ -194,7 +196,7 @@ void Draw( Camera camera = null ) int count = Mathf.Min( 1023, m_positions.Count - i ); if (m_segmentColors.Count > 0) - m_meshInstanceProperties.SetVectorArray("_Color", m_segmentColors[ i / 1023 ]); + m_meshInstanceProperties.SetVectorArray("_InstancedColor", m_segmentColors[ i / 1023 ]); Graphics.DrawMeshInstanced( m_sphereMeshInstance, 0, @@ -212,7 +214,7 @@ void Draw( Camera camera = null ) for ( int i = 0; i < m_numCylinders; i += 1023 ) { if (m_segmentColors.Count > 0) - m_meshInstanceProperties.SetVectorArray("_Color", m_segmentColors[ i / 1023 ]); + m_meshInstanceProperties.SetVectorArray("_InstancedColor", m_segmentColors[ i / 1023 ]); int count = Mathf.Min( 1023, m_numCylinders - i ); Graphics.DrawMeshInstanced( m_cylinderMeshInstance, @@ -297,7 +299,7 @@ private void SynchronizeData( bool isRoute ) m_segmentCylinderMatrices[ m_numCylinders / 1023 ][ m_numCylinders % 1023 ] = Matrix4x4.TRS( position, rotation, scale ); // If using render damage - if ((m_renderDamages || m_previousRenderDamages)){ + if (m_renderDamages || m_previousRenderDamages){ if (m_numCylinders / 1023 + 1 > m_segmentColors.Count) m_segmentColors.Add(new Vector4[1023]); diff --git a/Resources/Materials/CableMaterial_01_HDRP.mat b/Resources/Materials/CableMaterial_01_HDRP.mat new file mode 100644 index 00000000..f690a672 --- /dev/null +++ b/Resources/Materials/CableMaterial_01_HDRP.mat @@ -0,0 +1,166 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-6801270696830096067 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: CableMaterial_01_HDRP + m_Shader: {fileID: -6465566751694194690, guid: b9ac36e7bd7002b49997051eedd305f2, type: 3} + m_ShaderKeywords: _DISABLE_SSR_TRANSPARENT + m_LightmapFlags: 1 + m_EnableInstancingVariants: 1 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2225 + stringTagMap: + MotionVector: User + disabledShaderPasses: + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - MOTIONVECTORS + 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} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _Alpha: 0 + - _AlphaCutoffEnable: 0 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _AmbientOcclusion: 0 + - _BlendMode: 0 + - _BumpScale: 1 + - _ConservativeDepthOffsetEnable: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailNormalMapScale: 1 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 2 + - _DstBlend: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _GlossMapScale: 1 + - _Glossiness: 0.699 + - _GlossyReflections: 1 + - _Metallic: 0.167 + - _Mode: 0 + - _OcclusionStrength: 1 + - _OpaqueCullMode: 2 + - _Parallax: 0.02 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _RenderQueueType: 1 + - _RequireSplitLighting: 0 + - _Smoothness: 0.699 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _UVSec: 0 + - _UseShadowThreshold: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 0.1764706, g: 0.1764706, b: 0.1764706, a: 0} + - _Color: {r: 0.17647055, g: 0.17647055, b: 0.17647055, a: 0} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _Emission: {r: 0, g: 0, b: 0, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _Vector4: {r: 0, g: 0, b: 0, a: 0} + m_BuildTextureStacks: [] diff --git a/Resources/Materials/CableMaterial_01_HDRP.mat.meta b/Resources/Materials/CableMaterial_01_HDRP.mat.meta new file mode 100644 index 00000000..eba54a73 --- /dev/null +++ b/Resources/Materials/CableMaterial_01_HDRP.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0e859b04bcc1e2f49a48e0236d5a5978 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Resources/Materials/InstancedColorShaderGraph_HDRP.shadergraph b/Resources/Materials/InstancedColorShaderGraph_HDRP.shadergraph new file mode 100644 index 00000000..d3b17095 --- /dev/null +++ b/Resources/Materials/InstancedColorShaderGraph_HDRP.shadergraph @@ -0,0 +1,1575 @@ +{ + "m_SGVersion": 3, + "m_Type": "UnityEditor.ShaderGraph.GraphData", + "m_ObjectId": "fec6f1bf3258444f8e0ac87d02fcd022", + "m_Properties": [ + { + "m_Id": "900922bf7b0b4f1596506fa5f1209730" + }, + { + "m_Id": "341da26dd6d7453b9fb656f6bee80fd7" + }, + { + "m_Id": "19603ec7da08443c9e75bc3535ff67c9" + }, + { + "m_Id": "7d3569076cad4d69ae71b44d6fb956b7" + }, + { + "m_Id": "e604167bfd1c4660bd9c3809a9ee6aa8" + }, + { + "m_Id": "c0edcac1711b4a58972d60ac5719b3d8" + } + ], + "m_Keywords": [], + "m_Dropdowns": [], + "m_CategoryData": [ + { + "m_Id": "416e8060053a44c59f7407f61001bf23" + } + ], + "m_Nodes": [ + { + "m_Id": "520feefe461245179b2af6524feb5f0f" + }, + { + "m_Id": "02ca145233ac488790a87e93fd1b4f00" + }, + { + "m_Id": "2fd6966cbb134d16a60a6d921d210626" + }, + { + "m_Id": "8de2bfb72f1244768b2fbb3e22f9ee5f" + }, + { + "m_Id": "8a92b58dd8e448cc951a5908727593db" + }, + { + "m_Id": "f615a94eafae422796575ecc99d30764" + }, + { + "m_Id": "ab3f5b0e1e6e4425825084ed17e2f1ff" + }, + { + "m_Id": "b17706fe2a904bf4a992a183acb50bb5" + }, + { + "m_Id": "44d938a7e40643939e09c5a668612f49" + }, + { + "m_Id": "0c0195abb7d1495a93620bbd5f499714" + }, + { + "m_Id": "9c7c791016b84e9b842758ccc24d80e8" + }, + { + "m_Id": "2e62f578418e49188bdfd54989972d14" + }, + { + "m_Id": "7a8fbe9caa3b466fbf7a74baaa5b2c53" + }, + { + "m_Id": "98d85d8a087f4898bc1334fd7e27ec81" + }, + { + "m_Id": "693b240846544fcc84ce6215d8f0d24c" + }, + { + "m_Id": "2a66d142a7984af681de7a9631acb0bf" + }, + { + "m_Id": "58767eeaaa98410995ebdd5d58c24c02" + }, + { + "m_Id": "78f3d7e178ac40af98fdf802c1708588" + } + ], + "m_GroupDatas": [], + "m_StickyNoteDatas": [], + "m_Edges": [ + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "2a66d142a7984af681de7a9631acb0bf" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "44d938a7e40643939e09c5a668612f49" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "2e62f578418e49188bdfd54989972d14" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "8de2bfb72f1244768b2fbb3e22f9ee5f" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "58767eeaaa98410995ebdd5d58c24c02" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "0c0195abb7d1495a93620bbd5f499714" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "693b240846544fcc84ce6215d8f0d24c" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "b17706fe2a904bf4a992a183acb50bb5" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "78f3d7e178ac40af98fdf802c1708588" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "9c7c791016b84e9b842758ccc24d80e8" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "7a8fbe9caa3b466fbf7a74baaa5b2c53" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "2e62f578418e49188bdfd54989972d14" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "98d85d8a087f4898bc1334fd7e27ec81" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "ab3f5b0e1e6e4425825084ed17e2f1ff" + }, + "m_SlotId": 0 + } + } + ], + "m_VertexContext": { + "m_Position": { + "x": 0.0, + "y": 0.0 + }, + "m_Blocks": [ + { + "m_Id": "520feefe461245179b2af6524feb5f0f" + }, + { + "m_Id": "02ca145233ac488790a87e93fd1b4f00" + }, + { + "m_Id": "2fd6966cbb134d16a60a6d921d210626" + } + ] + }, + "m_FragmentContext": { + "m_Position": { + "x": 0.0, + "y": 198.0 + }, + "m_Blocks": [ + { + "m_Id": "8de2bfb72f1244768b2fbb3e22f9ee5f" + }, + { + "m_Id": "8a92b58dd8e448cc951a5908727593db" + }, + { + "m_Id": "f615a94eafae422796575ecc99d30764" + }, + { + "m_Id": "ab3f5b0e1e6e4425825084ed17e2f1ff" + }, + { + "m_Id": "b17706fe2a904bf4a992a183acb50bb5" + }, + { + "m_Id": "44d938a7e40643939e09c5a668612f49" + }, + { + "m_Id": "0c0195abb7d1495a93620bbd5f499714" + }, + { + "m_Id": "9c7c791016b84e9b842758ccc24d80e8" + } + ] + }, + "m_PreviewData": { + "serializedMesh": { + "m_SerializedMesh": "{\"mesh\":{\"instanceID\":0}}", + "m_Guid": "" + }, + "preventRotation": false + }, + "m_Path": "Shader Graphs", + "m_GraphPrecision": 1, + "m_PreviewMode": 2, + "m_OutputNode": { + "m_Id": "" + }, + "m_ActiveTargets": [ + { + "m_Id": "f4b16255baa344b5bc294a6d24ddbb5f" + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "02ca145233ac488790a87e93fd1b4f00", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Normal", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "58f05893794e451db34822e443432729" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Normal" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "0b5ee969edcb486a9fd3b5d188905480", + "m_Id": 0, + "m_DisplayName": "Alpha", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Alpha", + "m_StageCapability": 2, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "0c0195abb7d1495a93620bbd5f499714", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Occlusion", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "1764db5ebf674182ac0e9c895877abb8" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Occlusion" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "1764db5ebf674182ac0e9c895877abb8", + "m_Id": 0, + "m_DisplayName": "Ambient Occlusion", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Occlusion", + "m_StageCapability": 2, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 3, + "m_Type": "UnityEditor.ShaderGraph.Internal.ColorShaderProperty", + "m_ObjectId": "19603ec7da08443c9e75bc3535ff67c9", + "m_Guid": { + "m_GuidSerialized": "76fb2906-a9c3-4f83-8bf5-c674caf07937" + }, + "m_Name": "Emission", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "Emission", + "m_DefaultReferenceName": "_Emission", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "isMainColor": false, + "m_ColorMode": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDLitData", + "m_ObjectId": "1ec208117d13474dbc5d879a98101d46", + "m_RayTracing": false, + "m_MaterialType": 0, + "m_RefractionModel": 0, + "m_SSSTransmission": true, + "m_EnergyConservingSpecular": true, + "m_ClearCoat": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "2a66d142a7984af681de7a9631acb0bf", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -140.0, + "y": 442.0000305175781, + "width": 140.0, + "height": 34.0 + } + }, + "m_Slots": [ + { + "m_Id": "fd028618587b42d9adf1051bb43ca9df" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "7d3569076cad4d69ae71b44d6fb956b7" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PositionMaterialSlot", + "m_ObjectId": "2b27422df24749bf90ad070699934ad6", + "m_Id": 0, + "m_DisplayName": "Position", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Position", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.CustomFunctionNode", + "m_ObjectId": "2e62f578418e49188bdfd54989972d14", + "m_Group": { + "m_Id": "" + }, + "m_Name": "InstanceColor (Custom Function)", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -336.6666564941406, + "y": 198.0, + "width": 233.33331298828126, + "height": 278.0000305175781 + } + }, + "m_Slots": [ + { + "m_Id": "3d8207473bfb404388f4768c95858776" + }, + { + "m_Id": "4c2915f8058e40e0954f0cc241e2d700" + } + ], + "synonyms": [ + "code", + "HLSL" + ], + "m_Precision": 1, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SourceType": 0, + "m_FunctionName": "InstanceColor", + "m_FunctionSource": "4de7a1ee9eaa86d4dab3af3ec30d2d86", + "m_FunctionBody": "Enter function body here..." +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "2fce5baac0cc42cfad629d747d57e3bc", + "m_Id": 0, + "m_DisplayName": "BaseColor", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "2fd6966cbb134d16a60a6d921d210626", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Tangent", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "45e455ee47394fa99930a44817bff4a2" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Tangent" +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.Internal.Vector1ShaderProperty", + "m_ObjectId": "341da26dd6d7453b9fb656f6bee80fd7", + "m_Guid": { + "m_GuidSerialized": "aa2ad89a-6ea3-441d-8d8f-7387b78ceb47" + }, + "m_Name": "Metallic", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "Metallic", + "m_DefaultReferenceName": "_Metallic", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": 0.0, + "m_FloatType": 0, + "m_RangeValues": { + "x": 0.0, + "y": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "3d8207473bfb404388f4768c95858776", + "m_Id": 1, + "m_DisplayName": "BaseColor", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "BaseColor", + "m_StageCapability": 3, + "m_Value": { + "x": 45.0, + "y": 45.0, + "z": 45.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.CategoryData", + "m_ObjectId": "416e8060053a44c59f7407f61001bf23", + "m_Name": "", + "m_ChildObjectList": [ + { + "m_Id": "900922bf7b0b4f1596506fa5f1209730" + }, + { + "m_Id": "341da26dd6d7453b9fb656f6bee80fd7" + }, + { + "m_Id": "19603ec7da08443c9e75bc3535ff67c9" + }, + { + "m_Id": "7d3569076cad4d69ae71b44d6fb956b7" + }, + { + "m_Id": "e604167bfd1c4660bd9c3809a9ee6aa8" + }, + { + "m_Id": "c0edcac1711b4a58972d60ac5719b3d8" + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "44d938a7e40643939e09c5a668612f49", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Smoothness", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "b9e1ee36daa441b782177cf3dfbe8cb4" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Smoothness" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TangentMaterialSlot", + "m_ObjectId": "45e455ee47394fa99930a44817bff4a2", + "m_Id": 0, + "m_DisplayName": "Tangent", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Tangent", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "4c2915f8058e40e0954f0cc241e2d700", + "m_Id": 0, + "m_DisplayName": "Color", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Color", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "4d8c13f35edb4d979bced96244bc55fa", + "m_Id": 0, + "m_DisplayName": "Emission", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Emission", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_ColorMode": 1, + "m_DefaultColor": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "520feefe461245179b2af6524feb5f0f", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Position", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "2b27422df24749bf90ad070699934ad6" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Position" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "58767eeaaa98410995ebdd5d58c24c02", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -170.0, + "y": 486.6666564941406, + "width": 170.0, + "height": 33.999969482421878 + } + }, + "m_Slots": [ + { + "m_Id": "f0fbdc0ebc504f9e9e6a703cfcb9e583" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "e604167bfd1c4660bd9c3809a9ee6aa8" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "58f05893794e451db34822e443432729", + "m_Id": 0, + "m_DisplayName": "Normal", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Normal", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "5c4c86ae4bfd47fab49d6c406b75f327", + "m_Id": 0, + "m_DisplayName": "Alpha", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "693b240846544fcc84ce6215d8f0d24c", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -123.33334350585938, + "y": 392.0000305175781, + "width": 123.33334350585938, + "height": 34.0 + } + }, + "m_Slots": [ + { + "m_Id": "93fb83d886e3458ab58fdabc05097a62" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "19603ec7da08443c9e75bc3535ff67c9" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDLitSubTarget", + "m_ObjectId": "6b683aa5d811432c97fb0ffbeb0231f3" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "78f3d7e178ac40af98fdf802c1708588", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -99.0, + "y": 532.6666259765625, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "5c4c86ae4bfd47fab49d6c406b75f327" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "c0edcac1711b4a58972d60ac5719b3d8" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "7a8fbe9caa3b466fbf7a74baaa5b2c53", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -336.6666564941406, + "y": 127.33334350585938, + "width": 130.66665649414063, + "height": 34.0 + } + }, + "m_Slots": [ + { + "m_Id": "2fce5baac0cc42cfad629d747d57e3bc" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "900922bf7b0b4f1596506fa5f1209730" + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.Internal.Vector1ShaderProperty", + "m_ObjectId": "7d3569076cad4d69ae71b44d6fb956b7", + "m_Guid": { + "m_GuidSerialized": "432442d1-530b-4cbb-8612-20f8ca90fe38" + }, + "m_Name": "Smoothness", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "Smoothness", + "m_DefaultReferenceName": "_Smoothness", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": 0.0, + "m_FloatType": 0, + "m_RangeValues": { + "x": 0.0, + "y": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "8a92b58dd8e448cc951a5908727593db", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.NormalTS", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "eb5b836630f644d59fc57e8ced303485" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.NormalTS" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "8de2bfb72f1244768b2fbb3e22f9ee5f", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.BaseColor", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "f2a0210e871e45e1b9fd3dab3f4b1108" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.BaseColor" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "8f689d3ceb0e4b8da173c4e674144e8a", + "m_Id": 0, + "m_DisplayName": "Metallic", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 3, + "m_Type": "UnityEditor.ShaderGraph.Internal.ColorShaderProperty", + "m_ObjectId": "900922bf7b0b4f1596506fa5f1209730", + "m_Guid": { + "m_GuidSerialized": "3d207b84-c679-4a4e-ae08-7ff1aea94e35" + }, + "m_Name": "BaseColor", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "BaseColor", + "m_DefaultReferenceName": "_BaseColor", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 2, + "m_Hidden": false, + "m_Value": { + "r": 0.1764705926179886, + "g": 0.1764705926179886, + "b": 0.1764705926179886, + "a": 0.0 + }, + "isMainColor": false, + "m_ColorMode": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "923f36a228ed4a1381f91ec4b8c529e4", + "m_Id": 0, + "m_DisplayName": "Metallic", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Metallic", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "93fb83d886e3458ab58fdabc05097a62", + "m_Id": 0, + "m_DisplayName": "Emission", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.SystemData", + "m_ObjectId": "95450f37da7f483fa4c7000d84d0f128", + "m_MaterialNeedsUpdateHash": 529, + "m_SurfaceType": 0, + "m_RenderingPass": 1, + "m_BlendMode": 0, + "m_ZTest": 4, + "m_ZWrite": false, + "m_TransparentCullMode": 2, + "m_OpaqueCullMode": 2, + "m_SortPriority": 0, + "m_AlphaTest": false, + "m_TransparentDepthPrepass": false, + "m_TransparentDepthPostpass": false, + "m_SupportLodCrossFade": false, + "m_DoubleSidedMode": 0, + "m_DOTSInstancing": false, + "m_CustomVelocity": false, + "m_Tessellation": false, + "m_TessellationMode": 0, + "m_TessellationFactorMinDistance": 20.0, + "m_TessellationFactorMaxDistance": 50.0, + "m_TessellationFactorTriangleSize": 100.0, + "m_TessellationShapeFactor": 0.75, + "m_TessellationBackFaceCullEpsilon": -0.25, + "m_TessellationMaxDisplacement": 0.009999999776482582, + "m_Version": 1, + "inspectorFoldoutMask": 9 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "98d85d8a087f4898bc1334fd7e27ec81", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -116.0, + "y": 358.0000305175781, + "width": 116.0, + "height": 34.0 + } + }, + "m_Slots": [ + { + "m_Id": "8f689d3ceb0e4b8da173c4e674144e8a" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "341da26dd6d7453b9fb656f6bee80fd7" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "9c18393006cf41bab2fda3f8f4338910", + "m_Id": 0, + "m_DisplayName": "Bent Normal", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "BentNormal", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 3 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "9c7c791016b84e9b842758ccc24d80e8", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Alpha", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "0b5ee969edcb486a9fd3b5d188905480" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Alpha" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "ab3f5b0e1e6e4425825084ed17e2f1ff", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Metallic", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "923f36a228ed4a1381f91ec4b8c529e4" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Metallic" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.BuiltinData", + "m_ObjectId": "add1f4666e3f436aba3768246c6d0f97", + "m_Distortion": false, + "m_DistortionMode": 0, + "m_DistortionDepthTest": true, + "m_AddPrecomputedVelocity": false, + "m_TransparentWritesMotionVec": false, + "m_AlphaToMask": false, + "m_DepthOffset": false, + "m_ConservativeDepthOffset": false, + "m_TransparencyFog": true, + "m_AlphaTestShadow": false, + "m_BackThenFrontRendering": false, + "m_TransparentDepthPrepass": false, + "m_TransparentDepthPostpass": false, + "m_SupportLodCrossFade": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "b17706fe2a904bf4a992a183acb50bb5", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Emission", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "4d8c13f35edb4d979bced96244bc55fa" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Emission" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "b9e1ee36daa441b782177cf3dfbe8cb4", + "m_Id": 0, + "m_DisplayName": "Smoothness", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Smoothness", + "m_StageCapability": 2, + "m_Value": 0.5, + "m_DefaultValue": 0.5, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.LightingData", + "m_ObjectId": "bef78d1c2ab74d36bc4137d6357f323c", + "m_NormalDropOffSpace": 0, + "m_BlendPreserveSpecular": true, + "m_ReceiveDecals": true, + "m_ReceiveSSR": true, + "m_ReceiveSSRTransparent": false, + "m_SpecularAA": false, + "m_SpecularOcclusionMode": 1, + "m_OverrideBakedGI": false +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.Internal.Vector1ShaderProperty", + "m_ObjectId": "c0edcac1711b4a58972d60ac5719b3d8", + "m_Guid": { + "m_GuidSerialized": "2cdd9660-927e-4c5f-8923-0d8110956b22" + }, + "m_Name": "Alpha", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "Alpha", + "m_DefaultReferenceName": "_Alpha", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": 0.0, + "m_FloatType": 0, + "m_RangeValues": { + "x": 0.0, + "y": 1.0 + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.Internal.Vector1ShaderProperty", + "m_ObjectId": "e604167bfd1c4660bd9c3809a9ee6aa8", + "m_Guid": { + "m_GuidSerialized": "3379f481-75c2-4a76-b342-5a7970b63267" + }, + "m_Name": "AmbientOcclusion", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "AmbientOcclusion", + "m_DefaultReferenceName": "_AmbientOcclusion", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": 0.0, + "m_FloatType": 0, + "m_RangeValues": { + "x": 0.0, + "y": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "eb5b836630f644d59fc57e8ced303485", + "m_Id": 0, + "m_DisplayName": "Normal (Tangent Space)", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "NormalTS", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 3 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "f0fbdc0ebc504f9e9e6a703cfcb9e583", + "m_Id": 0, + "m_DisplayName": "AmbientOcclusion", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "f2a0210e871e45e1b9fd3dab3f4b1108", + "m_Id": 0, + "m_DisplayName": "Base Color", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "BaseColor", + "m_StageCapability": 2, + "m_Value": { + "x": 0.5, + "y": 0.5, + "z": 0.5 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 0.5, + "g": 0.5, + "b": 0.5, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDTarget", + "m_ObjectId": "f4b16255baa344b5bc294a6d24ddbb5f", + "m_ActiveSubTarget": { + "m_Id": "6b683aa5d811432c97fb0ffbeb0231f3" + }, + "m_Datas": [ + { + "m_Id": "1ec208117d13474dbc5d879a98101d46" + }, + { + "m_Id": "add1f4666e3f436aba3768246c6d0f97" + }, + { + "m_Id": "bef78d1c2ab74d36bc4137d6357f323c" + }, + { + "m_Id": "95450f37da7f483fa4c7000d84d0f128" + } + ], + "m_CustomEditorGUI": "", + "m_SupportVFX": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "f615a94eafae422796575ecc99d30764", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.BentNormal", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "9c18393006cf41bab2fda3f8f4338910" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.BentNormal" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "fd028618587b42d9adf1051bb43ca9df", + "m_Id": 0, + "m_DisplayName": "Smoothness", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + diff --git a/Resources/Materials/InstancedColorShaderGraph_HDRP.shadergraph.meta b/Resources/Materials/InstancedColorShaderGraph_HDRP.shadergraph.meta new file mode 100644 index 00000000..72783add --- /dev/null +++ b/Resources/Materials/InstancedColorShaderGraph_HDRP.shadergraph.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b9ac36e7bd7002b49997051eedd305f2 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} diff --git a/Resources/Materials/InstancedColorSurfaceShader.shader b/Resources/Materials/InstancedColorSurfaceShader.shader index 04ac3089..5775e2e6 100644 --- a/Resources/Materials/InstancedColorSurfaceShader.shader +++ b/Resources/Materials/InstancedColorSurfaceShader.shader @@ -36,13 +36,14 @@ Shader "Custom/CableDamageShader" // #pragma instancing_options assumeuniformscaling UNITY_INSTANCING_BUFFER_START(Props) // put more per-instance properties here - UNITY_DEFINE_INSTANCED_PROP(float4, _Color) + UNITY_DEFINE_INSTANCED_PROP(float4, _InstancedColor) UNITY_INSTANCING_BUFFER_END(Props) void surf (Input IN, inout SurfaceOutputStandard o) { // Albedo comes from a texture tinted by color - fixed4 color = UNITY_ACCESS_INSTANCED_PROP(Props, _Color); + fixed4 color = _Color; + color = UNITY_ACCESS_INSTANCED_PROP(Props, _InstancedColor); // Override if there is an instanced prop fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * color; o.Albedo = c.rgb; // Metallic and smoothness come from slider variables diff --git a/Resources/Materials/ShaderInstancePropertiesInclude.hlsl b/Resources/Materials/ShaderInstancePropertiesInclude.hlsl new file mode 100644 index 00000000..593c5aa5 --- /dev/null +++ b/Resources/Materials/ShaderInstancePropertiesInclude.hlsl @@ -0,0 +1,18 @@ +#ifndef CUSTOM_INSTANCING +#define CUSTOM_INSTANCING + +// Set up instance properties buffer +UNITY_INSTANCING_BUFFER_START(Props) + UNITY_DEFINE_INSTANCED_PROP(float4, _InstancedColor) +UNITY_INSTANCING_BUFFER_END(Props) + +float4 _Color = (0.3,0.3,0.3,1); + +// Returns _Color for this instance +void InstanceColor_float(float4 _BaseColor, out float4 Color) +{ + Color = _Color; + Color = UNITY_ACCESS_INSTANCED_PROP(Props, _InstancedColor); // Override if there is an instanced prop +} + +#endif \ No newline at end of file diff --git a/Resources/Materials/ShaderInstancePropertiesInclude.hlsl.meta b/Resources/Materials/ShaderInstancePropertiesInclude.hlsl.meta new file mode 100644 index 00000000..9d5c5630 --- /dev/null +++ b/Resources/Materials/ShaderInstancePropertiesInclude.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 4de7a1ee9eaa86d4dab3af3ec30d2d86 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From b431d659da165d3fef438ec56b4f0034cbebc8d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20M=C3=B6rk?= Date: Tue, 7 Nov 2023 13:05:20 +0100 Subject: [PATCH 07/12] Change name of property to avoid conflict --- AGXUnity/Rendering/CableRenderer.cs | 4 ++-- Resources/Materials/InstancedColorSurfaceShader.shader | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/AGXUnity/Rendering/CableRenderer.cs b/AGXUnity/Rendering/CableRenderer.cs index d26c0c2c..816c9ead 100644 --- a/AGXUnity/Rendering/CableRenderer.cs +++ b/AGXUnity/Rendering/CableRenderer.cs @@ -194,7 +194,7 @@ void Draw( Camera camera = null ) int count = Mathf.Min( 1023, m_positions.Count - i ); if (m_segmentColors.Count > 0) - m_meshInstanceProperties.SetVectorArray("_Color", m_segmentColors[ i / 1023 ]); + m_meshInstanceProperties.SetVectorArray("_InstancedColor", m_segmentColors[ i / 1023 ]); Graphics.DrawMeshInstanced( m_sphereMeshInstance, 0, @@ -212,7 +212,7 @@ void Draw( Camera camera = null ) for ( int i = 0; i < m_numCylinders; i += 1023 ) { if (m_segmentColors.Count > 0) - m_meshInstanceProperties.SetVectorArray("_Color", m_segmentColors[ i / 1023 ]); + m_meshInstanceProperties.SetVectorArray("_InstancedColor", m_segmentColors[ i / 1023 ]); int count = Mathf.Min( 1023, m_numCylinders - i ); Graphics.DrawMeshInstanced( m_cylinderMeshInstance, diff --git a/Resources/Materials/InstancedColorSurfaceShader.shader b/Resources/Materials/InstancedColorSurfaceShader.shader index 04ac3089..a1f6c7c0 100644 --- a/Resources/Materials/InstancedColorSurfaceShader.shader +++ b/Resources/Materials/InstancedColorSurfaceShader.shader @@ -36,13 +36,13 @@ Shader "Custom/CableDamageShader" // #pragma instancing_options assumeuniformscaling UNITY_INSTANCING_BUFFER_START(Props) // put more per-instance properties here - UNITY_DEFINE_INSTANCED_PROP(float4, _Color) + UNITY_DEFINE_INSTANCED_PROP(float4, _InstancedColor) UNITY_INSTANCING_BUFFER_END(Props) void surf (Input IN, inout SurfaceOutputStandard o) { // Albedo comes from a texture tinted by color - fixed4 color = UNITY_ACCESS_INSTANCED_PROP(Props, _Color); + fixed4 color = UNITY_ACCESS_INSTANCED_PROP(Props, _InstancedColor); fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * color; o.Albedo = c.rgb; // Metallic and smoothness come from slider variables From e08029c585d83da8f716a98b5308dcbf9b1d7203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20M=C3=B6rk?= Date: Wed, 8 Nov 2023 10:55:21 +0100 Subject: [PATCH 08/12] Move shader to own directory --- Resources/Shaders.meta | 8 ++++++++ .../InstancedColorSurfaceShader.shader | 0 .../InstancedColorSurfaceShader.shader.meta | 0 3 files changed, 8 insertions(+) create mode 100644 Resources/Shaders.meta rename Resources/{Materials => Shaders}/InstancedColorSurfaceShader.shader (100%) rename Resources/{Materials => Shaders}/InstancedColorSurfaceShader.shader.meta (100%) diff --git a/Resources/Shaders.meta b/Resources/Shaders.meta new file mode 100644 index 00000000..2b9b4f78 --- /dev/null +++ b/Resources/Shaders.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f4440226a2336a04db253e3257d16d36 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Resources/Materials/InstancedColorSurfaceShader.shader b/Resources/Shaders/InstancedColorSurfaceShader.shader similarity index 100% rename from Resources/Materials/InstancedColorSurfaceShader.shader rename to Resources/Shaders/InstancedColorSurfaceShader.shader diff --git a/Resources/Materials/InstancedColorSurfaceShader.shader.meta b/Resources/Shaders/InstancedColorSurfaceShader.shader.meta similarity index 100% rename from Resources/Materials/InstancedColorSurfaceShader.shader.meta rename to Resources/Shaders/InstancedColorSurfaceShader.shader.meta From a01aa6619f512a36a6306a8e754d106993d436f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20M=C3=B6rk?= Date: Wed, 8 Nov 2023 11:06:40 +0100 Subject: [PATCH 09/12] Add old cable renderer as fallback --- AGXUnity/Rendering/CableRendererFallback.cs | 226 ++++++++++++++++++ .../Rendering/CableRendererFallback.cs.meta | 11 + ...y+Rendering+CableRendererFallbackEditor.cs | 13 + ...dering+CableRendererFallbackEditor.cs.meta | 11 + 4 files changed, 261 insertions(+) create mode 100644 AGXUnity/Rendering/CableRendererFallback.cs create mode 100644 AGXUnity/Rendering/CableRendererFallback.cs.meta create mode 100644 Editor/CustomEditors/AGXUnity+Rendering+CableRendererFallbackEditor.cs create mode 100644 Editor/CustomEditors/AGXUnity+Rendering+CableRendererFallbackEditor.cs.meta diff --git a/AGXUnity/Rendering/CableRendererFallback.cs b/AGXUnity/Rendering/CableRendererFallback.cs new file mode 100644 index 00000000..f4417c2c --- /dev/null +++ b/AGXUnity/Rendering/CableRendererFallback.cs @@ -0,0 +1,226 @@ +using UnityEngine; +using AGXUnity.Utils; +using System.Collections.Generic; + +namespace AGXUnity.Rendering +{ + [AddComponentMenu( "AGXUnity/Rendering/Cable Renderer Fallback" )] + [ExecuteInEditMode] + [RequireComponent( typeof( Cable ) )] + public class CableRendererFallback : ScriptComponent + { + [SerializeField] + private SegmentSpawner m_segmentSpawner = null; + + [HideInInspector] + public SegmentSpawner SegmentSpawner { get { return m_segmentSpawner; } } + + [System.NonSerialized] + private Cable m_cable = null; + + [HideInInspector] + public Cable Cable + { + get + { + return m_cable ?? ( m_cable = GetComponent() ); + } + } + + [SerializeField] + private Material m_material = null; + public Material Material + { + get { return m_material ?? m_segmentSpawner.DefaultMaterial; } + set + { + m_material = value ?? m_segmentSpawner.DefaultMaterial; + m_segmentSpawner.Material = m_material; + } + } + + private CableDamage m_cableDamage = null; + private CableDamage CableDamage { get { return m_cableDamage ?? ( m_cableDamage = GetComponent() ); } } + + public void SetRenderDamages(bool value) => m_renderDamages = value; + + private bool m_renderDamages = false, m_previousRenderDamages = false; + private Dictionary m_segmentRenderers = new Dictionary(); + + public void InitializeRenderer( bool destructLast = false ) + { + if ( m_segmentSpawner != null ) { + m_segmentSpawner.Destroy(); + m_segmentSpawner = null; + } + + m_segmentSpawner = new SegmentSpawner( Cable, + @"Cable/CableSegment", + @"Cable/CableSegmentBegin" ); + m_segmentSpawner.Initialize( gameObject ); + } + + protected override void OnEnable() + { + OnEnableDisable( true ); + } + + protected override void OnDisable() + { + OnEnableDisable( false ); + } + + protected void LateUpdate() + { + // Late update from Editor. Exit if the application is running. + if ( Application.isPlaying ) + return; + + Render( Cable.Route, Cable.Radius ); + } + + private void Render( CableRoute route, float radius ) + { + if ( m_segmentSpawner == null ) + return; + + // Let OnDrawGizmos handle rendering when in prefab edit mode. + // It's not possible to use RuntimeObjects while there. + if ( PrefabUtils.IsPartOfEditingPrefab( gameObject ) ) + return; + + if ( !Cable.RoutePointCurveUpToDate ) + Cable.SynchronizeRoutePointCurve(); + + m_segmentSpawner.Begin(); + try { + var points = Cable.GetRoutePoints(); + for ( int i = 1; i < points.Length; ++i ) + m_segmentSpawner.CreateSegment( points[ i - 1 ], points[ i ], radius ); + } + catch ( System.Exception e ) { + Debug.LogException( e, this ); + } + m_segmentSpawner.End(); + } + + private void Render() + { + if ( m_segmentSpawner == null ) + return; + + var native = Cable.Native; + if ( native == null ) { + if ( m_segmentSpawner != null ) { + m_segmentSpawner.Destroy(); + m_segmentSpawner = null; + } + return; + } + else if ( !m_segmentSpawner.IsValid ) + InitializeRenderer( true ); + + var it = native.begin(); + var endIt = native.end(); + int i = 0; + + MaterialPropertyBlock block = new MaterialPropertyBlock(); + + m_segmentSpawner.Begin(); + try { + float radius = Cable.Radius; + var prevEndPosition = it.EqualWith( endIt ) ? + Vector3.zero : + it.getBeginPosition().ToHandedVector3(); + while ( !it.EqualWith( endIt ) ) { + var endPosition = it.getEndPosition().ToHandedVector3(); + + var go = m_segmentSpawner.CreateSegment( prevEndPosition, endPosition, radius ); + + // If using render damage + if ((m_renderDamages || m_previousRenderDamages)){ + int id = go.GetInstanceID(); + + (MeshRenderer, MeshRenderer) meshRenderers; + if (m_segmentRenderers.TryGetValue(id, out meshRenderers) && meshRenderers.Item1 != null){ + if (m_renderDamages && CableDamage.DamageValueCount == (int)native.getNumSegments()){ // TODO do we need the length check? + float t = CableDamage.DamageValue(i) / CableDamage.MaxDamage; + block.SetColor("_Color", Color.Lerp(CableDamage.Properties.MinColor, CableDamage.Properties.MaxColor, t)); + meshRenderers.Item1.SetPropertyBlock(block); + meshRenderers.Item2.SetPropertyBlock(block); + } + else{ + block.SetColor("_Color", Material.color); + meshRenderers.Item1.SetPropertyBlock(block); + meshRenderers.Item2.SetPropertyBlock(block); + } + } + else { + var renderers = go.GetComponentsInChildren(); + m_segmentRenderers.Add(id, (renderers[0], renderers[1])); + } + } + + i++; + prevEndPosition = endPosition; + it.inc(); + } + } + catch ( System.Exception e ) { + Debug.LogException( e, this ); + } + m_segmentSpawner.End(); + + m_previousRenderDamages = m_renderDamages; + + it.ReturnToPool(); + endIt.ReturnToPool(); + } + + private void OnEnableDisable( bool enable ) + { + if ( enable ) { + InitializeRenderer( true ); + if ( Application.isPlaying ) + Simulation.Instance.StepCallbacks.PostStepForward += Render; + } + else { + if ( m_segmentSpawner != null ) { + m_segmentSpawner.Destroy(); + m_segmentSpawner = null; + } + + if ( Simulation.HasInstance && Application.isPlaying ) + Simulation.Instance.StepCallbacks.PostStepForward -= Render; + } + } + + private void DrawGizmos( bool isSelected ) + { + if ( Application.isPlaying ) + return; + + if ( Cable == null || Cable.Route == null || Cable.Route.NumNodes < 2 ) + return; + + if ( !PrefabUtils.IsPartOfEditingPrefab( gameObject ) ) + return; + + var defaultColor = Color.Lerp( Color.black, Color.white, 0.15f ); + var selectedColor = Color.Lerp( defaultColor, Color.green, 0.15f ); + m_segmentSpawner?.DrawGizmos( Cable.GetRoutePoints(), + Cable.Radius, + isSelected ? selectedColor : defaultColor ); + } + + private void OnDrawGizmos() + { + DrawGizmos( false ); + } + + private void OnDrawGizmosSelected() + { + DrawGizmos( true ); + } + } +} diff --git a/AGXUnity/Rendering/CableRendererFallback.cs.meta b/AGXUnity/Rendering/CableRendererFallback.cs.meta new file mode 100644 index 00000000..79d26365 --- /dev/null +++ b/AGXUnity/Rendering/CableRendererFallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fd6b70ee9d5e49d47ab8558d1f207005 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 12c3d7669b4084649bd28f0b7c695431, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/CustomEditors/AGXUnity+Rendering+CableRendererFallbackEditor.cs b/Editor/CustomEditors/AGXUnity+Rendering+CableRendererFallbackEditor.cs new file mode 100644 index 00000000..8ee987e1 --- /dev/null +++ b/Editor/CustomEditors/AGXUnity+Rendering+CableRendererFallbackEditor.cs @@ -0,0 +1,13 @@ + +using System; +using AGXUnity; +using AGXUnity.Collide; +using UnityEditor; + +namespace AGXUnityEditor.Editors +{ + [CustomEditor( typeof( AGXUnity.Rendering.CableRendererFallback ) )] + [CanEditMultipleObjects] + public class AGXUnityRenderingCableRendererFallbackEditor : InspectorEditor + { } +} \ No newline at end of file diff --git a/Editor/CustomEditors/AGXUnity+Rendering+CableRendererFallbackEditor.cs.meta b/Editor/CustomEditors/AGXUnity+Rendering+CableRendererFallbackEditor.cs.meta new file mode 100644 index 00000000..1e1a324f --- /dev/null +++ b/Editor/CustomEditors/AGXUnity+Rendering+CableRendererFallbackEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c095de2b8713ee041965b11582f9805a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 47664a092e171a77ff8f251d4e805da5052ee7f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20M=C3=B6rk?= Date: Tue, 14 Nov 2023 16:23:27 +0100 Subject: [PATCH 10/12] Add _Color property from customer feedback --- Resources/Shaders/InstancedColorSurfaceShader.shader | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Shaders/InstancedColorSurfaceShader.shader b/Resources/Shaders/InstancedColorSurfaceShader.shader index a1f6c7c0..c5ce412c 100644 --- a/Resources/Shaders/InstancedColorSurfaceShader.shader +++ b/Resources/Shaders/InstancedColorSurfaceShader.shader @@ -30,6 +30,7 @@ Shader "Custom/CableDamageShader" half _Glossiness; half _Metallic; + half _Color; // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader. // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing. From d20faf8ada049f8b5c40ab237e13451e9e1d914d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20M=C3=B6rk?= Date: Tue, 14 Nov 2023 16:34:08 +0100 Subject: [PATCH 11/12] Rename shader --- Resources/Shaders/InstancedColorSurfaceShader.shader | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Shaders/InstancedColorSurfaceShader.shader b/Resources/Shaders/InstancedColorSurfaceShader.shader index a9a93731..8d23d400 100644 --- a/Resources/Shaders/InstancedColorSurfaceShader.shader +++ b/Resources/Shaders/InstancedColorSurfaceShader.shader @@ -1,4 +1,4 @@ -Shader "Custom/CableDamageShader" +Shader "AGXUnity/CableDamageShader" { Properties { From e9d49b65b527a6273d116d183a99f9c6d8bcd10e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20M=C3=B6rk?= Date: Tue, 14 Nov 2023 17:03:17 +0100 Subject: [PATCH 12/12] References to manual --- AGXUnity/Rendering/CableRenderer.cs | 1 + AGXUnity/Rendering/CableRendererFallback.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/AGXUnity/Rendering/CableRenderer.cs b/AGXUnity/Rendering/CableRenderer.cs index e2f6a32f..40c39e23 100644 --- a/AGXUnity/Rendering/CableRenderer.cs +++ b/AGXUnity/Rendering/CableRenderer.cs @@ -9,6 +9,7 @@ namespace AGXUnity.Rendering [AddComponentMenu( "AGXUnity/Rendering/Cable Renderer" )] [ExecuteInEditMode] [RequireComponent( typeof( Cable ) )] + [HelpURL( "https://us.download.algoryx.se/AGXUnity/documentation/current/editor_interface.html#cable-rendering" )] public class CableRenderer : ScriptComponent { /// diff --git a/AGXUnity/Rendering/CableRendererFallback.cs b/AGXUnity/Rendering/CableRendererFallback.cs index f4417c2c..86d40d84 100644 --- a/AGXUnity/Rendering/CableRendererFallback.cs +++ b/AGXUnity/Rendering/CableRendererFallback.cs @@ -7,6 +7,7 @@ namespace AGXUnity.Rendering [AddComponentMenu( "AGXUnity/Rendering/Cable Renderer Fallback" )] [ExecuteInEditMode] [RequireComponent( typeof( Cable ) )] + [HelpURL( "https://us.download.algoryx.se/AGXUnity/documentation/current/editor_interface.html#cable-rendering" )] public class CableRendererFallback : ScriptComponent { [SerializeField]