Unity3D使用溶解技术解决障碍物遮挡
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。
CSDN视频网址:http://edu.csdn.net/lecturer/144
在开发过程中,我们面临的首要挑战之一,就是在全3D的场景中让主角保持在头顶视角的镜头之内。也就是说,
如果有东西挡住了主角,是选择避免这些遮挡,还是把遮挡物隐藏掉?假使选择隐藏的话,如何采用一个视觉上令人
可以愉快接受的方式,来让隐藏的过程符合游戏风格?我们如何保持不会妨碍游戏体验的空间感?
已有的方案解决此类问题:
鸟瞰模式
第一个方案是禁止关卡中出现任何横亘玩家与摄像机之间的巨大障碍物。这意味着大部分区域必须非常广阔,而
墙壁和障碍物需要尽可能保持低矮,或干脆完全避免使用它们,并且摄像机与玩家角色要有一个特定的距离,尽可能
垂直向下看。这种形式非常适合于“街机”类游戏,或场景中所有物体都面向同一个方向的传统顶视角RPG。然而在我
们的案例中,视角与角色的距离拉远会导致玩家与主角产生疏远感。同时,也会使场景显得更加不自然,从而使玩家
难以感知我们的游戏性、沉浸感以及视觉风格。
切割方案
您可以把场景想象为一个多层蛋糕,基于当前镜头关注的区域,玩家只能看到某一层的内容。
当主角站在建筑外部时,可以看到建筑的屋顶;而当他进入建筑内部时,整个屋顶以及高楼层就被全部隐藏,
只显示当前楼层的墙壁和地板。大多数情况下不显示屋顶,这样能避免额外的设置工作。这种方法能够给玩家自然
进出建筑物的感觉,让游戏能有更复杂的关卡设计和更强的空间感。虽然我们依旧需要将镜头定位在一个合适的距
离并向下看,但由于障碍物可以被隐藏或显示,构造环境的方法可以更加自由。
为了进一步优化这个方法,我们隐藏墙壁和其他各种物体,决定它们是否遮挡我们的视野,是否允许更低的镜头角度
及玩家角色视野更近。
这种方法唯一的缺点是会让人感觉不太自然。虽然可以通过淡出和使用透明材质来减轻这种感觉,但总体来说,
我们希望尽可能远离这些东西,以避免重绘性能问题和全屏透明覆盖。这种方法确实更加符合需求,但对于我
们的游戏而言仍然不是非常理想。
在考察了常规的解决方案后,我们仍旧感觉有些问题。这些方法在大多数游戏中都工作得很好,但在这个
项目上,我们总感到似乎缺了点什么。所以我们具体想要达成什么样的目标呢?
- 障碍物应当能在平滑而自然的过渡之后被隐藏。
- 关卡设计师应当能控制哪些东西能够被隐藏,于是我们就可以保留一部分依然能够遮挡视野的物体,在环境中增加纵深感。
- 镜头和角色之间的距离发生变化时,系统应当运作如常。
- 遮挡处理应当在任何角度下都能工作。
- 障碍物被隐藏后,玩家需要依然能够感受到它的存在。
- 设置工作需要尽可能简化。
我们最终得出的方案整合了之前所有的方法,并增加了额外的障碍物隐藏风格。游戏中实现的效果图如下所示:
角色刚进入拱桥下面,即将通过拱桥,大家注意一下它的变化。
拱桥出现了一点变化,少了一部分,继续看下面的图片。
拱桥大部分都消失了,但是还保留一点,那是因为角色还没完全过去,继续看下面的图片:
角色完全通过拱桥,拱桥完全消失,这就是使用了融解技术解决遮挡问题。
首先将纹理类型设为“Advanced”并启用“Bypass sRGB Sampling”标志。下面的动画展示了启用该设置前后的区别。
在处理一些用到了纹理数据的更加复杂的着色器效果时,这个设置尤其重要。
下面给读者展示实现融解的Shader代码如下所示:
Shader "Custom/dissolution" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_NoisTex("Dissolution",3D) = "white"{}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
_DissolvePercentage("DissolvePercentage",Range(0,1))=1
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler3D _NoisTex;
struct Input {
float2 uv_MainTex;
float3 worldPos;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
float _DissolvePercentage;
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
//根据像素世界坐标获取3D贴图中的颜色:基本色
//这里的 c 可以直接用_Color代替,这样物体表面就是纯色了
fixed4 c = tex3D (_NoisTex,float3( IN.worldPos.rgb)) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
//根据像素世界坐标获取3D贴图中的颜色计算溶解
half gradient = tex3D(_NoisTex, float3( IN.worldPos.rgb)).r;
clip(gradient- _DissolvePercentage);
}
ENDCG
}
FallBack "Diffuse"
}
另外附上对Shader操作的脚本,代码如下所示:
using UnityEngine;
using System.Collections;
public class TextureUtility : MonoBehaviour {
public Texture3D tex;
public int TexSize=32;
public Material Mat;
// Use this for initialization
void Start () {
if (TexSize < 8) {
TexSize = 8;
} else if (TexSize > 64) {
TexSize = 64;
}
//生成噪点
Color[] ColorPool = new Color[TexSize*TexSize*TexSize];
for(int i =0 ;i<ColorPool.Length;i++){
ColorPool [i] = getColor;
}
//生成贴图并赋值到材质
tex = new Texture3D (TexSize,TexSize,TexSize, TextureFormat.ARGB32, true);
tex.SetPixels (ColorPool);
tex.Apply ();
Mat.SetTexture ("_NoisTex",tex);
}
//只获取纯黑和接近纯白的浅灰色
Color getColor{
get{
float c = Random.Range (-1f, 1f);
if (c >= 0) {
c = 0;
} else {
c = 0.95f;
}
return new Color (c, c, c, c);
}
}
}
这样就可以实现游戏中的融解效果,从而解决遮挡问题。
Unity3D使用溶解技术解决障碍物遮挡的更多相关文章
- [转]unity3d 脚本参考-技术文档
unity3d 脚本参考-技术文档 核心提示:一.脚本概览这是一个关于Unity内部脚本如何工作的简单概览.Unity内部的脚本,是通过附加自定义脚本对象到游戏物体组成的.在脚本对象内部不同志的函数被 ...
- 『零行代码』解决键盘遮挡问题(iOS)
关注仓库,及时获得更新:iOS-Source-Code-Analyze https://github.com/draveness/iOS-Source-Code-Analyze Follow: Dra ...
- FluentData - 轻量级.NET ORM持久化技术解决方式
FluentData - 轻量级.NET ORM持久化技术解决方式 文件夹: 一.什么是ORM? 二.使用ORM的优势 三.使用ORM的缺点 四.NET下的ORM框架有哪些? 五.几 ...
- ios -解决view遮挡按钮问题
#pragma mark -解决view遮挡按钮问题 //分享按钮赋予 self 最顶部 / web按钮赋予 self 最顶部 / showBtn显示按钮 self 最顶部 / scrollviews ...
- Javaweb 使用Servlet技术改写用户登录 使用Filter技术解决中文乱码
先把实验3的jsp页面复制过来: WebContent->WEB-INF->lib下面的jar包8.0版本也要记得复制: Java Resources->src下的 cn.edu.h ...
- Vue 本地代理 纯前端技术解决跨域
vue-axios获取数据很多小伙伴都会使用,但如果前后端分离且后台没设置跨域许可,那要怎样才能解决跨域问题? 常用方法有几种: 通过jsonp跨域 通过修改document.domain来跨子域 使 ...
- GIS技术在医疗行业的应用:利用切片地图发布技术解决dmetrix数字病理切片在线浏览
最近一直在研究切片地图发布技术,解决各种矢量和栅格数据的切片地图制作和发布问题.这块的技术在土地评估和调查类公司中应用较多,因为他们经常需要使用各地地图,传统的文件管理方式很难适应工作现状,如果将各种 ...
- Unity3D外包团队——技术分享U3D全景漫游(三)
22.给每个物体都附上贴图,如果是纯色物体,也付给纯色贴图 23.打光后,选择要烘培的物体 设置输出路径 添加烘培输出的贴图类型 添加“LightingMap”类型 设置烘培贴图大小和目标贴图位置为“ ...
- Unity3D 错误,nativeVideoFrameCallback解决方法。
原地址:http://blog.csdn.net/alking_sun/article/details/23684733 Unity3D在打包安卓应用的时候,一打开游戏就闪退,接入LogCat之后发现 ...
随机推荐
- HelloWorld程序编写调试及错误解决
HelloWorld程序编写调试及错误解决 eclipse软件编写 相较于windows内置记事本,eclipse编写程序更为简单快捷.由其生成的程序模板编写如下: package helloworl ...
- centos配置yum源为中国镜像源
有时候CentOS默认的yum源不一定是国内镜像,导致yum在线安装及更新速度不是很理想.这时候需要将yum源设置为国内镜像站点.国内主要开源的开源镜像站点应该是网易和阿里云了. 修改CentOS默认 ...
- 建站有很多技术,如 HTML、HTML5、XHTML、CSS、SQL、JavaScript、PHP、http://ASP.NET、Web Services、浏览器脚本、服务器脚本等。它们的区别是什么?新手一点不懂,想理清所有这些技术之间的关系和应用范围。
先普及用户通过 浏览器 访问网页 的过程: 网页内容是通过服务器运算得出的结果,将结果(网页代码)传输给浏览器,网页代码再通过浏览器运算(计算.渲染),最终展示在用户的眼前的. 至此,我们知道了有2个 ...
- Docker pull网络错误
[root@Oracle ~]# docker search centos Error response from daemon: Get https://index.docker.io/v1/sea ...
- ETL增量处理总结
1 LOG表 1.1 思路 用log表记录业务库某表yw_tableA发生变化数据的主键.数据进入BI库目标表bi_tableA前,先根据log表记录的主键进行delete. 1.2 设计 1.2.1 ...
- jquery 报错 $.cookie is not a function()
jquery 报错 $.cookie is not a function() ——我是之前可以运行的项目,突然报这个错误,很奇怪. 这是jquery的cookie插件报错. 插件名: jquery.c ...
- vc 导出函数/调用
loader(exe): #include "stdafx.h" #include <Windows.h> #include <stdio.h> #defi ...
- 使用cxf调用webservice
1.引入maven包 <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt ...
- 使用Idea工具nodeJS+mysql开发项目
一.MySQL Server的安装 1.mysql官网下载文件包:[我使用的版本是:mysql_5.7.17] 2.解压Zip压缩包: 3.安装:命令行:D:\soft\mysql-5.7.17-wi ...
- 简单的HelloWorld
简单的HelloWorld 步骤: -加入jar包 -在web.xml中配置DispatcherServlet -加入Spring MVC的配置文件 新建文件springmvc.xml: -编写处理请 ...