unity蒙板测试例子——传送门

news2025/6/18 1:56:25

返回目录

Unity蒙板测试例子——传送门

一、例子介绍

大家好,我是阿赵。
蒙板测试(Stencil Test)是渲染管线的合并输出环节里面的一种测试,和透明度测试或者深度测试一样,它实际上也是控制颜色值是否应该显示出来的一种手段。
在这里插入图片描述

这里我做了一个例子,在一个荒漠上面,出现一个传送门,传送门里面是另外一个世界,有一个人物从传送门里面的世界走出来,走到了荒漠的世界里面。
这个例子里面,角色动画控制和传送门特效都是为了让整体效果更好看的一些点缀而已,和蒙板测试本身并没有必然的联系,所以各位在看这个例子的时候,不要去关注这些东西,直接看蒙板测试本身的关系就行了。
我也知道,其实原理什么的,很多人都不会去看,源码放在最后面。

二、原理说明

1、模型准备

1.外部世界和角色

在这里插入图片描述

我这里准备了一个角色模型,随便给上了贴图,因为她不是重点。
重点是世界的构成,有一个天空球,然后有一个面片作为地面,给上了地面的贴图。

2.传送门

在这里插入图片描述

简单的,用了一个圆形的面片去做这个传送门的遮挡范围。外面的特效是点缀的,不要去关注它。
这个传送门的面片是这一个例子里面的重点了,它作为一个依据,分割了门外和门里面的世界的显示。

3.传送门内部世界

在这里插入图片描述

由于要模拟一个门里面的世界,所以我用一个翻转法线的球模拟了一个天空球,然后再用一个面片模拟了一个地面。

2、各个部分的关系说明

在这里插入图片描述

这个关系图,把刚才准备的各个部分做了一个关系说明

1.角色

角色是在门里面和外面都要看得到的,所以它不应该参与蒙板测试,就正常的显示。不过由于我们有动画效果,门是渐变出现的,所以在门出现之前,角色模型要先隐藏起来。

2.门蒙板

这个作为门的面片,就是我们的蒙板,我们暂时成为“门”。作为蒙板,它的值将决定另外两个部分是否显示。这里我假设这个门的蒙板值为1,下面用到。

3.外部世界

外部的世界是在门模型以外显示,门的内部不显示。所以我们可以设置它的蒙板值是0,并且只有大于等于缓冲区区才显示。没有门的地方,缓冲区前端值是0,所以外部模型可以显示。由于门是1,所以有门的地方,外部世界模型不显示

4.内部世界

内部世界是在门模型内部才显示,门外是不显示的。所以我们可以设置条件,内部蒙板值是1,并且只有小于等于缓冲区值时才显示。所以没有门的地方,缓冲区的值是0,内部世界不会显示,有门的地方才会显示

3、蒙板测试的代码说明

这些资料官方和网上都很多,我就稍微搬运以下。

stencil{
	Ref referenceValue
	ReadMask  readMask
	WriteMask writeMask
	Comp comparisonFunction
	Pass stencilOperation
	Fail stencilOperation
	ZFail stencilOperation
}

一段完整的蒙板测试代码,包含着以下这些字段,也可以只包含其中部分字段。

1.Ref

要比较的参考值(如果 Comp 是always以外的任何值)和/或要写入缓冲区的值(如果 Pass、Fail 或 ZFail 设置为替换)。值为 0 到 255 之间的整数。

2.ReadMask

一个 8 位掩码,值为 0 到 255 之间的整数,用于比较参考值和缓冲区的内容 (referenceValue&readMask)comparisonFunction(stencilBufferValue&readMask)。默认值:255

3.WriteMask

这是一个 8 位掩码,值为 0 到 255 之间整数,写入缓冲区时使用。请注意,与其他写掩码一样,它指定写操作将影响模板缓冲区的哪些位(例如 WriteMask 0 表示不会影响任何位,也不会写入 0)。默认值:255

4.Comp

用于将参考值与缓冲区的当前内容进行比较的函数。默认值:always

5.Pass

如果模板测试(和深度测试)通过,如何处理缓冲区的内容。默认值:keep

6.Fail

如果模板测试(和深度测试)失败,如何处理缓冲区的内容。默认值:keep

7.ZFail

如果模板测试通过但深度测试失败,如何处理缓冲区的内容。默认值:keep

上面的参数里面用到了2种类型的枚举,分别是comparisonFunction和stencilOperation
Comparison Function可以理解成是Comp 项的比较符号:
Greater Only render pixels whose reference value is greater than the value in the buffer.
GEqual Only render pixels whose reference value is greater than or equal to the value in the buffer.
Less Only render pixels whose reference value is less than the value in the buffer.
LEqual Only render pixels whose reference value is less than or equal to the value in the buffer.
Equal Only render pixels whose reference value equals the value in the buffer.
NotEqual Only render pixels whose reference value differs from the value in the buffer.
Always Make the stencil test always pass.
Never Make the stencil test always fail.

Stencil Operation可以理解成是当测试通过了或者失败时,对于原来的蒙板缓冲区的处理:
Keep Keep the current contents of the buffer.
Zero Write 0 into the buffer.
Replace Write the reference value into the buffer.
IncrSat Increment the current value in the buffer. If the value is 255 already, it stays at 255.
DecrSat Decrement the current value in the buffer. If the value is 0 already, it stays at 0.
Invert Negate all the bits.
IncrWrap Increment the current value in the buffer. If the value is 255 already, it becomes 0.
DecrWrap Decrement the current value in the buffer. If the value is 0 already, it becomes 255.

三、各个部分的实现

1、蒙板

1.Shader

Shader "azhao/StencilMask"
{
    Properties
    {

    }
    SubShader
    {
		Tags{ "RenderType" = "Opaque"  "Queue" = "Geometry-1" }
		Cull Back
		ZWrite Off
		Stencil
		{
			Ref 1
			Comp Always
			Pass Replace
		}
		ColorMask 0
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag


            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
            };


            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                return fixed4(1,1,1,1);
            }
            ENDCG
        }
    }
}

2.说明

这里有几个地方值得注意的:
(1)“Queue” = “Geometry-1”
这里的渲染队列是Geometry-1,这是因为门是其他渲染对象对比蒙板值的依据,所以,它应该是要比其他的对象先写入缓冲区的。
(2)ZWrite Off
关闭了深度写入,这里只用蒙板测试来决定是否需要显示。
(3)Ref 1
把1这个值写入了缓冲区
(4)Comp Always
和第一点一样,门需要最先写入,而且是必须写入的。
(5)ColorMask 0
由于这个“门”的模型并不需要显示,只是需要作为一个写入缓冲区的作用,所以用ColorMask来控制它并不实际显示。

2、外部世界

1.Shader

Shader "azhao/StencilFloor"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
		Stencil
		{
			Ref 0
			Comp GEqual
		}
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                return col;
            }
            ENDCG
        }
    }
}

2.说明

这里Ref 0,说明了外部世界的模型的蒙板值是0,然后用Comp GEqual来决定,只有当自己大于等于缓冲区的值时,才会通过。
在门以外的区域,缓冲区是空的,值是0,所以外部的模型就能通过测试。当遇到门覆盖的地方,由于门写入的缓冲区的值是1,而外部世界的值是0,所以有门的地方,外部的世界模型是不会显示的。

3、内部世界

1.Shader

Shader "azhao/StencilAfterGate"
{
    Properties
    {
		[HDR]_Color0("Color 0", Color) = (1,1,1,0)
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
		Stencil
		{
			Ref 1
			Comp LEqual
		}
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
			float4 _Color0;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
				col*= _Color0;
                return col;
            }
            ENDCG
        }
    }
}

2.说明

这里Ref 1,说明了内部世界的模型的蒙板值是1,然后用Comp LEqual来决定,只有当自己小于等于缓冲区的值时,才会通过。
在门以外的区域,缓冲区是空的,值是0,所以内部的模型不能通过测试,不会显示。当遇到门覆盖的地方,由于门写入的缓冲区的值是1,而内外部世界的值也是1,符合小于等于,所以有门的地方,内部的世界模型才会显示的。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

natapp + nginx 实现内网穿透

环境是我本地的win10 第一步:下载nginx压缩包并解压(这个自行百度吧) 第二步: 修改nginx的配置文件: 在最下方添加: #testserver {listen 8081;#你要映射的端口server_name localhost; #使用本地IPlocation / {proxy_pass…

面试官:如何搭建Prometheus和Grafana对业务指标进行监控?

Prometheus和Grafana都是非常流行的开源监控工具,可以协同使用来实现对各种应用程序、系统、网络和服务器等的监视和分析。 下面对Prometheus和Grafana进行简要介绍: Prometheus Prometheus是一款开源、云原生的系统和服务监控工具,它采用p…

戴尔惠普联想笔记本性价比(戴尔和联想笔记本性价比)

联想。 联想做笔记本时间长,售后、质量都不错,追求稳定,性价比合理,长久使用考虑,不会有太大笔记本毛病。 联想1984就开始进入笔记本电脑行业,由中科院投资,后来收购了IBM之后,笔记…

第13届蓝桥杯省赛真题剖析-2022年4月17日Scratch编程初中级组

[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第122讲。 第13届蓝桥杯省赛举办了两次,这是2022年4月17日举行的第一次省赛,比赛仍然采取线上形…

Air32F103CBT6|CCT6|KEIL-uVsion5|本地编译|STClink|(6)、Air32F103编译下载

目录 一、环境搭建 准备工作 安装支持包 二、新建工程 添加外设库支持 测试代码 三、下载烧录 一、环境搭建 准备工作 安装MDK5,具体方法请百度,安装后需要激活才能编译大文件 下载安装AIR32F103的SDK:luatos-soc-air32f103: Air32f…

FL Studio2023中文版本水果编曲工具

编曲、剪辑、录音、混音,23余年的技术积淀和实力研发,FL Studio 已经从电音领域破圈,成功蜕变为全球瞩目的全能DAW,把电脑变成全功能音乐工作室,接下来我们会为您一一展示FL Studio 21也叫做水果音乐编曲软件&#xff…

Chat GPT太强,多种玩法曝光

1、模拟面试、考试,备考等,以面试为例,让它扮演一个角色 先让它扮演互联网行业的商业分析师 2、写各种发言稿、文章、报告,给它你的明确要求和目标,以发言稿为例,输入继续,可以持续优化 3、…

报名截至在即 | “泰迪杯”挑战赛最后一场赛前指导直播!

为推广我国高校数据挖掘实践教学,培养学生数据挖掘的应用和创新能力,增加校企交流合作和信息共享,提升我国高校的教学质量和企业的竞争能力,第十一届“泰迪杯”数据挖掘挑战赛(以下简称挑战赛)已于2023年3月…

白银实时行情操作中的一些错误及其解决办法(下)

小编根据大师,网络上的高手以及自己的经验整理出的一些交易中典型的错误,投资者可以参考参考,有则改之无则加勉~续上文…… 问题三:长线获利的交易不容易坚持同时陷入盘整或亏损的交易(特别是大仓持有的品种&#xff…

银行数字化转型导师坚鹏:ChatGPT解密与银行应用案例

ChatGPT解密与银行应用案例 ——开启人类AI新纪元 打造数字化转型新利器 课程背景: 很多企业和员工存在以下问题: 不清楚ChatGPT对我们有什么影响? 不知道ChatGPT的发展现状及作用? 不知道ChatGPT的银行业应用案例?…

dy对接接口获取数据

1.需求方: 1.已知账户,获取该账户下每天的发视频数据,同时获取一个视频连续30天的点赞数,分享数,评论数。 2.需求方确定在标题中附带来源和作者相关信息,从标题中提取该部分信息,作为原创和作者绩效考核。…

项目人力资源管理

相关概念 组织结构图:用图形表示项目汇报关系。最常用的有层次结构图、矩阵图、文本格式的角色描述等3种。 任务分配矩阵(或称责任分配矩阵)(RAM):用来表示需要完成的工作由哪个团队成员负责的矩阵,或需要完成的工作与哪个团队成员有关的矩阵。 一、规划人力资源管理(编…

【Mybatis源码分析】类型处理器(TypeHandler)及其注册

TypeHandler和TypeHandlerRegistryTypeHandlerTypeHandler 源码分析TypeHandler注册,TypeHandlerRegistry源码分析TypeHandler拓展案例总结TypeHandler 大伙都知道Mybatis是对JDBC的封装,那Mybatis是如何处理JDBC类型和Java类型之间的转换的呢&#xff…

图文在线翻译-文本翻译

随着国际交流不断增加,越来越多的企业需要将产品介绍、宣传文案等相关信息翻译成多种语言,以扩大海外市场。但传统的翻译过程通常比较繁琐,耗费时间和人力成本也相对较高。为此,我们推出了一款批量图文翻译软件,帮助企…

【设计模式之美 设计原则与思想:规范与重构】35 | 实战一(下):手把手带你将ID生成器代码从“能用”重构为“好用”

上一节课中,我们结合 ID 生成器代码讲解了如何发现代码质量问题。虽然 ID 生成器的需求非常简单,代码行数也不多,但看似非常简单的代码,实际上还是有很多优化的空间。综合评价一下的话,小王的代码也只能算是“能用”、…

Apache配置与应用和优化

--------构建虚拟 Web 主机--------虚拟Web主机指的是在同一台服务器中运行多个Web站点,其中每一个站点实际上并不独立占用整个服务器,因此被称为“虚拟”Web 主机。通过虚拟 Web 主机服务可以充分利用服务器的硬件资源,从而大大降低网站构建…

【数据结构与算法】一、数据结构的基本概念

文章目录一、数据结构的基本概念1.1 数据结构的研究内容1.2 数据类型和抽象数据类型1.3 算法和算法分析1.3.1 算法的时间复杂度1.3.2 算法时间效率的比较1.4 知识回顾一、数据结构的基本概念 1.1 数据结构的研究内容 1.2 数据类型和抽象数据类型 抽象数据类型(ADT…

初识linux之线程基本概念

目录 一、进程地址空间和页表再理解 二、线程 1.线程的概念 2. 进程与线程 3. 线程的意义 4.线程的优点缺点 4.1 优点 4.2 缺点 4.linux中线程的优缺点 4.1 优点 4.2 缺点 5. linux中线程创建相关接口 5.1 线程创建 6. 通过代码查看进程与线程的关系 6.1 线程库…

【软件设计师11】面向对象设计

面向对象设计 1. 设计原则 单一职责原则:设计目的单一的类 开放-封闭原则:对外扩展开放,对修改关闭 里氏(Liskov)替换原则:子类可以替换父类 依赖倒置原则:要依赖与对象,而不是具体实现;针…

Windows安装配置Anaconda

要进行各类有意思大模型的运行,首选需要解决环境问题。本文介绍了windows 下安装anaconda、conda的配置、以及conda的常用命令。 一、下载安装 注1:不要求提前安装python。 注2:因为后续环境多了,会占用较大硬盘空间&#xff0…