3334 lines
133 KiB
C#
3334 lines
133 KiB
C#
// Amplify Shader Editor - Visual Shader Editing Tool
|
|
// Copyright (c) Amplify Creations, Lda <info@amplify.pt>
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
using UnityEditorInternal;
|
|
|
|
namespace AmplifyShaderEditor
|
|
{
|
|
public enum VertexMode
|
|
{
|
|
Relative,
|
|
Absolute
|
|
}
|
|
|
|
public enum RenderPath
|
|
{
|
|
All,
|
|
ForwardOnly,
|
|
DeferredOnly
|
|
}
|
|
|
|
public enum StandardShaderLightModel
|
|
{
|
|
Standard,
|
|
StandardSpecular,
|
|
Lambert,
|
|
BlinnPhong,
|
|
Unlit,
|
|
CustomLighting
|
|
}
|
|
|
|
public enum CullMode
|
|
{
|
|
Back,
|
|
Front,
|
|
Off
|
|
}
|
|
|
|
public enum AlphaMode
|
|
{
|
|
Opaque = 0,
|
|
Masked = 1,
|
|
Transparent = 2, // Transparent (alpha:fade)
|
|
Translucent = 3,
|
|
Premultiply = 4, // Alpha Premul (alpha:premul)
|
|
Custom = 5,
|
|
}
|
|
|
|
public enum DisableBatching
|
|
{
|
|
True,
|
|
False,
|
|
LODFading
|
|
}
|
|
|
|
public enum RenderType
|
|
{
|
|
Opaque,
|
|
Transparent,
|
|
TransparentCutout,
|
|
Background,
|
|
Overlay,
|
|
TreeOpaque,
|
|
TreeTransparentCutout,
|
|
TreeBillboard,
|
|
Grass,
|
|
GrassBillboard,
|
|
Custom
|
|
}
|
|
|
|
public enum RenderQueue
|
|
{
|
|
Background,
|
|
Geometry,
|
|
AlphaTest,
|
|
Transparent,
|
|
Overlay
|
|
}
|
|
|
|
public enum RenderPlatforms
|
|
{
|
|
d3d9,
|
|
d3d11,
|
|
glcore,
|
|
gles,
|
|
gles3,
|
|
metal,
|
|
d3d11_9x,
|
|
xbox360,
|
|
xboxone,
|
|
ps4,
|
|
psp2,
|
|
n3ds,
|
|
wiiu,
|
|
vulkan,
|
|
all
|
|
}
|
|
|
|
[Serializable]
|
|
public class NodeCache
|
|
{
|
|
public int TargetNodeId = -1;
|
|
public int TargetPortId = -1;
|
|
|
|
public NodeCache( int targetNodeId, int targetPortId )
|
|
{
|
|
SetData( targetNodeId, targetPortId );
|
|
}
|
|
|
|
public void SetData( int targetNodeId, int targetPortId )
|
|
{
|
|
TargetNodeId = targetNodeId;
|
|
TargetPortId = targetPortId;
|
|
}
|
|
|
|
public void Invalidate()
|
|
{
|
|
TargetNodeId = -1;
|
|
TargetPortId = -1;
|
|
}
|
|
|
|
public bool IsValid
|
|
{
|
|
get { return ( TargetNodeId >= 0 ); }
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return "TargetNodeId " + TargetNodeId + " TargetPortId " + TargetPortId;
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
public class CacheNodeConnections
|
|
{
|
|
public Dictionary<string, List<NodeCache>> NodeCacheArray;
|
|
|
|
public CacheNodeConnections()
|
|
{
|
|
NodeCacheArray = new Dictionary<string, List<NodeCache>>();
|
|
}
|
|
|
|
public void Add( string key, NodeCache value )
|
|
{
|
|
if( NodeCacheArray.ContainsKey( key ) )
|
|
{
|
|
NodeCacheArray[ key ].Add( value );
|
|
}
|
|
else
|
|
{
|
|
NodeCacheArray.Add( key, new List<NodeCache>() );
|
|
NodeCacheArray[ key ].Add( value );
|
|
}
|
|
}
|
|
|
|
public NodeCache Get( string key, int idx = 0 )
|
|
{
|
|
if( NodeCacheArray.ContainsKey( key ) )
|
|
{
|
|
if( idx < NodeCacheArray[ key ].Count )
|
|
return NodeCacheArray[ key ][ idx ];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public List<NodeCache> GetList( string key )
|
|
{
|
|
if( NodeCacheArray.ContainsKey( key ) )
|
|
{
|
|
return NodeCacheArray[ key ];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
foreach( KeyValuePair<string, List<NodeCache>> kvp in NodeCacheArray )
|
|
{
|
|
kvp.Value.Clear();
|
|
}
|
|
NodeCacheArray.Clear();
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
[NodeAttributes( "Standard Surface Output", "Master", "Surface shader generator output", null, KeyCode.None, false )]
|
|
public sealed class StandardSurfaceOutputNode : MasterNode, ISerializationCallbackReceiver
|
|
{
|
|
private readonly static string[] VertexLitFunc = { "\t\tinline half4 LightingUnlit( SurfaceOutput s, half3 lightDir, half atten )",
|
|
"\t\t{",
|
|
"\t\t\treturn half4 ( 0, 0, 0, s.Alpha );",
|
|
"\t\t}\n"};
|
|
|
|
private readonly static string[] FadeModeOptions = { "Opaque", "Masked", "Transparent", "Translucent", "Alpha Premultipled", "Custom" };
|
|
private const string VertexModeStr = "Vertex Output";
|
|
private readonly static GUIContent RenderPathContent = new GUIContent( "Render Path", "Selects and generates passes for the supported rendering paths\nDefault: All" );
|
|
private const string ShaderModelStr = "Shader Model";
|
|
private readonly static GUIContent LightModelContent = new GUIContent( "Light Model", "Surface shader lighting model defines how the surface reflects light\nDefault: Standard" );
|
|
private readonly static GUIContent ShaderLODContent = new GUIContent( "Shader LOD", "Shader LOD" );
|
|
private readonly static GUIContent CullModeContent = new GUIContent( "Cull Mode", "Polygon culling mode prevents rendering of either back-facing or front-facing polygons to save performance, turn it off if you want to render both sides\nDefault: Back" );
|
|
|
|
private const string ChromaticAberrationStr = "Chromatic Aberration";
|
|
private const string DiscardStr = "Opacity Mask";
|
|
private const string VertexDisplacementStr = "Local Vertex Offset";
|
|
private const string VertexPositionStr = "Local Vertex Position";
|
|
private const string VertexDataStr = "VertexData";
|
|
private const string VertexNormalStr = "Local Vertex Normal";
|
|
private const string CustomLightingStr = "Custom Lighting";
|
|
private const string AlbedoStr = "Albedo";
|
|
private const string NormalStr = "Normal";
|
|
private const string EmissionStr = "Emission";
|
|
private const string MetallicStr = "Metallic";
|
|
private const string SmoothnessStr = "Smoothness";
|
|
private const string OcclusionDataStr = "Occlusion";
|
|
private const string OcclusionLabelStr = "Ambient Occlusion";
|
|
private const string TransmissionStr = "Transmission";
|
|
private const string TranslucencyStr = "Translucency";
|
|
private const string RefractionStr = "Refraction";
|
|
private const string AlphaStr = "Opacity";
|
|
private const string AlphaDataStr = "Alpha";
|
|
private const string DebugStr = "Debug";
|
|
private const string SpecularStr = "Specular";
|
|
private const string GlossStr = "Gloss";
|
|
private const string CustomRenderTypeStr = "Custom Type";
|
|
private readonly static GUIContent AlphaModeContent = new GUIContent( " Blend Mode", "Defines how the surface blends with the background\nDefault: Opaque" );
|
|
private const string OpacityMaskClipValueStr = "Mask Clip Value";
|
|
private readonly static GUIContent OpacityMaskClipValueContent = new GUIContent( "Mask Clip Value", "Default clip value to be compared with opacity alpha ( 0 = fully Opaque, 1 = fully Masked )\nDefault: 0.5" );
|
|
private readonly static GUIContent CastShadowsContent = new GUIContent( "Cast Shadows", "Generates a shadow caster pass for vertex modifications and point lights in forward rendering\nDefault: ON" );
|
|
private readonly static GUIContent ReceiveShadowsContent = new GUIContent( "Receive Shadows", "Untick it to disable shadow receiving, this includes self-shadowing (only for forward rendering) \nDefault: ON" );
|
|
private readonly static GUIContent QueueIndexContent = new GUIContent( "Queue Index", "Value to offset the render queue, accepts both positive values to render later and negative values to render sooner\nDefault: 0" );
|
|
private readonly static GUIContent RefractionLayerStr = new GUIContent( "Refraction Layer", "Use it to group or ungroup different refraction shaders into the same or different grabpass (only for forward rendering) \nDefault: 0" );
|
|
private readonly static GUIContent AlphaToCoverageStr = new GUIContent( "Alpha To Coverage", "" );
|
|
private readonly static GUIContent RenderQueueContent = new GUIContent( "Render Queue", "Base rendering queue index\n(Background = 1000, Geometry = 2000, AlphaTest = 2450, Transparent = 3000, Overlay = 4000)\nDefault: Geometry" );
|
|
private readonly static GUIContent RenderTypeContent = new GUIContent( "Render Type", "Categorizes shaders into several predefined groups, usually to be used with screen shader effects\nDefault: Opaque" );
|
|
|
|
private const string ShaderInputOrderStr = "Shader Input Order";
|
|
|
|
|
|
[SerializeField]
|
|
private BlendOpsHelper m_blendOpsHelper = new BlendOpsHelper();
|
|
|
|
[SerializeField]
|
|
private StencilBufferOpHelper m_stencilBufferHelper = new StencilBufferOpHelper();
|
|
|
|
[SerializeField]
|
|
private ZBufferOpHelper m_zBufferHelper = new ZBufferOpHelper();
|
|
|
|
[SerializeField]
|
|
private OutlineOpHelper m_outlineHelper = new OutlineOpHelper();
|
|
|
|
[SerializeField]
|
|
private TessellationOpHelper m_tessOpHelper = new TessellationOpHelper();
|
|
|
|
[SerializeField]
|
|
private ColorMaskHelper m_colorMaskHelper = new ColorMaskHelper();
|
|
|
|
[SerializeField]
|
|
private RenderingPlatformOpHelper m_renderingPlatformOpHelper = new RenderingPlatformOpHelper();
|
|
|
|
[SerializeField]
|
|
private RenderingOptionsOpHelper m_renderingOptionsOpHelper = new RenderingOptionsOpHelper();
|
|
|
|
[SerializeField]
|
|
private BillboardOpHelper m_billboardOpHelper = new BillboardOpHelper();
|
|
|
|
[SerializeField]
|
|
private FallbackPickerHelper m_fallbackHelper = null;
|
|
|
|
[SerializeField]
|
|
private TerrainDrawInstancedHelper m_drawInstancedHelper = new TerrainDrawInstancedHelper();
|
|
|
|
//legacy
|
|
[SerializeField]
|
|
private AdditionalIncludesHelper m_additionalIncludes = new AdditionalIncludesHelper();
|
|
//legacy
|
|
[SerializeField]
|
|
private AdditionalPragmasHelper m_additionalPragmas = new AdditionalPragmasHelper();
|
|
//legacy
|
|
[SerializeField]
|
|
private AdditionalDefinesHelper m_additionalDefines = new AdditionalDefinesHelper();
|
|
|
|
[SerializeField]
|
|
private TemplateAdditionalDirectivesHelper m_additionalDirectives = new TemplateAdditionalDirectivesHelper( " Additional Directives" );
|
|
|
|
[SerializeField]
|
|
private AdditionalSurfaceOptionsHelper m_additionalSurfaceOptions = new AdditionalSurfaceOptionsHelper();
|
|
|
|
[SerializeField]
|
|
private UsePassHelper m_usePass;
|
|
|
|
[SerializeField]
|
|
private CustomTagsHelper m_customTagsHelper = new CustomTagsHelper();
|
|
|
|
[SerializeField]
|
|
private DependenciesHelper m_dependenciesHelper = new DependenciesHelper();
|
|
|
|
[SerializeField]
|
|
private StandardShaderLightModel m_currentLightModel;
|
|
|
|
[SerializeField]
|
|
private StandardShaderLightModel m_lastLightModel;
|
|
|
|
[SerializeField]
|
|
private CullMode m_cullMode = CullMode.Back;
|
|
|
|
[SerializeField]
|
|
private InlineProperty m_inlineCullMode = new InlineProperty();
|
|
|
|
[SerializeField]
|
|
private InlineProperty m_inlineChromaticAberration = new InlineProperty(0.1f);
|
|
|
|
[SerializeField]
|
|
private AlphaMode m_alphaMode = AlphaMode.Opaque;
|
|
|
|
[SerializeField]
|
|
private RenderType m_renderType = RenderType.Opaque;
|
|
|
|
[SerializeField]
|
|
private string m_customRenderType = string.Empty;
|
|
|
|
[SerializeField]
|
|
private RenderQueue m_renderQueue = RenderQueue.Geometry;
|
|
|
|
[SerializeField]
|
|
private RenderPath m_renderPath = RenderPath.All;
|
|
|
|
[SerializeField]
|
|
private VertexMode m_vertexMode = VertexMode.Relative;
|
|
|
|
[SerializeField]
|
|
private bool m_customBlendMode = false;
|
|
|
|
[SerializeField]
|
|
private float m_opacityMaskClipValue = 0.5f;
|
|
|
|
[SerializeField]
|
|
private InlineProperty m_inlineOpacityMaskClipValue = new InlineProperty();
|
|
|
|
[SerializeField]
|
|
private InlineProperty m_inlineAlphaToCoverage = new InlineProperty();
|
|
|
|
[SerializeField]
|
|
private int m_customLightingPortId = -1;
|
|
|
|
[SerializeField]
|
|
private int m_emissionPortId = -1;
|
|
|
|
[SerializeField]
|
|
private int m_discardPortId = -1;
|
|
|
|
[SerializeField]
|
|
private int m_opacityPortId = -1;
|
|
|
|
[SerializeField]
|
|
private int m_vertexPortId = -1;
|
|
|
|
[SerializeField]
|
|
private bool m_keepAlpha = true;
|
|
|
|
[SerializeField]
|
|
private bool m_castShadows = true;
|
|
|
|
//[SerializeField]
|
|
private bool m_customShadowCaster = false;
|
|
|
|
[SerializeField]
|
|
private bool m_receiveShadows = true;
|
|
|
|
[SerializeField]
|
|
private int m_queueOrder = 0;
|
|
|
|
[SerializeField]
|
|
private int m_grabOrder = 0;
|
|
|
|
[SerializeField]
|
|
private bool m_alphaToCoverage = false;
|
|
|
|
private InputPort m_transmissionPort;
|
|
private InputPort m_translucencyPort;
|
|
private InputPort m_tessellationPort;
|
|
private bool m_previousTranslucencyOn = false;
|
|
private bool m_previousRefractionOn = false;
|
|
|
|
[SerializeField]
|
|
private CacheNodeConnections m_cacheNodeConnections = new CacheNodeConnections();
|
|
|
|
|
|
private bool m_usingProSkin = false;
|
|
private GUIStyle m_inspectorFoldoutStyle;
|
|
private GUIStyle m_inspectorToolbarStyle;
|
|
private GUIStyle m_inspectorTooldropdownStyle;
|
|
|
|
|
|
private bool m_customBlendAvailable = false;
|
|
|
|
private Color m_cachedColor = Color.white;
|
|
private float m_titleOpacity = 0.5f;
|
|
private float m_boxOpacity = 0.5f;
|
|
|
|
private InputPort m_refractionPort;
|
|
private InputPort m_normalPort;
|
|
|
|
|
|
private GUIStyle m_inspectorDefaultStyle;
|
|
|
|
[SerializeField]
|
|
private ReordenatorNode m_specColorReorder = null;
|
|
|
|
[SerializeField]
|
|
private int m_specColorOrderIndex = -1;
|
|
|
|
[SerializeField]
|
|
private ReordenatorNode m_maskClipReorder = null;
|
|
|
|
[SerializeField]
|
|
private int m_maskClipOrderIndex = -1;
|
|
|
|
[SerializeField]
|
|
private ReordenatorNode m_translucencyReorder = null;
|
|
|
|
[SerializeField]
|
|
private int m_translucencyOrderIndex = -1;
|
|
|
|
[SerializeField]
|
|
private ReordenatorNode m_refractionReorder = null;
|
|
|
|
[SerializeField]
|
|
private int m_refractionOrderIndex = -1;
|
|
|
|
[SerializeField]
|
|
private ReordenatorNode m_tessellationReorder = null;
|
|
|
|
[SerializeField]
|
|
private int m_tessellationOrderIndex = -1;
|
|
|
|
private bool m_previousTessellationOn = false;
|
|
private bool m_initialize = true;
|
|
private bool m_checkChanges = true;
|
|
private bool m_lightModelChanged = true;
|
|
|
|
private PropertyNode m_dummyProperty = null;
|
|
|
|
protected override void CommonInit( int uniqueId )
|
|
{
|
|
m_currentLightModel = m_lastLightModel = StandardShaderLightModel.Standard;
|
|
m_textLabelWidth = 120;
|
|
m_autoDrawInternalPortData = false;
|
|
base.CommonInit( uniqueId );
|
|
m_zBufferHelper.ParentSurface = this;
|
|
m_tessOpHelper.ParentSurface = this;
|
|
m_customPrecision = true;
|
|
}
|
|
|
|
public override void OnEnable()
|
|
{
|
|
base.OnEnable();
|
|
if( m_usePass == null )
|
|
{
|
|
m_usePass = ScriptableObject.CreateInstance<UsePassHelper>();
|
|
m_usePass.Init( " Additional Use Passes" );
|
|
}
|
|
|
|
if( m_fallbackHelper == null )
|
|
{
|
|
m_fallbackHelper = ScriptableObject.CreateInstance<FallbackPickerHelper>();
|
|
m_fallbackHelper.Init();
|
|
}
|
|
}
|
|
|
|
public override void AddMasterPorts()
|
|
{
|
|
int vertexCorrection = 2;
|
|
int index = vertexCorrection + 2;
|
|
base.AddMasterPorts();
|
|
switch( m_currentLightModel )
|
|
{
|
|
case StandardShaderLightModel.Standard:
|
|
{
|
|
AddInputPort( WirePortDataType.FLOAT3, false, AlbedoStr, vertexCorrection + 1, MasterNodePortCategory.Fragment, 0 );
|
|
AddInputPort( WirePortDataType.FLOAT3, false, NormalStr, vertexCorrection + 0, MasterNodePortCategory.Fragment, 1 );
|
|
m_normalPort = m_inputPorts[ m_inputPorts.Count - 1 ];
|
|
AddInputPort( WirePortDataType.FLOAT3, false, EmissionStr, index++, MasterNodePortCategory.Fragment, 2 );
|
|
AddInputPort( WirePortDataType.FLOAT, false, MetallicStr, index++, MasterNodePortCategory.Fragment, 3 );
|
|
AddInputPort( WirePortDataType.FLOAT, false, SmoothnessStr, index++, MasterNodePortCategory.Fragment, 4 );
|
|
AddInputPort( WirePortDataType.FLOAT, false, OcclusionLabelStr, OcclusionDataStr, index++, MasterNodePortCategory.Fragment, 5 );
|
|
}
|
|
break;
|
|
case StandardShaderLightModel.StandardSpecular:
|
|
{
|
|
AddInputPort( WirePortDataType.FLOAT3, false, AlbedoStr, vertexCorrection + 1, MasterNodePortCategory.Fragment, 0 );
|
|
AddInputPort( WirePortDataType.FLOAT3, false, NormalStr, vertexCorrection + 0, MasterNodePortCategory.Fragment, 1 );
|
|
m_normalPort = m_inputPorts[ m_inputPorts.Count - 1 ];
|
|
AddInputPort( WirePortDataType.FLOAT3, false, EmissionStr, index++, MasterNodePortCategory.Fragment, 2 );
|
|
AddInputPort( WirePortDataType.FLOAT3, false, SpecularStr, index++, MasterNodePortCategory.Fragment, 3 );
|
|
AddInputPort( WirePortDataType.FLOAT, false, SmoothnessStr, index++, MasterNodePortCategory.Fragment, 4 );
|
|
AddInputPort( WirePortDataType.FLOAT, false, OcclusionLabelStr, OcclusionDataStr, index++, MasterNodePortCategory.Fragment, 5 );
|
|
}
|
|
break;
|
|
case StandardShaderLightModel.CustomLighting:
|
|
{
|
|
AddInputPort( WirePortDataType.FLOAT3, false, AlbedoStr, vertexCorrection + 1, MasterNodePortCategory.Fragment, 0 );
|
|
AddInputPort( WirePortDataType.FLOAT3, false, NormalStr, vertexCorrection + 0, MasterNodePortCategory.Fragment, 1 );
|
|
m_normalPort = m_inputPorts[ m_inputPorts.Count - 1 ];
|
|
m_inputPorts[ m_inputPorts.Count - 1 ].Locked = true;
|
|
AddInputPort( WirePortDataType.FLOAT3, false, EmissionStr, index++, MasterNodePortCategory.Fragment, 2 );
|
|
AddInputPort( WirePortDataType.FLOAT, false, SpecularStr, index++, MasterNodePortCategory.Fragment, 3 );
|
|
m_inputPorts[ m_inputPorts.Count - 1 ].Locked = true;
|
|
AddInputPort( WirePortDataType.FLOAT, false, GlossStr, index++, MasterNodePortCategory.Fragment, 4 );
|
|
m_inputPorts[ m_inputPorts.Count - 1 ].Locked = true;
|
|
}
|
|
break;
|
|
case StandardShaderLightModel.Unlit:
|
|
{
|
|
AddInputPort( WirePortDataType.FLOAT3, false, AlbedoStr, vertexCorrection + 1, MasterNodePortCategory.Fragment, 0 );
|
|
m_inputPorts[ m_inputPorts.Count - 1 ].Locked = true;
|
|
AddInputPort( WirePortDataType.FLOAT3, false, NormalStr, vertexCorrection + 0, MasterNodePortCategory.Fragment, 1 );
|
|
m_normalPort = m_inputPorts[ m_inputPorts.Count - 1 ];
|
|
m_inputPorts[ m_inputPorts.Count - 1 ].Locked = true;
|
|
AddInputPort( WirePortDataType.FLOAT3, false, EmissionStr, index++, MasterNodePortCategory.Fragment, 2 );
|
|
AddInputPort( WirePortDataType.FLOAT, false, SpecularStr, index++, MasterNodePortCategory.Fragment, 3 );
|
|
m_inputPorts[ m_inputPorts.Count - 1 ].Locked = true;
|
|
AddInputPort( WirePortDataType.FLOAT, false, GlossStr, index++, MasterNodePortCategory.Fragment, 4 );
|
|
m_inputPorts[ m_inputPorts.Count - 1 ].Locked = true;
|
|
}
|
|
break;
|
|
case StandardShaderLightModel.Lambert:
|
|
{
|
|
AddInputPort( WirePortDataType.FLOAT3, false, AlbedoStr, vertexCorrection + 1, MasterNodePortCategory.Fragment, 0 );
|
|
AddInputPort( WirePortDataType.FLOAT3, false, NormalStr, vertexCorrection + 0, MasterNodePortCategory.Fragment, 1 );
|
|
m_normalPort = m_inputPorts[ m_inputPorts.Count - 1 ];
|
|
AddInputPort( WirePortDataType.FLOAT3, false, EmissionStr, index++, MasterNodePortCategory.Fragment, 2 );
|
|
AddInputPort( WirePortDataType.FLOAT, false, SpecularStr, index++, MasterNodePortCategory.Fragment, 3 );
|
|
AddInputPort( WirePortDataType.FLOAT, false, GlossStr, index++, MasterNodePortCategory.Fragment, 4 );
|
|
}
|
|
break;
|
|
case StandardShaderLightModel.BlinnPhong:
|
|
{
|
|
AddInputPort( WirePortDataType.FLOAT3, false, AlbedoStr, vertexCorrection + 1, MasterNodePortCategory.Fragment, 0 );
|
|
AddInputPort( WirePortDataType.FLOAT3, false, NormalStr, vertexCorrection + 0, MasterNodePortCategory.Fragment, 1 );
|
|
m_normalPort = m_inputPorts[ m_inputPorts.Count - 1 ];
|
|
AddInputPort( WirePortDataType.FLOAT3, false, EmissionStr, index++, MasterNodePortCategory.Fragment, 2 );
|
|
AddInputPort( WirePortDataType.FLOAT, false, SpecularStr, index++, MasterNodePortCategory.Fragment, 3 );
|
|
AddInputPort( WirePortDataType.FLOAT, false, GlossStr, index++, MasterNodePortCategory.Fragment, 4 );
|
|
}
|
|
break;
|
|
}
|
|
|
|
// instead of setting in the switch emission port is always at position 2;
|
|
m_emissionPortId = 2;
|
|
|
|
AddInputPort( WirePortDataType.FLOAT3, false, TransmissionStr, index++, MasterNodePortCategory.Fragment, 6 );
|
|
m_transmissionPort = m_inputPorts[ m_inputPorts.Count - 1 ];
|
|
m_inputPorts[ m_inputPorts.Count - 1 ].Locked = ( m_currentLightModel == StandardShaderLightModel.Standard ) || ( m_currentLightModel == StandardShaderLightModel.StandardSpecular ) ? false : true;
|
|
|
|
AddInputPort( WirePortDataType.FLOAT3, false, TranslucencyStr, index++, MasterNodePortCategory.Fragment, 7 );
|
|
m_translucencyPort = m_inputPorts[ m_inputPorts.Count - 1 ];
|
|
m_inputPorts[ m_inputPorts.Count - 1 ].Locked = ( m_currentLightModel == StandardShaderLightModel.Standard ) || ( m_currentLightModel == StandardShaderLightModel.StandardSpecular ) ? false : true;
|
|
|
|
AddInputPort( WirePortDataType.FLOAT, false, RefractionStr, index + 2, MasterNodePortCategory.Fragment, 8 );
|
|
m_refractionPort = m_inputPorts[ m_inputPorts.Count - 1 ];
|
|
m_inputPorts[ m_inputPorts.Count - 1 ].Locked = ( m_alphaMode == AlphaMode.Opaque || m_alphaMode == AlphaMode.Masked || m_currentLightModel == StandardShaderLightModel.Unlit || m_currentLightModel == StandardShaderLightModel.CustomLighting );
|
|
|
|
AddInputPort( WirePortDataType.FLOAT, false, AlphaStr, index++, MasterNodePortCategory.Fragment, 9 );
|
|
m_inputPorts[ m_inputPorts.Count - 1 ].DataName = AlphaDataStr;
|
|
m_opacityPortId = m_inputPorts.Count - 1;
|
|
m_inputPorts[ m_inputPorts.Count - 1 ].Locked = ( m_alphaMode == AlphaMode.Opaque || m_alphaMode == AlphaMode.Masked );
|
|
|
|
AddInputPort( WirePortDataType.FLOAT, false, DiscardStr, index++, MasterNodePortCategory.Fragment, 10 );
|
|
m_inputPorts[ m_inputPorts.Count - 1 ].Locked = ( m_alphaMode != AlphaMode.Masked && m_alphaMode != AlphaMode.Custom );
|
|
m_discardPortId = m_inputPorts.Count - 1;
|
|
|
|
// This is done to take the index + 2 from refraction port into account and not overlap indexes
|
|
index++;
|
|
|
|
AddInputPort( WirePortDataType.FLOAT3, false, CustomLightingStr, index++, MasterNodePortCategory.Fragment, 13 );
|
|
m_inputPorts[ m_inputPorts.Count - 1 ].Locked = ( m_currentLightModel != StandardShaderLightModel.CustomLighting );
|
|
m_inputPorts[ m_inputPorts.Count - 1 ].GenType = PortGenType.CustomLighting;
|
|
m_customLightingPortId = m_inputPorts.Count - 1;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Vertex functions - Adding ordex index in order to force these to be the last ones
|
|
// Well now they have been moved to be the first ones so operations on vertex are to be taken into account
|
|
// by dither, screen position and similar nodes
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
m_vertexPortId = m_inputPorts.Count;
|
|
m_tessOpHelper.VertexOffsetIndexPort = m_vertexPortId;
|
|
AddInputPort( WirePortDataType.FLOAT3, false, ( m_vertexMode == VertexMode.Relative ? VertexDisplacementStr : VertexPositionStr ), VertexDataStr, 0/*index++*/, MasterNodePortCategory.Vertex, 11 );
|
|
AddInputPort( WirePortDataType.FLOAT3, false, VertexNormalStr, 1/*index++*/, MasterNodePortCategory.Vertex, 12 );
|
|
|
|
//AddInputPort( WirePortDataType.FLOAT3, false, CustomLightModelStr, index++, MasterNodePortCategory.Fragment, 13 );
|
|
//m_inputPorts[ m_inputPorts.Count - 1 ].Locked = true;// !(m_currentLightModel == StandardShaderLightModel.CustomLighting);
|
|
|
|
AddInputPort( WirePortDataType.FLOAT4, false, TessellationOpHelper.TessellationPortStr, index++, MasterNodePortCategory.Tessellation, 14 );
|
|
m_tessellationPort = m_inputPorts[ m_inputPorts.Count - 1 ];
|
|
m_tessOpHelper.MasterNodeIndexPort = m_tessellationPort.PortId;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
AddInputPort( WirePortDataType.FLOAT3, false, DebugStr, index++, MasterNodePortCategory.Debug, 15 );
|
|
|
|
for( int i = 0; i < m_inputPorts.Count; i++ )
|
|
{
|
|
m_inputPorts[ i ].CustomColor = Color.white;
|
|
}
|
|
m_sizeIsDirty = true;
|
|
}
|
|
|
|
public override void ForcePortType()
|
|
{
|
|
int portId = 0;
|
|
switch( m_currentLightModel )
|
|
{
|
|
case StandardShaderLightModel.Standard:
|
|
{
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false );
|
|
}
|
|
break;
|
|
case StandardShaderLightModel.StandardSpecular:
|
|
{
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false );
|
|
}
|
|
break;
|
|
case StandardShaderLightModel.CustomLighting:
|
|
{
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false );
|
|
}
|
|
break;
|
|
case StandardShaderLightModel.Unlit:
|
|
case StandardShaderLightModel.Lambert:
|
|
{
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false );
|
|
}
|
|
break;
|
|
case StandardShaderLightModel.BlinnPhong:
|
|
{
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false );
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false );
|
|
}
|
|
break;
|
|
}
|
|
|
|
//Transmission
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
//Translucency
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
//Refraction
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false );
|
|
//Alpha
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false );
|
|
//Discard
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false );
|
|
//Custom Lighting
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
//Vertex Offset
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
//Vertex Normal
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
//Tessellation
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT4, false );
|
|
//Debug
|
|
m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false );
|
|
}
|
|
|
|
public override void SetName( string name )
|
|
{
|
|
ShaderName = name;
|
|
}
|
|
|
|
public void DrawInspectorProperty()
|
|
{
|
|
if( m_inspectorDefaultStyle == null )
|
|
{
|
|
m_inspectorDefaultStyle = UIUtils.GetCustomStyle( CustomStyle.ResetToDefaultInspectorButton );
|
|
}
|
|
|
|
DrawCustomInspector( false );
|
|
}
|
|
|
|
private void RecursiveLog()
|
|
{
|
|
List<PropertyNode> nodes = UIUtils.PropertyNodesList();
|
|
nodes.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } );
|
|
for( int i = 0; i < nodes.Count; i++ )
|
|
{
|
|
if( ( nodes[ i ] is ReordenatorNode ) )
|
|
( nodes[ i ] as ReordenatorNode ).RecursiveLog();
|
|
else
|
|
Debug.Log( nodes[ i ].OrderIndex + " " + nodes[ i ].PropertyName );
|
|
}
|
|
}
|
|
|
|
public void DrawGeneralOptions()
|
|
{
|
|
DrawShaderName();
|
|
DrawCurrentShaderType();
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
m_currentLightModel = (StandardShaderLightModel)EditorGUILayoutEnumPopup( LightModelContent, m_currentLightModel );
|
|
if( EditorGUI.EndChangeCheck() )
|
|
{
|
|
ContainerGraph.ChangedLightingModel = true;
|
|
if( m_currentLightModel == StandardShaderLightModel.CustomLighting )
|
|
{
|
|
ContainerGraph.ParentWindow.CurrentNodeAvailability = NodeAvailability.CustomLighting;
|
|
//ContainerGraph.CurrentCanvasMode = NodeAvailability.CustomLighting;
|
|
}
|
|
else
|
|
{
|
|
ContainerGraph.ParentWindow.CurrentNodeAvailability = NodeAvailability.SurfaceShader;
|
|
//ContainerGraph.CurrentCanvasMode = NodeAvailability.SurfaceShader;
|
|
}
|
|
}
|
|
|
|
m_shaderModelIdx = EditorGUILayoutPopup( ShaderModelStr, m_shaderModelIdx, ShaderModelTypeArr );
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
DrawPrecisionProperty( false );
|
|
if( EditorGUI.EndChangeCheck() )
|
|
ContainerGraph.CurrentPrecision = m_currentPrecisionType;
|
|
//m_cullMode = (CullMode)EditorGUILayoutEnumPopup( CullModeContent, m_cullMode );
|
|
UndoParentNode inst = this;
|
|
m_inlineCullMode.CustomDrawer( ref inst, ( x ) => { m_cullMode = (CullMode)EditorGUILayoutEnumPopup( CullModeContent, m_cullMode ); }, CullModeContent.text );
|
|
//m_inlineCullMode.Value = (int)m_cullMode;
|
|
//m_inlineCullMode.EnumTypePopup( ref inst, CullModeContent.text, Enum.GetNames( typeof( CullMode ) ) );
|
|
//m_cullMode = (CullMode) m_inlineCullMode.Value;
|
|
|
|
m_renderPath = (RenderPath)EditorGUILayoutEnumPopup( RenderPathContent, m_renderPath );
|
|
|
|
m_castShadows = EditorGUILayoutToggle( CastShadowsContent, m_castShadows );
|
|
|
|
m_receiveShadows = EditorGUILayoutToggle( ReceiveShadowsContent, m_receiveShadows );
|
|
|
|
DrawSamplingMacros();
|
|
|
|
m_drawInstancedHelper.Draw( this );
|
|
|
|
m_queueOrder = EditorGUILayoutIntField( QueueIndexContent, m_queueOrder );
|
|
EditorGUI.BeginChangeCheck();
|
|
m_vertexMode = (VertexMode)EditorGUILayoutEnumPopup( VertexModeStr, m_vertexMode );
|
|
if( EditorGUI.EndChangeCheck() )
|
|
{
|
|
m_inputPorts[ m_vertexPortId ].Name = m_vertexMode == VertexMode.Relative ? VertexDisplacementStr : VertexPositionStr;
|
|
m_sizeIsDirty = true;
|
|
}
|
|
|
|
ShaderLOD = Mathf.Clamp( EditorGUILayoutIntField( ShaderLODContent, ShaderLOD ), 0, Shader.globalMaximumLOD );
|
|
////m_lodCrossfade = EditorGUILayoutToggle( LODCrossfadeContent, m_lodCrossfade );
|
|
m_fallbackHelper.Draw( this );
|
|
DrawInspectorProperty();
|
|
|
|
}
|
|
|
|
public void ShowOpacityMaskValueUI()
|
|
{
|
|
EditorGUI.BeginChangeCheck();
|
|
UndoParentNode inst = this;
|
|
m_inlineOpacityMaskClipValue.CustomDrawer( ref inst, ( x ) => { m_opacityMaskClipValue = EditorGUILayoutFloatField( OpacityMaskClipValueContent, m_opacityMaskClipValue ); }, OpacityMaskClipValueContent.text );
|
|
if( EditorGUI.EndChangeCheck() )
|
|
{
|
|
m_checkChanges = true;
|
|
if( m_currentMaterial != null && m_currentMaterial.HasProperty( IOUtils.MaskClipValueName ) )
|
|
{
|
|
m_currentMaterial.SetFloat( IOUtils.MaskClipValueName, m_opacityMaskClipValue );
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void DrawProperties()
|
|
{
|
|
if( m_inspectorFoldoutStyle == null || EditorGUIUtility.isProSkin != m_usingProSkin )
|
|
m_inspectorFoldoutStyle = new GUIStyle( GUI.skin.GetStyle( "foldout" ) );
|
|
|
|
if( m_inspectorToolbarStyle == null || EditorGUIUtility.isProSkin != m_usingProSkin )
|
|
{
|
|
m_inspectorToolbarStyle = new GUIStyle( GUI.skin.GetStyle( "toolbarbutton" ) )
|
|
{
|
|
fixedHeight = 20
|
|
};
|
|
}
|
|
|
|
if( m_inspectorTooldropdownStyle == null || EditorGUIUtility.isProSkin != m_usingProSkin )
|
|
{
|
|
m_inspectorTooldropdownStyle = new GUIStyle( GUI.skin.GetStyle( "toolbardropdown" ) )
|
|
{
|
|
fixedHeight = 20
|
|
};
|
|
m_inspectorTooldropdownStyle.margin.bottom = 2;
|
|
}
|
|
|
|
if( EditorGUIUtility.isProSkin != m_usingProSkin )
|
|
m_usingProSkin = EditorGUIUtility.isProSkin;
|
|
|
|
base.DrawProperties();
|
|
|
|
EditorGUILayout.BeginVertical();
|
|
{
|
|
EditorGUILayout.Separator();
|
|
|
|
m_titleOpacity = 0.5f;
|
|
m_boxOpacity = ( EditorGUIUtility.isProSkin ? 0.5f : 0.25f );
|
|
m_cachedColor = GUI.color;
|
|
|
|
// General
|
|
bool generalIsVisible = ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedGeneralShaderOptions;
|
|
NodeUtils.DrawPropertyGroup( ref generalIsVisible, GeneralFoldoutStr, DrawGeneralOptions );
|
|
ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedGeneralShaderOptions = generalIsVisible;
|
|
|
|
//Blend Mode
|
|
GUI.color = new Color( m_cachedColor.r, m_cachedColor.g, m_cachedColor.b, m_titleOpacity );
|
|
EditorGUILayout.BeginHorizontal( m_inspectorToolbarStyle );
|
|
GUI.color = m_cachedColor;
|
|
|
|
bool blendOptionsVisible = GUILayout.Toggle( ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedBlendOptions, AlphaModeContent, UIUtils.MenuItemToggleStyle, GUILayout.ExpandWidth( true ) );
|
|
if( Event.current.button == Constants.FoldoutMouseId )
|
|
{
|
|
ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedBlendOptions = blendOptionsVisible;
|
|
}
|
|
|
|
|
|
if( !EditorGUIUtility.isProSkin )
|
|
GUI.color = new Color( 0.25f, 0.25f, 0.25f, 1f );
|
|
|
|
float boxSize = 60;
|
|
switch( m_alphaMode )
|
|
{
|
|
case AlphaMode.Transparent:
|
|
boxSize = 85;
|
|
break;
|
|
case AlphaMode.Translucent:
|
|
boxSize = 80;
|
|
break;
|
|
case AlphaMode.Premultiply:
|
|
boxSize = 120;
|
|
break;
|
|
}
|
|
EditorGUI.BeginChangeCheck();
|
|
m_alphaMode = (AlphaMode)EditorGUILayoutPopup( string.Empty, (int)m_alphaMode, FadeModeOptions, UIUtils.InspectorPopdropdownStyle, GUILayout.Width( boxSize ), GUILayout.Height( 19 ) );
|
|
if( EditorGUI.EndChangeCheck() )
|
|
{
|
|
UpdateFromBlendMode();
|
|
}
|
|
|
|
GUI.color = m_cachedColor;
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
m_customBlendAvailable = ( m_alphaMode == AlphaMode.Custom || m_alphaMode == AlphaMode.Opaque );
|
|
|
|
if( ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedBlendOptions )
|
|
{
|
|
GUI.color = new Color( m_cachedColor.r, m_cachedColor.g, m_cachedColor.b, m_boxOpacity );
|
|
EditorGUILayout.BeginVertical( UIUtils.MenuItemBackgroundStyle );
|
|
GUI.color = m_cachedColor;
|
|
EditorGUI.indentLevel++;
|
|
EditorGUILayout.Separator();
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
|
|
m_renderType = (RenderType)EditorGUILayoutEnumPopup( RenderTypeContent, m_renderType );
|
|
if( m_renderType == RenderType.Custom )
|
|
{
|
|
EditorGUI.BeginChangeCheck();
|
|
m_customRenderType = EditorGUILayoutTextField( CustomRenderTypeStr, m_customRenderType );
|
|
if( EditorGUI.EndChangeCheck() )
|
|
{
|
|
m_customRenderType = UIUtils.RemoveInvalidCharacters( m_customRenderType );
|
|
}
|
|
}
|
|
|
|
m_renderQueue = (RenderQueue)EditorGUILayoutEnumPopup( RenderQueueContent, m_renderQueue );
|
|
|
|
if( EditorGUI.EndChangeCheck() )
|
|
{
|
|
if( m_renderType == RenderType.Opaque && m_renderQueue == RenderQueue.Geometry )
|
|
m_alphaMode = AlphaMode.Opaque;
|
|
else if( m_renderType == RenderType.TransparentCutout && m_renderQueue == RenderQueue.AlphaTest )
|
|
m_alphaMode = AlphaMode.Masked;
|
|
else if( m_renderType == RenderType.Transparent && m_renderQueue == RenderQueue.Transparent )
|
|
m_alphaMode = AlphaMode.Transparent;
|
|
else if( m_renderType == RenderType.Opaque && m_renderQueue == RenderQueue.Transparent )
|
|
m_alphaMode = AlphaMode.Translucent;
|
|
else
|
|
m_alphaMode = AlphaMode.Custom;
|
|
|
|
|
|
UpdateFromBlendMode();
|
|
}
|
|
|
|
bool bufferedEnabled = GUI.enabled;
|
|
|
|
GUI.enabled = ( m_alphaMode == AlphaMode.Masked || m_alphaMode == AlphaMode.Custom );
|
|
m_inputPorts[ m_discardPortId ].Locked = !GUI.enabled;
|
|
ShowOpacityMaskValueUI();
|
|
|
|
GUI.enabled = bufferedEnabled;
|
|
|
|
EditorGUI.BeginDisabledGroup( !( m_alphaMode == AlphaMode.Transparent || m_alphaMode == AlphaMode.Premultiply || m_alphaMode == AlphaMode.Translucent || m_alphaMode == AlphaMode.Custom ) );
|
|
m_grabOrder = EditorGUILayoutIntField( RefractionLayerStr, m_grabOrder );
|
|
float cachedLabelWidth = EditorGUIUtility.labelWidth;
|
|
UndoParentNode inst = this;
|
|
if( m_refractionPort.IsConnected )
|
|
{
|
|
EditorGUIUtility.labelWidth = 145;
|
|
EditorGUI.BeginChangeCheck();
|
|
m_inlineChromaticAberration.RangedFloatField( ref inst, ChromaticAberrationStr, 0.0f,0.3f );
|
|
if( EditorGUI.EndChangeCheck() )
|
|
{
|
|
if( m_currentMaterial != null && m_currentMaterial.HasProperty( IOUtils.ChromaticAberrationProperty ) )
|
|
{
|
|
m_currentMaterial.SetFloat( IOUtils.ChromaticAberrationProperty, m_inlineChromaticAberration.FloatValue );
|
|
}
|
|
}
|
|
}
|
|
|
|
//EditorGUIUtility.labelWidth = 130;
|
|
m_inlineAlphaToCoverage.CustomDrawer( ref inst, ( x ) => { m_alphaToCoverage = EditorGUILayoutToggle( AlphaToCoverageStr, m_alphaToCoverage ); }, AlphaToCoverageStr.text );
|
|
//EditorGUIUtility.labelWidth = cachedLabelWidth;
|
|
EditorGUI.EndDisabledGroup();
|
|
|
|
EditorGUILayout.Separator();
|
|
|
|
if( !m_customBlendAvailable )
|
|
{
|
|
EditorGUILayout.HelpBox( "Advanced options are only available for Custom blend modes", MessageType.Warning );
|
|
}
|
|
|
|
EditorGUI.BeginDisabledGroup( !m_customBlendAvailable );
|
|
m_blendOpsHelper.Draw( this, m_customBlendAvailable );
|
|
m_colorMaskHelper.Draw( this );
|
|
|
|
EditorGUI.EndDisabledGroup();
|
|
EditorGUILayout.Separator();
|
|
EditorGUI.indentLevel--;
|
|
EditorGUILayout.EndVertical();
|
|
}
|
|
|
|
m_stencilBufferHelper.Draw( this );
|
|
m_tessOpHelper.Draw( this, m_inspectorToolbarStyle, m_currentMaterial, m_tessellationPort.IsConnected );
|
|
m_outlineHelper.Draw( this, m_inspectorToolbarStyle, m_currentMaterial );
|
|
m_billboardOpHelper.Draw( this );
|
|
m_zBufferHelper.Draw( this, m_inspectorToolbarStyle, m_customBlendAvailable );
|
|
m_renderingOptionsOpHelper.Draw( this );
|
|
m_renderingPlatformOpHelper.Draw( this );
|
|
//m_additionalDefines.Draw( this );
|
|
//m_additionalIncludes.Draw( this );
|
|
//m_additionalPragmas.Draw( this );
|
|
m_additionalSurfaceOptions.Draw( this );
|
|
m_usePass.Draw( this );
|
|
m_additionalDirectives.Draw( this );
|
|
m_customTagsHelper.Draw( this );
|
|
m_dependenciesHelper.Draw( this );
|
|
DrawMaterialInputs( m_inspectorToolbarStyle );
|
|
}
|
|
|
|
EditorGUILayout.EndVertical();
|
|
}
|
|
|
|
public override void OnNodeLogicUpdate( DrawInfo drawInfo )
|
|
{
|
|
base.OnNodeLogicUpdate( drawInfo );
|
|
|
|
if( m_initialize )
|
|
{
|
|
m_initialize = false;
|
|
|
|
if( m_dummyProperty == null )
|
|
{
|
|
m_dummyProperty = ScriptableObject.CreateInstance<PropertyNode>();
|
|
m_dummyProperty.ContainerGraph = ContainerGraph;
|
|
}
|
|
}
|
|
|
|
if( m_currentLightModel != m_lastLightModel )
|
|
m_lightModelChanged = true;
|
|
|
|
if( m_lightModelChanged )
|
|
{
|
|
m_lightModelChanged = false;
|
|
if( m_currentLightModel == StandardShaderLightModel.BlinnPhong )
|
|
{
|
|
if( m_specColorReorder == null )
|
|
{
|
|
m_specColorReorder = ScriptableObject.CreateInstance<ReordenatorNode>();
|
|
m_specColorReorder.ContainerGraph = ContainerGraph;
|
|
m_specColorReorder.OrderIndex = m_specColorOrderIndex;
|
|
m_specColorReorder.Init( "_SpecColor", "Specular Color", null );
|
|
}
|
|
|
|
UIUtils.RegisterPropertyNode( m_specColorReorder );
|
|
}
|
|
else
|
|
{
|
|
if( m_specColorReorder != null )
|
|
UIUtils.UnregisterPropertyNode( m_specColorReorder );
|
|
}
|
|
|
|
if( m_currentLightModel == StandardShaderLightModel.CustomLighting && m_masterNodeCategory == 0 )
|
|
ContainerGraph.CurrentCanvasMode = NodeAvailability.CustomLighting;
|
|
else if( m_masterNodeCategory == 0 )
|
|
ContainerGraph.CurrentCanvasMode = NodeAvailability.SurfaceShader;
|
|
CacheCurrentSettings();
|
|
m_lastLightModel = m_currentLightModel;
|
|
DeleteAllInputConnections( true, true );
|
|
AddMasterPorts();
|
|
ConnectFromCache();
|
|
}
|
|
|
|
if( drawInfo.CurrentEventType != EventType.Layout )
|
|
return;
|
|
|
|
if( m_transmissionPort != null && m_transmissionPort.IsConnected && m_renderPath != RenderPath.ForwardOnly )
|
|
{
|
|
m_renderPath = RenderPath.ForwardOnly;
|
|
UIUtils.ShowMessage( "Render Path changed to Forward Only since transmission only works in forward rendering" );
|
|
}
|
|
|
|
if( m_translucencyPort != null && m_translucencyPort.IsConnected && m_renderPath != RenderPath.ForwardOnly )
|
|
{
|
|
m_renderPath = RenderPath.ForwardOnly;
|
|
UIUtils.ShowMessage( "Render Path changed to Forward Only since translucency only works in forward rendering" );
|
|
}
|
|
|
|
if( m_translucencyPort.IsConnected != m_previousTranslucencyOn )
|
|
m_checkChanges = true;
|
|
|
|
if( m_refractionPort.IsConnected != m_previousRefractionOn )
|
|
m_checkChanges = true;
|
|
|
|
if( ( m_tessOpHelper.EnableTesselation && !m_tessellationPort.IsConnected ) != m_previousTessellationOn )
|
|
m_checkChanges = true;
|
|
|
|
m_previousTranslucencyOn = m_translucencyPort.IsConnected;
|
|
|
|
m_previousRefractionOn = m_refractionPort.IsConnected;
|
|
|
|
m_previousTessellationOn = ( m_tessOpHelper.EnableTesselation && !m_tessellationPort.IsConnected );
|
|
|
|
if( m_checkChanges )
|
|
{
|
|
if( m_translucencyPort.IsConnected )
|
|
{
|
|
if( m_translucencyReorder == null )
|
|
{
|
|
List<PropertyNode> translucencyList = new List<PropertyNode>();
|
|
for( int i = 0; i < 7; i++ )
|
|
{
|
|
translucencyList.Add( m_dummyProperty );
|
|
}
|
|
|
|
m_translucencyReorder = ScriptableObject.CreateInstance<ReordenatorNode>();
|
|
m_translucencyReorder.ContainerGraph = ContainerGraph;
|
|
m_translucencyReorder.OrderIndex = m_translucencyOrderIndex;
|
|
m_translucencyReorder.Init( "_TranslucencyGroup", "Translucency", translucencyList );
|
|
}
|
|
|
|
UIUtils.RegisterPropertyNode( m_translucencyReorder );
|
|
}
|
|
else
|
|
{
|
|
if( m_translucencyReorder != null )
|
|
UIUtils.UnregisterPropertyNode( m_translucencyReorder );
|
|
}
|
|
|
|
if( m_refractionPort.IsConnected )
|
|
{
|
|
if( m_refractionReorder == null )
|
|
{
|
|
List<PropertyNode> refractionList = new List<PropertyNode>();
|
|
for( int i = 0; i < 2; i++ )
|
|
{
|
|
refractionList.Add( m_dummyProperty );
|
|
}
|
|
|
|
m_refractionReorder = ScriptableObject.CreateInstance<ReordenatorNode>();
|
|
m_refractionReorder.ContainerGraph = ContainerGraph;
|
|
m_refractionReorder.OrderIndex = m_refractionOrderIndex;
|
|
m_refractionReorder.Init( "_RefractionGroup", "Refraction", refractionList );
|
|
}
|
|
|
|
UIUtils.RegisterPropertyNode( m_refractionReorder );
|
|
}
|
|
else
|
|
{
|
|
if( m_refractionReorder != null )
|
|
UIUtils.UnregisterPropertyNode( m_refractionReorder );
|
|
}
|
|
|
|
if( m_tessOpHelper.EnableTesselation && !m_tessellationPort.IsConnected )
|
|
{
|
|
if( m_tessellationReorder == null )
|
|
{
|
|
List<PropertyNode> tessellationList = new List<PropertyNode>();
|
|
for( int i = 0; i < 4; i++ )
|
|
{
|
|
tessellationList.Add( m_dummyProperty );
|
|
}
|
|
|
|
m_tessellationReorder = ScriptableObject.CreateInstance<ReordenatorNode>();
|
|
m_tessellationReorder.ContainerGraph = ContainerGraph;
|
|
m_tessellationReorder.OrderIndex = m_tessellationOrderIndex;
|
|
m_tessellationReorder.Init( "_TessellationGroup", "Tessellation", tessellationList );
|
|
m_tessellationReorder.HeaderTitle = "Tesselation";
|
|
}
|
|
|
|
UIUtils.RegisterPropertyNode( m_tessellationReorder );
|
|
}
|
|
else
|
|
{
|
|
if( m_tessellationReorder != null )
|
|
UIUtils.UnregisterPropertyNode( m_tessellationReorder );
|
|
}
|
|
|
|
if( m_inputPorts[ m_discardPortId ].Available && !m_inlineOpacityMaskClipValue.IsValid )
|
|
{
|
|
if( m_maskClipReorder == null )
|
|
{
|
|
// Create dragable clip material property
|
|
m_maskClipReorder = ScriptableObject.CreateInstance<ReordenatorNode>();
|
|
m_maskClipReorder.ContainerGraph = ContainerGraph;
|
|
m_maskClipReorder.OrderIndex = m_maskClipOrderIndex;
|
|
m_maskClipReorder.Init( "_Cutoff", "Mask Clip Value", null );
|
|
}
|
|
|
|
UIUtils.RegisterPropertyNode( m_maskClipReorder );
|
|
}
|
|
else
|
|
{
|
|
if( m_maskClipReorder != null )
|
|
UIUtils.UnregisterPropertyNode( m_maskClipReorder );
|
|
}
|
|
|
|
m_checkChanges = false;
|
|
}
|
|
}
|
|
|
|
public override void OnNodeRepaint( DrawInfo drawInfo )
|
|
{
|
|
base.OnNodeRepaint( drawInfo );
|
|
|
|
if( m_containerGraph.IsInstancedShader || m_renderingOptionsOpHelper.ForceEnableInstancing )
|
|
{
|
|
DrawInstancedIcon( drawInfo );
|
|
}
|
|
}
|
|
|
|
private void CacheCurrentSettings()
|
|
{
|
|
m_cacheNodeConnections.Clear();
|
|
for( int portId = 0; portId < m_inputPorts.Count; portId++ )
|
|
{
|
|
if( m_inputPorts[ portId ].IsConnected )
|
|
{
|
|
WireReference connection = m_inputPorts[ portId ].GetConnection();
|
|
m_cacheNodeConnections.Add( m_inputPorts[ portId ].Name, new NodeCache( connection.NodeId, connection.PortId ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ConnectFromCache()
|
|
{
|
|
for( int i = 0; i < m_inputPorts.Count; i++ )
|
|
{
|
|
NodeCache cache = m_cacheNodeConnections.Get( m_inputPorts[ i ].Name );
|
|
if( cache != null )
|
|
{
|
|
UIUtils.SetConnection( UniqueId, m_inputPorts[ i ].PortId, cache.TargetNodeId, cache.TargetPortId );
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void UpdateMaterial( Material mat )
|
|
{
|
|
base.UpdateMaterial( mat );
|
|
if( m_alphaMode == AlphaMode.Masked || m_alphaMode == AlphaMode.Custom )
|
|
{
|
|
if( mat.HasProperty( IOUtils.MaskClipValueName ) )
|
|
mat.SetFloat( IOUtils.MaskClipValueName, m_opacityMaskClipValue );
|
|
}
|
|
|
|
if( m_refractionPort.IsConnected && !m_inlineChromaticAberration.Active )
|
|
{
|
|
if( mat.HasProperty( IOUtils.ChromaticAberrationProperty ) )
|
|
mat.SetFloat( IOUtils.ChromaticAberrationProperty, m_inlineChromaticAberration.FloatValue );
|
|
}
|
|
}
|
|
|
|
public override void SetMaterialMode( Material mat, bool fetchMaterialValues )
|
|
{
|
|
base.SetMaterialMode( mat, fetchMaterialValues );
|
|
if( m_alphaMode == AlphaMode.Masked || m_alphaMode == AlphaMode.Custom )
|
|
{
|
|
if( fetchMaterialValues && m_materialMode && mat.HasProperty( IOUtils.MaskClipValueName ) )
|
|
{
|
|
m_opacityMaskClipValue = mat.GetFloat( IOUtils.MaskClipValueName );
|
|
}
|
|
}
|
|
|
|
if( m_refractionPort.IsConnected && !m_inlineChromaticAberration.Active )
|
|
{
|
|
if( fetchMaterialValues && m_materialMode && mat.HasProperty( IOUtils.ChromaticAberrationProperty ) )
|
|
m_inlineChromaticAberration.FloatValue = mat.GetFloat( IOUtils.ChromaticAberrationProperty);
|
|
}
|
|
}
|
|
|
|
public override void ForceUpdateFromMaterial( Material material )
|
|
{
|
|
m_tessOpHelper.UpdateFromMaterial( material );
|
|
m_outlineHelper.UpdateFromMaterial( material );
|
|
|
|
if( m_alphaMode == AlphaMode.Masked || m_alphaMode == AlphaMode.Custom )
|
|
{
|
|
if( material.HasProperty( IOUtils.MaskClipValueName ) )
|
|
m_opacityMaskClipValue = material.GetFloat( IOUtils.MaskClipValueName );
|
|
}
|
|
|
|
if( m_refractionPort.IsConnected && !m_inlineChromaticAberration.Active )
|
|
{
|
|
if( material.HasProperty( IOUtils.ChromaticAberrationProperty ) )
|
|
m_inlineChromaticAberration.FloatValue = material.GetFloat( IOUtils.ChromaticAberrationProperty );
|
|
}
|
|
}
|
|
|
|
public override void UpdateMasterNodeMaterial( Material material )
|
|
{
|
|
m_currentMaterial = material;
|
|
UpdateMaterialEditor();
|
|
}
|
|
|
|
void UpdateMaterialEditor()
|
|
{
|
|
FireMaterialChangedEvt();
|
|
}
|
|
|
|
public string CreateInstructionsForVertexPort( InputPort port )
|
|
{
|
|
//Vertex displacement and per vertex custom data
|
|
WireReference connection = port.GetConnection();
|
|
ParentNode node = UIUtils.GetNode( connection.NodeId );
|
|
|
|
string vertexInstructions = node.GetValueFromOutputStr( connection.PortId, port.DataType, ref m_currentDataCollector, false );
|
|
|
|
if( m_currentDataCollector.DirtySpecialLocalVariables )
|
|
{
|
|
m_currentDataCollector.AddVertexInstruction( m_currentDataCollector.SpecialLocalVariables, UniqueId, false );
|
|
m_currentDataCollector.ClearSpecialLocalVariables();
|
|
}
|
|
|
|
if( m_currentDataCollector.DirtyVertexVariables )
|
|
{
|
|
m_currentDataCollector.AddVertexInstruction( m_currentDataCollector.VertexLocalVariables, UniqueId, false );
|
|
m_currentDataCollector.ClearVertexLocalVariables();
|
|
}
|
|
|
|
return vertexInstructions;
|
|
}
|
|
|
|
public void CreateInstructionsForPort( InputPort port, string portName, bool addCustomDelimiters = false, string customDelimiterIn = null, string customDelimiterOut = null, bool ignoreLocalVar = false, bool normalIsConnected = false , bool isDebugPort = false )
|
|
{
|
|
WireReference connection = port.GetConnection();
|
|
ParentNode node = UIUtils.GetNode( connection.NodeId );
|
|
|
|
string newInstruction = node.GetValueFromOutputStr( connection.PortId, port.DataType, ref m_currentDataCollector, ignoreLocalVar );
|
|
|
|
if( m_currentDataCollector.DirtySpecialLocalVariables )
|
|
{
|
|
m_currentDataCollector.AddInstructions( m_currentDataCollector.SpecialLocalVariables );
|
|
m_currentDataCollector.ClearSpecialLocalVariables();
|
|
}
|
|
|
|
if( m_currentDataCollector.DirtyVertexVariables )
|
|
{
|
|
m_currentDataCollector.AddVertexInstruction( m_currentDataCollector.VertexLocalVariables, port.NodeId, false );
|
|
m_currentDataCollector.ClearVertexLocalVariables();
|
|
}
|
|
|
|
if( m_currentDataCollector.ForceNormal && !normalIsConnected )
|
|
{
|
|
m_currentDataCollector.AddToStartInstructions( "\t\t\t" + Constants.OutputVarStr + ".Normal = float3(0,0,1);\n" );
|
|
m_currentDataCollector.DirtyNormal = true;
|
|
m_currentDataCollector.ForceNormal = false;
|
|
}
|
|
|
|
m_currentDataCollector.AddInstructions( addCustomDelimiters ? customDelimiterIn : ( "\t\t\t" + portName + " = " ) );
|
|
m_currentDataCollector.AddInstructions( newInstruction );
|
|
m_currentDataCollector.AddInstructions( addCustomDelimiters ? customDelimiterOut :((isDebugPort)?" + 1E-5;\n":";\n") );
|
|
}
|
|
|
|
public string CreateInstructionStringForPort( InputPort port, bool ignoreLocalVar = false )
|
|
{
|
|
WireReference connection = port.GetConnection();
|
|
ParentNode node = UIUtils.GetNode( connection.NodeId );
|
|
|
|
string newInstruction = node.GetValueFromOutputStr( connection.PortId, port.DataType, ref m_currentDataCollector, ignoreLocalVar );
|
|
|
|
if( m_currentDataCollector.DirtySpecialLocalVariables )
|
|
{
|
|
m_currentDataCollector.AddInstructions( m_currentDataCollector.SpecialLocalVariables );
|
|
m_currentDataCollector.ClearSpecialLocalVariables();
|
|
}
|
|
|
|
if( m_currentDataCollector.DirtyVertexVariables )
|
|
{
|
|
m_currentDataCollector.AddVertexInstruction( m_currentDataCollector.VertexLocalVariables, port.NodeId, false );
|
|
m_currentDataCollector.ClearVertexLocalVariables();
|
|
}
|
|
|
|
if( m_currentDataCollector.ForceNormal )
|
|
{
|
|
m_currentDataCollector.AddToStartInstructions( "\t\t\t" + Constants.OutputVarStr + ".Normal = float3(0,0,1);\n" );
|
|
m_currentDataCollector.DirtyNormal = true;
|
|
m_currentDataCollector.ForceNormal = false;
|
|
}
|
|
|
|
return newInstruction;
|
|
}
|
|
|
|
public override Shader Execute( string pathname, bool isFullPath )
|
|
{
|
|
ForcePortType();
|
|
ForceReordering();
|
|
UpdateFromBlendMode();
|
|
base.Execute( pathname, isFullPath );
|
|
RegisterStandaloneFuntions();
|
|
|
|
bool isInstancedShader = m_renderingOptionsOpHelper.ForceEnableInstancing || UIUtils.IsInstancedShader();
|
|
bool hasVirtualTexture = UIUtils.HasVirtualTexture();
|
|
bool hasTranslucency = false;
|
|
bool hasTransmission = false;
|
|
bool hasEmission = false;
|
|
bool hasOpacity = false;
|
|
bool hasOpacityMask = false;
|
|
bool hasRefraction = false;
|
|
//bool hasVertexOffset = false;
|
|
//bool hasCustomLightingAlpha = false;
|
|
bool hasCustomLightingMask = false;
|
|
|
|
string customLightingCode = string.Empty;
|
|
string customLightingAlphaCode = string.Empty;
|
|
string customLightingMaskCode = string.Empty;
|
|
string customLightingInstructions = string.Empty;
|
|
|
|
string refractionCode = string.Empty;
|
|
string refractionInstructions = string.Empty;
|
|
string refractionFix = string.Empty;
|
|
|
|
string aboveUsePasses = string.Empty;
|
|
string bellowUsePasses = string.Empty;
|
|
|
|
|
|
m_currentDataCollector.TesselationActive = m_tessOpHelper.EnableTesselation;
|
|
m_currentDataCollector.CurrentRenderPath = m_renderPath;
|
|
|
|
StandardShaderLightModel cachedLightModel = m_currentLightModel;
|
|
NodeAvailability cachedAvailability = ContainerGraph.CurrentCanvasMode;
|
|
|
|
bool debugIsUsingCustomLighting = false;
|
|
bool usingDebugPort = false;
|
|
if( m_inputPorts[ m_inputPorts.Count - 1 ].IsConnected )
|
|
{
|
|
usingDebugPort = true;
|
|
debugIsUsingCustomLighting = m_currentLightModel == StandardShaderLightModel.CustomLighting;
|
|
|
|
m_currentDataCollector.GenType = PortGenType.CustomLighting;
|
|
m_currentLightModel = StandardShaderLightModel.CustomLighting;
|
|
ContainerGraph.CurrentCanvasMode = NodeAvailability.CustomLighting;
|
|
}
|
|
|
|
if( isInstancedShader )
|
|
{
|
|
m_currentDataCollector.AddToPragmas( UniqueId, IOUtils.InstancedPropertiesHeader );
|
|
}
|
|
|
|
if( m_renderingOptionsOpHelper.SpecularHighlightToggle || m_renderingOptionsOpHelper.ReflectionsToggle )
|
|
m_currentDataCollector.AddToProperties( UniqueId, "[Header(Forward Rendering Options)]", 10001 );
|
|
if( m_renderingOptionsOpHelper.SpecularHighlightToggle )
|
|
{
|
|
m_currentDataCollector.AddToProperties( UniqueId, "[ToggleOff] _SpecularHighlights(\"Specular Highlights\", Float) = 1.0", 10002 );
|
|
m_currentDataCollector.AddToPragmas( UniqueId, "shader_feature _SPECULARHIGHLIGHTS_OFF" );
|
|
}
|
|
if( m_renderingOptionsOpHelper.ReflectionsToggle )
|
|
{
|
|
m_currentDataCollector.AddToProperties( UniqueId, "[ToggleOff] _GlossyReflections(\"Reflections\", Float) = 1.0", 10003 );
|
|
m_currentDataCollector.AddToPragmas( UniqueId, "shader_feature _GLOSSYREFLECTIONS_OFF" );
|
|
}
|
|
|
|
|
|
// See if each node is being used on frag and/or vert ports
|
|
SetupNodeCategories();
|
|
m_containerGraph.CheckPropertiesAutoRegister( ref m_currentDataCollector );
|
|
|
|
if( m_refractionPort.IsConnected || m_inputPorts[ m_inputPorts.Count - 1 ].IsConnected )
|
|
{
|
|
m_currentDataCollector.DirtyNormal = true;
|
|
m_currentDataCollector.ForceNormal = true;
|
|
}
|
|
//this.PropagateNodeData( nodeData );
|
|
|
|
string tags = "\"RenderType\" = \"{0}\" \"Queue\" = \"{1}\"";
|
|
string finalRenderType = ( m_renderType == RenderType.Custom && m_customRenderType.Length > 0 ) ? m_customRenderType : m_renderType.ToString();
|
|
tags = string.Format( tags, finalRenderType, ( m_renderQueue + ( ( m_queueOrder >= 0 ) ? "+" : string.Empty ) + m_queueOrder ) );
|
|
//if ( !m_customBlendMode )
|
|
{
|
|
if( m_alphaMode == AlphaMode.Transparent || m_alphaMode == AlphaMode.Premultiply )
|
|
{
|
|
//tags += " \"IgnoreProjector\" = \"True\"";
|
|
if( !m_renderingOptionsOpHelper.IgnoreProjectorValue )
|
|
{
|
|
Debug.Log( string.Format( "Setting Ignore Projector to True since it's requires by Blend Mode {0}.", m_alphaMode ) );
|
|
m_renderingOptionsOpHelper.IgnoreProjectorValue = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
tags += m_renderingOptionsOpHelper.IgnoreProjectorTag;
|
|
tags += m_renderingOptionsOpHelper.ForceNoShadowCastingTag;
|
|
tags += m_renderingOptionsOpHelper.DisableBatchingTag;
|
|
|
|
//add virtual texture support
|
|
if( hasVirtualTexture )
|
|
{
|
|
tags += " \"Amplify\" = \"True\" ";
|
|
}
|
|
|
|
//tags = "Tags{ " + tags + " }";
|
|
|
|
string outputStruct = "";
|
|
switch( m_currentLightModel )
|
|
{
|
|
case StandardShaderLightModel.CustomLighting: outputStruct = "SurfaceOutputCustomLightingCustom"; break;
|
|
case StandardShaderLightModel.Standard: outputStruct = "SurfaceOutputStandard"; break;
|
|
case StandardShaderLightModel.StandardSpecular: outputStruct = "SurfaceOutputStandardSpecular"; break;
|
|
case StandardShaderLightModel.Unlit:
|
|
case StandardShaderLightModel.Lambert:
|
|
case StandardShaderLightModel.BlinnPhong: outputStruct = "SurfaceOutput"; break;
|
|
}
|
|
|
|
if( m_currentLightModel == StandardShaderLightModel.CustomLighting )
|
|
{
|
|
m_currentDataCollector.AddToIncludes( UniqueId, Constants.UnityPBSLightingLib );
|
|
|
|
m_currentDataCollector.ChangeCustomInputHeader( m_currentLightModel.ToString() + Constants.CustomLightStructStr );
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Albedo", true );
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Normal", true );
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Emission", true );
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half Metallic", true );
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half Smoothness", true );
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half Occlusion", true );
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half Alpha", true );
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "Input SurfInput", true );
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "UnityGIInput GIData", true );
|
|
}
|
|
|
|
//Terrain Draw Instanced
|
|
if( m_drawInstancedHelper.Enabled )
|
|
{
|
|
if( !m_currentDataCollector.DirtyPerVertexData )
|
|
{
|
|
m_currentDataCollector.OpenPerVertexHeader( !m_tessOpHelper.EnableTesselation );
|
|
}
|
|
m_drawInstancedHelper.UpdateDataCollectorForStandard( ref m_currentDataCollector );
|
|
}
|
|
|
|
// Need to sort before creating local vars so they can inspect the normal port correctly
|
|
SortedList<int, InputPort> sortedPorts = new SortedList<int, InputPort>();
|
|
for( int i = 0; i < m_inputPorts.Count; i++ )
|
|
{
|
|
sortedPorts.Add( m_inputPorts[ i ].OrderId, m_inputPorts[ i ] );
|
|
}
|
|
|
|
bool normalIsConnected = m_normalPort.IsConnected;
|
|
m_tessOpHelper.Reset();
|
|
if( m_inputPorts[ m_inputPorts.Count - 1 ].IsConnected )
|
|
{
|
|
//Debug Port active
|
|
InputPort debugPort = m_inputPorts[ m_inputPorts.Count - 1 ];
|
|
m_currentDataCollector.PortCategory = debugPort.Category;
|
|
if( debugIsUsingCustomLighting )
|
|
{
|
|
m_currentDataCollector.UsingCustomOutput = true;
|
|
WireReference connection = m_inputPorts[ m_inputPorts.Count - 1 ].GetConnection();
|
|
ParentNode node = UIUtils.GetNode( connection.NodeId );
|
|
customLightingCode = node.GetValueFromOutputStr( connection.PortId, WirePortDataType.FLOAT3, ref m_currentDataCollector, false );
|
|
customLightingInstructions = m_currentDataCollector.CustomOutput;
|
|
|
|
if( m_currentDataCollector.ForceNormal )
|
|
{
|
|
m_currentDataCollector.AddToStartInstructions( "\t\t\t" + Constants.OutputVarStr + ".Normal = float3(0,0,1);\n" );
|
|
m_currentDataCollector.DirtyNormal = true;
|
|
m_currentDataCollector.ForceNormal = false;
|
|
}
|
|
|
|
if( m_currentDataCollector.DirtyVertexVariables )
|
|
{
|
|
m_currentDataCollector.AddVertexInstruction( m_currentDataCollector.VertexLocalVariables, UniqueId, false );
|
|
m_currentDataCollector.ClearVertexLocalVariables();
|
|
}
|
|
m_currentDataCollector.UsingCustomOutput = false;
|
|
}
|
|
else
|
|
{
|
|
CreateInstructionsForPort( debugPort, Constants.OutputVarStr + ".Emission", false, null, null, false, false,true );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MasterNodePortCategory currentCategory = sortedPorts[ 0 ].Category;
|
|
//Collect data from standard nodes
|
|
for( int i = 0; i < sortedPorts.Count; i++ )
|
|
{
|
|
// prepare ports for custom lighting
|
|
m_currentDataCollector.GenType = sortedPorts[ i ].GenType;
|
|
if( m_currentLightModel == StandardShaderLightModel.CustomLighting && sortedPorts[ i ].Name.Equals( AlphaStr ) )
|
|
ContainerGraph.ResetNodesLocalVariablesIfNot( MasterNodePortCategory.Vertex );
|
|
|
|
if( sortedPorts[ i ].IsConnected )
|
|
{
|
|
m_currentDataCollector.PortCategory = sortedPorts[ i ].Category;
|
|
|
|
if( sortedPorts[ i ].Name.Equals( NormalStr ) )// Normal Map is Connected
|
|
{
|
|
m_currentDataCollector.DirtyNormal = true;
|
|
}
|
|
if( sortedPorts[ i ].Name.Equals( TranslucencyStr ) )
|
|
{
|
|
hasTranslucency = true;
|
|
}
|
|
if( sortedPorts[ i ].Name.Equals( TransmissionStr ) )
|
|
{
|
|
hasTransmission = true;
|
|
}
|
|
if( sortedPorts[ i ].Name.Equals( EmissionStr ) )
|
|
{
|
|
hasEmission = true;
|
|
}
|
|
|
|
if( sortedPorts[ i ].Name.Equals( RefractionStr ) )
|
|
{
|
|
hasRefraction = true;
|
|
}
|
|
|
|
if( sortedPorts[ i ].Name.Equals( AlphaStr ) )
|
|
{
|
|
hasOpacity = true;
|
|
}
|
|
|
|
if( sortedPorts[ i ].Name.Equals( DiscardStr ) )
|
|
{
|
|
hasOpacityMask = true;
|
|
}
|
|
|
|
if( hasRefraction )
|
|
{
|
|
m_currentDataCollector.AddToInput( UniqueId, SurfaceInputs.SCREEN_POS );
|
|
m_currentDataCollector.AddToInput( UniqueId, SurfaceInputs.WORLD_POS );
|
|
|
|
//not necessary, just being safe
|
|
m_currentDataCollector.DirtyNormal = true;
|
|
m_currentDataCollector.ForceNormal = true;
|
|
|
|
if( m_grabOrder != 0 )
|
|
{
|
|
m_currentDataCollector.AddGrabPass( "RefractionGrab" + m_grabOrder );
|
|
m_currentDataCollector.AddToUniforms( UniqueId, "uniform sampler2D RefractionGrab" + m_grabOrder + ";" );
|
|
}
|
|
else
|
|
{
|
|
m_currentDataCollector.AddGrabPass( "" );
|
|
m_currentDataCollector.AddToUniforms( UniqueId, "uniform sampler2D _GrabTexture;" );
|
|
}
|
|
|
|
if( !m_inlineChromaticAberration.Active )
|
|
{
|
|
m_currentDataCollector.AddToUniforms( UniqueId, "uniform float _ChromaticAberration;" );
|
|
|
|
m_currentDataCollector.AddToProperties( UniqueId, "[Header(Refraction)]", m_refractionReorder.OrderIndex );
|
|
m_currentDataCollector.AddToProperties( UniqueId, "_ChromaticAberration(\"Chromatic Aberration\", Range( 0 , 0.3)) = 0.1", m_refractionReorder.OrderIndex + 1 );
|
|
}
|
|
|
|
m_currentDataCollector.AddToPragmas( UniqueId, "multi_compile _ALPHAPREMULTIPLY_ON" );
|
|
}
|
|
|
|
if( hasTranslucency || hasTransmission )
|
|
{
|
|
//Translucency and Transmission Generation
|
|
|
|
//Add properties and uniforms
|
|
m_currentDataCollector.AddToIncludes( UniqueId, Constants.UnityPBSLightingLib );
|
|
|
|
if( hasTranslucency )
|
|
{
|
|
m_currentDataCollector.AddToProperties( UniqueId, "[Header(Translucency)]", m_translucencyReorder.OrderIndex );
|
|
m_currentDataCollector.AddToProperties( UniqueId, "_Translucency(\"Strength\", Range( 0 , 50)) = 1", m_translucencyReorder.OrderIndex + 1 );
|
|
m_currentDataCollector.AddToProperties( UniqueId, "_TransNormalDistortion(\"Normal Distortion\", Range( 0 , 1)) = 0.1", m_translucencyReorder.OrderIndex + 2 );
|
|
m_currentDataCollector.AddToProperties( UniqueId, "_TransScattering(\"Scaterring Falloff\", Range( 1 , 50)) = 2", m_translucencyReorder.OrderIndex + 3 );
|
|
m_currentDataCollector.AddToProperties( UniqueId, "_TransDirect(\"Direct\", Range( 0 , 1)) = 1", m_translucencyReorder.OrderIndex + 4 );
|
|
m_currentDataCollector.AddToProperties( UniqueId, "_TransAmbient(\"Ambient\", Range( 0 , 1)) = 0.2", m_translucencyReorder.OrderIndex + 5 );
|
|
m_currentDataCollector.AddToProperties( UniqueId, "_TransShadow(\"Shadow\", Range( 0 , 1)) = 0.9", m_translucencyReorder.OrderIndex + 6 );
|
|
|
|
m_currentDataCollector.AddToUniforms( UniqueId, "uniform half _Translucency;" );
|
|
m_currentDataCollector.AddToUniforms( UniqueId, "uniform half _TransNormalDistortion;" );
|
|
m_currentDataCollector.AddToUniforms( UniqueId, "uniform half _TransScattering;" );
|
|
m_currentDataCollector.AddToUniforms( UniqueId, "uniform half _TransDirect;" );
|
|
m_currentDataCollector.AddToUniforms( UniqueId, "uniform half _TransAmbient;" );
|
|
m_currentDataCollector.AddToUniforms( UniqueId, "uniform half _TransShadow;" );
|
|
}
|
|
|
|
//Add custom struct
|
|
switch( m_currentLightModel )
|
|
{
|
|
case StandardShaderLightModel.Standard:
|
|
case StandardShaderLightModel.StandardSpecular:
|
|
outputStruct = "SurfaceOutput" + m_currentLightModel.ToString() + Constants.CustomLightStructStr; break;
|
|
}
|
|
|
|
m_currentDataCollector.ChangeCustomInputHeader( m_currentLightModel.ToString() + Constants.CustomLightStructStr );
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Albedo", true );
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Normal", true );
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Emission", true );
|
|
switch( m_currentLightModel )
|
|
{
|
|
case StandardShaderLightModel.Standard:
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half Metallic", true );
|
|
break;
|
|
case StandardShaderLightModel.StandardSpecular:
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Specular", true );
|
|
break;
|
|
}
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half Smoothness", true );
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half Occlusion", true );
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half Alpha", true );
|
|
if( hasTranslucency )
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Translucency", true );
|
|
|
|
if( hasTransmission )
|
|
m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Transmission", true );
|
|
}
|
|
|
|
if( sortedPorts[ i ].Name.Equals( DiscardStr ) )
|
|
{
|
|
//Discard Op Node
|
|
if( m_currentLightModel == StandardShaderLightModel.CustomLighting )
|
|
{
|
|
hasCustomLightingMask = true;
|
|
m_currentDataCollector.UsingCustomOutput = true;
|
|
m_currentDataCollector.GenType = PortGenType.CustomLighting;
|
|
WireReference connection = sortedPorts[ i ].GetConnection();
|
|
ParentNode node = UIUtils.GetNode( connection.NodeId );
|
|
|
|
customLightingMaskCode = node.GetValueFromOutputStr( connection.PortId, WirePortDataType.FLOAT, ref m_currentDataCollector, false );
|
|
customLightingMaskCode = "clip( " + customLightingMaskCode + " - " + m_inlineOpacityMaskClipValue.GetValueOrProperty( IOUtils.MaskClipValueName, false ) + " )";
|
|
customLightingInstructions = m_currentDataCollector.CustomOutput;
|
|
|
|
m_currentDataCollector.GenType = PortGenType.NonCustomLighting;
|
|
m_currentDataCollector.UsingCustomOutput = false;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
string clipIn = "\t\t\tclip( ";
|
|
string clipOut = " - " + m_inlineOpacityMaskClipValue.GetValueOrProperty( IOUtils.MaskClipValueName, false ) + " );\n";
|
|
//if( ( m_alphaToCoverage || m_inlineAlphaToCoverage.Active ) && m_castShadows )
|
|
//{
|
|
// clipIn = "\t\t\t#if UNITY_PASS_SHADOWCASTER\n" + clipIn;
|
|
// clipOut = clipOut + "\t\t\t#endif\n";
|
|
//}
|
|
CreateInstructionsForPort( sortedPorts[ i ], Constants.OutputVarStr + "." + sortedPorts[ i ].DataName, true, clipIn, clipOut, false, normalIsConnected );
|
|
}
|
|
}
|
|
else if( sortedPorts[ i ].DataName.Equals( VertexDataStr ) )
|
|
{
|
|
string vertexInstructions = CreateInstructionsForVertexPort( sortedPorts[ i ] );
|
|
m_currentDataCollector.AddToVertexDisplacement( vertexInstructions, m_vertexMode );
|
|
}
|
|
else if( sortedPorts[ i ].DataName.Equals( VertexNormalStr ) )
|
|
{
|
|
string vertexInstructions = CreateInstructionsForVertexPort( sortedPorts[ i ] );
|
|
m_currentDataCollector.AddToVertexNormal( vertexInstructions );
|
|
}
|
|
else if( m_tessOpHelper.IsTessellationPort( sortedPorts[ i ].PortId ) && sortedPorts[ i ].IsConnected /* && m_tessOpHelper.EnableTesselation*/)
|
|
{
|
|
//Vertex displacement and per vertex custom data
|
|
WireReference connection = sortedPorts[ i ].GetConnection();
|
|
ParentNode node = UIUtils.GetNode( connection.NodeId );
|
|
|
|
string vertexInstructions = node.GetValueFromOutputStr( connection.PortId, sortedPorts[ i ].DataType, ref m_currentDataCollector, false );
|
|
|
|
if( m_currentDataCollector.DirtySpecialLocalVariables )
|
|
{
|
|
m_tessOpHelper.AddAdditionalData( m_currentDataCollector.SpecialLocalVariables );
|
|
m_currentDataCollector.ClearSpecialLocalVariables();
|
|
}
|
|
|
|
if( m_currentDataCollector.DirtyVertexVariables )
|
|
{
|
|
m_tessOpHelper.AddAdditionalData( m_currentDataCollector.VertexLocalVariables );
|
|
m_currentDataCollector.ClearVertexLocalVariables();
|
|
}
|
|
|
|
m_tessOpHelper.AddCustomFunction( vertexInstructions );
|
|
}
|
|
else if( sortedPorts[ i ].Name.Equals( RefractionStr ) )
|
|
{
|
|
ContainerGraph.ResetNodesLocalVariables();
|
|
m_currentDataCollector.UsingCustomOutput = true;
|
|
|
|
refractionFix = " + 0.00001 * i.screenPos * i.worldPos";
|
|
m_currentDataCollector.AddInstructions( "\t\t\to.Normal = o.Normal" + refractionFix + ";\n" );
|
|
refractionCode = CreateInstructionStringForPort( sortedPorts[ i ], false );
|
|
refractionInstructions = m_currentDataCollector.CustomOutput;
|
|
|
|
m_currentDataCollector.UsingCustomOutput = false;
|
|
}
|
|
else if( sortedPorts[ i ].Name.Equals( CustomLightingStr ) )
|
|
{
|
|
m_currentDataCollector.UsingCustomOutput = true;
|
|
WireReference connection = sortedPorts[ i ].GetConnection();
|
|
ParentNode node = UIUtils.GetNode( connection.NodeId );
|
|
|
|
customLightingCode = node.GetValueFromOutputStr( connection.PortId, WirePortDataType.FLOAT3, ref m_currentDataCollector, false );
|
|
customLightingInstructions = m_currentDataCollector.CustomOutput;
|
|
|
|
if( m_currentDataCollector.ForceNormal )
|
|
{
|
|
m_currentDataCollector.AddToStartInstructions( "\t\t\t" + Constants.OutputVarStr + ".Normal = float3(0,0,1);\n" );
|
|
m_currentDataCollector.DirtyNormal = true;
|
|
m_currentDataCollector.ForceNormal = false;
|
|
}
|
|
|
|
if( m_currentDataCollector.DirtyVertexVariables )
|
|
{
|
|
m_currentDataCollector.AddVertexInstruction( m_currentDataCollector.VertexLocalVariables, UniqueId, false );
|
|
m_currentDataCollector.ClearVertexLocalVariables();
|
|
}
|
|
|
|
m_currentDataCollector.UsingCustomOutput = false;
|
|
|
|
}
|
|
else if( sortedPorts[ i ].Name.Equals( AlphaStr ) && m_currentLightModel == StandardShaderLightModel.CustomLighting )
|
|
{
|
|
m_currentDataCollector.UsingCustomOutput = true;
|
|
m_currentDataCollector.GenType = PortGenType.CustomLighting;
|
|
|
|
WireReference connection = sortedPorts[ i ].GetConnection();
|
|
ParentNode node = UIUtils.GetNode( connection.NodeId );
|
|
|
|
customLightingAlphaCode = node.GetValueFromOutputStr( connection.PortId, WirePortDataType.FLOAT, ref m_currentDataCollector, false );
|
|
customLightingInstructions = m_currentDataCollector.CustomOutput;
|
|
|
|
if( m_currentDataCollector.ForceNormal )
|
|
{
|
|
m_currentDataCollector.AddToStartInstructions( "\t\t\t" + Constants.OutputVarStr + ".Normal = float3(0,0,1);\n" );
|
|
m_currentDataCollector.DirtyNormal = true;
|
|
m_currentDataCollector.ForceNormal = false;
|
|
}
|
|
|
|
if( m_currentDataCollector.DirtyVertexVariables )
|
|
{
|
|
m_currentDataCollector.AddVertexInstruction( m_currentDataCollector.VertexLocalVariables, UniqueId, false );
|
|
m_currentDataCollector.ClearVertexLocalVariables();
|
|
}
|
|
|
|
m_currentDataCollector.GenType = PortGenType.NonCustomLighting;
|
|
m_currentDataCollector.UsingCustomOutput = false;
|
|
}
|
|
else
|
|
{
|
|
// Surface shader instruccions
|
|
// if working on normals and have normal dependent node then ignore local var generation
|
|
CreateInstructionsForPort( sortedPorts[ i ], Constants.OutputVarStr + "." + sortedPorts[ i ].DataName, false, null, null, false, normalIsConnected );
|
|
}
|
|
}
|
|
else if( sortedPorts[ i ].Name.Equals( AlphaStr ) )
|
|
{
|
|
if( m_currentLightModel != StandardShaderLightModel.CustomLighting )
|
|
{
|
|
m_currentDataCollector.AddInstructions( string.Format( "\t\t\t{0}.{1} = 1;\n", Constants.OutputVarStr, sortedPorts[ i ].DataName ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
m_billboardOpHelper.FillDataCollectorWithInternalData( ref m_currentDataCollector );
|
|
}
|
|
|
|
m_customShadowCaster = CustomShadowCaster;
|
|
//if( !m_renderingOptionsOpHelper.UseDefaultShadowCaster &&
|
|
// ( ( m_castShadows && ( m_alphaToCoverage || m_inlineAlphaToCoverage.Active ) ) ||
|
|
// ( m_castShadows && hasOpacity ) ||
|
|
// ( m_castShadows && ( m_currentDataCollector.UsingWorldNormal || m_currentDataCollector.UsingWorldReflection || m_currentDataCollector.UsingViewDirection ) ) ||
|
|
// ( m_castShadows && m_inputPorts[ m_discardPortId ].Available && m_inputPorts[ m_discardPortId ].IsConnected && m_currentLightModel == StandardShaderLightModel.CustomLighting ) ))
|
|
// m_customShadowCaster = true;
|
|
//else
|
|
// m_customShadowCaster = false;
|
|
|
|
//m_customShadowCaster = true;
|
|
|
|
for( int i = 0; i < 4; i++ )
|
|
{
|
|
if( m_currentDataCollector.GetChannelUsage( i ) == TextureChannelUsage.Required )
|
|
{
|
|
string channelName = UIUtils.GetChannelName( i );
|
|
m_currentDataCollector.AddToProperties( -1, UIUtils.GetTex2DProperty( channelName, TexturePropertyValues.white ), -1 );
|
|
}
|
|
}
|
|
|
|
m_currentDataCollector.AddToProperties( -1, IOUtils.DefaultASEDirtyCheckProperty, 10000 );
|
|
if( m_inputPorts[ m_discardPortId ].Available && m_inputPorts[ m_discardPortId ].IsConnected )
|
|
{
|
|
if( m_inlineOpacityMaskClipValue.IsValid )
|
|
{
|
|
RangedFloatNode fnode = UIUtils.GetNode( m_inlineOpacityMaskClipValue.NodeId ) as RangedFloatNode;
|
|
if( fnode != null )
|
|
{
|
|
m_currentDataCollector.AddToProperties( fnode.UniqueId, fnode.GetPropertyValue(), fnode.OrderIndex );
|
|
m_currentDataCollector.AddToUniforms( fnode.UniqueId, fnode.GetUniformValue() );
|
|
}
|
|
else
|
|
{
|
|
IntNode inode = UIUtils.GetNode( m_inlineOpacityMaskClipValue.NodeId ) as IntNode;
|
|
m_currentDataCollector.AddToProperties( inode.UniqueId, inode.GetPropertyValue(), inode.OrderIndex );
|
|
m_currentDataCollector.AddToUniforms( inode.UniqueId, inode.GetUniformValue() );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_currentDataCollector.AddToProperties( -1, string.Format( IOUtils.MaskClipValueProperty, OpacityMaskClipValueStr, m_opacityMaskClipValue ), ( m_maskClipReorder != null ) ? m_maskClipReorder.OrderIndex : -1 );
|
|
m_currentDataCollector.AddToUniforms( -1, string.Format( IOUtils.MaskClipValueUniform, m_opacityMaskClipValue ) );
|
|
}
|
|
}
|
|
|
|
if( !m_currentDataCollector.DirtyInputs )
|
|
m_currentDataCollector.AddToInput( UniqueId, "half filler", true );
|
|
|
|
if( m_currentLightModel == StandardShaderLightModel.BlinnPhong )
|
|
m_currentDataCollector.AddToProperties( -1, "_SpecColor(\"Specular Color\",Color)=(1,1,1,1)", m_specColorReorder.OrderIndex );
|
|
|
|
//Tesselation
|
|
if( m_tessOpHelper.EnableTesselation )
|
|
{
|
|
m_tessOpHelper.AddToDataCollector( ref m_currentDataCollector, m_tessellationReorder != null ? m_tessellationReorder.OrderIndex : -1 );
|
|
if( !m_currentDataCollector.DirtyPerVertexData )
|
|
{
|
|
m_currentDataCollector.OpenPerVertexHeader( false );
|
|
}
|
|
}
|
|
|
|
|
|
if( m_outlineHelper.EnableOutline || ( m_currentDataCollector.UsingCustomOutlineColor || m_currentDataCollector.CustomOutlineSelectedAlpha > 0 || m_currentDataCollector.UsingCustomOutlineWidth ) )
|
|
{
|
|
m_outlineHelper.AddToDataCollector( ref m_currentDataCollector );
|
|
}
|
|
|
|
#if !UNITY_2017_1_OR_NEWER
|
|
if( m_renderingOptionsOpHelper.LodCrossfade )
|
|
{
|
|
m_currentDataCollector.AddToPragmas( UniqueId, "multi_compile _ LOD_FADE_CROSSFADE" );
|
|
m_currentDataCollector.AddToStartInstructions( "\t\t\tUNITY_APPLY_DITHER_CROSSFADE(i);\n" );
|
|
m_currentDataCollector.AddToInput( UniqueId, "UNITY_DITHER_CROSSFADE_COORDS", false );
|
|
m_currentDataCollector.AddVertexInstruction( "UNITY_TRANSFER_DITHER_CROSSFADE( " + Constants.VertexShaderOutputStr + ", " + Constants.VertexShaderInputStr + ".vertex )", UniqueId, true );
|
|
}
|
|
#endif
|
|
//m_additionalIncludes.AddToDataCollector( ref m_currentDataCollector );
|
|
//m_additionalPragmas.AddToDataCollector( ref m_currentDataCollector );
|
|
//m_additionalDefines.AddToDataCollector( ref m_currentDataCollector );
|
|
m_additionalDirectives.AddAllToDataCollector( ref m_currentDataCollector );
|
|
|
|
//m_currentDataCollector.CloseInputs();
|
|
m_currentDataCollector.CloseCustomInputs();
|
|
m_currentDataCollector.CloseProperties();
|
|
m_currentDataCollector.ClosePerVertexHeader();
|
|
|
|
//build Shader Body
|
|
string ShaderBody = string.Empty;
|
|
OpenShaderBody( ref ShaderBody, m_shaderName );
|
|
{
|
|
//set properties
|
|
if( m_currentDataCollector.DirtyProperties )
|
|
{
|
|
ShaderBody += m_currentDataCollector.BuildPropertiesString();
|
|
}
|
|
//set subshader
|
|
OpenSubShaderBody( ref ShaderBody );
|
|
{
|
|
|
|
// Add extra depth pass
|
|
m_zBufferHelper.DrawExtraDepthPass( ref ShaderBody );
|
|
|
|
// Add optionalPasses
|
|
if( m_outlineHelper.EnableOutline || ( m_currentDataCollector.UsingCustomOutlineColor || m_currentDataCollector.CustomOutlineSelectedAlpha > 0 || m_currentDataCollector.UsingCustomOutlineWidth ) )
|
|
{
|
|
if( !usingDebugPort )
|
|
AddMultilineBody( ref ShaderBody, m_outlineHelper.OutlineFunctionBody( ref m_currentDataCollector, isInstancedShader, m_customShadowCaster, UIUtils.RemoveInvalidCharacters( ShaderName ), ( m_billboardOpHelper.IsBillboard && !usingDebugPort ? m_billboardOpHelper.GetInternalMultilineInstructions() : null ), ref m_tessOpHelper, ShaderModelTypeArr[ m_shaderModelIdx ], CurrentPrecisionType ) );
|
|
}
|
|
|
|
//Add SubShader tags
|
|
if( hasEmission )
|
|
{
|
|
tags += " \"IsEmissive\" = \"true\" ";
|
|
}
|
|
|
|
tags += m_customTagsHelper.GenerateCustomTags();
|
|
|
|
tags = "Tags{ " + tags + " }";
|
|
m_usePass.BuildUsePassInfo( m_currentDataCollector, ref aboveUsePasses, ref bellowUsePasses, "\t\t" );
|
|
if( !string.IsNullOrEmpty( aboveUsePasses ) )
|
|
{
|
|
ShaderBody += aboveUsePasses;
|
|
}
|
|
|
|
AddRenderTags( ref ShaderBody, tags );
|
|
AddShaderLOD( ref ShaderBody, ShaderLOD );
|
|
AddRenderState( ref ShaderBody, "Cull", m_inlineCullMode.GetValueOrProperty( m_cullMode.ToString() ) );
|
|
m_customBlendAvailable = ( m_alphaMode == AlphaMode.Custom || m_alphaMode == AlphaMode.Opaque );
|
|
if( ( m_zBufferHelper.IsActive && m_customBlendAvailable ) || m_outlineHelper.UsingZWrite || m_outlineHelper.UsingZTest )
|
|
{
|
|
ShaderBody += m_zBufferHelper.CreateDepthInfo( m_outlineHelper.UsingZWrite, m_outlineHelper.UsingZTest );
|
|
}
|
|
if( m_stencilBufferHelper.Active )
|
|
{
|
|
ShaderBody += m_stencilBufferHelper.CreateStencilOp( this );
|
|
}
|
|
|
|
if( m_blendOpsHelper.Active )
|
|
{
|
|
ShaderBody += m_blendOpsHelper.CreateBlendOps();
|
|
}
|
|
|
|
if( m_alphaToCoverage || m_inlineAlphaToCoverage.Active )
|
|
{
|
|
ShaderBody += "\t\tAlphaToMask "+ m_inlineAlphaToCoverage.GetValueOrProperty( "On" )+"\n";
|
|
}
|
|
|
|
// Build Color Mask
|
|
m_colorMaskHelper.BuildColorMask( ref ShaderBody, m_customBlendAvailable );
|
|
|
|
//ShaderBody += "\t\tZWrite " + _zWriteMode + '\n';
|
|
//ShaderBody += "\t\tZTest " + _zTestMode + '\n';
|
|
|
|
//Add GrabPass
|
|
if( m_currentDataCollector.DirtyGrabPass )
|
|
{
|
|
ShaderBody += m_currentDataCollector.GrabPass;
|
|
}
|
|
|
|
// build optional parameters
|
|
string OptionalParameters = string.Empty;
|
|
|
|
// addword standard to custom lighting to accepts standard lighting models
|
|
string standardCustomLighting = string.Empty;
|
|
if( m_currentLightModel == StandardShaderLightModel.CustomLighting )
|
|
standardCustomLighting = "Standard";
|
|
|
|
//add cg program
|
|
if( m_customShadowCaster )
|
|
OpenCGInclude( ref ShaderBody );
|
|
else
|
|
OpenCGProgram( ref ShaderBody );
|
|
{
|
|
//Add Defines
|
|
if( m_currentDataCollector.DirtyDefines )
|
|
ShaderBody += m_currentDataCollector.Defines;
|
|
|
|
//Add Includes
|
|
if( m_customShadowCaster )
|
|
{
|
|
m_currentDataCollector.AddToIncludes( UniqueId, Constants.UnityPBSLightingLib );
|
|
m_currentDataCollector.AddToIncludes( UniqueId, "Lighting.cginc" );
|
|
}
|
|
if( m_currentDataCollector.DirtyIncludes )
|
|
ShaderBody += m_currentDataCollector.Includes;
|
|
|
|
//define as surface shader and specify lighting model
|
|
if( UIUtils.GetTextureArrayNodeAmount() > 0 && m_shaderModelIdx < 3 )
|
|
{
|
|
UIUtils.ShowMessage( "Automatically changing Shader Model to 3.5 since\nit's the minimum required by texture arrays." );
|
|
m_shaderModelIdx = 3;
|
|
}
|
|
|
|
// if tessellation is active then we need be at least using shader model 4.6
|
|
if( m_tessOpHelper.EnableTesselation && m_shaderModelIdx < 6 )
|
|
{
|
|
UIUtils.ShowMessage( "Automatically changing Shader Model to 4.6 since\nit's the minimum required by tessellation." );
|
|
m_shaderModelIdx = 6;
|
|
}
|
|
|
|
// if translucency is ON change render path
|
|
if( hasTranslucency && m_renderPath != RenderPath.ForwardOnly )
|
|
{
|
|
UIUtils.ShowMessage( "Automatically changing Render Path to Forward Only since\ntranslucency only works in forward rendering." );
|
|
m_renderPath = RenderPath.ForwardOnly;
|
|
}
|
|
|
|
// if outline is ON change render path
|
|
if( m_outlineHelper.EnableOutline && m_renderPath != RenderPath.ForwardOnly )
|
|
{
|
|
UIUtils.ShowMessage( "Automatically changing Render Path to Forward Only since\noutline only works in forward rendering." );
|
|
m_renderPath = RenderPath.ForwardOnly;
|
|
}
|
|
|
|
// if transmission is ON change render path
|
|
if( hasTransmission && m_renderPath != RenderPath.ForwardOnly )
|
|
{
|
|
UIUtils.ShowMessage( "Automatically changing Render Path to Forward Only since\ntransmission only works in forward rendering." );
|
|
m_renderPath = RenderPath.ForwardOnly;
|
|
}
|
|
|
|
// if refraction is ON change render path
|
|
if( hasRefraction && m_renderPath != RenderPath.ForwardOnly )
|
|
{
|
|
UIUtils.ShowMessage( "Automatically changing Render Path to Forward Only since\nrefraction only works in forward rendering." );
|
|
m_renderPath = RenderPath.ForwardOnly;
|
|
}
|
|
|
|
ShaderBody += string.Format( IOUtils.PragmaTargetHeader, ShaderModelTypeArr[ m_shaderModelIdx ] );
|
|
|
|
|
|
//Add pragmas (needs check to see if all pragmas work with custom shadow caster)
|
|
if( m_currentDataCollector.DirtyPragmas/* && !m_customShadowCaster */)
|
|
ShaderBody += m_currentDataCollector.Pragmas;
|
|
|
|
CheckSamplingMacrosFlag();
|
|
m_currentDataCollector.AddASEMacros();
|
|
if( m_currentDataCollector.DirtyAdditionalDirectives )
|
|
ShaderBody += m_currentDataCollector.StandardAdditionalDirectives;
|
|
|
|
//if ( !m_customBlendMode )
|
|
{
|
|
switch( m_alphaMode )
|
|
{
|
|
case AlphaMode.Opaque:
|
|
case AlphaMode.Masked: break;
|
|
case AlphaMode.Transparent:
|
|
{
|
|
OptionalParameters += "alpha:fade" + Constants.OptionalParametersSep;
|
|
}
|
|
break;
|
|
case AlphaMode.Premultiply:
|
|
{
|
|
OptionalParameters += "alpha:premul" + Constants.OptionalParametersSep;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( m_keepAlpha )
|
|
{
|
|
OptionalParameters += "keepalpha" + Constants.OptionalParametersSep;
|
|
}
|
|
|
|
if( hasRefraction )
|
|
{
|
|
OptionalParameters += "finalcolor:RefractionF" + Constants.OptionalParametersSep;
|
|
}
|
|
|
|
if( !m_customShadowCaster && m_castShadows )
|
|
{
|
|
OptionalParameters += "addshadow" + Constants.OptionalParametersSep;
|
|
}
|
|
|
|
if( m_castShadows )
|
|
{
|
|
OptionalParameters += "fullforwardshadows" + Constants.OptionalParametersSep;
|
|
}
|
|
|
|
if( !m_receiveShadows )
|
|
{
|
|
OptionalParameters += "noshadow" + Constants.OptionalParametersSep;
|
|
}
|
|
|
|
if( m_renderingOptionsOpHelper.IsOptionActive( " Add Pass" ) && usingDebugPort )
|
|
{
|
|
OptionalParameters += "noforwardadd" + Constants.OptionalParametersSep;
|
|
}
|
|
|
|
if( m_renderingOptionsOpHelper.ForceDisableInstancing )
|
|
{
|
|
OptionalParameters += "noinstancing" + Constants.OptionalParametersSep;
|
|
}
|
|
|
|
switch( m_renderPath )
|
|
{
|
|
case RenderPath.All: break;
|
|
case RenderPath.DeferredOnly: OptionalParameters += "exclude_path:forward" + Constants.OptionalParametersSep; break;
|
|
case RenderPath.ForwardOnly: OptionalParameters += "exclude_path:deferred" + Constants.OptionalParametersSep; break;
|
|
}
|
|
|
|
//Add code generation options
|
|
m_renderingOptionsOpHelper.Build( ref OptionalParameters );
|
|
|
|
if( !m_customShadowCaster )
|
|
{
|
|
string customLightSurface = string.Empty;
|
|
if( hasTranslucency || hasTransmission )
|
|
customLightSurface = "Custom";
|
|
m_renderingPlatformOpHelper.SetRenderingPlatforms( ref ShaderBody );
|
|
|
|
//Check if Custom Vertex is being used and add tag
|
|
if( m_currentDataCollector.DirtyPerVertexData )
|
|
OptionalParameters += "vertex:" + Constants.VertexDataFunc + Constants.OptionalParametersSep;
|
|
|
|
if( m_tessOpHelper.EnableTesselation && !usingDebugPort )
|
|
{
|
|
m_tessOpHelper.WriteToOptionalParams( ref OptionalParameters );
|
|
}
|
|
|
|
m_additionalSurfaceOptions.WriteToOptionalSurfaceOptions( ref OptionalParameters );
|
|
|
|
AddShaderPragma( ref ShaderBody, "surface surf " + standardCustomLighting + m_currentLightModel.ToString() + customLightSurface + Constants.OptionalParametersSep + OptionalParameters );
|
|
}
|
|
else
|
|
{
|
|
if( /*m_currentDataCollector.UsingWorldNormal ||*/ m_currentDataCollector.UsingInternalData )
|
|
{
|
|
ShaderBody += "\t\t#ifdef UNITY_PASS_SHADOWCASTER\n";
|
|
ShaderBody += "\t\t\t#undef INTERNAL_DATA\n";
|
|
ShaderBody += "\t\t\t#undef WorldReflectionVector\n";
|
|
ShaderBody += "\t\t\t#undef WorldNormalVector\n";
|
|
ShaderBody += "\t\t\t#define INTERNAL_DATA half3 internalSurfaceTtoW0; half3 internalSurfaceTtoW1; half3 internalSurfaceTtoW2;\n";
|
|
ShaderBody += "\t\t\t#define WorldReflectionVector(data,normal) reflect (data.worldRefl, half3(dot(data.internalSurfaceTtoW0,normal), dot(data.internalSurfaceTtoW1,normal), dot(data.internalSurfaceTtoW2,normal)))\n";
|
|
ShaderBody += "\t\t\t#define WorldNormalVector(data,normal) half3(dot(data.internalSurfaceTtoW0,normal), dot(data.internalSurfaceTtoW1,normal), dot(data.internalSurfaceTtoW2,normal))\n";
|
|
ShaderBody += "\t\t#endif\n";
|
|
}
|
|
}
|
|
|
|
if( m_currentDataCollector.UsingHigherSizeTexcoords )
|
|
{
|
|
ShaderBody += "\t\t#undef TRANSFORM_TEX\n";
|
|
ShaderBody += "\t\t#define TRANSFORM_TEX(tex,name) float4(tex.xy * name##_ST.xy + name##_ST.zw, tex.z, tex.w)\n";
|
|
}
|
|
|
|
if( m_currentDataCollector.DirtyAppData )
|
|
ShaderBody += m_currentDataCollector.CustomAppData;
|
|
|
|
// Add Input struct
|
|
if( m_currentDataCollector.DirtyInputs )
|
|
ShaderBody += "\t\t" + m_currentDataCollector.Inputs + "\t\t};" + "\n\n";
|
|
|
|
// Add Custom Lighting struct
|
|
if( m_currentDataCollector.DirtyCustomInput )
|
|
ShaderBody += m_currentDataCollector.CustomInput + "\n\n";
|
|
|
|
//Add Uniforms
|
|
if( m_currentDataCollector.DirtyUniforms )
|
|
ShaderBody += m_currentDataCollector.Uniforms + "\n";
|
|
|
|
// Add Array Derivatives Macros
|
|
//if( m_currentDataCollector.UsingArrayDerivatives )
|
|
//{
|
|
// ShaderBody += "\t\t#if defined(UNITY_COMPILER_HLSL2GLSL) || defined(SHADER_TARGET_SURFACE_ANALYSIS)\n";
|
|
// ShaderBody += "\t\t\t#define ASE_SAMPLE_TEX2DARRAY_GRAD(tex,coord,dx,dy) UNITY_SAMPLE_TEX2DARRAY (tex,coord)\n";
|
|
// ShaderBody += "\t\t#else\n";
|
|
// ShaderBody += "\t\t\t#define ASE_SAMPLE_TEX2DARRAY_GRAD(tex,coord,dx,dy) tex.SampleGrad (sampler##tex,coord,dx,dy)\n";
|
|
// ShaderBody += "\t\t#endif\n\n";
|
|
//}
|
|
|
|
//Add Instanced Properties
|
|
if( isInstancedShader && m_currentDataCollector.DirtyInstancedProperties )
|
|
{
|
|
m_currentDataCollector.SetupInstancePropertiesBlock( UIUtils.RemoveInvalidCharacters( ShaderName ) );
|
|
ShaderBody += m_currentDataCollector.InstancedProperties + "\n";
|
|
}
|
|
|
|
if( m_currentDataCollector.DirtyFunctions )
|
|
ShaderBody += m_currentDataCollector.Functions + "\n";
|
|
|
|
|
|
//Tesselation
|
|
if( m_tessOpHelper.EnableTesselation && !usingDebugPort )
|
|
{
|
|
ShaderBody += m_tessOpHelper.GetCurrentTessellationFunction + "\n";
|
|
}
|
|
|
|
//Add Custom Vertex Data
|
|
if( m_currentDataCollector.DirtyPerVertexData )
|
|
{
|
|
ShaderBody += m_currentDataCollector.VertexData;
|
|
}
|
|
|
|
if( m_currentLightModel == StandardShaderLightModel.Unlit )
|
|
{
|
|
for( int i = 0; i < VertexLitFunc.Length; i++ )
|
|
{
|
|
ShaderBody += VertexLitFunc[ i ] + "\n";
|
|
}
|
|
}
|
|
|
|
//Add custom lighting
|
|
if( m_currentLightModel == StandardShaderLightModel.CustomLighting )
|
|
{
|
|
ShaderBody += "\t\tinline half4 LightingStandard" + m_currentLightModel.ToString() + "( inout " + outputStruct + " " + Constants.CustomLightOutputVarStr + ", half3 viewDir, UnityGI gi )\n\t\t{\n";
|
|
ShaderBody += "\t\t\tUnityGIInput data = s.GIData;\n";
|
|
ShaderBody += "\t\t\tInput i = s.SurfInput;\n";
|
|
ShaderBody += "\t\t\thalf4 c = 0;\n";
|
|
if( m_currentDataCollector.UsingLightAttenuation )
|
|
{
|
|
ShaderBody += "\t\t\t#ifdef UNITY_PASS_FORWARDBASE\n";
|
|
ShaderBody += "\t\t\tfloat ase_lightAtten = data.atten;\n";
|
|
ShaderBody += "\t\t\tif( _LightColor0.a == 0)\n";
|
|
ShaderBody += "\t\t\tase_lightAtten = 0;\n";
|
|
ShaderBody += "\t\t\t#else\n";
|
|
ShaderBody += "\t\t\tfloat3 ase_lightAttenRGB = gi.light.color / ( ( _LightColor0.rgb ) + 0.000001 );\n";
|
|
ShaderBody += "\t\t\tfloat ase_lightAtten = max( max( ase_lightAttenRGB.r, ase_lightAttenRGB.g ), ase_lightAttenRGB.b );\n";
|
|
ShaderBody += "\t\t\t#endif\n";
|
|
|
|
ShaderBody += "\t\t\t#if defined(HANDLE_SHADOWS_BLENDING_IN_GI)\n";
|
|
ShaderBody += "\t\t\thalf bakedAtten = UnitySampleBakedOcclusion(data.lightmapUV.xy, data.worldPos);\n";
|
|
ShaderBody += "\t\t\tfloat zDist = dot(_WorldSpaceCameraPos - data.worldPos, UNITY_MATRIX_V[2].xyz);\n";
|
|
ShaderBody += "\t\t\tfloat fadeDist = UnityComputeShadowFadeDistance(data.worldPos, zDist);\n";
|
|
ShaderBody += "\t\t\tase_lightAtten = UnityMixRealtimeAndBakedShadows(data.atten, bakedAtten, UnityComputeShadowFade(fadeDist));\n";
|
|
ShaderBody += "\t\t\t#endif\n";
|
|
}
|
|
|
|
//if( m_currentDataCollector.dirtyc )
|
|
ShaderBody += customLightingInstructions;
|
|
ShaderBody += "\t\t\tc.rgb = " + ( !string.IsNullOrEmpty( customLightingCode ) ? customLightingCode : "0" ) + ";\n";
|
|
ShaderBody += "\t\t\tc.a = " + ( !string.IsNullOrEmpty( customLightingAlphaCode ) ? customLightingAlphaCode : "1" ) + ";\n";
|
|
if( m_alphaMode == AlphaMode.Premultiply || ( ( m_alphaMode == AlphaMode.Custom || m_alphaMode == AlphaMode.Opaque ) && m_blendOpsHelper.CurrentBlendRGB.IndexOf( "Premultiplied" ) > -1 ) )
|
|
ShaderBody += "\t\t\tc.rgb *= c.a;\n";
|
|
if( hasCustomLightingMask )
|
|
ShaderBody += "\t\t\t" + customLightingMaskCode + ";\n";
|
|
ShaderBody += "\t\t\treturn c;\n";
|
|
ShaderBody += "\t\t}\n\n";
|
|
|
|
//Add GI function
|
|
ShaderBody += "\t\tinline void LightingStandard" + m_currentLightModel.ToString() + "_GI( inout " + outputStruct + " " + Constants.CustomLightOutputVarStr + ", UnityGIInput data, inout UnityGI gi )\n\t\t{\n";
|
|
ShaderBody += "\t\t\ts.GIData = data;\n";
|
|
//ShaderBody += "\t\t\tUNITY_GI(gi, " + Constants.CustomLightOutputVarStr + ", data);\n";
|
|
ShaderBody += "\t\t}\n\n";
|
|
}
|
|
|
|
//Add custom lighting function
|
|
if( hasTranslucency || hasTransmission )
|
|
{
|
|
ShaderBody += "\t\tinline half4 Lighting" + m_currentLightModel.ToString() + Constants.CustomLightStructStr + "(" + outputStruct + " " + Constants.CustomLightOutputVarStr + ", half3 viewDir, UnityGI gi )\n\t\t{\n";
|
|
if( hasTranslucency )
|
|
{
|
|
ShaderBody += "\t\t\t#if !DIRECTIONAL\n";
|
|
ShaderBody += "\t\t\tfloat3 lightAtten = gi.light.color;\n";
|
|
ShaderBody += "\t\t\t#else\n";
|
|
ShaderBody += "\t\t\tfloat3 lightAtten = lerp( _LightColor0.rgb, gi.light.color, _TransShadow );\n";
|
|
ShaderBody += "\t\t\t#endif\n";
|
|
ShaderBody += "\t\t\thalf3 lightDir = gi.light.dir + " + Constants.CustomLightOutputVarStr + ".Normal * _TransNormalDistortion;\n";
|
|
ShaderBody += "\t\t\thalf transVdotL = pow( saturate( dot( viewDir, -lightDir ) ), _TransScattering );\n";
|
|
ShaderBody += "\t\t\thalf3 translucency = lightAtten * (transVdotL * _TransDirect + gi.indirect.diffuse * _TransAmbient) * " + Constants.CustomLightOutputVarStr + ".Translucency;\n";
|
|
ShaderBody += "\t\t\thalf4 c = half4( " + Constants.CustomLightOutputVarStr + ".Albedo * translucency * _Translucency, 0 );\n\n";
|
|
}
|
|
|
|
if( hasTransmission )
|
|
{
|
|
ShaderBody += "\t\t\thalf3 transmission = max(0 , -dot(" + Constants.CustomLightOutputVarStr + ".Normal, gi.light.dir)) * gi.light.color * " + Constants.CustomLightOutputVarStr + ".Transmission;\n";
|
|
ShaderBody += "\t\t\thalf4 d = half4(" + Constants.CustomLightOutputVarStr + ".Albedo * transmission , 0);\n\n";
|
|
}
|
|
|
|
ShaderBody += "\t\t\tSurfaceOutput" + m_currentLightModel.ToString() + " r;\n";
|
|
ShaderBody += "\t\t\tr.Albedo = " + Constants.CustomLightOutputVarStr + ".Albedo;\n";
|
|
ShaderBody += "\t\t\tr.Normal = " + Constants.CustomLightOutputVarStr + ".Normal;\n";
|
|
ShaderBody += "\t\t\tr.Emission = " + Constants.CustomLightOutputVarStr + ".Emission;\n";
|
|
switch( m_currentLightModel )
|
|
{
|
|
case StandardShaderLightModel.Standard:
|
|
ShaderBody += "\t\t\tr.Metallic = " + Constants.CustomLightOutputVarStr + ".Metallic;\n";
|
|
break;
|
|
case StandardShaderLightModel.StandardSpecular:
|
|
ShaderBody += "\t\t\tr.Specular = " + Constants.CustomLightOutputVarStr + ".Specular;\n";
|
|
break;
|
|
}
|
|
ShaderBody += "\t\t\tr.Smoothness = " + Constants.CustomLightOutputVarStr + ".Smoothness;\n";
|
|
ShaderBody += "\t\t\tr.Occlusion = " + Constants.CustomLightOutputVarStr + ".Occlusion;\n";
|
|
ShaderBody += "\t\t\tr.Alpha = " + Constants.CustomLightOutputVarStr + ".Alpha;\n";
|
|
ShaderBody += "\t\t\treturn Lighting" + m_currentLightModel.ToString() + " (r, viewDir, gi)" + ( hasTranslucency ? " + c" : "" ) + ( hasTransmission ? " + d" : "" ) + ";\n";
|
|
ShaderBody += "\t\t}\n\n";
|
|
|
|
//Add GI function
|
|
ShaderBody += "\t\tinline void Lighting" + m_currentLightModel.ToString() + Constants.CustomLightStructStr + "_GI(" + outputStruct + " " + Constants.CustomLightOutputVarStr + ", UnityGIInput data, inout UnityGI gi )\n\t\t{\n";
|
|
|
|
ShaderBody += "\t\t\t#if defined(UNITY_PASS_DEFERRED) && UNITY_ENABLE_REFLECTION_BUFFERS\n";
|
|
ShaderBody += "\t\t\t\tgi = UnityGlobalIllumination(data, " + Constants.CustomLightOutputVarStr + ".Occlusion, " + Constants.CustomLightOutputVarStr + ".Normal);\n";
|
|
ShaderBody += "\t\t\t#else\n";
|
|
ShaderBody += "\t\t\t\tUNITY_GLOSSY_ENV_FROM_SURFACE( g, " + Constants.CustomLightOutputVarStr + ", data );\n";
|
|
ShaderBody += "\t\t\t\tgi = UnityGlobalIllumination( data, " + Constants.CustomLightOutputVarStr + ".Occlusion, " + Constants.CustomLightOutputVarStr + ".Normal, g );\n";
|
|
ShaderBody += "\t\t\t#endif\n";
|
|
|
|
//ShaderBody += "\t\t\tUNITY_GI(gi, " + Constants.CustomLightOutputVarStr + ", data);\n";
|
|
ShaderBody += "\t\t}\n\n";
|
|
}
|
|
|
|
if( hasRefraction )
|
|
{
|
|
ShaderBody += "\t\tinline float4 Refraction( Input " + Constants.InputVarStr + ", " + outputStruct + " " + Constants.OutputVarStr + ", float indexOfRefraction, float chomaticAberration ) {\n";
|
|
ShaderBody += "\t\t\tfloat3 worldNormal = " + Constants.OutputVarStr + ".Normal;\n";
|
|
ShaderBody += "\t\t\tfloat4 screenPos = " + Constants.InputVarStr + ".screenPos;\n";
|
|
ShaderBody += "\t\t\t#if UNITY_UV_STARTS_AT_TOP\n";
|
|
ShaderBody += "\t\t\t\tfloat scale = -1.0;\n";
|
|
ShaderBody += "\t\t\t#else\n";
|
|
ShaderBody += "\t\t\t\tfloat scale = 1.0;\n";
|
|
ShaderBody += "\t\t\t#endif\n";
|
|
ShaderBody += "\t\t\tfloat halfPosW = screenPos.w * 0.5;\n";
|
|
ShaderBody += "\t\t\tscreenPos.y = ( screenPos.y - halfPosW ) * _ProjectionParams.x * scale + halfPosW;\n";
|
|
ShaderBody += "\t\t\t#if SHADER_API_D3D9 || SHADER_API_D3D11\n";
|
|
ShaderBody += "\t\t\t\tscreenPos.w += 0.00000000001;\n";
|
|
ShaderBody += "\t\t\t#endif\n";
|
|
ShaderBody += "\t\t\tfloat2 projScreenPos = ( screenPos / screenPos.w ).xy;\n";
|
|
ShaderBody += "\t\t\tfloat3 worldViewDir = normalize( UnityWorldSpaceViewDir( " + Constants.InputVarStr + ".worldPos ) );\n";
|
|
ShaderBody += "\t\t\tfloat3 refractionOffset = ( indexOfRefraction - 1.0 ) * mul( UNITY_MATRIX_V, float4( worldNormal, 0.0 ) ) * ( 1.0 - dot( worldNormal, worldViewDir ) );\n";
|
|
ShaderBody += "\t\t\tfloat2 cameraRefraction = float2( refractionOffset.x, refractionOffset.y );\n";
|
|
|
|
string grabpass = "_GrabTexture";
|
|
if( m_grabOrder != 0 )
|
|
grabpass = "RefractionGrab" + m_grabOrder;
|
|
ShaderBody += "\t\t\tfloat4 redAlpha = tex2D( " + grabpass + ", ( projScreenPos + cameraRefraction ) );\n";
|
|
ShaderBody += "\t\t\tfloat green = tex2D( " + grabpass + ", ( projScreenPos + ( cameraRefraction * ( 1.0 - chomaticAberration ) ) ) ).g;\n";
|
|
ShaderBody += "\t\t\tfloat blue = tex2D( " + grabpass + ", ( projScreenPos + ( cameraRefraction * ( 1.0 + chomaticAberration ) ) ) ).b;\n";
|
|
ShaderBody += "\t\t\treturn float4( redAlpha.r, green, blue, redAlpha.a );\n";
|
|
ShaderBody += "\t\t}\n\n";
|
|
|
|
ShaderBody += "\t\tvoid RefractionF( Input " + Constants.InputVarStr + ", " + outputStruct + " " + Constants.OutputVarStr + ", inout half4 color )\n";
|
|
ShaderBody += "\t\t{\n";
|
|
ShaderBody += "\t\t\t#ifdef UNITY_PASS_FORWARDBASE\n";
|
|
ShaderBody += refractionInstructions;
|
|
if( m_inlineChromaticAberration.Active )
|
|
{
|
|
ShaderBody += "\t\t\tcolor.rgb = color.rgb + Refraction( " + Constants.InputVarStr + ", " + Constants.OutputVarStr + ", " + refractionCode + ", " + m_inlineChromaticAberration.GetValueOrProperty(false) + " ) * ( 1 - color.a );\n";
|
|
}
|
|
else
|
|
{
|
|
ShaderBody += "\t\t\tcolor.rgb = color.rgb + Refraction( " + Constants.InputVarStr + ", " + Constants.OutputVarStr + ", " + refractionCode + ", _ChromaticAberration ) * ( 1 - color.a );\n";
|
|
}
|
|
ShaderBody += "\t\t\tcolor.a = 1;\n";
|
|
ShaderBody += "\t\t\t#endif\n";
|
|
ShaderBody += "\t\t}\n\n";
|
|
}
|
|
|
|
//Add Surface Shader body
|
|
ShaderBody += "\t\tvoid surf( Input " + Constants.InputVarStr + " , inout " + outputStruct + " " + Constants.OutputVarStr + " )\n\t\t{\n";
|
|
{
|
|
// Pass input information to custom lighting function
|
|
if( m_currentLightModel == StandardShaderLightModel.CustomLighting )
|
|
ShaderBody += "\t\t\t" + Constants.OutputVarStr + ".SurfInput = " + Constants.InputVarStr + ";\n";
|
|
|
|
//add local vars
|
|
if( m_currentDataCollector.DirtyLocalVariables )
|
|
ShaderBody += m_currentDataCollector.LocalVariables;
|
|
|
|
//add nodes ops
|
|
if( m_currentDataCollector.DirtyInstructions )
|
|
ShaderBody += m_currentDataCollector.Instructions;
|
|
}
|
|
ShaderBody += "\t\t}\n";
|
|
}
|
|
CloseCGProgram( ref ShaderBody );
|
|
|
|
|
|
//Add custom Shadow Caster
|
|
if( m_customShadowCaster )
|
|
{
|
|
OpenCGProgram( ref ShaderBody );
|
|
string customLightSurface = hasTranslucency || hasTransmission ? "Custom" : "";
|
|
m_renderingPlatformOpHelper.SetRenderingPlatforms( ref ShaderBody );
|
|
|
|
//Check if Custom Vertex is being used and add tag
|
|
if( m_currentDataCollector.DirtyPerVertexData )
|
|
OptionalParameters += "vertex:" + Constants.VertexDataFunc + Constants.OptionalParametersSep;
|
|
|
|
if( m_tessOpHelper.EnableTesselation && !usingDebugPort )
|
|
{
|
|
m_tessOpHelper.WriteToOptionalParams( ref OptionalParameters );
|
|
}
|
|
//if ( hasRefraction )
|
|
// ShaderBody += "\t\t#pragma multi_compile _ALPHAPREMULTIPLY_ON\n";
|
|
|
|
m_additionalSurfaceOptions.WriteToOptionalSurfaceOptions( ref OptionalParameters );
|
|
|
|
AddShaderPragma( ref ShaderBody, "surface surf " + standardCustomLighting + m_currentLightModel.ToString() + customLightSurface + Constants.OptionalParametersSep + OptionalParameters );
|
|
CloseCGProgram( ref ShaderBody );
|
|
|
|
ShaderBody += "\t\tPass\n";
|
|
ShaderBody += "\t\t{\n";
|
|
ShaderBody += "\t\t\tName \"ShadowCaster\"\n";
|
|
ShaderBody += "\t\t\tTags{ \"LightMode\" = \"ShadowCaster\" }\n";
|
|
ShaderBody += "\t\t\tZWrite On\n";
|
|
if( m_alphaToCoverage || m_inlineAlphaToCoverage.Active )
|
|
ShaderBody += "\t\t\tAlphaToMask Off\n";
|
|
ShaderBody += "\t\t\tCGPROGRAM\n";
|
|
ShaderBody += "\t\t\t#pragma vertex vert\n";
|
|
ShaderBody += "\t\t\t#pragma fragment frag\n";
|
|
ShaderBody += "\t\t\t#pragma target " + ShaderModelTypeArr[ m_shaderModelIdx ] + "\n";
|
|
//ShaderBody += "\t\t\t#pragma multi_compile_instancing\n";
|
|
ShaderBody += "\t\t\t#pragma multi_compile_shadowcaster\n";
|
|
ShaderBody += "\t\t\t#pragma multi_compile UNITY_PASS_SHADOWCASTER\n";
|
|
ShaderBody += "\t\t\t#pragma skip_variants FOG_LINEAR FOG_EXP FOG_EXP2\n";
|
|
ShaderBody += "\t\t\t#include \"HLSLSupport.cginc\"\n";
|
|
#if UNITY_2018_3_OR_NEWER
|
|
//Preventing WebGL to throw error Duplicate system value semantic definition: input semantic 'SV_POSITION' and input semantic 'VPOS'
|
|
ShaderBody += "\t\t\t#if ( SHADER_API_D3D11 || SHADER_API_GLCORE || SHADER_API_GLES || SHADER_API_GLES3 || SHADER_API_METAL || SHADER_API_VULKAN )\n";
|
|
#else
|
|
ShaderBody += "\t\t\t#if ( SHADER_API_D3D11 || SHADER_API_GLCORE || SHADER_API_GLES3 || SHADER_API_METAL || SHADER_API_VULKAN )\n";
|
|
#endif
|
|
ShaderBody += "\t\t\t\t#define CAN_SKIP_VPOS\n";
|
|
ShaderBody += "\t\t\t#endif\n";
|
|
ShaderBody += "\t\t\t#include \"UnityCG.cginc\"\n";
|
|
ShaderBody += "\t\t\t#include \"Lighting.cginc\"\n";
|
|
ShaderBody += "\t\t\t#include \"UnityPBSLighting.cginc\"\n";
|
|
|
|
if( !( ( m_alphaToCoverage || m_inlineAlphaToCoverage.Active ) && hasOpacity && hasOpacityMask ) )
|
|
if( hasOpacity )
|
|
ShaderBody += "\t\t\tsampler3D _DitherMaskLOD;\n";
|
|
|
|
//ShaderBody += "\t\t\tsampler3D _DitherMaskLOD;\n";
|
|
|
|
ShaderBody += "\t\t\tstruct v2f\n";
|
|
ShaderBody += "\t\t\t{\n";
|
|
ShaderBody += "\t\t\t\tV2F_SHADOW_CASTER;\n";
|
|
int texcoordIndex = 1;
|
|
for( int i = 0; i < m_currentDataCollector.PackSlotsList.Count; i++ )
|
|
{
|
|
int size = 4 - m_currentDataCollector.PackSlotsList[ i ];
|
|
if( size > 0 )
|
|
{
|
|
ShaderBody += "\t\t\t\tfloat" + size + " customPack" + ( i + 1 ) + " : TEXCOORD" + ( i + 1 ) + ";\n";
|
|
}
|
|
texcoordIndex++;
|
|
}
|
|
|
|
if( !m_currentDataCollector.UsingInternalData )
|
|
ShaderBody += "\t\t\t\tfloat3 worldPos : TEXCOORD" + ( texcoordIndex++ ) + ";\n";
|
|
if( m_currentDataCollector.UsingScreenPos )
|
|
ShaderBody += "\t\t\t\tfloat4 screenPos : TEXCOORD" + ( texcoordIndex++ ) + ";\n";
|
|
if( /*m_currentDataCollector.UsingWorldNormal || m_currentDataCollector.UsingWorldPosition ||*/ m_currentDataCollector.UsingInternalData || m_currentDataCollector.DirtyNormal )
|
|
{
|
|
ShaderBody += "\t\t\t\tfloat4 tSpace0 : TEXCOORD" + ( texcoordIndex++ ) + ";\n";
|
|
ShaderBody += "\t\t\t\tfloat4 tSpace1 : TEXCOORD" + ( texcoordIndex++ ) + ";\n";
|
|
ShaderBody += "\t\t\t\tfloat4 tSpace2 : TEXCOORD" + ( texcoordIndex++ ) + ";\n";
|
|
}
|
|
else if( !m_currentDataCollector.UsingInternalData && m_currentDataCollector.UsingWorldNormal )
|
|
{
|
|
ShaderBody += "\t\t\t\tfloat3 worldNormal : TEXCOORD" + ( texcoordIndex++ ) + ";\n";
|
|
}
|
|
|
|
if( m_currentDataCollector.UsingVertexColor )
|
|
ShaderBody += "\t\t\t\thalf4 color : COLOR0;\n";
|
|
ShaderBody += "\t\t\t\tUNITY_VERTEX_INPUT_INSTANCE_ID\n";
|
|
ShaderBody += "\t\t\t\tUNITY_VERTEX_OUTPUT_STEREO\n";
|
|
ShaderBody += "\t\t\t};\n";
|
|
|
|
ShaderBody += "\t\t\tv2f vert( " + m_currentDataCollector.CustomAppDataName + " v )\n";
|
|
ShaderBody += "\t\t\t{\n";
|
|
ShaderBody += "\t\t\t\tv2f o;\n";
|
|
|
|
ShaderBody += "\t\t\t\tUNITY_SETUP_INSTANCE_ID( v );\n";
|
|
ShaderBody += "\t\t\t\tUNITY_INITIALIZE_OUTPUT( v2f, o );\n";
|
|
ShaderBody += "\t\t\t\tUNITY_INITIALIZE_VERTEX_OUTPUT_STEREO( o );\n";
|
|
ShaderBody += "\t\t\t\tUNITY_TRANSFER_INSTANCE_ID( v, o );\n";
|
|
|
|
if( m_currentDataCollector.DirtyPerVertexData || m_currentDataCollector.CustomShadowCoordsList.Count > 0 )
|
|
ShaderBody += "\t\t\t\tInput customInputData;\n";
|
|
if( m_currentDataCollector.DirtyPerVertexData )
|
|
{
|
|
ShaderBody += "\t\t\t\tvertexDataFunc( v" + ( m_currentDataCollector.TesselationActive ? "" : ", customInputData" ) + " );\n";
|
|
}
|
|
|
|
ShaderBody += "\t\t\t\tfloat3 worldPos = mul( unity_ObjectToWorld, v.vertex ).xyz;\n";
|
|
ShaderBody += "\t\t\t\thalf3 worldNormal = UnityObjectToWorldNormal( v.normal );\n";
|
|
if( m_currentDataCollector.UsingInternalData || m_currentDataCollector.DirtyNormal )
|
|
{
|
|
ShaderBody += "\t\t\t\thalf3 worldTangent = UnityObjectToWorldDir( v.tangent.xyz );\n";
|
|
ShaderBody += "\t\t\t\thalf tangentSign = v.tangent.w * unity_WorldTransformParams.w;\n";
|
|
ShaderBody += "\t\t\t\thalf3 worldBinormal = cross( worldNormal, worldTangent ) * tangentSign;\n";
|
|
ShaderBody += "\t\t\t\to.tSpace0 = float4( worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x );\n";
|
|
ShaderBody += "\t\t\t\to.tSpace1 = float4( worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y );\n";
|
|
ShaderBody += "\t\t\t\to.tSpace2 = float4( worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z );\n";
|
|
}
|
|
else if( !m_currentDataCollector.UsingInternalData && m_currentDataCollector.UsingWorldNormal )
|
|
{
|
|
ShaderBody += "\t\t\t\to.worldNormal = worldNormal;\n";
|
|
}
|
|
|
|
for( int i = 0; i < m_currentDataCollector.CustomShadowCoordsList.Count; i++ )
|
|
{
|
|
int size = UIUtils.GetChannelsAmount( m_currentDataCollector.CustomShadowCoordsList[ i ].DataType );
|
|
string channels = string.Empty;
|
|
for( int j = 0; j < size; j++ )
|
|
{
|
|
channels += Convert.ToChar( 120 + m_currentDataCollector.CustomShadowCoordsList[ i ].TextureIndex + j );
|
|
}
|
|
channels = channels.Replace( '{', 'w' );
|
|
ShaderBody += "\t\t\t\to.customPack" + ( m_currentDataCollector.CustomShadowCoordsList[ i ].TextureSlot + 1 ) + "." + channels + " = customInputData." + m_currentDataCollector.CustomShadowCoordsList[ i ].CoordName + ";\n";
|
|
|
|
//TODO: TEMPORARY SOLUTION, this needs to go somewhere else, there's no need for these comparisons
|
|
if( m_currentDataCollector.CustomShadowCoordsList[ i ].CoordName.StartsWith( "uv_" ) )
|
|
{
|
|
ShaderBody += "\t\t\t\to.customPack" + ( m_currentDataCollector.CustomShadowCoordsList[ i ].TextureSlot + 1 ) + "." + channels + " = v.texcoord;\n";
|
|
}
|
|
else if( m_currentDataCollector.CustomShadowCoordsList[ i ].CoordName.StartsWith( "uv2_" ) )
|
|
{
|
|
ShaderBody += "\t\t\t\to.customPack" + ( m_currentDataCollector.CustomShadowCoordsList[ i ].TextureSlot + 1 ) + "." + channels + " = v.texcoord1;\n";
|
|
}
|
|
else if( m_currentDataCollector.CustomShadowCoordsList[ i ].CoordName.StartsWith( "uv3_" ) )
|
|
{
|
|
ShaderBody += "\t\t\t\to.customPack" + ( m_currentDataCollector.CustomShadowCoordsList[ i ].TextureSlot + 1 ) + "." + channels + " = v.texcoord2;\n";
|
|
}
|
|
else if( m_currentDataCollector.CustomShadowCoordsList[ i ].CoordName.StartsWith( "uv4_" ) )
|
|
{
|
|
ShaderBody += "\t\t\t\to.customPack" + ( m_currentDataCollector.CustomShadowCoordsList[ i ].TextureSlot + 1 ) + "." + channels + " = v.texcoord3;\n";
|
|
}
|
|
}
|
|
|
|
if( !m_currentDataCollector.UsingInternalData )
|
|
ShaderBody += "\t\t\t\to.worldPos = worldPos;\n";
|
|
ShaderBody += "\t\t\t\tTRANSFER_SHADOW_CASTER_NORMALOFFSET( o )\n";
|
|
if( m_currentDataCollector.UsingScreenPos )
|
|
ShaderBody += "\t\t\t\to.screenPos = ComputeScreenPos( o.pos );\n";
|
|
if( m_currentDataCollector.UsingVertexColor )
|
|
ShaderBody += "\t\t\t\to.color = v.color;\n";
|
|
ShaderBody += "\t\t\t\treturn o;\n";
|
|
ShaderBody += "\t\t\t}\n";
|
|
|
|
ShaderBody += "\t\t\thalf4 frag( v2f IN\n";
|
|
ShaderBody += "\t\t\t#if !defined( CAN_SKIP_VPOS )\n";
|
|
ShaderBody += "\t\t\t, UNITY_VPOS_TYPE vpos : VPOS\n";
|
|
ShaderBody += "\t\t\t#endif\n";
|
|
ShaderBody += "\t\t\t) : SV_Target\n";
|
|
ShaderBody += "\t\t\t{\n";
|
|
ShaderBody += "\t\t\t\tUNITY_SETUP_INSTANCE_ID( IN );\n";
|
|
ShaderBody += "\t\t\t\tInput surfIN;\n";
|
|
ShaderBody += "\t\t\t\tUNITY_INITIALIZE_OUTPUT( Input, surfIN );\n";
|
|
|
|
for( int i = 0; i < m_currentDataCollector.CustomShadowCoordsList.Count; i++ )
|
|
{
|
|
int size = UIUtils.GetChannelsAmount( m_currentDataCollector.CustomShadowCoordsList[ i ].DataType );
|
|
string channels = string.Empty;
|
|
for( int j = 0; j < size; j++ )
|
|
{
|
|
channels += Convert.ToChar( 120 + m_currentDataCollector.CustomShadowCoordsList[ i ].TextureIndex + j );
|
|
}
|
|
channels = channels.Replace( '{', 'w' );
|
|
ShaderBody += "\t\t\t\tsurfIN." + m_currentDataCollector.CustomShadowCoordsList[ i ].CoordName + " = IN.customPack" + ( m_currentDataCollector.CustomShadowCoordsList[ i ].TextureSlot + 1 ) + "." + channels + ";\n";
|
|
}
|
|
|
|
if( m_currentDataCollector.UsingInternalData )
|
|
ShaderBody += "\t\t\t\tfloat3 worldPos = float3( IN.tSpace0.w, IN.tSpace1.w, IN.tSpace2.w );\n";
|
|
else
|
|
ShaderBody += "\t\t\t\tfloat3 worldPos = IN.worldPos;\n";
|
|
ShaderBody += "\t\t\t\thalf3 worldViewDir = normalize( UnityWorldSpaceViewDir( worldPos ) );\n";
|
|
|
|
if( m_currentDataCollector.UsingViewDirection && !m_currentDataCollector.DirtyNormal )
|
|
ShaderBody += "\t\t\t\tsurfIN.viewDir = worldViewDir;\n";
|
|
else if( m_currentDataCollector.UsingViewDirection )
|
|
ShaderBody += "\t\t\t\tsurfIN.viewDir = IN.tSpace0.xyz * worldViewDir.x + IN.tSpace1.xyz * worldViewDir.y + IN.tSpace2.xyz * worldViewDir.z;\n";
|
|
|
|
if( m_currentDataCollector.UsingWorldPosition )
|
|
ShaderBody += "\t\t\t\tsurfIN.worldPos = worldPos;\n";
|
|
|
|
if( m_currentDataCollector.UsingWorldNormal && m_currentDataCollector.UsingInternalData )
|
|
ShaderBody += "\t\t\t\tsurfIN.worldNormal = float3( IN.tSpace0.z, IN.tSpace1.z, IN.tSpace2.z );\n";
|
|
else if( !m_currentDataCollector.UsingInternalData && m_currentDataCollector.UsingWorldNormal )
|
|
ShaderBody += "\t\t\t\tsurfIN.worldNormal = IN.worldNormal;\n";
|
|
|
|
if( m_currentDataCollector.UsingWorldReflection )
|
|
ShaderBody += "\t\t\t\tsurfIN.worldRefl = -worldViewDir;\n";
|
|
|
|
if( m_currentDataCollector.UsingInternalData )
|
|
{
|
|
ShaderBody += "\t\t\t\tsurfIN.internalSurfaceTtoW0 = IN.tSpace0.xyz;\n";
|
|
ShaderBody += "\t\t\t\tsurfIN.internalSurfaceTtoW1 = IN.tSpace1.xyz;\n";
|
|
ShaderBody += "\t\t\t\tsurfIN.internalSurfaceTtoW2 = IN.tSpace2.xyz;\n";
|
|
}
|
|
|
|
if( m_currentDataCollector.UsingScreenPos )
|
|
ShaderBody += "\t\t\t\tsurfIN.screenPos = IN.screenPos;\n";
|
|
|
|
if( m_currentDataCollector.UsingVertexColor )
|
|
ShaderBody += "\t\t\t\tsurfIN.vertexColor = IN.color;\n";
|
|
|
|
ShaderBody += "\t\t\t\t" + outputStruct + " o;\n";
|
|
ShaderBody += "\t\t\t\tUNITY_INITIALIZE_OUTPUT( " + outputStruct + ", o )\n";
|
|
ShaderBody += "\t\t\t\tsurf( surfIN, o );\n";
|
|
if( ( hasOpacity || hasOpacityMask ) && m_currentLightModel == StandardShaderLightModel.CustomLighting )
|
|
{
|
|
ShaderBody += "\t\t\t\tUnityGI gi;\n";
|
|
ShaderBody += "\t\t\t\tUNITY_INITIALIZE_OUTPUT( UnityGI, gi );\n";
|
|
ShaderBody += "\t\t\t\to.Alpha = LightingStandardCustomLighting( o, worldViewDir, gi ).a;\n";
|
|
}
|
|
ShaderBody += "\t\t\t\t#if defined( CAN_SKIP_VPOS )\n";
|
|
ShaderBody += "\t\t\t\tfloat2 vpos = IN.pos;\n";
|
|
ShaderBody += "\t\t\t\t#endif\n";
|
|
|
|
/*if( ( ( m_alphaToCoverage || m_inlineAlphaToCoverage.Active ) && hasOpacity && m_inputPorts[ m_discardPortId ].IsConnected ) )
|
|
{
|
|
|
|
}
|
|
else*/ if(!( ( m_alphaToCoverage || m_inlineAlphaToCoverage.Active ) && hasOpacity && m_inputPorts[ m_discardPortId ].IsConnected ) && hasOpacity )
|
|
{
|
|
ShaderBody += "\t\t\t\thalf alphaRef = tex3D( _DitherMaskLOD, float3( vpos.xy * 0.25, o.Alpha * 0.9375 ) ).a;\n";
|
|
ShaderBody += "\t\t\t\tclip( alphaRef - 0.01 );\n";
|
|
}
|
|
|
|
ShaderBody += "\t\t\t\tSHADOW_CASTER_FRAGMENT( IN )\n";
|
|
ShaderBody += "\t\t\t}\n";
|
|
|
|
ShaderBody += "\t\t\tENDCG\n";
|
|
|
|
ShaderBody += "\t\t}\n";
|
|
}
|
|
|
|
}
|
|
|
|
if( !string.IsNullOrEmpty( bellowUsePasses ) )
|
|
{
|
|
ShaderBody += bellowUsePasses;
|
|
}
|
|
|
|
CloseSubShaderBody( ref ShaderBody );
|
|
|
|
if( m_dependenciesHelper.HasDependencies )
|
|
{
|
|
ShaderBody += m_dependenciesHelper.GenerateDependencies();
|
|
}
|
|
|
|
if( m_fallbackHelper.Active )
|
|
{
|
|
ShaderBody += m_fallbackHelper.TabbedFallbackShader;
|
|
}
|
|
else if( m_castShadows || m_receiveShadows )
|
|
{
|
|
AddShaderProperty( ref ShaderBody, "Fallback", "Diffuse" );
|
|
}
|
|
|
|
if( !string.IsNullOrEmpty( m_customInspectorName ) )
|
|
{
|
|
AddShaderProperty( ref ShaderBody, "CustomEditor", m_customInspectorName );
|
|
}
|
|
}
|
|
CloseShaderBody( ref ShaderBody );
|
|
|
|
if( usingDebugPort )
|
|
{
|
|
m_currentLightModel = cachedLightModel;
|
|
ContainerGraph.CurrentCanvasMode = cachedAvailability;
|
|
}
|
|
|
|
// Generate Graph info
|
|
ShaderBody += ContainerGraph.ParentWindow.GenerateGraphInfo();
|
|
|
|
//TODO: Remove current SaveDebugShader and uncomment SaveToDisk as soon as pathname is editable
|
|
if( !String.IsNullOrEmpty( pathname ) )
|
|
{
|
|
IOUtils.StartSaveThread( ShaderBody, ( isFullPath ? pathname : ( IOUtils.dataPath + pathname ) ) );
|
|
}
|
|
else
|
|
{
|
|
IOUtils.StartSaveThread( ShaderBody, Application.dataPath + "/AmplifyShaderEditor/Samples/Shaders/" + m_shaderName + ".shader" );
|
|
}
|
|
|
|
// Load new shader into material
|
|
|
|
if( CurrentShader == null )
|
|
{
|
|
AssetDatabase.Refresh( ImportAssetOptions.ForceUpdate );
|
|
CurrentShader = Shader.Find( ShaderName );
|
|
}
|
|
//else
|
|
//{
|
|
// // need to always get asset datapath because a user can change and asset location from the project window
|
|
// AssetDatabase.ImportAsset( AssetDatabase.GetAssetPath( m_currentShader ) );
|
|
// //ShaderUtil.UpdateShaderAsset( m_currentShader, ShaderBody );
|
|
//}
|
|
|
|
if( m_currentShader != null )
|
|
{
|
|
m_currentDataCollector.UpdateShaderImporter( ref m_currentShader );
|
|
if( m_currentMaterial != null )
|
|
{
|
|
if( m_currentShader != m_currentMaterial.shader )
|
|
m_currentMaterial.shader = m_currentShader;
|
|
#if UNITY_5_6_OR_NEWER
|
|
if ( isInstancedShader )
|
|
{
|
|
m_currentMaterial.enableInstancing = true;
|
|
}
|
|
#endif
|
|
m_currentDataCollector.UpdateMaterialOnPropertyNodes( m_currentMaterial );
|
|
UpdateMaterialEditor();
|
|
// need to always get asset datapath because a user can change and asset location from the project window
|
|
//AssetDatabase.ImportAsset( AssetDatabase.GetAssetPath( m_currentMaterial ) );
|
|
}
|
|
}
|
|
|
|
m_currentDataCollector.Destroy();
|
|
m_currentDataCollector = null;
|
|
|
|
return m_currentShader;
|
|
}
|
|
|
|
public override void UpdateFromShader( Shader newShader )
|
|
{
|
|
if( m_currentMaterial != null && m_currentMaterial.shader != newShader )
|
|
{
|
|
m_currentMaterial.shader = newShader;
|
|
}
|
|
CurrentShader = newShader;
|
|
}
|
|
|
|
public override void Destroy()
|
|
{
|
|
base.Destroy();
|
|
|
|
if( m_dummyProperty != null )
|
|
{
|
|
m_dummyProperty.Destroy();
|
|
GameObject.DestroyImmediate( m_dummyProperty );
|
|
m_dummyProperty = null;
|
|
}
|
|
|
|
m_drawInstancedHelper = null;
|
|
|
|
m_translucencyPort = null;
|
|
m_transmissionPort = null;
|
|
m_refractionPort = null;
|
|
m_normalPort = null;
|
|
|
|
m_renderingOptionsOpHelper.Destroy();
|
|
m_renderingOptionsOpHelper = null;
|
|
|
|
m_additionalIncludes.Destroy();
|
|
m_additionalIncludes = null;
|
|
|
|
m_additionalPragmas.Destroy();
|
|
m_additionalPragmas = null;
|
|
|
|
m_additionalDefines.Destroy();
|
|
m_additionalDefines = null;
|
|
|
|
m_additionalSurfaceOptions.Destroy();
|
|
m_additionalSurfaceOptions = null;
|
|
|
|
m_additionalDirectives.Destroy();
|
|
m_additionalDirectives = null;
|
|
|
|
m_customTagsHelper.Destroy();
|
|
m_customTagsHelper = null;
|
|
|
|
m_dependenciesHelper.Destroy();
|
|
m_dependenciesHelper = null;
|
|
|
|
m_renderingPlatformOpHelper = null;
|
|
m_inspectorDefaultStyle = null;
|
|
m_inspectorFoldoutStyle = null;
|
|
|
|
m_zBufferHelper = null;
|
|
m_stencilBufferHelper = null;
|
|
m_blendOpsHelper = null;
|
|
m_tessOpHelper.Destroy();
|
|
m_tessOpHelper = null;
|
|
m_outlineHelper.Destroy();
|
|
m_outlineHelper = null;
|
|
m_colorMaskHelper.Destroy();
|
|
m_colorMaskHelper = null;
|
|
m_billboardOpHelper = null;
|
|
|
|
m_fallbackHelper.Destroy();
|
|
GameObject.DestroyImmediate( m_fallbackHelper );
|
|
m_fallbackHelper = null;
|
|
|
|
m_usePass.Destroy();
|
|
GameObject.DestroyImmediate( m_usePass );
|
|
m_usePass = null;
|
|
}
|
|
|
|
public override int VersionConvertInputPortId( int portId )
|
|
{
|
|
int newPort = portId;
|
|
|
|
//added translucency input after occlusion
|
|
if( UIUtils.CurrentShaderVersion() <= 2404 )
|
|
{
|
|
switch( m_currentLightModel )
|
|
{
|
|
case StandardShaderLightModel.Standard:
|
|
case StandardShaderLightModel.StandardSpecular:
|
|
if( portId >= 6 )
|
|
newPort += 1;
|
|
break;
|
|
case StandardShaderLightModel.CustomLighting:
|
|
case StandardShaderLightModel.Unlit:
|
|
case StandardShaderLightModel.Lambert:
|
|
case StandardShaderLightModel.BlinnPhong:
|
|
if( portId >= 5 )
|
|
newPort += 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
portId = newPort;
|
|
|
|
//added transmission input after occlusion
|
|
if( UIUtils.CurrentShaderVersion() < 2407 )
|
|
{
|
|
switch( m_currentLightModel )
|
|
{
|
|
case StandardShaderLightModel.Standard:
|
|
case StandardShaderLightModel.StandardSpecular:
|
|
if( portId >= 6 )
|
|
newPort += 1;
|
|
break;
|
|
case StandardShaderLightModel.CustomLighting:
|
|
case StandardShaderLightModel.Unlit:
|
|
case StandardShaderLightModel.Lambert:
|
|
case StandardShaderLightModel.BlinnPhong:
|
|
if( portId >= 5 )
|
|
newPort += 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
portId = newPort;
|
|
|
|
//added tessellation ports
|
|
if( UIUtils.CurrentShaderVersion() < 3002 )
|
|
{
|
|
switch( m_currentLightModel )
|
|
{
|
|
case StandardShaderLightModel.Standard:
|
|
case StandardShaderLightModel.StandardSpecular:
|
|
if( portId >= 13 )
|
|
newPort += 1;
|
|
break;
|
|
case StandardShaderLightModel.CustomLighting:
|
|
case StandardShaderLightModel.Unlit:
|
|
case StandardShaderLightModel.Lambert:
|
|
case StandardShaderLightModel.BlinnPhong:
|
|
if( portId >= 10 )
|
|
newPort += 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
portId = newPort;
|
|
|
|
//added refraction after translucency
|
|
if( UIUtils.CurrentShaderVersion() < 3204 )
|
|
{
|
|
switch( m_currentLightModel )
|
|
{
|
|
case StandardShaderLightModel.Standard:
|
|
case StandardShaderLightModel.StandardSpecular:
|
|
if( portId >= 8 )
|
|
newPort += 1;
|
|
break;
|
|
case StandardShaderLightModel.CustomLighting:
|
|
case StandardShaderLightModel.Unlit:
|
|
case StandardShaderLightModel.Lambert:
|
|
case StandardShaderLightModel.BlinnPhong:
|
|
if( portId >= 7 )
|
|
newPort += 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
portId = newPort;
|
|
|
|
//removed custom lighting port
|
|
//if ( UIUtils.CurrentShaderVersion() < 10003 ) //runs everytime because this system is only used after 5000 version
|
|
{
|
|
switch( m_currentLightModel )
|
|
{
|
|
case StandardShaderLightModel.Standard:
|
|
case StandardShaderLightModel.StandardSpecular:
|
|
if( portId >= 13 )
|
|
newPort -= 1;
|
|
break;
|
|
case StandardShaderLightModel.CustomLighting:
|
|
case StandardShaderLightModel.Unlit:
|
|
case StandardShaderLightModel.Lambert:
|
|
case StandardShaderLightModel.BlinnPhong:
|
|
if( portId >= 12 )
|
|
newPort -= 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
portId = newPort;
|
|
|
|
//if( UIUtils.CurrentShaderVersion() < 13802 ) //runs everytime because this system is only used after 5000 version
|
|
{
|
|
switch( m_currentLightModel )
|
|
{
|
|
case StandardShaderLightModel.Standard:
|
|
case StandardShaderLightModel.StandardSpecular:
|
|
if( portId >= 11 )
|
|
newPort += 1;
|
|
break;
|
|
case StandardShaderLightModel.CustomLighting:
|
|
case StandardShaderLightModel.Unlit:
|
|
case StandardShaderLightModel.Lambert:
|
|
case StandardShaderLightModel.BlinnPhong:
|
|
if( portId >= 10 )
|
|
newPort += 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
portId = newPort;
|
|
return newPort;
|
|
}
|
|
|
|
public override void ReadFromString( ref string[] nodeParams )
|
|
{
|
|
try
|
|
{
|
|
base.ReadFromString( ref nodeParams );
|
|
m_currentLightModel = (StandardShaderLightModel)Enum.Parse( typeof( StandardShaderLightModel ), GetCurrentParam( ref nodeParams ) );
|
|
|
|
if( CurrentMasterNodeCategory == AvailableShaderTypes.SurfaceShader && m_currentLightModel == StandardShaderLightModel.CustomLighting )
|
|
{
|
|
ContainerGraph.CurrentCanvasMode = NodeAvailability.CustomLighting;
|
|
ContainerGraph.ParentWindow.CurrentNodeAvailability = NodeAvailability.CustomLighting;
|
|
}
|
|
else if( CurrentMasterNodeCategory == AvailableShaderTypes.SurfaceShader )
|
|
{
|
|
ContainerGraph.CurrentCanvasMode = NodeAvailability.SurfaceShader;
|
|
ContainerGraph.ParentWindow.CurrentNodeAvailability = NodeAvailability.SurfaceShader;
|
|
}
|
|
//if ( _shaderCategory.Length > 0 )
|
|
// _shaderCategory = UIUtils.RemoveInvalidCharacters( _shaderCategory );
|
|
ShaderName = GetCurrentParam( ref nodeParams );
|
|
if( m_shaderName.Length > 0 )
|
|
ShaderName = UIUtils.RemoveShaderInvalidCharacters( ShaderName );
|
|
|
|
m_renderingOptionsOpHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
|
|
m_cullMode = (CullMode)Enum.Parse( typeof( CullMode ), GetCurrentParam( ref nodeParams ) );
|
|
m_zBufferHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
|
|
string alphaMode = GetCurrentParam( ref nodeParams );
|
|
|
|
if( UIUtils.CurrentShaderVersion() < 4003 )
|
|
{
|
|
if( alphaMode.Equals( "Fade" ) )
|
|
{
|
|
alphaMode = "Transparent";
|
|
}
|
|
else if( alphaMode.Equals( "Transparent" ) )
|
|
{
|
|
alphaMode = "Premultiply";
|
|
}
|
|
}
|
|
|
|
m_alphaMode = (AlphaMode)Enum.Parse( typeof( AlphaMode ), alphaMode );
|
|
m_opacityMaskClipValue = Convert.ToSingle( GetCurrentParam( ref nodeParams ) );
|
|
m_keepAlpha = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
|
|
m_keepAlpha = true;
|
|
m_castShadows = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
|
|
m_queueOrder = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
|
|
if( UIUtils.CurrentShaderVersion() > 11 )
|
|
{
|
|
m_customBlendMode = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
|
|
m_renderType = (RenderType)Enum.Parse( typeof( RenderType ), GetCurrentParam( ref nodeParams ) );
|
|
if( UIUtils.CurrentShaderVersion() > 14305 )
|
|
{
|
|
m_customRenderType = GetCurrentParam( ref nodeParams );
|
|
}
|
|
m_renderQueue = (RenderQueue)Enum.Parse( typeof( RenderQueue ), GetCurrentParam( ref nodeParams ) );
|
|
}
|
|
if( UIUtils.CurrentShaderVersion() > 2402 )
|
|
{
|
|
m_renderPath = (RenderPath)Enum.Parse( typeof( RenderPath ), GetCurrentParam( ref nodeParams ) );
|
|
}
|
|
if( UIUtils.CurrentShaderVersion() > 2405 )
|
|
{
|
|
m_renderingPlatformOpHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 2500 )
|
|
{
|
|
m_colorMaskHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 2501 )
|
|
{
|
|
m_stencilBufferHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 2504 )
|
|
{
|
|
m_tessOpHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 2505 )
|
|
{
|
|
m_receiveShadows = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 3202 )
|
|
{
|
|
m_blendOpsHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 3203 )
|
|
{
|
|
m_grabOrder = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 5003 )
|
|
{
|
|
m_outlineHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 5110 )
|
|
{
|
|
m_billboardOpHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 6101 )
|
|
{
|
|
m_vertexMode = (VertexMode)Enum.Parse( typeof( VertexMode ), GetCurrentParam( ref nodeParams ) );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 6102 )
|
|
{
|
|
ShaderLOD = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
|
|
m_fallbackHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 7102 )
|
|
{
|
|
m_maskClipOrderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
|
|
m_translucencyOrderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
|
|
m_refractionOrderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
|
|
m_tessellationOrderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 10010 && UIUtils.CurrentShaderVersion() < 15312 )
|
|
{
|
|
m_additionalIncludes.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 11006 )
|
|
{
|
|
m_customTagsHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 13102 && UIUtils.CurrentShaderVersion() < 15312 )
|
|
{
|
|
m_additionalPragmas.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 13205 )
|
|
{
|
|
m_alphaToCoverage = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 13903 )
|
|
{
|
|
m_dependenciesHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 14005 && UIUtils.CurrentShaderVersion() < 15312 )
|
|
{
|
|
m_additionalDefines.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 14501 )
|
|
{
|
|
m_inlineCullMode.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 14502 )
|
|
{
|
|
m_specColorOrderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 15204 )
|
|
{
|
|
m_inlineOpacityMaskClipValue.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 15311 )
|
|
{
|
|
m_additionalDirectives.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
m_additionalSurfaceOptions.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
else
|
|
{
|
|
m_additionalDirectives.AddItems( AdditionalLineType.Define, m_additionalDefines.DefineList );
|
|
m_additionalDirectives.AddItems( AdditionalLineType.Include, m_additionalIncludes.IncludeList );
|
|
m_additionalDirectives.AddItems( AdditionalLineType.Pragma, m_additionalPragmas.PragmaList );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 15402 )
|
|
{
|
|
m_usePass.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 16203 )
|
|
{
|
|
m_drawInstancedHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 16204 )
|
|
m_inlineChromaticAberration.ReadFromString( ref m_currentReadParamIdx, ref nodeParams , false );
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 16207 )
|
|
m_inlineAlphaToCoverage.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 18302 )
|
|
SamplingMacros = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
|
|
else
|
|
SamplingMacros = false;
|
|
|
|
m_lightModelChanged = true;
|
|
m_lastLightModel = m_currentLightModel;
|
|
DeleteAllInputConnections( true );
|
|
AddMasterPorts();
|
|
UpdateFromBlendMode();
|
|
m_customBlendMode = TestCustomBlendMode();
|
|
|
|
ContainerGraph.CurrentPrecision = m_currentPrecisionType;
|
|
}
|
|
catch( Exception e )
|
|
{
|
|
Debug.Log( e );
|
|
}
|
|
}
|
|
|
|
public override void RefreshExternalReferences()
|
|
{
|
|
base.RefreshExternalReferences();
|
|
|
|
// change port connection from emission to the new custom lighting port
|
|
if( m_currentLightModel == StandardShaderLightModel.CustomLighting && m_inputPorts[ m_emissionPortId ].IsConnected && UIUtils.CurrentShaderVersion() < 13802 )
|
|
{
|
|
OutputPort port = m_inputPorts[ m_emissionPortId ].GetOutputConnection( 0 );
|
|
m_inputPorts[ m_emissionPortId ].FullDeleteConnections();
|
|
UIUtils.SetConnection( m_inputPorts[ m_customLightingPortId ].NodeId, m_inputPorts[ m_customLightingPortId ].PortId, port.NodeId, port.PortId );
|
|
}
|
|
}
|
|
|
|
public override void WriteToString( ref string nodeInfo, ref string connectionsInfo )
|
|
{
|
|
base.WriteToString( ref nodeInfo, ref connectionsInfo );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_currentLightModel );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_shaderName );
|
|
m_renderingOptionsOpHelper.WriteToString( ref nodeInfo );
|
|
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_cullMode );
|
|
m_zBufferHelper.WriteToString( ref nodeInfo );
|
|
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_alphaMode );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_opacityMaskClipValue );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_keepAlpha );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_castShadows );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_queueOrder );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_customBlendMode );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_renderType );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_customRenderType );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_renderQueue );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_renderPath );
|
|
m_renderingPlatformOpHelper.WriteToString( ref nodeInfo );
|
|
m_colorMaskHelper.WriteToString( ref nodeInfo );
|
|
m_stencilBufferHelper.WriteToString( ref nodeInfo );
|
|
m_tessOpHelper.WriteToString( ref nodeInfo );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_receiveShadows );
|
|
m_blendOpsHelper.WriteToString( ref nodeInfo );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_grabOrder );
|
|
m_outlineHelper.WriteToString( ref nodeInfo );
|
|
m_billboardOpHelper.WriteToString( ref nodeInfo );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_vertexMode );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, ShaderLOD );
|
|
m_fallbackHelper.WriteToString( ref nodeInfo );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, ( m_maskClipReorder != null ) ? m_maskClipReorder.OrderIndex : -1 );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, ( m_translucencyReorder != null ) ? m_translucencyReorder.OrderIndex : -1 );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, ( m_refractionReorder != null ) ? m_refractionReorder.OrderIndex : -1 );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, ( m_tessellationReorder != null ) ? m_tessellationReorder.OrderIndex : -1 );
|
|
//m_additionalIncludes.WriteToString( ref nodeInfo );
|
|
m_customTagsHelper.WriteToString( ref nodeInfo );
|
|
//m_additionalPragmas.WriteToString( ref nodeInfo );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_alphaToCoverage );
|
|
m_dependenciesHelper.WriteToString( ref nodeInfo );
|
|
//m_additionalDefines.WriteToString( ref nodeInfo );
|
|
m_inlineCullMode.WriteToString( ref nodeInfo );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, ( m_specColorReorder != null ) ? m_specColorReorder.OrderIndex : -1 );
|
|
m_inlineOpacityMaskClipValue.WriteToString( ref nodeInfo );
|
|
m_additionalDirectives.WriteToString( ref nodeInfo );
|
|
m_additionalSurfaceOptions.WriteToString( ref nodeInfo );
|
|
m_usePass.WriteToString( ref nodeInfo );
|
|
m_drawInstancedHelper.WriteToString( ref nodeInfo );
|
|
m_inlineChromaticAberration.WriteToString( ref nodeInfo );
|
|
m_inlineAlphaToCoverage.WriteToString( ref nodeInfo );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_samplingMacros );
|
|
}
|
|
|
|
private bool TestCustomBlendMode()
|
|
{
|
|
switch( m_alphaMode )
|
|
{
|
|
case AlphaMode.Opaque:
|
|
{
|
|
if( m_renderType == RenderType.Opaque && m_renderQueue == RenderQueue.Geometry )
|
|
return false;
|
|
}
|
|
break;
|
|
case AlphaMode.Masked:
|
|
{
|
|
if( m_renderType == RenderType.TransparentCutout && m_renderQueue == RenderQueue.AlphaTest )
|
|
return false;
|
|
}
|
|
break;
|
|
case AlphaMode.Transparent:
|
|
case AlphaMode.Premultiply:
|
|
{
|
|
if( m_renderType == RenderType.Transparent && m_renderQueue == RenderQueue.Transparent )
|
|
return false;
|
|
}
|
|
break;
|
|
case AlphaMode.Translucent:
|
|
{
|
|
if( m_renderType == RenderType.Opaque && m_renderQueue == RenderQueue.Transparent )
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private void UpdateFromBlendMode()
|
|
{
|
|
m_checkChanges = true;
|
|
bool lockRefractionPort = false;
|
|
if( m_currentLightModel == StandardShaderLightModel.Unlit || m_currentLightModel == StandardShaderLightModel.CustomLighting )
|
|
{
|
|
lockRefractionPort = true;
|
|
}
|
|
|
|
switch( m_alphaMode )
|
|
{
|
|
case AlphaMode.Opaque:
|
|
{
|
|
m_renderType = RenderType.Opaque;
|
|
m_renderQueue = RenderQueue.Geometry;
|
|
m_keepAlpha = true;
|
|
m_refractionPort.Locked = true;
|
|
m_inputPorts[ m_opacityPortId ].Locked = true;
|
|
m_inputPorts[ m_discardPortId ].Locked = true;
|
|
}
|
|
break;
|
|
case AlphaMode.Masked:
|
|
{
|
|
m_renderType = RenderType.TransparentCutout;
|
|
m_renderQueue = RenderQueue.AlphaTest;
|
|
m_keepAlpha = true;
|
|
m_refractionPort.Locked = true;
|
|
m_inputPorts[ m_opacityPortId ].Locked = true;
|
|
m_inputPorts[ m_discardPortId ].Locked = false;
|
|
}
|
|
break;
|
|
case AlphaMode.Transparent:
|
|
case AlphaMode.Premultiply:
|
|
{
|
|
m_renderType = RenderType.Transparent;
|
|
m_renderQueue = RenderQueue.Transparent;
|
|
m_refractionPort.Locked = false || lockRefractionPort;
|
|
m_inputPorts[ m_opacityPortId ].Locked = false;
|
|
m_inputPorts[ m_discardPortId ].Locked = true;
|
|
}
|
|
break;
|
|
case AlphaMode.Translucent:
|
|
{
|
|
m_renderType = RenderType.Opaque;
|
|
m_renderQueue = RenderQueue.Transparent;
|
|
m_refractionPort.Locked = false || lockRefractionPort;
|
|
m_inputPorts[ m_opacityPortId ].Locked = false;
|
|
m_inputPorts[ m_discardPortId ].Locked = true;
|
|
}
|
|
break;
|
|
case AlphaMode.Custom:
|
|
{
|
|
m_refractionPort.Locked = false || lockRefractionPort;
|
|
m_inputPorts[ m_opacityPortId ].Locked = false;
|
|
m_inputPorts[ m_discardPortId ].Locked = false;
|
|
}
|
|
break;
|
|
}
|
|
|
|
m_blendOpsHelper.SetBlendOpsFromBlendMode( m_alphaMode, ( m_alphaMode == AlphaMode.Custom || m_alphaMode == AlphaMode.Opaque ) );
|
|
}
|
|
|
|
public bool CastShadows { get { return m_castShadows; } }
|
|
public StandardShaderLightModel CurrentLightingModel { get { return m_currentLightModel; } }
|
|
public CullMode CurrentCullMode { get { return m_cullMode; } }
|
|
//public AdditionalIncludesHelper AdditionalIncludes { get { return m_additionalIncludes; } set { m_additionalIncludes = value; } }
|
|
//public AdditionalPragmasHelper AdditionalPragmas { get { return m_additionalPragmas; } set { m_additionalPragmas = value; } }
|
|
//public AdditionalDefinesHelper AdditionalDefines { get { return m_additionalDefines; } set { m_additionalDefines = value; } }
|
|
public TemplateAdditionalDirectivesHelper AdditionalDirectives { get { return m_additionalDirectives; } }
|
|
public OutlineOpHelper OutlineHelper { get { return m_outlineHelper; } }
|
|
public float OpacityMaskClipValue { get { return m_opacityMaskClipValue; } }
|
|
public InlineProperty InlineOpacityMaskClipValue { get { return m_inlineOpacityMaskClipValue; } set { m_inlineOpacityMaskClipValue = value; } }
|
|
public bool CustomShadowCaster
|
|
{
|
|
get
|
|
{
|
|
bool hasOpacity = m_inputPorts[ m_opacityPortId ].IsConnected;
|
|
return
|
|
( !m_renderingOptionsOpHelper.UseDefaultShadowCaster &&
|
|
( ( m_castShadows && ( m_alphaToCoverage || m_inlineAlphaToCoverage.Active ) ) ||
|
|
( m_castShadows && hasOpacity ) ||
|
|
( m_castShadows && ( m_currentDataCollector.UsingWorldNormal || m_currentDataCollector.UsingWorldReflection || m_currentDataCollector.UsingViewDirection ) ) ||
|
|
( m_castShadows && m_inputPorts[ m_discardPortId ].Available && m_inputPorts[ m_discardPortId ].IsConnected && m_currentLightModel == StandardShaderLightModel.CustomLighting ) ) );
|
|
}
|
|
}
|
|
public override AvailableShaderTypes CurrentMasterNodeCategory { get { return AvailableShaderTypes.SurfaceShader; } }
|
|
}
|
|
}
|