[Unity Shader编程之]自定义双面材质(doubleside material)一

 

Unity内置的Shader,都是单面效果,想必导入Mesh的同学都碰到过这样的痛苦,布料飘起的背面部分看起来是空气,汽车透过车窗看到是路面…各种蛋疼。
有些文章教导大家 把模型做出厚度来吧,这种做法实在太那个啥了……

其实用改写Shader的方法可以很方便的实现双面材质。
Unity里有3种Shader方式:
1.Fixed Function Shaders 
2.Vertex and Fragment Shaders
3. Surface Shaders
关于这部分的详细介绍,请参考官方的教程。
这三种方式里,都可以通过直接在Shader代码头部添加一个Cull off 语句,实现强制双面渲染。
但是直接用Cull off的方式 有个重大的缺陷,这材质从两面看无论贴图、颜色、反光、照明情况,都是一模一样的,这并不符合大多数实际情况的常识。
在第1和第2种Shader里,是可以通过在一个渲染子程序里用两个渲染Pass来实现双面不同效果的,这部分网上的资料也很多,写起来也很简单直接。

这里主要讨论的是第三种也是最常用的Surface Shader的双面不同效果的实现。
Surface Shader是不能写在Pass里的,所以要实现它的双面不同效果就要用其他变通的办法。

首先去Unity官方网站下载一个内置Shader的代码包,链接如下:
http://unity3d.com/download_unity/builtin_shaders.zip 
打开后看见一堆.shader文件,可以用任何文本编辑器打开。可以看见系统内建的Shader基本都是Surface方式。
这里随便打开一个Normal-BumpSpec.Shader 这是普通的高光-凹凸贴图材质


Shader "Bumped Specular" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
_Shininess ("Shininess", Range (0.03, 1)) = 0.078125
_MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 400

CGPROGRAM
#pragma surface surf BlinnPhong

sampler2D _MainTex;
sampler2D _BumpMap;
fixed4 _Color;
half _Shininess;

struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
};

void surf (Input IN, inout SurfaceOutput o) {
fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = tex.rgb * _Color.rgb;
o.Gloss = tex.a;
o.Alpha = tex.a * _Color.a;
o.Specular = _Shininess;
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
}
ENDCG
}
FallBack "Specular"
}

简单解说一下几个关键行:
第一行Shader “Bumped Specular” 指定了这个shader出现在Unity系统Shader菜单里的名字,如果要修改系统内建Shader的源代码,最好把这个名字改掉,否则和系统内建Shader重名啦。我是这样写的: Shader “Hog’s shaders/BumpSpec_Twoside” ,这个shader会出现在Hog’s shaders组里,系统会自动完成这个加载。
第二行Properties后面的一组以下划线开头的变量表示了这个渲染器需要设置的参数。对于一个高光-凹凸材质来说,需要材质颜色、反光颜色、反光率、材质贴图和法线贴图,这5个变量就对应这5个东西啦,详细请参考系统手册。
在第11行LOD 400 后面加上一行:Cull off,这个材质就会自动双面渲染了 Cull off表示双面都渲染,不写默认是Cull back,不渲染背面。你也可以写上Cull front,不渲染正面。
改完这行 ,把第一行改成你希望的名字,把这个shader文件拷贝到工程的assets目录底下,系统就能自动加载啦。
效果如图:
双面贴图

双面是双面了,但是哪有两面是一样亮同样高光区域的….,全透光的砖墙,这种双面很少会用到吧。
如何做到双面不同效果呢?

我们在将下篇文章《[Unity Shader编程之]自定义双面材质(doubleside material)二》进行介绍!

本篇unity3d教程到此结束,下篇我们再会!