// Amplify Shader Editor - Visual Shader Editing Tool // Copyright (c) Amplify Creations, Lda using System; using UnityEditor; using UnityEngine; namespace AmplifyShaderEditor { [Serializable] [NodeAttributes( "Voronoi", "Miscellaneous", "Voronoi", Tags = "noise" )] public sealed class VoronoiNode : ParentNode { // Unity Voronoi private readonly string UnityVoronoiNoiseFunc = "UnityVoronoi({0},{1},{2},{3})"; private readonly string[] UnityVoroniNoiseFunctionsBody = { "inline float2 UnityVoronoiRandomVector( float2 UV, float offset )\n", "{\n", "\tfloat2x2 m = float2x2( 15.27, 47.63, 99.41, 89.98 );\n", "\tUV = frac( sin(mul(UV, m) ) * 46839.32 );\n", "\treturn float2( sin(UV.y* +offset ) * 0.5 + 0.5, cos( UV.x* offset ) * 0.5 + 0.5 );\n", "}\n", "\n", "//x - Out y - Cells\n", "float3 UnityVoronoi( float2 UV, float AngleOffset, float CellDensity, inout float2 mr )\n", "{\n", "\tfloat2 g = floor( UV * CellDensity );\n", "\tfloat2 f = frac( UV * CellDensity );\n", "\tfloat t = 8.0;\n", "\tfloat3 res = float3( 8.0, 0.0, 0.0 );\n", "\n", "\tfor( int y = -1; y <= 1; y++ )\n", "\t{\n", "\t for( int x = -1; x <= 1; x++ )\n", "\t {\n", "\t\t\tfloat2 lattice = float2( x, y );\n", "\t\t\tfloat2 offset = UnityVoronoiRandomVector( lattice + g, AngleOffset );\n", "\t\t\tfloat d = distance( lattice + offset, f );\n", "\n", "\t\t\tif( d < res.x )\n", "\t\t\t{\n", "\t\t\t\tmr = f - lattice - offset;\n", "\t\t\t\tres = float3( d, offset.x, offset.y );\n", "\t\t\t}\n", "\t }\n", "\t}\n", "\treturn res;\n", "}\n", }; //////////// private const string VoronoiHashHeader = "float2 voronoihash{0}( float2 p )"; private readonly string[] VoronoiHashBody = { "p = p - 2 * floor( p / 2 );", "p = float2( dot( p, float2( 127.1, 311.7 ) ), dot( p, float2( 269.5, 183.3 ) ) );", "return frac( sin( p ) *43758.5453);" }; private const string VoronoiHeader = "float voronoi{0}( float2 v, float time, inout float2 id, inout float2 mr, float smoothness, inout float2 smoothId )"; private const string VoronoiFunc = "voronoi{0}( {1}, {2}, {3}, {4}, {5}, {6} )"; private string[] VoronoiBody = { "float2 n = floor( v );", "float2 f = frac( v );", "float F1 = 8.0;", "float F2 = 8.0; float2 mg = 0;", "for ( int j = -1; j <= 1; j++ )", "{", " \tfor ( int i = -1; i <= 1; i++ )", " \t{", " \t\tfloat2 g = float2( i, j );", " \t\tfloat2 o = voronoihash{0}( n + g );", " \t\tfloat2 r = f - g - ( sin( 0 + o * 6.2831 ) * 0.5 + 0.5 );", " \t\tfloat d = dot( r, r );", " \t\tif( d { for( int i = 0; i < m_inputPorts.Count; i++ ) { if( m_inputPorts[ i ].ValidInternalData && !m_inputPorts[ i ].IsConnected && m_inputPorts[ i ].Visible && m_inputPorts[ i ].AutoDrawInternalData ) { m_inputPorts[ i ].ShowInternalData( this ); } } } ); } void ChangeFunction( string scale ) { VoronoiBody[ 10 ] = "\t\to = ( sin( time + o * 6.2831 ) * 0.5 + 0.5 ); float2 r = f - g - o;"; int q = m_searchQuality + 1; VoronoiBody[ 4 ] = "for ( int j = -" + q + "; j <= " + q + "; j++ )"; VoronoiBody[ 6 ] = "\tfor ( int i = -" + q + "; i <= " + q + "; i++ )"; int dFunction = m_distanceFunction; if( m_functionType == 4 ) dFunction = 0; switch( dFunction ) { default: case 0: VoronoiBody[ 11 ] = "\t\tfloat d = 0.5 * dot( r, r );"; break; case 1: VoronoiBody[ 11 ] = "\t\tfloat d = 0.707 * sqrt(dot( r, r ));"; break; case 2: VoronoiBody[ 11 ] = "\t\tfloat d = 0.5 * ( abs(r.x) + abs(r.y) );"; break; case 3: VoronoiBody[ 11 ] = "\t\tfloat d = max(abs(r.x), abs(r.y));"; break; case 4: VoronoiBody[ 11 ] = "\t\tfloat d = " + ( 1 / Mathf.Pow( 2, 1 / m_minkowskiPower ) ).ToString( "n3" ) + " * pow( ( pow( abs( r.x ), " + m_minkowskiPower + " ) + pow( abs( r.y ), " + m_minkowskiPower + " ) ), " + ( 1 / m_minkowskiPower ).ToString( "n3" ) + " );"; break; } if( m_functionType == 0 ) { if( m_calculateSmoothValue ) { VoronoiBody[ 12 ] = " //\t\tif( d 17402 ) { m_calculateSmoothValue = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); } if( UIUtils.CurrentShaderVersion() > 18902 ) { m_applySmoothToIds = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); } ChangePorts(); ChechSmoothPorts(); } public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) { base.WriteToString( ref nodeInfo, ref connectionsInfo ); IOUtils.AddFieldValueToString( ref nodeInfo, m_searchQuality ); IOUtils.AddFieldValueToString( ref nodeInfo, m_distanceFunction ); IOUtils.AddFieldValueToString( ref nodeInfo, m_minkowskiPower ); IOUtils.AddFieldValueToString( ref nodeInfo, m_functionType ); IOUtils.AddFieldValueToString( ref nodeInfo, m_octaves ); IOUtils.AddFieldValueToString( ref nodeInfo, m_tileable.ToString() ); IOUtils.AddFieldValueToString( ref nodeInfo, m_tileScale ); IOUtils.AddFieldValueToString( ref nodeInfo, m_useUnity ); IOUtils.AddFieldValueToString( ref nodeInfo, m_calculateSmoothValue ); IOUtils.AddFieldValueToString( ref nodeInfo , m_applySmoothToIds ); } } }