diff options
author | chai <chaifix@163.com> | 2020-10-23 13:08:43 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2020-10-23 13:08:43 +0800 |
commit | b82da95b5181ac8bbae38efb13e950d5e88a4caa (patch) | |
tree | 48a6f3269276484bbc7cfc95f0651f40a2176aa1 /Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/HelperFuncs/ParallaxOcclusionMappingNode.cs | |
parent | 917e9e0b320775634dc2e710f7deac74fd0822f0 (diff) |
*移动amplify shader editor到third party目录
Diffstat (limited to 'Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/HelperFuncs/ParallaxOcclusionMappingNode.cs')
-rw-r--r-- | Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/HelperFuncs/ParallaxOcclusionMappingNode.cs | 744 |
1 files changed, 744 insertions, 0 deletions
diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/HelperFuncs/ParallaxOcclusionMappingNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/HelperFuncs/ParallaxOcclusionMappingNode.cs new file mode 100644 index 00000000..a956b231 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/HelperFuncs/ParallaxOcclusionMappingNode.cs @@ -0,0 +1,744 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; + +using System; +namespace AmplifyShaderEditor +{ + enum POMTexTypes + { + Texture2D, + Texture3D, + TextureArray + }; + + [Serializable] + [NodeAttributes( "Parallax Occlusion Mapping", "UV Coordinates", "Calculates offseted UVs for parallax occlusion mapping" )] + public sealed class ParallaxOcclusionMappingNode : ParentNode + { + private const string ArrayIndexStr = "Array Index"; + private const string Tex3DSliceStr = "Tex3D Slice"; + + private readonly string[] m_channelTypeStr = { "Red Channel", "Green Channel", "Blue Channel", "Alpha Channel" }; + private readonly string[] m_channelTypeVal = { "r", "g", "b", "a" }; + + [SerializeField] + private int m_selectedChannelInt = 0; + + //[SerializeField] + //private int m_minSamples = 8; + + //[SerializeField] + //private int m_maxSamples = 16; + [SerializeField] + private InlineProperty m_inlineMinSamples = new InlineProperty( 8 ); + + [SerializeField] + private InlineProperty m_inlineMaxSamples = new InlineProperty( 16 ); + + [ SerializeField] + private int m_sidewallSteps = 2; + + [SerializeField] + private float m_defaultScale = 0.02f; + + [SerializeField] + private float m_defaultRefPlane = 0f; + + [SerializeField] + private bool m_clipEnds = false; + + [SerializeField] + private Vector2 m_tilling = new Vector2( 1, 1 ); + + [SerializeField] + private bool m_useCurvature = false; + + //[SerializeField] + //private bool m_useTextureArray = false; + [SerializeField] + private POMTexTypes m_pomTexType = POMTexTypes.Texture2D; + + //[SerializeField] + //private bool m_useCurvature = false; + + [SerializeField] + private Vector2 m_CurvatureVector = new Vector2( 0, 0 ); + + private string m_functionHeader = "POM( {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13} )"; + private string m_functionBody = string.Empty; + + //private const string WorldDirVarStr = "worldViewDir"; + + private InputPort m_uvPort; + private InputPort m_texPort; + private InputPort m_scalePort; + private InputPort m_viewdirTanPort; + private InputPort m_refPlanePort; + private InputPort m_curvaturePort; + private InputPort m_arrayIndexPort; + + private OutputPort m_pomUVPort; + + private Vector4Node m_texCoordsHelper; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT2, false, "UV" ); + AddInputPort( WirePortDataType.SAMPLER2D, false, "Tex" ); + AddInputPort( WirePortDataType.FLOAT, false, "Scale" ); + AddInputPort( WirePortDataType.FLOAT3, false, "ViewDir (tan)" ); + AddInputPort( WirePortDataType.FLOAT, false, "Ref Plane" ); + AddInputPort( WirePortDataType.FLOAT2, false, "Curvature" ); + AddInputPort( WirePortDataType.FLOAT, false, ArrayIndexStr ); + AddOutputPort( WirePortDataType.FLOAT2, "Out" ); + + m_uvPort = m_inputPorts[ 0 ]; + m_texPort = m_inputPorts[ 1 ]; + m_scalePort = m_inputPorts[ 2 ]; + m_viewdirTanPort = m_inputPorts[ 3 ]; + m_refPlanePort = m_inputPorts[ 4 ]; + m_pomUVPort = m_outputPorts[ 0 ]; + m_curvaturePort = m_inputPorts[ 5 ]; + m_arrayIndexPort = m_inputPorts[ 6 ]; + m_scalePort.FloatInternalData = 0.02f; + m_useInternalPortData = false; + m_textLabelWidth = 130; + m_autoWrapProperties = true; + m_curvaturePort.Visible = false; + m_arrayIndexPort.Visible = false; + UpdateSampler(); + } + + public override void DrawProperties() + { + base.DrawProperties(); + + EditorGUI.BeginChangeCheck(); + m_selectedChannelInt = EditorGUILayoutPopup( "Channel", m_selectedChannelInt, m_channelTypeStr ); + if ( EditorGUI.EndChangeCheck() ) + { + UpdateSampler(); + GeneratePOMfunction(); + } + EditorGUIUtility.labelWidth = 105; + + //m_minSamples = EditorGUILayoutIntSlider( "Min Samples", m_minSamples, 1, 128 ); + UndoParentNode inst = this; + m_inlineMinSamples.CustomDrawer( ref inst, ( x ) => { m_inlineMinSamples.IntValue = EditorGUILayoutIntSlider( "Min Samples", m_inlineMinSamples.IntValue, 1, 128 ); }, "Min Samples" ); + //m_maxSamples = EditorGUILayoutIntSlider( "Max Samples", m_maxSamples, 1, 128 ); + m_inlineMaxSamples.CustomDrawer( ref inst, ( x ) => { m_inlineMaxSamples.IntValue = EditorGUILayoutIntSlider( "Max Samples", m_inlineMaxSamples.IntValue, 1, 128 ); }, "Max Samples" ); + + EditorGUI.BeginChangeCheck(); + m_sidewallSteps = EditorGUILayoutIntSlider( "Sidewall Steps", m_sidewallSteps, 0, 10 ); + if ( EditorGUI.EndChangeCheck() ) + { + GeneratePOMfunction(); + } + + + EditorGUI.BeginDisabledGroup(m_scalePort.IsConnected ); + m_defaultScale = EditorGUILayoutSlider( "Default Scale", m_defaultScale, 0, 1 ); + EditorGUI.EndDisabledGroup(); + + EditorGUI.BeginDisabledGroup( m_refPlanePort.IsConnected ); + m_defaultRefPlane = EditorGUILayoutSlider( "Default Ref Plane", m_defaultRefPlane, 0, 1 ); + EditorGUI.EndDisabledGroup(); + EditorGUIUtility.labelWidth = m_textLabelWidth; + EditorGUI.BeginChangeCheck(); + //m_useTextureArray = EditorGUILayoutToggle( "Use Texture Array", m_useTextureArray ); + m_pomTexType = (POMTexTypes)EditorGUILayoutEnumPopup( "Texture Type", m_pomTexType ); + if( EditorGUI.EndChangeCheck() ) + { + UpdateIndexPort(); + m_sizeIsDirty = true; + GeneratePOMfunction(); + //UpdateCurvaturePort(); + } + + if( m_arrayIndexPort.Visible && !m_arrayIndexPort.IsConnected ) + { + m_arrayIndexPort.FloatInternalData = EditorGUILayoutFloatField( "Array Index", m_arrayIndexPort.FloatInternalData ); + } + + //float cached = EditorGUIUtility.labelWidth; + //EditorGUIUtility.labelWidth = 70; + m_clipEnds = EditorGUILayoutToggle( "Clip Edges", m_clipEnds ); + //EditorGUIUtility.labelWidth = -1; + //EditorGUIUtility.labelWidth = 100; + //EditorGUILayout.BeginHorizontal(); + //EditorGUI.BeginDisabledGroup( !m_clipEnds ); + //m_tilling = EditorGUILayout.Vector2Field( string.Empty, m_tilling ); + //EditorGUI.EndDisabledGroup(); + //EditorGUILayout.EndHorizontal(); + //EditorGUIUtility.labelWidth = cached; + + EditorGUI.BeginChangeCheck(); + m_useCurvature = EditorGUILayoutToggle( "Clip Silhouette", m_useCurvature ); + if ( EditorGUI.EndChangeCheck() ) + { + GeneratePOMfunction(); + UpdateCurvaturePort(); + } + + EditorGUI.BeginDisabledGroup( !(m_useCurvature && !m_curvaturePort.IsConnected) ); + m_CurvatureVector = EditorGUILayoutVector2Field( string.Empty, m_CurvatureVector ); + EditorGUI.EndDisabledGroup(); + + EditorGUILayout.HelpBox( "WARNING:\nTex must be connected to a Texture Object for this node to work\n\nMin and Max samples:\nControl the minimum and maximum number of layers extruded\n\nSidewall Steps:\nThe number of interpolations done to smooth the extrusion result on the side of the layer extrusions, min is used at steep angles while max is used at orthogonal angles\n\n"+ + "Ref Plane:\nReference plane lets you adjust the starting reference height, 0 = deepen ground, 1 = raise ground, any value above 0 might cause distortions at higher angles\n\n"+ + "Clip Edges:\nThis will clip the ends of your uvs to give a more 3D look at the edges. It'll use the tilling given by your Heightmap input.\n\n"+ + "Clip Silhouette:\nTurning this on allows you to use the UV coordinates to clip the effect curvature in U or V axis, useful for cylinders, works best with 'Clip Edges' turned OFF", MessageType.None ); + } + + private void UpdateIndexPort() + { + m_arrayIndexPort.Visible = m_pomTexType != POMTexTypes.Texture2D; + if( m_arrayIndexPort.Visible ) + { + m_arrayIndexPort.Name = m_pomTexType == POMTexTypes.Texture3D ? Tex3DSliceStr : ArrayIndexStr; + } + } + + private void UpdateSampler() + { + m_texPort.Name = "Tex (" + m_channelTypeVal[ m_selectedChannelInt ].ToUpper() + ")"; + } + + private void UpdateCurvaturePort() + { + if ( m_useCurvature ) + m_curvaturePort.Visible = true; + else + m_curvaturePort.Visible = false; + + m_sizeIsDirty = true; + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + if( !m_texPort.IsConnected ) + { + UIUtils.ShowMessage( UniqueId, "Parallax Occlusion Mapping node only works if a Texture Object is connected to its Tex (R) port" ); + return "0"; + } + base.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar ); + WirePortDataType texType = ( m_pomTexType == POMTexTypes.Texture3D )?WirePortDataType.SAMPLER3D: WirePortDataType.SAMPLER2D; + + GeneratePOMfunction(); + string arrayIndex = m_arrayIndexPort.Visible?m_arrayIndexPort.GeneratePortInstructions( ref dataCollector ):"0"; + string textcoords = m_uvPort.GeneratePortInstructions( ref dataCollector ); + if( m_pomTexType == POMTexTypes.Texture3D ) + { + string texName = "pomTexCoord" + OutputId; + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT3, texName, string.Format( "float3({0},{1})", textcoords, arrayIndex ) ); + textcoords = texName; + } + + string texture = m_texPort.GenerateShaderForOutput( ref dataCollector, texType,false,true ); + string scale = m_defaultScale.ToString(); + if( m_scalePort.IsConnected ) + scale = m_scalePort.GeneratePortInstructions( ref dataCollector ); + + string viewDirTan = ""; + if ( !m_viewdirTanPort.IsConnected ) + { + if ( !dataCollector.DirtyNormal ) + dataCollector.ForceNormal = true; + + + if ( dataCollector.IsTemplate ) + { + viewDirTan = dataCollector.TemplateDataCollectorInstance.GetTangentViewDir( CurrentPrecisionType ); + } + else + { + viewDirTan = GeneratorUtils.GenerateViewDirection( ref dataCollector, UniqueId, ViewSpace.Tangent ); + //dataCollector.AddToInput( UniqueId, SurfaceInputs.VIEW_DIR, m_currentPrecisionType ); + //viewDirTan = Constants.InputVarStr + "." + UIUtils.GetInputValueFromType( SurfaceInputs.VIEW_DIR ); + } + } + else + { + viewDirTan = m_viewdirTanPort.GeneratePortInstructions( ref dataCollector ); + } + + //generate world normal + string normalWorld = string.Empty; + if ( dataCollector.IsTemplate ) + { + normalWorld = dataCollector.TemplateDataCollectorInstance.GetWorldNormal( CurrentPrecisionType ); + } + else + { + dataCollector.AddToInput( UniqueId, SurfaceInputs.WORLD_NORMAL, CurrentPrecisionType ); + dataCollector.AddToInput( UniqueId, SurfaceInputs.INTERNALDATA, addSemiColon: false ); + normalWorld = GeneratorUtils.GenerateWorldNormal( ref dataCollector, UniqueId ); + } + + //string normalWorld = "WorldNormalVector( " + Constants.InputVarStr + ", float3( 0, 0, 1 ) )"; + + //generate viewDir in world space + + //string worldPos = string.Empty; + //if( dataCollector.IsTemplate ) + //{ + // worldPos = dataCollector.TemplateDataCollectorInstance.GetWorldPos(); + //} + //else + //{ + // dataCollector.AddToInput( UniqueId, SurfaceInputs.WORLD_POS ); + // worldPos = Constants.InputVarStr + ".worldPos"; + //} + + //if( !dataCollector.IsTemplate ) + // dataCollector.AddToInput( UniqueId, SurfaceInputs.WORLD_POS ); + + string worldViewDir = GeneratorUtils.GenerateViewDirection( ref dataCollector, UniqueId, ViewSpace.World ); + //dataCollector.AddToLocalVariables( UniqueId, m_currentPrecisionType, WirePortDataType.FLOAT3, WorldDirVarStr, TemplateHelperFunctions.WorldSpaceViewDir( dataCollector, worldPos, true ) ); + string dx = "ddx("+ textcoords + ")"; + string dy = "ddy(" + textcoords + ")"; + + string refPlane = m_defaultRefPlane.ToString(); + if ( m_refPlanePort.IsConnected ) + refPlane = m_refPlanePort.GeneratePortInstructions( ref dataCollector ); + + + string curvature = "float2("+ m_CurvatureVector.x + "," + m_CurvatureVector.y + ")"; + if ( m_useCurvature ) + { + dataCollector.AddToProperties( UniqueId, "[Header(Parallax Occlusion Mapping)]", 300 ); + dataCollector.AddToProperties( UniqueId, "_CurvFix(\"Curvature Bias\", Range( 0 , 1)) = 1", 301 ); + dataCollector.AddToUniforms( UniqueId, "uniform float _CurvFix;" ); + + if ( m_curvaturePort.IsConnected ) + curvature = m_curvaturePort.GeneratePortInstructions( ref dataCollector ); + } + + + string localVarName = "OffsetPOM" + OutputId; + string textCoordsST = string.Empty; + //string textureSTType = dataCollector.IsSRP ? "float4 " : "uniform float4 "; + //dataCollector.AddToUniforms( UniqueId, textureSTType + texture +"_ST;"); + if( m_texCoordsHelper == null ) + { + m_texCoordsHelper = CreateInstance<Vector4Node>(); + m_texCoordsHelper.ContainerGraph = ContainerGraph; + m_texCoordsHelper.SetBaseUniqueId( UniqueId, true ); + m_texCoordsHelper.RegisterPropertyOnInstancing = false; + m_texCoordsHelper.AddGlobalToSRPBatcher = true; + } + + if( UIUtils.CurrentWindow.OutsideGraph.IsInstancedShader ) + { + m_texCoordsHelper.CurrentParameterType = PropertyType.InstancedProperty; + } + else + { + m_texCoordsHelper.CurrentParameterType = PropertyType.Global; + } + m_texCoordsHelper.ResetOutputLocals(); + m_texCoordsHelper.SetRawPropertyName( texture + "_ST" ); + textCoordsST = m_texCoordsHelper.GenerateShaderForOutput( 0, ref dataCollector, false ); + ////// + + if( m_pomTexType == POMTexTypes.TextureArray ) + dataCollector.UsingArrayDerivatives = true; + string textureArgs = string.Empty; + if( m_pomTexType == POMTexTypes.TextureArray ) + { + if( UIUtils.CurrentWindow.OutsideGraph.IsSRP ) + { + textureArgs = "TEXTURE2D_ARRAY_ARGS( " + texture + ", sampler" + texture + ")"; + } + else + { + textureArgs = "UNITY_PASS_TEX2DARRAY(" + texture + ")"; + } + } + else + { + bool sampleThroughMacros = UIUtils.CurrentWindow.OutsideGraph.SamplingThroughMacros; + if( sampleThroughMacros ) + { + dataCollector.AddToUniforms( UniqueId, string.Format( Constants.SamplerDeclarationSRPMacros[ TextureType.Texture2D ], texture ) ); + textureArgs = string.Format( "{0},sampler{0}", texture ); + } + else + { + textureArgs = texture; + } + } + //string functionResult = dataCollector.AddFunctions( m_functionHeader, m_functionBody, ( (m_pomTexType == POMTexTypes.TextureArray) ? "UNITY_PASS_TEX2DARRAY(" + texture + ")": texture), textcoords, dx, dy, normalWorld, worldViewDir, viewDirTan, m_minSamples, m_maxSamples, scale, refPlane, texture+"_ST.xy", curvature, arrayIndex ); + string functionResult = dataCollector.AddFunctions( m_functionHeader, m_functionBody, textureArgs, textcoords, dx, dy, normalWorld, worldViewDir, viewDirTan, m_inlineMinSamples.GetValueOrProperty(false), m_inlineMinSamples.GetValueOrProperty(false), scale, refPlane, textCoordsST + ".xy", curvature, arrayIndex ); + + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, m_pomUVPort.DataType, localVarName, functionResult ); + + return GetOutputVectorItem( 0, outputId, localVarName ); + } + + private void GeneratePOMfunction() + { + bool sampleThroughMacros = UIUtils.CurrentWindow.OutsideGraph.SamplingThroughMacros; + m_functionBody = string.Empty; + switch( m_pomTexType ) + { + default: + case POMTexTypes.Texture2D: + { + string sampleParam = sampleThroughMacros ? "TEXTURE2D_PARAM(heightMap,samplerheightMap)" : "sampler2D heightMap"; + IOUtils.AddFunctionHeader( ref m_functionBody, string.Format("inline float2 POM( {0}, float2 uvs, float2 dx, float2 dy, float3 normalWorld, float3 viewWorld, float3 viewDirTan, int minSamples, int maxSamples, float parallax, float refPlane, float2 tilling, float2 curv, int index )", sampleParam )); + } + break; + case POMTexTypes.Texture3D: + { + string sampleParam = sampleThroughMacros ? "TEXTURE3D_PARAM( heightMap,samplerheightMap) " : "sampler3D heightMap"; + IOUtils.AddFunctionHeader( ref m_functionBody, string.Format("inline float2 POM( {0}, float3 uvs, float3 dx, float3 dy, float3 normalWorld, float3 viewWorld, float3 viewDirTan, int minSamples, int maxSamples, float parallax, float refPlane, float2 tilling, float2 curv, int index )", sampleParam ) ); + } + break; + case POMTexTypes.TextureArray: + if( UIUtils.CurrentWindow.OutsideGraph.IsSRP ) + IOUtils.AddFunctionHeader( ref m_functionBody, "inline float2 POM( TEXTURE2D_ARRAY_PARAM(heightMap,samplerheightMap), float2 uvs, float2 dx, float2 dy, float3 normalWorld, float3 viewWorld, float3 viewDirTan, int minSamples, int maxSamples, float parallax, float refPlane, float2 tilling, float2 curv, int index )" ); + else + IOUtils.AddFunctionHeader( ref m_functionBody, "inline float2 POM( UNITY_ARGS_TEX2DARRAY(heightMap), float2 uvs, float2 dx, float2 dy, float3 normalWorld, float3 viewWorld, float3 viewDirTan, int minSamples, int maxSamples, float parallax, float refPlane, float2 tilling, float2 curv, int index )" ); + break; + } + + IOUtils.AddFunctionLine( ref m_functionBody, "float3 result = 0;" ); + IOUtils.AddFunctionLine( ref m_functionBody, "int stepIndex = 0;" ); + //IOUtils.AddFunctionLine( ref m_functionBody, "int numSteps = ( int )( minSamples + dot( viewWorld, normalWorld ) * ( maxSamples - minSamples ) );" ); + //IOUtils.AddFunctionLine( ref m_functionBody, "int numSteps = ( int )lerp( maxSamples, minSamples, length( fwidth( uvs ) ) * 10 );" ); + IOUtils.AddFunctionLine( ref m_functionBody, "int numSteps = ( int )lerp( (float)maxSamples, (float)minSamples, saturate( dot( normalWorld, viewWorld ) ) );" ); + IOUtils.AddFunctionLine( ref m_functionBody, "float layerHeight = 1.0 / numSteps;" ); + IOUtils.AddFunctionLine( ref m_functionBody, "float2 plane = parallax * ( viewDirTan.xy / viewDirTan.z );" ); + + switch( m_pomTexType ) + { + default: + case POMTexTypes.Texture2D: + IOUtils.AddFunctionLine( ref m_functionBody, "uvs += refPlane * plane;" ); + break; + case POMTexTypes.Texture3D: + IOUtils.AddFunctionLine( ref m_functionBody, "uvs.xy += refPlane * plane;" ); + break; + case POMTexTypes.TextureArray: + IOUtils.AddFunctionLine( ref m_functionBody, "uvs += refPlane * plane;" ); + break; + } + + IOUtils.AddFunctionLine( ref m_functionBody, "float2 deltaTex = -plane * layerHeight;" ); + IOUtils.AddFunctionLine( ref m_functionBody, "float2 prevTexOffset = 0;" ); + IOUtils.AddFunctionLine( ref m_functionBody, "float prevRayZ = 1.0f;" ); + IOUtils.AddFunctionLine( ref m_functionBody, "float prevHeight = 0.0f;" ); + IOUtils.AddFunctionLine( ref m_functionBody, "float2 currTexOffset = deltaTex;" ); + IOUtils.AddFunctionLine( ref m_functionBody, "float currRayZ = 1.0f - layerHeight;" ); + IOUtils.AddFunctionLine( ref m_functionBody, "float currHeight = 0.0f;" ); + IOUtils.AddFunctionLine( ref m_functionBody, "float intersection = 0;" ); + IOUtils.AddFunctionLine( ref m_functionBody, "float2 finalTexOffset = 0;" ); + IOUtils.AddFunctionLine( ref m_functionBody, "while ( stepIndex < numSteps + 1 )" ); + IOUtils.AddFunctionLine( ref m_functionBody, "{" ); + if( m_useCurvature ) + { + IOUtils.AddFunctionLine( ref m_functionBody, " result.z = dot( curv, currTexOffset * currTexOffset );" ); + + + switch( m_pomTexType ) + { + default: + case POMTexTypes.Texture2D: + { + if( sampleThroughMacros ) + { + IOUtils.AddFunctionLine( ref m_functionBody, " currHeight = SAMPLE_TEXTURE2D_GRAD( heightMap, samplerheightMap, uvs + currTexOffset, dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + " * ( 1 - result.z );" ); + } + else + { + IOUtils.AddFunctionLine( ref m_functionBody, " currHeight = tex2Dgrad( heightMap, uvs + currTexOffset, dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + " * ( 1 - result.z );" ); + } + } + break; + case POMTexTypes.Texture3D: + { + if( sampleThroughMacros ) + { + IOUtils.AddFunctionLine( ref m_functionBody, " currHeight = SAMPLE_TEXTURE2D_GRAD( heightMap, samplerheightMap, uvs + float3(currTexOffset,0), dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + " * ( 1 - result.z );" ); + } + else + { + IOUtils.AddFunctionLine( ref m_functionBody, " currHeight = tex3Dgrad( heightMap, uvs + float3(currTexOffset,0), dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + " * ( 1 - result.z );" ); + } + } + break; + case POMTexTypes.TextureArray: + if( UIUtils.CurrentWindow.OutsideGraph.IsSRP ) + IOUtils.AddFunctionLine( ref m_functionBody, " currHeight = SAMPLE_TEXTURE2D_ARRAY_GRAD( heightMap,samplerheightMap, uvs + currTexOffset,index, dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + " * ( 1 - result.z );" ); + else + IOUtils.AddFunctionLine( ref m_functionBody, " currHeight = ASE_SAMPLE_TEX2DARRAY_GRAD( heightMap, float3(uvs + currTexOffset,index), dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + " * ( 1 - result.z );" ); + break; + } + + } + else + { + switch( m_pomTexType ) + { + default: + case POMTexTypes.Texture2D: + { + if( sampleThroughMacros ) + { + IOUtils.AddFunctionLine( ref m_functionBody, " currHeight = SAMPLE_TEXTURE2D_GRAD( heightMap,samplerheightMap, uvs + currTexOffset, dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + ";" ); + } + else + { + IOUtils.AddFunctionLine( ref m_functionBody, " currHeight = tex2Dgrad( heightMap, uvs + currTexOffset, dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + ";" ); + } + } + break; + case POMTexTypes.Texture3D: + { + if( sampleThroughMacros ) + { + IOUtils.AddFunctionLine( ref m_functionBody, " currHeight = SAMPLE_TEXTURE2D_GRAD( heightMap, samplerheightMap, uvs + float3(currTexOffset,0), dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + ";" ); + } + else + { + IOUtils.AddFunctionLine( ref m_functionBody, " currHeight = tex3Dgrad( heightMap, uvs + float3(currTexOffset,0), dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + ";" ); + } + } + break; + case POMTexTypes.TextureArray: + if( UIUtils.CurrentWindow.OutsideGraph.IsSRP ) + IOUtils.AddFunctionLine( ref m_functionBody, " currHeight = SAMPLE_TEXTURE2D_ARRAY_GRAD( heightMap, samplerheightMap, uvs + currTexOffset,index, dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + ";" ); + else + IOUtils.AddFunctionLine( ref m_functionBody, " currHeight = ASE_SAMPLE_TEX2DARRAY_GRAD( heightMap, float3(uvs + currTexOffset,index), dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + ";" ); + break; + } + } + IOUtils.AddFunctionLine( ref m_functionBody, " if ( currHeight > currRayZ )" ); + IOUtils.AddFunctionLine( ref m_functionBody, " {" ); + IOUtils.AddFunctionLine( ref m_functionBody, " stepIndex = numSteps + 1;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " }" ); + IOUtils.AddFunctionLine( ref m_functionBody, " else" ); + IOUtils.AddFunctionLine( ref m_functionBody, " {" ); + IOUtils.AddFunctionLine( ref m_functionBody, " stepIndex++;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " prevTexOffset = currTexOffset;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " prevRayZ = currRayZ;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " prevHeight = currHeight;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " currTexOffset += deltaTex;" ); + if ( m_useCurvature ) + IOUtils.AddFunctionLine( ref m_functionBody, " currRayZ -= layerHeight * ( 1 - result.z ) * (1+_CurvFix);" ); + else + IOUtils.AddFunctionLine( ref m_functionBody, " currRayZ -= layerHeight;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " }" ); + IOUtils.AddFunctionLine( ref m_functionBody, "}" ); + + if ( m_sidewallSteps > 0 ) + { + IOUtils.AddFunctionLine( ref m_functionBody, "int sectionSteps = " + m_sidewallSteps + ";" ); + IOUtils.AddFunctionLine( ref m_functionBody, "int sectionIndex = 0;" ); + IOUtils.AddFunctionLine( ref m_functionBody, "float newZ = 0;" ); + IOUtils.AddFunctionLine( ref m_functionBody, "float newHeight = 0;" ); + IOUtils.AddFunctionLine( ref m_functionBody, "while ( sectionIndex < sectionSteps )" ); + IOUtils.AddFunctionLine( ref m_functionBody, "{" ); + IOUtils.AddFunctionLine( ref m_functionBody, " intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );" ); + IOUtils.AddFunctionLine( ref m_functionBody, " finalTexOffset = prevTexOffset + intersection * deltaTex;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " newZ = prevRayZ - intersection * layerHeight;" ); + + switch( m_pomTexType ) + { + default: + case POMTexTypes.Texture2D: + { + if( sampleThroughMacros ) + { + IOUtils.AddFunctionLine( ref m_functionBody, " newHeight = SAMPLE_TEXTURE2D_GRAD( heightMap, samplerheightMap, uvs + finalTexOffset, dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + ";" ); + } + else + { + IOUtils.AddFunctionLine( ref m_functionBody, " newHeight = tex2Dgrad( heightMap, uvs + finalTexOffset, dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + ";" ); + } + } + break; + case POMTexTypes.Texture3D: + { + if( sampleThroughMacros ) + { + IOUtils.AddFunctionLine( ref m_functionBody, " newHeight = SAMPLE_TEXTURE2D_GRAD( heightMap, samplerheightMap, uvs + float3(finalTexOffset,0), dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + ";" ); + } + else + { + IOUtils.AddFunctionLine( ref m_functionBody, " newHeight = tex3Dgrad( heightMap, uvs + float3(finalTexOffset,0), dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + ";" ); + } + } + break; + case POMTexTypes.TextureArray: + if( UIUtils.CurrentWindow.OutsideGraph.IsSRP ) + IOUtils.AddFunctionLine( ref m_functionBody, " newHeight = SAMPLE_TEXTURE2D_ARRAY_GRAD( heightMap, samplerheightMap, uvs + finalTexOffset,index, dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + ";" ); + else + IOUtils.AddFunctionLine( ref m_functionBody, " newHeight = ASE_SAMPLE_TEX2DARRAY_GRAD( heightMap, float3(uvs + finalTexOffset,index), dx, dy )." + m_channelTypeVal[ m_selectedChannelInt ] + ";" ); + break; + } + + IOUtils.AddFunctionLine( ref m_functionBody, " if ( newHeight > newZ )" ); + IOUtils.AddFunctionLine( ref m_functionBody, " {" ); + IOUtils.AddFunctionLine( ref m_functionBody, " currTexOffset = finalTexOffset;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " currHeight = newHeight;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " currRayZ = newZ;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " deltaTex = intersection * deltaTex;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " layerHeight = intersection * layerHeight;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " }" ); + IOUtils.AddFunctionLine( ref m_functionBody, " else" ); + IOUtils.AddFunctionLine( ref m_functionBody, " {" ); + IOUtils.AddFunctionLine( ref m_functionBody, " prevTexOffset = finalTexOffset;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " prevHeight = newHeight;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " prevRayZ = newZ;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " deltaTex = ( 1 - intersection ) * deltaTex;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " layerHeight = ( 1 - intersection ) * layerHeight;" ); + IOUtils.AddFunctionLine( ref m_functionBody, " }" ); + IOUtils.AddFunctionLine( ref m_functionBody, " sectionIndex++;" ); + IOUtils.AddFunctionLine( ref m_functionBody, "}" ); + } + else + { + IOUtils.AddFunctionLine( ref m_functionBody, "finalTexOffset = currTexOffset;" ); + } + + if ( m_useCurvature ) + { + IOUtils.AddFunctionLine( ref m_functionBody, "#ifdef UNITY_PASS_SHADOWCASTER" ); + IOUtils.AddFunctionLine( ref m_functionBody, "if ( unity_LightShadowBias.z == 0.0 )" ); + IOUtils.AddFunctionLine( ref m_functionBody, "{" ); + IOUtils.AddFunctionLine( ref m_functionBody, "#endif" ); + IOUtils.AddFunctionLine( ref m_functionBody, " if ( result.z > 1 )" ); + IOUtils.AddFunctionLine( ref m_functionBody, " clip( -1 );" ); + IOUtils.AddFunctionLine( ref m_functionBody, "#ifdef UNITY_PASS_SHADOWCASTER" ); + IOUtils.AddFunctionLine( ref m_functionBody, "}" ); + IOUtils.AddFunctionLine( ref m_functionBody, "#endif" ); + } + + if ( m_clipEnds ) + { + IOUtils.AddFunctionLine( ref m_functionBody, "result.xy = uvs + finalTexOffset;" ); + IOUtils.AddFunctionLine( ref m_functionBody, "#ifdef UNITY_PASS_SHADOWCASTER" ); + IOUtils.AddFunctionLine( ref m_functionBody, "if ( unity_LightShadowBias.z == 0.0 )" ); + IOUtils.AddFunctionLine( ref m_functionBody, "{" ); + IOUtils.AddFunctionLine( ref m_functionBody, "#endif" ); + IOUtils.AddFunctionLine( ref m_functionBody, " if ( result.x < 0 )" ); + IOUtils.AddFunctionLine( ref m_functionBody, " clip( -1 );" ); + IOUtils.AddFunctionLine( ref m_functionBody, " if ( result.x > tilling.x )" ); + IOUtils.AddFunctionLine( ref m_functionBody, " clip( -1 );" ); + IOUtils.AddFunctionLine( ref m_functionBody, " if ( result.y < 0 )" ); + IOUtils.AddFunctionLine( ref m_functionBody, " clip( -1 );" ); + IOUtils.AddFunctionLine( ref m_functionBody, " if ( result.y > tilling.y )" ); + IOUtils.AddFunctionLine( ref m_functionBody, " clip( -1 );" ); + IOUtils.AddFunctionLine( ref m_functionBody, "#ifdef UNITY_PASS_SHADOWCASTER" ); + IOUtils.AddFunctionLine( ref m_functionBody, "}" ); + IOUtils.AddFunctionLine( ref m_functionBody, "#endif" ); + IOUtils.AddFunctionLine( ref m_functionBody, "return result.xy;" ); + } + else + { + IOUtils.AddFunctionLine( ref m_functionBody, "return uvs + finalTexOffset;" ); + } + IOUtils.CloseFunctionBody( ref m_functionBody ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + m_selectedChannelInt = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + //m_minSamples = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + //m_maxSamples = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + if( UIUtils.CurrentShaderVersion() < 15406 ) + { + m_inlineMinSamples.IntValue = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_inlineMaxSamples.IntValue = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + else + { + m_inlineMinSamples.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + m_inlineMaxSamples.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + m_sidewallSteps = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_defaultScale = Convert.ToSingle( GetCurrentParam( ref nodeParams ) ); + m_defaultRefPlane = Convert.ToSingle( GetCurrentParam( ref nodeParams ) ); + if ( UIUtils.CurrentShaderVersion() > 3001 ) + { + m_clipEnds = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + string[] vector2Component = GetCurrentParam( ref nodeParams ).Split( IOUtils.VECTOR_SEPARATOR ); + if ( vector2Component.Length == 2 ) + { + m_tilling.x = Convert.ToSingle( vector2Component[ 0 ] ); + m_tilling.y = Convert.ToSingle( vector2Component[ 1 ] ); + } + } + + if ( UIUtils.CurrentShaderVersion() > 5005 ) + { + m_useCurvature = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + m_CurvatureVector = IOUtils.StringToVector2( GetCurrentParam( ref nodeParams ) ); + } + + if( UIUtils.CurrentShaderVersion() > 13103 ) + { + if( UIUtils.CurrentShaderVersion() < 15307 ) + { + bool arrayIndexVisible = false; + arrayIndexVisible = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + m_pomTexType = arrayIndexVisible ? POMTexTypes.TextureArray : POMTexTypes.Texture2D; + } + else + { + m_pomTexType = (POMTexTypes)Enum.Parse( typeof(POMTexTypes), GetCurrentParam( ref nodeParams ) ); + } + + UpdateIndexPort(); + } + + UpdateSampler(); + GeneratePOMfunction(); + UpdateCurvaturePort(); + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_selectedChannelInt ); + //IOUtils.AddFieldValueToString( ref nodeInfo, m_minSamples ); + //IOUtils.AddFieldValueToString( ref nodeInfo, m_maxSamples ); + m_inlineMinSamples.WriteToString( ref nodeInfo ); + m_inlineMaxSamples.WriteToString( ref nodeInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_sidewallSteps ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_defaultScale ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_defaultRefPlane ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_clipEnds ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_tilling.x.ToString() + IOUtils.VECTOR_SEPARATOR + m_tilling.y.ToString() ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_useCurvature ); + IOUtils.AddFieldValueToString( ref nodeInfo, IOUtils.Vector2ToString( m_CurvatureVector ) ); + //IOUtils.AddFieldValueToString( ref nodeInfo, m_useTextureArray ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_pomTexType); + } + + public override void Destroy() + { + base.Destroy(); + //Not calling m_texCoordsHelper.Destroy() on purpose so UIUtils does not incorrectly unregister stuff + if( m_texCoordsHelper != null ) + { + DestroyImmediate( m_texCoordsHelper ); + m_texCoordsHelper = null; + } + + + m_uvPort = null; + m_texPort = null; + m_scalePort = null; + m_viewdirTanPort = null; + m_pomUVPort = null; + } + } +} |