我的专栏目录:

小IVan:专题概述及目录

体积光在游戏里被越来越多地用到,对烘托场景气氛,提高游戏的逼格有比较重要的作用。这篇就来由浅入深研究一下这个东西。从容易的做法到高端做法依次递进。

首先先来分析一下体积光该如何模拟,在模拟之前还是需要基于现实来观察

可以把体积光模拟分为以下几个部分

(1)光线在介质中传播的衰减

(2)因为有物体的遮挡,体积光会有物体的遮挡影子,可以看到上图光柱因为有物体的遮挡被打散得成一条一条的。

(3)一些细节加成,如尘埃,照亮反弹等。


【1】模型 || Bilboard体积光。

我先不说做法,先上效果:

是不是感觉像是那么回事呢。这种体积光是最简单的一种,就是直接拿个模型或者billboard把一个addtive混合模式的材质叠上去就可以了,甚至还可以使用贴图去控制它们的形状。这种做法在如今的手机游戏上十分常见,高级的做法手机上也跑不了啊(2018年)。

体积光就是对光在介质中传播的模拟。这里的话我使用指数型衰减材光线亮度。

当然还有很多对上述办法的改进方法,比如加一些尘埃的贴图叠在上面模拟体积光中的尘埃等等。

我一直主张多种方法技术混合使用,比如玩家能进入的区域,就用比较昂贵的方法做,中远景其实使用这些简单的体积光是比较好的选择。

对于使用模型或者billboard的体积光还有一些改进就是根据视角来改变模型的形状。常见的办法有把模型画两遍,第一遍沿灯光方向拉扯模型,第二遍正常画模型等等。

总得来说都是在对体积光的三大特征(文章开头所说的那三条)做模拟。


【2】ScreenSpace径向模糊

第一种方法非常简单非常便宜,但是缺点也显而易见,那就是很容易露馅儿。玩家的尽头推得比较近或者镜头快速大角度移动的时候,就显得非常假。所以又想了其它办法来思考对体积光的模拟。

假设现在我们有一条光带,并且我们把这盏灯画到了屏幕上。

如果它向下发射光线,并且假设周围存在空气(微小颗粒),那么光线会发生衰减

能够想到比较简单的做法就是把它的图像向下模糊

下面是我的代码

        float Custom(texture2D tex, sampler texSampler, float2 uv, int ns, float decay)
{float outcol = 0;float2 pos = uv/512;pos = (pos - 0.5) * 2;float weight = 1.0f;float2 dir = float2(0, 1);for(int i = 0; i < ns; i++){uv -= dir / ns;float samplecol = Texture2DSample(tex,texSampler,uv).a;samplecol *= weight;outcol += samplecol;weight *= decay;}outcol = outcol / ns;return outcol;
}

上面只是个快速演示,在游戏中我们可以渲染stencil,对stencil做这种处理。但是这种十分不好控制因为这就是个有方向的模糊。


【3】RayMarching

体积光可以被认为是在介质中均匀散射(没有阻挡的情况下)。所以我的最终图像上每一个像素的亮度应该是对这个方向上能量的积分。

所以我们得到了一个充斥着光的场景。现在模拟了光,剩下的就是模拟体积光的被遮挡的现象了。

现在我们只是从屏幕发射光线,对所有光线进行积分,但是每考虑到遮挡。如果采样点和光线的连线被遮挡了,那这个采样点所采到的值应该低一些才对。这是不是很熟悉,这其实就是shadowmap的思路啦。

小IVan:虚幻4渲染编程(灯光篇)【第一卷:各种ShadowMap】

我们在世界空间架一台摄像机,然后抓一张深度图,用shadowmap的方法对场景进行投射。你将会看到:

上面的Custom节点被我改造过,如果自己不会改引擎的你可以使用我的unrealshadertoy插件。customnode中的代码如下:

        float3 TransForm(float3 v ,float3 x,float3 y,float3 z,float3 w)
{float3 loc1 = v.x * x;float3 loc2 = v.y * y;float3 loc3 = v.z * z;float3 loc4 = loc1 + loc2;float3 loc5 = w + loc3;return loc4 + loc5;
}float lightindensity(float3 or, float3 rd, float3 wp, Texture2D depthmap, SamplerState depthmapSampler,float4 lx,float4 ly,float4 lz,float4 lw,float4 px,float4 py,float4 pz,float4 pw)
{float lindensity = 0.0f;float3 twp = TransForm(wp,lx.xyz,ly.xyz,lz.xyz,lw.xyz);float3 ttwp = TransForm(twp,px.xyz,py.xyz,pz.xyz,pw.xyz);float2 uv = ttwp.xy * 0.5 + 0.5;float depth = Texture2DSample(depthmap, depthmapSampler, uv);depth /= ttwp.z;float nomdepth = depth / 1000;float boc = ttwp.z - 0.01 > nomdepth ? 0 : 1;return boc;
}return lightindensity(or,  rd,  wp,  depthmap,  depthmapSampler, lx, ly, lz, lw, px, py, pz, pw);

下一步就是从摄像机方向发射光线,对光线进行积分,每个采样点判断一下于光线方向上的遮挡信息,如果被遮挡,那么此处采样点的能量将小于其它地方。

我们可以得到如下的效果:

材质如下:

代码如下:

        float3 TransForm(float3 v ,float3 x,float3 y,float3 z,float3 w)
{float3 loc1 = v.x * x;float3 loc2 = v.y * y;float3 loc3 = v.z * z;float3 loc4 = loc1 + loc2;float3 loc5 = w + loc3;return loc4 + loc5;
}float lightindensity(float3 or, float3 rd, float3 wp, Texture2D depthmap, SamplerState depthmapSampler,float4 lx,float4 ly,float4 lz,float4 lw,float4 px,float4 py,float4 pz,float4 pw)
{float lindensity = 0.0f;int maxstep = 64;float lengthperstep = 20;float lightinsperlit = 0.01;float lightinsperunlit = 0.005;float3 pos = or;for(int i = 0; i < maxstep; i++){float3 twp = TransForm(pos,lx.xyz,ly.xyz,lz.xyz,lw.xyz);float3 ttwp = TransForm(twp,px.xyz,py.xyz,pz.xyz,pw.xyz);float2 uv = ttwp.xy * 0.5 + 0.5;float depth = Texture2DSample(depthmap, depthmapSampler, uv);depth /= ttwp.z;float nomdepth = depth / 1000;bool boc = ttwp.z - 0.05 > nomdepth ? 0 : 1;if(boc){lindensity += lightinsperunlit;}else{lindensity += lightinsperlit;}pos = pos + rd * lengthperstep;}return lindensity;
}
//写在Custom节点主code里的代码
return lightindensity(or,  rd,  wp,  depthmap,  depthmapSampler, lx, ly, lz, lw, px, py, pz, pw);

我这里采样了64次,光线每次向前迭代20个单位。其实比较粗糙了。把精度加大,采样次数128,单步10单位试试。

其实还有很多改进空间,欢迎大神留言讨论。

Enjoy it!


Next:

小IVan:虚幻4渲染编程(灯光篇)【第三卷:Lighting components of UE4】


参考资料

【1】Shadertoy

【2】http://advances.realtimerendering.com/s2014/wronski/bwronski_volumetric_fog_siggraph2014.pdf

【3】游戏开发相关实时渲染技术之体积光

虚幻4渲染编程(灯光篇)【第二卷:体积光】相关推荐

  1. unity scence灯光不显示_Unity渲染编程(灯光篇)【第二卷:MobileVolumetricLight】

    MY BLOG DIRECTORY: todo... INTRODUCTION: 如果需要一个方案来渲染城镇或空旷的马路上巨量的灯光.图形程序拿到这个需求直接开始搞F+或者延迟光照,但是对于移动端的巨 ...

  2. 渲染到ui_虚幻4渲染编程(UI篇)【第二卷:程序化UI特效-[1]】

    MY BLOG DIRECTORY: 小IVan:专题概述及目录​zhuanlan.zhihu.com INTRODUCTION: 当遇见某些特殊需求,比如对游戏效果有很多变化的要求,这时使用静态的贴 ...

  3. 虚幻4渲染编程(材质编辑器篇)【第三卷:正式准备开始材质开发】

    My blog directory: YivanLee:专题概述及目录 Introduction: 前面两章我们已经完成了对工具的研究,下面我们久正式开始启程啦!后面的内容可能就比较美术了. 还是老规 ...

  4. 虚幻4渲染编程(灯光篇)【第一卷:各种ShadowMap】

    小IVan:专题概述及目录 灯光篇开篇概述: 灯光在游戏里非常重要,游戏画面的整体感觉,游戏运行的效率都和它息息相关.然而虚幻把这些逻辑封得死死地.各种概念和庞大的系统常常令人束手无策.本篇将从灯光光 ...

  5. 虚幻4渲染编程(环境模拟篇)【第三卷:体积云天空模拟(3)---高层云】

    我的专栏目录: 小IVan:专题概述及目录 目前业内流行有两种体积云模拟的方式,模型+特殊shader法,RayMarching法.我前两篇文章已经对它们都做了介绍.当然还有些比较非主流的,比如粒子云 ...

  6. 虚幻4渲染编程(环境模拟篇)【第五卷:可交互物理植被模拟 - 上】

    我的专栏目录: 小IVan:专题概述及目录 开篇综述 这一卷将会开始研究可交互植被环境的模拟.我把可交互植被环境模拟这个大的课题拆解为几个部分.我挑选了几个森林模拟至关重要的几个要素并且实现它们. [ ...

  7. 虚幻4渲染编程(材质编辑器篇)【第五卷:布料,丝绸纱皮革棉】

    My blog directory: 小IVan:专题概述及目录 Introduction: 现在的游戏对质感要求越来越高(我估计是硬件越来越好,可编程管线越来越来越完善).游戏的画面已经越来越接近影 ...

  8. 虚幻4渲染编程(图元汇编篇)【第五卷:游戏中的动力学模拟】

    我的专栏目录 小IVan:专题概述及目录 还是先上效果吧 目前(2018年)在游戏中,通常使用韦尔莱积分做动力学模拟.使用韦尔莱积分可以模拟大部分物体的运动.布料,绳子,弹簧,软体,棍子都可以模拟.但 ...

  9. 虚幻4皮肤材质_虚幻4渲染编程(材质编辑器篇)【第六卷:各向异性材质amp;玻璃材质】...

    My blog directory: YivanLee:专题概述及目录​zhuanlan.zhihu.com Introduction: 各向异性材质 玻璃材质 材质编辑器篇的很多效果都非常简单,可以 ...

最新文章

  1. 【LeetCode】121.买卖股票的最佳时机
  2. 定时器 Quartz
  3. Linux日志系统-02:logrotate简介
  4. 网络抓包工具wireshark and tcpdump 及其实现基于的libpcap
  5. python只能对列表进行切片_Python3:类型错误:列表索引必须是整数或切片,而不是s...
  6. XidianOJ 1176 ship
  7. 紧急通知:360 网站卫士前端公共库已停止服务
  8. 想打ACM?想刷题?来这些online judge!
  9. [11] ADB 实用功能
  10. 服务超时时间如何设置、如何对超时时间治理、超时设计原则一文揭秘!
  11. c语言系统关键词有哪些,C语言的那些关键字
  12. sybase相关的知识
  13. ubuntu16.04下安装wine及TIM
  14. 直流双闭环调速系统的计算机仿真,基于MATLAB的双闭环直流调速系统仿真研究
  15. 科普贴:示波器的组成
  16. 中兴光猫F412超级管理员密码获取
  17. fgo服务器维护补偿,FGO游戏内显示问题修复通知 全服补偿2个金苹果
  18. ks检验正态分布结果_看SPSS如何检验数据是否服从正态分布
  19. SAR图像的相干斑噪声
  20. windows恶意软件删除工具 MRT.EXE

热门文章

  1. C语言线上线下混合式教学,线上线下混合式教学探索与实践
  2. java赵云主角兵器谱游戏_完美武将:赵云兵器大盘点
  3. 牛顿黏度定律【Newton's Law of Viscosity】
  4. CSS--媒体查询是什么
  5. 2018年通信工程师交换技术考试成绩查询
  6. SpringMVC下载上传Excel文件
  7. WiFi 射频测试指标学习之路
  8. 一、Excel基础操作
  9. 整数表示---整型数据类型
  10. 集美大学计算机类专业排名,2019集美大学专业排名