https://blog.csdn.net/noahzuo/article/details/51162472

在游戏中,头发一直是比较难以驾驭。头发难的地方有三块,一在模拟,二在着色,三在工具链适配。目前很多游戏的开发通常都会避免长发和散发,只采用短发。

但是哪怕是短发,其着色也是非常重要的一环。


我自己也看到有不少团队的头发完全使用贴图来进行着色。这样的着色的优点在于在特定的光照与摄像机角度下能够有很精彩的表现,但是如果光照条件与摄像机角度变化后,头发的表现就会非常怪异。

这篇博客介绍了Kajiya-Kay Shading,一种简单而酷炫的头发渲染着色器,原文传送门。

Kajiya-Kay Model

Kajiya-Kay Model与其他Shading Model显著不同一点的就是它使用的是发丝的切线而不是这一点的法线来进行计算。在这个模型中,Specular N.H为:

sin(T,H)speculartiy=1−dot(T,H)2−−−−−−−−−−−−√speculartiysin⁡(T,H)speculartiy=1−dot(T,H)2speculartiy

而不是:

dot(N,H)specularitydot(N,H)specularity

但是需要注意的是,Kajiya-Kay的着色模型需要比较正确的自阴影。否则相对来讲会太亮。

Vertex Shader

VS没有什么特别的,仅仅是将T, N, V, L, AO这些数值传递给PS。

Pixel Shader

  • Diffuse Lighting. 
    Kajiya-Kay 的diffuse可以使用衰弱的N.L,也可以使用sin(T, L)。正如前面提到的,sin(T, L)需要有自阴影,否则会太亮。

  • Specular Highlights 
    在Kajiya-Kay的着色模型中,我们有两个偏移的Specular量,从而表现头发的高光(下图来自本人小妹的自拍)。

Specular Highlights

为了产生沿着发丝方向偏移的高光,我们需要将切线沿着法线方向进行一个偏移,如下图:

正向的偏移意味着向发根的高光偏移,而负向的偏移则意味着偏向发梢。

在这个着色模型中,我们通过一张纹理来表示偏移量:

代码如下:

float3 ShiftTangent(float3 T, float3 N, float shift)
{float3 shiftedT = T + (shift * N);return normalize(shiftedT);
}

发丝光照

在这个着色模型中,我们使用半角向量(half-angle vector)。用reflectionview向量也可以,但是会使Shader略显复杂。

在两个高光中,可以使用不同的颜色、specular exponent以及不同的切线偏移度。第一层高光可以直接计算,而第二层高光表现的主要是闪耀的情况——通过noise texture进行调整。

代码如下:

float StrandSpecular(float3 T, float3 V, float L, float exponent)
{float3 H = normalize(L + V);float dotTH = dot(T, H);float sinTH = sqrt(1.0 - dotTH*dotTH);float dirAtten = smoothstep(-1.0, 0.0, dot(T, H));return dirAtten * pow(sinTH, exponent);
}

值得一提的是,对于dirAtten这个变量的意义我一直不太了解,在stackoverflow上面找到了答案,传送门。

最终代码

float4 HairLighting (float3 tangent, float3 normal, float3 lightVec, float3 viewVec, float2 uv, float ambOcc)
{// shift tangentsfloat shiftTex = tex2D(tSpecShift, uv) - 0.5;float3 t1 = ShiftTangent(tangent, normal, primaryShift + shiftTex);float3 t2 = ShiftTangent(tangent, normal, secondaryShift + shiftTex);// diffuse lightingfloat3 diffuse = saturate(lerp(0.25, 1.0, dot(normal, lightVec)));// specular lightingfloat3 specular = specularColor1 * StrandSpecular(t1, viewVec, lightVec, specExp1);// add second specular termfloat specMask = tex2D(tSpecMask, uv); specular += specularColor2 * specMask * StrandSpecular(t2, viewVec, lightVec, specExp2);// Final colorfloat4 o;o.rgb = (diffuse + specular) * tex2D(tBase, uv) * lightColor;o.rgb *= ambOcc; o.a = tex2D(tAlpha, uv);return o;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

最终效果

以后会在Unreal Engine 4中实现Kajiya-Kay Shading……

<全文完>

【头发渲染】Technical Artist的不归路 —— Kajiya-Kay Shading相关推荐

  1. Technical Artist的不归路 —— Kajiya-Kay Shading

    在游戏中,头发一直是比较难以驾驭.头发难的地方有三块,一在模拟,二在着色,三在工具链适配.目前很多游戏的开发通常都会避免长发和散发,只采用短发. 但是哪怕是短发,其着色也是非常重要的一环. 我自己也看 ...

  2. Technical Artist的不归路 —— 创建游戏世界前团队交流之我见

    这篇博客介绍了我认为的在游戏世界创建之前,整个开发团队需要着重交流沟通的一些事项.在这些事项上详尽的沟通将能够对于避免设计矛盾,中期返工等有一定的帮助. 这篇博客不涉及到如何进行游戏世界的创建,而将着 ...

  3. Technical Artist 的不归路 —— 场景构图中的物件

    这篇博客介绍了在游戏场景中进行构图的时候对物件摆放的一些需要注意的点. 自然物件的摆放 自然物件,例如树木.岩石和植被之类,它们的摆放都需要注意在任意摆放与太过整齐之间找到一个平衡点.完全任意的物件摆 ...

  4. 各向异性渲染(二)Kajiya Kay头发渲染

    介绍 基于之前的各向异性得结果,我们可以再推广到头发渲染.Kajiya Kay头发渲染是一种经验模型.它把头发模型为一条一条细管.然后利用上一章的数学基础,但当然Kajiya Kay也加了几个细节.包 ...

  5. 雷军:同事格式化了我的电脑,让我走上当CEO的“不归路”

    12月22日,是金山软件创立30周年纪念日.1991 年,雷军遇到了属于他的伯乐--求伯君,1992 年,雷军参与创办金山软件,成为了金山的第6号员工,1998年出任金山软件CEO,到2007年,金山 ...

  6. 图形学基础|各项异性与头发渲染

    图形学基础|各项异性与头发渲染 文章目录 图形学基础|各项异性与头发渲染 一.前言 二.各向异性光照 2.1 各向异性光照现象 2.2 ShadingModel扩展 三.头发光照模型 3.1 Kaji ...

  7. IT认证不归路、CCIE高失业率

    附件: IT认证不归路 CCIE 高失业率一族.zip [1.72 MiB] 被下载 482 次 引用: 这个帖子是2003年9月份发的,作者背景简介: 1.刚毕业时做×××电脑管理员(其实就是一份零 ...

  8. 4.1 陷入不归路的调试-机器学习笔记-斯坦福吴恩达教授

    陷入不归路的调试 在线性回归中,我们使用了如下的代价函数来评估预测误差: J(θ)=12m[∑i=1m(hθ(x(i))−y(i))2+λ∑i=1mθj2]J(θ)=\frac1{2m}[∑_{i=1 ...

  9. web前端 真是一条不归路,2年前的文章 如今依然影响很多人

    「 矫  情 」 这个web前端入坑系列是2年前也就是16年开是写的,如今依然影响了很多人.到目前为止每天的新关注粉丝很多一部分还是看了我的入坑系列关注我的,所以这系列文章被一些调皮的铁粉戏称为:震号 ...

  10. PBR渲染(四)——PBR头发渲染

    PBR头发渲染 1.渲染方案 首先在光照模型的选择上,选择了Marschner基于物理的理论模型. 理论模型:头发不是完美的圆柱体或管子,实际上,头发更像是一系列堆叠的圆锥体.每一根头发纤维由角质层( ...

最新文章

  1. python标准库介绍——23 UserString 模块详解
  2. Machine Learning——DAY1
  3. 业界首发|阿里云重磅发布云原生架构白皮书
  4. 为什么我们批评C++?又爱又恨的垃圾回收机制
  5. Spring-data-redis集成提交数据出现'maxActive'和‘maxWaitMillis’错误
  6. 来了,单片机最强科普总结!
  7. ASP.NET中下载文件的几种方法
  8. 如何将你的 MySQL 查询速度提升 300 倍
  9. 计算机软考高级科目试题及答案,软考高级哪个含金量高 2018计算机软考信息系统项目管理师单选试题及答案...
  10. IntelliJ IDEA主题修改
  11. PageHelper分页pageSize和total异常问题
  12. 用户DSN、系统DSN、文件DSN的区别
  13. python-安居客-郑州二手房销售信息抓取
  14. java 计算一个月有多少天和多少周
  15. 51单片机c语言学习感想,学习51单片机心得体会
  16. 设计模式-->结构型模式-->代理模式
  17. 最大似然函数及其求解
  18. 【文章思路、算法分析】Membership Inference Attacks Against Machine Learning Models
  19. 如何利用MATLAB对多项式进行计算?
  20. 查看java安装路径[linux]

热门文章

  1. 利用PIN码破解wifi密码(WPA2-PSK)
  2. 大火的何铠明:MAE——用于计算机视觉的可扩展自监督学习神器
  3. 【Golang】查找-学习笔记
  4. 笔耕不辍 elementUI el-tree实现懒加载和直接查询实现
  5. PC端微信图片的解密
  6. pip安装第三方库 报错:You should consider upgrading
  7. oracle的em能干什么,Oracle中EM的配置
  8. 应用于arcgis的代码,长期更新…
  9. Klog开发笔记——分页插件 Kaminari 介绍
  10. 现代化SharePoint经典网站