634 lines
22 KiB
C#
634 lines
22 KiB
C#
// Amplify Shader Editor - Visual Shader Editing Tool
|
|
// Copyright (c) Amplify Creations, Lda <info@amplify.pt>
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace AmplifyShaderEditor
|
|
{
|
|
public enum OutlineMode
|
|
{
|
|
VertexOffset,
|
|
VertexScale
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class OutlineOpHelper
|
|
{
|
|
|
|
private string[] ModeTags =
|
|
{
|
|
"Tags{ }",
|
|
"Tags{ \"RenderType\" = \"TransparentCutout\" \"Queue\" = \"AlphaTest+0\"}",
|
|
"Tags{ \"RenderType\" = \"Transparent\" \"Queue\" = \"Transparent+0\"}",
|
|
"Tags{ \"RenderType\" = \"Transparent\" \"Queue\" = \"Transparent+0\" }"
|
|
};
|
|
|
|
private string[] ModePragma =
|
|
{
|
|
string.Empty,
|
|
string.Empty,
|
|
"alpha:fade ",
|
|
"alpha:premul "
|
|
};
|
|
|
|
|
|
private readonly string OutlineSurfaceConfig = "#pragma surface outlineSurf Outline {0} keepalpha noshadow noambient novertexlights nolightmap nodynlightmap nodirlightmap nometa noforwardadd vertex:outlineVertexDataFunc ";
|
|
|
|
private readonly string OutlineBodyStructBegin = "struct Input {";
|
|
private readonly string OutlineBodyStructDefault = "\thalf filler;";
|
|
private readonly string OutlineBodyStructEnd = "};";
|
|
|
|
private readonly string OutlineDefaultUniformColor = "half4 _ASEOutlineColor;";
|
|
private readonly string OutlineDefaultUniformWidth = "half _ASEOutlineWidth;";
|
|
private readonly string OutlineDefaultUniformColorInstanced = "UNITY_DEFINE_INSTANCED_PROP( half4, _ASEOutlineColor )";
|
|
private readonly string OutlineDefaultUniformWidthInstanced = "UNITY_DEFINE_INSTANCED_PROP( half, _ASEOutlineWidth )";
|
|
|
|
private readonly string OutlineDefaultVertexHeader = "void outlineVertexDataFunc( inout appdata_full v, out Input o )\n\t\t{";
|
|
private readonly string OutlineTessVertexHeader = "void outlineVertexDataFunc( inout appdata_full v )\n\t\t{";
|
|
|
|
private readonly string OutlineDefaultVertexOutputDeclaration = "\tUNITY_INITIALIZE_OUTPUT( Input, o );";
|
|
|
|
private readonly string[] OutlineSurfBody = {
|
|
"\to.Emission = _ASEOutlineColor.rgb;",
|
|
"\to.Alpha = 1;"
|
|
};
|
|
|
|
private readonly string[] OutlineSurfBodyInstanced = {
|
|
"\to.Emission = UNITY_ACCESS_INSTANCED_PROP(_ASEOutlineColor).rgb;",
|
|
"\to.Alpha = 1;"
|
|
};
|
|
|
|
private readonly string[] OutlineBodyDefaultSurfBegin = {
|
|
"}",
|
|
"inline half4 LightingOutline( SurfaceOutput s, half3 lightDir, half atten ) { return half4 ( 0,0,0, s.Alpha); }",
|
|
"void outlineSurf( Input i, inout SurfaceOutput o )",
|
|
"{"};
|
|
|
|
private readonly string[] OutlineBodyDefaultSurfEnd = {
|
|
"}",
|
|
"ENDCG",
|
|
"\n"};
|
|
|
|
//private const string OutlineInstancedHeader = "#pragma multi_compile_instancing";
|
|
|
|
//private readonly string[] OutlineBodyInstancedBegin = {
|
|
// "UNITY_INSTANCING_CBUFFER_START({0})",
|
|
// "\tUNITY_DEFINE_INSTANCED_PROP( half4, _ASEOutlineColor )",
|
|
// "\tUNITY_DEFINE_INSTANCED_PROP(half, _ASEOutlineWidth)",
|
|
// "UNITY_INSTANCING_CBUFFER_END",
|
|
// "void outlineVertexDataFunc( inout appdata_full v, out Input o )",
|
|
// "{",
|
|
// "\tUNITY_INITIALIZE_OUTPUT( Input, o );"};
|
|
|
|
//private readonly string[] OutlineBodyInstancedEnd = {
|
|
// "}",
|
|
// "inline half4 LightingOutline( SurfaceOutput s, half3 lightDir, half atten ) { return half4 ( 0,0,0, s.Alpha); }",
|
|
// "void outlineSurf( Input i, inout SurfaceOutput o ) { o.Emission = UNITY_ACCESS_INSTANCED_PROP( _ASEOutlineColor ).rgb; o.Alpha = 1; }",
|
|
// "ENDCG",
|
|
// "\n"};
|
|
|
|
private const string WidthVariableAccessInstanced = "UNITY_ACCESS_INSTANCED_PROP( _ASEOutlineWidth )";
|
|
|
|
private const string OutlineVertexOffsetMode = "\tv.vertex.xyz += ( v.normal * {0} );";
|
|
private const string OutlineVertexScaleMode = "\tv.vertex.xyz *= ( 1 + {0});";
|
|
private const string OutlineVertexCustomMode = "\tv.vertex.xyz += {0};";
|
|
|
|
private const string OutlineColorLabel = "Color";
|
|
private const string OutlineWidthLabel = "Width";
|
|
|
|
private const string ColorPropertyName = "_ASEOutlineColor";
|
|
private const string WidthPropertyName = "_ASEOutlineWidth";
|
|
|
|
|
|
private const string WidthPropertyNameInstanced = "UNITY_ACCESS_INSTANCED_PROP(_ASEOutlineWidth)";
|
|
|
|
|
|
|
|
private const string ColorPropertyDec = "_ASEOutlineColor( \"Outline Color\", Color ) = ({0})";
|
|
private const string OutlinePropertyDec = "_ASEOutlineWidth( \"Outline Width\", Float ) = {0}";
|
|
|
|
private const string ModePropertyStr = "Mode";
|
|
|
|
private const string NoFogStr = "No Fog";
|
|
|
|
private const string BillboardInstructionFormat = "\t{0};";
|
|
|
|
[SerializeField]
|
|
private Color m_outlineColor;
|
|
|
|
[SerializeField]
|
|
private float m_outlineWidth;
|
|
|
|
[SerializeField]
|
|
private bool m_enabled;
|
|
|
|
[SerializeField]
|
|
private OutlineMode m_mode = OutlineMode.VertexOffset;
|
|
|
|
[SerializeField]
|
|
private bool m_noFog = true;
|
|
|
|
private CullMode m_cullMode = CullMode.Front;
|
|
private int m_zTestMode = 0;
|
|
private int m_zWriteMode = 0;
|
|
private bool m_dirtyInput = false;
|
|
private string m_inputs = string.Empty;
|
|
private List<PropertyDataCollector> m_inputList = new List<PropertyDataCollector>();
|
|
private string m_uniforms = string.Empty;
|
|
private List<PropertyDataCollector> m_uniformList = new List<PropertyDataCollector>();
|
|
private List<PropertyDataCollector> m_instancedPropertiesList = new List<PropertyDataCollector>();
|
|
private string m_instancedProperties = string.Empty;
|
|
private string m_instructions = string.Empty;
|
|
private string m_functions = string.Empty;
|
|
private string m_includes = string.Empty;
|
|
private string m_pragmas = string.Empty;
|
|
private string m_defines = string.Empty;
|
|
private string m_standardAdditionalDirectives = string.Empty;
|
|
private string m_vertexData = string.Empty;
|
|
private string m_grabPasses = string.Empty;
|
|
private Dictionary<string, string> m_localFunctions;
|
|
|
|
//private OutlineMode m_customMode = OutlineMode.VertexOffset;
|
|
private int m_offsetMode = 0;
|
|
private bool m_customNoFog = true;
|
|
|
|
public void Draw( ParentNode owner, GUIStyle toolbarstyle, Material mat )
|
|
{
|
|
Color cachedColor = GUI.color;
|
|
GUI.color = new Color( cachedColor.r, cachedColor.g, cachedColor.b, 0.5f );
|
|
EditorGUILayout.BeginHorizontal( toolbarstyle );
|
|
GUI.color = cachedColor;
|
|
owner.ContainerGraph.ParentWindow.InnerWindowVariables.OutlineActiveMode = owner.GUILayoutToggle( owner.ContainerGraph.ParentWindow.InnerWindowVariables.OutlineActiveMode , EditorVariablesManager.OutlineActiveMode.LabelName, UIUtils.MenuItemToggleStyle, GUILayout.ExpandWidth( true ) );
|
|
EditorGUI.BeginChangeCheck();
|
|
m_enabled = owner.EditorGUILayoutToggle( string.Empty, m_enabled, UIUtils.MenuItemEnableStyle, GUILayout.Width( 16 ) );
|
|
if( EditorGUI.EndChangeCheck() )
|
|
{
|
|
if( m_enabled )
|
|
UpdateToMaterial( mat );
|
|
|
|
UIUtils.RequestSave();
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
if( owner.ContainerGraph.ParentWindow.InnerWindowVariables.OutlineActiveMode )
|
|
{
|
|
cachedColor = GUI.color;
|
|
GUI.color = new Color( cachedColor.r, cachedColor.g, cachedColor.b, ( EditorGUIUtility.isProSkin ? 0.5f : 0.25f ) );
|
|
EditorGUILayout.BeginVertical( UIUtils.MenuItemBackgroundStyle );
|
|
GUI.color = cachedColor;
|
|
|
|
EditorGUILayout.Separator();
|
|
EditorGUI.BeginDisabledGroup( !m_enabled );
|
|
|
|
EditorGUI.indentLevel += 1;
|
|
{
|
|
m_mode = (OutlineMode)owner.EditorGUILayoutEnumPopup( ModePropertyStr, m_mode );
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
m_outlineColor = owner.EditorGUILayoutColorField( OutlineColorLabel, m_outlineColor );
|
|
if( EditorGUI.EndChangeCheck() && mat != null )
|
|
{
|
|
if( mat.HasProperty( ColorPropertyName ) )
|
|
{
|
|
mat.SetColor( ColorPropertyName, m_outlineColor );
|
|
}
|
|
}
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
m_outlineWidth = owner.EditorGUILayoutFloatField( OutlineWidthLabel, m_outlineWidth );
|
|
if( EditorGUI.EndChangeCheck() && mat != null )
|
|
{
|
|
if( mat.HasProperty( WidthPropertyName ) )
|
|
{
|
|
mat.SetFloat( WidthPropertyName, m_outlineWidth );
|
|
}
|
|
}
|
|
|
|
m_noFog = owner.EditorGUILayoutToggle( NoFogStr, m_noFog );
|
|
}
|
|
|
|
EditorGUI.indentLevel -= 1;
|
|
EditorGUI.EndDisabledGroup();
|
|
EditorGUILayout.Separator();
|
|
EditorGUILayout.EndVertical();
|
|
}
|
|
}
|
|
|
|
public void UpdateToMaterial( Material mat )
|
|
{
|
|
if( mat == null )
|
|
return;
|
|
|
|
if( mat.HasProperty( ColorPropertyName ) )
|
|
{
|
|
mat.SetColor( ColorPropertyName, m_outlineColor );
|
|
}
|
|
|
|
if( mat.HasProperty( WidthPropertyName ) )
|
|
{
|
|
mat.SetFloat( WidthPropertyName, m_outlineWidth );
|
|
}
|
|
}
|
|
|
|
public void ReadFromString( ref uint index, ref string[] nodeParams )
|
|
{
|
|
m_enabled = Convert.ToBoolean( nodeParams[ index++ ] );
|
|
m_outlineWidth = Convert.ToSingle( nodeParams[ index++ ] );
|
|
m_outlineColor = IOUtils.StringToColor( nodeParams[ index++ ] );
|
|
if( UIUtils.CurrentShaderVersion() > 5004 )
|
|
{
|
|
m_mode = (OutlineMode)Enum.Parse( typeof( OutlineMode ), nodeParams[ index++ ] );
|
|
}
|
|
|
|
if( UIUtils.CurrentShaderVersion() > 13902 )
|
|
{
|
|
m_noFog = Convert.ToBoolean( nodeParams[ index++ ] );
|
|
}
|
|
}
|
|
|
|
public void WriteToString( ref string nodeInfo )
|
|
{
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_enabled );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_outlineWidth );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, IOUtils.ColorToString( m_outlineColor ) );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_mode );
|
|
IOUtils.AddFieldValueToString( ref nodeInfo, m_noFog );
|
|
}
|
|
|
|
public void AddToDataCollector( ref MasterNodeDataCollector dataCollector )
|
|
{
|
|
if( !dataCollector.UsingCustomOutlineColor )
|
|
dataCollector.AddToProperties( -1, string.Format( ColorPropertyDec, IOUtils.ColorToString( m_outlineColor ) ), -1 );
|
|
if( !dataCollector.UsingCustomOutlineWidth )
|
|
dataCollector.AddToProperties( -1, string.Format( OutlinePropertyDec, m_outlineWidth ), -1 );
|
|
}
|
|
|
|
public void UpdateFromMaterial( Material mat )
|
|
{
|
|
if( mat.HasProperty( ColorPropertyName ) )
|
|
{
|
|
m_outlineColor = mat.GetColor( ColorPropertyName );
|
|
}
|
|
|
|
if( mat.HasProperty( WidthPropertyName ) )
|
|
{
|
|
m_outlineWidth = mat.GetFloat( WidthPropertyName );
|
|
}
|
|
}
|
|
|
|
void AddMultibodyString( string body , List<string> list )
|
|
{
|
|
body = body.Replace( "\t\t", string.Empty );
|
|
string[] strArr = body.Split( '\n' );
|
|
for( int i = 0; i < strArr.Length; i++ )
|
|
{
|
|
list.Add( strArr[ i ] );
|
|
}
|
|
|
|
}
|
|
public string[] OutlineFunctionBody( ref MasterNodeDataCollector dataCollector, bool instanced, bool isShadowCaster, string shaderName, string[] billboardInfo, ref TessellationOpHelper tessOpHelper, string target, PrecisionType precision )
|
|
{
|
|
List<string> body = new List<string>();
|
|
body.Add( ModeTags[ dataCollector.CustomOutlineSelectedAlpha ] );
|
|
if( !string.IsNullOrEmpty( m_grabPasses ))
|
|
body.Add( m_grabPasses.Replace( "\t\t",string.Empty ));
|
|
|
|
if( m_zWriteMode != 0 )
|
|
body.Add( "ZWrite " + ZBufferOpHelper.ZWriteModeValues[ m_zWriteMode ] );
|
|
if( m_zTestMode != 0 )
|
|
body.Add( "ZTest " + ZBufferOpHelper.ZTestModeValues[ m_zTestMode ] );
|
|
|
|
body.Add( "Cull " + m_cullMode );
|
|
body.Add( "CGPROGRAM" );
|
|
if( tessOpHelper.EnableTesselation )
|
|
{
|
|
body.Add( "#include \"" + TessellationOpHelper.TessInclude + "\"" );
|
|
body.Add( "#pragma target " + target );
|
|
}
|
|
else
|
|
{
|
|
body.Add( "#pragma target 3.0" );
|
|
}
|
|
bool customOutline = dataCollector.UsingCustomOutlineColor || dataCollector.UsingCustomOutlineWidth || dataCollector.UsingCustomOutlineAlpha;
|
|
int outlineMode = customOutline ? m_offsetMode : ( m_mode == OutlineMode.VertexOffset ? 0 : 1 );
|
|
string extraOptions = ( customOutline ? m_customNoFog : m_noFog ) ? "nofog " : string.Empty;
|
|
if( dataCollector.CustomOutlineSelectedAlpha > 0 )
|
|
{
|
|
extraOptions += ModePragma[ dataCollector.CustomOutlineSelectedAlpha ];
|
|
}
|
|
|
|
string surfConfig = string.Format( OutlineSurfaceConfig, extraOptions );
|
|
|
|
if( tessOpHelper.EnableTesselation )
|
|
tessOpHelper.WriteToOptionalParams( ref surfConfig );
|
|
|
|
body.Add( surfConfig );
|
|
if( !isShadowCaster )
|
|
{
|
|
AddMultibodyString( m_defines, body );
|
|
AddMultibodyString( m_includes, body );
|
|
AddMultibodyString( m_pragmas, body );
|
|
}
|
|
AddMultibodyString( m_standardAdditionalDirectives, body );
|
|
//if( instanced )
|
|
//{
|
|
// body.Add( OutlineInstancedHeader );
|
|
//}
|
|
|
|
if( customOutline )
|
|
{
|
|
if( isShadowCaster )
|
|
{
|
|
|
|
for( int i = 0; i < InputList.Count; i++ )
|
|
{
|
|
dataCollector.AddToInput( InputList[ i ].NodeId, InputList[ i ].PropertyName, !InputList[ i ].IsDirective );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( !string.IsNullOrEmpty( m_inputs ) )
|
|
body.Add( m_inputs.Trim( '\t', '\n' ) );
|
|
}
|
|
|
|
if( !DirtyInput && !isShadowCaster )
|
|
body.Add( OutlineBodyStructDefault );
|
|
|
|
if( !isShadowCaster )
|
|
body.Add( OutlineBodyStructEnd );
|
|
}
|
|
else if( !isShadowCaster )
|
|
{
|
|
body.Add( OutlineBodyStructBegin );
|
|
body.Add( OutlineBodyStructDefault );
|
|
body.Add( OutlineBodyStructEnd );
|
|
}
|
|
|
|
if( instanced )
|
|
{
|
|
//for( int i = 0; i < OutlineBodyInstancedBegin.Length; i++ )
|
|
//{
|
|
// body.Add( ( i == 0 ) ? string.Format( OutlineBodyInstancedBegin[ i ], shaderName ) : OutlineBodyInstancedBegin[ i ] );
|
|
//}
|
|
|
|
//if( (object)billboardInfo != null )
|
|
//{
|
|
// for( int j = 0; j < billboardInfo.Length; j++ )
|
|
// {
|
|
// body.Add( string.Format( BillboardInstructionFormat, billboardInfo[ j ] ) );
|
|
// }
|
|
//}
|
|
|
|
//switch( outlineMode )
|
|
//{
|
|
// case 0: body.Add( string.Format( OutlineVertexOffsetMode, WidthVariableAccessInstanced ) ); break;
|
|
// case 1: body.Add( string.Format( OutlineVertexScaleMode, WidthVariableAccessInstanced ) ); break;
|
|
// case 2: body.Add( string.Format( OutlineVertexCustomMode, WidthVariableAccessInstanced ) ); break;
|
|
//}
|
|
//for( int i = 0; i < OutlineBodyInstancedEnd.Length; i++ )
|
|
//{
|
|
// body.Add( OutlineBodyInstancedEnd[ i ] );
|
|
//}
|
|
|
|
//Instanced block name must differ from used on main shader so it won't throw a duplicate name error
|
|
shaderName = shaderName+ "Outline";
|
|
bool openCBuffer = true;
|
|
if( customOutline )
|
|
{
|
|
if( isShadowCaster )
|
|
{
|
|
for( int i = 0; i < UniformList.Count; i++ )
|
|
{
|
|
dataCollector.AddToUniforms( UniformList[ i ].NodeId, UniformList[ i ].PropertyName );
|
|
}
|
|
|
|
foreach( KeyValuePair<string, string> kvp in m_localFunctions )
|
|
{
|
|
dataCollector.AddFunction( kvp.Key, kvp.Value );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( !string.IsNullOrEmpty( Uniforms ) )
|
|
body.Add( Uniforms.Trim( '\t', '\n' ) );
|
|
|
|
openCBuffer = false;
|
|
body.Add( string.Format( IOUtils.InstancedPropertiesBegin, shaderName ));
|
|
if( !string.IsNullOrEmpty( InstancedProperties ) )
|
|
body.Add( InstancedProperties.Trim( '\t', '\n' ) );
|
|
}
|
|
}
|
|
|
|
if( openCBuffer)
|
|
body.Add( string.Format( IOUtils.InstancedPropertiesBegin, shaderName ) );
|
|
|
|
if( !dataCollector.UsingCustomOutlineColor )
|
|
body.Add( precision == PrecisionType.Float ? OutlineDefaultUniformColorInstanced.Replace( "half", "float" ) : OutlineDefaultUniformColorInstanced );
|
|
|
|
if( !dataCollector.UsingCustomOutlineWidth )
|
|
body.Add( precision == PrecisionType.Float ? OutlineDefaultUniformWidthInstanced.Replace( "half", "float" ) : OutlineDefaultUniformWidthInstanced );
|
|
|
|
body.Add( IOUtils.InstancedPropertiesEnd );
|
|
|
|
//Functions
|
|
if( customOutline && !isShadowCaster )
|
|
body.Add( Functions );
|
|
|
|
if( tessOpHelper.EnableTesselation && !isShadowCaster )
|
|
{
|
|
body.Add( tessOpHelper.Uniforms().TrimStart( '\t' ) );
|
|
body.Add( tessOpHelper.GetCurrentTessellationFunction.Trim( '\t', '\n' ) + "\n" );
|
|
}
|
|
|
|
if( tessOpHelper.EnableTesselation )
|
|
{
|
|
body.Add( OutlineTessVertexHeader );
|
|
}
|
|
else
|
|
{
|
|
body.Add( OutlineDefaultVertexHeader );
|
|
body.Add( OutlineDefaultVertexOutputDeclaration );
|
|
}
|
|
|
|
if( customOutline )
|
|
{
|
|
if( !string.IsNullOrEmpty( VertexData ) )
|
|
body.Add( "\t" + VertexData.Trim( '\t', '\n' ) );
|
|
}
|
|
|
|
if( (object)billboardInfo != null )
|
|
{
|
|
for( int j = 0; j < billboardInfo.Length; j++ )
|
|
{
|
|
body.Add( string.Format( BillboardInstructionFormat, billboardInfo[ j ] ) );
|
|
}
|
|
}
|
|
|
|
switch( outlineMode )
|
|
{
|
|
case 0: body.Add( string.Format( OutlineVertexOffsetMode, dataCollector.UsingCustomOutlineWidth ? "outlineVar" : WidthPropertyNameInstanced ) ); break;
|
|
case 1: body.Add( string.Format( OutlineVertexScaleMode, dataCollector.UsingCustomOutlineWidth ? "outlineVar" : WidthPropertyNameInstanced ) ); break;
|
|
case 2: body.Add( string.Format( OutlineVertexCustomMode, dataCollector.UsingCustomOutlineWidth ? "outlineVar" : WidthPropertyNameInstanced ) ); break;
|
|
}
|
|
|
|
for( int i = 0; i < OutlineBodyDefaultSurfBegin.Length; i++ )
|
|
{
|
|
body.Add( OutlineBodyDefaultSurfBegin[ i ] );
|
|
}
|
|
if( dataCollector.UsingCustomOutlineColor || dataCollector.CustomOutlineSelectedAlpha > 0 )
|
|
{
|
|
body.Add( "\t" + Instructions.Trim( '\t', '\n' ) );
|
|
}
|
|
else
|
|
{
|
|
for( int i = 0; i < OutlineSurfBodyInstanced.Length; i++ )
|
|
{
|
|
body.Add( OutlineSurfBodyInstanced[ i ] );
|
|
}
|
|
}
|
|
|
|
for( int i = 0; i < OutlineBodyDefaultSurfEnd.Length; i++ )
|
|
{
|
|
body.Add( OutlineBodyDefaultSurfEnd[ i ] );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( customOutline )
|
|
{
|
|
if( isShadowCaster )
|
|
{
|
|
for( int i = 0; i < UniformList.Count; i++ )
|
|
{
|
|
dataCollector.AddToUniforms( UniformList[ i ].NodeId, UniformList[ i ].PropertyName );
|
|
}
|
|
|
|
foreach( KeyValuePair<string, string> kvp in m_localFunctions )
|
|
{
|
|
dataCollector.AddFunction( kvp.Key, kvp.Value );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( !string.IsNullOrEmpty( Uniforms ) )
|
|
body.Add( Uniforms.Trim( '\t', '\n' ) );
|
|
}
|
|
}
|
|
|
|
if( !dataCollector.UsingCustomOutlineColor )
|
|
body.Add( precision == PrecisionType.Float ? OutlineDefaultUniformColor.Replace( "half", "float" ) : OutlineDefaultUniformColor );
|
|
|
|
if( !dataCollector.UsingCustomOutlineWidth )
|
|
body.Add( precision == PrecisionType.Float ? OutlineDefaultUniformWidth.Replace( "half", "float" ) : OutlineDefaultUniformWidth );
|
|
|
|
//Functions
|
|
if( customOutline && !isShadowCaster )
|
|
body.Add( Functions );
|
|
|
|
if( tessOpHelper.EnableTesselation && !isShadowCaster )
|
|
{
|
|
body.Add( tessOpHelper.Uniforms().TrimStart( '\t' ) );
|
|
body.Add( tessOpHelper.GetCurrentTessellationFunction.Trim( '\t', '\n' ) + "\n" );
|
|
}
|
|
|
|
if( tessOpHelper.EnableTesselation )
|
|
{
|
|
body.Add( OutlineTessVertexHeader );
|
|
}
|
|
else
|
|
{
|
|
body.Add( OutlineDefaultVertexHeader );
|
|
body.Add( OutlineDefaultVertexOutputDeclaration );
|
|
}
|
|
|
|
if( customOutline )
|
|
{
|
|
if( !string.IsNullOrEmpty( VertexData ) )
|
|
body.Add( "\t" + VertexData.Trim( '\t', '\n' ) );
|
|
}
|
|
|
|
if( (object)billboardInfo != null )
|
|
{
|
|
for( int j = 0; j < billboardInfo.Length; j++ )
|
|
{
|
|
body.Add( string.Format( BillboardInstructionFormat, billboardInfo[ j ] ) );
|
|
}
|
|
}
|
|
|
|
switch( outlineMode )
|
|
{
|
|
case 0: body.Add( string.Format( OutlineVertexOffsetMode, dataCollector.UsingCustomOutlineWidth ? "outlineVar" : WidthPropertyName ) ); break;
|
|
case 1: body.Add( string.Format( OutlineVertexScaleMode, dataCollector.UsingCustomOutlineWidth ? "outlineVar" : WidthPropertyName ) ); break;
|
|
case 2: body.Add( string.Format( OutlineVertexCustomMode, dataCollector.UsingCustomOutlineWidth ? "outlineVar" : WidthPropertyName ) ); break;
|
|
}
|
|
for( int i = 0; i < OutlineBodyDefaultSurfBegin.Length; i++ )
|
|
{
|
|
body.Add( OutlineBodyDefaultSurfBegin[ i ] );
|
|
}
|
|
if( dataCollector.UsingCustomOutlineColor || dataCollector.CustomOutlineSelectedAlpha > 0 )
|
|
{
|
|
body.Add( "\t" + Instructions.Trim( '\t', '\n' ) );
|
|
}
|
|
else
|
|
{
|
|
for( int i = 0; i < OutlineSurfBody.Length; i++ )
|
|
{
|
|
body.Add( OutlineSurfBody[ i ] );
|
|
}
|
|
}
|
|
|
|
for( int i = 0; i < OutlineBodyDefaultSurfEnd.Length; i++ )
|
|
{
|
|
body.Add( OutlineBodyDefaultSurfEnd[ i ] );
|
|
}
|
|
}
|
|
|
|
string[] bodyArr = body.ToArray();
|
|
body.Clear();
|
|
body = null;
|
|
return bodyArr;
|
|
}
|
|
|
|
|
|
public void Destroy()
|
|
{
|
|
m_inputList = null;
|
|
m_uniformList = null;
|
|
m_instancedPropertiesList = null;
|
|
m_localFunctions = null;
|
|
}
|
|
|
|
public bool EnableOutline { get { return m_enabled; } }
|
|
|
|
public bool UsingCullMode { get { return m_cullMode != CullMode.Front; } }
|
|
public bool UsingZWrite { get { return m_zWriteMode != 0; } }
|
|
public bool UsingZTest { get { return m_zTestMode != 0; } }
|
|
public int ZWriteMode { get { return m_zWriteMode; } set { m_zWriteMode = value; } }
|
|
public int ZTestMode { get { return m_zTestMode; } set { m_zTestMode = value; } }
|
|
public CullMode OutlineCullMode { get { return m_cullMode; } set { m_cullMode = value; } }
|
|
public string Inputs { get { return m_inputs; } set { m_inputs = value; } }
|
|
public string Uniforms { get { return m_uniforms; } set { m_uniforms = value; } }
|
|
public string InstancedProperties { get { return m_instancedProperties; } set { m_instancedProperties = value; } }
|
|
public string Instructions { get { return m_instructions; } set { m_instructions = value; } }
|
|
public string Functions { get { return m_functions; } set { m_functions = value; } }
|
|
public string Includes { get { return m_includes; } set { m_includes = value; } }
|
|
public string Pragmas { get { return m_pragmas; } set { m_pragmas = value; } }
|
|
public string Defines { get { return m_defines; } set { m_defines = value; } }
|
|
public string StandardAdditionalDirectives { get { return m_standardAdditionalDirectives; } set { m_standardAdditionalDirectives = value; } }
|
|
public string VertexData { get { return m_vertexData; } set { m_vertexData = value; } }
|
|
public string GrabPasses { get { return m_grabPasses; } set { m_grabPasses = value; } }
|
|
public List<PropertyDataCollector> InputList { get { return m_inputList; } set { m_inputList = value; } }
|
|
public List<PropertyDataCollector> UniformList { get { return m_uniformList; } set { m_uniformList = value; } }
|
|
public List<PropertyDataCollector> InstancedPropertiesList { get { return m_instancedPropertiesList; } set { m_instancedPropertiesList = value; } }
|
|
|
|
public Dictionary<string, string> LocalFunctions { get { return m_localFunctions; } set { m_localFunctions = value; } }
|
|
public bool DirtyInput { get { return m_dirtyInput; } set { m_dirtyInput = value; } }
|
|
|
|
//public OutlineMode CustomMode { get { return m_customMode; } set { m_customMode = value; } }
|
|
public int OffsetMode { get { return m_offsetMode; } set { m_offsetMode = value; } }
|
|
public bool CustomNoFog { get { return m_customNoFog; } set { m_customNoFog = value; } }
|
|
}
|
|
}
|