Roman 5b28c9a977 Squashed commit of the following:
commit bb3be793ca5db3df43679f2d6c34c75f768047a1
Author: SAIPO <grasste0403@hotmail.com>
Date:   Wed Dec 22 07:46:07 2021 +0800

    修改佛教Boss关卡和伊斯兰Boss关卡的粒子特效

commit 1987a63954402be8894f9cc9805545432afefa18
Author: SAIPO <grasste0403@hotmail.com>
Date:   Tue Dec 21 20:55:05 2021 +0800

    任务:编写shader,完善数据库类
    1.完善了PlayerInfo类,用以数据库功能
     1) 编写GetSqlData()函数,使用多线程获取用户信息,使用前请先设置公关变量name。
     2) 编写CreateUser(string username)函数,在用户表内创建一个用户。
     3) 编写hasName(string _searchName)函数,判断是否存在这个用户。
     4) 编写GetBoardInfo(int WorldId)函数,获取指定世界的留言板链表。
     5) 编写GetDeadInfo(int WorldId)函数,获取指定世界的死亡信息链表。
     6) 编写CreateDead(int WorldId, Vector2 postion)函数,创建一条死亡信息。
     7) 编写CreateBoard(int WorldId, Vector2 postion,string text)函数,创建一条留言信息。
     8) 编写UpdatePlayerInfo()函数,将类里储存的信息上传到数据库。

    2.实装相关Shader
     1)完善以撒关卡的屏幕后特效,使其可以在发怒场景发出红色辉光。
     2)完善以撒鬼魂的粒子,并且颜色和发怒与否关联。
     3)实装以撒关卡的窗户辉光效果。
     4)实装伊斯兰Boss关卡炸弹弹反的粒子特效。
     5)实装伊斯兰Boss关卡的尘土特效(需要重做)
     6)实装佛教Boss关卡的敲钟声波特效。
     7)实装佛教Boss关卡的钟声受击灰尘(需要重做)

    3.目前发现的bug
     1)当人物恰好调到角落里会卡动画。
     2)伊斯兰Boss关卡,特洛伊木马吐出的炸弹落到特效小怪上会闪退。

commit c06b842382051bc260d9f509491c683a41ca2a4c
Author: SAIPO <grasste0403@hotmail.com>
Date:   Tue Dec 21 14:08:06 2021 +0800

    Squashed commit of the following:

    commit e7dcdec1d9913e283f42d42f72f1030f0c8b6fda
    Author: Roman <1325980292@qq.com>
    Date:   Tue Dec 21 00:45:50 2021 +0800

        任务:搭建前置关卡,编写演出逻辑

        1.流程化游戏
        (1.制作转移器,内含字典,根据玩家的静态属性“阶段”来决定到转移点后将会移动到哪一个场景
        (2.制作转场器,水平方向从左到右

        下班

    commit 74f926815ec8d00fa051192eb3b978ff4b3c01a6
    Author: Roman <1325980292@qq.com>
    Date:   Mon Dec 20 23:33:14 2021 +0800

        任务:搭建前置关卡,编写演出逻辑

        1.编写基督前置关卡
        (1.放置平台、怪物和男童
        (2.修改男童类,外加OnSaveEvent,OnSave时若有事件则触发该Event
        (3.编写开幕演出,与yi前置类似
        (4.编写男童解救演出
        ((1.触发Fungus对话
        ((2.对话结束后,开启通往上层的门

        2.搭建村场景
        (1.放置平台和元素
        (2.为可动元素制作动画

        3.为玩家添加static属性,进度。0:刚开,1进村,2通佛,3通伊,4.通基

        4.制作死亡重开功能
        (1.当玩家生命值降到0及以下,触发死亡事件
        (2.死亡后reload当前场景,并设记录员,关闭某些事件和演出不再执行

        *优化和修复
        (1.尝试制作击中卡肉效果,目前打击感太弱。也可以尝试粒子效果

        *至此,全部前置关卡搭建完毕,村场景搭建完毕。
        *明天可以完成流程化,接下来就是填充剧情、UI、死亡标记和留言板等系统了

        下班

    commit f257b40d10373a13380e9c395fe94d6559a82a0f
    Author: Roman <1325980292@qq.com>
    Date:   Sun Dec 19 23:57:44 2021 +0800

        任务:搭建前置关卡,编写演出逻辑

        1.编写佛教前置关开场演出
        (*.休整地形,使得左边多出一块地面,方便演出正常运作
        (*.项目后期再通过逻辑触发该演出,目前先用调试方式触发演出
        (1.关闭空气墙
        (2.修改玩家inputDir使玩家从屏幕外冲进到屏幕内部
        (3.等待一段时间
        (4.此时玩家应该走到某个合适的位置,停止玩家的inputDir
        (5.等待一小段时间给玩家反应
        (6.修改相机offset,使其对准对话的两个小怪
        (7.等待一小段时间给玩家反应
        (8.触发Fungus对话
        (9.Fungus对话结束后,返回标记命令演出Main继续执行
        *.修改NormalEnemy,添加标识isInFoStage,在Update中判断,若是,使该怪物水平方向上追踪玩家,可以参考爱欲品的Seek
        (10.修改左边小怪的isInFoStage
        (11.开启右边小怪的Path动画,表现其慌忙逃跑
        (12.Invoke一个延时,等右边小怪逃出视野后删除它
        (13.触发善后和结束事件
        (14.重写善后事件,重新开启空气墙

        2.搭建伊斯兰前置关卡

        3.创建伊斯兰前置关卡演出
        (1.关闭空气墙
        (2.修改玩家inputDir使玩家从屏幕外冲进到屏幕内部
        (3.等待一段时间
        (4.此时玩家应该走到某个合适的位置,停止玩家的inputDir
        (5.等待一小段时间给玩家反应
        (6.触发善后与结束事件

        4.创建玩家隔间触发事件
        (1.是进入式触发器对象
        (2.触发时Call隔间演出

        5.编写隔间演出逻辑
        (1.表现关门
        (2.左右晃一下镜头,中心移动到左右门处,表示门被关闭
        (3.镜头回到玩家处,同时压缩相机可移动范围更窄
        (4.打开隔间墙壁的空气墙
        (5.设置EndEvent为伊斯兰事件

        6.编写召唤伊斯兰事件
        (1.摘自木马的召唤攻击,稍作修改
        (2.当召唤的伊斯兰全部挂了,触发隔间结束事件

        7.编写隔间结束事件
        (1.表现开门
        (2.关闭隔间的空气墙
        (3.重设相机移动范围

        8.搭建基督前置关卡

        *.至此,第一关、第二关前置关卡的逻辑基本开发完毕

        *.明天能做完所有前置关,顺便应该能搭完村场景,后天可以开始搭建新系统,目前还差留言、死亡标记等系统等待编写

        下班

    commit cd22966ad7637a84c0f08c3a716d5ec549699749
    Author: Roman <1325980292@qq.com>
    Date:   Sun Dec 19 14:12:05 2021 +0800

        Squashed commit of the following:

        commit 26aff356971bdc2c2a6a3bd444eeb50c4bf7ec14
        Author: SAIPO <grasste0403@hotmail.com>
        Date:   Sun Dec 19 02:20:44 2021 +0800

            导入近期制作的一些Shader
            1.合并分支
            2.完成了人物描边的流动shader制作,并且可以对Bloom屏幕后处理产生反应。
            3.完成了基督教boss关卡,彩色窗户辉光的shader制作,可以对Bloom产生反应。
            4.完成了伊斯兰教弹反的炸弹拖尾粒子shader的制作。
            5.完成了火焰粒子shader的制作(可以用在基督教的以撒鬼魂上)。
            6.完成了灰尘粒子像素化的shader制作。
            7.完成了边缘扭曲的shader制作,可以用在一些树木上,让画面产生动感。

            明天制作敲钟的声波Shader

    # Conflicts:
    #	UserSettings/EditorUserSettings.asset

commit 26aff356971bdc2c2a6a3bd444eeb50c4bf7ec14
Author: SAIPO <grasste0403@hotmail.com>
Date:   Sun Dec 19 02:20:44 2021 +0800

    导入近期制作的一些Shader
    1.合并分支
    2.完成了人物描边的流动shader制作,并且可以对Bloom屏幕后处理产生反应。
    3.完成了基督教boss关卡,彩色窗户辉光的shader制作,可以对Bloom产生反应。
    4.完成了伊斯兰教弹反的炸弹拖尾粒子shader的制作。
    5.完成了火焰粒子shader的制作(可以用在基督教的以撒鬼魂上)。
    6.完成了灰尘粒子像素化的shader制作。
    7.完成了边缘扭曲的shader制作,可以用在一些树木上,让画面产生动感。

    明天制作敲钟的声波Shader

# Conflicts:
#	Assets/Scenes/TeLuoYiStageTest.unity
#	Assets/Shader/火焰粒子shader/particle.shadergraph
#	Assets/Shader/灰尘粒子用shader/Pixel_My.shader
#	Assets/Shader/灰尘粒子用shader/Unlit_Pixel_My 1.mat
#	Assets/Shader/灰尘粒子用shader/Unlit_Pixel_My 2.mat
#	Assets/Shader/灰尘粒子用shader/Unlit_Pixel_My.mat
#	Logs/ApiUpdaterCheck.txt
#	UserSettings/EditorUserSettings.asset
2021-12-22 10:01:30 +08:00

3343 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,
xboxseries,
ps4,
playstation,
psp2,
n3ds,
wiiu,
@switch,
vulkan,
nomrt,
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;
#if UNITY_IOS
// On iOS custom app data must be used since fixed4 color from appdata_full generates an error on it when tessellation is active
m_currentDataCollector.ForceCustomAppDataUsage();
#endif
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( ref m_currentDataCollector ) + "\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\t#if !defined(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.SurfaceVertexStructure + " 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; } }
}
}