哈喽,大家好,我是搜狐畅游引擎部的TA老胡,很高兴有机会和大家分享一下前一段时间工作和学习的成果。

前一阵,我做技术支持的项目提出,想要一个效果好一点的,眼睛的解决方案。

Unity自带的渲染部分,包含内容的丰富程度大家都是了解的,稍微有针对性一些的表现,就基本指望不上了,于是花了一些时间,研究学习了一下眼睛相关的知识,下面,就来和大家分享一下相关的内容。

先来看看最终的效果是什么样子的。

目前眼球实现的功能有,瞳孔的缩放,黑眼球整体的缩放,虹膜的颜色,角膜的折射,眼睛的焦散,眼睛的环境反射,眼球的次表面散射,角膜环的控制,上眼皮的遮蔽,眼底的液体,以及一些细节的调节等。

进入主题,按惯例,先从眼睛结构讲起。

眼睛的结构比较复杂,渲染的部分,基本只涉及到瞳孔,虹膜,巩膜,角膜这几个部分,这里引用Next-GenerationCharacter Rendering中的描述来说一下这几个部分。

巩膜 是眼睛的白色部分

虹膜 是彩色部分

瞳孔 是虹膜内的黑色部分

角膜 是覆盖所有这些元素的透明薄层,也是眼睛中发生的折射现象的起源

光线和视线穿过角膜和前方的房水,产生了折射后,到达了虹膜,所以要想产生眼睛的立体效果,就需要模拟折射的效果。

但是眼球中只有角膜区域(俗称黑眼仁)才会有折射产生,巩膜覆盖的区域(俗称白眼仁)并不会有折射效果,所以在计算折射前,先需要把角膜和巩膜的区域区分出来,这样就可以分别对两个区域做不同的计算了。

介绍怎么区分角膜和巩膜前,我们先看看眼睛模型的相关做法,这里主要分为了两个部分,一个部分是眼球,就只是个半球体。如下图

角膜,虹膜,巩膜,瞳孔的表现都是在这里进行的。

UE数字人Meet Mike和Next-GenerationCharacter Rendering中的眼球模型其实都是角膜部分有凸起的,如下图

这样在计算折射时,更容易产生比较好的效果。

但是这样的模型在眼球转动时,容易和外面那层半透明的模型产生交叉,凸起的规格又和shader计算上有一些关联,制作的不标准,反而会影响效果,美术制作起来会麻烦一点,所以我直接采用了半球型,大概效果上也不会差很多。

第二个部分,是内眼角,眼底的液体,睫毛和上眼皮对眼球的投影。模型是这样的。

这种做法,在游戏里应该已经很常见了,大家想必也很熟悉。

这样做,上眼皮对眼球的遮蔽和投影不会随着眼球的转动而跟着改变。眼球和下眼皮模型之间生硬的过渡,也可以产生柔和的效果。

这部分模型,使用半透明渲染,因为结构比较简单,正常屏幕占比又不会太高,所以基本不会和其他半透明物体产生排序问题。

这个部分主要是模型和贴图的工作,这里就不详细讲了。

现在我们来说怎么区分角膜和巩膜,这里虹膜和巩膜分别采样了两张单独的贴图,采样贴图时所使用的UV也是不同的。下面是虹膜和巩膜的贴图。

不过因为我们还做了眼球整体缩放的功能,所以角膜和巩膜的UV是需要在整体缩放的UV基础上做的。

整体缩放的功能比较简单,是通过以UV中心点为基点进行缩放。代码如下

Scale是传入的缩放值。

这种缩放方法,Scale值越大,模型的UV越向(0.5,0.5)的位置收缩,显示的结果就是贴图放大的效果。

基础的眼白贴图(巩膜)就可以使用缩放后的UV进行采样了。

接下来要计算出虹膜的mask区域。

使用缩放后的UV和UV的中心点(0.5,0.5)求距离,可以得到一个中间点为0,向外逐渐渐变成灰度的值,因为UV的边缘距离中心点的距离最大也不会到1,所以最亮也只是灰度值。如下图

然后我们再减去一个虹膜的半径值,可以得到一个随着半径值变大或者变小的黑色圆形区域。

半径值为0.2和0.35时的样子,半径值为shader传进来的参数。

作为mask图,我们需要的是尽量只有白或者黑的图,所以我们把结果再除以一个比较小的值,这样大于0的值,就会放大很多倍,变成白色,小于等于零的值,则依然小于等于零,显示黑色。

这样我们就可以得到一个这样的值。

再反向一下,就可以得到一个虹膜的mask图了。最后记得要把值,规范到0和1之间。

并且,因为我们使用的是有缩放功能的UV值,所以mask区域除了可以使用半径值单独缩放,也是可以随着UV的整体缩放一起缩放的。

这样,我们已经有了采样后的巩膜,还有区分巩膜和角膜的Mask。

下面就该角膜部分的计算了,因为要在单层半球模型上表现出外层透明角膜和内层彩色虹膜的效果,需要在采样虹膜贴图时,对UV进行偏移,因为还需要瞳孔缩放的功能,所以还要加上缩放,这部分也是眼睛渲染中比较复杂一点的地方。

虹膜UV的偏移方式大致上有两种,一种是使用视差贴图的方式,一种是基于物理的折射。

下面是Next-GenerationCharacter Rendering中提供的两种方法的基本算法。

视差贴图的方式计算比较简单,基于物理的折射,计算上要复杂一些,但效果也会更好一些。

我这里采用了基于物理的折射。实现方法和UE数字人Meet Mike的折射算法基本一致。

我们先看一下Meet Mike中折射的大概蓝图。

还是比较复杂的,里面还有些代码处理的自定义节点,不过下载工程后捋一遍,还不算太困难。

下面先来看一下,计算需要准备那些参数。

我们需要入射方向,这里是使用视线的方向,也就是观察方向。这个比较容易求出来,不多说。

我们还需要视线经过角膜折射后的方向,这个要怎么求出来呢,我是直接搬运的UE中的算法,如下图。

airIOR是空气中的折射率,internalIOR是射入角膜的折射率,这个网上可查,一般在1.3-1.4就可以。这样就可以求出折射后的方向。

还需要一个虚拟虹膜的法线方向,也就是上面图中的frontNormal,这个要怎么得到呢,这个是通过一张法线贴图得到的,图如下

图来自UE的数字人工程。

可以看出来,左侧的适合眼球模型有凸起,右侧的适合没有凸起的。

为什么这个图可以得到虹膜的法线呢?如果想要自己制作,又要怎么制作呢?

我们通过下面这个图来想象一下,假设虹膜是眼球中的一个plane,plane前面的球形部分是角膜,那么,如果把这个plane的法线烘焙到球形上,就会得到类似上面的法线图。

然后当我们采样这张图,再把法线贴图转换成法线向量时,是不是就可以得到类似虹膜的法线了。

我们还需要角膜各个部分到虹膜的高度,即下面图中红色箭头的长度值。

因为虹膜是虚拟的,并没有真实的模型,所以需要通过取巧的方式获得。

在UE的Meet Mike项目中,是使用了一张HDR格式的HeightMap来获得的,如下图。

这张图的数值范围,大概是从0-2,为了节省一点点,我使用的是普通的从0到1的一张图,采样后,又乘了2。精度上应该没有HDR的准确,不过效果上看,也可以接受。

这样,就有了折射计算所需要的基础数据,结合之前计算出来的角膜UV,就可以计算出折射后的UV偏移值还有一个IrisMask的数值了。

具体的计算还是比较复杂的,对细节过程感兴趣的同学,可以下载Meet Mike的工程,查看ML_EyeRefraction的详细计算。

或者看看文章末尾列出的YivanLee大佬 的那篇文,里面有比较详细的代码计算步骤。

使用折射后偏移的UV和IrisMask采样虹膜的贴图,就可以得到有折射效果的眼球了。

到此,眼球区别于其他常见类型的渲染部分,就差不多说完了,剩下的光照计算部分,其实和普通的PBR渲染差不多,我们就只说说不太一样的部分和一些小调整。其他的基本光照计算,这里就不详细说了。

首先,为了眼球能有一个比较漂亮的高光,在眼球shader中,在光照方向计算时,给眼球添加了一个Y轴旋转的高光偏移值,这样可以解决场景中的光照角度比较大时,眼球的高光点位置会被眼皮遮挡的问题。示意图如下。

这样就可以在不影响场景光照的前提下,给眼睛一个合适的光照方向。

光照角度X为30时,无偏移的效果

偏移后的效果

然后眼球还需要一个单独的cubemap来计算反射,并需要给这个cubemap一个旋转值,这样可以调整到最合适的反射角度,让眼睛有一个好看的反射光斑。

上面的图是使用了不同反射球的效果。

因为眼睛的反射需要的是少量的亮斑,所以需要的反射球尽量是亮暗对比比较强烈的,效果才会比较好,大家可以多多尝试一下。

还有焦散的计算,因为眼球的结构,虹膜从边缘到瞳孔的位置,其实是有一些内凹的,所以当光线从眼睛的右上方向照过来时,照亮的却是虹膜的左下部分。

图中可以看出来整体的光照方向,是从左侧照过来的,虹膜接受光照的位置是右侧。

这样,就需要一个凹陷的法线来参与光照计算了,这个凹陷的法线,可以通过反向眼球本身的法线来获得,当然我们只需要角膜范围内的部分就够了。

Meet Mike项目的眼睛ShadingModel中,还对这个凹陷的法线进行了一些加工,用虹膜的法线(就是前面通过一个plane烘焙出来的那张)和凹陷后的法线进行lerp融合,决定lerp融合的参数是通过折射计算出来的IrisMask。下面是UE中具体的焦散算法。

具体的代码,可以在ShadingModels.ush中的EyeBxDF函数中找到。我的焦散基本上采用了UE的这种方法,只是有一些简单的微调,方便美术调节

其实眼球的整体实现还是挺复杂的,说了这么多,还是有很多细节没有讲到,如果以后有机会,可以再更完整的聊一聊,这篇就先说这么多了。

最后,我们看一下完成后的动态效果。

到这里,关于眼球的渲染分享,就结束了,写写大家耐心观看,再见^_^。

在学习和实现的过程中,主要参考了以下的内容:

1向往大佬发表在博客园的文章《剖析Unreal Engine超真实人类的渲染技术》中的眼球篇

https://www.cnblogs.com/timlly/p/11144950.html

2 YivanLee 大佬在知乎上的文章 虚幻4渲染编程(人物篇)第三卷:Human Eye Rendering

虚幻4渲染编程(人物篇)【第三卷:Human Eye Rendering】 - 知乎

3 UE官方在GDC2017分享的 数字人类 Meet Mike,在虚幻商城里,可以免费下载到完整工程。

4 GDC2013上的Next-GenerationCharacter Rendering PPT

http://www.iryoku.com/downloads/Next-Generation-Character-Rendering-v6.pptx

还有一些网上零零碎碎的知识。

感谢众多大佬的无私奉献,当然,还是UE最给力。

一句话总结这段学习和研究:俺不生产知识,俺只是知识的搬运工。

渲染TA实战:眼球的渲染相关推荐

  1. 渲染TA实战:三方向映射 UE4

    大家好我是来自搜狐畅游引擎部TA组的小源小榞小圆,这次是分享关于三方向映射纹理的做法. 三方向映射在制作地形贴图,和一些需要在任意角度覆盖模型的材质会比较常用到.比如苔藓.污渍.锈迹.以及最常用到的地 ...

  2. 渲染TA实战:冰面效果制作分享

    序 Hello大家好我是来自引擎部ta组的小圆,这次为大家介绍多层采样的冰面制作的分享.这个效果的特点在于:使用视差+多层采样实现了表面的凹凸起伏和具有深度的裂纹效果. 本次分享的包含: Substa ...

  3. 渲染TA实战:摄影测量游戏模型制作指南

    hi,大家好~我是来自搜狐畅游引擎部的美术向技术美术,小源小榞小圆,来到我们畅游引擎部门马上就要两年了.这次应部门老大邀请做一次分享.主要为摄影测量的实践细节. 为什么分享的主题是摄影测量游戏模型制作 ...

  4. 毛发及眼球的渲染技术

    前言 这是关于角色渲染技术的第二篇,前一篇关于皮肤的渲染方法可见这里. 实际上为了逼真地还原一个角色,除了渲染技术外,在很多游戏中还使用了动画.物理仿真等其他方面的技术,这些技术也非常重要.譬如今年的 ...

  5. unity中实现ue眼球的渲染

    此图取至ue官方网站 在shader里面我们还是需要使用英文,中英文对照: 巩膜:sclera 角膜缘:limbus 虹膜:iris 瞳孔:pupil 角膜:cornea 渲染效果. 模型方面: 使用 ...

  6. 微信小程序入门与实战之条件渲染、列表渲染与小程序事件

    使用LinUI的Icon组件代替图片ICON 引入LinUI的icon库: "usingComponents": {"l-icon":"/minipr ...

  7. 图片渲染延迟_前向渲染与延迟渲染

    如果您开发过3D游戏,那么您可能会在现代图形引擎的研究中遇到术语"前向渲染"和"延迟渲染". 而且,通常,您必须选择一种在游戏中使用.但是它们是什么,它们有什么 ...

  8. 浏览器渲染机制面试_浏览器渲染原理

    本文目录结构 问题 浏览器渲染原理 渲染过程 1. 浏览器接收到 HTML ⽂件并转换为 DOM 树 当我们打开⼀个⽹⻚时,浏览器都会去请求对应的 HTML ⽂件.虽然平时我 们写代码时都会分为 JS ...

  9. 图片渲染延迟_2D Canvas 的渲染优化

    简介 HTML 上的图形渲染主要有两种方案 SVG 和 Canvas,前者更易于使用,而后者潜力更大,本文主要关注如何使用 Canvas 绘制出更多的图形,提供更加流畅的交互.本文的内容有: 渲染机制 ...

最新文章

  1. Linux下设置进程使用指定核的CPU
  2. 马斯克连发三推,发布退出OpenAI内情
  3. linux下如何查看文件大小 快速找到最大文件的方法
  4. poj 2201(RMQ+笛卡尔树)
  5. 使用Chrome的timeline工具分析web应用性能
  6. 数据结构进阶篇-跳表
  7. SpringBoot热部署加持
  8. word2vector数据集样式_这样做数据可视化驾驶舱,高端大气,一目了然,领导不点赞都难...
  9. 【redis】redis实用Utils
  10. log4j1升级log4j2
  11. [Python] L1-028. 判断素数-PAT团体程序设计天梯赛GPLT
  12. php 有趣的php 封装,封装PHP常用的操作类
  13. 计算机网络实验报告3-tcp,计算机网络实验报告3 TCP
  14. java gson解析JSON
  15. python各城市对应的省_python实现城市和省份字典(根据城市判断属于哪个省份)...
  16. failed to solve with frontend dockerfile.v0: failed to create LLB definition: failed to copy: httpRe
  17. ruby 安装问题的 一二事
  18. 单阶段和两阶段目标检测
  19. Vue——May(1)
  20. echarts条形图

热门文章

  1. 一条命令导出电脑中所有wifi账号密码
  2. CollageIt 3 Pro for mac(拼贴精灵3专业版)
  3. 根据出生日期自动计算年龄
  4. 程序员加薪升职之成长金字塔
  5. 诸葛java_java - 诸葛_子房的个人空间 - OSCHINA - 中文开源技术交流社区
  6. 60度斜坡怎么计算_坡度怎么计算
  7. GoogleMap+renderDoc获取地图3D模型
  8. python内置模块re_13.python内置模块之re模块
  9. 华科计算机保研复试题目,华科计算机保研复试机试题目2.doc
  10. Ionic React和Capacitor入门