1.本篇让我们一起动手试试使用ShaderForge创建一个基本的Shader
2.介绍Shader文件Main函数中公开的节点
1.使用ShaderForge创建一个基本的Shader
效果如下左1为 node_1311 Color效果为纯白下的 ,左2为 node_1311 Color效果为红色RGB(255,0,0)
生成代码如下,在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中的公开节点
Diffuse(漫反射)
这是我们着色器的主色调,漫反射的颜色来源于光,上图中阴影部分为入射光线的衰弱区域
Diffuse Power(漫反射的幂)
这是光线衰弱的幂次方,使用大于1的幂时可以用于模拟金属的外观
Specular(镜面反射)
这是你的Shader镜面高光的颜色,值越高颜色越艳丽,当物体为黑色的时候不受Specular影响。
Gloss(光泽度)
当Gloss数值越高的时候你的物体表面看起来越有光泽反之亦然。
Normal(法线贴图)
这个我就不解释了,法线贴图记录了贴图的空间信息,使你的图看起来凹凸有致,谁帮我画一个美女的法线贴图?
Emission(发散)
顾名思义,反射出来的光的强度
Transmission(这个词我觉得可以折中一些翻译比如翻译成 “通透性”)
举个例子,你是一个玻璃(或者是棵植物),我在你背后点一盏灯,你正前方的人能透过你看到你后面的光,如果你的杂质越多(改变Transmission值),那么我能透过你看到的光就越弱
Light Wrapping(四周光/环绕光)
控制光的角度的衰弱偏移量,获得类似与地表散射光线的效果,多用于光滑的物体,入人类的皮肤
Diffuse Ambient Light(环境光漫反射)
它将光线添加到你的着色器,受漫反射影响(Diffuse),多用于基于图像的照明
Specular Ambient Light(镜面反射环境光)
和Diffuse Ambient Light类似,多了一个镜面反射效果
Diffuse Ambient Occlusion(漫反射环境光遮蔽)
顾名思义,用来抑制Diffuse散发出来的光
Specular Ambient Occlusion(镜面反射环境光遮蔽)
如上,为了抑制镜面反射出来的光
Custom Lighting(用户自定义光)
允许用户自定义照明行为
Alpha(透明通道)
这个就不多说了,如果不知道这个可以去撞豆腐了
Alpha Clip(透明通道裁切)
顾名思义,裁切效果
Refraction(折射)
折射背景元素使屏幕空间的UV偏移
Outline Width(描边宽度)
在网格边缘偏移处加描边并且控制其宽度
Outline Color(描边颜色)
Vertex Offset(顶点偏移)
这里可以用于动画着色器,随着Time函数变化,改变Vertex Offset偏移
DX11 Displacement(DX11位移)
在 DirectX 11规范 下的位移,不能再Unity里用
DX11 Tessellation(DX11 细分曲面技术)
Tessellation细分曲面技术是AMD(ATI)常年研发多代的技术,经过多年发展最终被采纳成为DX11的一项关键技术,因此历来都是宣传重点。和光线追踪不同,现在的光栅化图形渲染技术的核心是绘制大量三角形来组成3D模型,而Tessellation技术就是利用GPU硬件加速,将现有3D模型的三角形拆分得更细小、更细致,也就是大大增加三角形数量,使得渲染对象的表面和边缘更平滑、更精细。
本章为了降低操作的复杂性只选用了一个计算函数 Multiply ,在ShaderForge中右键arithmetic中可以找到,可以通过右侧边快捷属性栏中可找到,祝大家学习愉快!