Unity Shader-GodRay,体积光(BillBoard,Volume Shadow,Raidal Blur,Ray-Marching)

本文介绍了Unity中实现GodRay(体积光)的四种不同方式,包括BillBoard特效贴片、Volume Shadow光方向挤出、Raidal Blur后处理径向模糊以及Ray-Marching光线追踪。通过实例和代码解析,展示了这些方法的工作原理和应用场景,旨在帮助开发者理解并实现在游戏中的体积光效果。
摘要由CSDN通过智能技术生成

好久没有更新博客了,经历了不少事情,好在最近回归了一点正轨,决定继续Unity Shader的学习之路。作为回归的第一篇,来玩一个比较酷炫的效果(当然废话也比较多),一般称之为GodRay(圣光),也有人叫它云隙光,还有人叫它体积光(探照灯)。这几个名字对应几种类似的效果,但是实现方式相差甚远。先来几张照片以及其他游戏的截图看一下:

ps:这张图片是一张照片哈,是本屌丝看别人的云南游记发现的,哎呀,看着好美好想去>_<

ps:这张截图是《耻辱-外魔之死》的一张截图,窗缝中透过的光形成了一道道光束。也不知道《耻辱》系列还有没有后续了,超级喜欢的一个系列,最近才买的这一部,一共五关,还剩一关就通关了,我竟然有点舍不得玩了...

ps:这张图是《罗马之子》中的一个截图,抬头看太阳会发现一个很耀眼的光束,啥时候能自带个这样的光效哈,CryEngine渲染就是棒。这个游戏玩得有点心酸,感觉主角好悲剧。

ps:《剑灵》中云隙光的效果,很明显,很给力!

ps:来张《天涯明月刀》中的动态效果,天刀人模的渲染和天气系统太给力了,技能也很流畅,对,还有萌萌哒萝莉,萝莉,萝莉!!!本来是想着去看看有啥效果可以玩一下的,结果一不小心沉迷了好几个月,差点玩成《天涯上班刀》。

ps:《Inside》打水怪的一关,潜艇探照灯的效果;这是个人很喜欢的一部游戏,当初只是感觉这个游戏玩法很好,直到看了他们GDC的分享,反过来再玩这个游戏的时候,才意识到这个游戏的渲染技术竟然也如此超前,可能游戏本身的玩法太好玩,以至于我第一遍玩的时候,完全没注意这些效果相关的东东。

 

额,赶脚我是一个写游戏评测的的...回归正题,GodRay效果对游戏的画面提升很大,也成了当今各种大型游戏中很常见的一个效果,所以今天本人打算把上面的这几个效果用四种不同的方式实现一遍,当然,上面的都是3A大作,我这个小菜鸟只能简单模拟一下,权当实践一遍当今游戏中常见的体积光实现的技术,疏漏之处,还望各位高手不吝赐教。

 

简介

首先得了解一下真实世界中GodRay现象的原理,然后我们再去模拟(虽然大多数情况实现跟原理相差十万八千里)。这种光的现象是中学物理学过的一个东东,叫丁达尔效应。胶体中粒子对光线进行了散射形成光亮的通路。自然界中,云,雾,空气中的烟尘等都是胶体,所以当光照射过去的时候,发生散射,就形成了我们看到的GodRay了。

我们要在游戏中模拟这种现象,·当然不太可能完全按照现实世界中的方式去做,如果真的按照现实方式去渲染体积光,可能需要非常非常大量的粒子,这在PC端实时计算都很困难,在目前的移动设备上就更不可能了。对于游戏中我们所要的,就是在需要的地方,能显示出一道光线就好了。今天主要介绍以下几种实现方式,BillBoard特效贴片,Volume Shadow沿光方向挤出顶点,Raidal Blur Postprocessing基于后处理的实现,Ray-Marching基于光线追踪的实现。几种方式殊途同归,都是尽可能用最省的消耗来近似模拟这一酷炫的现象。

 

BillBoard特效贴片

最简单的方法,直接在需要有GodRay的地方,放一个特效片,模拟一个光效,就完成啦!

通过Unity自带的粒子系统,控制粒子贴图采样uv变换,以及颜色的alpha变换,模拟灯光摇曳的状态(今天找到了一个Gif录屏软件,GifCam,感觉还不错,终于摆脱了先录视频再转Gif的费劲工作流...):

这是最简单粗暴的方法,不过往往也是最行之有效的,同时也是性能最好的。对于场景中的一些简单装饰性的效果,其实用这种方式就可以满足了,这也是最适合手游的一种方案。《耻辱-外魔之死》的窗缝中透光的效果,如果不考虑近处穿帮的问题,其实就可以使用这种方式进行近似模拟。

不过,这个方式过于简单了点儿,远景效果还可以,如果离近了可能会显得不是很真实,所以就有很多针对这个效果的变种,最著名的应该就是Shadow Gun里面的实现了,Shadow Gun确实是一个好东东,里面很多效果的实现都很经典,下面来分析一下ShadowGun的体积光效果。

Shadow Gun中的体积光有两个重要的特性,第一个是根据距离远近 ,动态调整体积光的颜色及透明度,来达到更加真实的体积光的效果,在远距离看不清体积光,距离近些时逐渐清晰,当距离很近时,降低强度,使之更容易看清背后物体。第二个特性是动态调整体积光网格的位置,当摄像机贴近体积光时,避免了相机与半透穿插,同时也避免了因半透占屏比高导致的像素计算暴涨的性能问题。

下面附上一段代码:

[csharp] view plain  copy
 
  1. //puppet_master  
  2. //2018.4.15  
  3. //Shadow Gun中贴片方式实现GodRay代码,升级unity2017.3,增加一些注释  
  4. Shader "GodRay/ShadowGunSimple"   
  5. {  
  6.   
  7.     Properties   
  8.     {  
  9.         _MainTex ("Base texture", 2D) =www.120xh.cn   "white" {}  
  10.         _FadeOutDistNear ("Near fadeout dist", float) = 10    
  11.         _FadeOutDistFar ("Far fadeout dist", float) = 10000   
  12.         _Multiplier("Multiplier", float) = 1  
  13.         _ContractionAmount("Near www.taohuayuan178.com   contraction amount", float) = 5  
  14.         //增加一个颜色控制(仅RGB生效)  
  15.         _Color("Color", Color) = (1,1,1,1)  
  16.     }  
  17.   
  18.     SubShader   
  19.     {     
  20.         Tags { "Queue"="Transparent" "IgnoreProjector"=www.qinlinyule.cn "True" "RenderType"="Transparent" }  
  21.           
  22.         //叠加方式Blend  
  23.         Blend One www.taohuayuangw.com One  
  24.         Cull Off   
  25.         Lighting Off   
  26.         ZWrite Off   
  27.         Fog { Color (0,0,0,0) }  
  28.           
  29.         CGINCLUDE     
  30.         #include "UnityCG.cginc"  
  31.         sampler2D _www.thd178.com MainTex;  
  32.           
  33.         float _FadeOutDistNear;  
  34.         float _FadeOutDistFar;  
  35.         float _Multiplier;  
  36.         float _ContractionAmount;  
  37.         float4 _Color;  
  38.   
  39.         struct v2f {  
  40.             float4  pos : SV_POSITION;  
  41.             float2  uv      : TEXCOORD0;  
  42.             fixed4  color   : TEXCOORD1;  
  43.         };  
  44.           
  45.         v2f vert (appdata_full v)  
  46.         {  
  47.             v2f         o;  
  48.             //update mul(UNITY_MATRIX_MV, v.vertex) 根据UNITY_USE_PREMULTIPLIED_MATRICES宏控制,可以预计算矩阵,减少逐顶点计算  
  49.             float3      viewPos     = www.baohuayule.net  UnityObjectToViewPos(v.vertex);  
  50.             float       dist        = length(viewPos);  
  51.             float       nfadeout    = saturate(dist / _FadeOutDistNear);  
  52.             float       ffadeout    = 1 - saturate(max(dist - _FadeOutDistFar,0) * 0.2);  
  53.               
  54.             //乘方扩大影响  
  55.             ffadeout *= ffadeout;  
  56.             nfadeout *= nfadeout;  
  57.             nfadeout *= nfadeout;  
  58.             nfadeout *= ffadeout;  
  59.               
  60.             float4 vpos = v.vertex;  
  61.             //沿normal反方向根据fade系数控制顶点位置缩进,刷了顶点色控制哪些顶点需要缩进  
  62.             //黑科技:mesh是特制的,normal方向是沿着面片方向的,而非正常的垂直于面片  
  63.             vpos.xyz -=   v.normal * saturate(1 -www.thd178.com/  nfadeout) * v.color.a * _ContractionAmount;  
  64.                               
  65.             o.uv    = v.texcoord.xy;  
  66.             o.pos   = UnityObjectToClipPos(vpos);  
  67.             //直接在vert中计算淡出效果  
  68.             o.color = nfadeout * v.color * _Multiplier* _Color;  
  69.                               
  70.             return o;  
  71.         }  
  72.           
  73.         fixed4 frag (v2f i) : COLOR  
  74.         {             
  75.                 return tex2D (_MainTex, i.uv.xy) * i.color ;  
  76.         }  
  77.         ENDCG  
  78.   
  79.         Pass   
  80.         {  
  81.             CGPROGRAM  
  82.             #pragma vertex vert  
  83.             #pragma fragment frag  
  84.             #pragma fragmentoption ARB_precision_hint_fastest             
  85.             ENDCG   
  86.         }     
  87.     }  
  88. }  

效果如下:

简单分析一下:根据远近控制淡入淡出比较简单,只要设置两个距离的系数,根据距离去计算即可,如果感觉效果不够强,就乘方一下,这个也是shader中比较常用的一个提高某个属性对效果影响强度的手段。另一点,根据距离去动态调整顶点的位置,本身这个思想就比较有想法,但是实现更加惊艳到我了。首先刷顶点色这个也是比较常用的控制模型不同位置不同表现的一个方法,但是Shadow Gun不光刷了顶点色,还把法线的内容改了(本身不需要光照计算,没有法线的需求),直接在制作模型的时候将面片的法线改为沿着面片的方向,而不是正常的垂直于面片的方向,这样在计算时,就可以很容易地让模型的缩进方向改为沿着面片。所以这个shader必须结合特制的mesh来使用,并且model设置的法线必须为Import方式,如果改为calculate方式,Unity自己计算出的法线的话,效果就完全不对了。

Shadow Gun中还有一个稍微复杂一些的GodRay Shader,除上面的效果外,又增加了一个根据正弦波等模拟的灯光忽明忽暗的效果,与最上面粒子的控制效果大同小异。这种shader的变种其实可以模拟做一个聚光灯的效果,用一个圆筒形的Mesh,根据菲涅尔计算一个柔和的边缘,然后光柱本身采样一下噪声图,做一个UV滚动,也可以刷一下顶点数控制一下光渐变,就有一个比较好的探照灯效果啦。

 

Volume Shadow光方向挤出

这个方案也是一个相对比较省的方案,但是效果的局限性很大,只是某些特殊情况下可以出比较好的效果,主要的思想是阴影的一种实现-体积阴影的扩展。这个效果在《黑魂2》里面我曾经见过一次,然而这个游戏我实在没有兴趣再被虐一遍,所以木有找到游戏截图,另外天刀的神威职业选人界面的效果与这个有些类似。

Shader代码如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值