Unity3D使用溶解技术解决障碍物遮挡

原创 2017年07月10日 14:18:35

笔者介绍:姜雪伟,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官方教程

遮挡剔除 (Occlusion Culling) 功能可在对象因被其他物体遮挡,当前在相机中无法看到时,禁用对象渲染。该功能不会在三维计算机图形中自动开启,因为在大部分情况下,离相机最远的对象最先渲染...
  • levine2008
  • levine2008
  • 2016年07月19日 01:29
  • 5183

Unity Shader-遮挡处理(X-Ray,遮挡描边,遮挡半透,遮挡溶解)

游戏中处理遮挡的几种常用的方法,遮挡溶解,遮挡描边,遮挡半透,X光效果。...
  • puppet_master
  • puppet_master
  • 2017年07月26日 01:38
  • 4762

Unity3D使用溶解技术解决障碍物遮挡

笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等...
  • jxw167
  • jxw167
  • 2017年07月10日 14:18
  • 1132

UnityShader实例08:溶解消融(Dissolve)材质

溶解消融(Dissolve)材质 在不少3D游戏中,角色死亡后会有一个溶解消融的特效,这个除了粒子特效以外还需要shader的配合。下面就是本例实现的一个效果,当然没有例子配合看起来是搓搓的,不过效果...
  • u011047171
  • u011047171
  • 2015年07月14日 09:35
  • 6020

[UnityShader3]溶解与重现效果

参考链接:http://www.cnblogs.com/Esfog/p/DissolveShader.html 效果图: 从颜色变化来说,有三种,一种是纹理颜色,一种是纹理与黑边的混合颜色...
  • lyh916
  • lyh916
  • 2015年06月10日 13:14
  • 3731

Unity模型溶解特效

  • 2016年11月22日 11:24
  • 105KB
  • 下载

shader溶解特效

前言:在游戏中间我们常常看见物体会慢慢消融,变为灰烬,这个效果可以用于人物的消失,毁灭. 代码: Shader "Esfog/Dissolve" { Properties ...
  • xiaoge132
  • xiaoge132
  • 2016年06月15日 12:23
  • 1716

Unity3D图像后处理特效——Screen Space Ambient Occlusion (SSAO) image effect

Screen Space Ambient Occlusion (SSAO) approximates Ambient Occlusion in realtime, as an image post-...
  • pizi0475
  • pizi0475
  • 2012年09月19日 06:33
  • 5010

一个简单的SSAO

http://blog.csdn.net/xoyojank/article/details/5734537 by José María Méndez  原文链接: http://www.g...
  • cexgiant
  • cexgiant
  • 2016年05月27日 10:06
  • 715

最近用unity5弄的一些渲染

9月末。。。要找工作了,,压力山大。。。顺便求职(实习,明年五月左右)。。 邮箱:wolf_crixus@sina.cn                          --...
  • wolf96
  • wolf96
  • 2015年09月23日 12:52
  • 7916
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Unity3D使用溶解技术解决障碍物遮挡
举报原因:
原因补充:

(最多只允许输入30个字)