目录
一、前言
二、“渲染两次”
三、本次成品介绍
四、第一次渲染代码
五、第二次渲染代码
六、截止目前的所有代码
七、调整代码
八、总结
一、前言
之前一直讲的shader文件中,都只写了一次CG代码。
为了大家对这部分的整体理解,我们这次渲染两次。
二、“渲染两次”
这个词是我造的~不是定义。
什么叫渲染两次?
渲染就是画画的意思,渲染两次就是画两次。这里用画画举例。
第一次画画。(如图1所示)

这里如果用文字描述一下,就是画了一个绿色的三角形。
第二次画画。(如图2所示)

如果用语言形容就是,在中间画了一个橘黄色的圆形。
所以我们一套结构CG结构就是画了一幅画。(如图3所示)
不用太在意具体写的什么代码,主要注意一些标志
CGPROGRAM前面是一些准备工作,像之前的模版写入,深度写入之类的。
ENDCG就是结束了绘制
中间就是一些绘制过程,引入一些材料。
这个全过程就是一次画画的全过程。

渲染两次的意思是,我可以在一个shader文件中写两套这个东西。
三、本次成品介绍
我们这次先画一个模型的黑影,但是这个黑影要比模型本身大一点。这个做法参考上节课的代码。
Unity | Shader基础知识(第二十一集:应用-怪兽膨胀、顶点着色器和表面着色器合并)_unity 顶点膨胀shader-CSDN博客
然后再正常把模型渲染上去,就可以给模型做一个阴影或者说边框。(如图4所示)

四、第一次渲染代码
我们第一次先画一个模型的黑影(如图4所示),
备注:模型还是用上节课的模型。代码还是用的上节课的思路。

Properties{//模型的贴图_MainTex ("Texture", 2D) = "white" {}//边框的大小(膨胀的大了,边框就大,反之就小)_Outline ("Outline Width", Range(0.002,0.1)) = 0.005//边框的颜色,我们要做黑影,所以就先来个黑色_OutlineColor ("Outline Color", Color) = (0,0,0,1)}SubShader{CGPROGRAM//引用,同上一集#pragma surface surf Lambert vertex:vert//承接上面素材,略sampler2D _MainTex;float4 _OutlineColor;float _Outline;void vert(inout appdata_full v){//让原本的顶点在法线的方向上增加一点位置,这样影子就会变大v.vertex.xyz += v.normal * _Outline;}//其实目前代码里都没用到,但因为用了表面着色器,必须写struct Input{float2 uv_MainTex;};void surf(Input IN,inout SurfaceOutput o){//我们把颜色直接给到自发光//备注:这里给到贴图也是可以的,但自发光要更亮一点,可以自己试o.Emission = _OutlineColor.rgb;}ENDCG}
这样我们第一次渲染就画好了。
五、第二次渲染代码
到了ENDCG以后,就是这次画已经画完了,接下来我们再画模型真正的样子。
第二次不需要膨胀,所以顶点那部分就不用加了,直接把颜色上上去。这部分讲太多遍了,就不详解了。
CGPROGRAM#pragma surface surf Lambert struct Input{float2 uv_MainTex;};sampler2D _MainTex;void surf(Input IN, inout SurfaceOutput o){o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;}ENDCG}
六、截止目前的所有代码
Shader "Unlit/019"
{Properties{_MainTex ("Texture", 2D) = "white" {}_Outline ("Outline Width", Range(0.002,0.1)) = 0.005_OutlineColor ("Outline Color", Color) = (0,0,0,1)}SubShader{//第一套渲染-------------------------------------CGPROGRAM#pragma surface surf Lambert vertex:vertstruct Input{float2 uv_MainTex;};sampler2D _MainTex;float4 _OutlineColor;float _Outline;void vert(inout appdata_full v){v.vertex.xyz += v.normal * _Outline;}void surf(Input IN,inout SurfaceOutput o){o.Emission = _OutlineColor.rgb;}ENDCG//第二套渲染--------------------------------------CGPROGRAM#pragma surface surf Lambert struct Input{float2 uv_MainTex;};sampler2D _MainTex;void surf(Input IN, inout SurfaceOutput o){o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;}ENDCG}
}
到这里我只是想证明给你们,渲染可以在后面加的,并不是只能写在那一个里面。
七、调整代码
到现在为止,我们渲染出来的结果。(如图5所示)

这并不是我们想要的样子,为什么会都是黑色,因为黑色部分是膨胀的,比彩色的大,所以被藏在里面了。(如图6所示)你可以通过增加膨胀的系数在缝隙里面看见。

解决方案:把深度写入关掉。
不管是你在外面还是里面,都画出来。
代码如下。(如图7所示)

到这里一步我们就可以得到(如图8所示)

但是下一步的麻烦就是,我把模型背面也渲染出来了。
解决方案:在渲染黑色自发光时,关掉深度写入,在渲染模型时(第二次画画时),打开深度写入。(如图9所示)
这样我们就可以得到我们想要的结果了。
八、总结
本节想表达的重点:
1.渲染可以写好几次
2.每次渲染之前,可以去调节后面渲染的一些方式。本次案例用深度写入为例子。