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博客

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

Shader "Custom/013-2"
{
Properties
    {
        _MainTex ("MainTex", 2D) = "white" {}
    }
    SubShader
    {
        Tags
        {
        "Queue" = "Transparent"
        }
        Stencil
		{
			Ref 1
			Comp Equal
			Pass Keep
		}
 
        Cull Off
 
        CGPROGRAM
        #pragma surface surf Lambert alpha:fade
 
        sampler2D _MainTex;
 
        struct Input
        {
            float2 uv_MainTex;
        };
 
        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c =tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

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

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

图6 模版测试

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

    Properties
    {
        _MainTex ("MainTex", 2D) = "white" {}
        _SRef("Stencil Ref",Float) = 1
        _SComp("Stencil Comp",Float) = 8
        _SOp("Stencil Op",Float) = 2
    }

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

        Stencil
		{
            Ref[_SRef]
            Comp[_SComp]
            Pass[_SOp]
		}

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


番外备注:

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

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

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

图7 下拉框

这样就方便多了!


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

Tags
{
"Queue" = "Transparent+1"
}

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

2.图片部分纯净代码
Shader "Custom/014plant"
{
    Properties
    {
        _MainTex ("MainTex", 2D) = "white" {}
        _SRef("Stencil Ref",Float) = 1
        [Enum(UnityEngine.Rendering.CompareFunction)] _SComp("Stencil Comp",Float) = 8
        [Enum(UnityEngine.Rendering.StencilOp)] _SOp("Stencil Op",Float) = 2
    }
    SubShader
    {
        Tags
        {
        "Queue" = "Transparent+1"
        }
        Stencil
		{
            Ref[_SRef]
            Comp[_SComp]
            Pass[_SOp]
		}

        Cull Off

        CGPROGRAM
        #pragma surface surf Lambert alpha:fade

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c =tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
3.遮罩部分复习

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

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

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

Shader "Custom/013-1"
{
Properties
    {
        _MainTex ("MainTex", 2D) = "white" {}
    }
    SubShader
    {
        Tags
        {
        "Queue" = "Transparent-1"
        }
        Stencil
		{
			Ref 1
			Comp Always
			Pass replace
		}
 
        Cull Off
 
        CGPROGRAM
        #pragma surface surf Lambert alpha:fade
 
        sampler2D _MainTex;
 
        struct Input
        {
            float2 uv_MainTex;
        };
 
        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c =tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

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

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,但同时它不能挡住后面的花花草草,所以要把深度检测关了。

Shader "Custom/014"
{
    Properties
    {
        _MainTex ("MainTex", 2D) = "white" {}
        _SRef("Stencil Ref",Float) = 1
        [Enum(UnityEngine.Rendering.CompareFunction)] _SComp("Stencil Comp",Float) = 8
        [Enum(UnityEngine.Rendering.StencilOp)] _SOp("Stencil Op",Float) = 2
    }

    SubShader
    {
        Tags { "Queue" = "Geometry" }

        ZWrite off
        ColorMask 0
       
       Stencil
       {
        Ref[_SRef]
        Comp[_SComp]
        Pass[_SOp]
       }

        CGPROGRAM
       #pragma surface surf Lambert
       sampler2D _MainTex;

       struct Input
       {
       float2 uv_MainTex;
       };

       void surf(Input IN,inout SurfaceOutput o)
       {
       o.Albedo = tex2D (_MainTex, IN.uv_MainTex);
       
       }
        ENDCG
    }
    FallBack "Diffuse"
}

四、场景中shader使用

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

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

对应植物1的遮罩:

植物1:

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

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

五、作者的碎碎念

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/803547.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

速部署 HBase 测试环境

快速部署 HBase 测试环境 第一步:下载软件,在HBase官网下载最新版, 找到 bin,点击下载,比如我这里下载的是 hbase-2.5.6-bin.tar.gz 第二步:解压软件 $ tar -zxvf hbase-2.5.6-bin.tar.gz $ cd hbase-2.…

业务终端动态分配IP-DHCP技术、DHCP中继技术

一、为什么需要DHCP? 1、许多设备(主机、无线WiFi终端等)需要动态地址的分配; 2、人工手工配置任务繁琐、容易出错,比如:IP地址冲突; 3、网络规模扩大、复杂度提高,网络配置越来越复杂,计算机的位置变化和数量超过可分配IP地址的数量,造成IP地址变法频繁以及IP地址…

微信小游戏 彩色试管 倒水游戏 逻辑 (四)

最近开始研究微信小游戏,有兴趣的 可以关注一下 公众号, 记录一些心路历程和源代码。 定义了一个名为 WaterFlow class,该类继承自 cc.Graphics,用于在 Cocos Creator 中创建和显示水流的动画效果。下面是对代码的详细解释&#x…

FPGA FIR fdatool filter designer MATLAB

位数问题 fdatool 先确定输入信号的位宽,比如17位在fdatool中,选set quantization parameters 选input/output 设置input word length 为17bit(not confirmed) fir compiler implementation 注意: 当设置输入位宽为16位时,ip核…

智能手术新时代:Apple Vision Pro在医疗领域的突破性应用

无人驾驶的未来:AI如何重塑我们的出行世界-CSDN博客文章浏览阅读2.2k次,点赞109次,收藏64次。无人驾驶汽车的发展是AI技术应用的一次伟大尝试。特斯拉与百度“萝卜快跑”在这个领域的竞争与合作,不仅展示了AI技术的强大潜力&#…

记录些MySQL题集(6)

MySQL 单表为什么不要超过 2000W 行? 数据持久化在磁盘中,磁盘的最小单元是扇区,一个扇区 0.5 KB,而由 8 个扇区可以构成一个文件系统块(4K),以 InnoDB 存储引擎为例,一个数据页的大…

React Native 自定义 Hook 获取组件位置和大小

在 React Native 中自定义 Hook useLayout 获取 View、Pressable 等组件的位置和大小的信息 import {useState, useCallback} from react import {LayoutChangeEvent, LayoutRectangle} from react-nativeexport function useLayout() {const [layout, setLayout] useState&l…

MySQL数据库查询索引失效场景

在连表情况下,如果排序字段涉及到了两个表,排序字段将无法走索引. 加上第二个排序字段之后,走全表扫描了. 或者尽量让两次排序都用同一个表的字段,这样可以建联合索引让排序也能走索引.(不想建联合索引的话,可以第二次排序用表id,这样单个的…

《昇思25天学习打卡营第25天|第10天》

今天是打卡的第十天,今天开始学应用实践中的LLM原理和实践,今天学的是基于MindSpore实现BERT对话情绪识别。最先了解的是BERT模型的简介(来自变换器的双向编码器表征量(Bidirectional Encoder Representations from Transformers&…

暑期-大数据人工智能学习-在线实习项目

这个暑期 默默努力一把 悄悄惊艳所有人 在线企业项目试岗实训 助你突破固有思维模式,伴你进阶成长

Prometheus 云原生 - Prometheus 数据模型、Metrics 指标类型、Exporter 相关

目录 开始 Prometheus 数据类型 简单理解 时序样本 格式 和 命名要求 Metrics 指标类型 Counter 计数器 Gauge Histogram Summary Exporter 相关 概述 Exporter 类型 Exporter 规范 开始 Prometheus 数据类型 简单理解 a)安装好 Prometheus 后会暴露…

Nginx、LNMP万字详解

目录 Nginx 特点 Nginx安装 添加Nginx服务 Nginx配置文件 全局配置 HTTP配置 状态统计页面 Nginx访问控制 授权用户 授权IP 虚拟主机 基于域名 测试 基于IP 测试 基于端口 测试 LNAMP 解析方式 LNMP转发php-fpm解析 Nginx代理LAMP解析 LNMP部署示例 实…

Android:将自定义视图设为互动式

一、简介 点击查看将自定义视图设为互动式官网文档 绘制界面只是创建自定义视图的一个部分。您还需要让视图以非常类似于您模仿的真实操作的方式响应用户输入。 让应用中的对象的行为方式与真实对象相似。例如,不要让应用中的图片消失后重新出现在其他位置&#x…

模块化和包管理工具

一,模块化 1.定义 将一个复杂的程序文件依据一定规则(规范)拆分成多个文件的过程称之为 模块化 其中拆分出的 每个文件就是一个模块 ,模块的内部数据是私有的,不过模块可以暴露内部数据以便其他模块使用 2.模块化…

NC65 流程设置 选择项目(project)参照时,得到的是合并报表项目参照

NC65 流程设置 枚举项选择项目(project)参照时,取值得到的是合并报表项目参照,如下图, 造成以上原因是因为存在相同编码的情况时,默认取该编码的第一个参照名称,而"project"编码对应…

彩电上自带的推箱子游戏是什么编程语言开发的?

2000年左右的厦新彩电上,自带了推箱子、华容道游戏。界面如下: 在线版推箱子游戏,网址:https://www.tuixiangzi.cn/ BASIC,全称是Beginners All-purpose Symbolic Instruction Code,含义是初学者通用符号…

【设计模式】【创建型模式】【02工厂模式】

系列文章 可跳转到下面链接查看下表所有内容https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5501文章浏览阅读2次。系列文章大全https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5501 目录 系…

pico+unity3d手部动画

在 Unity 开发中,输入系统的选择和运用对于实现丰富的交互体验至关重要。本文将深入探讨 Unity 中的 Input System 和 XR Input Subsystem 这两种不同的输入系统,并详细介绍它们在控制手部动画方面的应用。 一、Input System 和 XR Input Subsystem 的区…

【Linux 配置静态IP】Ubuntu20.04

最近学习网络编程,为了方便学习需要Ubuntu配置静态IP,网上看了好多贴子跟着试了下可以实现,但重启虚拟机后有时就无法连接,总之各种各样问题;相关的配置方法也比较凌乱,有用netplan 或者 ifupdown ,笔者简单…

使用LobeChat+Ollama快速搭建本地大模型,离线可用

文章目录 准备工作下载Ollama什么是Ollama 参考文献 分享一下如何部署本地大模型,让它成为你的离线助手。 准备工作 服务器或者电脑一台,配置越高越好, Windows和Mac皆可,Widows最好内存8G以上而且带一块好一点的显卡&#xff1b…