前情提要:

讲求基本算法

  1. Unity3d 基于物理渲染Physically-Based Renderingspecular BRDF

plus篇

  1. Unity3d 基于物理渲染Physically-Based Rendering之实现

最后我们用fragment shader 实现,加上diffuse漫反射,代码和之前的surface差不多,只是多了reflect方向的计算,reflect方向的计算方法为用CG函数库中函数reflect,

float3 reflect(float3 i, float3 n);
i为in入射方向,n为normal发现方向,此处入射方向为view direction。

  1. float3 refDir = reflect(-viewDir,N);

参考了下SIGGRAPH 2013中虚幻引擎的diffuse
他们的方法为new diffuse = diffuse color/π。
把π改为可控参数就好,调成我们想要的效果。

建立了一个外部变量_ReflAmount为cubeMap和diffuse的比重,_ReflAmount越高反射周围景物越明显
这是本文实现效果

 
 
 _ReflAmount = 0.5
 
_ReflAmount = 0
有没有要滴出血的感觉?
 
_ReflAmount = 1

高大上的丝袜黑

_ReflAmount = 1
 
_ReflAmount = 0
 
_ReflAmount = 0.5

与unity作比较:

diffuse:

specular:

这是虚幻引擎在SIGGRAPH 2013发表的效果:

可惜我没有那么高大上的模型做实验,可惜了,就用人脸做代替

代码如下:

  1. Shader "Custom/reflect new ops3" {
  2. Properties{
  3. _MainTex("Base (RGB)", 2D) = "white" {}
  4. _Maintint("Main Color", Color) = (1, 1, 1, 1)
  5. _Cubemap("CubeMap", CUBE) = ""{}
  6. _SC("Specular Color", Color) = (1, 1, 1, 1)
  7. _GL("gloss", Range(0, 1)) = 0.5
  8. _nMips("nMipsF", Range(0, 5)) = 0.5
  9. _ReflAmount("Reflection Amount", Range(0.01, 1)) = 0.5
  10. }
  11. SubShader{
  12. pass{//平行光的的pass渲染
  13. Tags{ "LightMode" = "ForwardBase" }
  14. Cull Back
  15. CGPROGRAM
  16. #pragma vertex vert
  17. #pragma fragment frag
  18. #include "UnityCG.cginc"
  19.  
  20. float4 _LightColor0;
  21. samplerCUBE _Cubemap;
  22. float4 _SC;
  23. float _GL;
  24. float4 _Maintint;
  25. float _nMips;
  26. float _ReflAmount;
  27. uniform sampler2D _MainTex;
  28. float4 _MainTex_ST;
  29. struct v2f {
  30. float4 pos : SV_POSITION;
  31. float2 uv_MainTex : TEXCOORD0;
  32. float3 lightDir : TEXCOORD1;
  33. float3 viewDir : TEXCOORD2;
  34. float3 normal : TEXCOORD3;
  35.  
  36. };
  37.  
  38. v2f vert(appdata_full v) {
  39. v2f o;
  40. o.pos = mul(UNITY_MATRIX_MVP, v.vertex);//切换到世界坐标
  41. o.normal = v.normal;
  42. o.lightDir = ObjSpaceLightDir(v.vertex);
  43. o.viewDir = ObjSpaceViewDir(v.vertex);
  44. o.uv_MainTex = TRANSFORM_TEX(v.texcoord, _MainTex);
  45. return o;
  46. }
  47. #define PIE 3.1415926535
  48.  
  49. float4 frag(v2f i) :COLOR
  50. {
  51. float3 viewDir = normalize(i.viewDir);
  52. float3 lightDir = normalize(i.lightDir);
  53. float3 H = normalize(lightDir + viewDir);
  54. float3 N = normalize(i.normal);
  55. float _SP = pow(8192, _GL);
  56. float d = (_SP + 2) / (8 * PIE) * pow(dot(N, H), _SP);
  57. // float f = _SC + (1 - _SC)*pow((1 - dot(H, lightDir)), 5);
  58. float f = _SC + (1 - _SC)*pow(2, -10 * dot(H, lightDir));
  59. float k = min(1, _GL + 0.545);
  60. float v = 1 / (k* dot(viewDir, H)*dot(viewDir, H) + (1 - k));
  61.  
  62. float all = d*f*v;
  63. // float3 refDir = N - lightDir / 2;//H
  64. float3 refDir = reflect(-viewDir,N);
  65. float3 ref = texCUBElod(_Cubemap, float4(refDir, _nMips - _GL*_nMips)).rgb;//* _ReflAmount;
  66. float3 c = tex2D(_MainTex, i.uv_MainTex);
  67. float3 diff = dot(lightDir, N);
  68. // diff /= PIE;
  69. diff = (1 - all)*diff;
  70.  
  71. // return float4(c *(diff + all), 1) * _LightColor0;
  72. return float4(lerp(c, ref, _ReflAmount) *(diff*_Maintint + all), 1)*_LightColor0;
  73. // return float4(ref*((_Maintint+0.2) * (1 - dot(lightDir, N))) + c *(diff*_Maintint + all), 1)*_LightColor0;
  74. // return float4(lerp(c, ref, _ReflAmount) *(diff*(_Maintint + 0.2)* (1 - dot(lightDir, N)) + all), 1)*_LightColor0;
  75. }
  76. ENDCG
  77. }
  78. }
  79. }

                                       ----- by wolf96

Unity3d 基于物理渲染Physically-Based Rendering之最终篇的更多相关文章

  1. unity3d 基于物理渲染的问题解决

    最近1个月做了unity 次世代开发的一些程序方面的支持工作,当然也是基于物理渲染相关的,主要还是skyshop marmoset的使用吧,他算是unity4.x版本 PBR的优秀方案之一了但在使用以 ...

  2. PBR:基于物理的渲染(Physically Based Rendering)+理论相关

    一: 关于能量守恒 出射光线的能量永远不能超过入射光线的能量(发光面除外).如图示我们可以看到,随着粗糙度的上升镜面反射区域的会增加,但是镜面反射的亮度却会下降.如果不管反射轮廓的大小而让每个像素的镜 ...

  3. Unity3d 基于物理渲染Physically-Based Rendering之specular BRDF

    在实时渲染中Physically-Based Rendering(PBR)中文为基于物理的渲染它能为渲染的物体带来更真实的效果,而且能量守恒 稍微解释一下字母的意思,为对后文的理解有帮助,从右到左L为 ...

  4. Unity3d 基于物理渲染Physically-Based Rendering之实现

    根据前文的例子http://blog.csdn.net/wolf96/article/details/44172243(不弄超链接了审核太慢)弄一下真正的基于物理的渲染逃了节课= =,弄了一下.公式和 ...

  5. 基于物理渲染的渲染器Tiberius计划

    既然决定实现一个光栅化软件渲染器,我又萌生了一个念头:实现一个基于物理渲染的渲染器.

  6. Physically Based Rendering

    Microfacet Models for Refraction through Rough Surfaces 这篇论文...名字被我忘记了 找了好久...之前存电脑里的 ggx beckmann 找 ...

  7. Thinking in Unity3D:基于物理着色(PBS)的材质系统

    关于<Thinking in Unity3D> 笔者在研究和使用Unity3D的过程中,获得了一些Unity3D方面的信息,同时也感叹Unity3D设计之精妙.不得不说,笔者最近几年的引擎 ...

  8. Physically Based Render in Game 序

    基于物理渲的渲染理论,从SIGGRAPH06被Naty Hoffman等人提出后,近年来也越来越多的被各大游戏公司所采用,几乎已经是次世代游戏的标准特性,也是每个3D游戏工作者所必备的知识,尽管每年S ...

  9. Physically Based Shader Development for Unity 2017 Develop Custom Lighting Systems (Claudia Doppioslash 著)

    http://www.doppioslash.com/ https://github.com/Apress/physically-based-shader-dev-for-unity-2017 Par ...

随机推荐

  1. hibernate 对象状态异常:object references an unsaved transient instance - save the transient instance before flushing

    我的问题出在,删除的对象对应的表中有一个外键,关联着另外一个表,可是另外一个表中没有数据,所以报了这个错误. 参考http://www.cnblogs.com/onlywujun/archive/20 ...

  2. Oracle: Oracle行转列、列转行的Sql语句总结

    例子原型: ' ; 运行结果如下: 一.多字段的拼接 将两个或者多个字段拼接成一个字段: ' ; 运行结果: 二.行转列 将某个字段的多行结果,拼接成一个字段,获取拼接的字符串[默认逗号隔开] ' ; ...

  3. Mybatis的学习总结二:使用Mybatis对表进行CRUD操作【参考】

    一.使用Mybatis对表进行CRUD操作------基于XML的实现 1.定义SQL的映射文件 2.在conf.xml中进行注册. 2.创建测试类 [具体过程参考:Mybatis的学习总结一] 二. ...

  4. SQL SERVER while循环

    在SQL数据库中,可以通过WHILE实现循环,下面就将为您介绍SQL循环执行while控制,希望对您提升WHILE的使用水平能够有些帮助. WHILE Boolean_expression    { ...

  5. Object-C Init

    上一篇为Object-C类实现 我们可以创建一个init方法用来给我们的实例变量设置初始化值: - (id)init { if(self = [super init]) { [self setCapt ...

  6. js实现文件上传,删除效果

    效果图: 刚开始: 点击按钮"选择更多后",可以添加很多选择文件: 点击按钮"删除"后: 实现代码: <!DOCTYPE html><html ...

  7. 去掉Visual Studio 编辑器里中文注释的红色波浪线 转载

    我们通常用visual studio进行开发的时候,我们通常会用到一款比较流行比较方便的插件,那就是Visual Assist X,它可以增强Microsoft开发环境下的编辑能力,支持C/C++,C ...

  8. 《玩转shutdown》-linux命令五分钟系列之十三

    1 我想立即关机! $shutdown -h now 2 我想立即重启 $shutdown -r now 3 我想在23:30分准时关机 $shutdown -h 23:30 4 我想在15分钟后关机 ...

  9. Xcode 插件开发

    我最近一年来都在开发ios应用,不过感觉公司的app维护起来非常麻烦. 因为公司要为很多个企业订做app,每个app的功能基本相同,只是界面上的一些图片和文字要换掉,功能也有一些小改动.考虑到代码维护 ...

  10. linux下安装MySQL5.6记录

    把之前装的mysql卸载了,准备重新用代码包装一遍,问了一下公司的DBA,他推荐给我mysql-5.6.16版本,说这个版本比较稳定. 按照网上的教程安装,结果就少文件,我还在找原因的时候,同事来找我 ...