前情提要:

讲求基本算法

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

plus篇

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

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

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

[cpp]  view plain copy
  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发表的效果:

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

代码如下:

[cpp]  view plain copy
  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. float4 _LightColor0;
  20. samplerCUBE _Cubemap;
  21. float4 _SC;
  22. float _GL;
  23. float4 _Maintint;
  24. float _nMips;
  25. float _ReflAmount;
  26. uniform sampler2D _MainTex;
  27. float4 _MainTex_ST;
  28. struct v2f {
  29. float4 pos : SV_POSITION;
  30. float2 uv_MainTex : TEXCOORD0;
  31. float3 lightDir : TEXCOORD1;
  32. float3 viewDir : TEXCOORD2;
  33. float3 normal : TEXCOORD3;
  34. };
  35. v2f vert(appdata_full v) {
  36. v2f o;
  37. o.pos = mul(UNITY_MATRIX_MVP, v.vertex);//切换到世界坐标
  38. o.normal = v.normal;
  39. o.lightDir = ObjSpaceLightDir(v.vertex);
  40. o.viewDir = ObjSpaceViewDir(v.vertex);
  41. o.uv_MainTex = TRANSFORM_TEX(v.texcoord, _MainTex);
  42. return o;
  43. }
  44. #define PIE 3.1415926535
  45. float4 frag(v2f i) :COLOR
  46. {
  47. float3 viewDir = normalize(i.viewDir);
  48. float3 lightDir = normalize(i.lightDir);
  49. float3 H = normalize(lightDir + viewDir);
  50. float3 N = normalize(i.normal);
  51. float _SP = pow(8192, _GL);
  52. float d = (_SP + 2) / (8 * PIE) * pow(dot(N, H), _SP);
  53. //  float f = _SC + (1 - _SC)*pow((1 - dot(H, lightDir)), 5);
  54. float f = _SC + (1 - _SC)*pow(2, -10 * dot(H, lightDir));
  55. float k = min(1, _GL + 0.545);
  56. float v = 1 / (k* dot(viewDir, H)*dot(viewDir, H) + (1 - k));
  57. float all = d*f*v;
  58. //  float3 refDir = N - lightDir / 2;//H
  59. float3 refDir = reflect(-viewDir,N);
  60. float3 ref = texCUBElod(_Cubemap, float4(refDir, _nMips - _GL*_nMips)).rgb;//* _ReflAmount;
  61. float3 c = tex2D(_MainTex, i.uv_MainTex);
  62. float3 diff = dot(lightDir, N);
  63. //  diff /= PIE;
  64. diff = (1 - all)*diff;
  65. //  return float4(c *(diff + all), 1)  * _LightColor0;
  66. return float4(lerp(c, ref, _ReflAmount) *(diff*_Maintint + all), 1)*_LightColor0;
  67. //  return float4(ref*((_Maintint+0.2) * (1 - dot(lightDir, N))) + c *(diff*_Maintint + all), 1)*_LightColor0;
  68. //  return float4(lerp(c, ref, _ReflAmount) *(diff*(_Maintint + 0.2)* (1 - dot(lightDir, N)) + all), 1)*_LightColor0;
  69. }
  70. ENDCG
  71. }
  72. }
  73. }

                                       ----- by wolf96  http://blog.csdn.net/wolf96

Unity3d 基于物理渲染Physically-Based Rendering之最终篇相关推荐

  1. opengl-PBR基于物理的渲染(Physically Based Rendering):理论基础

    PBR文档链接 PBR-learnOpengl官方文档 理论基础 PBR概念 PBR基于物理的渲染(Physically Based Rendering),它指的是一些在不同程度上都基于与现实世界的物 ...

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

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

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

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

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

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

  5. Physically Based Rendering,PBRT(光线跟踪:基于物理的渲染) 笔记

     提起PBRT(Physically Based Rendering: From Theory to Implementation)这本书, 在图形学业界可是鼎鼎大名, 该书获得2005年软件界J ...

  6. Learn OpenGL 笔记7.1 PBR Theory(physically based rendering基于物理的渲染 理论)

    PBR,或更通常称为基于物理的渲染,是一组渲染技术,它们或多或少基于与物理世界更接近的相同基础理论.由于基于物理的渲染旨在以物理上合理的方式模拟光线,因此与我们的原始光照算法(如 Phong 和 Bl ...

  7. Unity3D 的物理渲染和光照模型

    阅读目录 漫反射面:郎伯模型 朗伯着色器(Lambertian shader) Toon shading 镜面: Blinn-Phong模型 在Unity5中物理渲染 Unity 中使用的着色技术 结 ...

  8. Physically Based Rendering——史上最容易理解的BRDF中D函数NDF的中文资料

    粗糙度决定了D函数的分布,一般粗糙度是D函数的方差 本文假定读者已经对PBR即Physcially Based Rendering 基于物理的渲染有了初步的了解,对于PBR的入门有很多文章都介绍的不错 ...

  9. PBR (Physically Based Rendering)概念篇

    一.PBR是什么? Physically Based Rendering:基于物理的渲染 PBR:是一套框架,通过PBR保证整体的色调以及画面的统一 什么是基于物理渲染? 对现实世界中的一种近似,而不 ...

最新文章

  1. __purecall 链接错误
  2. UVA, 580 Critical Mass
  3. ffmpeg结构体(二)
  4. 电容过大导致电压下降_现场| 典型的断直流电源导致开关误分合案例分析
  5. dnse 2.0音效厉害还是full sound厉害点呢?谢谢!!
  6. 信息学奥赛一本通C++语言——1041:奇偶数判断
  7. 【ElasticSearch】Es 源码之 PeerRecoverySourceService 源码解读
  8. 【java】Java内省Introspector
  9. TCP的可靠传输実现
  10. c++学习笔记---指针
  11. python 核心编程 练习题
  12. OWASP A6 Vulnerable and Outdated Components (自带缺陷和过时的组件)
  13. 空间管理系统有哪些管理模块?
  14. 计算机组成原理源码,计算机组成原理源码两位乘课程设计报告.docx
  15. 探讨SEO之项目管理
  16. 南邮 OJ 2026 Keroro侵略地球
  17. 华氏摄氏温度转换程序
  18. matlab里newff,新版matlab中神经网络训练函数newff的使用方法
  19. Kindle在线推书网站 强烈推荐
  20. final class java_Java 中常见的 final 类

热门文章

  1. 哪些人不适合做程序员?
  2. 英镑兑美元汇率跌至1985年以来的最低水平 英镑危机临近
  3. html文件从手机里打开方式,在手机上打开word的两种方法
  4. 爬虫抓取58简历之字库解密
  5. mybatis学习(2)
  6. python中的index()函数
  7. [ACNOI2022]林昆
  8. verilator常用基础知识
  9. idea改变大于等于、不等于!=等符号的样式
  10. 使用数据库DDL语言创建数据库和基本表?(SQL Server 2014)