Unity | Shader基础知识(第二十二集:两次渲染)

目录

一、前言

二、"渲染两次"

三、本次成品介绍

四、第一次渲染代码

五、第二次渲染代码

六、截止目前的所有代码

七、调整代码

八、总结


一、前言

之前一直讲的shader文件中,都只写了一次CG代码。

为了大家对这部分的整体理解,我们这次渲染两次。

二、"渲染两次"

这个词是我造的~不是定义。

什么叫渲染两次?

渲染就是画画的意思,渲染两次就是画两次。这里用画画举例。

第一次画画。(如图1所示)
图1 第一次画画

这里如果用文字描述一下,就是画了一个绿色的三角形。


第二次画画。(如图2所示)

图2 第二次画画

如果用语言形容就是,在中间画了一个橘黄色的圆形。


所以我们一套结构CG结构就是画了一幅画。(如图3所示)

不用太在意具体写的什么代码,主要注意一些标志

CGPROGRAM前面是一些准备工作,像之前的模版写入,深度写入之类的。

ENDCG就是结束了绘制

中间就是一些绘制过程,引入一些材料。

这个全过程就是一次画画的全过程。
图3 一套流程

渲染两次的意思是,我可以在一个shader文件中写两套这个东西。

三、本次成品介绍

我们这次先画一个模型的黑影,但是这个黑影要比模型本身大一点。这个做法参考上节课的代码。

Unity | Shader基础知识(第二十一集:应用-怪兽膨胀、顶点着色器和表面着色器合并)_unity 顶点膨胀shader-CSDN博客

然后再正常把模型渲染上去,就可以给模型做一个阴影或者说边框。(如图4所示)
图4 成品

四、第一次渲染代码

我们第一次先画一个模型的黑影(如图4所示),

备注:模型还是用上节课的模型。代码还是用的上节课的思路。
图4 我是谁?带刺小盆栽~

cs 复制代码
 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以后,就是这次画已经画完了,接下来我们再画模型真正的样子。

第二次不需要膨胀,所以顶点那部分就不用加了,直接把颜色上上去。这部分讲太多遍了,就不详解了。

cs 复制代码
 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
 }

六、截止目前的所有代码

cs 复制代码
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:vert
        struct 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所示)
图5 结果

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

不管是你在外面还是里面,都画出来。

代码如下。(如图7所示)
图7 深度写入

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

但是下一步的麻烦就是,我把模型背面也渲染出来了。

解决方案:在渲染黑色自发光时,关掉深度写入,在渲染模型时(第二次画画时),打开深度写入。(如图9所示)

这样我们就可以得到我们想要的结果了。

八、总结

本节想表达的重点:

1.渲染可以写好几次

2.每次渲染之前,可以去调节后面渲染的一些方式。本次案例用深度写入为例子。

相关推荐
suzh1qian15 小时前
Unity类银河战士恶魔城学习总结(P156 Audio Settings音频设置)
学习·unity·c#·游戏引擎
fcm1917 小时前
untiy之碰撞体编辑器
游戏·unity
大梦百万秋17 小时前
C++ 游戏开发:跨平台游戏引擎的构建与优化
开发语言·c++·游戏引擎
tealcwu20 小时前
【Unity基础】Unity中Transform.forward的详解与应用
unity·游戏引擎
W Y1 天前
【Unity-摩擦力】
unity·游戏引擎
高远-临客1 天前
unity读取mysql5.7版本示例
unity·游戏引擎
suzh1qian1 天前
Unity类银河战士恶魔城学习总结(P155 More example on audio effects更多的音效细节)
学习·游戏·unity·c#·游戏引擎
Lowjin_1 天前
Unity中,Canva的三种渲染模式
unity·游戏引擎
小白球滚芝麻1 天前
Unity下载文件断点续下
android·unity·c#·游戏引擎·vr
半夏知半秋2 天前
unity中控制相机跟随物体移动
笔记·数码相机·unity·c#·游戏引擎