和Keyle一起学ShaderForge – Create Base Shader

和Keyle一起学ShaderForge – Create Base Shader

1.本篇让我们一起动手试试使用ShaderForge创建一个基本的Shader

2.介绍Shader文件Main函数中公开的节点

1.使用ShaderForge创建一个基本的Shader

和Keyle一起学ShaderForge – Create Base Shader

效果如下左1为 node_1311 Color效果为纯白下的 ,左2为 node_1311 Color效果为红色RGB(255,0,0)

和Keyle一起学ShaderForge – Create Base Shader和Keyle一起学ShaderForge – Create Base Shader

生成代码如下,在Properties 属性中增加了_keyleTexture 贴图,_TextureNormal 法线贴图 ,_node_1311 Color ,在两个对应的Pass块中使用了在Propertity中定义的三个变量。在frag(片段)函数中计算的叠加的色值,标黄区域为ShadeForge中计算Multiply的代码。

// Shader created with Shader Forge v1.04 
// Shader Forge (c) Neat Corporation / Joachim Holmer - http://www.acegikmo.com/shaderforge/
// Note: Manually altering this data may prevent you from opening it in Shader Forge
/*SF_DATA;ver:1.04;sub:START;pass:START;ps:flbk:,lico:1,lgpr:1,nrmq:1,limd:1,uamb:True,mssp:True,lmpd:False,lprd:False,rprd:False,enco:False,frtr:True,vitr:True,dbil:False,rmgx:True,rpth:0,hqsc:True,hqlp:False,tesm:0,blpr:0,bsrc:0,bdst:1,culm:0,dpts:2,wrdp:True,dith:2,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,ofsf:0,ofsu:0,f2p0:False;n:type:ShaderForge.SFN_Final,id:8894,x:32590,y:32620,varname:node_8894,prsc:2|diff-6495-OUT,normal-6723-RGB;n:type:ShaderForge.SFN_Tex2d,id:2068,x:32175,y:32518,ptovrint:False,ptlb:keyleTexture,ptin:_keyleTexture,cmnt:添加一个贴图,varname:node_2068,prsc:2,tex:3da1dd3705158564c97ec7cf99c87747,ntxv:0,isnm:False;n:type:ShaderForge.SFN_Tex2d,id:6723,x:32179,y:32883,ptovrint:False,ptlb:TextureNormal,ptin:_TextureNormal,cmnt:法线贴图,varname:node_6723,prsc:2,tex:105d97327ec4c5146bb18706fffed5cd,ntxv:3,isnm:True;n:type:ShaderForge.SFN_Multiply,id:6495,x:32378,y:32587,varname:node_6495,prsc:2|A-2068-RGB,B-1311-RGB;n:type:ShaderForge.SFN_Color,id:1311,x:32056,y:32708,ptovrint:False,ptlb:node_1311,ptin:_node_1311,cmnt:Mix Color,varname:node_1311,prsc:2,glob:False,c1:1,c2:1,c3:1,c4:1;proporder:2068-6723-1311;pass:END;sub:END;*/

Shader "Custom/NewShader" {
    Properties {
        _keyleTexture ("keyleTexture", 2D) = "white" {}
        _TextureNormal ("TextureNormal", 2D) = "bump" {}
        _node_1311 ("node_1311", Color) = (1,1,1,1)
    }
    SubShader {
        Tags {
            "RenderType"="Opaque"
        }
        LOD 200
        Pass {
            Name "ForwardBase"
            Tags {
                "LightMode"="ForwardBase"
            }
            
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #define UNITY_PASS_FORWARDBASE
            #include "UnityCG.cginc"
            #include "AutoLight.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma exclude_renderers xbox360 ps3 flash d3d11_9x 
            #pragma target 3.0
            uniform float4 _LightColor0;
            uniform sampler2D _keyleTexture; uniform float4 _keyleTexture_ST;
            uniform sampler2D _TextureNormal; uniform float4 _TextureNormal_ST;
            uniform float4 _node_1311;
            struct VertexInput {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 tangent : TANGENT;
                float2 texcoord0 : TEXCOORD0;
            };
            struct VertexOutput {
                float4 pos : SV_POSITION;
                float2 uv0 : TEXCOORD0;
                float4 posWorld : TEXCOORD1;
                float3 normalDir : TEXCOORD2;
                float3 tangentDir : TEXCOORD3;
                float3 binormalDir : TEXCOORD4;
                LIGHTING_COORDS(5,6)
            };
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                o.uv0 = v.texcoord0;
                o.normalDir = mul(_Object2World, float4(v.normal,0)).xyz;
                o.tangentDir = normalize( mul( _Object2World, float4( v.tangent.xyz, 0.0 ) ).xyz );
                o.binormalDir = normalize(cross(o.normalDir, o.tangentDir) * v.tangent.w);
                o.posWorld = mul(_Object2World, v.vertex);
                float3 lightColor = _LightColor0.rgb;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                TRANSFER_VERTEX_TO_FRAGMENT(o)
                return o;
            }
            fixed4 frag(VertexOutput i) : COLOR {
                i.normalDir = normalize(i.normalDir);
                float3x3 tangentTransform = float3x3( i.tangentDir, i.binormalDir, i.normalDir);
/////// Vectors:
                float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
                float3 _TextureNormal_var = UnpackNormal(tex2D(_TextureNormal,TRANSFORM_TEX(i.uv0, _TextureNormal))); // 法线贴图
                float3 normalLocal = _TextureNormal_var.rgb;
                float3 normalDirection = normalize(mul( normalLocal, tangentTransform )); // Perturbed normals
                float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
                float3 lightColor = _LightColor0.rgb;
////// Lighting:
                float attenuation = LIGHT_ATTENUATION(i);
                float3 attenColor = attenuation * _LightColor0.xyz;
/////// Diffuse:
                float NdotL = max(0.0,dot( normalDirection, lightDirection ));
                float3 indirectDiffuse = float3(0,0,0);
                float3 directDiffuse = max( 0.0, NdotL) * attenColor;
                indirectDiffuse += UNITY_LIGHTMODEL_AMBIENT.rgb; // Ambient Light
                float4 _keyleTexture_var = tex2D(_keyleTexture,TRANSFORM_TEX(i.uv0, _keyleTexture)); // 添加一个贴图
                  float3 diffuse = (directDiffuse + indirectDiffuse) * (_keyleTexture_var.rgb*_node_1311.rgb);
/// Final Color:
                float3 finalColor = diffuse;
                return fixed4(finalColor,1);
            }
            ENDCG
        }
        Pass {
            Name "ForwardAdd"
            Tags {
                "LightMode"="ForwardAdd"
            }
            Blend One One
            
            
            Fog { Color (0,0,0,0) }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #define UNITY_PASS_FORWARDADD
            #include "UnityCG.cginc"
            #include "AutoLight.cginc"
            #pragma multi_compile_fwdadd_fullshadows
            #pragma exclude_renderers xbox360 ps3 flash d3d11_9x 
            #pragma target 3.0
            uniform float4 _LightColor0;
            uniform sampler2D _keyleTexture; uniform float4 _keyleTexture_ST;
            uniform sampler2D _TextureNormal; uniform float4 _TextureNormal_ST;
            uniform float4 _node_1311;
            struct VertexInput {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 tangent : TANGENT;
                float2 texcoord0 : TEXCOORD0;
            };
            struct VertexOutput {
                float4 pos : SV_POSITION;
                float2 uv0 : TEXCOORD0;
                float4 posWorld : TEXCOORD1;
                float3 normalDir : TEXCOORD2;
                float3 tangentDir : TEXCOORD3;
                float3 binormalDir : TEXCOORD4;
                LIGHTING_COORDS(5,6)
            };
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                o.uv0 = v.texcoord0;
                o.normalDir = mul(_Object2World, float4(v.normal,0)).xyz;
                o.tangentDir = normalize( mul( _Object2World, float4( v.tangent.xyz, 0.0 ) ).xyz );
                o.binormalDir = normalize(cross(o.normalDir, o.tangentDir) * v.tangent.w);
                o.posWorld = mul(_Object2World, v.vertex);
                float3 lightColor = _LightColor0.rgb;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                TRANSFER_VERTEX_TO_FRAGMENT(o)
                return o;
            }
            fixed4 frag(VertexOutput i) : COLOR {
                i.normalDir = normalize(i.normalDir);
                float3x3 tangentTransform = float3x3( i.tangentDir, i.binormalDir, i.normalDir);
/////// Vectors:
                float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
                float3 _TextureNormal_var = UnpackNormal(tex2D(_TextureNormal,TRANSFORM_TEX(i.uv0, _TextureNormal))); // 法线贴图
                float3 normalLocal = _TextureNormal_var.rgb;
                float3 normalDirection = normalize(mul( normalLocal, tangentTransform )); // Perturbed normals
                float3 lightDirection = normalize(lerp(_WorldSpaceLightPos0.xyz, _WorldSpaceLightPos0.xyz - i.posWorld.xyz,_WorldSpaceLightPos0.w));
                float3 lightColor = _LightColor0.rgb;
////// Lighting:
                float attenuation = LIGHT_ATTENUATION(i);
                float3 attenColor = attenuation * _LightColor0.xyz;
/////// Diffuse:
                float NdotL = max(0.0,dot( normalDirection, lightDirection ));
                float3 directDiffuse = max( 0.0, NdotL) * attenColor;
                float4 _keyleTexture_var = tex2D(_keyleTexture,TRANSFORM_TEX(i.uv0, _keyleTexture)); // 添加一个贴图
                float3 diffuse = directDiffuse * (_keyleTexture_var.rgb*_node_1311.rgb);
/// Final Color:
                float3 finalColor = diffuse;
                return fixed4(finalColor * 1,0);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
    CustomEditor "ShaderForgeMaterialInspector"
}

2.Main中的公开节点

和Keyle一起学ShaderForge – Create Base Shader和Keyle一起学ShaderForge – Create Base ShaderDiffuse(漫反射)

这是我们着色器的主色调,漫反射的颜色来源于光,上图中阴影部分为入射光线的衰弱区域

和Keyle一起学ShaderForge – Create Base ShaderDiffuse Power(漫反射的幂)

这是光线衰弱的幂次方,使用大于1的幂时可以用于模拟金属的外观

和Keyle一起学ShaderForge – Create Base ShaderSpecular(镜面反射)

这是你的Shader镜面高光的颜色,值越高颜色越艳丽,当物体为黑色的时候不受Specular影响。

和Keyle一起学ShaderForge – Create Base ShaderGloss(光泽度)

当Gloss数值越高的时候你的物体表面看起来越有光泽反之亦然。

和Keyle一起学ShaderForge – Create Base ShaderNormal(法线贴图)

这个我就不解释了,法线贴图记录了贴图的空间信息,使你的图看起来凹凸有致,谁帮我画一个美女的法线贴图?

和Keyle一起学ShaderForge – Create Base ShaderEmission(发散)

顾名思义,反射出来的光的强度

和Keyle一起学ShaderForge – Create Base ShaderTransmission(这个词我觉得可以折中一些翻译比如翻译成 “通透性”)

举个例子,你是一个玻璃(或者是棵植物),我在你背后点一盏灯,你正前方的人能透过你看到你后面的光,如果你的杂质越多(改变Transmission值),那么我能透过你看到的光就越弱

和Keyle一起学ShaderForge – Create Base ShaderLight Wrapping(四周光/环绕光)

控制光的角度的衰弱偏移量,获得类似与地表散射光线的效果,多用于光滑的物体,入人类的皮肤

和Keyle一起学ShaderForge – Create Base ShaderDiffuse Ambient Light(环境光漫反射)

它将光线添加到你的着色器,受漫反射影响(Diffuse),多用于基于图像的照明

和Keyle一起学ShaderForge – Create Base ShaderSpecular Ambient Light(镜面反射环境光)

和Diffuse Ambient Light类似,多了一个镜面反射效果

和Keyle一起学ShaderForge – Create Base ShaderDiffuse Ambient Occlusion(漫反射环境光遮蔽)

顾名思义,用来抑制Diffuse散发出来的光

和Keyle一起学ShaderForge – Create Base ShaderSpecular Ambient Occlusion(镜面反射环境光遮蔽)

如上,为了抑制镜面反射出来的光

和Keyle一起学ShaderForge – Create Base ShaderCustom Lighting(用户自定义光)

允许用户自定义照明行为

和Keyle一起学ShaderForge – Create Base ShaderAlpha(透明通道)

这个就不多说了,如果不知道这个可以去撞豆腐了

和Keyle一起学ShaderForge – Create Base ShaderAlpha Clip(透明通道裁切)

顾名思义,裁切效果

和Keyle一起学ShaderForge – Create Base ShaderRefraction(折射)

折射背景元素使屏幕空间的UV偏移

和Keyle一起学ShaderForge – Create Base ShaderOutline Width(描边宽度)

在网格边缘偏移处加描边并且控制其宽度

和Keyle一起学ShaderForge – Create Base ShaderOutline Color(描边颜色)

和Keyle一起学ShaderForge – Create Base ShaderVertex Offset(顶点偏移)

这里可以用于动画着色器,随着Time函数变化,改变Vertex Offset偏移

和Keyle一起学ShaderForge – Create Base ShaderDX11 Displacement(DX11位移)

在 DirectX 11规范  下的位移,不能再Unity里用

和Keyle一起学ShaderForge – Create Base ShaderDX11 Tessellation(DX11 细分曲面技术)

Tessellation细分曲面技术是AMD(ATI)常年研发多代的技术,经过多年发展最终被采纳成为DX11的一项关键技术,因此历来都是宣传重点。和光线追踪不同,现在的光栅化图形渲染技术的核心是绘制大量三角形来组成3D模型,而Tessellation技术就是利用GPU硬件加速,将现有3D模型的三角形拆分得更细小、更细致,也就是大大增加三角形数量,使得渲染对象的表面和边缘更平滑、更精细。

本章为了降低操作的复杂性只选用了一个计算函数 Multiply ,在ShaderForge中右键arithmetic中可以找到,可以通过右侧边快捷属性栏中可找到,祝大家学习愉快!