一个实用的实时毛发渲染及着色方法

Thorsten scheuermann

ATI Resarch,Inc.

翻译:潘曦

(译文里的(pancy:XXX)为译者注)

介绍:

我们提出了一个使用多边形模型的实时毛发渲染算法,并且将其应用于今年SIGGRAPH动画节上的一个实时动画《ruby:The Double Cross》上面。该毛发渲染算法是基于Kajiya-Kay 毛发渲染模型的算法,但是在其之上添加了一个实时的接近现实高光的镜面反射效果(pancy:原始算法可能没有考虑到头发的高光只计算了漫反射或者只是简单的模拟了镜面反射)。这个部分的工作主要由由 Marschner 等人来实现。此外,我们还定义了一个简明的渲染过程(pancy:图形引擎里面一般将一个渲染效果称作一个tecnique,暂且翻译为渲染过程),该过程将告诉大家如何近似达到back-to-front排序的效果来实现多层半透明毛发的渲染。(pancy:模拟back-to-front排序是ATI解决多层半透明渲染的重要GPU算法,在这篇论文下面会详细介绍),在以往的算法中,多层半透明材质的排序需要在每一帧里面依靠cpu来做,在我们的算法中这个方法将被摒弃,我们将依靠在gpu上进行多次渲染来做到对多层半透明毛发的排序。(pancy:这里解释一下为什么之前要对头发进行排序,半透明效果是通过alpha混合来产生的,但是alpha混合的缺点就是需要进行back-to-front排序,也就是说半透明是相对的,相对于在其之前绘制的物体才是半透明,在他之后绘制的东西则会完全盖住它。而头发模型只有一个,除非建模的时候分开否则就要由cpu来分层决定谁先绘制谁后绘制达到完美的半透明效果)

毛发模型:

我们算法所需要输入的模型是一种由很多层的2维多边形所模拟的毛发,这种多层模拟既很容易模拟头发细节,又可以凑成一套几何体。这种多边形模型非常容易进行渲染,因为他的顶点信息较少而能够降低vertex shader的载荷,并且其简化了多边形毛发的几何形状,使其易于进行back-to-front渲染。

该模型有两种最主要的纹理,其一是用于映射精细结构的映射,另一个是一组用于修补多层毛发之间不协调的不透明纹理。(pancy:毛发之所以需要半透明效果主要是由于毛发的发梢部分是逐渐渐透明的,这个效果是alpha-test不能代替的,但是多层毛发之间的不协调修补则不涉及发梢,可以作为完全不透明的材质)

毛发渲染:

1:漫反射部分:

我们使用了N-L偏移以及一个缩放来模拟漫反射光既:diffuse = max(0,0.75N*L + 0.25)(pancy:我们通常在计算漫反射光的时候是使用N*L作为漫反射角度的,而这篇论文通过上述公式,将头发的漫反射系数压缩到了一个比较小的区域,所计算的漫反射会比通常的计算效果色差更小,亮度更亮,不过大家可以根据自己模型的发质情况选择性的使用这个公式)这种计算漫反射的方法让头发的对光部分更加明亮,并且为整个头发创建了一个柔和的外观。

2:镜面反射高光:

我们用于模拟镜面反射光的基本方法是沿用了 Kajiya-Kay的着色模型,但是我们有更为新颖的做法。Marschner 等人指出头发应该有两种可以被肉眼辨认的镜面反射高光,其一便是头发表面直接所反射的光线,并且这部分光线会集中于头发的顶端。其二便是光线进入到很多头发组成的发束中,经过多次反射进入到观察者眼中(pancy:这个过程类似于环境光模拟要解决的问题,只不过是严格的高光经过了多次反射,如果要严格模拟必然会涉及到ray-tracing,不过这里既没有严格的头发模型,也不可能在实时渲染算法中出现ray-tracing,所以应该会根据这种光线的特点弄一些近似的算法)这种突出的高光颜色取决于头发的本身发色,并且它总是朝着头发的根部,并且外观也很杂乱。

为了模拟Marschner 等人发现的这一视觉效果,我们在每次渲染的时候会输入两个不同的镜面发射光源,这两个镜面反射光的颜色不同,镜面反射指数不同,并且,我们会根据头发丝的方向将这两个镜面反射光转换到相反的两个方向(pancy:大概就是一个顺着头发,一个逆着头发丝吧,这里就是为了模拟上一段提到的两种不同的镜面反射光),对于第二种镜面反射光,我们会通过一个噪声纹理来两次对其高光进行调整,这样就可以以极小的代价来实现类似于真实头发的闪烁外观(pancy:gpu shader没有很多内置函数,例如产生随机数,因此涉及到随机算法一般会传给shader一张由cpu产生的纹理来实现这个效果),为了得到两个沿着头发方向相反的镜面反射光方向,我们可以重新构造头发的表面切向量,通过使用用于各个层头发片的切向量以及头发片的法向量:T’ = normalize(T+s*N),其中s代表修改参数,根据这个参数取正或取负的不同,我们可以分别得到沿着头发指向发根,以及沿着头发指向发梢这两个不同的方向。这里为了修缮细节我们不会对一个头发片决定s,而是从纹理上来获得,这种方法类似于我们常用的法线贴图,只不过这里s是寻找头发的切线细节,所以我们称之为“切线贴图”

(pancy:正如我们之前所说,第二种镜面光想法不错但是实现难度很大,只能是近似模拟,这里他提到了用切线贴图,我解释一下这个名词,如果对于每一层的头发只使用一个切线,也就是那一层的多边形片所在平面切线,那么计算出来的高光就不是针对每个头发的,而是对那个多边形片的,因此他们想到了现在用于记录法线细节的法线贴图算法,也就是把头发的细节记录在一张图片上,当然只是切线细节而不是所有的细节。然后回头用的时候再根据uv坐标还原回去,这样就可以从视觉角度上还原一部分头发信息,当然这种方法是有缺陷的,比如不能平视等,顺便吐槽一下,如今曲面细分技术已经可以在大部分家用机器上实现了,所以这个算法应该可以再进行很大的改进吧例如切线位移贴图神马的云云.....当然只是吐槽,人家ATI或者NVIDA肯定有更好的方法渲染毛发了,今非昔比)

3环境光遮蔽部分:

我们为了简要的表示头发的自阴影,在程序的预处理阶段我们为每个顶点计算了一次环境光遮蔽,在最终的像素处理中,我们将像素的漫反射+镜面发射+ao的颜色综合作为像素输出。(pancy:这里基本上相当于啥都没说^O^,环境光遮蔽算法我说一下,这里基本上可以认为他们用的是SSAO了,环境光遮蔽主要是为了模拟环境光,也就是间接反射光线,跟上面的第二种镜面反射光差不多。不过真要准确模拟代价很大,因此就提出了”计算遮蔽”这种近似的算法。根据一个顶点前面没有完全遮挡住他的点来计算出一个环境光遮蔽值,如论文所述,对于毛发渲染来说这个算法也就是主要模拟头发自己遮蔽自己所造成的阴影)

近似深度排序渲染:

为了实现头发正确的半透明混合,我们必须还原头发模型之前的各个层面的深度顺序。我们在建模的时候就要先进行一遍处理,将个层头发根据它们离头部的距离进行排序,然后根据这个顺序记录将索引存放于静态的索引缓冲当中,然后再渲染的过程中,我们使用4个pass来描述我们的着色模型:

Pass1:

1,激活alpha-test,只允许不透明像素通过测试。

2,关闭背面消隐

3,激活深度缓冲区,设置其为less

4,关闭颜色缓冲区的写操作

这一步的pixelshader只返回alpha信息

Pass2:

1,关闭背面消隐

2,激活深度缓冲区,设置为equal

Pass3:

1,开启背面消隐,消隐掉正面

2,关闭z缓冲区

Pass4:

1,开启背面消隐,消隐掉背面

2,打开z缓冲区,设置其为less

(pancy:ATI著名的4-pass半透明渲染过程,大致思想就是前两个pass找到不透明的部分,把他们先绘制了,避免了透明部分遮住不透明部分这种尴尬的现象。然后再去正反两面绘制半透明部分,这样就能完美的绘制出半透明发梢,并且巧妙的避开了之前多层头发之间的互相遮挡所需要的多层排序问题)

提前的深度剔除( early-Z culling ):

我们之所以在第一个pass开启z缓冲区,因为激活alpha-test会让我们无法开启提前的z消隐(early-Z culling),我们提前将z缓冲区记录,然后使用通过z缓冲的像素来执行pixel shader是一种效率很高的做法。余下的三个pass都会由于这个提前的z缓冲区记录获得性能上的收益。(pancy:early-Z culling是指要求深度测试早于pixelshader,通常来讲,我们的z测试,模板测试等测试都是在pixelshader之后的,而将其提前的话在某些算法里面可以消隐掉很多不该出现的面,节省很多的资源,比如说这里的多层半透明毛发渲染)

我们的头发渲染方案最大的优点就是不需要在运行的每一帧都用cpu对头发进行空间上的排序,但是我们的算法只能对头发模型进行一些“温和”的动画,也就是说不能把头发片移动的过于相关联(pancy:大概就是头发不能完全按照物理模型相关联的受力,比如这片撞到了那一片然后一起运动一类的)。如果不符合这个假设的话。暂时还是只能依靠cpu基础的运行时逐帧毛发排序

一个实用的实时毛发渲染及着色方法相关推荐

  1. 4毛发渲染及着色方法

    一个实用的实时毛发渲染及着色方法 Thorsten scheuermann ATI Resarch,Inc. 翻译:潘曦 (译文里的(pancy:XXX)为译者注) 介绍: 我们提出了一个使用多边形模 ...

  2. bfgs sherman_介绍Sherman(第2部分)–一个Unity项目,其中包含动画师的实时毛发,HDRP和Visual FX Graph

    bfgs sherman Created by the Emmy-winning team that brought you Baymax Dreams, Sherman is a new real ...

  3. 剖析Unreal Engine超真实人类的渲染技术Part 3 - 毛发渲染及其它

    目录 四.毛发渲染 4.1 毛发的构造及渲染技术 4.1.1 毛发的构造 4.1.2 Marschner毛发渲染模型 4.1.3 毛发的间接光照 4.2 毛发的底层实现 4.3 毛发的材质解析 4.3 ...

  4. 毛发渲染(一)--基于多pass透明混合

    作者最近有些忙哈哈哈,连这篇文章还在年前拖到了年后才更新完成!这里只简单比较叙述多pass的基本原理,与毛发各种的渲染模拟的比较等等,后续会更详细描述毛发相关的渲染~ 毛发渲染模拟的简介: 毛发渲染一 ...

  5. 怎样对ZBrush中的材料进行渲染和着色

    ZBrush可以实时的进行不断的渲染和着色. 对于绘制操作,ZBrush®增加了新的范围尺度,可以让你给基于像素的作品增加深度,材质,光照和复杂精密的渲染特效,真正实现了 2D 与 3D 的结合,模糊 ...

  6. 美摄云非编系统——网页端实时编辑渲染方案

    美摄云非编是一款新型网页端非线性编辑工具,应用WebAssembly技术实现网页端直接渲染图像.本次LiveVideoStackCon 2020线上峰会我们邀请到了北京美摄网络科技有限公司的研发总监黄 ...

  7. 实时渲染、离线渲染、实时云渲染、混合渲染是什么?

    渲染,就是将 3D 模型转换成 2D 图像,并最终呈现在屏幕上的过程.虽然这里只有一句话,但是这一句话里面包含了太多的数学.物理和计算机方面的知识,它描述了我们用计算机来虚拟化真实世界的基本逻辑.渲染 ...

  8. 基于区域求和表的实时体渲染环境光遮蔽和光晕技术

    对于体模型来说,很多光学效应都很难实时生成.它们可能对渲染时间有重要影响,或者它们需要预先计算,阻止了以交互方式更改传递函数,因为它决定了遮挡. 本文提出了两种在体模型上快速生成环境遮挡的方法: 第一 ...

  9. 在线非线编系统——网页端实时编辑渲染方案

    本次我分享的主题是云非编系统,是一种web端视音频实时编辑渲染方案. 本次内容分为五个部分: 是美摄云非编方案的技术背景,也就是目前web端视音频编辑的现状以及我们采用新方案的原因: 是美摄云非编的技 ...

最新文章

  1. c语言流程图图裂代表的意义,程序流程图的意义
  2. Ueditor富文本添加视频内容,视频不显示以及编辑富文本时,视频不显示解决方案
  3. ICCV2019最佳论文SinGAN全面解读,看这一篇就懂了
  4. Newton-Raphson method
  5. 开放寻址法VS链表法
  6. Eclipse相关快捷键
  7. maven项目引用新模块,依赖的jar包与新模块中的jar包版本不一致
  8. SharePoint Designer 2010中的外部内容类型-SQL Server
  9. java实现梯度异步通知,BIO原理及代码实现
  10. 用php做动态时钟,vue实现动态时钟以及日期
  11. 计算机课件制作技能,PPT技能制作大比拼
  12. lookup基础用法
  13. android 闪屏 实现,Android游戏闪屏实现步骤详解
  14. git push 提交失败
  15. 数据推荐 | 自然对话语音数据集
  16. 【Python小工具】若干图片合并生成动态图(.gif)
  17. MBR与GPT(GUID)的区别及使用方式(偏实际操作)
  18. HTTP请求,出现Status Code: 405
  19. ajax请求失败readyState为0
  20. 孙陶然:有能力的第一个标准是解决问题

热门文章

  1. 迷宫寻径问题(数据结构4.4.3)
  2. 最基础的协同过滤介绍
  3. 又来了!10分钟实现微信 “炸屎“大作战
  4. datagridview获取行中列的数据
  5. RFID固定资产管理降低人工成本,实现智能化的管理-新导智能
  6. c++编程题2——ISBN计算识别码
  7. PHP中调用http接口
  8. Mac安装brew,国内推荐使用
  9. 浅谈Web App前端设计原则
  10. 2012年第23周限时免费游戏应用点评