【Unity3D】广告牌特效
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; // 模型空间顶点坐标
half2 texcoord : TEXCOORD0; // 顶点纹理坐标
};
struct v2f {
float4 pos : SV_POSITION; // 裁剪空间顶点坐标
half2 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; // 模型空间顶点坐标
half2 texcoord : TEXCOORD0; // 顶点纹理坐标
};
struct v2f {
float4 pos : SV_POSITION; // 裁剪空间顶点坐标
half2 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; // 模型空间顶点坐标
half2 texcoord : TEXCOORD0; // 顶点纹理坐标
};
struct v2f {
float4 pos : SV_POSITION; // 裁剪空间顶点坐标
half2 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"
}
运行效果:

声明:本文转自【Unity3D】广告牌特效。
【Unity3D】广告牌特效的更多相关文章
- Unity3d粒子特效:制作火焰效果
效果 分析 真实的火焰效果,通常包括:火.火光.火星等组成部分,而火焰对周围环境的烘焙,可以通过灯光实现,如点光源. 针对火焰组成部分,我们可以创建对应的粒子系统组件,实现相应的效果,如下图所示: 1 ...
- 【Unity3D】基于粒子系统实现烟花特效
1 需求实现 粒子系统ParticleSystem 中介绍了粒子初始化.粒子发射.发射器形状.渲染器.碰撞.子发射器.拖尾等粒子系统的基本用法,本节将基于粒子系统实现烟花特效. 实现需求如下( ...
- Unity塔防游戏开发
Unity3D塔防开发流程 配置环境及场景搭建编程语言:C#,略懂些许设计模式,如果不了解设计模式,BUG More开发工具:Unity3D编辑器.Visual Studio编译器开发建议:了解Uni ...
- Unity3D特效-场景淡入淡出
最近公司开始搞Unity3D..整个游戏..特效需求还是比较多的.关于UI部分的特效淡入淡出.看网上用的方法都是用个黑东东遮挡然后设置alpha这么搞....本大神感觉非常的low.而且很渣.故奋笔疾 ...
- unity3d 游戏插件 溶解特效插件 - Dissolve Shader
unity3d 游戏插件 溶解特效插件 - Dissolve Shader 链接: https://pan.baidu.com/s/1hr7w39U 密码: 3ed2
- Unity3D之挥动武器产生的剑痕特效
网维教程网 观看很多其它教程 眼下已知3种方法能够做这样的剑痕特效 1.尾随特效 2.程序实现动态面来处理剑痕动画. 3.美术实现剑痕动画,直接坐在模型动画里面 (由于我不会美术所以这个忽略 嘿嘿) ...
- [Unity3D]Unity3D游戏开发之刀光剑影特效的实现
大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei. 我实在不明确有的人为什么不喜欢武侠/仙侠类游戏,也许是因为武侠/仙侠类游戏身上被永远烙上的国 ...
- Unity3D学习笔记——组件之Effects(效果/特效)——Particle System(粒子系统)
Effects:效果/特效. Particle System:粒子系统.可用于创建烟雾.气流.火焰.涟漪等效果. 在Unity3D 3.5版本之后退出了新的shuriken粒子系统: 添加组件之后 ...
- unity3d笔记:控制特效的播放速度
一般在游戏中,主角或者怪物会受到减速效果,或者攻击速度减慢等类似的状态.本身动作减速的同时,衔接在角色上的特效也需要改变相应的播放速度.一般特效有三个游戏组件: 关键点就是改变Ani ...
- GJM : Unity3D - UI - UI边缘流光特效小技巧 [转载]
感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...
随机推荐
- Jquery - 获取所有子节点 ( 并删除 )
1,获取所有子节点 $(".parent").find('.child') 2,获取所有子节点,通过上层 div 的类名 , 获取上层 div 节点 $(".pare ...
- [转帖]MySQL 官方出品,比 mydumper 更快的多线程逻辑备份工具-MySQL Shell Dump & Load
MySQL 官方出品,比 mydumper 更快的多线程逻辑备份工具-MySQL Shell Dump & Load - 知乎 (zhihu.com) 目录 收起 什么是 MySQL Sh ...
- [转帖]使用 Dumpling 导出数据
16 Contributors 使用数据导出工具 Dumpling,你可以把存储在 TiDB 或 MySQL 中的数据导出为 SQL 或 CSV 格式,用于逻辑全量备份.Dumpling 也支持将 ...
- [转帖]Kafka-Kraft 模式架构部署
news文章来源: Kafka-Kraft 模式架构部署 Kafka网址:https://kafka.apache.org/ PS:因环境原因此文档内端口都有修改! 1.去官网下载二进制包 PS:3. ...
- JVM内存学习 2.0
先说一下结果 1. Linux的内存分配是惰性分配的. APP申明了 kernel并不会立即进行初始化和使用. 2. JVM的内存主要分为, 堆区, 非堆区, 以及jvm使用的其他内存. 比如直接内存 ...
- Oracle数据库权限学习--表或者是视图不存在
Oracle数据库权限学习--表或者是视图不存在 摘要 本文写于: 12.10 01:00 巴西踢的太烂了 帮同事看一下补丁执行报错的问题. 问题原因很简单. user_all_table能够后去本用 ...
- 使用linux上面powershell安装vm powercli 连接vcenter 通过计划任务自动创建部分虚拟机的快照以及自动清理过期快照的办法
经过一晚上的折腾, 终于验证出来一个非常简单的方法. 也比较好理解和使用. 这里简单记录一下: 使用linux上面powershell安装vm powercli 连接vcenter 通过计划任务自动创 ...
- Rsync的简单使用
Rsync的简单使用 需求 一个运行很久的系统里面可能包含了非常多的垃圾文件. 但是又不可能随便删除, 很多垃圾可能有某些奇葩的用法. 有时候新建一个应用复制文件的话比较浪费磁盘和带宽. 所以这里简单 ...
- Gitlab使用说明
零.gitlab简介 Gitlab是一个成熟的代码管理工具.为企业和组织提供内部的源代码的存储和管理功能. 一.gitlab角色总览 gitlab中的角色分管理员和 ...
- MySQL控制权限
编写顺序和执行顺序是不一样的 编写顺序: SELECT 字段列表 FROM 表名列表 WHERE 条件列表 GROUP BY 分组字段列表 HAVING 分组后条件列表 ORDER BY 排序字段列表 ...