修正半透明头发的渲染异常

这两天在整理 小甜甜 的捏脸系统,顺带把前项目 半透明头发渲染异常的bug 修正了,效果如下:

其实,前项目的头发工作良好,只是有一点 半透明渲染顺序 的小瑕疵,但正如前文 一个自阴影的Bug 所提到的:我在迁移shader的时候因为偷懒,把头发改成了 Surface Shader,从而带来了一些新的问题。


问题一:关于Surface Shader的alpha指令

首先,我犯了第一个错误,改 Surface Shader 的过程中,我漏掉了 alpha 指令的设置,shader变成了 实体渲染,表现如下:

关于 Surface Shader的alpha指令,可以参考Unity帮助文档:

alpha or alpha:auto - Will pick fade-transparency (same as alpha:fade) for simple lighting functions, and premultiplied transparency (same as alpha:premul) for physically based lighting functions.

alpha:blend - Enable alpha blending.

alpha:fade - Enable traditional fade-transparency.

alpha:premul - Enable premultiplied alpha transparency.

虽然我指定了 Queue = TransparentBlend SrcAlpha OneMinusSrcAlpha,但因为没设置 alpha,Unity最终生成的代码给我加了这么一句:

UNITY_OPAQUE_ALPHA(c.a);

UNITY_OPAQUE_ALPHA定义如下:

#define UNITY_OPAQUE_ALPHA(outputAlpha) outputAlpha = 1.0

这里认为是 实体渲染,强制的把alpha设置为 1 了。

修正这个问题很简单,加上 alpha 指令的设置即可:

#pragma surface surf BGHair fullforwardshadows addshadow vertex:vert alpha

问题二:半透明的渲染顺序

加上 alpha 后,头发通透了好多,但是新的问题来了,当 头发的半透明部分相互交错 时,渲染表现错误:

因为是半透明渲染,Surface Shader生成的代码开启了 深度测试,关闭了 深度缓冲写入,当 半透部分相互交错 时,前后关系难以保证。

这是半透材质经常遇到的问题,我们可以把头发模型拆成 实体半透 两部分,先渲染 实体部分,再渲染 半透部分,在实体的基础上做Alpha混合,从而尽可能避免半透交错的机会。

不过当初做这个头发的时候,并没有拆分模型,做法也很简单:开启 深度缓冲写入,让头发的半透明部分仅局限于 发尾,由于半透区域很小,一般情况下很难穿帮,不过某些角度下细看还是会有问题。

比如下图红圈标注的部位,后面的头发因为 深度测试 没通过,导致前面的头发直接和背景混合,引发了表现错误。

此外,因为迁移到了 Surface Shader,我发现如果打开了 alpha 指令,无论我是否指定 ZWrite On,Unity给我生成的代码始终是 ZWrite Off 的。


解决方式一:用AlphaTest代替AlphaBlend

如果这里我们用 AlphaTest 来取代 AlphaBlend ,效果会如何呢?

作为测试,简单的加一句 clip,并且关闭 alpha 指令:

clip(mainColor.a - 0.6);

效果如下:

渲染正确了,只是发尾太硬,用美术的话说:不够透气


解决方式二:加一个Pass

方式一 不够完美,不过我们可以用它做一个 额外的Pass,类似拆分模型后的 实体部分渲染,渲染完毕再做之前的 半透明渲染

代码如下:

Pass
{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"sampler2D _MainTex;float4 _MainTex_ST;half4 _Color;half4 _Color2;half _Color2Offset;struct appdata            {float3 pos : POSITION;    float3 uv0 : TEXCOORD0;   UNITY_VERTEX_INPUT_INSTANCE_ID};struct v2f {UNITY_POSITION(pos);float4 uv0 : TEXCOORD0;UNITY_VERTEX_OUTPUT_STEREO};v2f vert (appdata IN){v2f o;UNITY_SETUP_INSTANCE_ID(IN);UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);o.pos = UnityObjectToClipPos(IN.pos);o.uv0.xy = TRANSFORM_TEX(IN.uv0, _MainTex);return o;}half4 frag(v2f IN) : SV_Target{half4 mainColor = tex2D( _MainTex, IN.uv0.xy );clip(mainColor.a - 0.999);half3 hairColor = _Color.rgb * mainColor.r;half mixStrength = saturate(mainColor.g + _Color2Offset);hairColor = lerp(hairColor, _Color2.rgb, mixStrength);return half4(hairColor, 1);}ENDCG
}

代码很简单,最主要的就是下面这句:

clip(mainColor.a - 0.999);

这里把原来的半透部分尽可能的裁剪掉,只保留实体的轮廓,如下:

在这个基础之上,再做一次半透明渲染即可。


局限

采用 方式二 后,原先 发尾 部分因为 半透重叠 引发的 渲染瑕疵 也可以更大程度的缓解了,如下图:

此外,需要注意的是,这里能良好工作,头发的半透部分仅局限于 发尾 也是一个重要因素。

最后换个脸妆再来一张:


个人主页

本文的个人主页链接:https://baddogzz.github.io/2019/12/24/Fix-Hair-Transparent/

好了,拜拜。

修正半透明头发的渲染异常相关推荐

  1. android 首页广告位,IT之家安卓版 7.25:去文章内广告位、修正专题和头像显示异常...

    原标题:IT之家安卓版 7.25:去文章内广告位.修正专题和头像显示异常 IT之家 安卓版 7.25 更新! 刚才发布了 IT之家 iOS 版 7.23,带来了大量更新,现在安卓版 7.25 发布,同 ...

  2. 游戏中各向异性头发的渲染

    趁有时间写一篇关于各向异性头发的渲染. 先上效果图(不含Ao). 这个是04年的一个ppt,主要介绍了头发的渲染,其追到源头还是要看这个原理. 各向异性的主要计算公式: 主要代码如下: 切线混合扰动部 ...

  3. unity 头发的渲染

    光照模型 Kajiya-Kay 一般使用的光照模型 为不透明的完美圆柱体. 只考虑反射,没有考虑透射,没有考虑内部反射,没有考虑吸收. Marschner 基于物理的渲染 理论模型:头发不是完美的圆柱 ...

  4. unity3d Hair real time rendering 真实头发实时渲染

    先放上效果 惊现塞拉酱 算法是Weta Digital根据siggraph2003的论文加以改进,改进之前使用的是Kajiya and Kay's 模型,它能量不守恒,也就是说不是基于物理的,不准确 ...

  5. Z-score与修正的Z-score评分识别异常

    z-score 对于一维数据,最常用评价异常的方法就是z-score方法,它的定义如下: z i = x i − u δ z_i=\frac{x_i-u}{\delta} zi​=δxi​−u​ 其中 ...

  6. unity给头发添加物理_unity3d Hair real time rendering 真实头发实时渲染

    先放上效果 惊现塞拉酱 算法是Weta Digital根据siggraph2003的论文加以改进,改进之前使用的是Kajiya and Kay's 模型,它能量不守恒,也就是说不是基于物理的,不准确 ...

  7. easyUI datagrid 多行多列数据渲染异常缓慢原因以及解决方法

    原因 最近,在优化之前公司帮联想(外包)做的一个老的后台管理系统,由于项目是基于easy UI框架,页面是后台用jsp实现的,再加上在公司推行前后端分离的实践,大部分项目都基于vue采用前后端分离去实 ...

  8. 半透明渲染新技术摘录

    http://blog.csdn.net/garuda/article/details/6541579 ATI 的头发渲染方案: 1.       在网格制作阶段对三角形排序,使头发的三角形大致按从下 ...

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

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

  10. unity urp 实现头发渲染

    此篇文章参考 Hair Rendering and Shading 地址: https://web.engr.oregonstate.edu/~mjb/cs519/Projects/Papers/Ha ...

最新文章

  1. Linux内核中锁机制之完成量、互斥量
  2. 2021-春季学习-智能车技术创新与实践(90)
  3. STM32 HAL库、标准外设库、LL库(STM32 Embedded Software)
  4. js判断鼠标旋转度数以及顺逆方向详解
  5. 开需求评审会,你会出汗吗?
  6. 百度pcs 如何获取Access Token
  7. svn java注释_svn 强制用户添加注释 和 允许用户修改注释
  8. python中不同类型的数据不能相互运算_Python第三课——数据类型与运算(2)
  9. Java生成指定范围随机数的方法
  10. python文本编辑器下载_海龟编辑器(Python编辑器)
  11. 双网卡centos7 iptables防火墙与/etc/rc.d/rc.local开机运行
  12. 4-2 面向复用的软件构造技术
  13. HP刀箱无法识别刀片的处理方法
  14. 在css中arial,Helvetica或Arial作为CSS中的基本字体?
  15. 亲测可用:推荐一个免费下载外文文献的网站
  16. python3自动发送邮件并添加附件
  17. excel如何输入身份证号码
  18. 使用python替换word文档部分内容
  19. c#中 把字符串转换为拼音码
  20. 老九学堂 学习C++ 第六天

热门文章

  1. iPhone如何快速设置自定义铃声?苹果手机铃声设置教程
  2. 计算机软件专业硕士,软件工程硕士与计算机硕士区别
  3. vscode Run coder 支持c++11
  4. Matlab fprintf
  5. Python批量将MP3音频转为WAV格式(附代码) | Python工具
  6. 解决excel里面“取消隐藏”是灰色的问题
  7. 计算机专业本科一批,本科一批招生计划
  8. python打包时出现RecursionError: maximum recursion depth exceeded的解决方法
  9. 平衡二叉树(C++实现)
  10. 手机浏览器电脑版有什么作用,手机浏览器如何设置成电脑版