当前位置:   article > 正文

Unity | Shader基础知识(第十八集:Stencil应用-透视立方盒子)_unity shader stencil

unity shader stencil

目录

一、前言

二、场景布置

三、 shader部分

1.图片的部分

2.图片部分纯净代码

3.遮罩部分复习

4.深度写入 ZWrite

5.颜色遮罩ColorMask

6.遮罩纯净代码

四、场景中shader使用

五、作者的碎碎念


一、前言

因为这个内容稍微有点多,我尽力讲清楚了,如果不想看长篇大论的,可以直接下载成品。

上一集我们学了一个知识,叫做Stencil,这集我们把这部分知识扩展应用一下,做一个透视立方盒子。旋转到不同的面,展示不同的植物。这个植物可以是模型,也可以是图片。为了方便,我们用图片。(如图1所示)

图1 成品

二、场景布置

这个盒子是由6个quad的片组成的。把显示的面都放在里面,下方的quad加了草地的材质。(如图2所示)

图2 盒子墙

为了让盒子立体效果更好,在周围加了4个柱子,这四个柱子也只是cube拉长了。(如图3所示)

图3 柱子

因为我们展示了4个植物,所以也要放四个植物的图片,放在不同的方向,因为总要展示植物的正面。(如图4所示一个框一个植物)

图4 植物

最后也是最重要的,我们要沿着四周的墙建一圈遮罩(如图5所示),这个遮罩和墙大小一样,但注意墙的可见面是朝里的,但是遮罩的可见面是朝外的。因为你是从外面往里看,然后被遮住。

图5 遮罩

三、 shader部分

我们的shader分成两个,一个是挂在图片上的,一个是挂在遮罩上的。

1.图片的部分

根据之前学过的内容,图片部分就是之前美女图片的代码,链接如下。

Unity | Shader基础知识(第十七集:学习Stencil并做出透视效果)_unity stencil-CSDN博客

在这篇文章中,我们写了一个在遮罩后面才能看见的美女。不想回顾的,我把代码放在下面。

  1. Shader "Custom/013-2"
  2. {
  3. Properties
  4. {
  5. _MainTex ("MainTex", 2D) = "white" {}
  6. }
  7. SubShader
  8. {
  9. Tags
  10. {
  11. "Queue" = "Transparent"
  12. }
  13. Stencil
  14. {
  15. Ref 1
  16. Comp Equal
  17. Pass Keep
  18. }
  19. Cull Off
  20. CGPROGRAM
  21. #pragma surface surf Lambert alpha:fade
  22. sampler2D _MainTex;
  23. struct Input
  24. {
  25. float2 uv_MainTex;
  26. };
  27. void surf (Input IN, inout SurfaceOutput o)
  28. {
  29. fixed4 c =tex2D (_MainTex, IN.uv_MainTex);
  30. o.Albedo = c.rgb;
  31. o.Alpha = c.a;
  32. }
  33. ENDCG
  34. }
  35. FallBack "Diffuse"
  36. }

在上面的基础上,我们进行更改 。

需要更改的第一个部分,我们之前是在内部去设定测试模版的。(如图6所示)

图6 模版测试

但我们现在有4个树,每一个都在内部去改,我们就需要好多shader了,这样不方便,于是全部放到资源里。

  1. Properties
  2. {
  3. _MainTex ("MainTex", 2D) = "white" {}
  4. _SRef("Stencil Ref",Float) = 1
  5. _SComp("Stencil Comp",Float) = 8
  6. _SOp("Stencil Op",Float) = 2
  7. }

 然后在后面引用,只需要在原本的参数后面,书写中括号,再书写引用的符号,就可以了。

  1. Stencil
  2. {
  3. Ref[_SRef]
  4. Comp[_SComp]
  5. Pass[_SOp]
  6. }

这样我们就把参数改成外配的了!~


番外备注:

如果上一集你认真测试了,你会发现,总记不得等于到底是哪个,大于到底是哪个,如果有选项就好了,所以,unity为我们内置了选项,enum。

  1. //选项 引用UnityEngine.Rendering.CompareFunction作为enum
  2. [Enum(UnityEngine.Rendering.CompareFunction)] _SComp("Stencil Comp",Float) = 8
  3. //选项 引用UnityEngine.Rendering.StencilOp作为enum
  4. [Enum(UnityEngine.Rendering.StencilOp)] _SOp("Stencil Op",Float) = 2

这时候,你外面的材质球,对应的地方就会变成下拉选项。(如图7所示)

图7 下拉框

这样就方便多了!


因为我们的植物图片并不是一直显示,而是看见遮罩那一面的时候才显示,所以我们必须在遮罩后面渲染,因为遮罩打算放在Transparent层级,所以我们植物就比它晚一个点就行。

  1. Tags
  2. {
  3. "Queue" = "Transparent+1"
  4. }

到此为止,我们图片的所有更改都结束了。

2.图片部分纯净代码
  1. Shader "Custom/014plant"
  2. {
  3. Properties
  4. {
  5. _MainTex ("MainTex", 2D) = "white" {}
  6. _SRef("Stencil Ref",Float) = 1
  7. [Enum(UnityEngine.Rendering.CompareFunction)] _SComp("Stencil Comp",Float) = 8
  8. [Enum(UnityEngine.Rendering.StencilOp)] _SOp("Stencil Op",Float) = 2
  9. }
  10. SubShader
  11. {
  12. Tags
  13. {
  14. "Queue" = "Transparent+1"
  15. }
  16. Stencil
  17. {
  18. Ref[_SRef]
  19. Comp[_SComp]
  20. Pass[_SOp]
  21. }
  22. Cull Off
  23. CGPROGRAM
  24. #pragma surface surf Lambert alpha:fade
  25. sampler2D _MainTex;
  26. struct Input
  27. {
  28. float2 uv_MainTex;
  29. };
  30. void surf (Input IN, inout SurfaceOutput o)
  31. {
  32. fixed4 c =tex2D (_MainTex, IN.uv_MainTex);
  33. o.Albedo = c.rgb;
  34. o.Alpha = c.a;
  35. }
  36. ENDCG
  37. }
  38. FallBack "Diffuse"
  39. }
3.遮罩部分复习

也是之前学过的内容,遮罩部分也就是之前的遮罩代码,链接如下。

Unity | Shader基础知识(第十七集:学习Stencil并做出透视效果)_unity stencil-CSDN博客

不想回顾的,我把代码放在下面。

  1. Shader "Custom/013-1"
  2. {
  3. Properties
  4. {
  5. _MainTex ("MainTex", 2D) = "white" {}
  6. }
  7. SubShader
  8. {
  9. Tags
  10. {
  11. "Queue" = "Transparent-1"
  12. }
  13. Stencil
  14. {
  15. Ref 1
  16. Comp Always
  17. Pass replace
  18. }
  19. Cull Off
  20. CGPROGRAM
  21. #pragma surface surf Lambert alpha:fade
  22. sampler2D _MainTex;
  23. struct Input
  24. {
  25. float2 uv_MainTex;
  26. };
  27. void surf (Input IN, inout SurfaceOutput o)
  28. {
  29. fixed4 c =tex2D (_MainTex, IN.uv_MainTex);
  30. o.Albedo = c.rgb;
  31. o.Alpha = c.a;
  32. }
  33. ENDCG
  34. }
  35. FallBack "Diffuse"
  36. }

首先,我们依然把内置的模版测试改成外部可更改的,这部分略。之后我们需要学两个重要的知识点:深度写入和颜色遮罩。

4.深度写入 ZWrite

这个功能默认是开启的,也是一个非常好用的功能。

如果物体a被物体b挡住了,在大部分时候,我们是不需要去看物体a的,因为被挡住了,所以就看不见了。(如图8所示),方块的一部分,被平面挡住了。

图8 平面挡住方块

但是,你怎么知道方块在后面的?因为计算机检测了深度。如果此时把深度检测关了。计算机就觉得,大家都在第一面上,所以都显示。(如图9所示)

图9 关闭深度检测

 


我们进一步了解一下这个功能,在打开ZWrite时,如果它检测到物体是在前面的,并且,不是透明的(我设置不是透明,如图10所示)。计算机就会考虑,被一个不是透明的物体挡住了,那就不渲染了。所以这里不仅仅是看不见,而是它压根就不画了。

图10 

这里我们设置为普通物体(如图10所示),再打开深度写入,同时我们让前面的固体显示是透明的。就会出现(如图11所示)。后面的物体会以为自己挡住了,所以不画了,就会出现这个景象。

图11 以为自己被挡住

总结:

a.打开深度写入 ZWrite On

这时候,计算机会测试一下, 发现有谁是躲在后面的吗?干脆就不画这部分了

b.关闭了深度写入ZWrite Off

这时候,计算机不管你是否在后面,都会渲染。


5.颜色遮罩ColorMask

我们在unity里每次看图片,都有一个颜色通道功能。(如图12所示)

图12 颜色通道

在shader中,我们也自带了这个功能,我们可以选择只显示一个通道的内容。也可以选择都不显示。(就是前面我们深度写入中,虽然是物体,但做成了不显示的样子) 

标注了颜色遮罩,我们就可以选择只显示某一种或者某几种,或者不显示。

ColorMask RGBA        全部显示

ColorMask 0                全部关闭

ColorMask R                显示红色通道

ColorMask G                显示绿色通道 

ColorMask B                显示蓝色通道 

ColorMask A                显示透明通道 

ColorMask RG             显示红色和绿色通道

ColorMask RB             显示红色和蓝色通道

ColorMask RA             显示红色和透明通道

ColorMask GB             显示绿色和蓝色通道

ColorMask GA             显示绿色和透明通道

ColorMask BA             显示蓝色和透明通道

6.遮罩纯净代码

所以,我们的遮罩应该就是一个不显示的物体,要把颜色遮罩设置为0,但同时它不能挡住后面的花花草草,所以要把深度检测关了。

  1. Shader "Custom/014"
  2. {
  3. Properties
  4. {
  5. _MainTex ("MainTex", 2D) = "white" {}
  6. _SRef("Stencil Ref",Float) = 1
  7. [Enum(UnityEngine.Rendering.CompareFunction)] _SComp("Stencil Comp",Float) = 8
  8. [Enum(UnityEngine.Rendering.StencilOp)] _SOp("Stencil Op",Float) = 2
  9. }
  10. SubShader
  11. {
  12. Tags { "Queue" = "Geometry" }
  13. ZWrite off
  14. ColorMask 0
  15. Stencil
  16. {
  17. Ref[_SRef]
  18. Comp[_SComp]
  19. Pass[_SOp]
  20. }
  21. CGPROGRAM
  22. #pragma surface surf Lambert
  23. sampler2D _MainTex;
  24. struct Input
  25. {
  26. float2 uv_MainTex;
  27. };
  28. void surf(Input IN,inout SurfaceOutput o)
  29. {
  30. o.Albedo = tex2D (_MainTex, IN.uv_MainTex);
  31. }
  32. ENDCG
  33. }
  34. FallBack "Diffuse"
  35. }

四、场景中shader使用

遮罩和图片的shader需要各自的材质并创建,这里我就略过了,直接进入参数配置。

我们的遮罩和植物图片应该是一一对应的。

对应植物1的遮罩:

植物1:

其他部分不变,其他植物使用不同的数就行,如3,4,5

这样就完成了所有的设置了。

五、作者的碎碎念

这集设置场景的部分比较多,但shader代码和之前差距不大哦。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/975045
推荐阅读
相关标签
  

闽ICP备14008679号