Unityshader实例02:Xray材质

需要实现的效果大概如下图所示

原理及思路

由图大概可知道X射线效果是中间很透明边缘比较亮的渐变效果,因此实现这种效果的话需要使用边缘光效果。

正常来说,物体法线与视线(从顶点至相机的方向)角度越一致,就越是能被玩家看见的中间。而边缘一般与法线垂直。由点乘即可计算轮廓光。half rim = 1.0 – saturate(dot (normalize(IN.viewDir), o.Normal));

shader代码实现

VF版本代码01:

Shader "PengLu/XRaySimpleVF" {Properties {_RimColor("RimColor",Color) = (1,1,0,1)_RimPower ("Rim Power", Range(0.1,8.0)) = 3.0}SubShader {Tags { "Queue"="Transparent" "RenderType"="Opaque" }LOD 200Pass{Blend SrcAlpha OneZWrite offLighting offCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"float4 _RimColor;float _RimPower;struct appdata_t {float4 vertex : POSITION;float2 texcoord : TEXCOORD0;float4 color:COLOR;float4 normal:NORMAL;};struct v2f {float4 pos : SV_POSITION;float4color:COLOR;} ;v2f vert (appdata_t v){v2f o;o.pos = mul(UNITY_MATRIX_MVP,v.vertex);float3 viewDir = normalize(ObjSpaceViewDir(v.vertex));float rim = 1 – saturate(dot(viewDir,v.normal ));o.color = _RimColor*pow(rim,_RimPower);return o;}float4 frag (v2f i) : COLOR{return i.color;}ENDCG}} FallBack "Diffuse"}

VF版本代码01效果:

VF版本代码02:法线贴图Shader "PengLu/XRayBumpVF"{Properties {_BumpMap ("Normalmap", 2D) = "bump" {}_RimColor("RimColor",Color) = (1,1,0,1)_RimPower ("Rim Power", Range(0.1,8)) = 3.0}SubShader {Tags { "Queue"="Transparent" "RenderType"="Opaque" }LOD 200Pass{Blend SrcAlpha OneZWrite offLighting offCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"float4 _RimColor;sampler2D _BumpMap;float _RimPower;float4 _BumpMap_ST;struct v2f {float4 pos : SV_POSITION;float2 uv : TEXCOORD0;float3 viewDir:TEXCOORD1;float3 tangent:TEXCOORD2;float3 binormal:TEXCOORD3;float3 normal:TEXCOORD4;} ;v2f vert (appdata_full v){v2f o;o.pos = mul(UNITY_MATRIX_MVP,v.vertex);o.uv = TRANSFORM_TEX( v.texcoord, _BumpMap );o.tangent=v.tangent.xyz;o.binormal=cross(v.normal,v.tangent)*v.tangent.w;o.normal=v.normal;o.viewDir = normalize(ObjSpaceViewDir(v.vertex));return o;}float4 frag (v2f i) : COLOR{float3x3 rotation=float3x3 (i.tangent.xyz,i.binormal,i.normal);//float4 packedN=tex2D(_BumpMap,i.uv);//float3 N=float3(2.0*packedN.wy-1,1.0);//N.z=sqrt(1-N.x*N.x-N.y*N.y);float3 N = UnpackNormal(tex2D(_BumpMap,i.uv));N=normalize(mul(N,rotation));//把从贴图中得到的法线转换到世界坐标中float rim=1 – saturate(dot(i.viewDir,N));float4 c=_RimColor*pow(rim,_RimPower);return c;}ENDCG}} FallBack "Diffuse"}VF版本代码02效果:

PS:fragment中使用了Unity定义在UnityCG.cginc中的函数UnpackNormal,下面是这个函数的原型,多了对移动平台RGB法线贴图的支持

inline fixed3 UnpackNormal(fixed4 packednormal){#if defined (SHADER_API_GLES) && defined(SHADER_API_MOBILE)return packednormal.xyz*2-1;#elsefixed3 normal;normal.xy=packednormal.wy*2-1;normal.z = sqrt(1-normal.x*normal.x-normal.y*normal.y);return normal;#endif}

Surf版本代码03:

Shader "PengLu/XRaySimpleSurf"{Properties {_RimColor("RimColor",Color) = (1,1,0,1)_RimPower ("Rim Power", Range(0.1,8)) = 3.0}SubShader {Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}LOD 200CGPROGRAM#pragma surface surf Lambert alpha:blend#include "UnityCG.cginc"float4 _RimColor;float _RimPower;struct Input {float3 viewDir;};void surf (Input IN, inout SurfaceOutput o) {half rim = 1.0 – saturate(dot (normalize(IN.viewDir), o.Normal));float4 c=_RimColor * pow (rim, _RimPower);o.Alpha=c.a;o.Emission =c.rgb*2; }ENDCG} FallBack "PengLu/XRaySimpleVF"}Surf版本代码03效果:

回首往事,日子里竟全是斑澜的光影,

Unityshader实例02:Xray材质

相关文章:

你感兴趣的文章:

标签云: