最近尝试实现了一下光线追踪体积光,效果如下:

光线追踪(Ray tracing)是三维计算机图形学中的特殊渲染算法,跟踪从眼睛发出的光线而不是光源发出的光线,通过这样一项技术生成编排好的场景的数学模型显现出来。(摘自维基百科)

实现步骤:

一、在灯光区域生成体积光的载体mesh,即我们的体积光实际上是渲染在mesh上的,因此光线追踪的起点是每个顶点的位置,并计算出该顶点的视线方向,延视线进行递进:

二、在灯光空间生成深度图渲染相机:

我们需要在射线递进的过程中通过比较深度来判断是否当前点处于光线不可到达的遮挡位置,以此来渲染体积光中的阴影位置,这里我渲染了视空间深度(当然如果考虑直接使用unity的阴影贴图也可以,这样就可以直接为unity灯光添加体积光效果了):

Pass
{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct v2f{float4 vertex : SV_POSITION;float depth : TEXCOORD0;};v2f vert(appdata_base v){v2f o;UNITY_INITIALIZE_OUTPUT(v2f, o);o.vertex = UnityObjectToClipPos(v.vertex);o.depth = COMPUTE_DEPTH_01;return o;}fixed4 frag(v2f i) : SV_Target{return EncodeFloatRGBA(i.depth);}ENDCG
}

三、光线追踪:

为了在每次递进后可以方便的采样深度图,我将递进的过程放到了投影空间,并且在投影空间下可以方便的计算每次递进的距离:

for (float k = 0; k< RAY_STEP; k++) {float4 curpos = beginPjPos;float3 vdir = pjViewDir.xyz*k*delta;curpos.xyz += vdir;half cdep = LinearLightEyeDepth(-curpos.z);float boardFac = step(-1, curpos.x)*step(-1, curpos.y)*step(-1, curpos.z)*step(curpos.x, 1)*step(curpos.y, 1)*step(curpos.z, 1);curpos = ComputeScreenPos(curpos);half2 pjuv = curpos.xy / curpos.w;
#if UNITY_UV_STARTS_AT_TOPpjuv.y = 1 - pjuv.y;
#endif#ifdef USE_COOKIEfixed4 cookie = tex2D(internalCookie, pjuv);fixed3 cookiecol = cookie.rgb*cookie.a;
#elsehalf2 toCent = pjuv - half2(0.5, 0.5);half l = 1 - saturate((length(toCent) - 0.3) / (0.5 - 0.3));fixed3 cookiecol = fixed3(l, l, l);
#endifhalf dep = DecodeFloatRGBA(tex2D(internalShadowMap, pjuv)) / internalProjectionParams.w;float shadow = step(cdep, dep) *(1 - saturate(cdep*internalProjectionParams.w));col.rgb += cookiecol*i.vcol.rgb*delta / 2 * boardFac*shadow;
}

另外,考虑到在片段着色器下进行递进可能比较影响性能,可以尝试在顶点着色器下执行,注意如果在顶点着色器执行需要适当的增加载体mesh的顶点数量,否则可能无法达到较精确的效果,如下:

Demo GitHub链接请点击http://www.lsngo.net/2017/10/22/unityshader_volumetriclight/

更多文章:http://www.lsngo.net

【UnityShader】光线追踪体积光相关推荐

  1. UnityShader——挺进体积光

    原本是想找找体积雾的,无意中发现了 GPU Gems 3上的一篇屏幕特效实现体积光散射的文章,实现了一波发现文章里公式列的很高大上,结果具体实现却出乎意料的简单,只是通过像素的屏幕位置和光源的屏幕位置 ...

  2. UnityShader 实现简单的体积光

    现实中的体积光效果: 在生活中,我们常会看到类似这样的效果,也就是丁达尔效应. 其他游戏中的使用 例如深海迷航中的使用(P.S. 游戏真的很好玩,续集的零度之下也是非常nice的) Unity中的简单 ...

  3. UnityShader实战 之 体积光的实现

    大家好,我是Zander. 今天我们用Shader来模拟体积光.先看一下效果: 这是在ShadowGun场景里的一个实现效果. Shader代码如下: Shader "Custom/Blin ...

  4. UnityShader实现简单的体积光

    欢迎来到我的博客 又开始疯狂摸鱼了,药丸药丸!!!真是是间歇性踌躇满志,持续性混吃等死啊. 本篇文章用两种比较简单的方法实现了体积光,因为简单,所以瑕疵还是有的. 上图是百度百科的丁达尔效应那弄来的图 ...

  5. unity3d 求两个点长度_Unity3D实现体积光

    体积光是现实中常见的因丁达尔效应而产生的一种大气现象,文人墨客常用"慵懒的阳光泄下"描绘该现象带来的美感.笔者在一次旅游后见到了这种神奇的自然现象,遂决定在游戏中实现并使用这样的效 ...

  6. webgl径向模糊实现体积光

    体积光介绍 首先,我们要确认一下什么是体积光.体积光通俗来说是我们能看见的"光路",并不是所有灯光都会形成体积光效果,它是光照到大气中粒子散射后得到的效果(丁达尔效应).我们有时候 ...

  7. 【Unity Shader】聚光灯体积光效果的简单实现

    效果如下: Unity中的聚光灯SpotLight,可以用作手电筒,射灯等类似的效果,比如这样的 但是如果想把光束的效果做出来,就超出了SpotLight的能力范围了,本篇就为了记录一下一种简单的实现 ...

  8. 体积光 GodRay

    1.灯光控制系统 体积光属于一种室内灯光控制系统,其主要呈现一种灯光洒过某种介质后在物体周围所形成的一种光泽. 体积光的渲染方法: 先打开一盏主光灯,调好主光灯的参数,原地复制一个出来(但这时注意不要 ...

  9. Unity Shader学习:体积光/体积阴影

    Unity Shader学习:体积光/体积阴影 在前向渲染下实现平行光的体积光影效果,需要全屏深度图,延迟渲染会更划算. 思路:通过ray marching的步进点位置计算该点是否在阴影中,采样阴影贴 ...

最新文章

  1. 视频直播技术详解(0)开篇
  2. Reactive Extensions for .NET (Rx)
  3. php中strtotime的意思,php中strtotime函数用法详解
  4. 一张图搞定SDF的概念
  5. 2017-2018-1 JAVA实验站 第三周作业
  6. oracel 数据库问题 ORA-12547 ORA-12571
  7. 一般判五年几年能出来_A股十年不涨的“元凶”被揪了出来,指数不该被冤枉...
  8. 安卓手机端口号怎么查看_安卓手机来电闪光灯怎么设置
  9. 正在使用的项目,项目名那里出现了红色感叹号?怎么去除?
  10. LVS详解(六)——LVS DR模式实战
  11. 合并k个有序链表 python_leecode刷题(27)-- 合并k个排序链表
  12. 推荐一款在线文件对比工具
  13. 反射之前奏Oracle升级版
  14. UI设计初学者必备的工具以及学习路线(附思维导图)
  15. day64 url用法以及django的路由系统
  16. 频数直方图的步骤_把握步骤 正确绘制频数分布直方图
  17. OSChina 周一乱弹 —— 为什么人类和人工智能定要一战
  18. 在Linux中,_exit()、exit(0)、exit(1)、和return的区别!!
  19. 手把手教你批量剪辑视频
  20. Laradock启用RabbitMQ

热门文章

  1. UART串行通信模式
  2. 南部一名女子欲跳江轻生,已经被成功营救
  3. N32926 usb gadget 加 adb驱动, 插入USB线一点反应都没有。
  4. 最新手机制作抖音/西瓜沙雕动画教程+素材打包
  5. 用Python解决数据结构与算法问题(一):Python基础
  6. iOS开发:加载、滑动翻阅大量图片解决方案
  7. java 生成当天日期 昨天日期
  8. 基于MITRE ATTCK的Red Teaming行动实践
  9. 《计算机科学与探索》期刊投稿
  10. 他写代码如入定,人称阿里“扫地僧”