1378 lines
57 KiB
C#
Raw Normal View History

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
// Amplify Shader Editor - Visual Shader Editing Tool
// Copyright (c) Amplify Creations, Lda <info@amplify.pt>
namespace AmplifyShaderEditor
{
public static class GeneratorUtils
{
public const string VertexBlendWeightsStr = "ase_blendWeights";
public const string VertexBlendIndicesStr = "ase_blendIndices";
public const string ObjectScaleStr = "ase_objectScale";
public const string ParentObjectScaleStr = "ase_parentObjectScale";
public const string ScreenDepthStr = "ase_screenDepth";
public const string ViewPositionStr = "ase_viewPos";
public const string WorldViewDirectionStr = "ase_worldViewDir";
public const string TangentViewDirectionStr = "ase_tanViewDir";
public const string NormalizedViewDirStr = "ase_normViewDir";
public const string ClipPositionStr = "ase_clipPos";
public const string VertexPosition3Str = "ase_vertex3Pos";
public const string VertexPosition4Str = "ase_vertex4Pos";
public const string VertexNormalStr = "ase_vertexNormal";
public const string VertexTangentStr = "ase_vertexTangent";
public const string VertexTangentSignStr = "ase_vertexTangentSign";
public const string VertexBitangentStr = "ase_vertexBitangent";
public const string ScreenPositionStr = "ase_screenPos";
public const string NormalizedScreenPosFormat = "{0} / {0}.w";
public const string ScreenPositionNormalizedStr = "ase_screenPosNorm";
public const string GrabScreenPositionStr = "ase_grabScreenPos";
public const string GrabScreenPositionNormalizedStr = "ase_grabScreenPosNorm";
public const string WorldPositionStr = "ase_worldPos";
public const string RelativeWorldPositionStr = "ase_relWorldPos";
public const string VFaceStr = "ase_vface";
public const string ShadowCoordsStr = "ase_shadowCoords";
public const string WorldLightDirStr = "ase_worldlightDir";
public const string ObjectLightDirStr = "ase_objectlightDir";
public const string WorldNormalStr = "ase_worldNormal";
public const string NormalizedWorldNormalStr = "ase_normWorldNormal";
public const string WorldReflectionStr = "ase_worldReflection";
public const string WorldTangentStr = "ase_worldTangent";
public const string WorldBitangentStr = "ase_worldBitangent";
public const string WorldToTangentStr = "ase_worldToTangent";
public const string ObjectToTangentStr = "ase_objectToTangent";
public const string TangentToWorldPreciseStr = "ase_tangentToWorldPrecise";
public const string TangentToWorldFastStr = "ase_tangentToWorldFast";
public const string TangentToObjectStr = "ase_tangentToObject";
public const string TangentToObjectFastStr = "ase_tangentToObjectFast";
private const string Float3Format = "float3 {0} = {1};";
private const string Float4Format = "float4 {0} = {1};";
private const string GrabFunctionHeader = "inline float4 ASE_ComputeGrabScreenPos( float4 pos )";
private const string GrabFunctionCall = "ASE_ComputeGrabScreenPos( {0} )";
private const string Identity4x4 = "ase_identity4x4";
private static readonly string[] GrabFunctionBody = {
"#if UNITY_UV_STARTS_AT_TOP",
"float scale = -1.0;",
"#else",
"float scale = 1.0;",
"#endif",
"float4 o = pos;",
"o.y = pos.w * 0.5f;",
"o.y = ( pos.y - o.y ) * _ProjectionParams.x * scale + o.y;",
"return o;"
};
// MATRIX IDENTITY
static public string GenerateIdentity4x4( ref MasterNodeDataCollector dataCollector, int uniqueId )
{
dataCollector.AddLocalVariable( uniqueId, "float4x4 ase_identity4x4 = float4x4(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1);" );
return Identity4x4;
}
// OBJECT SCALE
static public string GenerateObjectScale( ref MasterNodeDataCollector dataCollector, int uniqueId )
{
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GenerateObjectScale( ref dataCollector, uniqueId );
//string value= "1/float3( length( unity_WorldToObject[ 0 ].xyz ), length( unity_WorldToObject[ 1 ].xyz ), length( unity_WorldToObject[ 2 ].xyz ) );";
string value = "float3( length( unity_ObjectToWorld[ 0 ].xyz ), length( unity_ObjectToWorld[ 1 ].xyz ), length( unity_ObjectToWorld[ 2 ].xyz ) )";
dataCollector.AddLocalVariable( uniqueId, PrecisionType.Float, WirePortDataType.FLOAT3, ObjectScaleStr, value );
return ObjectScaleStr;
}
static public string GenerateRotationIndependentObjectScale( ref MasterNodeDataCollector dataCollector, int uniqueId )
{
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GenerateRotationIndependentObjectScale( ref dataCollector, uniqueId );
string value = "(1.0/float3( length( unity_WorldToObject[ 0 ].xyz ), length( unity_WorldToObject[ 1 ].xyz ), length( unity_WorldToObject[ 2 ].xyz ) ))";
dataCollector.AddLocalVariable( uniqueId, PrecisionType.Float, WirePortDataType.FLOAT3, ParentObjectScaleStr, value );
return ParentObjectScaleStr;
}
// WORLD POSITION
static public string GenerateWorldPosition( ref MasterNodeDataCollector dataCollector, int uniqueId )
{
PrecisionType precision = PrecisionType.Float;
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GetWorldPos();
dataCollector.AddToInput( -1, SurfaceInputs.WORLD_POS, precision );
string result = Constants.InputVarStr + ".worldPos";
if( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation )
result = "mul( unity_ObjectToWorld, " + Constants.VertexShaderInputStr + ".vertex )";
//dataCollector.AddToLocalVariables( dataCollector.PortCategory, uniqueId, string.Format( Float3Format, WorldPositionStr, result ) );
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3, WorldPositionStr, result );
return WorldPositionStr;
}
// WORLD REFLECTION
static public string GenerateWorldReflection( ref MasterNodeDataCollector dataCollector, int uniqueId, bool normalize = false )
{
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GetWorldReflection( UIUtils.CurrentWindow.CurrentGraph.CurrentPrecision, true, MasterNodePortCategory.Fragment, normalize );
string precisionType = UIUtils.PrecisionWirePortToCgType( UIUtils.CurrentWindow.CurrentGraph.CurrentPrecision, WirePortDataType.FLOAT3 );
string result = string.Empty;
if( !dataCollector.DirtyNormal )
result = Constants.InputVarStr + ".worldRefl";
else
result = "WorldReflectionVector( " + Constants.InputVarStr + ", " + precisionType + "( 0, 0, 1 ) )";
if( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation )
result = "UnityObjectToWorldNormal( " + Constants.VertexShaderInputStr + ".normal )";
if( normalize )
{
result = string.Format( "normalize( {0} )", result );
}
dataCollector.AddToLocalVariables( dataCollector.PortCategory, uniqueId, string.Concat( precisionType, " ", WorldReflectionStr, " = ", result, ";" ) );
return WorldReflectionStr;
}
// WORLD NORMAL
static public string GenerateWorldNormal( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precisionType, string normal, string outputId )
{
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GetWorldNormal( uniqueId, precisionType, normal, outputId );
string tanToWorld = GenerateTangentToWorldMatrixFast( ref dataCollector, uniqueId, precisionType );
return string.Format( "mul({0},{1})", tanToWorld, normal );
}
static public string GenerateWorldNormal( ref MasterNodeDataCollector dataCollector, int uniqueId, bool normalize = false )
{
PrecisionType precision = UIUtils.CurrentWindow.CurrentGraph.CurrentPrecision;
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GetWorldNormal( precision, true, MasterNodePortCategory.Fragment, normalize );
string precisionType = UIUtils.PrecisionWirePortToCgType( precision, WirePortDataType.FLOAT3 );
string result = string.Empty;
if( !dataCollector.DirtyNormal )
result = Constants.InputVarStr + ".worldNormal";
else
result = "WorldNormalVector( " + Constants.InputVarStr + ", " + precisionType + "( 0, 0, 1 ) )";
if( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation )
result = "UnityObjectToWorldNormal( " + Constants.VertexShaderInputStr + ".normal )";
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3, WorldNormalStr, result );
if( normalize )
{
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3, NormalizedWorldNormalStr, "normalize( " + WorldNormalStr + " )" );
return NormalizedWorldNormalStr;
}
return WorldNormalStr;
}
// WORLD TANGENT
static public string GenerateWorldTangent( ref MasterNodeDataCollector dataCollector, int uniqueId )
{
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GetWorldTangent( UIUtils.CurrentWindow.CurrentGraph.CurrentPrecision );
string precisionType = UIUtils.PrecisionWirePortToCgType( UIUtils.CurrentWindow.CurrentGraph.CurrentPrecision, WirePortDataType.FLOAT3 );
string result = "WorldNormalVector( " + Constants.InputVarStr + ", " + precisionType + "( 1, 0, 0 ) )";
if( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation )
result = "UnityObjectToWorldDir( " + Constants.VertexShaderInputStr + ".tangent.xyz )";
dataCollector.AddLocalVariable( uniqueId, UIUtils.CurrentWindow.CurrentGraph.CurrentPrecision, WirePortDataType.FLOAT3, WorldTangentStr, result );
//dataCollector.AddToLocalVariables( dataCollector.PortCategory, uniqueId, string.Concat( precisionType, " ", WorldTangentStr, " = ", result, ";" ) );
return WorldTangentStr;
}
// WORLD BITANGENT
static public string GenerateWorldBitangent( ref MasterNodeDataCollector dataCollector, int uniqueId )
{
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GetWorldBinormal( UIUtils.CurrentWindow.CurrentGraph.CurrentPrecision );
string precisionType = UIUtils.PrecisionWirePortToCgType( UIUtils.CurrentWindow.CurrentGraph.CurrentPrecision, WirePortDataType.FLOAT3 );
string result = "WorldNormalVector( " + Constants.InputVarStr + ", " + precisionType + "( 0, 1, 0 ) )";
if( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation )
{
string worldNormal = GenerateWorldNormal( ref dataCollector, uniqueId );
string worldTangent = GenerateWorldTangent( ref dataCollector, uniqueId );
dataCollector.AddToVertexLocalVariables( uniqueId, string.Format( "half tangentSign = {0}.tangent.w * unity_WorldTransformParams.w;", Constants.VertexShaderInputStr ) );
result = "cross( " + worldNormal + ", " + worldTangent + " ) * tangentSign";
}
dataCollector.AddToLocalVariables( dataCollector.PortCategory, uniqueId, string.Concat( precisionType, " ", WorldBitangentStr, " = ", result, ";" ) );
return WorldBitangentStr;
}
// OBJECT TO TANGENT MATRIX
static public string GenerateObjectToTangentMatrix( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision )
{
string normal = GenerateVertexNormal( ref dataCollector, uniqueId, precision );
string tangent = GenerateVertexTangent( ref dataCollector, uniqueId, precision, WirePortDataType.FLOAT3 );
string bitangen = GenerateVertexBitangent( ref dataCollector, uniqueId, precision );
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3x3, ObjectToTangentStr, "float3x3( " + tangent + ", " + bitangen + ", " + normal + " )" );
return ObjectToTangentStr;
}
// TANGENT TO OBJECT
//static public string GenerateTangentToObjectMatrixFast( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision )
//{
// string normal = GenerateVertexNormal( ref dataCollector, uniqueId, precision );
// string tangent = GenerateVertexTangent( ref dataCollector, uniqueId, precision );
// string bitangent = GenerateVertexBitangent( ref dataCollector, uniqueId, precision );
// string result = string.Format( "float3x3({0}.x,{1}.x,{2}.x,{0}.y,{1}.y,{2}.y,{0}.z,{1}.z,{2}.z)",tangent,bitangent,normal );
// dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3x3, TangentToObjectFastStr, result );
// return TangentToObjectFastStr;
//}
//static public string GenerateTangentToObjectMatrixPrecise( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision )
//{
// string objectToTangent = GenerateObjectToTangentMatrix( ref dataCollector, uniqueId, precision );
// Add3x3InverseFunction( ref dataCollector, UIUtils.PrecisionWirePortToCgType( precision, WirePortDataType.FLOAT ) );
// dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3x3, TangentToObjectStr, string.Format( Inverse3x3Header, objectToTangent ) );
// return TangentToObjectStr;
//}
// WORLD TO TANGENT MATRIX
static public string GenerateWorldToTangentMatrix( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision )
{
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GetWorldToTangentMatrix( precision );
if( dataCollector.IsFragmentCategory )
{
dataCollector.ForceNormal = true;
dataCollector.AddToInput( -1, SurfaceInputs.WORLD_NORMAL, precision );
dataCollector.AddToInput( -1, SurfaceInputs.INTERNALDATA, addSemiColon: false );
}
string worldNormal = GenerateWorldNormal( ref dataCollector, uniqueId );
string worldTangent = GenerateWorldTangent( ref dataCollector, uniqueId );
string worldBitangent = GenerateWorldBitangent( ref dataCollector, uniqueId );
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3x3, WorldToTangentStr, "float3x3( " + worldTangent + ", " + worldBitangent + ", " + worldNormal + " )" );
return WorldToTangentStr;
}
// TANGENT TO WORLD
static public string GenerateTangentToWorldMatrixFast( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision )
{
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GetTangentToWorldMatrixFast( precision );
if( dataCollector.IsFragmentCategory )
{
dataCollector.ForceNormal = true;
dataCollector.AddToInput( -1, SurfaceInputs.WORLD_NORMAL, precision );
dataCollector.AddToInput( -1, SurfaceInputs.INTERNALDATA, addSemiColon: false );
}
string worldNormal = GenerateWorldNormal( ref dataCollector, uniqueId );
string worldTangent = GenerateWorldTangent( ref dataCollector, uniqueId );
string worldBitangent = GenerateWorldBitangent( ref dataCollector, uniqueId );
string result = string.Format( "float3x3({0}.x,{1}.x,{2}.x,{0}.y,{1}.y,{2}.y,{0}.z,{1}.z,{2}.z)", worldTangent, worldBitangent, worldNormal );
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3x3, TangentToWorldFastStr, result );
return TangentToWorldFastStr;
}
static public string GenerateTangentToWorldMatrixPrecise( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision )
{
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GetTangentToWorldMatrixPrecise( precision );
if( dataCollector.IsFragmentCategory )
{
dataCollector.ForceNormal = true;
dataCollector.AddToInput( -1, SurfaceInputs.WORLD_NORMAL, precision );
dataCollector.AddToInput( -1, SurfaceInputs.INTERNALDATA, addSemiColon: false );
}
string worldToTangent = GenerateWorldToTangentMatrix( ref dataCollector, uniqueId, precision );
Add3x3InverseFunction( ref dataCollector, UIUtils.PrecisionWirePortToCgType( precision, WirePortDataType.FLOAT ) );
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3x3, TangentToWorldPreciseStr, string.Format( Inverse3x3Header, worldToTangent ) );
return TangentToWorldPreciseStr;
}
// SAMPLER STATES
static public string GenerateSamplerState( ref MasterNodeDataCollector dataCollector, int uniqueId, string propertyName, VariableMode varMode, bool returnPropertyName = false )
{
string sampler = string.Format( Constants.SamplerFormat, propertyName );
string samplerDecl = string.Empty;
ParentGraph outsideGraph = UIUtils.CurrentWindow.OutsideGraph;
#if !UNITY_2018_1_OR_NEWER
if( outsideGraph.IsStandardSurface )
return string.Empty;
#endif
if( outsideGraph.IsSRP )
//if( dataCollector.IsSRP )
samplerDecl = string.Format( Constants.SamplerDeclSRPFormat, sampler ) + ";";
else
samplerDecl = string.Format( Constants.SamplerDeclFormat, sampler ) + ";";
if( varMode == VariableMode.Create )
dataCollector.AddToUniforms( uniqueId, samplerDecl );
if( returnPropertyName )
return propertyName;
else
return sampler;
}
public static string GetPropertyFromSamplerState( string sampler )
{
if( sampler.StartsWith( "sampler" ) )
return sampler.Remove( 0, 7 );
else
return sampler;
}
public static string GetSamplerDeclaraction( string texture, WirePortDataType type, string termination = "" )
{
return GetSamplerDeclaraction( texture, Constants.WireToTexture[ type ], termination );
}
public static string GetSamplerDeclaraction( string sampler, TextureType type, string termination = "" )
{
ParentGraph outsideGraph = UIUtils.CurrentWindow.OutsideGraph;
#if UNITY_2018_1_OR_NEWER
if( outsideGraph.SamplingMacros || type == TextureType.Texture2DArray )
#else
if( ( outsideGraph.SamplingMacros || type == TextureType.Texture2DArray ) && !outsideGraph.IsStandardSurface /*) || type == TextureType.Texture2DArray*/ )
#endif
{
if( outsideGraph.IsSRP )
return string.Format( Constants.SamplerDeclSRPFormat, sampler ) + termination;
else
return string.Format( Constants.SamplerDeclFormat, sampler ) + termination;
}
// we don't use sampler states when macros are not available
return string.Empty;
}
// PROPERTY MACRO
public static string GetPropertyDeclaraction( string texture, WirePortDataType type, string termination = "" )
{
return GetPropertyDeclaraction( texture, Constants.WireToTexture[ type ], termination );
}
public static string GetPropertyDeclaraction( string texture, TextureType type, string termination = "" )
{
if( type == TextureType.Texture1D )
return "sampler1D " + texture + termination;
ParentGraph outsideGraph = UIUtils.CurrentWindow.OutsideGraph;
#if UNITY_2018_1_OR_NEWER
if( outsideGraph.SamplingMacros || type == TextureType.Texture2DArray )
#else
if( ( outsideGraph.SamplingMacros || type == TextureType.Texture2DArray ) && !outsideGraph.IsStandardSurface )
#endif
{
if( outsideGraph.IsSRP )
return string.Format( Constants.TexDeclarationNoSamplerSRPMacros[ type ], texture ) + termination;
else
return string.Format( Constants.TexDeclarationNoSamplerStandardMacros[ type ], texture ) + termination;
}
return UIUtils.TextureTypeToCgType( type )+ " " + texture + termination;
}
// SAMPLING CALL
public static string GenerateSamplingCall( ref MasterNodeDataCollector dataCollector, WirePortDataType type, string property, string samplerState, string uv, MipType mip = MipType.Auto, params string[] mipData )
{
ParentGraph ousideGraph = UIUtils.CurrentWindow.OutsideGraph;
string result = string.Empty;
string mipSuffix = string.Empty;
//samplerState = GetPropertyFromSamplerState( samplerState );
TextureType textureType = Constants.WireToTexture[ type ];
bool usingMacro = false;
#if UNITY_2018_1_OR_NEWER
if( ousideGraph.SamplingMacros || textureType == TextureType.Texture2DArray )
#else
if( ( ousideGraph.SamplingMacros && !ousideGraph.IsStandardSurface ) || textureType == TextureType.Texture2DArray )
#endif
usingMacro = true;
switch( mip )
{
default:
case MipType.Auto:
break;
case MipType.MipLevel:
mipSuffix = usingMacro ? "_LOD" : "lod";
break;
case MipType.MipBias:
mipSuffix = usingMacro ? "_BIAS" : "bias";
break;
case MipType.Derivative:
mipSuffix = usingMacro ? "_GRAD" : "grad";
break;
}
string mipParams = string.Empty;
if( mip != MipType.Auto )
{
for( int i = 0; i < mipData.Length; i++ )
{
mipParams += ", " + mipData[ i ];
}
}
if( usingMacro )
{
if( ousideGraph.IsSRP )
{
if( textureType == TextureType.Texture3D && ( mip == MipType.MipBias || mip == MipType.Derivative ) )
AddCustom3DSRPMacros( ref dataCollector );
// srp macro
result = string.Format( Constants.TexSampleSRPMacros[ textureType ], mipSuffix, property, samplerState, uv + mipParams );
}
else
{
AddCustomStandardSamplingMacros( ref dataCollector, type, mip );
#if !UNITY_2018_1_OR_NEWER
if( ousideGraph.IsStandardSurface )
result = string.Format( Constants.TexSampleStandardMacros[ textureType ], mipSuffix, property, samplerState, uv + mipParams );
else
#endif
result = string.Format( Constants.TexSampleSamplerStandardMacros[ textureType ], mipSuffix, property, samplerState, uv + mipParams );
}
}
else
{
//no macro : builtin and srp
string uvs = uv + mipParams;
string emptyParam = ", 0";
if( textureType == TextureType.Texture3D || textureType == TextureType.Cube )
emptyParam = string.Empty;
if( ( mip == MipType.MipBias || mip == MipType.MipLevel ) )
uvs = "float4(" + uv + emptyParam + mipParams + ")";
result = string.Format( Constants.TexSampleStandard[ textureType ], mipSuffix, property, uvs );
}
return result;
}
// AUTOMATIC UVS
static public string GenerateAutoUVs( ref MasterNodeDataCollector dataCollector, int uniqueId, int index, string propertyName = null, WirePortDataType size = WirePortDataType.FLOAT2, string scale = null, string offset = null, string outputId = null )
{
string result = string.Empty;
string varName = string.Empty;
string indexStr = index > 0 ? ( index + 1 ).ToString() : "";
string sizeDif = string.Empty;
if( size == WirePortDataType.FLOAT3 )
sizeDif = "3";
else if( size == WirePortDataType.FLOAT4 )
sizeDif = "4";
if( !dataCollector.IsTemplate && index > 3 )
{
string texCoordNameIn = TemplateHelperFunctions.BaseInterpolatorName + index;
string texCoordNameOut = TemplateHelperFunctions.BaseInterpolatorName + ( index + 1 ).ToString();
if( dataCollector.IsFragmentCategory )
{
GenerateValueInVertex( ref dataCollector, uniqueId, size, PrecisionType.Float, Constants.VertexShaderInputStr + "." + texCoordNameIn, texCoordNameOut, true );
result = Constants.InputVarStr + "." + texCoordNameOut;
}
else
{
result = Constants.VertexShaderInputStr + "." + texCoordNameIn;
}
if( !string.IsNullOrEmpty( propertyName ) )
{
varName = "uv" + indexStr + ( size != WirePortDataType.FLOAT2 ? "s" + sizeDif : "" ) + propertyName;
dataCollector.AddToUniforms( uniqueId, "uniform float4 " + propertyName + "_ST;" );
if( size > WirePortDataType.FLOAT2 )
{
dataCollector.UsingHigherSizeTexcoords = true;
dataCollector.AddToLocalVariables( dataCollector.PortCategory, uniqueId, PrecisionType.Float, size, varName, result );
dataCollector.AddToLocalVariables( dataCollector.PortCategory, uniqueId, varName + ".xy = " + result + ".xy * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw;" );
}
else
{
dataCollector.AddToLocalVariables( dataCollector.PortCategory, uniqueId, PrecisionType.Float, size, varName, result + " * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw" );
}
result = varName;
}
switch( size )
{
default:
case WirePortDataType.FLOAT2:
{
result += ".xy";
}
break;
case WirePortDataType.FLOAT3:
{
result += ".xyz";
}
break;
case WirePortDataType.FLOAT4: break;
}
return result;
}
if( dataCollector.PortCategory == MasterNodePortCategory.Fragment || dataCollector.PortCategory == MasterNodePortCategory.Debug )
{
string dummyPropUV = "_tex" + sizeDif + "coord" + indexStr;
string dummyUV = "uv" + indexStr + dummyPropUV;
dataCollector.AddToProperties( uniqueId, "[HideInInspector] " + dummyPropUV + "( \"\", 2D ) = \"white\" {}", 100 );
dataCollector.AddToInput( uniqueId, dummyUV, size );
result = Constants.InputVarStr + "." + dummyUV;
}
else
{
result = Constants.VertexShaderInputStr + ".texcoord";
if( index > 0 )
{
result += index.ToString();
}
switch( size )
{
default:
case WirePortDataType.FLOAT2:
{
result += ".xy";
}
break;
case WirePortDataType.FLOAT3:
{
result += ".xyz";
}
break;
case WirePortDataType.FLOAT4: break;
}
}
varName = "uv" + indexStr + ( size != WirePortDataType.FLOAT2 ? "s" + sizeDif : "" ) + "_TexCoord" + outputId;
if( !string.IsNullOrEmpty( propertyName ) )
{
string finalVarName = "uv" + indexStr + ( size != WirePortDataType.FLOAT2 ? "s" + sizeDif : "" ) + propertyName;
dataCollector.AddToUniforms( uniqueId, "uniform float4 " + propertyName + "_ST;" );
if( size > WirePortDataType.FLOAT2 )
{
dataCollector.UsingHigherSizeTexcoords = true;
dataCollector.AddToLocalVariables( dataCollector.PortCategory, uniqueId, PrecisionType.Float, size, finalVarName, result );
dataCollector.AddToLocalVariables( dataCollector.PortCategory, uniqueId, finalVarName + ".xy = " + result + ".xy * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw;" );
}
else
{
dataCollector.AddToLocalVariables( dataCollector.PortCategory, uniqueId, PrecisionType.Float, size, finalVarName, result + " * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw" );
}
result = finalVarName;
}
else if( !string.IsNullOrEmpty( scale ) || !string.IsNullOrEmpty( offset ) )
{
if( size > WirePortDataType.FLOAT2 )
{
dataCollector.UsingHigherSizeTexcoords = true;
dataCollector.AddToLocalVariables( dataCollector.PortCategory, uniqueId, PrecisionType.Float, size, varName, result );
dataCollector.AddToLocalVariables( dataCollector.PortCategory, uniqueId, varName + ".xy = " + result + ".xy" + ( string.IsNullOrEmpty( scale ) ? "" : " * " + scale ) + ( string.IsNullOrEmpty( offset ) ? "" : " + " + offset ) + ";" );
}
else
{
dataCollector.AddToLocalVariables( dataCollector.PortCategory, uniqueId, PrecisionType.Float, size, varName, result + ( string.IsNullOrEmpty( scale ) ? "" : " * " + scale ) + ( string.IsNullOrEmpty( offset ) ? "" : " + " + offset ) );
}
result = varName;
}
else if( dataCollector.PortCategory == MasterNodePortCategory.Fragment )
{
if( size > WirePortDataType.FLOAT2 )
dataCollector.UsingHigherSizeTexcoords = true;
}
return result;
}
// SCREEN POSITION NORMALIZED
static public string GenerateScreenPositionNormalizedForValue( string customVertexPos, string outputId, ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision, bool addInput = true )
{
string stringPosVar = GenerateScreenPositionForValue( customVertexPos, outputId, ref dataCollector, uniqueId, precision, addInput );
string varName = ScreenPositionNormalizedStr + uniqueId;
// TODO: check later if precision can be half
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT4, varName, string.Format( NormalizedScreenPosFormat, stringPosVar ) );
dataCollector.AddLocalVariable( uniqueId, varName + ".z = ( UNITY_NEAR_CLIP_VALUE >= 0 ) ? " + varName + ".z : " + varName + ".z * 0.5 + 0.5;" );
return varName;
}
static public string GenerateScreenPositionNormalized( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision, bool addInput = true, string customScreenPos = null )
{
string stringPosVar = string.IsNullOrEmpty( customScreenPos ) ? GenerateScreenPosition( ref dataCollector, uniqueId, precision, addInput ) : customScreenPos;
// TODO: check later if precision can be half
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT4, ScreenPositionNormalizedStr, string.Format( NormalizedScreenPosFormat, stringPosVar ) );
dataCollector.AddLocalVariable( uniqueId, ScreenPositionNormalizedStr + ".z = ( UNITY_NEAR_CLIP_VALUE >= 0 ) ? " + ScreenPositionNormalizedStr + ".z : " + ScreenPositionNormalizedStr + ".z * 0.5 + 0.5;" );
return ScreenPositionNormalizedStr;
}
// SCREEN POSITION
static public string GenerateScreenPositionForValue( string customVertexPosition, string outputId, ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision, bool addInput = true )
{
// overriding precision
precision = PrecisionType.Float;
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GetScreenPosForValue( precision, customVertexPosition, outputId );
string value = GenerateVertexScreenPositionForValue( customVertexPosition, outputId, ref dataCollector, uniqueId, precision );
if( !dataCollector.IsFragmentCategory )
{
return value;
}
string screenPosVarName = "screenPosition" + outputId;
dataCollector.AddToInput( uniqueId, screenPosVarName, WirePortDataType.FLOAT4, precision );
dataCollector.AddToVertexLocalVariables( uniqueId, Constants.VertexShaderOutputStr + "." + screenPosVarName + " = " + value + ";" );
string screenPosVarNameOnFrag = ScreenPositionStr + outputId;
string globalResult = Constants.InputVarStr + "." + screenPosVarName;
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT4, screenPosVarNameOnFrag, globalResult );
return screenPosVarNameOnFrag;
}
static public string GenerateScreenPosition( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision, bool addInput = true )
{
// overriding precision
precision = PrecisionType.Float;
if( dataCollector.UsingCustomScreenPos && dataCollector.IsFragmentCategory )
{
string value = GenerateVertexScreenPosition( ref dataCollector, uniqueId, precision );
dataCollector.AddToInput( uniqueId, "screenPosition", WirePortDataType.FLOAT4, precision );
dataCollector.AddToVertexLocalVariables( uniqueId, Constants.VertexShaderOutputStr + ".screenPosition = " + value + ";" );
string globalResult = Constants.InputVarStr + ".screenPosition";
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT4, ScreenPositionStr, globalResult );
return ScreenPositionStr;
}
else
{
if( !dataCollector.IsFragmentCategory )
return GenerateVertexScreenPosition( ref dataCollector, uniqueId, precision );
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GetScreenPos( precision );
}
if( addInput )
dataCollector.AddToInput( uniqueId, SurfaceInputs.SCREEN_POS, precision );
string result = Constants.InputVarStr + ".screenPos";
dataCollector.AddLocalVariable( uniqueId, string.Format( "float4 {0} = float4( {1}.xyz , {1}.w + 0.00000000001 );", ScreenPositionStr, result ) );
return ScreenPositionStr;
}
// GRAB SCREEN POSITION
static public string GenerateGrabScreenPosition( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision, bool addInput = true, string customScreenPos = null )
{
// overriding precision
precision = PrecisionType.Float;
string screenPos = string.Empty;
if( string.IsNullOrEmpty( customScreenPos ) )
screenPos = GenerateScreenPosition( ref dataCollector, uniqueId, precision, addInput );
else
screenPos = customScreenPos;
string computeBody = string.Empty;
IOUtils.AddFunctionHeader( ref computeBody, GrabFunctionHeader );
foreach( string line in GrabFunctionBody )
IOUtils.AddFunctionLine( ref computeBody, line );
IOUtils.CloseFunctionBody( ref computeBody );
string functionResult = dataCollector.AddFunctions( GrabFunctionCall, computeBody, screenPos );
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT4, GrabScreenPositionStr, functionResult );
return GrabScreenPositionStr;
}
// GRAB SCREEN POSITION NORMALIZED
static public string GenerateGrabScreenPositionNormalized( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision, bool addInput = true, string customScreenPos = null )
{
string stringPosVar = GenerateGrabScreenPosition( ref dataCollector, uniqueId, precision, addInput, customScreenPos );
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT4, GrabScreenPositionNormalizedStr, string.Format( NormalizedScreenPosFormat, stringPosVar ) );
return GrabScreenPositionNormalizedStr;
}
// SCREEN POSITION ON VERT
static public string GenerateVertexScreenPositionForValue( string customVertexPosition, string outputId, ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision )
{
// overriding precision
precision = PrecisionType.Float;
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GetScreenPosForValue( precision, customVertexPosition, outputId );
string screenPosVarName = ScreenPositionStr + outputId;
string value = string.Format( "ComputeScreenPos( UnityObjectToClipPos( {0} ) )", customVertexPosition );
dataCollector.AddToVertexLocalVariables( uniqueId, precision, WirePortDataType.FLOAT4, screenPosVarName, value );
return screenPosVarName;
}
static public string GenerateVertexScreenPosition( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision )
{
// overriding precision
precision = PrecisionType.Float;
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GetScreenPos( precision );
string value = string.Format( "ComputeScreenPos( UnityObjectToClipPos( {0}.vertex ) )", Constants.VertexShaderInputStr );
dataCollector.AddToVertexLocalVariables( uniqueId, precision, WirePortDataType.FLOAT4, ScreenPositionStr, value );
return ScreenPositionStr;
}
// VERTEX POSITION
static public string GenerateVertexPosition( ref MasterNodeDataCollector dataCollector, int uniqueId, WirePortDataType size )
{
// overriding precision
var precision = PrecisionType.Float;
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GetVertexPosition( size, precision );
string value = Constants.VertexShaderInputStr + ".vertex";
if( size == WirePortDataType.FLOAT3 )
value += ".xyz";
if( dataCollector.PortCategory == MasterNodePortCategory.Fragment || dataCollector.PortCategory == MasterNodePortCategory.Debug )
{
dataCollector.AddToInput( uniqueId, SurfaceInputs.WORLD_POS );
dataCollector.AddToIncludes( uniqueId, Constants.UnityShaderVariables );
value = "mul( unity_WorldToObject, float4( " + Constants.InputVarStr + ".worldPos , 1 ) )";
}
string varName = VertexPosition4Str;
if( size == WirePortDataType.FLOAT3 )
varName = VertexPosition3Str;
dataCollector.AddLocalVariable( uniqueId, precision, size, varName, value );
return varName;
}
// VERTEX NORMAL
static public string GenerateVertexNormal( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision )
{
if( dataCollector.MasterNodeCategory == AvailableShaderTypes.Template )
{
return dataCollector.TemplateDataCollectorInstance.GetVertexNormal( UIUtils.CurrentWindow.CurrentGraph.CurrentPrecision );
}
string value = Constants.VertexShaderInputStr + ".normal.xyz";
if( dataCollector.PortCategory == MasterNodePortCategory.Fragment || dataCollector.PortCategory == MasterNodePortCategory.Debug )
{
GenerateWorldNormal( ref dataCollector, uniqueId );
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3, VertexNormalStr, "mul( unity_WorldToObject, float4( " + WorldNormalStr + ", 0 ) )" );
//dataCollector.AddToLocalVariables( uniqueId, precision, WirePortDataType.FLOAT3, VertexNormalStr, "mul( unity_WorldToObject, float4( " + WorldNormalStr + ", 0 ) )" );
}
else
{
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3, VertexNormalStr, value );
}
return VertexNormalStr;
}
// VERTEX TANGENT
static public string GenerateVertexTangent( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision, WirePortDataType size )
{
if( dataCollector.MasterNodeCategory == AvailableShaderTypes.Template )
{
return dataCollector.TemplateDataCollectorInstance.GetVertexTangent( size,UIUtils.CurrentWindow.CurrentGraph.CurrentPrecision );
}
if( dataCollector.PortCategory == MasterNodePortCategory.Fragment || dataCollector.PortCategory == MasterNodePortCategory.Debug )
{
GenerateWorldTangent( ref dataCollector, uniqueId );
dataCollector.AddToLocalVariables( uniqueId, precision, WirePortDataType.FLOAT4, VertexTangentStr, "mul( unity_WorldToObject, float4( " + WorldTangentStr + ", 0 ) )" );
}
else
{
string value = Constants.VertexShaderInputStr + ".tangent";
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT4, VertexTangentStr, value );
}
return ( size == WirePortDataType.FLOAT4 ) ? VertexTangentStr : VertexTangentStr + ".xyz";
}
// VERTEX TANGENT SIGN
static public string GenerateVertexTangentSign( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision )
{
if( dataCollector.MasterNodeCategory == AvailableShaderTypes.Template )
{
return dataCollector.TemplateDataCollectorInstance.GetTangentSign( UIUtils.CurrentWindow.CurrentGraph.CurrentPrecision );
}
string value = Constants.VertexShaderInputStr + ".tangent.w";
if( dataCollector.IsFragmentCategory )
{
dataCollector.AddToInput( uniqueId, VertexTangentSignStr, WirePortDataType.FLOAT, PrecisionType.Half );
dataCollector.AddToVertexLocalVariables( uniqueId, Constants.VertexShaderOutputStr + "." + VertexTangentSignStr + " = " + Constants.VertexShaderInputStr + ".tangent.w;" );
return Constants.InputVarStr + "." + VertexTangentSignStr;
}
else
{
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT, VertexTangentSignStr, value );
}
return VertexTangentSignStr;
}
// VERTEX BITANGENT
static public string GenerateVertexBitangent( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision )
{
if( dataCollector.MasterNodeCategory == AvailableShaderTypes.Template )
{
return dataCollector.TemplateDataCollectorInstance.GetVertexBitangent( UIUtils.CurrentWindow.CurrentGraph.CurrentPrecision );
}
if( dataCollector.PortCategory == MasterNodePortCategory.Fragment || dataCollector.PortCategory == MasterNodePortCategory.Debug )
{
GenerateWorldBitangent( ref dataCollector, uniqueId );
dataCollector.AddToLocalVariables( uniqueId, precision, WirePortDataType.FLOAT3, VertexBitangentStr, "mul( unity_WorldToObject, float4( " + WorldBitangentStr + ", 0 ) )" );
}
else
{
GenerateVertexNormal( ref dataCollector, uniqueId, precision );
GenerateVertexTangent( ref dataCollector, uniqueId, precision, WirePortDataType.FLOAT3 );
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3, VertexBitangentStr, "cross( " + VertexNormalStr + ", " + VertexTangentStr + ") * " + Constants.VertexShaderInputStr + ".tangent.w * unity_WorldTransformParams.w" );
}
return VertexBitangentStr;
}
// VERTEX POSITION ON FRAG
static public string GenerateVertexPositionOnFrag( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision )
{
dataCollector.AddToInput( uniqueId, SurfaceInputs.WORLD_POS );
dataCollector.AddToIncludes( uniqueId, Constants.UnityShaderVariables );
string value = "mul( unity_WorldToObject, float4( " + Constants.InputVarStr + ".worldPos , 1 ) )";
dataCollector.AddToLocalVariables( uniqueId, precision, WirePortDataType.FLOAT4, VertexPosition4Str, value );
return VertexPosition4Str;
}
// CLIP POSITION ON FRAG
static public string GenerateClipPositionOnFrag( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision )
{
if( dataCollector.IsTemplate )
return dataCollector.TemplateDataCollectorInstance.GetClipPos();
string vertexName = GenerateVertexPositionOnFrag( ref dataCollector, uniqueId, precision );
string value = string.Format( "ComputeScreenPos( UnityObjectToClipPos( {0} ) )", vertexName );
dataCollector.AddToLocalVariables( uniqueId, precision, WirePortDataType.FLOAT4, ClipPositionStr, value );
return ClipPositionStr;
}
// VIEW DIRECTION
static public string GenerateViewDirection( ref MasterNodeDataCollector dataCollector, int uniqueId, ViewSpace space = ViewSpace.World )
{
PrecisionType precision = UIUtils.CurrentWindow.CurrentGraph.CurrentPrecision;
if( dataCollector.IsTemplate )
return ( space == ViewSpace.Tangent ) ? dataCollector.TemplateDataCollectorInstance.GetTangentViewDir( precision ) : dataCollector.TemplateDataCollectorInstance.GetViewDir();
string worldPos = GenerateWorldPosition( ref dataCollector, uniqueId );
string safeNormalizeInstruction = string.Empty;
if( dataCollector.SafeNormalizeViewDir )
{
if( dataCollector.IsTemplate && dataCollector.IsSRP )
{
safeNormalizeInstruction = "SafeNormalize";
}
else
{
if( dataCollector.IsTemplate )
dataCollector.AddToIncludes( -1, Constants.UnityBRDFLib );
safeNormalizeInstruction = "Unity_SafeNormalize";
}
}
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3, WorldViewDirectionStr, ( dataCollector.SafeNormalizeViewDir ? safeNormalizeInstruction : "normalize" ) + "( UnityWorldSpaceViewDir( " + worldPos + " ) )" );
if( space == ViewSpace.Tangent )
{
string worldToTangent = GenerateWorldToTangentMatrix( ref dataCollector, uniqueId, precision );
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3, TangentViewDirectionStr, "mul( " + worldToTangent + ", " + WorldViewDirectionStr + " )" );
return TangentViewDirectionStr;
}
else
{
return WorldViewDirectionStr;
}
}
// VIEW POS
static public string GenerateViewPositionOnFrag( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision )
{
// overriding precision
precision = PrecisionType.Float;
if( dataCollector.IsTemplate )
UnityEngine.Debug.LogWarning( "View Pos not implemented on Templates" );
string vertexName = GenerateVertexPositionOnFrag( ref dataCollector, uniqueId, precision );
string value = string.Format( "UnityObjectToViewPos( {0} )", vertexName );
dataCollector.AddToLocalVariables( uniqueId, precision, WirePortDataType.FLOAT3, ViewPositionStr, value );
return ViewPositionStr;
}
// SCREEN DEPTH
static public string GenerateScreenDepthOnFrag( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision )
{
// overriding precision
precision = PrecisionType.Float;
if( dataCollector.IsTemplate )
UnityEngine.Debug.LogWarning( "Screen Depth not implemented on Templates" );
string viewPos = GenerateViewPositionOnFrag( ref dataCollector, uniqueId, precision );
string value = string.Format( "-{0}.z", viewPos );
dataCollector.AddToLocalVariables( uniqueId, precision, WirePortDataType.FLOAT, ScreenDepthStr, value );
return ScreenDepthStr;
}
// LIGHT DIRECTION WORLD
static public string GenerateWorldLightDirection( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision )
{
dataCollector.AddToIncludes( uniqueId, Constants.UnityCgLibFuncs );
string worldPos = GeneratorUtils.GenerateWorldPosition( ref dataCollector, uniqueId );
dataCollector.AddLocalVariable( uniqueId, "#if defined(LIGHTMAP_ON) && UNITY_VERSION < 560 //aseld" );
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3, WorldLightDirStr, "0" );
dataCollector.AddLocalVariable( uniqueId, "#else //aseld" );
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3, WorldLightDirStr, ( dataCollector.SafeNormalizeLightDir ? "Unity_SafeNormalize" : "normalize" ) + "( UnityWorldSpaceLightDir( " + worldPos + " ) )" );
dataCollector.AddLocalVariable( uniqueId, "#endif //aseld" );
return WorldLightDirStr;
}
private static readonly string[] SafeNormalizeBuiltin =
{
"inline float{0} ASESafeNormalize(float{0} inVec)\n",
"{\n",
"\tfloat dp3 = max( 0.001f , dot( inVec , inVec ) );\n",
"\treturn inVec* rsqrt( dp3);\n",
"}\n"
};
private static readonly string[] SafeNormalizeSRP =
{
"real{0} ASESafeNormalize(float{0} inVec)\n",
"{\n",
"\treal dp3 = max(FLT_MIN, dot(inVec, inVec));\n",
"\treturn inVec* rsqrt( dp3);\n",
"}\n",
};
static public string NormalizeValue( ref MasterNodeDataCollector dataCollector , bool safeNormalize , WirePortDataType dataType, string value )
{
string normalizeInstruction = string.Empty;
if( safeNormalize )
{
string[] finalFunction = null;
string[] funcVersion = dataCollector.IsSRP ? SafeNormalizeSRP : SafeNormalizeBuiltin;
finalFunction = new string[ funcVersion.Length ];
switch( dataType )
{
case WirePortDataType.FLOAT:
finalFunction[0] = string.Format( funcVersion[ 0 ] , string.Empty );
break;
case WirePortDataType.FLOAT2:
finalFunction[ 0 ] = string.Format( funcVersion[ 0 ] , "2" );
break;
case WirePortDataType.FLOAT3:
finalFunction[ 0 ] = string.Format( funcVersion[ 0 ] , "3" );
break;
case WirePortDataType.FLOAT4:
case WirePortDataType.COLOR:
finalFunction[ 0 ] = string.Format( funcVersion[ 0 ] , "4" );
break;
default:
case WirePortDataType.FLOAT3x3:
case WirePortDataType.FLOAT4x4:
case WirePortDataType.INT:
case WirePortDataType.OBJECT:
case WirePortDataType.SAMPLER1D:
case WirePortDataType.SAMPLER2D:
case WirePortDataType.SAMPLER3D:
case WirePortDataType.SAMPLERCUBE:
case WirePortDataType.UINT:
case WirePortDataType.UINT4:
case WirePortDataType.SAMPLER2DARRAY:
case WirePortDataType.SAMPLERSTATE:return value;
}
for( int i = 1 ; i < funcVersion.Length ; i++ )
{
finalFunction[ i ] = funcVersion[ i ];
}
dataCollector.AddFunction( finalFunction[ 0 ] , finalFunction , false );
normalizeInstruction = "ASESafeNormalize";
}
else
{
normalizeInstruction = "normalize";
}
return normalizeInstruction = normalizeInstruction + "( " + value + " )";
}
// LIGHT DIRECTION Object
static public string GenerateObjectLightDirection( ref MasterNodeDataCollector dataCollector, int uniqueId, PrecisionType precision, string vertexPos )
{
dataCollector.AddToIncludes( uniqueId, Constants.UnityCgLibFuncs );
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3, ObjectLightDirStr, "normalize( ObjSpaceLightDir( " + vertexPos + " ) )" );
return ObjectLightDirStr;
}
// UNPACK NORMALS
public static string GenerateUnpackNormalStr( ref MasterNodeDataCollector dataCollector, PrecisionType precision, int uniqueId, string outputId, string src, bool applyScale, string scale )
{
string funcName;
if( dataCollector.IsTemplate && dataCollector.IsSRP )
{
#if UNITY_2018_3_OR_NEWER
if( ASEPackageManagerHelper.CurrentHDVersion > ASESRPVersions.ASE_SRP_7_2_1 )
{
if( applyScale )
{
dataCollector.AddLocalVariable( uniqueId, precision, WirePortDataType.FLOAT3, "unpack" + outputId, "UnpackNormalScale( " + src + ", " + scale + " )" );
dataCollector.AddLocalVariable( uniqueId, "unpack" + outputId + ".z = lerp( 1, unpack" + outputId + ".z, saturate(" + scale + ") );" );
funcName = "unpack" + outputId;
}
else
{
funcName = "UnpackNormalScale( " + src + ", " + scale + " )";
}
}
else
#endif
{
if( dataCollector.TemplateDataCollectorInstance.IsHDRP )
funcName = "UnpackNormalmapRGorAG( " + src + ", " + scale + " )";
else
funcName = "UnpackNormalScale( " + src + ", " + scale + " )";
}
}
else
{
funcName = applyScale ? "UnpackScaleNormal( " + src + ", " + scale + " )" : "UnpackNormal( " + src + " )";
}
return funcName;
}
//MATRIX INVERSE
// 3x3
public static string Inverse3x3Header = "Inverse3x3( {0} )";
public static string[] Inverse3x3Function =
{
"{0}3x3 Inverse3x3({0}3x3 input)\n",
"{\n",
"\t{0}3 a = input._11_21_31;\n",
"\t{0}3 b = input._12_22_32;\n",
"\t{0}3 c = input._13_23_33;\n",
"\treturn {0}3x3(cross(b,c), cross(c,a), cross(a,b)) * (1.0 / dot(a,cross(b,c)));\n",
"}\n"
};
public static bool[] Inverse3x3FunctionFlags =
{
true,
false,
true,
true,
true,
true,
false
};
public static void Add3x3InverseFunction( ref MasterNodeDataCollector dataCollector, string precisionString )
{
if( !dataCollector.HasFunction( Inverse3x3Header ) )
{
//Hack to be used util indent is properly used
int currIndent = UIUtils.ShaderIndentLevel;
if( dataCollector.IsTemplate )
{
UIUtils.ShaderIndentLevel = 0;
}
else
{
UIUtils.ShaderIndentLevel = 1;
UIUtils.ShaderIndentLevel++;
}
string finalFunction = string.Empty;
for( int i = 0; i < Inverse3x3Function.Length; i++ )
{
finalFunction += UIUtils.ShaderIndentTabs + ( Inverse3x3FunctionFlags[ i ] ? string.Format( Inverse3x3Function[ i ], precisionString ) : Inverse3x3Function[ i ] );
}
UIUtils.ShaderIndentLevel = currIndent;
dataCollector.AddFunction( Inverse3x3Header, finalFunction );
}
}
public static string GenerateValueInVertex( ref MasterNodeDataCollector dataCollector, int uniqueId, WirePortDataType dataType, PrecisionType currentPrecisionType, string dataValue, string dataName, bool createInterpolator )
{
if( !dataCollector.IsFragmentCategory )
return dataValue;
//TEMPLATES
if( dataCollector.IsTemplate )
{
if( createInterpolator && dataCollector.TemplateDataCollectorInstance.HasCustomInterpolatedData( dataName ) )
return dataName;
MasterNodePortCategory category = dataCollector.PortCategory;
dataCollector.PortCategory = MasterNodePortCategory.Vertex;
dataCollector.PortCategory = category;
if( createInterpolator )
{
dataCollector.TemplateDataCollectorInstance.RegisterCustomInterpolatedData( dataName, dataType, currentPrecisionType, dataValue );
}
else
{
dataCollector.AddToVertexLocalVariables( -1, currentPrecisionType, dataType, dataName, dataValue );
}
return dataName;
}
//SURFACE
{
if( dataCollector.TesselationActive )
{
UIUtils.ShowMessage( "Unable to use Vertex to Frag when Tessellation is active" );
switch( dataType )
{
case WirePortDataType.FLOAT2:
{
return "(0).xx";
}
case WirePortDataType.FLOAT3:
{
return "(0).xxx";
}
case WirePortDataType.FLOAT4:
case WirePortDataType.COLOR:
{
return "(0).xxxx";
}
}
return "0";
}
if( createInterpolator )
dataCollector.AddToInput( uniqueId, dataName, dataType, currentPrecisionType );
MasterNodePortCategory portCategory = dataCollector.PortCategory;
dataCollector.PortCategory = MasterNodePortCategory.Vertex;
if( createInterpolator )
{
dataCollector.AddLocalVariable( uniqueId, Constants.VertexShaderOutputStr + "." + dataName, dataValue + ";" );
}
else
{
dataCollector.AddLocalVariable( uniqueId, currentPrecisionType, dataType, dataName, dataValue );
}
dataCollector.PortCategory = portCategory;
return createInterpolator ? Constants.InputVarStr + "." + dataName : dataName;
}
}
public static void AddCustomStandardSamplingMacros( ref MasterNodeDataCollector dataCollector, TextureType type, MipType mip )
{
AddCustomStandardSamplingMacros( ref dataCollector, Constants.TextureToWire[ type ], mip );
}
public static void AddCustomStandardSamplingMacros( ref MasterNodeDataCollector dataCollector, WirePortDataType type, MipType mip )
{
MacrosMask result = MacrosMask.NONE;
switch( mip )
{
default:
case MipType.Auto:
result |= MacrosMask.AUTO;
break;
case MipType.MipLevel:
result |= MacrosMask.LOD;
break;
case MipType.MipBias:
result |= MacrosMask.BIAS;
break;
case MipType.Derivative:
result |= MacrosMask.GRAD;
break;
}
switch( type )
{
default:
case WirePortDataType.SAMPLER2D:
dataCollector.Using2DMacrosMask |= result;
break;
case WirePortDataType.SAMPLER3D:
dataCollector.Using3DMacrosMask |= result;
break;
case WirePortDataType.SAMPLERCUBE:
dataCollector.UsingCUBEMacrosMask |= result;
break;
case WirePortDataType.SAMPLER2DARRAY:
dataCollector.Using2DArrayMacrosMask |= result;
break;
}
}
public static void AddCustom3DSRPMacros( ref MasterNodeDataCollector dataCollector )
{
// add just once
if( dataCollector.UsingExtra3DSRPMacros )
return;
dataCollector.UsingExtra3DSRPMacros = true;
for( int i = 0; i < Constants.CustomSRPSamplingMacros.Length; i++ )
dataCollector.AddToDirectives( Constants.CustomSRPSamplingMacros[ i ] );
}
public static void AddCustomArraySamplingMacros( ref MasterNodeDataCollector dataCollector )
{
// add just once
if( dataCollector.UsingArrayDerivatives )
return;
dataCollector.UsingArrayDerivatives = true;
for( int i = 0; i < Constants.CustomArraySamplingMacros.Length; i++ )
dataCollector.AddToDirectives( Constants.CustomArraySamplingMacros[ i ] );
}
/*public static void AddCustomASEMacros( ref MasterNodeDataCollector dataCollector )
{
string varPrefix = dataCollector.IsSRP ? varPrefix = "TEXTURE" : "UNITY_DECLARE_TEX";
if( dataCollector.IsSRP )
{
for( int i = 0; i < Constants.CustomASESRPArgsMacros.Length; i++ )
{
dataCollector.AddToDirectives( Constants.CustomASESRPArgsMacros[ i ] );
}
for( int i = 0; i < Constants.CustomSRPSamplingMacros.Length; i++ )
{
dataCollector.AddToDirectives( Constants.CustomSRPSamplingMacros[ i ] );
}
}
else
{
for( int i = 0; i < Constants.CustomASEStandardArgsMacros.Length; i++ )
{
dataCollector.AddToDirectives( Constants.CustomASEStandardArgsMacros[ i ] );
}
for( int i = 0; i < Constants.CustomStandardSamplingMacros.Length; i++ )
{
dataCollector.AddToDirectives( Constants.CustomStandardSamplingMacros[ i ] );
}
}
for( int i = 0; i < Constants.CustomASEDeclararionMacros.Length; i++ )
{
string value = string.Format( Constants.CustomASEDeclararionMacros[ i ], varPrefix );
dataCollector.AddToDirectives( value );
}
string samplePrefix = string.Empty;
string samplerArgs = string.Empty;
string samplerDecl = string.Empty;
if( dataCollector.IsSRP )
{
samplePrefix = "SAMPLE_TEXTURE";
samplerArgs = "samplerName,";
for( int i = 0; i < Constants.CustomASESamplingMacros.Length; i++ )
{
string value = string.Format( Constants.CustomASESamplingMacros[ i ], samplerArgs, samplePrefix, samplerDecl );
dataCollector.AddToDirectives( value );
}
}
else
{
samplePrefix = "UNITY_SAMPLE_TEX";
samplerArgs = "samplerName,";
samplerDecl = "_SAMPLER";
dataCollector.AddToDirectives( Constants.CustomASEStandarSamplingMacrosHelper[ 0 ] );
for( int i = 0; i < Constants.CustomASESamplingMacros.Length; i++ )
{
string value = string.Format( Constants.CustomASESamplingMacros[ i ], samplerArgs, samplePrefix, samplerDecl );
dataCollector.AddToDirectives( value );
}
dataCollector.AddToDirectives( Constants.CustomASEStandarSamplingMacrosHelper[ 1 ] );
samplerArgs = string.Empty;
samplerDecl = string.Empty;
for( int i = 0; i < Constants.CustomASESamplingMacros.Length; i++ )
{
string value = string.Format( Constants.CustomASESamplingMacros[ i ], samplerArgs, samplePrefix, samplerDecl );
dataCollector.AddToDirectives( value );
}
dataCollector.AddToDirectives( Constants.CustomASEStandarSamplingMacrosHelper[ 2 ] );
}
}*/
public static void RegisterUnity2019MatrixDefines( ref MasterNodeDataCollector dataCollector )
{
#if UNITY_2019_1_OR_NEWER
if( dataCollector.IsSRP && dataCollector.TemplateDataCollectorInstance.IsHDRP && ASEPackageManagerHelper.CurrentHDVersion >= ASESRPVersions.ASE_SRP_5_13_0 )
{
//dataCollector.AddToDefines( -1, "unity_CameraProjection UNITY_MATRIX_P" );
//dataCollector.AddToDefines( -1, "unity_CameraInvProjection UNITY_MATRIX_I_P" );
//dataCollector.AddToDefines( -1, "unity_WorldToCamera UNITY_MATRIX_V" );
//dataCollector.AddToDefines( -1, "unity_CameraToWorld UNITY_MATRIX_I_V" );
dataCollector.AddToUniforms( -1, "float4x4 unity_CameraProjection;" );
dataCollector.AddToUniforms( -1, "float4x4 unity_CameraInvProjection;" );
dataCollector.AddToUniforms( -1, "float4x4 unity_WorldToCamera;" );
dataCollector.AddToUniforms( -1, "float4x4 unity_CameraToWorld;" );
}
#endif
}
}
}