【Unity3D】广告牌特效

news2025/4/11 22:08:34

1 前言

        广告牌特效是指:空间中的一个 2D 对象始终(或尽可能)面向相机,使得用户能够尽可能看清楚该 2D 物体。广告牌特效一共有以下 3 种:

  • 正视广告牌:广告牌始终以正视图姿态面向相机,即广告牌的 x、y、z 轴正方向始终指向相机的 x、y、z 轴正方向;
  • 血条广告牌:游戏中的血条效果广告牌,广告牌可以绕世界坐标系的 y 轴旋转,使其尽可能面向相机,即广告牌的 x 轴正方向始终指向相机的 x 轴正方向,y 轴正方向始终指向 (0, 1, 0) 方向,z 轴正方向可以随相机位置和姿态变动;
  • 测距广告牌:测距时显示距离效果的广告牌,广告牌可以绕局部坐标系的 x 轴旋转,使其尽可能面向相机,如同,即广告牌的 x 轴正方向固定不变,y、z 轴正方向可以随相机位置和姿态变动。

        本文完整资源见→Unity3D广告牌特效。

2 正视广告牌

        正视广告牌是指:广告牌始终以正视图姿态面向相机,即广告牌的 x、y、z 轴正方向始终指向相机的 x、y、z 轴正方向。

        FrontView.shader

Shader "MyShader/Billboard/FrontView" { // 正视广告牌
	Properties{
		_MainTex("Main Tex", 2D) = "white" {} // 材质纹理
		_Color("Color Tint", Color) = (1, 1, 1, 1) // 材质颜色
	}

	SubShader{
        // 批处理会合并所有相关的模型, 导致模型各自的模型空间丢失
		Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "DisableBatching" = "True"}

		Pass {
			Tags { "LightMode" = "ForwardBase" }

			ZWrite Off
			Blend SrcAlpha OneMinusSrcAlpha
			Cull Off

			CGPROGRAM

			#pragma vertex vert
			#pragma fragment frag

			#include "Lighting.cginc"

			sampler2D _MainTex; // 材质纹理
			float4 _MainTex_ST; // 材质纹理的缩放和偏移
			fixed4 _Color; // 材质颜色

			struct a2v {
				float4 vertex : POSITION; // 模型空间顶点坐标
				float4 texcoord : TEXCOORD0; // 顶点纹理坐标
			};

			struct v2f {
				float4 pos : SV_POSITION; // 裁剪空间顶点坐标
				float2 uv : TEXCOORD0; // 顶点纹理坐标
			};

			v2f vert(a2v v) {
				v2f o;
				float3 center = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz; // 世界坐标系中模型中心坐标
				float3 right = mul(unity_MatrixInvV, float4(1, 0, 0, 0)).xyz; // 世界坐标系中相机的right向量(广告牌的x轴)
				float3 up = mul(unity_MatrixInvV, float4(0, 1, 0, 0)).xyz; // 世界坐标系中相机的up向量(广告牌的y轴)
				float3 forward = mul(unity_MatrixInvV, float4(0, 0, 1, 0).xyz); // 世界坐标系中相机的forward向量(广告牌的z轴)
				float3 worldVec = mul(unity_ObjectToWorld, v.vertex).xyz - center; // 世界坐标系中模型中心指向顶点的向量
				float3 worldPos = center + worldVec.x * right + worldVec.y * up + worldVec.z * forward; // 世界坐标系中顶点坐标经过广告牌变换后的坐标
				o.pos = mul(unity_MatrixVP, float4(worldPos, 1)); // 裁剪坐标系中顶点坐标
				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); // 纹理uv坐标
				return o;
			}

			fixed4 frag(v2f i) : SV_Target {
				fixed4 color = tex2D(_MainTex, i.uv);
				color.rgb *= _Color.rgb;
				return color;
			}

			ENDCG
		}
	}

	FallBack "Transparent/VertexLit"
}

        运行效果:

3 血条广告牌

        血条广告牌是指:游戏中的血条效果广告牌,广告牌可以绕世界坐标系的 y 轴旋转,使其尽可能面向相机,即广告牌的 x 轴正方向始终指向相机的 x 轴正方向,y 轴正方向始终指向 (0, 1, 0) 方向,z 轴正方向可以随相机位置和姿态变动。

        Lifebar.shader

Shader "MyShader/Billboard/Lifebar" { // 血条广告牌
	Properties{
		_MainTex("Main Tex", 2D) = "white" {} // 材质纹理
		_Color("Color Tint", Color) = (1, 1, 1, 1) // 材质颜色
	}

	SubShader{
        // 批处理会合并所有相关的模型, 导致模型各自的模型空间丢失
		Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "DisableBatching" = "True"}

		Pass {
			Tags { "LightMode" = "ForwardBase" }

			ZWrite Off
			Blend SrcAlpha OneMinusSrcAlpha
			Cull Off

			CGPROGRAM

			#pragma vertex vert
			#pragma fragment frag

			#include "Lighting.cginc"

			sampler2D _MainTex; // 材质纹理
			float4 _MainTex_ST; // 材质纹理的缩放和偏移
			fixed4 _Color; // 材质颜色

			struct a2v {
				float4 vertex : POSITION; // 模型空间顶点坐标
				float4 texcoord : TEXCOORD0; // 顶点纹理坐标
			};

			struct v2f {
				float4 pos : SV_POSITION; // 裁剪空间顶点坐标
				float2 uv : TEXCOORD0; // 顶点纹理坐标
			};

			v2f vert(a2v v) {
				v2f o;
				float3 center = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz; // 世界坐标系中模型中心坐标
				float3 right = mul(unity_MatrixInvV, float4(1, 0, 0, 0)).xyz; // 世界坐标系中相机的right向量(广告牌的x轴)
				float3 up = float3(0, 1, 0); // 广告牌的y轴
				float3 forward = cross(right, up); // 广告牌的z轴
				float3 worldVec = mul(unity_ObjectToWorld, v.vertex).xyz - center; // 世界坐标系中模型中心指向顶点的向量
				float3 worldPos = center + worldVec.x * right + worldVec.y * up + worldVec.z * forward; // 世界坐标系中顶点坐标经过广告牌变换后的坐标
				o.pos = mul(unity_MatrixVP, float4(worldPos, 1)); // 裁剪坐标系中顶点坐标
				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); // 纹理uv坐标
				return o;
			}

			fixed4 frag(v2f i) : SV_Target {
				fixed4 color = tex2D(_MainTex, i.uv);
				color.rgb *= _Color.rgb;
				return color;
			}

			ENDCG
		}
	}

	FallBack "Transparent/VertexLit"
}

        运行效果:

4 测距广告牌

        测距广告牌是指:测距时显示距离效果的广告牌,广告牌可以绕局部坐标系的 x 轴旋转,使其尽可能面向相机,如同,即广告牌的 x 轴正方向固定不变,y、z 轴正方向可以随相机位置和姿态变动。

        MeasureDist.shader

Shader "MyShader/Billboard/MeasureDist" { // 测距广告牌
	Properties{
		_MainTex("Main Tex", 2D) = "white" {} // 材质纹理
		_Color("Color Tint", Color) = (1, 1, 1, 1) // 材质颜色
	}

	SubShader{
        // 批处理会合并所有相关的模型, 导致模型各自的模型空间丢失
		Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "DisableBatching" = "True"}

		Pass {
			Tags { "LightMode" = "ForwardBase" }

			ZWrite Off
			Blend SrcAlpha OneMinusSrcAlpha
			Cull Off

			CGPROGRAM

			#pragma vertex vert
			#pragma fragment frag

			#include "Lighting.cginc"

			sampler2D _MainTex; // 材质纹理
			float4 _MainTex_ST; // 材质纹理的缩放和偏移
			fixed4 _Color; // 材质颜色

			struct a2v {
				float4 vertex : POSITION; // 模型空间顶点坐标
				float4 texcoord : TEXCOORD0; // 顶点纹理坐标
			};

			struct v2f {
				float4 pos : SV_POSITION; // 裁剪空间顶点坐标
				float2 uv : TEXCOORD0; // 顶点纹理坐标
			};

			v2f vert(a2v v) {
				v2f o;
				float3 forwardDire = mul(unity_ObjectToWorld, float4(0, 0, 1, 0)).xyz; // 世界坐标系中模型的forward向量
				float3 center = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz; // 世界坐标系中模型中心坐标
				float3 viewDire = normalize(center - _WorldSpaceCameraPos.xyz); // 观察向量, 相机指向顶点
				float3 right = normalize(mul(unity_ObjectToWorld, float4(1, 0, 0, 0)).xyz) * sign(dot(viewDire, forwardDire)); // 世界坐标系中模型的right向量(广告牌的x轴)
				float3 up = cross(viewDire, right); // 广告牌的y轴
				float3 forward = cross(right, up); // 广告牌的z轴
				float3 worldVec = mul(unity_ObjectToWorld, v.vertex).xyz - center; // 世界坐标系中模型中心指向顶点的向量
				float3 worldPos = center + worldVec.x * right + worldVec.y * up + worldVec.z * forward; // 世界坐标系中顶点坐标经过广告牌变换后的坐标
				o.pos = mul(unity_MatrixVP, float4(worldPos, 1)); // 裁剪坐标系中顶点坐标
				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); // 纹理uv坐标
				return o;
			}

			fixed4 frag(v2f i) : SV_Target {
				fixed4 color = tex2D(_MainTex, i.uv);
				color.rgb *= _Color.rgb;
				return color;
			}

			ENDCG
		}
	}

	FallBack "Transparent/VertexLit"
}

        运行效果:

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

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

相关文章

异常检测进阶梳理1:Tabular AD视角

接触异常检测领域也有一年多的时间了,过程中遇到不少坑,知识体系也在不断更新完善,这里以专题的形式进行知识体系的梳理~ 异常检测(Anomaly Detection, AD)领域内的划分体系较多,这里基于异常检测最常用到的…

【P39】JMeter 随机顺序控制器(Random Order Controller)

文章目录 一、随机顺序控制器(Random Order Controller)参数说明二、测试计划设计2.1、测试计划一2.2、测试计划二 一、随机顺序控制器(Random Order Controller)参数说明 可以让控制器内部的组件按随机顺序执行(内部…

Alibaba Arthas学习与使用

Alibaba Arthas学习与使用 目录 下载安装卸载退出快捷键重点部分: 命令 dashboardthreadjvmsyspropsysenvvmoptiongetstaticognlscsmjadmcredefinedumpclassloadermonitorwatchtracestackttoptionsprofiler 下载安装 # 下载 curl -O https://alibaba.github.io/arthas/art…

Apache Kafka - 如何实现可靠的数据传递

文章目录 可靠的数据传递导图 可靠的数据传递 Kafka 通过以下几个方面实现可靠的数据传递: 分区副本 - Kafka 的分区有多个副本,如果某个副本失效,其他副本可以继续服务。生产者重试 - 生产者在发送消息失败时会自动重试,一直到成功发送或者达到最大重试次数。批量确认 - 生产…

云服务器和专用服务器之间的区别

在当今数字化时代,服务器是构建和支持各种应用和服务的基础设施之一。随着技术的发展和需求的增加,出现了不同类型的服务器,其中最常见的是云服务器和专用服务器。本文将详细介绍云服务器和专用服务器之间的区别,以帮助您更好地了…

SpringSecurity从入门到实战

SpringSecurity从入门到实战 0. 简介 ​ Spring Security 是 Spring 家族中的一个安全管理框架。相比与另外一个安全框架Shiro,它提供了更丰富的功能,社区资源也比Shiro丰富。 ​ 一般来说中大型的项目都是使用SpringSecurity 来做安全框架。小项目有…

【LAMP架构】

目录 一、LAMP架构1、组件作用 二、编译安装Apache httpd服务2、安装环境依赖包3、配置软件模块4、编译及安装5、优化配置文件路径,并把httpd服务的可执行程序文件放入路径环境变量的目录中便于系统识别6.添加httpd系统服务7.修改httpd 服务配置文件8.浏览器访问验证…

【云原生|探索 Kubernetes 系列 5】简化 Kubernetes 的部署,深入解析其工作流程

前言 大家好,我是秋意零。 在前面 4 个章节中,我们充分了解了容器技术和 Kubernes 原生时代引擎的架构和设计思想,今天分享的主要内容是,探索 Kubernetes 部署,深入解析其工作流程 👿 简介 &#x1f3e0…

[元带你学: eMMC协议详解 11] Data transfer mode 数据传输模式

依JEDEC eMMC 5.1及经验辛苦整理,付费内容,禁止转载。 所在专栏 《元带你学: eMMC协议详解》 全文2300 字, 主要介绍数据传输模式,本节数据传输模式图非常重要。数据传输模式图可以说是我查对过最频繁的图之一了。eMMC 限定了这么…

数据库基础——6.排序与分页

这篇文章来讲一下数据库的排序与分页 目录 1.排序数据 1.1排序规则 1.2 单列排序 1.3 多列排序 2.分页 2.1 背景 2.2 实现规则 2.3 拓展 1.排序数据 1.1排序规则 使用 ORDER BY 子句排序 ASC(ascend):升序 ; DESC&a…

怎么一键保存浏览器中打开的所有标签页?

2023年5月28日,周日晚上: 被这个问题困扰很久了,之前一直不知道怎么全部保存浏览器中打开的所有标签页,浪费了不少的时间,今天下午偶然发现了解决办法。 很简单,直接在浏览器里使用快捷键“CtrlShiftD” …

本周大新闻|传Meta与Magic Leap谈专利授权;PS VR2前6周出货60万台

本周XR大新闻,AR方面,苹果XR项目核心高管曝光;传Meta与Magic Leap洽谈专利授权合作;歌尔光学公布新一代AR显示模组;Lumus公布二代波导Z-Lens最新细节;JBD X-cube发布全彩Micro LED光机Hummingbird&#xff…

我用GPT写了一个关于GPT的文章,大家看看写的如何

声明:以下内容来自GPT-3.5大模型(图片除外) 目录 I. 引言 1.1 研究背景和意义 1.2 现有研究综述 II. ChatGPT技术介绍 2.1 ChatGPT技术原理 2.2 ChatGPT技术优势 III. ChatGPT技术在智能客服中的应用和挑战 3.1 ChatGPT技术在智能客…

【TOP生物信息】使用Seurat包自带的方法进行单细胞类型注释

扫码关注下方公粽号,回复推文合集,获取400页单细胞学习资源! 本文共计1318字,阅读大约需要4分钟,目录如下: 方法简介演示数据来源代码演示小结代码参考往期单细胞系统教程 单细胞自动注释细胞类型的软件和…

华为OD机试真题B卷 Java 实现【查字典】,附详细解题思路

一、题目描述 输入一个单词前缀和一个字典,输出包含该前缀的单词。 二、输入描述 单词前缀字典长度字典。 字典是一个有序单词数组。 输入输出都是小写。 三、输出描述 所有包含该前缀的单词,多个单词换行输出。 若没有则返回-1。 四、解题思路…

Java的包:提高代码可维护性和可扩展性的神器

🧑‍💻CSDN主页:夏志121的主页 📋专栏地址:Java基础进阶核心技术专栏 目录 🍔 一、包名 🧆 二、类的导入 🥘 三、静态导入 🥘 四、在包中增加类 🍱 五、…

腾讯云服务器地域有什么不同?地域怎么选?

腾讯云服务器地域有什么区别?怎么选择比较好?地域选择就近原则,距离地域越近网络延迟越低,速度越快。关于地域的选择还有很多因素,地域节点选择还要考虑到网络延迟速度方面、内网连接、是否需要备案、不同地域价格因素…

Docker环境下将已运行的容器打包成新的镜像并运行在另一个服务器上的Docker容器中

1、 查看当前运行的容器 1.1、使用root账户登录进入Linux系统中,键入docker ps命令。 2、打包容器为镜像包 2.1、正在运行的容器一行中CONTAINER ID一列下面的字符串就是容器id,复制想要打包的容器ID并执行docker commit 容器id 容器新名称 例如&…

Spring Boot集成Seata利用AT模式分布式事务示例 | Spring Cloud 53

一、前言 通过以下系列章节: docker-compose 实现Seata Server高可用部署 | Spring Cloud 51 Seata AT 模式理论学习、事务隔离及部分源码解析 | Spring Cloud 52 我们对Seata及其AT事务模式有了基础的了解,今天我们通过搭建Spring Boot集成Seata示例…

组合总和--纯垃圾内容别看,浪费时间

1题目 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被选…