Unity3d shader之次表面散射(Subsurface Scattering)
次表面散射是一种非常常用的效果,可以用在很多材质上
如皮肤,牛奶,奶油奶酪,番茄酱,土豆等等
初衷是想做一个牛奶shader的,但后来就干脆研究了sss
这是在vray上的次表面散射效果
这是本文在unity中实现了的次表面散射效果:
左侧为BRDF(双向反射分布),右侧为BSSRDF(双向次表面散射反射分布)
各参数如上为:
S:BSSRDF结果
Rd: BSSRDF的漫反射
Fr:: 菲涅尔反射
Ft: 菲涅尔透明度,透射比
Fdr: 菲涅尔漫反射的反射率
E:辐照方向
Wiki
中给出:radiant fluence is the radiant energy received by a surface per unit
area, or equivalently the irradiance of a surface integrated over time
of irradiation
Phi:每单位表面受到的辐照能
Sigma A: 吸收率
Sigma S: 散射率
Sigma T: 消散率
Sigma T’ : 减少消散率
Sigma TR : 有效消散率
D:漫反射常量
Alpha: 反射率
P:相函数
Eta:反射的相关指数
g:散射角的平均cos值
Q:源分布值
Q0:第0个源分布
Q1:第1个源分布
漫反射近似
漫反射近似是基于光线高分散媒介倾向于各向异性的观察,光源的分布与相函数是各向异性的。每次散射都模糊了光线的分布,随着散射的次数增多导致光线的分布更加均匀。
这种辐照类似于一个二项式涉及单位表面受到的辐照能和辐照方向
使用了Henyey-Greenstein的相函数:
常量决定于单位表面受到的辐照能和辐照方向。
对于一个无穷小的光线进入了一个媒介,入射能量将随着进入深度s呈指数性减小
减小强度:
<span style="font-size:14px;">float Lri(float3 w_P, float phi_x, float p_L_Dist, float D)
{
float _Sigma_t = _Sigma_A + _Sigma_S;
float L = 1 / (4 * PIE) * phi_x + 3 / (4 * PIE) * dot(w_P, -D*_Nabla * phi_x); float Lri = L * pow(E, -_Sigma_t* p_L_Dist);
return Lri;
}</span>
第一次散射减小强度,被作为体积来源处理
for (int i = 0; i < 30; i++)
{
w_P = normalize(float3(N.x + rand(fixed2(i*0.05, i*0.05)), N.y + rand(fixed2(-i*0.05, i*0.05)), N.z + rand(fixed2(i*0.05, -i*0.05))));
// float3 w_P = normalize(float3(lightDir.x + rand(i.uv_MainTex + fixed2(i*0.01, i*0.01)), lightDir.y + rand(i.uv_MainTex + fixed2(-i*0.01, i*0.01)), lightDir.z + rand(i.uv_MainTex + fixed2(i*0.01, -i*0.01)))); Q += phase(dot(lightDir, w_P))*Lri(w_P, phi_x, p_L_Dist, D);
Q *= _Sigma_S;
Q1 += Q*w_P; }
30次随机光线散射方向
观察光在体积内部传播行为,这个方程式很有用
这个方程式与辐照度标量或通量相关
第0个与第一个源分布公式
Sigma参数之间的互相推倒,
光线变成各向异性的,后向散射关系改变了净通量,前向散射与无散射是没有区别的。
此处D = 1/(3* sigma_T’);是漫反射常量
最终我们得到了漫反射公式
漫反射部分的推导公式,得到如下结果
在做定积分时进行叠加了30次随机光线散射方向,效果还算不错。
漫反射的反射部分
然后就是求漫反射的反射部分
菲涅尔反射公式,在可传导介质的菲涅耳漫反射的反射:
媒介本身的性质不同反射器情况也不同,Eta为这种性质的相关指数
这是经过精确测量的反射率,我们可以用这个公式来免去计算消耗
通量公式:
Dr = ||x - xr||为当前点与光源的距离
Dv = ||x-xv||为当前点与眼睛(相机)的距离
if (_WorldSpaceLightPos0.w != 0)
{
p_L_Dist = distance(_WorldSpaceLightPos0, i.worldPos);
}
float v_C_Dist = distance(_WorldSpaceCameraPos, i.worldPos)*0.3;
Φ为光源强度
最终,我们的反射公式为
<span style="font-size:14px;">float3 ref = -D * (dot(N, _Nabla*phi_x_S)) / (diff*_LumPow_D);</span>
在最后加入Physically-Based Rendering的specular,大功告成
参数调节
关于参数调节,参数非常不好调,pdf上和自己弄得参数不搭,只能自己调了
最终效果:
参考:
1. A Practical Model for Subsurface Light Transport
2. A Measurement-Based Skin Reflectance Model for Face Rendering and Editing
Unity3d shader之次表面散射(Subsurface Scattering)的更多相关文章
- 次表面散射(SubSurface Scattering) Shader 【转】
原文 http://www.azure.com.cn/article.asp?id=231 用深度值近似模拟物体的厚度,厚度越小处透光越多. varying vec4 position;varying ...
- unity3d shader之实时室外光线散射(大气散射)渲染
散射需要:吸收,内散射,外散射分为瑞利散射Rayleigh Scattering和米氏散射 Mie Scattering 后面会详细讲解 大气中散射由多种原因产生,微粒,尘埃,水蒸气等等 阳光由于散 ...
- Unity3d 屏幕空间人体皮肤知觉渲染&次表面散射Screen-Space Perceptual Rendering & Subsurface Scattering of Human Skin
之前的人皮渲染相关 前篇1:unity3d Human skin real time rendering 真实模拟人皮实时渲染 前篇2:unity3d Human skin real time ren ...
- (转)GEM -次表面散射的实时近似
次表面散射(Subsurface Scattering),简称SSS,或3S,是光射入非金属材质后在内部发生散射, 最后射出物体并进入视野中产生的现象, 即光从表面进入物体经过内部散射,然后又通过物体 ...
- 【译】Unity3D Shader 新手教程(1/6)
本文为翻译,附上原文链接. 转载请注明出处--polobymulberry-博客园. 刚开始接触Unity3D Shader编程时,你会发现有关shader的文档相当散,这也造成初学者对Unity3D ...
- Unity3D shader简介
Unity3D shader简介 可以肯定的说Unity3D使得很多开发者开发游戏更容易.毫无疑问,shader(着色器)编码,仍有很长的路要走.shader是一个专门运行在GPU的程序,经常被神秘包 ...
- 【浅墨Unity3D Shader编程】之一 夏威夷篇:游戏场景的创建 & 第一个Shader的书写
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40723789 作者:毛星云(浅墨) ...
- 转 猫都能学会的Unity3D Shader入门指南(二)
猫都能学会的Unity3D Shader入门指南(二) 关于本系列 这是Unity3D Shader入门指南系列的第二篇,本系列面向的对象是新接触Shader开发的Unity3D使用者,因为我本身自己 ...
- Unity3D Shader入门指南(二)
关于本系列 这是Unity3D Shader入门指南系列的第二篇,本系列面向的对象是新接触Shader开发的Unity3D使用者,因为我本身自己也是Shader初学者,因此可能会存在错误或者疏漏,如果 ...
随机推荐
- org.hibernate.HibernateException: No CurrentSessionContext configured!
hibernate可以通过两种方式获得Session: getCurrentSession() 和openSession(). 当通过getCurrentSession()方法时,需要在 hibern ...
- 优化有标量子查询的SQL
数据库环境:SQL SERVER 2008R2 今天在数据库中抓出一条比较耗费资源的SQL,只返回904条数据,居然跑了40多分钟.SQL及对应的数据量如下图: SELECT saft04.cur_y ...
- Java小例子(学习整理)-----学生管理系统-控制台版
1.功能介绍: 首先,这个小案例没有使用数据库,用集合的形式暂时保存数据,做测试! 功能: 增加学生信息 删除学生信息 修改学生信息 查询学生信息: 按照学号(精确查询) 按照姓名(模糊查询) 打 ...
- 实现基于文件存储的Session类
自主实现Session功能的类,基于文件方式存储Session数据,测试基本通过,还比较好玩,实际应用没有意义,只不过是学习Session是如何实现的. 一般基于文件存储Session数据效率不是很高 ...
- Git (2)
要使用Git首先遇到的问题是怎么把文件加到库中. 很简单. 新建一个目录,然后git init. 完成上述工作之后的唯一改动是在当前目录下生成了一个.git的子目录.这个子目录是一个集中的数据库,包含 ...
- javascript 自定义鼠标右键菜单
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- js 默认的参数、可变的参数、变量作用域
可以通过arguments对象来实现可变的参数 在函数代码中,使用特殊对象 arguments,开发者无需明确指出参数名,就能访问它们. arguments是一个数组对象,可以通过下标来实别参数的位置 ...
- 超链接字体颜色设置(通过html/css的设置方法)
超链接字体颜色设置是通过css来设置,a链接的颜色设置常用的有以下两种,1.超链接a的初始状态颜色,2.超链接字体的鼠标滑过颜色,还有两种病不常用:3.超链接字体的已访问颜色,4.超链接字体在按下鼠标 ...
- StrongReference
原创作品:未经本人允许,不得转载前段时间写项目时遇到了一个问题,就是从网络获取图片资源的问题,总是出现OOM异常,经过几天的努力,终于处理的还算是可以使用,OOM的处理一直都是很头疼的问题.对于三级缓 ...
- 移动web页面使用微软雅黑字体的问题
很多前端工程师在开发手机页面的时候,发现视觉设计师们喜欢用微软雅黑作为中文字体进行设计,于是写页面的时候也定义 font-family 为微软雅黑,后来发到线上后,细心的产品经理发现页面的字体不是微软 ...