You've already forked FateViewer
Add project files.
This commit is contained in:
@@ -0,0 +1,445 @@
|
||||
// Amplify Shader Editor - Visual Shader Editing Tool
|
||||
// Copyright (c) Amplify Creations, Lda <info@amplify.pt>
|
||||
|
||||
//https://www.shadertoy.com/view/XdS3RW
|
||||
//http://www.deepskycolors.com/archivo/2010/04/21/formulas-for-Photoshop-blending-modes.html
|
||||
//http://www.pegtop.net/delphi/articles/blendmodes/softlight.htm
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
namespace AmplifyShaderEditor
|
||||
{
|
||||
public enum BlendOps
|
||||
{
|
||||
ColorBurn,
|
||||
ColorDodge,
|
||||
Darken,
|
||||
Divide,
|
||||
Difference,
|
||||
Exclusion,
|
||||
SoftLight,
|
||||
HardLight,
|
||||
HardMix,
|
||||
Lighten,
|
||||
LinearBurn,
|
||||
LinearDodge,
|
||||
LinearLight,
|
||||
Multiply,
|
||||
Overlay,
|
||||
PinLight,
|
||||
Subtract,
|
||||
Screen,
|
||||
VividLight
|
||||
}
|
||||
[Serializable]
|
||||
[NodeAttributes( "Blend Operations", "Image Effects", "Common layer blending modes" )]
|
||||
public class BlendOpsNode : ParentNode
|
||||
{
|
||||
//private const string ASEHardLightCall = "ASEHardLight({0},{1})";
|
||||
//private const string ASEHardLightFunc =
|
||||
//"inline float ASEHardLight( float srcLocalVar, float dstLocalVar ){" +
|
||||
//" return ( ( srcLocalVar > 0.5 ) ? ( 1.0 - ( 1.0 - 2.0 * ( srcLocalVar - 0.5 ) ) * ( 1.0 - dstLocalVar ) ) : ( 2.0 * srcLocalVar * dstLocalVar ) ); }";
|
||||
|
||||
//private const string ASELinearLightCall = "ASELinearLight({0},{1})";
|
||||
//private const string ASELinearLightFunc =
|
||||
//"inline float ASELinearLight( float srcLocalVar, float dstLocalVar ){" +
|
||||
//" return ( ( srcLocalVar > 0.5 ) ? ( dstLocalVar + 2.0 * srcLocalVar - 1.0 ) : ( dstLocalVar + 2.0 * ( srcLocalVar - 0.5 ) ) ); }";
|
||||
|
||||
//private const string ASEOverlayCall = "ASEOverlay({0},{1})";
|
||||
//private const string ASEOverlayFunc =
|
||||
//"inline float ASEOverlay( float srcLocalVar, float dstLocalVar ){" +
|
||||
//" return ( ( dstLocalVar > 0.5 ) ? ( 1.0 - ( 1.0 - 2.0 * ( dstLocalVar - 0.5 ) ) * ( 1.0 - srcLocalVar ) ) : ( 2.0 * dstLocalVar * srcLocalVar ) ); }";
|
||||
////" return (dstLocalVar < 0.5) ? 2.0 * srcLocalVar * dstLocalVar : 1.0 - 2.0 * (1.0 - srcLocalVar) * (1.0 - dstLocalVar); }";
|
||||
|
||||
//private const string ASEPinLightCall = "ASEPinLight({0},{1})";
|
||||
//private const string ASEPinLightFunc =
|
||||
//"inline float ASEPinLight( float srcLocalVar, float dstLocalVar ){" +
|
||||
//" return ( ( srcLocalVar > 0.5 ) ? max( dstLocalVar , 2.0 * ( srcLocalVar - 0.5 ) ) : min( dstLocalVar , 2.0 * srcLocalVar ) ); }";
|
||||
|
||||
//private const string ASEVividLightCall = "ASEVividLight({0},{1})";
|
||||
//private const string ASEVividLightFunc = "inline float ASEVividLight( float srcLocalVar, float dstLocalVar ){" +
|
||||
//" return ( ( srcLocalVar > 0.5 ) ? ( dstLocalVar / ( ( 1.0 - srcLocalVar ) * 2.0 ) ) : ( 1.0 - ( ( ( 1.0 - dstLocalVar ) * 0.5 ) / srcLocalVar ) ) ); }";
|
||||
|
||||
private const string ASEDarkerColorCall = "ASEDarkerColor{}({0},{1})";
|
||||
private const string ASEDarkerColorFunc = "inline float ASEDarkerColor{0}( float srcLocalVar, float dstLocalVar ){" +
|
||||
" return ({1} < {2}) ? s : d; }";
|
||||
|
||||
private const string ASELighterColorCall = "ASELighterColor{}({0},{1})";
|
||||
private const string ASELighterColorFunc = "inline float ASELighterColor{0}( float srcLocalVar, float dstLocalVar ){" +
|
||||
" return ({1} > {2}) ? s : d; }";
|
||||
|
||||
private const string BlendOpsModeStr = "Blend Op";
|
||||
private const string SaturateResultStr = "Saturate";
|
||||
|
||||
[SerializeField]
|
||||
private BlendOps m_currentBlendOp = BlendOps.ColorBurn;
|
||||
|
||||
[SerializeField]
|
||||
private WirePortDataType m_mainDataType = WirePortDataType.COLOR;
|
||||
|
||||
[SerializeField]
|
||||
private bool m_saturate = true;
|
||||
|
||||
private UpperLeftWidgetHelper m_upperLeftWidget = new UpperLeftWidgetHelper();
|
||||
|
||||
protected override void CommonInit( int uniqueId )
|
||||
{
|
||||
base.CommonInit( uniqueId );
|
||||
AddInputPort( WirePortDataType.COLOR, false, "Source" );
|
||||
AddInputPort( WirePortDataType.COLOR, false, "Destiny" );
|
||||
AddInputPort( WirePortDataType.FLOAT, false,"Alpha" );
|
||||
m_inputPorts[ 2 ].FloatInternalData = 1;
|
||||
AddOutputPort( WirePortDataType.COLOR, Constants.EmptyPortValue );
|
||||
m_inputPorts[ 0 ].AddPortForbiddenTypes( WirePortDataType.FLOAT3x3,
|
||||
WirePortDataType.FLOAT4x4,
|
||||
WirePortDataType.SAMPLER1D,
|
||||
WirePortDataType.SAMPLER2D,
|
||||
WirePortDataType.SAMPLER3D,
|
||||
WirePortDataType.SAMPLERCUBE,
|
||||
WirePortDataType.SAMPLER2DARRAY );
|
||||
m_inputPorts[ 1 ].AddPortForbiddenTypes( WirePortDataType.FLOAT3x3,
|
||||
WirePortDataType.FLOAT4x4,
|
||||
WirePortDataType.SAMPLER1D,
|
||||
WirePortDataType.SAMPLER2D,
|
||||
WirePortDataType.SAMPLER3D,
|
||||
WirePortDataType.SAMPLERCUBE,
|
||||
WirePortDataType.SAMPLER2DARRAY );
|
||||
m_textLabelWidth = 75;
|
||||
m_autoWrapProperties = true;
|
||||
m_hasLeftDropdown = true;
|
||||
SetAdditonalTitleText( string.Format( Constants.SubTitleTypeFormatStr, m_currentBlendOp ) );
|
||||
m_useInternalPortData = true;
|
||||
m_previewShaderGUID = "6d6b3518705b3ba49acdc6e18e480257";
|
||||
}
|
||||
|
||||
public override void SetPreviewInputs()
|
||||
{
|
||||
base.SetPreviewInputs();
|
||||
|
||||
m_previewMaterialPassId = (int)m_currentBlendOp;
|
||||
PreviewMaterial.SetInt( "_Sat", m_saturate ? 1 : 0 );
|
||||
int lerpMode = ( m_inputPorts[ 2 ].IsConnected || m_inputPorts[ 2 ].FloatInternalData < 1 ) ? 1 : 0;
|
||||
PreviewMaterial.SetInt( "_Lerp", lerpMode );
|
||||
}
|
||||
|
||||
public override void AfterCommonInit()
|
||||
{
|
||||
base.AfterCommonInit();
|
||||
|
||||
if( PaddingTitleLeft == 0 )
|
||||
{
|
||||
PaddingTitleLeft = Constants.PropertyPickerWidth + Constants.IconsLeftRightMargin;
|
||||
if( PaddingTitleRight == 0 )
|
||||
PaddingTitleRight = Constants.PropertyPickerWidth + Constants.IconsLeftRightMargin;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true )
|
||||
{
|
||||
base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode );
|
||||
UpdateConnection( portId );
|
||||
}
|
||||
|
||||
public override void OnConnectedOutputNodeChanges( int inputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type )
|
||||
{
|
||||
base.OnConnectedOutputNodeChanges( inputPortId, otherNodeId, otherPortId, name, type );
|
||||
UpdateConnection( inputPortId );
|
||||
}
|
||||
|
||||
public override void OnInputPortDisconnected( int portId )
|
||||
{
|
||||
base.OnInputPortDisconnected( portId );
|
||||
UpdateDisconnection( portId );
|
||||
}
|
||||
|
||||
void UpdateConnection( int portId )
|
||||
{
|
||||
if( portId == 2 )
|
||||
return;
|
||||
|
||||
m_inputPorts[ portId ].MatchPortToConnection();
|
||||
int otherPortId = ( portId + 1 ) % 2;
|
||||
if( m_inputPorts[ otherPortId ].IsConnected )
|
||||
{
|
||||
m_mainDataType = UIUtils.GetPriority( m_inputPorts[ 0 ].DataType ) > UIUtils.GetPriority( m_inputPorts[ 1 ].DataType ) ? m_inputPorts[ 0 ].DataType : m_inputPorts[ 1 ].DataType;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mainDataType = m_inputPorts[ portId ].DataType;
|
||||
m_inputPorts[ otherPortId ].ChangeType( m_mainDataType, false );
|
||||
}
|
||||
m_outputPorts[ 0 ].ChangeType( m_mainDataType, false );
|
||||
}
|
||||
|
||||
void UpdateDisconnection( int portId )
|
||||
{
|
||||
if( portId == 2 )
|
||||
return;
|
||||
|
||||
int otherPortId = ( portId + 1 ) % 2;
|
||||
if( m_inputPorts[ otherPortId ].IsConnected )
|
||||
{
|
||||
m_mainDataType = m_inputPorts[ otherPortId ].DataType;
|
||||
m_inputPorts[ portId ].ChangeType( m_mainDataType, false );
|
||||
m_outputPorts[ 0 ].ChangeType( m_mainDataType, false );
|
||||
}
|
||||
}
|
||||
|
||||
public override void DrawProperties()
|
||||
{
|
||||
base.DrawProperties();
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_currentBlendOp = (BlendOps)EditorGUILayoutEnumPopup( BlendOpsModeStr, m_currentBlendOp );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
{
|
||||
SetAdditonalTitleText( string.Format( Constants.SubTitleTypeFormatStr, m_currentBlendOp ) );
|
||||
}
|
||||
m_saturate = EditorGUILayoutToggle( SaturateResultStr, m_saturate );
|
||||
}
|
||||
|
||||
public override void Draw( DrawInfo drawInfo )
|
||||
{
|
||||
base.Draw( drawInfo );
|
||||
m_upperLeftWidget.DrawWidget<BlendOps>( ref m_currentBlendOp, this, OnWidgetUpdate );
|
||||
}
|
||||
|
||||
private readonly Action<ParentNode> OnWidgetUpdate = ( x ) =>
|
||||
{
|
||||
x.SetAdditonalTitleText( string.Format( Constants.SubTitleTypeFormatStr, ( x as BlendOpsNode ).m_currentBlendOp ) );
|
||||
};
|
||||
|
||||
private string CreateMultiChannel( ref MasterNodeDataCollector dataCollector, string function, string srcLocalVar, string dstLocalVar, string varName )
|
||||
{
|
||||
switch( m_outputPorts[ 0 ].DataType )
|
||||
{
|
||||
default:
|
||||
{
|
||||
return string.Format( function, srcLocalVar, dstLocalVar );
|
||||
}
|
||||
case WirePortDataType.FLOAT2:
|
||||
{
|
||||
string xChannelName = varName + OutputId + "X";
|
||||
string xChannelValue = string.Format( function, srcLocalVar + ".x", dstLocalVar + ".x" );
|
||||
dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT, xChannelName, xChannelValue );
|
||||
|
||||
string yChannelName = varName + OutputId + "Y";
|
||||
string yChannelValue = string.Format( function, srcLocalVar + ".y", dstLocalVar + ".y" );
|
||||
dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT, yChannelName, yChannelValue );
|
||||
|
||||
return string.Format( "float2({0},{1})", xChannelName, yChannelName );
|
||||
}
|
||||
case WirePortDataType.FLOAT3:
|
||||
{
|
||||
string xChannelName = varName + OutputId + "X";
|
||||
string xChannelValue = string.Format( function, srcLocalVar + ".x", dstLocalVar + ".x" );
|
||||
dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT, xChannelName, xChannelValue );
|
||||
|
||||
string yChannelName = varName + OutputId + "Y";
|
||||
string yChannelValue = string.Format( function, srcLocalVar + ".y", dstLocalVar + ".y" );
|
||||
dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT, yChannelName, yChannelValue );
|
||||
|
||||
string zChannelName = varName + OutputId + "Z";
|
||||
string zChannelValue = string.Format( function, srcLocalVar + ".z", dstLocalVar + ".z" );
|
||||
dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT, zChannelName, zChannelValue );
|
||||
|
||||
return string.Format( "float3({0},{1},{2})", xChannelName, yChannelName, zChannelName );
|
||||
}
|
||||
case WirePortDataType.FLOAT4:
|
||||
case WirePortDataType.COLOR:
|
||||
{
|
||||
string xChannelName = varName + OutputId + "X";
|
||||
string xChannelValue = string.Format( function, srcLocalVar + ".x", dstLocalVar + ".x" );
|
||||
dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT, xChannelName, xChannelValue );
|
||||
|
||||
string yChannelName = varName + OutputId + "Y";
|
||||
string yChannelValue = string.Format( function, srcLocalVar + ".y", dstLocalVar + ".y" );
|
||||
dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT, yChannelName, yChannelValue );
|
||||
|
||||
string zChannelName = varName + OutputId + "Z";
|
||||
string zChannelValue = string.Format( function, srcLocalVar + ".z", dstLocalVar + ".z" );
|
||||
dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT, zChannelName, zChannelValue );
|
||||
|
||||
string wChannelName = varName + OutputId + "W";
|
||||
string wChannelValue = string.Format( function, srcLocalVar + ".w", dstLocalVar + ".w" );
|
||||
dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT, wChannelName, wChannelValue );
|
||||
|
||||
return string.Format( "float4({0},{1},{2},{3})", xChannelName, yChannelName, zChannelName, wChannelName );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
|
||||
{
|
||||
if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) )
|
||||
return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
|
||||
|
||||
string src = m_inputPorts[ 0 ].GenerateShaderForOutput( ref dataCollector, m_mainDataType, false, true );
|
||||
string dst = m_inputPorts[ 1 ].GenerateShaderForOutput( ref dataCollector, m_mainDataType, false, true );
|
||||
|
||||
string srcLocalVar = "blendOpSrc" + OutputId;
|
||||
string dstLocalVar = "blendOpDest" + OutputId;
|
||||
dataCollector.AddLocalVariable( UniqueId, UIUtils.PrecisionWirePortToCgType( CurrentPrecisionType, m_mainDataType ) + " " + srcLocalVar, src + ";" );
|
||||
dataCollector.AddLocalVariable( UniqueId, UIUtils.PrecisionWirePortToCgType( CurrentPrecisionType, m_mainDataType ) + " " + dstLocalVar, dst + ";" );
|
||||
|
||||
int currIndent = UIUtils.ShaderIndentLevel;
|
||||
if( dataCollector.MasterNodeCategory == AvailableShaderTypes.Template )
|
||||
{
|
||||
UIUtils.ShaderIndentLevel = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
UIUtils.ShaderIndentLevel = 1;
|
||||
UIUtils.ShaderIndentLevel++;
|
||||
}
|
||||
|
||||
string result = string.Empty;
|
||||
switch( m_currentBlendOp )
|
||||
{
|
||||
case BlendOps.ColorBurn:
|
||||
{
|
||||
result = string.Format( "( 1.0 - ( ( 1.0 - {0}) / max( {1}, 0.00001) ) )", dstLocalVar, srcLocalVar);
|
||||
}
|
||||
break;
|
||||
case BlendOps.ColorDodge:
|
||||
{
|
||||
result = string.Format( "( {0}/ max( 1.0 - {1}, 0.00001 ) )", dstLocalVar, srcLocalVar );
|
||||
}
|
||||
break;
|
||||
case BlendOps.Darken:
|
||||
{
|
||||
result = "min( " + srcLocalVar + " , " + dstLocalVar + " )";
|
||||
}
|
||||
break;
|
||||
case BlendOps.Divide:
|
||||
{
|
||||
result = string.Format( "( {0} / max({1},0.00001) )", dstLocalVar, srcLocalVar );
|
||||
}
|
||||
break;
|
||||
case BlendOps.Difference:
|
||||
{
|
||||
result = "abs( " + srcLocalVar + " - " + dstLocalVar + " )";
|
||||
}
|
||||
break;
|
||||
case BlendOps.Exclusion:
|
||||
{
|
||||
result = "( 0.5 - 2.0 * ( " + srcLocalVar + " - 0.5 ) * ( " + dstLocalVar + " - 0.5 ) )";
|
||||
}
|
||||
break;
|
||||
case BlendOps.SoftLight:
|
||||
{
|
||||
result = string.Format( "2.0f*{0}*{1} + {0}*{0}*(1.0f - 2.0f*{1})", dstLocalVar, srcLocalVar );
|
||||
}
|
||||
break;
|
||||
case BlendOps.HardLight:
|
||||
{
|
||||
result = " (( " + srcLocalVar + " > 0.5 ) ? ( 1.0 - ( 1.0 - 2.0 * ( " + srcLocalVar + " - 0.5 ) ) * ( 1.0 - " + dstLocalVar + " ) ) : ( 2.0 * " + srcLocalVar + " * " + dstLocalVar + " ) )";
|
||||
//dataCollector.AddFunction( ASEHardLightCall, UIUtils.ShaderIndentTabs + ASEHardLightFunc );
|
||||
//result = CreateMultiChannel( ref dataCollector, ASEHardLightCall, srcLocalVar, dstLocalVar, "hardLightBlend" );
|
||||
}
|
||||
break;
|
||||
case BlendOps.HardMix:
|
||||
{
|
||||
result = " round( 0.5 * ( " + srcLocalVar + " + " + dstLocalVar + " ) )";
|
||||
}
|
||||
break;
|
||||
case BlendOps.Lighten:
|
||||
{
|
||||
result = " max( " + srcLocalVar + ", " + dstLocalVar + " )";
|
||||
}
|
||||
break;
|
||||
case BlendOps.LinearBurn:
|
||||
{
|
||||
result = "( " + srcLocalVar + " + " + dstLocalVar + " - 1.0 )";
|
||||
}
|
||||
break;
|
||||
case BlendOps.LinearDodge:
|
||||
{
|
||||
result = "( " + srcLocalVar + " + " + dstLocalVar + " )";
|
||||
}
|
||||
break;
|
||||
case BlendOps.LinearLight:
|
||||
{
|
||||
result = "(( " + srcLocalVar + " > 0.5 )? ( " + dstLocalVar + " + 2.0 * " + srcLocalVar + " - 1.0 ) : ( " + dstLocalVar + " + 2.0 * ( " + srcLocalVar + " - 0.5 ) ) )";
|
||||
//dataCollector.AddFunction( ASELinearLightCall, UIUtils.ShaderIndentTabs + ASELinearLightFunc );
|
||||
//result = CreateMultiChannel( ref dataCollector, ASELinearLightCall, srcLocalVar, dstLocalVar, "linearLightBlend" );
|
||||
}
|
||||
break;
|
||||
case BlendOps.Multiply:
|
||||
{
|
||||
result = "( " + srcLocalVar + " * " + dstLocalVar + " )";
|
||||
}
|
||||
break;
|
||||
case BlendOps.Overlay:
|
||||
{
|
||||
//result = "(( " + dstLocalVar + " > 0.5 ) ? ( 1.0 - ( 1.0 - 2.0 * ( " + dstLocalVar + " - 0.5 ) ) * ( 1.0 - " + srcLocalVar + " ) ) : ( 2.0 * " + dstLocalVar + " * " + srcLocalVar + " ) )";
|
||||
result = "(( " + dstLocalVar + " > 0.5 ) ? ( 1.0 - 2.0 * ( 1.0 - " + dstLocalVar + " ) * ( 1.0 - " + srcLocalVar + " ) ) : ( 2.0 * " + dstLocalVar + " * " + srcLocalVar + " ) )";
|
||||
//dataCollector.AddFunction( ASEOverlayCall, UIUtils.ShaderIndentTabs + ASEOverlayFunc );
|
||||
//result = CreateMultiChannel( ref dataCollector, ASEOverlayCall, srcLocalVar, dstLocalVar, "overlayBlend" );
|
||||
}
|
||||
break;
|
||||
case BlendOps.PinLight:
|
||||
{
|
||||
result = "(( " + srcLocalVar + " > 0.5 ) ? max( " + dstLocalVar + ", 2.0 * ( " + srcLocalVar + " - 0.5 ) ) : min( " + dstLocalVar + ", 2.0 * " + srcLocalVar + " ) )";
|
||||
//dataCollector.AddFunction( ASEPinLightCall, UIUtils.ShaderIndentTabs + ASEPinLightFunc );
|
||||
//result = CreateMultiChannel( ref dataCollector, ASEPinLightCall, srcLocalVar, dstLocalVar, "pinLightBlend" );
|
||||
}
|
||||
break;
|
||||
case BlendOps.Subtract:
|
||||
{
|
||||
result = "( " + dstLocalVar + " - " + srcLocalVar + " )";
|
||||
}
|
||||
break;
|
||||
case BlendOps.Screen:
|
||||
{
|
||||
result = "( 1.0 - ( 1.0 - " + srcLocalVar + " ) * ( 1.0 - " + dstLocalVar + " ) )";
|
||||
}
|
||||
break;
|
||||
case BlendOps.VividLight:
|
||||
{
|
||||
result = string.Format( "(( {0} > 0.5 ) ? ( {1} / max( ( 1.0 - {0} ) * 2.0 ,0.00001) ) : ( 1.0 - ( ( ( 1.0 - {1} ) * 0.5 ) / max( {0},0.00001) ) ) )", srcLocalVar, dstLocalVar);
|
||||
//dataCollector.AddFunction( ASEVividLightCall, UIUtils.ShaderIndentTabs + ASEVividLightFunc );
|
||||
//result = CreateMultiChannel( ref dataCollector, ASEVividLightCall, srcLocalVar, dstLocalVar, "vividLightBlend" );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
UIUtils.ShaderIndentLevel = currIndent;
|
||||
if( m_inputPorts[ 2 ].IsConnected || m_inputPorts[ 2 ].FloatInternalData < 1.0 )
|
||||
{
|
||||
string opacity = m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector );
|
||||
string lerpVar = "lerpBlendMode" + OutputId;
|
||||
string lerpResult = string.Format( "lerp({0},{1},{2})", dstLocalVar, result, opacity );
|
||||
dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, m_outputPorts[ 0 ].DataType, lerpVar, lerpResult );
|
||||
result = lerpVar;
|
||||
}
|
||||
|
||||
if( m_saturate )
|
||||
result = "( saturate( " + result + " ))";
|
||||
|
||||
return CreateOutputLocalVariable( 0, result, ref dataCollector );
|
||||
}
|
||||
|
||||
public override void WriteToString( ref string nodeInfo, ref string connectionsInfo )
|
||||
{
|
||||
base.WriteToString( ref nodeInfo, ref connectionsInfo );
|
||||
IOUtils.AddFieldValueToString( ref nodeInfo, m_currentBlendOp );
|
||||
IOUtils.AddFieldValueToString( ref nodeInfo, m_saturate );
|
||||
}
|
||||
|
||||
public override void ReadFromString( ref string[] nodeParams )
|
||||
{
|
||||
base.ReadFromString( ref nodeParams );
|
||||
m_currentBlendOp = (BlendOps)Enum.Parse( typeof( BlendOps ), GetCurrentParam( ref nodeParams ) );
|
||||
m_saturate = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
|
||||
SetAdditonalTitleText( string.Format( Constants.SubTitleTypeFormatStr, m_currentBlendOp ) );
|
||||
}
|
||||
|
||||
public override void Destroy()
|
||||
{
|
||||
base.Destroy();
|
||||
m_upperLeftWidget = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09fb0867c2a616c488bad8929f4f7ad7
|
||||
timeCreated: 1481126953
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,57 @@
|
||||
// Amplify Shader Editor - Visual Shader Editing Tool
|
||||
// Copyright (c) Amplify Creations, Lda <info@amplify.pt>
|
||||
|
||||
// http://stackoverflow.com/questions/9320953/what-algorithm-does-photoshop-use-to-desaturate-an-image
|
||||
// https://www.shadertoy.com/view/lsdXDH
|
||||
|
||||
namespace AmplifyShaderEditor
|
||||
{
|
||||
[System.Serializable]
|
||||
[NodeAttributes( "Desaturate", "Image Effects", "Generic desaturation operation" )]
|
||||
public sealed class DesaturateOpNode : ParentNode
|
||||
{
|
||||
private const string GenericDesaturateOp0 = "dot( {0}, float3( 0.299, 0.587, 0.114 ))";
|
||||
private const string GenericDesaturateOp1 = "lerp( {0}, {1}.xxx, {2} )";
|
||||
//private const string GenericDesaturateOp = "lerp( {0},dot({0},float3(0.299,0.587,0.114)).xxx,{1})";
|
||||
|
||||
protected override void CommonInit( int uniqueId )
|
||||
{
|
||||
base.CommonInit( uniqueId );
|
||||
AddInputPort( WirePortDataType.FLOAT3, false, "RGB" );
|
||||
AddInputPort( WirePortDataType.FLOAT, false, "Fraction" );
|
||||
AddOutputPort( WirePortDataType.FLOAT3, Constants.EmptyPortValue );
|
||||
m_useInternalPortData = true;
|
||||
m_previewShaderGUID = "faabe9efdf44b9648a523f1742abdfd3";
|
||||
}
|
||||
|
||||
void UpdatePorts( int portId )
|
||||
{
|
||||
if ( portId == 0 )
|
||||
{
|
||||
m_inputPorts[ 0 ].MatchPortToConnection();
|
||||
m_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, false );
|
||||
}
|
||||
}
|
||||
|
||||
public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
|
||||
{
|
||||
|
||||
if ( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) )
|
||||
return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
|
||||
|
||||
string initalColorValue = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
|
||||
string fraction = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector );
|
||||
|
||||
string initialColorVarName = "desaturateInitialColor" + OutputId;
|
||||
dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT3, initialColorVarName, initalColorValue );
|
||||
|
||||
string dotVarName = "desaturateDot" + OutputId;
|
||||
string dotVarValue = string.Format( GenericDesaturateOp0, initialColorVarName );
|
||||
|
||||
dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT, dotVarName, dotVarValue );
|
||||
RegisterLocalVariable( 0, string.Format( GenericDesaturateOp1, initialColorVarName, dotVarName,fraction ), ref dataCollector, "desaturateVar" + OutputId );
|
||||
|
||||
return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eddae0a124877fc47b28ae8853286174
|
||||
timeCreated: 1489414268
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
|
||||
namespace AmplifyShaderEditor
|
||||
{
|
||||
[Serializable]
|
||||
[NodeAttributes( "HSV to RGB", "Image Effects", "Converts from HSV to RGB color space" )]
|
||||
public sealed class HSVToRGBNode : ParentNode
|
||||
{
|
||||
public static readonly string HSVToRGBHeader = "HSVToRGB( {0}3({1},{2},{3}) )";
|
||||
public static readonly string[] HSVToRGBFunction = { "{0}3 HSVToRGB( {0}3 c )\n",
|
||||
"{\n",
|
||||
"\t{0}4 K = {0}4( 1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0 );\n",
|
||||
"\t{0}3 p = abs( frac( c.xxx + K.xyz ) * 6.0 - K.www );\n",
|
||||
"\treturn c.z * lerp( K.xxx, saturate( p - K.xxx ), c.y );\n",
|
||||
"}\n"};
|
||||
public static readonly bool[] HSVToRGBFlags = { true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false};
|
||||
|
||||
protected override void CommonInit( int uniqueId )
|
||||
{
|
||||
base.CommonInit( uniqueId );
|
||||
AddInputPort( WirePortDataType.FLOAT, false, "Hue" );
|
||||
AddInputPort( WirePortDataType.FLOAT, false, "Saturation" );
|
||||
AddInputPort( WirePortDataType.FLOAT, false, "Value" );
|
||||
AddOutputColorPorts( "RGB", false );
|
||||
m_previewShaderGUID = "fab445eb945d63047822a7a6b81b959d";
|
||||
m_useInternalPortData = true;
|
||||
m_autoWrapProperties = true;
|
||||
m_customPrecision = true;
|
||||
}
|
||||
|
||||
public override void DrawProperties()
|
||||
{
|
||||
base.DrawProperties();
|
||||
DrawPrecisionProperty();
|
||||
}
|
||||
|
||||
public static void AddHSVToRGBFunction( ref MasterNodeDataCollector dataCollector , string precisionString )
|
||||
{
|
||||
if( !dataCollector.HasFunction( HSVToRGBHeader ) )
|
||||
{
|
||||
//Hack to be used util indent is properly used
|
||||
int currIndent = UIUtils.ShaderIndentLevel;
|
||||
if( dataCollector.MasterNodeCategory == AvailableShaderTypes.Template )
|
||||
{
|
||||
UIUtils.ShaderIndentLevel = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
UIUtils.ShaderIndentLevel = 1;
|
||||
UIUtils.ShaderIndentLevel++;
|
||||
}
|
||||
|
||||
string finalFunction = string.Empty;
|
||||
for( int i = 0; i < HSVToRGBFunction.Length; i++ )
|
||||
{
|
||||
finalFunction += UIUtils.ShaderIndentTabs + ( HSVToRGBFlags[ i ] ? string.Format( HSVToRGBFunction[ i ], precisionString ) : HSVToRGBFunction[ i ] );
|
||||
}
|
||||
|
||||
UIUtils.ShaderIndentLevel = currIndent;
|
||||
|
||||
dataCollector.AddFunction( HSVToRGBHeader, finalFunction );
|
||||
}
|
||||
}
|
||||
|
||||
public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
|
||||
{
|
||||
if ( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) )
|
||||
return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) );
|
||||
|
||||
string precisionString = UIUtils.PrecisionWirePortToCgType( CurrentPrecisionType, WirePortDataType.FLOAT );
|
||||
|
||||
AddHSVToRGBFunction( ref dataCollector , precisionString );
|
||||
|
||||
string hue = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
|
||||
string saturation = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector );
|
||||
string value = m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector );
|
||||
|
||||
RegisterLocalVariable( 0, string.Format( HSVToRGBHeader, precisionString, hue, saturation, value ), ref dataCollector, "hsvTorgb" + OutputId );
|
||||
return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d992a68cff329a4a9bd1deb999fe691
|
||||
timeCreated: 1494857111
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
// Amplify Shader Editor - Visual Shader Editing Tool
|
||||
// Copyright (c) Amplify Creations, Lda <info@amplify.pt>
|
||||
|
||||
using System;
|
||||
|
||||
namespace AmplifyShaderEditor
|
||||
{
|
||||
[Serializable]
|
||||
[NodeAttributes( "Luminance", "Image Effects", "Calculates Luminance value from input")]
|
||||
public sealed class LuminanceNode : ParentNode
|
||||
{
|
||||
protected override void CommonInit( int uniqueId )
|
||||
{
|
||||
base.CommonInit( uniqueId );
|
||||
AddInputPort( WirePortDataType.FLOAT3, false, "RGB" );
|
||||
AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue );
|
||||
m_previewShaderGUID = "81e1d8ffeec8a4b4cabb1094bc981048";
|
||||
}
|
||||
|
||||
public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
|
||||
{
|
||||
if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) )
|
||||
return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
|
||||
|
||||
string value = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
|
||||
string grayscale = "Luminance(" + value + ")";
|
||||
|
||||
RegisterLocalVariable( 0, grayscale, ref dataCollector, "luminance" + OutputId );
|
||||
return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5f40d01acf184946b8660599f33109f
|
||||
timeCreated: 1574935849
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,466 @@
|
||||
// Amplify Shader Editor - Visual Shader Editing Tool
|
||||
// Copyright (c) Amplify Creations, Lda <info@amplify.pt>
|
||||
// Based on the work by https://github.com/keijiro/NoiseShader
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AmplifyShaderEditor
|
||||
{
|
||||
public enum NoiseGeneratorType
|
||||
{
|
||||
Simplex2D,
|
||||
Simplex3D,
|
||||
Gradient,
|
||||
Simple
|
||||
};
|
||||
|
||||
[Serializable]
|
||||
[NodeAttributes( "Noise Generator", "Miscellaneous", "Collection of procedural noise generators", tags: "simplex gradient" )]
|
||||
public sealed class NoiseGeneratorNode : ParentNode
|
||||
{
|
||||
private const string TypeLabelStr = "Type";
|
||||
private const string SetTo01RangeOpStr = "{0} = {0}*0.5 + 0.5;";
|
||||
private const string SetToMinus1To1RangeOpStr = "{0} = {0}*2 - 1;";
|
||||
private const string SetTo01RangeLabel = "0-1 Range";
|
||||
private const string SetTo01RangePreviewId = "_To01Range";
|
||||
private const string UseUnityVersionLabel = "Use Unity Version";
|
||||
|
||||
// Simple
|
||||
private const string SimpleNoiseRandomValueFunc = "inline float noise_randomValue (float2 uv) { return frac(sin(dot(uv, float2(12.9898, 78.233)))*43758.5453); }";
|
||||
private const string SimpleNoiseInterpolateFunc = "inline float noise_interpolate (float a, float b, float t) { return (1.0-t)*a + (t*b); }";
|
||||
private const string SimpleValueNoiseHeader = "inline float valueNoise (float2 uv)";
|
||||
private readonly string[] SimpleValueNoiseBody = { "inline float valueNoise (float2 uv)\n",
|
||||
"{\n",
|
||||
"\tfloat2 i = floor(uv);\n",
|
||||
"\tfloat2 f = frac( uv );\n",
|
||||
"\tf = f* f * (3.0 - 2.0 * f);\n",
|
||||
"\tuv = abs( frac(uv) - 0.5);\n",
|
||||
"\tfloat2 c0 = i + float2( 0.0, 0.0 );\n",
|
||||
"\tfloat2 c1 = i + float2( 1.0, 0.0 );\n",
|
||||
"\tfloat2 c2 = i + float2( 0.0, 1.0 );\n",
|
||||
"\tfloat2 c3 = i + float2( 1.0, 1.0 );\n",
|
||||
"\tfloat r0 = noise_randomValue( c0 );\n",
|
||||
"\tfloat r1 = noise_randomValue( c1 );\n",
|
||||
"\tfloat r2 = noise_randomValue( c2 );\n",
|
||||
"\tfloat r3 = noise_randomValue( c3 );\n",
|
||||
"\tfloat bottomOfGrid = noise_interpolate( r0, r1, f.x );\n",
|
||||
"\tfloat topOfGrid = noise_interpolate( r2, r3, f.x );\n",
|
||||
"\tfloat t = noise_interpolate( bottomOfGrid, topOfGrid, f.y );\n",
|
||||
"\treturn t;\n",
|
||||
"}\n"};
|
||||
|
||||
private const string SimpleNoiseHeader = "float SimpleNoise(float2 UV, float Scale)";
|
||||
private const string SimpleNoiseFunc = "SimpleNoise( {0} )";
|
||||
private readonly string[] SimpleNoiseBody = { "float SimpleNoise(float2 UV)\n",
|
||||
"{\n",
|
||||
"\tfloat t = 0.0;\n",
|
||||
"\tfloat freq = pow( 2.0, float( 0 ) );\n",
|
||||
"\tfloat amp = pow( 0.5, float( 3 - 0 ) );\n",
|
||||
"\tt += valueNoise( UV/freq )*amp;\n",
|
||||
"\tfreq = pow(2.0, float(1));\n",
|
||||
"\tamp = pow(0.5, float(3-1));\n",
|
||||
"\tt += valueNoise( UV/freq )*amp;\n",
|
||||
"\tfreq = pow(2.0, float(2));\n",
|
||||
"\tamp = pow(0.5, float(3-2));\n",
|
||||
"\tt += valueNoise( UV/freq )*amp;\n",
|
||||
"\treturn t;\n",
|
||||
"}\n"};
|
||||
|
||||
// Simplex 2D
|
||||
private const string Simplex2DFloat3Mod289Func = "float3 mod2D289( float3 x ) { return x - floor( x * ( 1.0 / 289.0 ) ) * 289.0; }";
|
||||
private const string Simplex2DFloat2Mod289Func = "float2 mod2D289( float2 x ) { return x - floor( x * ( 1.0 / 289.0 ) ) * 289.0; }";
|
||||
private const string Simplex2DPermuteFunc = "float3 permute( float3 x ) { return mod2D289( ( ( x * 34.0 ) + 1.0 ) * x ); }";
|
||||
|
||||
private const string SimplexNoise2DHeader = "float snoise( float2 v )";
|
||||
private const string SimplexNoise2DFunc = "snoise( {0} )";
|
||||
private readonly string[] SimplexNoise2DBody = {"float snoise( float2 v )\n",
|
||||
"{\n",
|
||||
"\tconst float4 C = float4( 0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439 );\n",
|
||||
"\tfloat2 i = floor( v + dot( v, C.yy ) );\n",
|
||||
"\tfloat2 x0 = v - i + dot( i, C.xx );\n",
|
||||
"\tfloat2 i1;\n",
|
||||
"\ti1 = ( x0.x > x0.y ) ? float2( 1.0, 0.0 ) : float2( 0.0, 1.0 );\n",
|
||||
"\tfloat4 x12 = x0.xyxy + C.xxzz;\n",
|
||||
"\tx12.xy -= i1;\n",
|
||||
"\ti = mod2D289( i );\n",
|
||||
"\tfloat3 p = permute( permute( i.y + float3( 0.0, i1.y, 1.0 ) ) + i.x + float3( 0.0, i1.x, 1.0 ) );\n",
|
||||
"\tfloat3 m = max( 0.5 - float3( dot( x0, x0 ), dot( x12.xy, x12.xy ), dot( x12.zw, x12.zw ) ), 0.0 );\n",
|
||||
"\tm = m * m;\n",
|
||||
"\tm = m * m;\n",
|
||||
"\tfloat3 x = 2.0 * frac( p * C.www ) - 1.0;\n",
|
||||
"\tfloat3 h = abs( x ) - 0.5;\n",
|
||||
"\tfloat3 ox = floor( x + 0.5 );\n",
|
||||
"\tfloat3 a0 = x - ox;\n",
|
||||
"\tm *= 1.79284291400159 - 0.85373472095314 * ( a0 * a0 + h * h );\n",
|
||||
"\tfloat3 g;\n",
|
||||
"\tg.x = a0.x * x0.x + h.x * x0.y;\n",
|
||||
"\tg.yz = a0.yz * x12.xz + h.yz * x12.yw;\n",
|
||||
"\treturn 130.0 * dot( m, g );\n",
|
||||
"}\n"};
|
||||
// Simplex 3D
|
||||
|
||||
|
||||
|
||||
private const string Simplex3DFloat3Mod289 = "float3 mod3D289( float3 x ) { return x - floor( x / 289.0 ) * 289.0; }";
|
||||
private const string Simplex3DFloat4Mod289 = "float4 mod3D289( float4 x ) { return x - floor( x / 289.0 ) * 289.0; }";
|
||||
private const string Simplex3DFloat4Permute = "float4 permute( float4 x ) { return mod3D289( ( x * 34.0 + 1.0 ) * x ); }";
|
||||
private const string TaylorInvSqrtFunc = "float4 taylorInvSqrt( float4 r ) { return 1.79284291400159 - r * 0.85373472095314; }";
|
||||
|
||||
private const string SimplexNoise3DHeader = "float snoise( float3 v )";
|
||||
private const string SimplexNoise3DFunc = "snoise( {0} )";
|
||||
private readonly string[] SimplexNoise3DBody =
|
||||
{
|
||||
"float snoise( float3 v )\n",
|
||||
"{\n",
|
||||
"\tconst float2 C = float2( 1.0 / 6.0, 1.0 / 3.0 );\n",
|
||||
"\tfloat3 i = floor( v + dot( v, C.yyy ) );\n",
|
||||
"\tfloat3 x0 = v - i + dot( i, C.xxx );\n",
|
||||
"\tfloat3 g = step( x0.yzx, x0.xyz );\n",
|
||||
"\tfloat3 l = 1.0 - g;\n",
|
||||
"\tfloat3 i1 = min( g.xyz, l.zxy );\n",
|
||||
"\tfloat3 i2 = max( g.xyz, l.zxy );\n",
|
||||
"\tfloat3 x1 = x0 - i1 + C.xxx;\n",
|
||||
"\tfloat3 x2 = x0 - i2 + C.yyy;\n",
|
||||
"\tfloat3 x3 = x0 - 0.5;\n",
|
||||
"\ti = mod3D289( i);\n",
|
||||
"\tfloat4 p = permute( permute( permute( i.z + float4( 0.0, i1.z, i2.z, 1.0 ) ) + i.y + float4( 0.0, i1.y, i2.y, 1.0 ) ) + i.x + float4( 0.0, i1.x, i2.x, 1.0 ) );\n",
|
||||
"\tfloat4 j = p - 49.0 * floor( p / 49.0 ); // mod(p,7*7)\n",
|
||||
"\tfloat4 x_ = floor( j / 7.0 );\n",
|
||||
"\tfloat4 y_ = floor( j - 7.0 * x_ ); // mod(j,N)\n",
|
||||
"\tfloat4 x = ( x_ * 2.0 + 0.5 ) / 7.0 - 1.0;\n",
|
||||
"\tfloat4 y = ( y_ * 2.0 + 0.5 ) / 7.0 - 1.0;\n",
|
||||
"\tfloat4 h = 1.0 - abs( x ) - abs( y );\n",
|
||||
"\tfloat4 b0 = float4( x.xy, y.xy );\n",
|
||||
"\tfloat4 b1 = float4( x.zw, y.zw );\n",
|
||||
"\tfloat4 s0 = floor( b0 ) * 2.0 + 1.0;\n",
|
||||
"\tfloat4 s1 = floor( b1 ) * 2.0 + 1.0;\n",
|
||||
"\tfloat4 sh = -step( h, 0.0 );\n",
|
||||
"\tfloat4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;\n",
|
||||
"\tfloat4 a1 = b1.xzyw + s1.xzyw * sh.zzww;\n",
|
||||
"\tfloat3 g0 = float3( a0.xy, h.x );\n",
|
||||
"\tfloat3 g1 = float3( a0.zw, h.y );\n",
|
||||
"\tfloat3 g2 = float3( a1.xy, h.z );\n",
|
||||
"\tfloat3 g3 = float3( a1.zw, h.w );\n",
|
||||
"\tfloat4 norm = taylorInvSqrt( float4( dot( g0, g0 ), dot( g1, g1 ), dot( g2, g2 ), dot( g3, g3 ) ) );\n",
|
||||
"\tg0 *= norm.x;\n",
|
||||
"\tg1 *= norm.y;\n",
|
||||
"\tg2 *= norm.z;\n",
|
||||
"\tg3 *= norm.w;\n",
|
||||
"\tfloat4 m = max( 0.6 - float4( dot( x0, x0 ), dot( x1, x1 ), dot( x2, x2 ), dot( x3, x3 ) ), 0.0 );\n",
|
||||
"\tm = m* m;\n",
|
||||
"\tm = m* m;\n",
|
||||
"\tfloat4 px = float4( dot( x0, g0 ), dot( x1, g1 ), dot( x2, g2 ), dot( x3, g3 ) );\n",
|
||||
"\treturn 42.0 * dot( m, px);\n",
|
||||
"}\n"
|
||||
};
|
||||
|
||||
//Gradient Noise
|
||||
private readonly string UnityGradientNoiseFunc = "UnityGradientNoise({0},{1})";
|
||||
private readonly string[] UnityGradientNoiseFunctionsBody =
|
||||
{
|
||||
"float2 UnityGradientNoiseDir( float2 p )\n",
|
||||
"{\n",
|
||||
"\tp = fmod(p , 289);\n",
|
||||
"\tfloat x = fmod((34 * p.x + 1) * p.x , 289) + p.y;\n",
|
||||
"\tx = fmod( (34 * x + 1) * x , 289);\n",
|
||||
"\tx = frac( x / 41 ) * 2 - 1;\n",
|
||||
"\treturn normalize( float2(x - floor(x + 0.5 ), abs( x ) - 0.5 ) );\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"float UnityGradientNoise( float2 UV, float Scale )\n",
|
||||
"{\n",
|
||||
"\tfloat2 p = UV * Scale;\n",
|
||||
"\tfloat2 ip = floor( p );\n",
|
||||
"\tfloat2 fp = frac( p );\n",
|
||||
"\tfloat d00 = dot( UnityGradientNoiseDir( ip ), fp );\n",
|
||||
"\tfloat d01 = dot( UnityGradientNoiseDir( ip + float2( 0, 1 ) ), fp - float2( 0, 1 ) );\n",
|
||||
"\tfloat d10 = dot( UnityGradientNoiseDir( ip + float2( 1, 0 ) ), fp - float2( 1, 0 ) );\n",
|
||||
"\tfloat d11 = dot( UnityGradientNoiseDir( ip + float2( 1, 1 ) ), fp - float2( 1, 1 ) );\n",
|
||||
"\tfp = fp * fp * fp * ( fp * ( fp * 6 - 15 ) + 10 );\n",
|
||||
"\treturn lerp( lerp( d00, d01, fp.y ), lerp( d10, d11, fp.y ), fp.x ) + 0.5;\n",
|
||||
"}\n"
|
||||
};
|
||||
private readonly string GradientNoiseFunc = "GradientNoise({0},{1})";
|
||||
private readonly string[] GradientNoiseFunctionsBody =
|
||||
{
|
||||
"//https://www.shadertoy.com/view/XdXGW8\n",
|
||||
"float2 GradientNoiseDir( float2 x )\n",
|
||||
"{\n",
|
||||
"\tconst float2 k = float2( 0.3183099, 0.3678794 );\n",
|
||||
"\tx = x * k + k.yx;\n",
|
||||
"\treturn -1.0 + 2.0 * frac( 16.0 * k * frac( x.x * x.y * ( x.x + x.y ) ) );\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"float GradientNoise( float2 UV, float Scale )\n",
|
||||
"{\n",
|
||||
"\tfloat2 p = UV * Scale;\n",
|
||||
"\tfloat2 i = floor( p );\n",
|
||||
"\tfloat2 f = frac( p );\n",
|
||||
"\tfloat2 u = f * f * ( 3.0 - 2.0 * f );\n",
|
||||
"\treturn lerp( lerp( dot( GradientNoiseDir( i + float2( 0.0, 0.0 ) ), f - float2( 0.0, 0.0 ) ),\n",
|
||||
"\t\t\tdot( GradientNoiseDir( i + float2( 1.0, 0.0 ) ), f - float2( 1.0, 0.0 ) ), u.x ),\n",
|
||||
"\t\t\tlerp( dot( GradientNoiseDir( i + float2( 0.0, 1.0 ) ), f - float2( 0.0, 1.0 ) ),\n",
|
||||
"\t\t\tdot( GradientNoiseDir( i + float2( 1.0, 1.0 ) ), f - float2( 1.0, 1.0 ) ), u.x ), u.y );\n",
|
||||
"}\n"
|
||||
};
|
||||
|
||||
[SerializeField]
|
||||
private NoiseGeneratorType m_type = NoiseGeneratorType.Simplex2D;
|
||||
|
||||
[SerializeField]
|
||||
private bool m_setTo01Range = true;
|
||||
|
||||
[SerializeField]
|
||||
private bool m_unityVersion = false;
|
||||
private int m_setTo01RangePreviewId;
|
||||
|
||||
private UpperLeftWidgetHelper m_upperLeftWidget = new UpperLeftWidgetHelper();
|
||||
|
||||
protected override void CommonInit( int uniqueId )
|
||||
{
|
||||
base.CommonInit( uniqueId );
|
||||
AddInputPort( WirePortDataType.FLOAT2, false, "UV" );
|
||||
AddInputPort( WirePortDataType.FLOAT, false, "Scale" );
|
||||
m_inputPorts[ 1 ].FloatInternalData = 1;
|
||||
AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue );
|
||||
m_useInternalPortData = true;
|
||||
m_autoWrapProperties = true;
|
||||
m_hasLeftDropdown = true;
|
||||
SetAdditonalTitleText( string.Format( Constants.SubTitleTypeFormatStr, m_type ) );
|
||||
m_previewShaderGUID = "cd2d37ef5da190b42a91a5a690ba2a7d";
|
||||
ConfigurePorts();
|
||||
}
|
||||
|
||||
public override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
m_setTo01RangePreviewId = Shader.PropertyToID( SetTo01RangePreviewId );
|
||||
}
|
||||
|
||||
public override void AfterCommonInit()
|
||||
{
|
||||
base.AfterCommonInit();
|
||||
if( PaddingTitleLeft == 0 )
|
||||
{
|
||||
PaddingTitleLeft = Constants.PropertyPickerWidth + Constants.IconsLeftRightMargin;
|
||||
if( PaddingTitleRight == 0 )
|
||||
PaddingTitleRight = Constants.PropertyPickerWidth + Constants.IconsLeftRightMargin;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Destroy()
|
||||
{
|
||||
base.Destroy();
|
||||
m_upperLeftWidget = null;
|
||||
}
|
||||
|
||||
public override void SetPreviewInputs()
|
||||
{
|
||||
base.SetPreviewInputs();
|
||||
float range01 = m_setTo01Range ? 1 : 0;
|
||||
PreviewMaterial.SetFloat( m_setTo01RangePreviewId, range01 );
|
||||
}
|
||||
|
||||
public override void Draw( DrawInfo drawInfo )
|
||||
{
|
||||
base.Draw( drawInfo );
|
||||
m_upperLeftWidget.DrawWidget<NoiseGeneratorType>( ref m_type, this, OnWidgetUpdate );
|
||||
}
|
||||
|
||||
private readonly Action<ParentNode> OnWidgetUpdate = ( x ) =>
|
||||
{
|
||||
( x as NoiseGeneratorNode ).ConfigurePorts();
|
||||
};
|
||||
|
||||
public override void DrawProperties()
|
||||
{
|
||||
base.DrawProperties();
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_type = (NoiseGeneratorType)EditorGUILayoutEnumPopup( TypeLabelStr, m_type );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
{
|
||||
ConfigurePorts();
|
||||
}
|
||||
|
||||
m_setTo01Range = EditorGUILayoutToggle( SetTo01RangeLabel, m_setTo01Range );
|
||||
|
||||
if( m_type == NoiseGeneratorType.Gradient )
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_unityVersion = EditorGUILayoutToggle( UseUnityVersionLabel, m_unityVersion );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
{
|
||||
ConfigurePorts();
|
||||
}
|
||||
}
|
||||
//EditorGUILayout.HelpBox( "Node still under construction. Use with caution", MessageType.Info );
|
||||
}
|
||||
|
||||
private void ConfigurePorts()
|
||||
{
|
||||
SetAdditonalTitleText( string.Format( Constants.SubTitleTypeFormatStr, m_type ) );
|
||||
|
||||
switch( m_type )
|
||||
{
|
||||
case NoiseGeneratorType.Simplex2D:
|
||||
{
|
||||
m_inputPorts[ 0 ].ChangeType( WirePortDataType.FLOAT2, false );
|
||||
m_previewMaterialPassId = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case NoiseGeneratorType.Simplex3D:
|
||||
{
|
||||
m_inputPorts[ 0 ].ChangeType( WirePortDataType.FLOAT3, false );
|
||||
m_previewMaterialPassId = 1;
|
||||
}
|
||||
break;
|
||||
case NoiseGeneratorType.Gradient:
|
||||
{
|
||||
m_inputPorts[ 0 ].ChangeType( WirePortDataType.FLOAT2, false );
|
||||
m_previewMaterialPassId = m_unityVersion ? 3 : 2;
|
||||
}
|
||||
break;
|
||||
case NoiseGeneratorType.Simple:
|
||||
{
|
||||
m_inputPorts[ 0 ].ChangeType( WirePortDataType.FLOAT2, false );
|
||||
m_previewMaterialPassId = 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
PreviewIsDirty = true;
|
||||
}
|
||||
|
||||
public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
|
||||
{
|
||||
if( m_outputPorts[ outputId ].IsLocalValue( dataCollector.PortCategory ) )
|
||||
{
|
||||
return m_outputPorts[ outputId ].LocalValue( dataCollector.PortCategory );
|
||||
}
|
||||
|
||||
string size = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
|
||||
string scale = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector );
|
||||
|
||||
switch( m_type )
|
||||
{
|
||||
case NoiseGeneratorType.Simplex2D:
|
||||
{
|
||||
|
||||
string float3Mod289Func = ( dataCollector.IsTemplate ) ? Simplex2DFloat3Mod289Func : "\t\t" + Simplex2DFloat3Mod289Func;
|
||||
dataCollector.AddFunction( Simplex2DFloat3Mod289Func, float3Mod289Func );
|
||||
|
||||
string float2Mod289Func = ( dataCollector.IsTemplate ) ? Simplex2DFloat2Mod289Func : "\t\t" + Simplex2DFloat2Mod289Func;
|
||||
dataCollector.AddFunction( Simplex2DFloat2Mod289Func, float2Mod289Func );
|
||||
|
||||
string permuteFunc = ( dataCollector.IsTemplate ) ? Simplex2DPermuteFunc : "\t\t" + Simplex2DPermuteFunc;
|
||||
dataCollector.AddFunction( Simplex2DPermuteFunc, permuteFunc );
|
||||
|
||||
dataCollector.AddFunction( SimplexNoise2DHeader, SimplexNoise2DBody, false );
|
||||
|
||||
|
||||
if( m_inputPorts[ 1 ].IsConnected || m_inputPorts[ 1 ].FloatInternalData != 1.0f )
|
||||
{
|
||||
size = string.Format( "{0}*{1}", size, scale );
|
||||
}
|
||||
|
||||
RegisterLocalVariable( 0, string.Format( SimplexNoise2DFunc, size ), ref dataCollector, ( "simplePerlin2D" + OutputId ) );
|
||||
}
|
||||
break;
|
||||
case NoiseGeneratorType.Simplex3D:
|
||||
{
|
||||
|
||||
string float3Mod289Func = ( dataCollector.IsTemplate ) ? Simplex3DFloat3Mod289 : "\t\t" + Simplex3DFloat3Mod289;
|
||||
dataCollector.AddFunction( Simplex3DFloat3Mod289, float3Mod289Func );
|
||||
|
||||
string float4Mod289Func = ( dataCollector.IsTemplate ) ? Simplex3DFloat4Mod289 : "\t\t" + Simplex3DFloat4Mod289;
|
||||
dataCollector.AddFunction( Simplex3DFloat4Mod289, float4Mod289Func );
|
||||
|
||||
string permuteFunc = ( dataCollector.IsTemplate ) ? Simplex3DFloat4Permute : "\t\t" + Simplex3DFloat4Permute;
|
||||
dataCollector.AddFunction( Simplex3DFloat4Permute, permuteFunc );
|
||||
|
||||
string taylorInvSqrtFunc = ( dataCollector.IsTemplate ) ? TaylorInvSqrtFunc : "\t\t" + TaylorInvSqrtFunc;
|
||||
dataCollector.AddFunction( TaylorInvSqrtFunc, taylorInvSqrtFunc );
|
||||
|
||||
dataCollector.AddFunction( SimplexNoise3DHeader, SimplexNoise3DBody, false );
|
||||
|
||||
if( m_inputPorts[ 1 ].IsConnected || m_inputPorts[ 1 ].FloatInternalData != 1.0f )
|
||||
{
|
||||
size = string.Format( "{0}*{1}", size, scale );
|
||||
}
|
||||
|
||||
RegisterLocalVariable( 0, string.Format( SimplexNoise3DFunc, size ), ref dataCollector, ( "simplePerlin3D" + OutputId ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case NoiseGeneratorType.Gradient:
|
||||
{
|
||||
string[] body = m_unityVersion ? UnityGradientNoiseFunctionsBody : GradientNoiseFunctionsBody;
|
||||
string func = m_unityVersion ? UnityGradientNoiseFunc : GradientNoiseFunc;
|
||||
|
||||
dataCollector.AddFunction( body[ 0 ], body, false);
|
||||
RegisterLocalVariable( 0, string.Format( func, size, scale ), ref dataCollector, ( "gradientNoise" + OutputId ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case NoiseGeneratorType.Simple:
|
||||
{
|
||||
string randomValue = ( dataCollector.IsTemplate ) ? SimpleNoiseRandomValueFunc : "\t\t" + SimpleNoiseRandomValueFunc;
|
||||
dataCollector.AddFunction( SimpleNoiseRandomValueFunc, randomValue );
|
||||
|
||||
string interpolate = ( dataCollector.IsTemplate ) ? SimpleNoiseInterpolateFunc : "\t\t" + SimpleNoiseInterpolateFunc;
|
||||
dataCollector.AddFunction( SimpleNoiseInterpolateFunc, interpolate );
|
||||
|
||||
dataCollector.AddFunction( SimpleValueNoiseHeader, SimpleValueNoiseBody, false );
|
||||
|
||||
dataCollector.AddFunction( SimpleNoiseHeader, SimpleNoiseBody, false );
|
||||
|
||||
if( m_inputPorts[ 1 ].IsConnected || m_inputPorts[ 1 ].FloatInternalData != 1.0f )
|
||||
{
|
||||
size = string.Format( "{0}*{1}", size, scale );
|
||||
}
|
||||
RegisterLocalVariable( 0, string.Format( SimpleNoiseFunc, size ), ref dataCollector, ( "simpleNoise" + OutputId ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if( m_type == NoiseGeneratorType.Simple && !m_setTo01Range )
|
||||
{
|
||||
dataCollector.AddLocalVariable( outputId, string.Format( SetToMinus1To1RangeOpStr, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) ) );
|
||||
}
|
||||
|
||||
if( m_setTo01Range && m_type != NoiseGeneratorType.Simple )
|
||||
{
|
||||
dataCollector.AddLocalVariable( outputId, string.Format( SetTo01RangeOpStr, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) ) );
|
||||
}
|
||||
|
||||
return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
|
||||
}
|
||||
|
||||
public override void ReadFromString( ref string[] nodeParams )
|
||||
{
|
||||
base.ReadFromString( ref nodeParams );
|
||||
m_type = (NoiseGeneratorType)Enum.Parse( typeof( NoiseGeneratorType ), GetCurrentParam( ref nodeParams ) );
|
||||
if( UIUtils.CurrentShaderVersion() < 16903 )
|
||||
{
|
||||
m_setTo01Range = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_setTo01Range = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
|
||||
m_unityVersion = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
|
||||
}
|
||||
|
||||
ConfigurePorts();
|
||||
}
|
||||
|
||||
public override void WriteToString( ref string nodeInfo, ref string connectionsInfo )
|
||||
{
|
||||
base.WriteToString( ref nodeInfo, ref connectionsInfo );
|
||||
IOUtils.AddFieldValueToString( ref nodeInfo, m_type );
|
||||
IOUtils.AddFieldValueToString( ref nodeInfo, m_setTo01Range );
|
||||
IOUtils.AddFieldValueToString( ref nodeInfo, m_unityVersion );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b82a8d1dffe4204fa03a09e2fe783b3
|
||||
timeCreated: 1485355115
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,98 @@
|
||||
// Amplify Shader Editor - Visual Shader Editing Tool
|
||||
// Copyright (c) Amplify Creations, Lda <info@amplify.pt>
|
||||
|
||||
//https://www.shadertoy.com/view/ldX3D4
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
namespace AmplifyShaderEditor
|
||||
{
|
||||
[Serializable]
|
||||
[NodeAttributes( "Posterize", "Image Effects", "Converts a continuous gradation of tones to multiple regions of fewer tones" )]
|
||||
public sealed class PosterizeNode : ParentNode
|
||||
{
|
||||
private const string PosterizationPowerStr = "Power";
|
||||
[SerializeField]
|
||||
private int m_posterizationPower = 1;
|
||||
|
||||
protected override void CommonInit( int uniqueId )
|
||||
{
|
||||
base.CommonInit( uniqueId );
|
||||
AddInputPort( WirePortDataType.COLOR, false, "RGBA", -1, MasterNodePortCategory.Fragment, 1 );
|
||||
AddInputPort( WirePortDataType.INT, false, "Power", -1, MasterNodePortCategory.Fragment, 0 );
|
||||
m_inputPorts[ 1 ].AutoDrawInternalData = true;
|
||||
AddOutputPort( WirePortDataType.COLOR, Constants.EmptyPortValue );
|
||||
m_textLabelWidth = 60;
|
||||
m_autoWrapProperties = true;
|
||||
m_previewShaderGUID = "ecb3048ef0eec1645bad1d72a98d8279";
|
||||
}
|
||||
|
||||
public override void DrawProperties()
|
||||
{
|
||||
base.DrawProperties();
|
||||
if( !m_inputPorts[ 1 ].IsConnected )
|
||||
{
|
||||
EditorGUILayout.BeginVertical();
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_posterizationPower = EditorGUILayoutIntSlider( PosterizationPowerStr, m_posterizationPower, 1, 256 );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
{
|
||||
GetInputPortByUniqueId( 0 ).IntInternalData = m_posterizationPower;
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
}
|
||||
|
||||
public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar )
|
||||
{
|
||||
if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) )
|
||||
return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
|
||||
|
||||
string posterizationPower = "1";
|
||||
if( m_inputPorts[ 1 ].IsConnected )
|
||||
{
|
||||
posterizationPower = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector );
|
||||
}
|
||||
else
|
||||
{
|
||||
posterizationPower = m_posterizationPower.ToString();
|
||||
}
|
||||
|
||||
string colorTarget = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
|
||||
|
||||
string divVar = "div" + OutputId;
|
||||
dataCollector.AddLocalVariable( UniqueId, "float " + divVar + "=256.0/float(" + posterizationPower + ");" );
|
||||
string result = "( floor( " + colorTarget + " * " + divVar + " ) / " + divVar + " )";
|
||||
|
||||
RegisterLocalVariable( 0, result, ref dataCollector, "posterize" + OutputId );
|
||||
|
||||
return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
|
||||
}
|
||||
|
||||
public override void RefreshExternalReferences()
|
||||
{
|
||||
base.RefreshExternalReferences();
|
||||
m_inputPorts[ 0 ].ChangeType( WirePortDataType.COLOR, false );
|
||||
m_inputPorts[ 1 ].ChangeType( WirePortDataType.INT, false );
|
||||
}
|
||||
|
||||
public override void WriteToString( ref string nodeInfo, ref string connectionsInfo )
|
||||
{
|
||||
base.WriteToString( ref nodeInfo, ref connectionsInfo );
|
||||
IOUtils.AddFieldValueToString( ref nodeInfo, m_posterizationPower );
|
||||
}
|
||||
|
||||
public override void ReadFromString( ref string[] nodeParams )
|
||||
{
|
||||
base.ReadFromString( ref nodeParams );
|
||||
m_posterizationPower = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7dc4667cd643835489312daa244a03b9
|
||||
timeCreated: 1481126957
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
|
||||
namespace AmplifyShaderEditor
|
||||
{
|
||||
[Serializable]
|
||||
[NodeAttributes( "RGB to HSV", "Image Effects", "Converts from RGB to HSV color space" )]
|
||||
public sealed class RGBToHSVNode : ParentNode
|
||||
{
|
||||
public static readonly string RGBToHSVHeader = "RGBToHSV( {0} )";
|
||||
public static readonly string[] RGBToHSVFunction = { "{0}3 RGBToHSV({0}3 c)\n",
|
||||
"{\n",
|
||||
"\t{0}4 K = {0}4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n",
|
||||
"\t{0}4 p = lerp( {0}4( c.bg, K.wz ), {0}4( c.gb, K.xy ), step( c.b, c.g ) );\n",
|
||||
"\t{0}4 q = lerp( {0}4( p.xyw, c.r ), {0}4( c.r, p.yzx ), step( p.x, c.r ) );\n",
|
||||
"\t{0} d = q.x - min( q.w, q.y );\n",
|
||||
"\t{0} e = 1.0e-10;\n",
|
||||
"\treturn {0}3( abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n",
|
||||
"}"
|
||||
};
|
||||
|
||||
public static readonly bool[] RGBToHSVFlags = { true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false};
|
||||
|
||||
protected override void CommonInit( int uniqueId )
|
||||
{
|
||||
base.CommonInit( uniqueId );
|
||||
AddInputPort( WirePortDataType.FLOAT3, false, "RGB" );
|
||||
AddOutputPort( WirePortDataType.FLOAT3, "HSV" );
|
||||
AddOutputPort( WirePortDataType.FLOAT, "Hue" );
|
||||
AddOutputPort( WirePortDataType.FLOAT, "Saturation" );
|
||||
AddOutputPort( WirePortDataType.FLOAT, "Value" );
|
||||
m_previewShaderGUID = "0f2f09b49bf4954428aafa2dfe1a9a09";
|
||||
m_useInternalPortData = true;
|
||||
m_autoWrapProperties = true;
|
||||
m_customPrecision = true;
|
||||
}
|
||||
|
||||
public override void DrawProperties()
|
||||
{
|
||||
base.DrawProperties();
|
||||
DrawPrecisionProperty();
|
||||
}
|
||||
|
||||
public void AddRGBToHSVFunction( ref MasterNodeDataCollector dataCollector, string precisionString )
|
||||
{
|
||||
if( !dataCollector.HasFunction( RGBToHSVHeader ) )
|
||||
{
|
||||
//Hack to be used util indent is properly used
|
||||
int currIndent = UIUtils.ShaderIndentLevel;
|
||||
if( dataCollector.MasterNodeCategory == AvailableShaderTypes.Template )
|
||||
{
|
||||
UIUtils.ShaderIndentLevel = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
UIUtils.ShaderIndentLevel = 1;
|
||||
UIUtils.ShaderIndentLevel++;
|
||||
}
|
||||
|
||||
string finalFunction = string.Empty;
|
||||
for( int i = 0; i < RGBToHSVFunction.Length; i++ )
|
||||
{
|
||||
finalFunction += UIUtils.ShaderIndentTabs + ( RGBToHSVFlags[ i ] ? string.Format( RGBToHSVFunction[ i ], precisionString ) : RGBToHSVFunction[ i ] );
|
||||
}
|
||||
UIUtils.ShaderIndentLevel--;
|
||||
UIUtils.ShaderIndentLevel = currIndent;
|
||||
|
||||
dataCollector.AddFunction( RGBToHSVHeader, finalFunction );
|
||||
}
|
||||
}
|
||||
|
||||
public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
|
||||
{
|
||||
if ( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) )
|
||||
return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) );
|
||||
|
||||
string precisionString = UIUtils.PrecisionWirePortToCgType( CurrentPrecisionType, WirePortDataType.FLOAT );
|
||||
AddRGBToHSVFunction( ref dataCollector, precisionString );
|
||||
|
||||
string rgbValue = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
|
||||
|
||||
RegisterLocalVariable( 0, string.Format( RGBToHSVHeader, rgbValue ), ref dataCollector, "hsvTorgb" + OutputId );
|
||||
return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d24b838adbc80d4cb63e3fc4f5a1c79
|
||||
timeCreated: 1494863846
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,55 @@
|
||||
// Amplify Shader Editor - Visual Shader Editing Tool
|
||||
// Copyright (c) Amplify Creations, Lda <info@amplify.pt>
|
||||
using System;
|
||||
|
||||
namespace AmplifyShaderEditor
|
||||
{
|
||||
[Serializable]
|
||||
[NodeAttributes( "Simple Contrast", "Image Effects", "Simple contrast matrix multiplication" )]
|
||||
public sealed class SimpleContrastOpNode : ParentNode
|
||||
{
|
||||
private const string InputTypeStr = "Contrast";
|
||||
private const string FunctionHeader = "CalculateContrast({0},{1})";
|
||||
private readonly string[] m_functionBody = { "float4 CalculateContrast( float contrastValue, float4 colorTarget )\n",
|
||||
"{\n",
|
||||
"\tfloat t = 0.5 * ( 1.0 - contrastValue );\n",
|
||||
"\treturn mul( float4x4( contrastValue,0,0,t, 0,contrastValue,0,t, 0,0,contrastValue,t, 0,0,0,1 ), colorTarget );\n",
|
||||
"}"};
|
||||
protected override void CommonInit( int uniqueId )
|
||||
{
|
||||
base.CommonInit( uniqueId );
|
||||
AddPorts();
|
||||
m_textLabelWidth = 70;
|
||||
m_useInternalPortData = true;
|
||||
m_previewShaderGUID = "8d76799413f9f0547ac9b1de7ba798f1";
|
||||
}
|
||||
|
||||
void AddPorts()
|
||||
{
|
||||
AddInputPort( WirePortDataType.COLOR, false, "RGBA", -1, MasterNodePortCategory.Fragment, 1 );
|
||||
AddInputPort( WirePortDataType.FLOAT, false, "Value", -1, MasterNodePortCategory.Fragment, 0 );
|
||||
AddOutputPort( WirePortDataType.COLOR, Constants.EmptyPortValue );
|
||||
}
|
||||
|
||||
public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar )
|
||||
{
|
||||
if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) )
|
||||
return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
|
||||
|
||||
string contrastValue = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector );
|
||||
string colorTarget = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
|
||||
string result = dataCollector.AddFunctions( FunctionHeader, m_functionBody, false, contrastValue, colorTarget );
|
||||
|
||||
return CreateOutputLocalVariable( 0, result, ref dataCollector );
|
||||
}
|
||||
|
||||
public override void ReadFromString( ref string[] nodeParams )
|
||||
{
|
||||
base.ReadFromString( ref nodeParams );
|
||||
if( UIUtils.CurrentShaderVersion() < 5004 )
|
||||
{
|
||||
m_inputPorts[ 1 ].FloatInternalData = Convert.ToSingle( GetCurrentParam( ref nodeParams ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f49defa61805f948a04775d391e507a
|
||||
timeCreated: 1481126955
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,104 @@
|
||||
// Amplify Shader Editor - Visual Shader Editing Tool
|
||||
// Copyright (c) Amplify Creations, Lda <info@amplify.pt>
|
||||
|
||||
//https://www.shadertoy.com/view/XsX3zB
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
|
||||
namespace AmplifyShaderEditor
|
||||
{
|
||||
public enum NoiseType
|
||||
{
|
||||
Simplex3D,
|
||||
Simplex3DFractal
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
[NodeAttributes( "[Deprecated] Simplex Noise", "Image Effects", "Noise generated via the Simplex algorithm",null,KeyCode.None,false,true)]
|
||||
public sealed class SimplexNoiseNode : ParentNode
|
||||
{
|
||||
private string m_randomFuncBody;
|
||||
private string m_simplex3dFuncBody;
|
||||
private string m_simplex3dFractalFuncBody;
|
||||
|
||||
private const string RandomfunctionHeader = "Random3({0})";
|
||||
private const string Simplex3dfunctionHeader = "Simplex3d({0})";
|
||||
private const string Simplex3dFractalfunctionHeader = "Simplex3dFractal( {0})";
|
||||
|
||||
private const string NoiseTypeStr = "Type";
|
||||
|
||||
[SerializeField]
|
||||
private NoiseType m_type = NoiseType.Simplex3D;
|
||||
|
||||
protected override void CommonInit( int uniqueId )
|
||||
{
|
||||
base.CommonInit( uniqueId );
|
||||
|
||||
IOUtils.AddFunctionHeader( ref m_randomFuncBody, "float3 Random3 ( float3 c )" );
|
||||
IOUtils.AddFunctionLine( ref m_randomFuncBody, "float fracMul = 512.0;float j = 4096.0*sin ( dot ( c, float3 ( 17.0, 59.4, 15.0 ) ) );float3 r;r.z = frac ( fracMul*j );j *= .125;r.x = frac ( fracMul*j );j *= .125;r.y = frac ( fracMul*j );return r - 0.5;" );
|
||||
IOUtils.CloseFunctionBody( ref m_randomFuncBody );
|
||||
|
||||
IOUtils.AddFunctionHeader( ref m_simplex3dFuncBody, "float3 Simplex3d ( float3 p )" );
|
||||
IOUtils.AddFunctionLine( ref m_simplex3dFuncBody, "float F3 = 0.3333333;float G3 = 0.1666667;float3 s = floor ( p + dot ( p, F3.xxx ) );float3 x = p - s + dot ( s, G3.xxx );float3 e = step ( ( 0.0 ).xxx, x - x.yzx );float3 i1 = e*( 1.0 - e.zxy );float3 i2 = 1.0 - e.zxy*( 1.0 - e );float3 x1 = x - i1 + G3;float3 x2 = x - i2 + 2.0*G3;float3 x3 = x - 1.0 + 3.0*G3;float4 w, d;w.x = dot ( x, x );w.y = dot ( x1, x1 );w.z = dot ( x2, x2 );w.w = dot ( x3, x3 );w = max ( 0.6 - w, 0.0 );d.x = dot ( Random3 ( s ), x );d.y = dot ( Random3 ( s + i1 ), x1 );d.z = dot ( Random3 ( s + i2 ), x2 );d.w = dot ( Random3 ( s + 1.0 ), x3 );w *= w;w *= w;d *= w;return dot ( d, ( 52.0 ).xxx ).xxx;" );
|
||||
IOUtils.CloseFunctionBody( ref m_simplex3dFuncBody );
|
||||
|
||||
IOUtils.AddFunctionHeader( ref m_simplex3dFractalFuncBody, "float3 Simplex3dFractal ( float3 m )" );
|
||||
IOUtils.AddFunctionLine( ref m_simplex3dFractalFuncBody, "return (0.5333333*Simplex3d ( m ) + 0.2666667*Simplex3d ( 2.0*m ) + 0.1333333*Simplex3d ( 4.0*m ) + 0.0666667*Simplex3d ( 8.0*m )).xxx;" );
|
||||
IOUtils.CloseFunctionBody( ref m_simplex3dFractalFuncBody );
|
||||
|
||||
AddInputPort( WirePortDataType.FLOAT3, false, "Position" );
|
||||
AddInputPort( WirePortDataType.FLOAT, false, "Width" );
|
||||
AddOutputPort( WirePortDataType.FLOAT3, Constants.EmptyPortValue );
|
||||
m_textLabelWidth = 50;
|
||||
m_useInternalPortData = true;
|
||||
m_autoWrapProperties = true;
|
||||
}
|
||||
|
||||
public override void DrawProperties()
|
||||
{
|
||||
base.DrawProperties();
|
||||
m_type = ( NoiseType ) EditorGUILayoutEnumPopup( NoiseTypeStr, m_type );
|
||||
}
|
||||
|
||||
public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
|
||||
{
|
||||
|
||||
|
||||
string posValue = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
|
||||
string widthValue = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector );
|
||||
dataCollector.AddFunctions( RandomfunctionHeader, m_randomFuncBody, "0" );
|
||||
string result = string.Empty;
|
||||
switch ( m_type )
|
||||
{
|
||||
case NoiseType.Simplex3D:
|
||||
{
|
||||
string finalValue = dataCollector.AddFunctions( Simplex3dfunctionHeader, m_simplex3dFuncBody, posValue + "*" + widthValue );
|
||||
result = finalValue + "* 0.5 + 0.5";
|
||||
}break;
|
||||
|
||||
case NoiseType.Simplex3DFractal:
|
||||
{
|
||||
dataCollector.AddFunctions( Simplex3dfunctionHeader, m_simplex3dFuncBody, posValue + "*" + widthValue );
|
||||
string finalValue = dataCollector.AddFunctions( Simplex3dFractalfunctionHeader, m_simplex3dFractalFuncBody, posValue + "*" + widthValue + "+" + widthValue );
|
||||
result = finalValue + "* 0.5 + 0.5";
|
||||
}break;
|
||||
}
|
||||
|
||||
return CreateOutputLocalVariable( 0, result, ref dataCollector );
|
||||
}
|
||||
|
||||
public override void ReadFromString( ref string[] nodeParams )
|
||||
{
|
||||
base.ReadFromString( ref nodeParams );
|
||||
m_type = ( NoiseType ) Enum.Parse( typeof( NoiseType ), GetCurrentParam( ref nodeParams ) );
|
||||
}
|
||||
|
||||
public override void WriteToString( ref string nodeInfo, ref string connectionsInfo )
|
||||
{
|
||||
base.WriteToString( ref nodeInfo, ref connectionsInfo );
|
||||
IOUtils.AddFieldValueToString( ref nodeInfo, m_type );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f888e3dadb5df94199547ab13cb74d2
|
||||
timeCreated: 1481126955
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,116 @@
|
||||
// Amplify Shader Editor - Visual Shader Editing Tool
|
||||
// Copyright (c) Amplify Creations, Lda <info@amplify.pt>
|
||||
//
|
||||
// Custom Node Grayscale
|
||||
// Donated by The Four Headed Cat - @fourheadedcat
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
namespace AmplifyShaderEditor
|
||||
{
|
||||
[Serializable]
|
||||
[NodeAttributes( "Grayscale", "Image Effects", "Convert image colors to grayscale", null, KeyCode.None, true, false, null, null, "The Four Headed Cat - @fourheadedcat", tags:"luminance" )]
|
||||
public sealed class TFHCGrayscale : ParentNode
|
||||
{
|
||||
private const string GrayscaleStyleStr = "Grayscale Style";
|
||||
|
||||
[SerializeField]
|
||||
private int m_grayscaleStyle;
|
||||
|
||||
[SerializeField]
|
||||
private readonly string[] m_GrayscaleStyleValues = { "Luminance", "Natural Classic", "Old School" };
|
||||
|
||||
private UpperLeftWidgetHelper m_upperLeftWidget = new UpperLeftWidgetHelper();
|
||||
|
||||
protected override void CommonInit( int uniqueId )
|
||||
{
|
||||
base.CommonInit( uniqueId );
|
||||
AddInputPort( WirePortDataType.FLOAT3, false, "RGB" );
|
||||
AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue );
|
||||
m_textLabelWidth = 120;
|
||||
m_useInternalPortData = true;
|
||||
m_hasLeftDropdown = true;
|
||||
m_autoWrapProperties = true;
|
||||
SetAdditonalTitleText( string.Format( Constants.SubTitleTypeFormatStr, m_GrayscaleStyleValues[ m_grayscaleStyle ] ) );
|
||||
m_previewShaderGUID = "56781cd022be9124597f0f396a46a35f";
|
||||
}
|
||||
|
||||
public override void AfterCommonInit()
|
||||
{
|
||||
base.AfterCommonInit();
|
||||
if( PaddingTitleLeft == 0 )
|
||||
{
|
||||
PaddingTitleLeft = Constants.PropertyPickerWidth + Constants.IconsLeftRightMargin;
|
||||
if( PaddingTitleRight == 0 )
|
||||
PaddingTitleRight = Constants.PropertyPickerWidth + Constants.IconsLeftRightMargin;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Destroy()
|
||||
{
|
||||
base.Destroy();
|
||||
m_upperLeftWidget = null;
|
||||
}
|
||||
|
||||
void UpdateFromSelected()
|
||||
{
|
||||
m_previewMaterialPassId = m_grayscaleStyle;
|
||||
SetAdditonalTitleText( string.Format( Constants.SubTitleTypeFormatStr, m_GrayscaleStyleValues[ m_grayscaleStyle ] ) );
|
||||
}
|
||||
|
||||
public override void Draw( DrawInfo drawInfo )
|
||||
{
|
||||
base.Draw( drawInfo );
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_grayscaleStyle = m_upperLeftWidget.DrawWidget( this, m_grayscaleStyle, m_GrayscaleStyleValues );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
{
|
||||
UpdateFromSelected();
|
||||
}
|
||||
}
|
||||
|
||||
public override void DrawProperties()
|
||||
{
|
||||
base.DrawProperties();
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_grayscaleStyle = EditorGUILayoutPopup( GrayscaleStyleStr, m_grayscaleStyle, m_GrayscaleStyleValues );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
{
|
||||
UpdateFromSelected();
|
||||
}
|
||||
EditorGUILayout.HelpBox( "Grayscale Old:\n\n - In: Image to convert.\n - Grayscale Style: Select the grayscale style.\n\n - Out: Grayscale version of the image.", MessageType.None );
|
||||
}
|
||||
|
||||
public override void ReadFromString( ref string[] nodeParams )
|
||||
{
|
||||
base.ReadFromString( ref nodeParams );
|
||||
m_grayscaleStyle = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
|
||||
UpdateFromSelected();
|
||||
}
|
||||
|
||||
public override void WriteToString( ref string nodeInfo, ref string connectionsInfo )
|
||||
{
|
||||
base.WriteToString( ref nodeInfo, ref connectionsInfo );
|
||||
IOUtils.AddFieldValueToString( ref nodeInfo, m_grayscaleStyle );
|
||||
}
|
||||
|
||||
public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
|
||||
{
|
||||
if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) )
|
||||
return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
|
||||
|
||||
string i = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
|
||||
string grayscale = string.Empty;
|
||||
switch( m_grayscaleStyle )
|
||||
{
|
||||
case 1: { grayscale = "dot(" + i + ", float3(0.299,0.587,0.114))"; } break;
|
||||
case 2: { grayscale = "(" + i + ".r + " + i + ".g + " + i + ".b) / 3"; } break;
|
||||
default: { grayscale = "Luminance(" + i + ")"; } break;
|
||||
}
|
||||
RegisterLocalVariable( 0, grayscale, ref dataCollector, "grayscale" + OutputId );
|
||||
return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32d7b01a9f453d448abf3685a35c4a19
|
||||
timeCreated: 1481126954
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,593 @@
|
||||
// Amplify Shader Editor - Visual Shader Editing Tool
|
||||
// Copyright (c) Amplify Creations, Lda <info@amplify.pt>
|
||||
|
||||
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 )";
|
||||
private const string VoronoiFunc = "voronoi{0}( {1}, {2}, {3}, {4}, {5} )";
|
||||
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<F1 ) {",//12
|
||||
" \t\t\tF2 = F1;",//13
|
||||
" \t\t\tF1 = d; mg = g; mr = r; id = o;",//14
|
||||
" \t\t} else if( d<F2 ) {",//15
|
||||
" \t\t\tF2 = d;",//16
|
||||
" \t\t}",//17
|
||||
" \t}",
|
||||
"}",
|
||||
"return F1;"
|
||||
};
|
||||
|
||||
private string VoronoiDistanceBody =
|
||||
"\nF1 = 8.0;" +
|
||||
"\nfor ( int j = -2; j <= 2; j++ )" +
|
||||
"\n{{" +
|
||||
"\nfor ( int i = -2; i <= 2; i++ )" +
|
||||
"\n{{" +
|
||||
"\nfloat2 g = mg + float2( i, j );" +
|
||||
"\nfloat2 o = voronoihash{1}( n + g );" +
|
||||
"\n{0}" +
|
||||
"\nfloat d = dot( 0.5 * ( r + mr ), normalize( r - mr ) );" +
|
||||
"\nF1 = min( F1, d );" +
|
||||
"\n}}" +
|
||||
"\n}}" +
|
||||
"\nreturn F1;";
|
||||
|
||||
[SerializeField]
|
||||
private int m_distanceFunction = 0;
|
||||
|
||||
[SerializeField]
|
||||
private float m_minkowskiPower = 1;
|
||||
|
||||
[SerializeField]
|
||||
private int m_functionType = 0;
|
||||
|
||||
[SerializeField]
|
||||
private int m_octaves = 1;
|
||||
|
||||
[SerializeField]
|
||||
private bool m_tileable = false;
|
||||
|
||||
[SerializeField]
|
||||
private int m_tileScale = 1;
|
||||
|
||||
[SerializeField]
|
||||
private bool m_useUnity = false;
|
||||
|
||||
[SerializeField]
|
||||
private bool m_calculateSmoothValue = false;
|
||||
|
||||
private const string FunctionTypeStr = "Method";//"Function Type";
|
||||
private readonly string[] m_functionTypeStr = { "Cells", "Crystal", "Glass", "Caustic", "Distance" };
|
||||
|
||||
private const string DistanceFunctionLabelStr = "Distance Function";
|
||||
private readonly string[] m_distanceFunctionStr = { "Euclidean\u00B2", "Euclidean", "Manhattan", "Chebyshev", "Minkowski" };
|
||||
|
||||
[SerializeField]
|
||||
private int m_searchQuality = 0;
|
||||
private const string SearchQualityLabelStr = "Search Quality";
|
||||
private readonly string[] m_searchQualityStr = { "9 Cells", "25 Cells", "49 Cells" };
|
||||
|
||||
|
||||
private const string UseTileScaleStr = "_UseTileScale";
|
||||
private const string TileScaleStr = "_TileScale";
|
||||
private const string MinkowskiPowerStr = "_MinkowskiPower";
|
||||
private const string DistFuncStr = "_DistFunc";
|
||||
private const string MethodTypeStr = "_MethodType";
|
||||
private const string SearchQualityStr = "_SearchQuality";
|
||||
private const string OctavesStr = "_Octaves";
|
||||
private const string UseSmoothnessStr = "_UseSmoothness";
|
||||
|
||||
private int m_UseTileScaleId;
|
||||
private int m_TileScaleId;
|
||||
private int m_MinkowskiPowerId;
|
||||
private int m_DistFuncId;
|
||||
private int m_MethodTypeId;
|
||||
private int m_SearchQualityId;
|
||||
private int m_OctavesId;
|
||||
private int m_UseSmoothnessId;
|
||||
|
||||
private int m_cachedUvsId = -1;
|
||||
|
||||
protected override void CommonInit( int uniqueId )
|
||||
{
|
||||
base.CommonInit( uniqueId );
|
||||
AddInputPort( WirePortDataType.FLOAT2, false, "UV" );
|
||||
AddInputPort( WirePortDataType.FLOAT, false, "Angle" );
|
||||
AddInputPort( WirePortDataType.FLOAT, false, "Scale" );
|
||||
AddInputPort( WirePortDataType.FLOAT, false, "Smoothness" );
|
||||
|
||||
m_inputPorts[ 1 ].AutoDrawInternalData = true;
|
||||
m_inputPorts[ 2 ].AutoDrawInternalData = true;
|
||||
m_inputPorts[ 2 ].FloatInternalData = 1;
|
||||
|
||||
AddOutputPort( WirePortDataType.FLOAT, "Out" );
|
||||
AddOutputPort( WirePortDataType.FLOAT2, "ID" );
|
||||
AddOutputPort( WirePortDataType.FLOAT2, "UV" );
|
||||
m_textLabelWidth = 120;
|
||||
//m_useInternalPortData = true;
|
||||
m_autoWrapProperties = true;
|
||||
m_previewShaderGUID = "bc1498ccdade442479038b24982fc946";
|
||||
ChangePorts();
|
||||
ChechSmoothPorts();
|
||||
}
|
||||
|
||||
void ChechSmoothPorts()
|
||||
{
|
||||
m_inputPorts[ 3 ].Visible = !m_useUnity && m_calculateSmoothValue && (m_functionType == 0) ;
|
||||
m_sizeIsDirty = true;
|
||||
}
|
||||
|
||||
void ChangePorts()
|
||||
{
|
||||
m_previewMaterialPassId = 0;
|
||||
}
|
||||
|
||||
public override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
m_UseTileScaleId = Shader.PropertyToID( UseTileScaleStr );
|
||||
m_TileScaleId = Shader.PropertyToID( TileScaleStr );
|
||||
m_MinkowskiPowerId = Shader.PropertyToID( MinkowskiPowerStr );
|
||||
m_DistFuncId = Shader.PropertyToID( DistFuncStr );
|
||||
m_MethodTypeId = Shader.PropertyToID( MethodTypeStr );
|
||||
m_SearchQualityId = Shader.PropertyToID( SearchQualityStr );
|
||||
m_OctavesId = Shader.PropertyToID( OctavesStr );
|
||||
m_UseSmoothnessId = Shader.PropertyToID( UseSmoothnessStr );
|
||||
}
|
||||
|
||||
public override void SetPreviewInputs()
|
||||
{
|
||||
base.SetPreviewInputs();
|
||||
|
||||
if( m_cachedUvsId == -1 )
|
||||
m_cachedUvsId = Shader.PropertyToID( "_CustomUVs" );
|
||||
|
||||
PreviewMaterial.SetInt( m_cachedUvsId, ( m_inputPorts[ 0 ].IsConnected ? 1 : 0 ) );
|
||||
|
||||
m_previewMaterialPassId = m_useUnity ? 0 : 1;
|
||||
if( !m_useUnity )
|
||||
{
|
||||
PreviewMaterial.SetInt( m_SearchQualityId, m_searchQuality + 1 );
|
||||
|
||||
if( m_functionType == 4)
|
||||
{
|
||||
PreviewMaterial.SetInt( m_DistFuncId, 0 );
|
||||
} else
|
||||
{
|
||||
PreviewMaterial.SetInt( m_DistFuncId, m_distanceFunction );
|
||||
}
|
||||
|
||||
if( m_distanceFunction == 4 )
|
||||
{
|
||||
PreviewMaterial.SetFloat( m_MinkowskiPowerId, m_minkowskiPower );
|
||||
}
|
||||
|
||||
PreviewMaterial.SetInt( m_MethodTypeId, m_functionType );
|
||||
int smoothnessValue = m_calculateSmoothValue ? 1 : 0;
|
||||
PreviewMaterial.SetInt( m_UseSmoothnessId, smoothnessValue );
|
||||
|
||||
PreviewMaterial.SetFloat( m_UseTileScaleId, m_tileable ? 1.0f : 0.0f );
|
||||
|
||||
if( m_tileable )
|
||||
PreviewMaterial.SetInt( m_TileScaleId, m_tileScale );
|
||||
|
||||
PreviewMaterial.SetInt( m_OctavesId, m_octaves );
|
||||
}
|
||||
}
|
||||
|
||||
public override void RenderNodePreview()
|
||||
{
|
||||
//Runs at least one time
|
||||
if( !m_initialized )
|
||||
{
|
||||
// nodes with no preview don't update at all
|
||||
PreviewIsDirty = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !PreviewIsDirty )
|
||||
return;
|
||||
|
||||
SetPreviewInputs();
|
||||
|
||||
RenderTexture temp = RenderTexture.active;
|
||||
|
||||
RenderTexture.active = m_outputPorts[ 0 ].OutputPreviewTexture;
|
||||
PreviewMaterial.SetInt( "_PreviewID", 0 );
|
||||
Graphics.Blit( null, m_outputPorts[ 0 ].OutputPreviewTexture, PreviewMaterial, m_previewMaterialPassId );
|
||||
|
||||
RenderTexture.active = m_outputPorts[ 1 ].OutputPreviewTexture;
|
||||
PreviewMaterial.SetInt( "_PreviewID", 1 );
|
||||
Graphics.Blit( null, m_outputPorts[ 1 ].OutputPreviewTexture, PreviewMaterial, m_previewMaterialPassId );
|
||||
|
||||
RenderTexture.active = m_outputPorts[ 2 ].OutputPreviewTexture;
|
||||
PreviewMaterial.SetInt( "_PreviewID", 2 );
|
||||
Graphics.Blit( null, m_outputPorts[ 2 ].OutputPreviewTexture, PreviewMaterial, m_previewMaterialPassId );
|
||||
RenderTexture.active = temp;
|
||||
|
||||
PreviewIsDirty = m_continuousPreviewRefresh;
|
||||
|
||||
FinishPreviewRender = true;
|
||||
}
|
||||
|
||||
public override void DrawProperties()
|
||||
{
|
||||
base.DrawProperties();
|
||||
EditorGUI.BeginChangeCheck();
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup( m_useUnity );
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_functionType = EditorGUILayoutPopup( FunctionTypeStr, m_functionType, m_functionTypeStr );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
{
|
||||
ChechSmoothPorts();
|
||||
}
|
||||
|
||||
EditorGUI.BeginDisabledGroup( m_functionType == 4 );
|
||||
m_distanceFunction = EditorGUILayoutPopup( DistanceFunctionLabelStr, m_distanceFunction, m_distanceFunctionStr );
|
||||
if( m_distanceFunction == 4 )
|
||||
{
|
||||
m_minkowskiPower = EditorGUILayoutSlider( "Minkowski Power", m_minkowskiPower, 1, 5 );
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
m_searchQuality = EditorGUILayoutPopup( SearchQualityLabelStr, m_searchQuality, m_searchQualityStr );
|
||||
m_octaves = EditorGUILayoutIntSlider( "Octaves", m_octaves, 1, 8 );
|
||||
m_tileable = EditorGUILayoutToggle( "Tileable", m_tileable );
|
||||
EditorGUI.BeginDisabledGroup( !m_tileable );
|
||||
m_tileScale = EditorGUILayoutIntField( "Tile Scale", m_tileScale );
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
//Only smoothing cells type for now
|
||||
if( m_functionType == 0 )
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_calculateSmoothValue = EditorGUILayoutToggle( "Smooth", m_calculateSmoothValue );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
{
|
||||
ChechSmoothPorts();
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_useUnity = EditorGUILayoutToggle( "Unity's Voronoi", m_useUnity );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
{
|
||||
ChangePorts();
|
||||
ChechSmoothPorts();
|
||||
}
|
||||
}
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
{
|
||||
PreviewIsDirty = true;
|
||||
}
|
||||
|
||||
NodeUtils.DrawPropertyGroup( ref m_internalDataFoldout, Constants.InternalDataLabelStr, () =>
|
||||
{
|
||||
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<F1 ) {";
|
||||
VoronoiBody[ 13 ] = " //\t\t\tF2 = F1;";
|
||||
VoronoiBody[ 14 ] = " \t\t\tfloat h = smoothstep(0.0, 1.0, 0.5 + 0.5 * (F1 - d) / smoothness); F1 = lerp(F1, d, h) - smoothness * h * (1.0 - h);mg = g; mr = r; id = o;";
|
||||
VoronoiBody[ 15 ] = " //\t\t} else if( d<F2 ) {";
|
||||
VoronoiBody[ 16 ] = " //\t\t\tF2 = d;";
|
||||
VoronoiBody[ 17 ] = " //\t\t}";
|
||||
}
|
||||
else
|
||||
{
|
||||
VoronoiBody[ 12 ] = " \t\tif( d<F1 ) {";
|
||||
VoronoiBody[ 13 ] = " \t\t\tF2 = F1;";
|
||||
VoronoiBody[ 14 ] = " \t\t\tF1 = d; mg = g; mr = r; id = o;";
|
||||
VoronoiBody[ 15 ] = " \t\t} else if( d<F2 ) {";
|
||||
VoronoiBody[ 16 ] = " \t\t\tF2 = d;";
|
||||
VoronoiBody[ 17 ] = " \t\t}";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
VoronoiBody[ 12 ] = " \t\tif( d<F1 ) {";
|
||||
VoronoiBody[ 13 ] = " \t\t\tF2 = F1;";
|
||||
VoronoiBody[ 14 ] = " \t\t\tF1 = d; mg = g; mr = r; id = o;";
|
||||
VoronoiBody[ 15 ] = " \t\t} else if( d<F2 ) {";
|
||||
VoronoiBody[ 16 ] = " \t\t\tF2 = d;";
|
||||
VoronoiBody[ 17 ] = " \t\t}";
|
||||
}
|
||||
|
||||
switch( m_functionType )
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
VoronoiBody[ 20 ] = "return F1;";
|
||||
break;
|
||||
case 1:
|
||||
VoronoiBody[ 20 ] = "return F2;";
|
||||
break;
|
||||
case 2:
|
||||
VoronoiBody[ 20 ] = "return F2 - F1;";
|
||||
break;
|
||||
case 3:
|
||||
VoronoiBody[ 20 ] = "return (F2 + F1) * 0.5;";
|
||||
break;
|
||||
case 4:
|
||||
VoronoiBody[ 20 ] = string.Format( VoronoiDistanceBody , VoronoiBody[ 10 ], OutputId );
|
||||
break;
|
||||
}
|
||||
|
||||
if( m_tileable )
|
||||
{
|
||||
|
||||
VoronoiHashBody[ 0 ] = "p = p - " + m_tileScale + " * floor( p / " + m_tileScale + " );";
|
||||
}
|
||||
else
|
||||
{
|
||||
VoronoiHashBody[ 0 ] = "";
|
||||
}
|
||||
}
|
||||
|
||||
public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
|
||||
{
|
||||
if( m_outputPorts[ outputId ].IsLocalValue( dataCollector.PortCategory ) )
|
||||
{
|
||||
return m_outputPorts[ outputId ].LocalValue( dataCollector.PortCategory );
|
||||
}
|
||||
|
||||
if( m_useUnity )
|
||||
{
|
||||
string uvValue = string.Empty;
|
||||
if( m_inputPorts[ 0 ].IsConnected )
|
||||
uvValue = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
|
||||
else
|
||||
{
|
||||
if( dataCollector.IsTemplate )
|
||||
uvValue = dataCollector.TemplateDataCollectorInstance.GenerateAutoUVs( 0 );
|
||||
else
|
||||
uvValue = GeneratorUtils.GenerateAutoUVs( ref dataCollector, UniqueId, 0 );
|
||||
}
|
||||
string angleOffset = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector );
|
||||
string cellDensity = m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector );
|
||||
dataCollector.AddLocalVariable( UniqueId, string.Format( "float2 uv{0} = 0;", OutputId ) );
|
||||
dataCollector.AddFunction( UnityVoroniNoiseFunctionsBody[ 0 ], UnityVoroniNoiseFunctionsBody, false );
|
||||
string varName = "unityVoronoy" + OutputId;
|
||||
string varValue = string.Format( UnityVoronoiNoiseFunc, uvValue, angleOffset, cellDensity, "uv" + OutputId );
|
||||
dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT3, varName, varValue );
|
||||
m_outputPorts[ 0 ].SetLocalValue( varName + ".x", dataCollector.PortCategory );
|
||||
m_outputPorts[ 1 ].SetLocalValue( varName + ".yz", dataCollector.PortCategory );
|
||||
m_outputPorts[ 2 ].SetLocalValue( "uv" + OutputId, dataCollector.PortCategory );
|
||||
return m_outputPorts[ outputId ].LocalValue( dataCollector.PortCategory );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
string scaleValue = m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector );
|
||||
|
||||
string timeVarValue = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector );
|
||||
string timeVarName = "time" + OutputId;
|
||||
dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT, timeVarName, timeVarValue );
|
||||
|
||||
ChangeFunction( scaleValue );
|
||||
|
||||
string voronoiHashFunc = string.Empty;
|
||||
string VoronoiHashHeaderFormatted = string.Format( VoronoiHashHeader, OutputId );
|
||||
IOUtils.AddFunctionHeader( ref voronoiHashFunc, VoronoiHashHeaderFormatted );
|
||||
for( int i = 0; i < VoronoiHashBody.Length; i++ )
|
||||
{
|
||||
IOUtils.AddFunctionLine( ref voronoiHashFunc, VoronoiHashBody[ i ] );
|
||||
}
|
||||
IOUtils.CloseFunctionBody( ref voronoiHashFunc );
|
||||
dataCollector.AddFunction( VoronoiHashHeaderFormatted, voronoiHashFunc );
|
||||
|
||||
string smoothnessName = "0";
|
||||
if( m_calculateSmoothValue )
|
||||
{
|
||||
smoothnessName = "voronoiSmooth" + outputId;
|
||||
string smoothnessValue = m_inputPorts[ 3 ].GeneratePortInstructions( ref dataCollector );
|
||||
dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT, smoothnessName, smoothnessValue );
|
||||
}
|
||||
|
||||
string voronoiFunc = string.Empty;
|
||||
IOUtils.AddFunctionHeader( ref voronoiFunc, string.Format( VoronoiHeader, OutputId ) );
|
||||
for( int i = 0; i < VoronoiBody.Length; i++ )
|
||||
{
|
||||
if( i == 9 )
|
||||
{
|
||||
IOUtils.AddFunctionLine( ref voronoiFunc, string.Format( VoronoiBody[ i ],OutputId ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
IOUtils.AddFunctionLine( ref voronoiFunc, VoronoiBody[ i ] );
|
||||
}
|
||||
}
|
||||
IOUtils.CloseFunctionBody( ref voronoiFunc );
|
||||
dataCollector.AddFunction( string.Format( VoronoiHeader, OutputId ), voronoiFunc );
|
||||
|
||||
string uvs = string.Empty;
|
||||
if( m_inputPorts[ 0 ].IsConnected )
|
||||
uvs = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
|
||||
else
|
||||
{
|
||||
if( dataCollector.IsTemplate )
|
||||
{
|
||||
uvs = dataCollector.TemplateDataCollectorInstance.GenerateAutoUVs( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
uvs = GeneratorUtils.GenerateAutoUVs( ref dataCollector, UniqueId, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
dataCollector.AddLocalVariable( UniqueId, string.Format( "float2 coords{0} = {1} * {2};", OutputId, uvs, scaleValue ) );
|
||||
dataCollector.AddLocalVariable( UniqueId, string.Format( "float2 id{0} = 0;", OutputId ) );
|
||||
dataCollector.AddLocalVariable( UniqueId, string.Format( "float2 uv{0} = 0;", OutputId ) );
|
||||
|
||||
if( m_octaves == 1 )
|
||||
{
|
||||
dataCollector.AddLocalVariable( UniqueId, string.Format( "float voroi{0} = {1};", OutputId, string.Format( VoronoiFunc, OutputId, "coords" + OutputId,timeVarName, "id"+ OutputId, "uv" + OutputId, smoothnessName ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
dataCollector.AddLocalVariable( UniqueId, string.Format( "float fade{0} = 0.5;", OutputId ) );
|
||||
dataCollector.AddLocalVariable( UniqueId, string.Format( "float voroi{0} = 0;", OutputId ) );
|
||||
dataCollector.AddLocalVariable( UniqueId, string.Format( "float rest{0} = 0;", OutputId ) );
|
||||
dataCollector.AddLocalVariable( UniqueId, string.Format( "for( int it{0} = 0; it{0} <" + m_octaves + "; it{0}++ ){{", OutputId) );
|
||||
dataCollector.AddLocalVariable( UniqueId, string.Format( "voroi{0} += fade{0} * voronoi{0}( coords{0}, time{0}, id{0}, uv{0}, {1} );", OutputId, smoothnessName ) );
|
||||
dataCollector.AddLocalVariable( UniqueId, string.Format( "rest{0} += fade{0};", OutputId ) );
|
||||
dataCollector.AddLocalVariable( UniqueId, string.Format( "coords{0} *= 2;", OutputId ) );
|
||||
dataCollector.AddLocalVariable( UniqueId, string.Format( "fade{0} *= 0.5;", OutputId ) );
|
||||
dataCollector.AddLocalVariable( UniqueId, "}" + "//Voronoi" + OutputId );
|
||||
dataCollector.AddLocalVariable( UniqueId, string.Format( "voroi{0} /= rest{0};", OutputId ) );
|
||||
}
|
||||
m_outputPorts[ 0 ].SetLocalValue( "voroi" + OutputId, dataCollector.PortCategory );
|
||||
m_outputPorts[ 1 ].SetLocalValue( "id" + OutputId, dataCollector.PortCategory );
|
||||
m_outputPorts[ 2 ].SetLocalValue( "uv" + OutputId, dataCollector.PortCategory );
|
||||
return m_outputPorts[ outputId ].LocalValue( dataCollector.PortCategory );
|
||||
}
|
||||
}
|
||||
|
||||
public override void ReadFromString( ref string[] nodeParams )
|
||||
{
|
||||
base.ReadFromString( ref nodeParams );
|
||||
m_searchQuality = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
|
||||
m_distanceFunction = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
|
||||
m_minkowskiPower = Convert.ToSingle( GetCurrentParam( ref nodeParams ) );
|
||||
m_functionType = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
|
||||
m_octaves = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
|
||||
m_tileable = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
|
||||
m_tileScale = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
|
||||
m_useUnity = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
|
||||
if( UIUtils.CurrentShaderVersion() > 17402 )
|
||||
{
|
||||
m_calculateSmoothValue = 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3f99c25e876b164789b7612a63ec748
|
||||
timeCreated: 1566897514
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user