Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Amplify vs Shader Forge

Discussion in 'General Discussion' started by boxhallowed, Dec 4, 2016.

  1. boxhallowed

    boxhallowed

    Joined:
    Mar 31, 2015
    Posts:
    513
    I've been wibble wobbling with what I want to spend my Christmas bonus on. I've researched both Shader Forge and Amplify:

    Shader Forge - $95
    https://www.assetstore.unity3d.com/en/#!/content/14147

    Amplify - $25
    https://www.assetstore.unity3d.com/en/#!/content/68570

    Shader Forge looks like the most fully featured shader editor, and it looks impressive. Amplify looks a bit rough, but it has the potential to kill Shader Forge, and it's $70 cheaper.

    Is there any major disadvantage to going with the plugin that's $70 cheaper?
     
    Farelle likes this.
  2. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,264
    Fixed that for you. Full source code available. Shader Forge is closed source. That makes it a winner in my opinion. :D
     
    Alverik likes this.
  3. boxhallowed

    boxhallowed

    Joined:
    Mar 31, 2015
    Posts:
    513
    Well, that pretty well sold me.
     
  4. Martin_H

    Martin_H

    Joined:
    Jul 11, 2015
    Posts:
    4,436
    I have shaderforge (from a sale I think) and do get some value out of it. But I'm gonna be honest, I wouldn't buy it again at full price because it is closed source (something I didn't notice before purchase) and can't do half the stuff I'd want to make with it, like complex multipass shaders (which I also didn't realize beforehand). And although I'd say it is a lot faster to make a shader with it (if you can make the shader in question with it) through trial and error, I kind of feel I'm missing out on learning-opportunities and the satisfaction that I get with manual shader writing. Also I think that shaderforge removes a lot less of the complexity of making your own shaders, than people generally anticipate. You still need to understand the math and operations you are using, there's no way around that imho.

    I haven't bought the amplify editor yet. My question is, is there anything that would really be a reason for me to buy it too and stop using shaderforge? I'm having my doubts that any node-based solution will reach the freedom you get with writing shaders from scratch (or modifying existing ones). But maybe I'm wrong?

    P.S.: also how likely is it that Unity make these tools redundant soon, like they did with ngui or Scion by offering very similar solutions themselves? I don't know about the UI stuff but imho the new post stack is way better than Scion.
     
    Alverik likes this.
  5. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,264
    I just picked up a copy but I haven't done much more than fiddle with the interface and search for opinions and articles. Back when it was announced on Reddit the author didn't seem very eager to compare it with Shader Forge which is understandable because at the time the only real differences were the cost and that it included source.

    https://www.reddit.com/r/Unity3D/comments/52lkyl/new_amplify_shader_editor_nodebased_shader/

    They mentioned that the user interface was one of the advantages but I have to disagree with that as the icons they selected for tasks like saving the shader, viewing the source code, and so on don't make any sense whatsoever. If it wasn't for the tool tips I would have had to experiment or read the source to understand their purpose.

    One other aspect I looked at was the state of the code generated. It produces very minimalistic code compared to SF which generates a few hundred lines for even a very basic shader.

    Thinking back on a statement from the developer that the Shader Forge binary was more akin to a folder used to keep the asset clean I ran a quick decompile of it and discovered that it isn't obfuscated in the slightest.
     
    Last edited: Dec 4, 2016
    Martin_H likes this.
  6. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    As much as I understand where this stance normally comes from, I'm really not sure why anyone would try to fix the asset over writing their own shaders at that point. They must really love the workflow if they are that committed to not learning how to write shaders.
     
  7. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,624
    Because in a team the person modding the tool might not be the person making the shaders. I've often added features for tools so that someone in a different role can do their job more effectively.
     
  8. Martin_H

    Martin_H

    Joined:
    Jul 11, 2015
    Posts:
    4,436
    That's a big minus for amplify, I always prefer text over icons. Shaderforge has some nicely streamlined workflows for adding nodes with hotkeys, although some things about the editor annoy me too.

    Minimalistic in a good or a bad way?
     
  9. Player7

    Player7

    Joined:
    Oct 21, 2015
    Posts:
    1,533
    I give a shout out to ushader... https://www.assetstore.unity3d.com/en/#!/search/page=1/sortby=relevance/query=ushader
    https://forum.unity3d.com/threads/ushader.409038/

    surprisingly alot more features included already,
    feature wise it beats amplify currently and price wise it beats shaderforge... ofc there is more to it than that :)

    I actually only noticed them in the asset store after purchasing amplify shaders myself, good forum presence and website helps alot... and if that means having a good indie price to get forum activity up well then :)... all things considered active development, where its at, cheaper early buy in price to something that may offer much better featureset later on.. yeh I went with amplify and I'm happy with it. I given up waiting on Unity to sort that sht out with a native and more interactive node based shader creating solution. ofc that's my just entitlement showing boohoo :p

    For shaderforge, the price doesn't appeal to me knowing how much I would/wouldn't be utilizing it and the development is not exactly going anywhere.. closed source.. ya nope.

    I don't even want it for doing complex shaders either, its really just to tailor shaders to be less generic with some extra effects on them for things..with an editor that can be quicker to do (amplify is not there yet but active development is encouraging to be involved). And afteral it is getting easy to tell Unreal game from a Unity ones.. that later ones all look the same and tend to have same static material shaders with zero effects.. I can't effng imagine why ofc, other than I don't think many indies enjoy messing with shader syntax language when a default toolset set consisting of a material/shader editor makes it less of a hassle to tailor up new shader materials and effects for them.

    "I'm having my doubts that any node-based solution will reach the freedom you get with writing shaders from scratch (or modifying existing ones). But maybe I'm wrong?"

    I think if you're really get into making your own shaders you would just end up wanting to see and work with the code, but that isn't for me, and not why I went for a node editor for it.. its literately one of the few things I know a node editor makes sense ..Unity should be ashamed, they copy Maya like viewport controls and other aspects for Unity.. and don't even bother to include the hypershade editor for doing shaders with.. terrible :D

    "P.S.: also how likely is it that Unity make these tools redundant soon, like they did with ngui"

    I imagine if I had gotten into using Unity 3years ago instead 1 year and started using ngui, I wouldn't touch ugui, its like half baked solution that falls short of ngui in many aspects from what I looked at into it. Which is disappointing really, 5.5 had literally no new additions or improvements to ugui components. You practically have to fix them yourself to improve them, as they all seem tested for mobile, mousewheel scroll on the scrollbar component.. yeh S*** until u fix it yourself. And find third party enhancements still.. previous 5.x releases have just been fixing bugs for ugui.. not much else. But you end up using it as is its the native solution and so yeah I have less interest to purchase ngui but you can't knock the asset as its still holds some value I guess..

    Unity kinda sit on these things and just mess third party asset developers and end users around by not being clear on what they will be adding in any meaningful timeframe. At this point if they hire some developers to work on a native node shader, I'll just remind myself that whatever solution gets built in.. it will be inferior to an asset store version because it seems to hold true for most things so far.
     
  10. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    But even then, you've still got a case where someone knows exactly what they want, but have to take this roundabout method to get there. Unless it's to add a feature that will be used all over the place (why was this not something shopped for?), it just seems like it's patching the workflow and not the problem.
     
  11. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,264
    Check out this example shader implemented in both assets from the following website. Notice that the Shader Forge node data is a single line whereas Amplify is multiple lines but still far shorter. Keep in mind that I have little to no experience writing shader code so my choice of words might be off and there may be a reason for them being this long that I'm not aware of.

    http://blog.kjinteractive.net/2016/shader-forge-vs-amplify-shader-editor/

    Amplify Shader
    Code (csharp):
    1. Shader "EcoTales/EcoTales_PBR_Test_Amplify"
    2. {
    3.     Properties
    4.     {
    5.         _LerpTex("LerpTex", 2D) = "white" {}
    6.         _MainTex("MainTex", 2D) = "white" {}
    7.         [HideInInspector] __dirty( "", Int ) = 1
    8.         _NormalMap("NormalMap", 2D) = "bump" {}
    9.         _ColorWhite("ColorWhite", Color) = (0,0,0,0)
    10.         _ColorBlack("ColorBlack", Color) = (1,1,1,0)
    11.     }
    12.  
    13.     SubShader
    14.     {
    15.         Tags{ "RenderType" = "Opaque"  "Queue" = "Geometry0" }
    16.         Cull Back
    17.         CGPROGRAM
    18.         #pragma target 3.0
    19.         #pragma surface surf Standard keepalpha addshadow fullforwardshadows
    20.         struct Input
    21.         {
    22.             float2 uv_NormalMap;
    23.             float2 uv_LerpTex;
    24.             float2 uv_MainTex;
    25.         };
    26.  
    27.         uniform sampler2D _NormalMap;
    28.         uniform float4 _ColorWhite;
    29.         uniform float4 _ColorBlack;
    30.         uniform sampler2D _LerpTex;
    31.         uniform sampler2D _MainTex;
    32.  
    33.         void surf( Input input , inout SurfaceOutputStandard output )
    34.         {
    35.             output.Normal = UnpackNormal( tex2D( _NormalMap,input.uv_NormalMap) );
    36.             output.Albedo = ( lerp( _ColorWhite , _ColorBlack , tex2D( _LerpTex,input.uv_LerpTex).r ) * tex2D( _MainTex,input.uv_MainTex) ).xyz;
    37.             float3 _Vector0 = float3(0,0,0);
    38.             output.Metallic = _Vector0.x;
    39.             output.Smoothness = _Vector0.x;
    40.         }
    41.  
    42.         ENDCG
    43.     }
    44.     Fallback "Diffuse"
    45. }
    46. /*ASEBEGIN
    47. Version=10
    48. 0;678;934;350;716.2492;-115.1004;1.6;True;False
    49. Node;AmplifyShaderEditor.LerpOp;8;-57.45016,92.30013;0.0,0,0,0;0.0,0,0,0;0.0
    50. Node;AmplifyShaderEditor.SimpleMultiplyOpNode;10;234.3494,117.0001;0.0,0,0,0;0.0,0,0,0
    51. Node;AmplifyShaderEditor.StandardSurfaceOutputNode;0;559.8005,58.89998;True;Standard;EcoTales/EcoTales_PBR_Test_Amplify;False;False;False;False;False;False;False;False;False;False;False;False;Back;On;LEqual;Opaque;0.5;True;True;0;0,0,0;0,0,0;0,0,0;0.0;0.0;0.0;0.0;0.0;0.0;0.0;0.0;0,0,0
    52. Node;AmplifyShaderEditor.ColorNode;6;-445.9497,-9.900023;Property;_ColorBlack;ColorBlack;1,1,1,0
    53. Node;AmplifyShaderEditor.SamplerNode;7;-444.6508,212.2997;Property;_LerpTex;LerpTex;None;True;0;False;white;Auto;False;0,0;1.0
    54. Node;AmplifyShaderEditor.SamplerNode;9;-302.9506,446.3002;Property;_MainTex;MainTex;None;True;0;False;white;Auto;False;0,0;1.0
    55. Node;AmplifyShaderEditor.SamplerNode;12;-259.7502,676.7004;Property;_NormalMap;NormalMap;None;True;0;True;bump;Auto;True;0,0;1.0
    56. Node;AmplifyShaderEditor.ColorNode;5;-444.649,-189.3003;Property;_ColorWhite;ColorWhite;0,0,0,0
    57. Node;AmplifyShaderEditor.Vector3Node;17;183.3508,304.4001;Constant;_Vector0;Vector 0;0,0,0
    58. WireConnection;8;0;5;0
    59. WireConnection;8;1;6;0
    60. WireConnection;8;2;7;1
    61. WireConnection;10;0;8;0
    62. WireConnection;10;1;9;0
    63. WireConnection;0;0;10;0
    64. WireConnection;0;1;12;0
    65. WireConnection;0;3;17;0
    66. WireConnection;0;4;17;0
    67. ASEEND*/
    68. //CHKSM=9173DEF0D32FC428CFFEA7A13AECBF946DB306D8

    Shader Forge - Forward Shader
    Code (csharp):
    1. // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
    2.  
    3. // Shader created with Shader Forge v1.28
    4. // Shader Forge (c) Neat Corporation / Joachim Holmer - http://www.acegikmo.com/shaderforge/
    5. // Note: Manually altering this data may prevent you from opening it in Shader Forge
    6. /*SF_DATA;ver:1.28;sub:START;pass:START;ps:flbk:,iptp:0,cusa:False,bamd:0,lico:1,lgpr:1,limd:3,spmd:1,trmd:0,grmd:0,uamb:True,mssp:True,bkdf:True,hqlp:False,rprd:True,enco:False,rmgx:True,rpth:0,vtps:0,hqsc:True,nrmq:1,nrsp:0,vomd:0,spxs:False,tesm:0,olmd:1,culm:0,bsrc:0,bdst:1,dpts:2,wrdp:True,dith:0,rfrpo:True,rfrpn:Refraction,coma:15,ufog:True,aust:True,igpj:False,qofs:0,qpre:1,rntp:1,fgom:False,fgoc:False,fgod:False,fgor:False,fgmd:0,fgcr:0.5,fgcg:0.5,fgcb:0.5,fgca:1,fgde:0.01,fgrn:0,fgrf:300,stcl:False,stva:128,stmr:255,stmw:255,stcp:6,stps:0,stfa:0,stfz:0,ofsf:0,ofsu:0,f2p0:False,fnsp:False,fnfb:False;n:type:ShaderForge.SFN_Final,id:2865,x:32719,y:32712,varname:node_2865,prsc:2|diff-6343-OUT,spec-383-OUT,gloss-383-OUT,normal-5964-RGB;n:type:ShaderForge.SFN_Multiply,id:6343,x:32399,y:32683,varname:node_6343,prsc:2|A-8466-OUT,B-7736-RGB;n:type:ShaderForge.SFN_Tex2d,id:7736,x:31710,y:32879,ptovrint:True,ptlb:Base Color,ptin:_MainTex,varname:_MainTex,prsc:2,glob:False,taghide:False,taghdr:False,tagprd:False,tagnsco:False,tagnrm:False,ntxv:0,isnm:False;n:type:ShaderForge.SFN_Tex2d,id:5964,x:32055,y:32936,ptovrint:True,ptlb:Normal Map,ptin:_BumpMap,varname:_BumpMap,prsc:2,glob:False,taghide:False,taghdr:False,tagprd:False,tagnsco:False,tagnrm:False,ntxv:3,isnm:True;n:type:ShaderForge.SFN_Lerp,id:8466,x:31852,y:32462,varname:node_8466,prsc:2|A-1185-RGB,B-626-RGB,T-5966-R;n:type:ShaderForge.SFN_Color,id:1185,x:31592,y:32244,ptovrint:False,ptlb:ColorWhite,ptin:_ColorWhite,varname:node_1185,prsc:2,glob:False,taghide:False,taghdr:False,tagprd:False,tagnsco:False,tagnrm:False,c1:0.5,c2:0.5,c3:0.5,c4:1;n:type:ShaderForge.SFN_Color,id:626,x:31592,y:32420,ptovrint:False,ptlb:ColorBlack,ptin:_ColorBlack,varname:node_626,prsc:2,glob:False,taghide:False,taghdr:False,tagprd:False,tagnsco:False,tagnrm:False,c1:0.5,c2:0.5,c3:0.5,c4:1;n:type:ShaderForge.SFN_Tex2d,id:5966,x:31592,y:32652,ptovrint:False,ptlb:LerpTex,ptin:_LerpTex,varname:node_5966,prsc:2,glob:False,taghide:False,taghdr:False,tagprd:False,tagnsco:False,tagnrm:False,ntxv:0,isnm:False;n:type:ShaderForge.SFN_Vector1,id:383,x:32459,y:32494,varname:node_383,prsc:2,v1:0;proporder:5964-7736-1185-626-5966;pass:END;sub:END;*/
    7.  
    8. Shader "EcoTales/EcoTales_PBR_Test_ShaderForge" {
    9.     Properties {
    10.         _BumpMap ("Normal Map", 2D) = "bump" {}
    11.         _MainTex ("Base Color", 2D) = "white" {}
    12.         _ColorWhite ("ColorWhite", Color) = (0.5,0.5,0.5,1)
    13.         _ColorBlack ("ColorBlack", Color) = (0.5,0.5,0.5,1)
    14.         _LerpTex ("LerpTex", 2D) = "white" {}
    15.     }
    16.     SubShader {
    17.         Tags {
    18.             "RenderType"="Opaque"
    19.         }
    20.         Pass {
    21.             Name "FORWARD"
    22.             Tags {
    23.                 "LightMode"="ForwardBase"
    24.             }
    25.      
    26.      
    27.             CGPROGRAM
    28.             #pragma vertex vert
    29.             #pragma fragment frag
    30.             #define UNITY_PASS_FORWARDBASE
    31.             #define SHOULD_SAMPLE_SH ( defined (LIGHTMAP_OFF) && defined(DYNAMICLIGHTMAP_OFF) )
    32.             #define _GLOSSYENV 1
    33.             #include "UnityCG.cginc"
    34.             #include "AutoLight.cginc"
    35.             #include "Lighting.cginc"
    36.             #include "UnityPBSLighting.cginc"
    37.             #include "UnityStandardBRDF.cginc"
    38.             #pragma multi_compile_fwdbase_fullshadows
    39.             #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
    40.             #pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE
    41.             #pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
    42.             #pragma multi_compile_fog
    43.             #pragma exclude_renderers gles3 metal d3d11_9x xbox360 xboxone ps3 ps4 psp2
    44.             #pragma target 3.0
    45.             uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
    46.             uniform sampler2D _BumpMap; uniform float4 _BumpMap_ST;
    47.             uniform float4 _ColorWhite;
    48.             uniform float4 _ColorBlack;
    49.             uniform sampler2D _LerpTex; uniform float4 _LerpTex_ST;
    50.             struct VertexInput {
    51.                 float4 vertex : POSITION;
    52.                 float3 normal : NORMAL;
    53.                 float4 tangent : TANGENT;
    54.                 float2 texcoord0 : TEXCOORD0;
    55.                 float2 texcoord1 : TEXCOORD1;
    56.                 float2 texcoord2 : TEXCOORD2;
    57.             };
    58.             struct VertexOutput {
    59.                 float4 pos : SV_POSITION;
    60.                 float2 uv0 : TEXCOORD0;
    61.                 float2 uv1 : TEXCOORD1;
    62.                 float2 uv2 : TEXCOORD2;
    63.                 float4 posWorld : TEXCOORD3;
    64.                 float3 normalDir : TEXCOORD4;
    65.                 float3 tangentDir : TEXCOORD5;
    66.                 float3 bitangentDir : TEXCOORD6;
    67.                 LIGHTING_COORDS(7,8)
    68.                 UNITY_FOG_COORDS(9)
    69.                 #if defined(LIGHTMAP_ON) || defined(UNITY_SHOULD_SAMPLE_SH)
    70.                     float4 ambientOrLightmapUV : TEXCOORD10;
    71.                 #endif
    72.             };
    73.             VertexOutput vert (VertexInput v) {
    74.                 VertexOutput o = (VertexOutput)0;
    75.                 o.uv0 = v.texcoord0;
    76.                 o.uv1 = v.texcoord1;
    77.                 o.uv2 = v.texcoord2;
    78.                 #ifdef LIGHTMAP_ON
    79.                     o.ambientOrLightmapUV.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
    80.                     o.ambientOrLightmapUV.zw = 0;
    81.                 #elif UNITY_SHOULD_SAMPLE_SH
    82.                 #endif
    83.                 #ifdef DYNAMICLIGHTMAP_ON
    84.                     o.ambientOrLightmapUV.zw = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
    85.                 #endif
    86.                 o.normalDir = UnityObjectToWorldNormal(v.normal);
    87.                 o.tangentDir = normalize( mul( unity_ObjectToWorld, float4( v.tangent.xyz, 0.0 ) ).xyz );
    88.                 o.bitangentDir = normalize(cross(o.normalDir, o.tangentDir) * v.tangent.w);
    89.                 o.posWorld = mul(unity_ObjectToWorld, v.vertex);
    90.                 float3 lightColor = _LightColor0.rgb;
    91.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex );
    92.                 UNITY_TRANSFER_FOG(o,o.pos);
    93.                 TRANSFER_VERTEX_TO_FRAGMENT(o)
    94.                 return o;
    95.             }
    96.             float4 frag(VertexOutput i) : COLOR {
    97.                 i.normalDir = normalize(i.normalDir);
    98.                 float3x3 tangentTransform = float3x3( i.tangentDir, i.bitangentDir, i.normalDir);
    99.                 float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
    100.                 float3 _BumpMap_var = UnpackNormal(tex2D(_BumpMap,TRANSFORM_TEX(i.uv0, _BumpMap)));
    101.                 float3 normalLocal = _BumpMap_var.rgb;
    102.                 float3 normalDirection = normalize(mul( normalLocal, tangentTransform )); // Perturbed normals
    103.                 float3 viewReflectDirection = reflect( -viewDirection, normalDirection );
    104.                 float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    105.                 float3 lightColor = _LightColor0.rgb;
    106.                 float3 halfDirection = normalize(viewDirection+lightDirection);
    107. ////// Lighting:
    108.                 float attenuation = LIGHT_ATTENUATION(i);
    109.                 float3 attenColor = attenuation * _LightColor0.xyz;
    110.                 float Pi = 3.141592654;
    111.                 float InvPi = 0.31830988618;
    112. ///////// Gloss:
    113.                 float node_383 = 0.0;
    114.                 float gloss = node_383;
    115.                 float specPow = exp2( gloss * 10.0+1.0);
    116. /////// GI Data:
    117.                 UnityLight light;
    118.                 #ifdef LIGHTMAP_OFF
    119.                     light.color = lightColor;
    120.                     light.dir = lightDirection;
    121.                     light.ndotl = LambertTerm (normalDirection, light.dir);
    122.                 #else
    123.                     light.color = half3(0.f, 0.f, 0.f);
    124.                     light.ndotl = 0.0f;
    125.                     light.dir = half3(0.f, 0.f, 0.f);
    126.                 #endif
    127.                 UnityGIInput d;
    128.                 d.light = light;
    129.                 d.worldPos = i.posWorld.xyz;
    130.                 d.worldViewDir = viewDirection;
    131.                 d.atten = attenuation;
    132.                 #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
    133.                     d.ambient = 0;
    134.                     d.lightmapUV = i.ambientOrLightmapUV;
    135.                 #else
    136.                     d.ambient = i.ambientOrLightmapUV;
    137.                 #endif
    138.                 d.boxMax[0] = unity_SpecCube0_BoxMax;
    139.                 d.boxMin[0] = unity_SpecCube0_BoxMin;
    140.                 d.probePosition[0] = unity_SpecCube0_ProbePosition;
    141.                 d.probeHDR[0] = unity_SpecCube0_HDR;
    142.                 d.boxMax[1] = unity_SpecCube1_BoxMax;
    143.                 d.boxMin[1] = unity_SpecCube1_BoxMin;
    144.                 d.probePosition[1] = unity_SpecCube1_ProbePosition;
    145.                 d.probeHDR[1] = unity_SpecCube1_HDR;
    146.                 Unity_GlossyEnvironmentData ugls_en_data;
    147.                 ugls_en_data.roughness = 1.0 - gloss;
    148.                 ugls_en_data.reflUVW = viewReflectDirection;
    149.                 UnityGI gi = UnityGlobalIllumination(d, 1, normalDirection, ugls_en_data );
    150.                 lightDirection = gi.light.dir;
    151.                 lightColor = gi.light.color;
    152. ////// Specular:
    153.                 float NdotL = max(0, dot( normalDirection, lightDirection ));
    154.                 float LdotH = max(0.0,dot(lightDirection, halfDirection));
    155.                 float3 specularColor = node_383;
    156.                 float specularMonochrome;
    157.                 float4 _LerpTex_var = tex2D(_LerpTex,TRANSFORM_TEX(i.uv0, _LerpTex));
    158.                 float4 _MainTex_var = tex2D(_MainTex,TRANSFORM_TEX(i.uv0, _MainTex));
    159.                 float3 diffuseColor = (lerp(_ColorWhite.rgb,_ColorBlack.rgb,_LerpTex_var.r)*_MainTex_var.rgb); // Need this for specular when using metallic
    160.                 diffuseColor = DiffuseAndSpecularFromMetallic( diffuseColor, specularColor, specularColor, specularMonochrome );
    161.                 specularMonochrome = 1.0-specularMonochrome;
    162.                 float NdotV = max(0.0,dot( normalDirection, viewDirection ));
    163.                 float NdotH = max(0.0,dot( normalDirection, halfDirection ));
    164.                 float VdotH = max(0.0,dot( viewDirection, halfDirection ));
    165.                 float visTerm = SmithJointGGXVisibilityTerm( NdotL, NdotV, 1.0-gloss );
    166.                 float normTerm = max(0.0, GGXTerm(NdotH, 1.0-gloss));
    167.                 float specularPBL = (NdotL*visTerm*normTerm) * (UNITY_PI / 4);
    168.                 if (IsGammaSpace())
    169.                     specularPBL = sqrt(max(1e-4h, specularPBL));
    170.                 specularPBL = max(0, specularPBL * NdotL);
    171.                 float3 directSpecular = (floor(attenuation) * _LightColor0.xyz)*specularPBL*FresnelTerm(specularColor, LdotH);
    172.                 half grazingTerm = saturate( gloss + specularMonochrome );
    173.                 float3 indirectSpecular = (gi.indirect.specular);
    174.                 indirectSpecular *= FresnelLerp (specularColor, grazingTerm, NdotV);
    175.                 float3 specular = (directSpecular + indirectSpecular);
    176. /////// Diffuse:
    177.                 NdotL = max(0.0,dot( normalDirection, lightDirection ));
    178.                 half fd90 = 0.5 + 2 * LdotH * LdotH * (1-gloss);
    179.                 float nlPow5 = Pow5(1-NdotL);
    180.                 float nvPow5 = Pow5(1-NdotV);
    181.                 float3 directDiffuse = ((1 +(fd90 - 1)*nlPow5) * (1 + (fd90 - 1)*nvPow5) * NdotL) * attenColor;
    182.                 float3 indirectDiffuse = float3(0,0,0);
    183.                 indirectDiffuse += gi.indirect.diffuse;
    184.                 float3 diffuse = (directDiffuse + indirectDiffuse) * diffuseColor;
    185. /// Final Color:
    186.                 float3 finalColor = diffuse + specular;
    187.                 fixed4 finalRGBA = fixed4(finalColor,1);
    188.                 UNITY_APPLY_FOG(i.fogCoord, finalRGBA);
    189.                 return finalRGBA;
    190.             }
    191.             ENDCG
    192.         }
    193.         Pass {
    194.             Name "FORWARD_DELTA"
    195.             Tags {
    196.                 "LightMode"="ForwardAdd"
    197.             }
    198.             Blend One One
    199.      
    200.      
    201.             CGPROGRAM
    202.             #pragma vertex vert
    203.             #pragma fragment frag
    204.             #define UNITY_PASS_FORWARDADD
    205.             #define SHOULD_SAMPLE_SH ( defined (LIGHTMAP_OFF) && defined(DYNAMICLIGHTMAP_OFF) )
    206.             #define _GLOSSYENV 1
    207.             #include "UnityCG.cginc"
    208.             #include "AutoLight.cginc"
    209.             #include "Lighting.cginc"
    210.             #include "UnityPBSLighting.cginc"
    211.             #include "UnityStandardBRDF.cginc"
    212.             #pragma multi_compile_fwdadd_fullshadows
    213.             #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
    214.             #pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE
    215.             #pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
    216.             #pragma multi_compile_fog
    217.             #pragma exclude_renderers gles3 metal d3d11_9x xbox360 xboxone ps3 ps4 psp2
    218.             #pragma target 3.0
    219.             uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
    220.             uniform sampler2D _BumpMap; uniform float4 _BumpMap_ST;
    221.             uniform float4 _ColorWhite;
    222.             uniform float4 _ColorBlack;
    223.             uniform sampler2D _LerpTex; uniform float4 _LerpTex_ST;
    224.             struct VertexInput {
    225.                 float4 vertex : POSITION;
    226.                 float3 normal : NORMAL;
    227.                 float4 tangent : TANGENT;
    228.                 float2 texcoord0 : TEXCOORD0;
    229.                 float2 texcoord1 : TEXCOORD1;
    230.                 float2 texcoord2 : TEXCOORD2;
    231.             };
    232.             struct VertexOutput {
    233.                 float4 pos : SV_POSITION;
    234.                 float2 uv0 : TEXCOORD0;
    235.                 float2 uv1 : TEXCOORD1;
    236.                 float2 uv2 : TEXCOORD2;
    237.                 float4 posWorld : TEXCOORD3;
    238.                 float3 normalDir : TEXCOORD4;
    239.                 float3 tangentDir : TEXCOORD5;
    240.                 float3 bitangentDir : TEXCOORD6;
    241.                 LIGHTING_COORDS(7,8)
    242.                 UNITY_FOG_COORDS(9)
    243.             };
    244.             VertexOutput vert (VertexInput v) {
    245.                 VertexOutput o = (VertexOutput)0;
    246.                 o.uv0 = v.texcoord0;
    247.                 o.uv1 = v.texcoord1;
    248.                 o.uv2 = v.texcoord2;
    249.                 o.normalDir = UnityObjectToWorldNormal(v.normal);
    250.                 o.tangentDir = normalize( mul( unity_ObjectToWorld, float4( v.tangent.xyz, 0.0 ) ).xyz );
    251.                 o.bitangentDir = normalize(cross(o.normalDir, o.tangentDir) * v.tangent.w);
    252.                 o.posWorld = mul(unity_ObjectToWorld, v.vertex);
    253.                 float3 lightColor = _LightColor0.rgb;
    254.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex );
    255.                 UNITY_TRANSFER_FOG(o,o.pos);
    256.                 TRANSFER_VERTEX_TO_FRAGMENT(o)
    257.                 return o;
    258.             }
    259.             float4 frag(VertexOutput i) : COLOR {
    260.                 i.normalDir = normalize(i.normalDir);
    261.                 float3x3 tangentTransform = float3x3( i.tangentDir, i.bitangentDir, i.normalDir);
    262.                 float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
    263.                 float3 _BumpMap_var = UnpackNormal(tex2D(_BumpMap,TRANSFORM_TEX(i.uv0, _BumpMap)));
    264.                 float3 normalLocal = _BumpMap_var.rgb;
    265.                 float3 normalDirection = normalize(mul( normalLocal, tangentTransform )); // Perturbed normals
    266.                 float3 lightDirection = normalize(lerp(_WorldSpaceLightPos0.xyz, _WorldSpaceLightPos0.xyz - i.posWorld.xyz,_WorldSpaceLightPos0.w));
    267.                 float3 lightColor = _LightColor0.rgb;
    268.                 float3 halfDirection = normalize(viewDirection+lightDirection);
    269. ////// Lighting:
    270.                 float attenuation = LIGHT_ATTENUATION(i);
    271.                 float3 attenColor = attenuation * _LightColor0.xyz;
    272.                 float Pi = 3.141592654;
    273.                 float InvPi = 0.31830988618;
    274. ///////// Gloss:
    275.                 float node_383 = 0.0;
    276.                 float gloss = node_383;
    277.                 float specPow = exp2( gloss * 10.0+1.0);
    278. ////// Specular:
    279.                 float NdotL = max(0, dot( normalDirection, lightDirection ));
    280.                 float LdotH = max(0.0,dot(lightDirection, halfDirection));
    281.                 float3 specularColor = node_383;
    282.                 float specularMonochrome;
    283.                 float4 _LerpTex_var = tex2D(_LerpTex,TRANSFORM_TEX(i.uv0, _LerpTex));
    284.                 float4 _MainTex_var = tex2D(_MainTex,TRANSFORM_TEX(i.uv0, _MainTex));
    285.                 float3 diffuseColor = (lerp(_ColorWhite.rgb,_ColorBlack.rgb,_LerpTex_var.r)*_MainTex_var.rgb); // Need this for specular when using metallic
    286.                 diffuseColor = DiffuseAndSpecularFromMetallic( diffuseColor, specularColor, specularColor, specularMonochrome );
    287.                 specularMonochrome = 1.0-specularMonochrome;
    288.                 float NdotV = max(0.0,dot( normalDirection, viewDirection ));
    289.                 float NdotH = max(0.0,dot( normalDirection, halfDirection ));
    290.                 float VdotH = max(0.0,dot( viewDirection, halfDirection ));
    291.                 float visTerm = SmithJointGGXVisibilityTerm( NdotL, NdotV, 1.0-gloss );
    292.                 float normTerm = max(0.0, GGXTerm(NdotH, 1.0-gloss));
    293.                 float specularPBL = (NdotL*visTerm*normTerm) * (UNITY_PI / 4);
    294.                 if (IsGammaSpace())
    295.                     specularPBL = sqrt(max(1e-4h, specularPBL));
    296.                 specularPBL = max(0, specularPBL * NdotL);
    297.                 float3 directSpecular = attenColor*specularPBL*FresnelTerm(specularColor, LdotH);
    298.                 float3 specular = directSpecular;
    299. /////// Diffuse:
    300.                 NdotL = max(0.0,dot( normalDirection, lightDirection ));
    301.                 half fd90 = 0.5 + 2 * LdotH * LdotH * (1-gloss);
    302.                 float nlPow5 = Pow5(1-NdotL);
    303.                 float nvPow5 = Pow5(1-NdotV);
    304.                 float3 directDiffuse = ((1 +(fd90 - 1)*nlPow5) * (1 + (fd90 - 1)*nvPow5) * NdotL) * attenColor;
    305.                 float3 diffuse = directDiffuse * diffuseColor;
    306. /// Final Color:
    307.                 float3 finalColor = diffuse + specular;
    308.                 fixed4 finalRGBA = fixed4(finalColor * 1,0);
    309.                 UNITY_APPLY_FOG(i.fogCoord, finalRGBA);
    310.                 return finalRGBA;
    311.             }
    312.             ENDCG
    313.         }
    314.         Pass {
    315.             Name "Meta"
    316.             Tags {
    317.                 "LightMode"="Meta"
    318.             }
    319.             Cull Off
    320.      
    321.             CGPROGRAM
    322.             #pragma vertex vert
    323.             #pragma fragment frag
    324.             #define UNITY_PASS_META 1
    325.             #define SHOULD_SAMPLE_SH ( defined (LIGHTMAP_OFF) && defined(DYNAMICLIGHTMAP_OFF) )
    326.             #define _GLOSSYENV 1
    327.             #include "UnityCG.cginc"
    328.             #include "Lighting.cginc"
    329.             #include "UnityPBSLighting.cginc"
    330.             #include "UnityStandardBRDF.cginc"
    331.             #include "UnityMetaPass.cginc"
    332.             #pragma fragmentoption ARB_precision_hint_fastest
    333.             #pragma multi_compile_shadowcaster
    334.             #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
    335.             #pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE
    336.             #pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
    337.             #pragma multi_compile_fog
    338.             #pragma exclude_renderers gles3 metal d3d11_9x xbox360 xboxone ps3 ps4 psp2
    339.             #pragma target 3.0
    340.             uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
    341.             uniform float4 _ColorWhite;
    342.             uniform float4 _ColorBlack;
    343.             uniform sampler2D _LerpTex; uniform float4 _LerpTex_ST;
    344.             struct VertexInput {
    345.                 float4 vertex : POSITION;
    346.                 float2 texcoord0 : TEXCOORD0;
    347.                 float2 texcoord1 : TEXCOORD1;
    348.                 float2 texcoord2 : TEXCOORD2;
    349.             };
    350.             struct VertexOutput {
    351.                 float4 pos : SV_POSITION;
    352.                 float2 uv0 : TEXCOORD0;
    353.                 float2 uv1 : TEXCOORD1;
    354.                 float2 uv2 : TEXCOORD2;
    355.                 float4 posWorld : TEXCOORD3;
    356.             };
    357.             VertexOutput vert (VertexInput v) {
    358.                 VertexOutput o = (VertexOutput)0;
    359.                 o.uv0 = v.texcoord0;
    360.                 o.uv1 = v.texcoord1;
    361.                 o.uv2 = v.texcoord2;
    362.                 o.posWorld = mul(unity_ObjectToWorld, v.vertex);
    363.                 o.pos = UnityMetaVertexPosition(v.vertex, v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST );
    364.                 return o;
    365.             }
    366.             float4 frag(VertexOutput i) : SV_Target {
    367.                 float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
    368.                 UnityMetaInput o;
    369.                 UNITY_INITIALIZE_OUTPUT( UnityMetaInput, o );
    370.          
    371.                 o.Emission = 0;
    372.          
    373.                 float4 _LerpTex_var = tex2D(_LerpTex,TRANSFORM_TEX(i.uv0, _LerpTex));
    374.                 float4 _MainTex_var = tex2D(_MainTex,TRANSFORM_TEX(i.uv0, _MainTex));
    375.                 float3 diffColor = (lerp(_ColorWhite.rgb,_ColorBlack.rgb,_LerpTex_var.r)*_MainTex_var.rgb);
    376.                 float specularMonochrome;
    377.                 float3 specColor;
    378.                 float node_383 = 0.0;
    379.                 diffColor = DiffuseAndSpecularFromMetallic( diffColor, node_383, specColor, specularMonochrome );
    380.                 float roughness = 1.0 - node_383;
    381.                 o.Albedo = diffColor + specColor * roughness * roughness * 0.5;
    382.          
    383.                 return UnityMetaFragment( o );
    384.             }
    385.             ENDCG
    386.         }
    387.     }
    388.     FallBack "Diffuse"
    389.     CustomEditor "ShaderForgeMaterialInspector"
    390. }

    Shader Forge - Deferred Shader
    Code (csharp):
    1. // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
    2.  
    3. // Shader created with Shader Forge v1.29
    4. // Shader Forge (c) Neat Corporation / Joachim Holmer - http://www.acegikmo.com/shaderforge/
    5. // Note: Manually altering this data may prevent you from opening it in Shader Forge
    6. /*SF_DATA;ver:1.29;sub:START;pass:START;ps:flbk:,iptp:0,cusa:False,bamd:0,lico:1,lgpr:1,limd:3,spmd:1,trmd:0,grmd:0,uamb:True,mssp:True,bkdf:True,hqlp:False,rprd:True,enco:False,rmgx:True,rpth:1,vtps:0,hqsc:True,nrmq:1,nrsp:0,vomd:0,spxs:False,tesm:0,olmd:1,culm:0,bsrc:0,bdst:1,dpts:2,wrdp:True,dith:0,rfrpo:True,rfrpn:Refraction,coma:15,ufog:True,aust:True,igpj:False,qofs:0,qpre:1,rntp:1,fgom:False,fgoc:False,fgod:False,fgor:False,fgmd:0,fgcr:0.5,fgcg:0.5,fgcb:0.5,fgca:1,fgde:0.01,fgrn:0,fgrf:300,stcl:False,stva:128,stmr:255,stmw:255,stcp:6,stps:0,stfa:0,stfz:0,ofsf:0,ofsu:0,f2p0:False,fnsp:False,fnfb:False;n:type:ShaderForge.SFN_Final,id:2865,x:32719,y:32712,varname:node_2865,prsc:2|diff-6343-OUT,spec-383-OUT,gloss-383-OUT,normal-5964-RGB;n:type:ShaderForge.SFN_Multiply,id:6343,x:32399,y:32683,varname:node_6343,prsc:2|A-8466-OUT,B-7736-RGB;n:type:ShaderForge.SFN_Tex2d,id:7736,x:31710,y:32879,ptovrint:True,ptlb:Base Color,ptin:_MainTex,varname:_MainTex,prsc:2,glob:False,taghide:False,taghdr:False,tagprd:False,tagnsco:False,tagnrm:False,ntxv:0,isnm:False;n:type:ShaderForge.SFN_Tex2d,id:5964,x:32055,y:32936,ptovrint:True,ptlb:Normal Map,ptin:_BumpMap,varname:_BumpMap,prsc:2,glob:False,taghide:False,taghdr:False,tagprd:False,tagnsco:False,tagnrm:False,ntxv:3,isnm:True;n:type:ShaderForge.SFN_Lerp,id:8466,x:31852,y:32462,varname:node_8466,prsc:2|A-1185-RGB,B-626-RGB,T-5966-R;n:type:ShaderForge.SFN_Color,id:1185,x:31592,y:32244,ptovrint:False,ptlb:ColorWhite,ptin:_ColorWhite,varname:node_1185,prsc:2,glob:False,taghide:False,taghdr:False,tagprd:False,tagnsco:False,tagnrm:False,c1:0.5,c2:0.5,c3:0.5,c4:1;n:type:ShaderForge.SFN_Color,id:626,x:31592,y:32420,ptovrint:False,ptlb:ColorBlack,ptin:_ColorBlack,varname:node_626,prsc:2,glob:False,taghide:False,taghdr:False,tagprd:False,tagnsco:False,tagnrm:False,c1:0.5,c2:0.5,c3:0.5,c4:1;n:type:ShaderForge.SFN_Tex2d,id:5966,x:31592,y:32652,ptovrint:False,ptlb:LerpTex,ptin:_LerpTex,varname:node_5966,prsc:2,glob:False,taghide:False,taghdr:False,tagprd:False,tagnsco:False,tagnrm:False,ntxv:0,isnm:False;n:type:ShaderForge.SFN_Vector1,id:383,x:32459,y:32494,varname:node_383,prsc:2,v1:0;proporder:5964-7736-1185-626-5966;pass:END;sub:END;*/
    7.  
    8. Shader "EcoTales/EcoTales_PBR_Test_ShaderForge_Def" {
    9.     Properties {
    10.         _BumpMap ("Normal Map", 2D) = "bump" {}
    11.         _MainTex ("Base Color", 2D) = "white" {}
    12.         _ColorWhite ("ColorWhite", Color) = (0.5,0.5,0.5,1)
    13.         _ColorBlack ("ColorBlack", Color) = (0.5,0.5,0.5,1)
    14.         _LerpTex ("LerpTex", 2D) = "white" {}
    15.     }
    16.     SubShader {
    17.         Tags {
    18.             "RenderType"="Opaque"
    19.         }
    20.         Pass {
    21.             Name "DEFERRED"
    22.             Tags {
    23.                 "LightMode"="Deferred"
    24.             }
    25.        
    26.        
    27.             CGPROGRAM
    28.             #pragma vertex vert
    29.             #pragma fragment frag
    30.             #define UNITY_PASS_DEFERRED
    31.             #define SHOULD_SAMPLE_SH ( defined (LIGHTMAP_OFF) && defined(DYNAMICLIGHTMAP_OFF) )
    32.             #define _GLOSSYENV 1
    33.             #include "UnityCG.cginc"
    34.             #include "Lighting.cginc"
    35.             #include "UnityPBSLighting.cginc"
    36.             #include "UnityStandardBRDF.cginc"
    37.             #pragma fragmentoption ARB_precision_hint_fastest
    38.             #pragma multi_compile_shadowcaster
    39.             #pragma multi_compile ___ UNITY_HDR_ON
    40.             #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
    41.             #pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE
    42.             #pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
    43.             #pragma multi_compile_fog
    44.             #pragma exclude_renderers gles3 metal d3d11_9x xbox360 xboxone ps3 ps4 psp2
    45.             #pragma target 3.0
    46.             uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
    47.             uniform sampler2D _BumpMap; uniform float4 _BumpMap_ST;
    48.             uniform float4 _ColorWhite;
    49.             uniform float4 _ColorBlack;
    50.             uniform sampler2D _LerpTex; uniform float4 _LerpTex_ST;
    51.             struct VertexInput {
    52.                 float4 vertex : POSITION;
    53.                 float3 normal : NORMAL;
    54.                 float4 tangent : TANGENT;
    55.                 float2 texcoord0 : TEXCOORD0;
    56.                 float2 texcoord1 : TEXCOORD1;
    57.                 float2 texcoord2 : TEXCOORD2;
    58.             };
    59.             struct VertexOutput {
    60.                 float4 pos : SV_POSITION;
    61.                 float2 uv0 : TEXCOORD0;
    62.                 float2 uv1 : TEXCOORD1;
    63.                 float2 uv2 : TEXCOORD2;
    64.                 float4 posWorld : TEXCOORD3;
    65.                 float3 normalDir : TEXCOORD4;
    66.                 float3 tangentDir : TEXCOORD5;
    67.                 float3 bitangentDir : TEXCOORD6;
    68.                 #if defined(LIGHTMAP_ON) || defined(UNITY_SHOULD_SAMPLE_SH)
    69.                     float4 ambientOrLightmapUV : TEXCOORD7;
    70.                 #endif
    71.             };
    72.             VertexOutput vert (VertexInput v) {
    73.                 VertexOutput o = (VertexOutput)0;
    74.                 o.uv0 = v.texcoord0;
    75.                 o.uv1 = v.texcoord1;
    76.                 o.uv2 = v.texcoord2;
    77.                 #ifdef LIGHTMAP_ON
    78.                     o.ambientOrLightmapUV.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
    79.                     o.ambientOrLightmapUV.zw = 0;
    80.                 #elif UNITY_SHOULD_SAMPLE_SH
    81.                 #endif
    82.                 #ifdef DYNAMICLIGHTMAP_ON
    83.                     o.ambientOrLightmapUV.zw = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
    84.                 #endif
    85.                 o.normalDir = UnityObjectToWorldNormal(v.normal);
    86.                 o.tangentDir = normalize( mul( unity_ObjectToWorld, float4( v.tangent.xyz, 0.0 ) ).xyz );
    87.                 o.bitangentDir = normalize(cross(o.normalDir, o.tangentDir) * v.tangent.w);
    88.                 o.posWorld = mul(unity_ObjectToWorld, v.vertex);
    89.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex );
    90.                 return o;
    91.             }
    92.             void frag(
    93.                 VertexOutput i,
    94.                 out half4 outDiffuse : SV_Target0,
    95.                 out half4 outSpecSmoothness : SV_Target1,
    96.                 out half4 outNormal : SV_Target2,
    97.                 out half4 outEmission : SV_Target3 )
    98.             {
    99.                 i.normalDir = normalize(i.normalDir);
    100.                 float3x3 tangentTransform = float3x3( i.tangentDir, i.bitangentDir, i.normalDir);
    101.                 float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
    102.                 float3 _BumpMap_var = UnpackNormal(tex2D(_BumpMap,TRANSFORM_TEX(i.uv0, _BumpMap)));
    103.                 float3 normalLocal = _BumpMap_var.rgb;
    104.                 float3 normalDirection = normalize(mul( normalLocal, tangentTransform )); // Perturbed normals
    105.                 float3 viewReflectDirection = reflect( -viewDirection, normalDirection );
    106. ////// Lighting:
    107.                 float Pi = 3.141592654;
    108.                 float InvPi = 0.31830988618;
    109. ///////// Gloss:
    110.                 float node_383 = 0.0;
    111.                 float gloss = node_383;
    112. /////// GI Data:
    113.                 UnityLight light; // Dummy light
    114.                 light.color = 0;
    115.                 light.dir = half3(0,1,0);
    116.                 light.ndotl = max(0,dot(normalDirection,light.dir));
    117.                 UnityGIInput d;
    118.                 d.light = light;
    119.                 d.worldPos = i.posWorld.xyz;
    120.                 d.worldViewDir = viewDirection;
    121.                 d.atten = 1;
    122.                 #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
    123.                     d.ambient = 0;
    124.                     d.lightmapUV = i.ambientOrLightmapUV;
    125.                 #else
    126.                     d.ambient = i.ambientOrLightmapUV;
    127.                 #endif
    128.                 d.boxMax[0] = unity_SpecCube0_BoxMax;
    129.                 d.boxMin[0] = unity_SpecCube0_BoxMin;
    130.                 d.probePosition[0] = unity_SpecCube0_ProbePosition;
    131.                 d.probeHDR[0] = unity_SpecCube0_HDR;
    132.                 d.boxMax[1] = unity_SpecCube1_BoxMax;
    133.                 d.boxMin[1] = unity_SpecCube1_BoxMin;
    134.                 d.probePosition[1] = unity_SpecCube1_ProbePosition;
    135.                 d.probeHDR[1] = unity_SpecCube1_HDR;
    136.                 Unity_GlossyEnvironmentData ugls_en_data;
    137.                 ugls_en_data.roughness = 1.0 - gloss;
    138.                 ugls_en_data.reflUVW = viewReflectDirection;
    139.                 UnityGI gi = UnityGlobalIllumination(d, 1, normalDirection, ugls_en_data );
    140. ////// Specular:
    141.                 float3 specularColor = node_383;
    142.                 float specularMonochrome;
    143.                 float4 _LerpTex_var = tex2D(_LerpTex,TRANSFORM_TEX(i.uv0, _LerpTex));
    144.                 float4 _MainTex_var = tex2D(_MainTex,TRANSFORM_TEX(i.uv0, _MainTex));
    145.                 float3 diffuseColor = (lerp(_ColorWhite.rgb,_ColorBlack.rgb,_LerpTex_var.r)*_MainTex_var.rgb); // Need this for specular when using metallic
    146.                 diffuseColor = DiffuseAndSpecularFromMetallic( diffuseColor, specularColor, specularColor, specularMonochrome );
    147.                 specularMonochrome = 1.0-specularMonochrome;
    148.                 float NdotV = max(0.0,dot( normalDirection, viewDirection ));
    149.                 half grazingTerm = saturate( gloss + specularMonochrome );
    150.                 float3 indirectSpecular = (gi.indirect.specular);
    151.                 indirectSpecular *= FresnelLerp (specularColor, grazingTerm, NdotV);
    152. /////// Diffuse:
    153.                 float3 indirectDiffuse = float3(0,0,0);
    154.                 indirectDiffuse += gi.indirect.diffuse;
    155. /// Final Color:
    156.                 outDiffuse = half4( diffuseColor, 1 );
    157.                 outSpecSmoothness = half4( specularColor, gloss );
    158.                 outNormal = half4( normalDirection * 0.5 + 0.5, 1 );
    159.                 outEmission = half4(0,0,0,1);
    160.                 outEmission.rgb += indirectSpecular * 1;
    161.                 outEmission.rgb += indirectDiffuse * diffuseColor;
    162.                 #ifndef UNITY_HDR_ON
    163.                     outEmission.rgb = exp2(-outEmission.rgb);
    164.                 #endif
    165.             }
    166.             ENDCG
    167.         }
    168.         Pass {
    169.             Name "FORWARD"
    170.             Tags {
    171.                 "LightMode"="ForwardBase"
    172.             }
    173.        
    174.        
    175.             CGPROGRAM
    176.             #pragma vertex vert
    177.             #pragma fragment frag
    178.             #define UNITY_PASS_FORWARDBASE
    179.             #define SHOULD_SAMPLE_SH ( defined (LIGHTMAP_OFF) && defined(DYNAMICLIGHTMAP_OFF) )
    180.             #define _GLOSSYENV 1
    181.             #include "UnityCG.cginc"
    182.             #include "AutoLight.cginc"
    183.             #include "Lighting.cginc"
    184.             #include "UnityPBSLighting.cginc"
    185.             #include "UnityStandardBRDF.cginc"
    186.             #pragma multi_compile_fwdbase_fullshadows
    187.             #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
    188.             #pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE
    189.             #pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
    190.             #pragma multi_compile_fog
    191.             #pragma exclude_renderers gles3 metal d3d11_9x xbox360 xboxone ps3 ps4 psp2
    192.             #pragma target 3.0
    193.             uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
    194.             uniform sampler2D _BumpMap; uniform float4 _BumpMap_ST;
    195.             uniform float4 _ColorWhite;
    196.             uniform float4 _ColorBlack;
    197.             uniform sampler2D _LerpTex; uniform float4 _LerpTex_ST;
    198.             struct VertexInput {
    199.                 float4 vertex : POSITION;
    200.                 float3 normal : NORMAL;
    201.                 float4 tangent : TANGENT;
    202.                 float2 texcoord0 : TEXCOORD0;
    203.                 float2 texcoord1 : TEXCOORD1;
    204.                 float2 texcoord2 : TEXCOORD2;
    205.             };
    206.             struct VertexOutput {
    207.                 float4 pos : SV_POSITION;
    208.                 float2 uv0 : TEXCOORD0;
    209.                 float2 uv1 : TEXCOORD1;
    210.                 float2 uv2 : TEXCOORD2;
    211.                 float4 posWorld : TEXCOORD3;
    212.                 float3 normalDir : TEXCOORD4;
    213.                 float3 tangentDir : TEXCOORD5;
    214.                 float3 bitangentDir : TEXCOORD6;
    215.                 LIGHTING_COORDS(7,8)
    216.                 UNITY_FOG_COORDS(9)
    217.                 #if defined(LIGHTMAP_ON) || defined(UNITY_SHOULD_SAMPLE_SH)
    218.                     float4 ambientOrLightmapUV : TEXCOORD10;
    219.                 #endif
    220.             };
    221.             VertexOutput vert (VertexInput v) {
    222.                 VertexOutput o = (VertexOutput)0;
    223.                 o.uv0 = v.texcoord0;
    224.                 o.uv1 = v.texcoord1;
    225.                 o.uv2 = v.texcoord2;
    226.                 #ifdef LIGHTMAP_ON
    227.                     o.ambientOrLightmapUV.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
    228.                     o.ambientOrLightmapUV.zw = 0;
    229.                 #elif UNITY_SHOULD_SAMPLE_SH
    230.                 #endif
    231.                 #ifdef DYNAMICLIGHTMAP_ON
    232.                     o.ambientOrLightmapUV.zw = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
    233.                 #endif
    234.                 o.normalDir = UnityObjectToWorldNormal(v.normal);
    235.                 o.tangentDir = normalize( mul( unity_ObjectToWorld, float4( v.tangent.xyz, 0.0 ) ).xyz );
    236.                 o.bitangentDir = normalize(cross(o.normalDir, o.tangentDir) * v.tangent.w);
    237.                 o.posWorld = mul(unity_ObjectToWorld, v.vertex);
    238.                 float3 lightColor = _LightColor0.rgb;
    239.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex );
    240.                 UNITY_TRANSFER_FOG(o,o.pos);
    241.                 TRANSFER_VERTEX_TO_FRAGMENT(o)
    242.                 return o;
    243.             }
    244.             float4 frag(VertexOutput i) : COLOR {
    245.                 i.normalDir = normalize(i.normalDir);
    246.                 float3x3 tangentTransform = float3x3( i.tangentDir, i.bitangentDir, i.normalDir);
    247.                 float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
    248.                 float3 _BumpMap_var = UnpackNormal(tex2D(_BumpMap,TRANSFORM_TEX(i.uv0, _BumpMap)));
    249.                 float3 normalLocal = _BumpMap_var.rgb;
    250.                 float3 normalDirection = normalize(mul( normalLocal, tangentTransform )); // Perturbed normals
    251.                 float3 viewReflectDirection = reflect( -viewDirection, normalDirection );
    252.                 float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    253.                 float3 lightColor = _LightColor0.rgb;
    254.                 float3 halfDirection = normalize(viewDirection+lightDirection);
    255. ////// Lighting:
    256.                 float attenuation = LIGHT_ATTENUATION(i);
    257.                 float3 attenColor = attenuation * _LightColor0.xyz;
    258.                 float Pi = 3.141592654;
    259.                 float InvPi = 0.31830988618;
    260. ///////// Gloss:
    261.                 float node_383 = 0.0;
    262.                 float gloss = node_383;
    263.                 float specPow = exp2( gloss * 10.0+1.0);
    264. /////// GI Data:
    265.                 UnityLight light;
    266.                 #ifdef LIGHTMAP_OFF
    267.                     light.color = lightColor;
    268.                     light.dir = lightDirection;
    269.                     light.ndotl = LambertTerm (normalDirection, light.dir);
    270.                 #else
    271.                     light.color = half3(0.f, 0.f, 0.f);
    272.                     light.ndotl = 0.0f;
    273.                     light.dir = half3(0.f, 0.f, 0.f);
    274.                 #endif
    275.                 UnityGIInput d;
    276.                 d.light = light;
    277.                 d.worldPos = i.posWorld.xyz;
    278.                 d.worldViewDir = viewDirection;
    279.                 d.atten = attenuation;
    280.                 #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
    281.                     d.ambient = 0;
    282.                     d.lightmapUV = i.ambientOrLightmapUV;
    283.                 #else
    284.                     d.ambient = i.ambientOrLightmapUV;
    285.                 #endif
    286.                 d.boxMax[0] = unity_SpecCube0_BoxMax;
    287.                 d.boxMin[0] = unity_SpecCube0_BoxMin;
    288.                 d.probePosition[0] = unity_SpecCube0_ProbePosition;
    289.                 d.probeHDR[0] = unity_SpecCube0_HDR;
    290.                 d.boxMax[1] = unity_SpecCube1_BoxMax;
    291.                 d.boxMin[1] = unity_SpecCube1_BoxMin;
    292.                 d.probePosition[1] = unity_SpecCube1_ProbePosition;
    293.                 d.probeHDR[1] = unity_SpecCube1_HDR;
    294.                 Unity_GlossyEnvironmentData ugls_en_data;
    295.                 ugls_en_data.roughness = 1.0 - gloss;
    296.                 ugls_en_data.reflUVW = viewReflectDirection;
    297.                 UnityGI gi = UnityGlobalIllumination(d, 1, normalDirection, ugls_en_data );
    298.                 lightDirection = gi.light.dir;
    299.                 lightColor = gi.light.color;
    300. ////// Specular:
    301.                 float NdotL = max(0, dot( normalDirection, lightDirection ));
    302.                 float LdotH = max(0.0,dot(lightDirection, halfDirection));
    303.                 float3 specularColor = node_383;
    304.                 float specularMonochrome;
    305.                 float4 _LerpTex_var = tex2D(_LerpTex,TRANSFORM_TEX(i.uv0, _LerpTex));
    306.                 float4 _MainTex_var = tex2D(_MainTex,TRANSFORM_TEX(i.uv0, _MainTex));
    307.                 float3 diffuseColor = (lerp(_ColorWhite.rgb,_ColorBlack.rgb,_LerpTex_var.r)*_MainTex_var.rgb); // Need this for specular when using metallic
    308.                 diffuseColor = DiffuseAndSpecularFromMetallic( diffuseColor, specularColor, specularColor, specularMonochrome );
    309.                 specularMonochrome = 1.0-specularMonochrome;
    310.                 float NdotV = max(0.0,dot( normalDirection, viewDirection ));
    311.                 float NdotH = max(0.0,dot( normalDirection, halfDirection ));
    312.                 float VdotH = max(0.0,dot( viewDirection, halfDirection ));
    313.                 float visTerm = SmithJointGGXVisibilityTerm( NdotL, NdotV, 1.0-gloss );
    314.                 float normTerm = max(0.0, GGXTerm(NdotH, 1.0-gloss));
    315.                 float specularPBL = (NdotL*visTerm*normTerm) * (UNITY_PI / 4);
    316.                 if (IsGammaSpace())
    317.                     specularPBL = sqrt(max(1e-4h, specularPBL));
    318.                 specularPBL = max(0, specularPBL * NdotL);
    319.                 float3 directSpecular = (floor(attenuation) * _LightColor0.xyz)*specularPBL*FresnelTerm(specularColor, LdotH);
    320.                 half grazingTerm = saturate( gloss + specularMonochrome );
    321.                 float3 indirectSpecular = (gi.indirect.specular);
    322.                 indirectSpecular *= FresnelLerp (specularColor, grazingTerm, NdotV);
    323.                 float3 specular = (directSpecular + indirectSpecular);
    324. /////// Diffuse:
    325.                 NdotL = max(0.0,dot( normalDirection, lightDirection ));
    326.                 half fd90 = 0.5 + 2 * LdotH * LdotH * (1-gloss);
    327.                 float nlPow5 = Pow5(1-NdotL);
    328.                 float nvPow5 = Pow5(1-NdotV);
    329.                 float3 directDiffuse = ((1 +(fd90 - 1)*nlPow5) * (1 + (fd90 - 1)*nvPow5) * NdotL) * attenColor;
    330.                 float3 indirectDiffuse = float3(0,0,0);
    331.                 indirectDiffuse += gi.indirect.diffuse;
    332.                 float3 diffuse = (directDiffuse + indirectDiffuse) * diffuseColor;
    333. /// Final Color:
    334.                 float3 finalColor = diffuse + specular;
    335.                 fixed4 finalRGBA = fixed4(finalColor,1);
    336.                 UNITY_APPLY_FOG(i.fogCoord, finalRGBA);
    337.                 return finalRGBA;
    338.             }
    339.             ENDCG
    340.         }
    341.         Pass {
    342.             Name "FORWARD_DELTA"
    343.             Tags {
    344.                 "LightMode"="ForwardAdd"
    345.             }
    346.             Blend One One
    347.        
    348.        
    349.             CGPROGRAM
    350.             #pragma vertex vert
    351.             #pragma fragment frag
    352.             #define UNITY_PASS_FORWARDADD
    353.             #define SHOULD_SAMPLE_SH ( defined (LIGHTMAP_OFF) && defined(DYNAMICLIGHTMAP_OFF) )
    354.             #define _GLOSSYENV 1
    355.             #include "UnityCG.cginc"
    356.             #include "AutoLight.cginc"
    357.             #include "Lighting.cginc"
    358.             #include "UnityPBSLighting.cginc"
    359.             #include "UnityStandardBRDF.cginc"
    360.             #pragma multi_compile_fwdadd_fullshadows
    361.             #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
    362.             #pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE
    363.             #pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
    364.             #pragma multi_compile_fog
    365.             #pragma exclude_renderers gles3 metal d3d11_9x xbox360 xboxone ps3 ps4 psp2
    366.             #pragma target 3.0
    367.             uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
    368.             uniform sampler2D _BumpMap; uniform float4 _BumpMap_ST;
    369.             uniform float4 _ColorWhite;
    370.             uniform float4 _ColorBlack;
    371.             uniform sampler2D _LerpTex; uniform float4 _LerpTex_ST;
    372.             struct VertexInput {
    373.                 float4 vertex : POSITION;
    374.                 float3 normal : NORMAL;
    375.                 float4 tangent : TANGENT;
    376.                 float2 texcoord0 : TEXCOORD0;
    377.                 float2 texcoord1 : TEXCOORD1;
    378.                 float2 texcoord2 : TEXCOORD2;
    379.             };
    380.             struct VertexOutput {
    381.                 float4 pos : SV_POSITION;
    382.                 float2 uv0 : TEXCOORD0;
    383.                 float2 uv1 : TEXCOORD1;
    384.                 float2 uv2 : TEXCOORD2;
    385.                 float4 posWorld : TEXCOORD3;
    386.                 float3 normalDir : TEXCOORD4;
    387.                 float3 tangentDir : TEXCOORD5;
    388.                 float3 bitangentDir : TEXCOORD6;
    389.                 LIGHTING_COORDS(7,8)
    390.                 UNITY_FOG_COORDS(9)
    391.             };
    392.             VertexOutput vert (VertexInput v) {
    393.                 VertexOutput o = (VertexOutput)0;
    394.                 o.uv0 = v.texcoord0;
    395.                 o.uv1 = v.texcoord1;
    396.                 o.uv2 = v.texcoord2;
    397.                 o.normalDir = UnityObjectToWorldNormal(v.normal);
    398.                 o.tangentDir = normalize( mul( unity_ObjectToWorld, float4( v.tangent.xyz, 0.0 ) ).xyz );
    399.                 o.bitangentDir = normalize(cross(o.normalDir, o.tangentDir) * v.tangent.w);
    400.                 o.posWorld = mul(unity_ObjectToWorld, v.vertex);
    401.                 float3 lightColor = _LightColor0.rgb;
    402.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex );
    403.                 UNITY_TRANSFER_FOG(o,o.pos);
    404.                 TRANSFER_VERTEX_TO_FRAGMENT(o)
    405.                 return o;
    406.             }
    407.             float4 frag(VertexOutput i) : COLOR {
    408.                 i.normalDir = normalize(i.normalDir);
    409.                 float3x3 tangentTransform = float3x3( i.tangentDir, i.bitangentDir, i.normalDir);
    410.                 float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
    411.                 float3 _BumpMap_var = UnpackNormal(tex2D(_BumpMap,TRANSFORM_TEX(i.uv0, _BumpMap)));
    412.                 float3 normalLocal = _BumpMap_var.rgb;
    413.                 float3 normalDirection = normalize(mul( normalLocal, tangentTransform )); // Perturbed normals
    414.                 float3 lightDirection = normalize(lerp(_WorldSpaceLightPos0.xyz, _WorldSpaceLightPos0.xyz - i.posWorld.xyz,_WorldSpaceLightPos0.w));
    415.                 float3 lightColor = _LightColor0.rgb;
    416.                 float3 halfDirection = normalize(viewDirection+lightDirection);
    417. ////// Lighting:
    418.                 float attenuation = LIGHT_ATTENUATION(i);
    419.                 float3 attenColor = attenuation * _LightColor0.xyz;
    420.                 float Pi = 3.141592654;
    421.                 float InvPi = 0.31830988618;
    422. ///////// Gloss:
    423.                 float node_383 = 0.0;
    424.                 float gloss = node_383;
    425.                 float specPow = exp2( gloss * 10.0+1.0);
    426. ////// Specular:
    427.                 float NdotL = max(0, dot( normalDirection, lightDirection ));
    428.                 float LdotH = max(0.0,dot(lightDirection, halfDirection));
    429.                 float3 specularColor = node_383;
    430.                 float specularMonochrome;
    431.                 float4 _LerpTex_var = tex2D(_LerpTex,TRANSFORM_TEX(i.uv0, _LerpTex));
    432.                 float4 _MainTex_var = tex2D(_MainTex,TRANSFORM_TEX(i.uv0, _MainTex));
    433.                 float3 diffuseColor = (lerp(_ColorWhite.rgb,_ColorBlack.rgb,_LerpTex_var.r)*_MainTex_var.rgb); // Need this for specular when using metallic
    434.                 diffuseColor = DiffuseAndSpecularFromMetallic( diffuseColor, specularColor, specularColor, specularMonochrome );
    435.                 specularMonochrome = 1.0-specularMonochrome;
    436.                 float NdotV = max(0.0,dot( normalDirection, viewDirection ));
    437.                 float NdotH = max(0.0,dot( normalDirection, halfDirection ));
    438.                 float VdotH = max(0.0,dot( viewDirection, halfDirection ));
    439.                 float visTerm = SmithJointGGXVisibilityTerm( NdotL, NdotV, 1.0-gloss );
    440.                 float normTerm = max(0.0, GGXTerm(NdotH, 1.0-gloss));
    441.                 float specularPBL = (NdotL*visTerm*normTerm) * (UNITY_PI / 4);
    442.                 if (IsGammaSpace())
    443.                     specularPBL = sqrt(max(1e-4h, specularPBL));
    444.                 specularPBL = max(0, specularPBL * NdotL);
    445.                 float3 directSpecular = attenColor*specularPBL*FresnelTerm(specularColor, LdotH);
    446.                 float3 specular = directSpecular;
    447. /////// Diffuse:
    448.                 NdotL = max(0.0,dot( normalDirection, lightDirection ));
    449.                 half fd90 = 0.5 + 2 * LdotH * LdotH * (1-gloss);
    450.                 float nlPow5 = Pow5(1-NdotL);
    451.                 float nvPow5 = Pow5(1-NdotV);
    452.                 float3 directDiffuse = ((1 +(fd90 - 1)*nlPow5) * (1 + (fd90 - 1)*nvPow5) * NdotL) * attenColor;
    453.                 float3 diffuse = directDiffuse * diffuseColor;
    454. /// Final Color:
    455.                 float3 finalColor = diffuse + specular;
    456.                 fixed4 finalRGBA = fixed4(finalColor * 1,0);
    457.                 UNITY_APPLY_FOG(i.fogCoord, finalRGBA);
    458.                 return finalRGBA;
    459.             }
    460.             ENDCG
    461.         }
    462.         Pass {
    463.             Name "Meta"
    464.             Tags {
    465.                 "LightMode"="Meta"
    466.             }
    467.             Cull Off
    468.        
    469.             CGPROGRAM
    470.             #pragma vertex vert
    471.             #pragma fragment frag
    472.             #define UNITY_PASS_META 1
    473.             #define SHOULD_SAMPLE_SH ( defined (LIGHTMAP_OFF) && defined(DYNAMICLIGHTMAP_OFF) )
    474.             #define _GLOSSYENV 1
    475.             #include "UnityCG.cginc"
    476.             #include "Lighting.cginc"
    477.             #include "UnityPBSLighting.cginc"
    478.             #include "UnityStandardBRDF.cginc"
    479.             #include "UnityMetaPass.cginc"
    480.             #pragma fragmentoption ARB_precision_hint_fastest
    481.             #pragma multi_compile_shadowcaster
    482.             #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
    483.             #pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE
    484.             #pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
    485.             #pragma multi_compile_fog
    486.             #pragma exclude_renderers gles3 metal d3d11_9x xbox360 xboxone ps3 ps4 psp2
    487.             #pragma target 3.0
    488.             uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
    489.             uniform float4 _ColorWhite;
    490.             uniform float4 _ColorBlack;
    491.             uniform sampler2D _LerpTex; uniform float4 _LerpTex_ST;
    492.             struct VertexInput {
    493.                 float4 vertex : POSITION;
    494.                 float2 texcoord0 : TEXCOORD0;
    495.                 float2 texcoord1 : TEXCOORD1;
    496.                 float2 texcoord2 : TEXCOORD2;
    497.             };
    498.             struct VertexOutput {
    499.                 float4 pos : SV_POSITION;
    500.                 float2 uv0 : TEXCOORD0;
    501.                 float2 uv1 : TEXCOORD1;
    502.                 float2 uv2 : TEXCOORD2;
    503.                 float4 posWorld : TEXCOORD3;
    504.             };
    505.             VertexOutput vert (VertexInput v) {
    506.                 VertexOutput o = (VertexOutput)0;
    507.                 o.uv0 = v.texcoord0;
    508.                 o.uv1 = v.texcoord1;
    509.                 o.uv2 = v.texcoord2;
    510.                 o.posWorld = mul(unity_ObjectToWorld, v.vertex);
    511.                 o.pos = UnityMetaVertexPosition(v.vertex, v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST );
    512.                 return o;
    513.             }
    514.             float4 frag(VertexOutput i) : SV_Target {
    515.                 float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
    516.                 UnityMetaInput o;
    517.                 UNITY_INITIALIZE_OUTPUT( UnityMetaInput, o );
    518.            
    519.                 o.Emission = 0;
    520.            
    521.                 float4 _LerpTex_var = tex2D(_LerpTex,TRANSFORM_TEX(i.uv0, _LerpTex));
    522.                 float4 _MainTex_var = tex2D(_MainTex,TRANSFORM_TEX(i.uv0, _MainTex));
    523.                 float3 diffColor = (lerp(_ColorWhite.rgb,_ColorBlack.rgb,_LerpTex_var.r)*_MainTex_var.rgb);
    524.                 float specularMonochrome;
    525.                 float3 specColor;
    526.                 float node_383 = 0.0;
    527.                 diffColor = DiffuseAndSpecularFromMetallic( diffColor, node_383, specColor, specularMonochrome );
    528.                 float roughness = 1.0 - node_383;
    529.                 o.Albedo = diffColor + specColor * roughness * roughness * 0.5;
    530.            
    531.                 return UnityMetaFragment( o );
    532.             }
    533.             ENDCG
    534.         }
    535.     }
    536.     FallBack "Diffuse"
    537.     CustomEditor "ShaderForgeMaterialInspector"
    538. }
     
    Last edited: Dec 5, 2016
  12. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,624
    Because it might not exist. If generic, off-the-shelf solutions could do everything that was ever needed then there'd be no further use for programmers.

    Modding tools isn't necessarily about achieving something that's otherwise unachievable. It's about building workflows that suit your project and scale in ways that you need to scale. If you're getting a programmer to spend time automating something that you could have done manually and only needed to do once then you're probably not making the best use of your resources. Similarly, if you repeatedly do something manually that a programmer could make your computer do for you then you're also probably not making the best use of your resources.
     
    Alverik, Martin_H and Ryiah like this.
  13. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    You do realize this is my point, right? Just how inadequate does the shader tool have to be before it becomes a value add to have the source? This is assuming at least that it's fit for purchase and can cover most use cases. Just how out there and wacky are people getting for a handful of fairly typical datatypes and fairly typical operations not to cover it? And they are doing this frequently enough that making one-offs by hand isn't cost effective?
     
    theANMATOR2b likes this.
  14. boxhallowed

    boxhallowed

    Joined:
    Mar 31, 2015
    Posts:
    513
    Guess what.



    I bought it.
     
  15. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,264
    Why would it need to be a matter of inadequacy? All it would take is for the author to cease development of it and for Unity to reach the point where the editor needs modifications to function properly. It has happened before by the way with one of the earliest visual shader editors. Strumpy's Shader Editor became broken starting with Unity 4.

    https://forum.unity3d.com/threads/strumpy-shader-editor-now-open-source.56180/
     
    angrypenguin and boxhallowed like this.
  16. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Nowhere near soon.

    IMHO the amplify one's output is actually modifiable and clean, and worth using (from the glance at it above).
     
    Alverik and Martin_H like this.
  17. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    I would tend to think of something broken and not supported as being pretty inadequate and not very fit for purchase. Just how much time is actually being saved if you've become the primary support for it. I'm sorry, but having source code in this case seems far more like a non-issue at best and a trap at worst.
     
  18. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,264
    Naturally I wouldn't recommend purchasing a dead asset but unless you're able to predict the future you have no way of knowing if an asset will continue to receive support after purchasing it.
     
    Alverik and angrypenguin like this.
  19. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,624
    "Adequate" and "inadequate" are pretty binary terms for something like this. For me something may well be "adequate" if it's a good starting point for me to do my own stuff on top of. Like, say, the Unity Editor. ;)

    It all comes down to how much time something saves. If I can save more time by using someone else's tool and modding it compared to either building my own or doing things manually then that's a win. It's off the table if you don't have the source, though.

    Even if I deem that something is "inadequate" for my specific needs, if it will take relatively little work to make it "adequate" then why start from scratch?
     
  20. djweinbaum

    djweinbaum

    Joined:
    Nov 3, 2013
    Posts:
    533
    @Ryiah and everyone under the impression that Amplify makes cleaner/shorter shader code: Consider that Amplify currently creates surface shaders, while SF creates its own shader. A surface shader is kind of like Unity's shader shorthand, which will be used to generate the actual shader. A basic surface shader can be 50 lines but its generated code is around 700, while an SF shader is around 400. I'm not recommending one over the other, I'm just saying comparing SF output to Amplify output is apples to oranges. I have found a basic PBR shader from SF to be a little faster than a basic Unity PBR surface shader.
     
  21. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,584
    In all honesty, if you can write your own shaders, there's no point in buying any of them. IF you can write your own shaders.
     
    Alverik and djweinbaum like this.
  22. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,035
    As I said before on similar topics:
    Anybody who have the skills to create a shader visually for sure has the skill to write it, the sintax couldn't be more simple since you should avoid most conditional code. The hard stuff is the math which you must know anyway even if you do it visually.
    Just take a simple basic shader and start tweaking it, you'll be amazed how simple it is.
    If you'll be relying on somebody else shader network, then there are plenty of free shaders around, so again I don't see the point.
     
    Billy4184 likes this.
  23. djweinbaum

    djweinbaum

    Joined:
    Nov 3, 2013
    Posts:
    533
    I've been using SF for years. Learned surface shaders a month or two ago and, agreed, I will never go back to node editor. Surface shaders already are Unity's "shader editor" solution and its pretty fast and easy. I can't tell you how many times I've hooked up the same crap over and over when I could have been writing my own shaders and using a cginclude. Wish I'd learned shaders years ago.
     
  24. boxhallowed

    boxhallowed

    Joined:
    Mar 31, 2015
    Posts:
    513
    I can write my own, but that's like saying, "If you know how to program, what's the point of syntax aids like auto indent?", it's a toy. Fun things are fun.
     
    recon0303 and Deleted User like this.
  25. djweinbaum

    djweinbaum

    Joined:
    Nov 3, 2013
    Posts:
    533
    I dunno. I think its more like saying "if you can program, what's the point of visual scripting?", and to that I say, none. Visual scripting is for people who don't know code scripting.
     
    Peter77 and neginfinity like this.
  26. boxhallowed

    boxhallowed

    Joined:
    Mar 31, 2015
    Posts:
    513
    Once again, I find myself disagreeing. I've been programming since I was 9, and during my time with Unreal I found myself banging out quick code with their Blueprint editor. If y'all don't want to use it, that's great, but I asked which one, not if I needed one at all. I bought Amplify and I'm pretty happy with it.
     
    Alverik and djweinbaum like this.
  27. Deleted User

    Deleted User

    Guest

    Yep gotta agree with @The-Britain, irrelevant of the language you still have to understand logical concepts to achieve said goal (if it's a proper VS system). For coders it's a great way to avoid boiler plate code for many game specific systems, it can streamline prototype's / development many times over. No matter how fast a coder you are, no matter how good you are, you couldn't physically type fast enough to create something like a camera / character controller in the time you could do it in BP's, never mind debugging etc.

    As for the rest it's an easy way to do simple tasks without having to understanding the finer points of languages like C++ (also stops people bothering coders every two minutes). With C# it does become slightly less relevant, but I'm going off topic now.

    The same applies to a decent material editor, it should exist to save you time / fit nicely into existing art pipelines. In UE I managed to whip up some very advanced terrain / particle / water / vertex paint materials with little effort. The dream would be to have a system in Unity on par (whether third party or not).

    From my experience the guys / gals at Amplify are great, awesome support and never let products get stale etc. It's early days, but I purchased the early version (even if I don't use it).. As I'm sure it will mature and be worth every $.
     
  28. Billy4184

    Billy4184

    Joined:
    Jul 7, 2014
    Posts:
    6,035
    Not saying a shader editor wouldn't necessarily be a good idea, but imo it really isn't as spooky as it looks to deal with shader code. You just have to understand that the graphics card is sort of a limited access device and the code interface has certain peculiarities.

    The examples on the Unity site are a good starting point. Pretty much once you're inside the vert method you can just do whatever you like with the incoming data.
     
    angrypenguin likes this.
  29. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    If you know exactly what you want, then the main benefit to an editor is it keeps an artist's eyes from melting. The real benefit I see is you can easily play with it. You see the results immediately, so you can go crazy trying anything and everything.
     
    Alverik and angrypenguin like this.
  30. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    It would be cooler if amplify reached out to other shader developers like RTP/Uber etc and got some integration going. It would increase the appeal of the product since mostly, it's not really that useful to me if I have something like Uber. Because Uber offers a lot more than I'd get making my own from scratch. As Uber is also based on standard shader, it's a possibility.

    I see the megasplat guy already jumped on board.
     
    Alverik and Martin_H like this.
  31. DaDarkDragon

    DaDarkDragon

    Joined:
    Jun 6, 2013
    Posts:
    115
    YES YES YES, I tried to do a few shader tutorials and i just couldn't seem to grasp it that well. That and i was always thinking that that there was always so much prep to do even for a basic custom shader, like declaring a variable in 2 different places just to use it, or just how specific some built in variables need to be used/placed to not get a magenta blob on screen.

    Amplify & Shader Forge just let me dick around without worrying too much about it. And i get to make some interesting effects, intentionally or not. even if i cant do all of them yet.
     
    Alverik and Ryiah like this.
  32. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,584
    It is worth remembering that you can actually write custom inspectors for materials that use your shaders. Meaning if you need some parameter to have a visual representation, chances are you can make this happen.

    The api for writing custom editors for materials is a bit verbose, but it is there and can be used.
     
    Billy4184 likes this.
  33. Martin_H

    Martin_H

    Joined:
    Jul 11, 2015
    Posts:
    4,436
    Is it possible to make a multipass shader use 2 passes from Shaders you make (and continue to tweak!) in Shaderforge by using usepass?
    https://docs.unity3d.com/Manual/SL-UsePass.html

    Maybe that would be a good way around some of the multipass limitations of shader editors in general?
     
  34. Deleted User

    Deleted User

    Guest

    Well you'd want all the stuff from Uber etc. provided in the mat editor, like UE4's "cheat" nodes / options. You can just drop in a POM node or check a tickbox for SSS, then it's just a matter of setting stuff like scatter amounts and translucency constant's..

    Without all that extra cool stuff they don't really add that much to the table. In reality you could just buy Uber and it'll cover most user case scenario's for most of the game. As for the rest, well again the asset store does seem to cover most of it..

    The only thing that's not easily accessible is a decent terrain shader for Unity's system, which is mainly down to the terrain system itself. Looking forward to that upgrade.!
     
  35. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Yeah it's just I need to tweak Uber, and I can't stand it's source frankly. I'm too stupid for all that.
     
  36. Deleted User

    Deleted User

    Guest

    Lol, AFAIK the guys at amplify were looking into adding all that Jazz.. It's early days for them. Something to keep an eye on maybe?
     
  37. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    They have added it, several 3rd parties have added support, like that megasplat guy. I'm just saying the responsibility at this point to encourage 3rd party support lies with Amplify. It's a gentle nudge.
     
  38. ChaosWWW

    ChaosWWW

    Joined:
    Nov 25, 2009
    Posts:
    470
    There's a lot of negativity going on regarding shader forge so I wanted to chime in a little bit (I own both).

    Right now I would say that Shader Forge is the better product. There's a lot of subtle things that contribute to this, but I'd say its the best graph based shader editor I've ever used. The usability is what makes it for me; it feels like there has been a lot of care put into the UX and as such as a user I can focus on my goals rather than interacting with the thing. Small things like having a preview attached to every node and having float values be displayed under mathematical operations helps a lot. Also, being around for longer does give it some advantages. There are more nodes and you can do a lot more with Shader Forge right now than with Amplify.

    That being said, I did purchase Amplify because it has the potential to de-throne Shader Forge, but it's definitely not there yet. One advantage to Amplify that was already pointed out is more editable shader code. However, this is only relevant if you need to edit shader code, which has been a rare desire for me with Shader Forge (currently, lack of texture arrays and GPU instancing being my only motivation to edit shader code). The main way Amplify is going to contend, I believe, is going to be through intergrations with 3rd party tools. Due to the open source I've already seen some 3rd party tools have integrations, and Amplify' Shader Editor's eventual integration with Amplify Texture will be a very juicy combo indeed.

    Especially since it's super cheap in beta, I think its a good investment to get Amplify's Shader Editor since it's for sure going to go up in value. However,t if you need a robust shader editing solution to solve problems you have right now, Shader Forge is the better product as it stands.
     
  39. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Thanks for the clarification, interesting points. In my case I need to get at the code. I need to take a pass later in dev on the slower shaders and clean those up. Especially some of the more exotic particle shaders I have in mind. These have to be fast for obvious reasons.
     
  40. Martin_H

    Martin_H

    Joined:
    Jul 11, 2015
    Posts:
    4,436
    Can you talk more about those? That sounds interesting.
     
  41. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Well it's just lit particles. Particle System in unity is upgraded so you get good tangents/normals so lighting is possible on them now. I was doing volume blood effects and nicer flow mapped smoke :) but I want them lit too.

    Other things are: I want my transparent stuff to cast decent shadows. I want them to use cutout for shadows, but dither mask based on alpha value of particle.

    Currently to do that, I just make a new standard shader and get coding. But it's slow going (as it's trial and error what works in Unity as trial and error is faster than finding non-existent documentation on what works) and something like amplify might speed things up. Problem is, I don't know if it supports passes for shadows and all that.

    Other things are vector flipbook stuff. I'd like to get into that so I can do decent explosions. I'd like to also experiment with particles being all drawn to a buffer that's say, 75% the size and then composite with depth my way for soft particles but also particles that feel more volumetric than they actually are, so instead of this binary in front of, or behind, I can test/blend against a sphere or other primitive shape.

    ...and for obvious reasons this stuff isn't too quick. So I need to make them quick :)
     
  42. SunnySunshine

    SunnySunshine

    Joined:
    May 18, 2009
    Posts:
    979
    Someone might've mentioned this already, but Shader Forge generates a fragment shader whereas Amplify generates a surface shader (which is then generated into a fragment shader by Unity). If you'd actually open the generated code of the amplify shader, it would probably be far longer than the Shader Forge generated one.

    As for the assets themselves - I have both and I prefer Shader Forge because each node gives a nice preview. Overall I prefer the Shader Forge workflow with Key + Mouse click for quick access to nodes. I don't do anything but prototype shaders in these tools though and I would recommend you actually learn how to write your own shaders. You'll have a lot more freedom that way and the shaders will perform better.

    I feel there's an undeserved fear of shaders that really doesn't make any sense. If you just give it some hours they will start making sense real quick if you're used to development. The Unity docs and surface shader system makes it really easy to get into.
     
  43. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Not for non programmers :p and I'd rather be coding the game than coding shaders which I feel is probably best left to the artists.
     
    Alverik and Martin_H like this.
  44. Player7

    Player7

    Joined:
    Oct 21, 2015
    Posts:
    1,533
    His new addon and usage of amplify with integrating some extra nodes is what got me interested in checking it out.

    I agree the problem with third party solutions, unlike people making enhancements for a native engine feature like I dunno the poor state of Unity terrain and its default terrain shader is at least it progresses the state and features for that native feature a lot more. While the addons that come in to completely fill missing gaps, are less likely to get other developers making addons extending that third partly solution, or tutorials for etc.. it becomes even rarer, or fractured with multiple addons doing similar things splitting the user/knowledge base up more.

    Its not very 'unifying' really

    "I have both and I prefer Shader Forge because each node gives a nice preview."

    yup one area I am hoping amplify implements support for in a later build soon.
     
    Alverik and Martin_H like this.
  45. boxhallowed

    boxhallowed

    Joined:
    Mar 31, 2015
    Posts:
    513
    This may be a bit conspiracy based, but I really believe Unity leaves out essential features so people need to buy them on the asset store. Thus offsetting development cost and padding their pockets with asset store royalty. At the cost of a complete product I'm afraid. Just look at ProGrids. There is no reason in the world that shouldn't be implemented directly.

    Don't get me wrong, I'm not complaining. I mean they give us Unity for free, so I have no right. Just a thought.
     
    Alverik likes this.
  46. Voronoi

    Voronoi

    Joined:
    Jul 2, 2012
    Posts:
    590
    I'm an artist and I love to code, mainly in C#. Game code makes perfect sense to me. Shaders are really hard for me to grasp. Maybe it's the fact that my code editor doesn't use intellisense on shaders, or the documentation is not easily searchable. To me, shader code logic just escapes me.

    I have looked at the Unity examples, and while it seems like they are good, I just can't wrap my head around the concepts. Does anyone have a recommendation for a really good set of tutorials to learn to write shaders?

    TBH, there seems to be a lot of assumptions about prior knowledge when I start reading about shaders. For example surface vs. fragment shaders vs. vertex. CG or compute, what? I don't really understand the difference and have not found a good resource to explain the differences and why as an artist I should use one over the other. It seems related to video cards and such, but as an artist I am really most interested in the visual reproduction on my current computer. Once I understand that, I could see starting to make the shaders cross-platform and/or performant.

    Right now, I feel like my skills just aren't there and thus the need for tools like these.
     
    Martin_H likes this.
  47. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Utter nonsense. I've spoken with staff for years, it's nonsense. No business would be able to survive doing that unless they want to earn pocket change and suffer a product that falls behind the competition. Currently, Unity's features by large beat the competition*. And it takes a long time to make that stuff.

    *where competition is other engines and asset store

    Regarding your comment about progrids...You can't assume your project needs are the same, therefore Unity doesn't assume either, so the idea of the editor is it's a blank slate that should be extended to exactly match the game you're working on.

    Having said that, it could use a great built in grid system someday. I'm sure they will, they just haven't got around to it.

    The reason your conspiracy theory falls apart big time is that Unity's cut from progrids probably would not be enough to pay for staff coffee for a single day.
     
    Ryiah and Martin_H like this.
  48. SunnySunshine

    SunnySunshine

    Joined:
    May 18, 2009
    Posts:
    979
    I suppose you're right, but to me shaders have always been something quite technical, and you need to know what you're doing regardless if you're programming visually or in code. Because that's the thing - even though you're using a visual node system, you're still programming.

    This whole node based visual authoring trend is fascinating, because it's as people think you don't need to know anything in order to use them. I don't know, is that the case? Can an artist really pick something like this up without any prior knowledge? To me it seems like the step from a system like Shader Froge to actually coding a shader is minimal, but then again I'm a developer so maybe I simply can't see the difficulty.

    I think you're over-analyzing it. Game engine development is hard and takes a really long time, and right now their focus is on more important things.

    In a way I suppose you're right though. Since the market has an ability to adjust itself to accommodate demand, Unity might focus mainly on features where demand is rather than where demand has been satisfied thanks to the asset store, but not in the way you suggest. I don't know if I'm making any sense. :)

    Can't remember what I used to get into it. But here's a short overview:

    A shader usually consists of two parts:

    Vertex part

    This takes some vertex data as input (vertex location in 3D space, vertex color, UVs etc). Here you can, if you want to, alter the location, if, for example, you want to extrude the vertices. Usually, you'll just transform the 3D point into the camera's 2D projection space.

    A vertex function is also responsible for feeding the fragment shader with data.

    Fragment part

    This function takes the vertex output as input, and is doing its operations per-pixel. I.e., for each pixel on a face on an object, this function will run. Here you'll usually look up values in textures, using the vertex input (UVs), and do lighting calculations.

    Then we have surface shaders...

    Luckily, you don't need to think about all this, because Unity has made it easy with surface shaders. A surface shader is a more simple form of shader that is compiled into a fragment shader. All you need to do in a surface shader is feed it's different outputs (albedo, normal, emission, occlusion etc) with data (just like you would in a visual node based system). Then Unity will do all the lighting calculations and vertex stuff for you (unless you want to do it yourself, which they also make possible with certain macros).

    CG is just a shader language I think, just like GLSL and HLSL are languages.

    Compute shaders are something completely different. Like a normal shader, they're also programs that you run on the GPU, but more general purpose. Usually you'll feed a compute shader with some data, which it then can compute very fast using the GPU's parallell computing capabilities. It doesn't work with algorithms where each iteration depends on the previous one, but it's excellent for tasks where you just need to do a lot of something.
     
  49. Martin_H

    Martin_H

    Joined:
    Jul 11, 2015
    Posts:
    4,436
    That all sounds super interesting! Please ping me if you post about it somewhere.
    We've been talking here about explosions/smoke recently, in case you missed the thread:
    https://forum.unity3d.com/threads/mushroom-cloud-proper-way-of-doing.440462/

    I'm still searching for better explosion solutions myself.
     
  50. boxhallowed

    boxhallowed

    Joined:
    Mar 31, 2015
    Posts:
    513
    On the other hand, what money is there to be made by then adding that needed feature when people are buying it?

    I guess one of the main attraction I had to Unity was the fact it was blank. I remember having to remove all Unreal code from UDK just start up a blank project haha.

    Back on point. I am enjoying Amplify so far, and its feature set is great. I am still getting used to shaders in general, but it's really sped up my workflow by showing me what options are available. I wish it had context sensitive menus, but a minor complaint.