前情提要:

讲求基本算法

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。

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发表的效果:

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

代码如下:

Shader "Custom/reflect new ops3" {
Properties{
_MainTex("Base (RGB)", 2D) = "white" {}
_Maintint("Main Color", Color) = (1, 1, 1, 1)
_Cubemap("CubeMap", CUBE) = ""{}
_SC("Specular Color", Color) = (1, 1, 1, 1)
_GL("gloss", Range(0, 1)) = 0.5
_nMips("nMipsF", Range(0, 5)) = 0.5
_ReflAmount("Reflection Amount", Range(0.01, 1)) = 0.5
}
SubShader{
pass{//平行光的的pass渲染
Tags{ "LightMode" = "ForwardBase" }
Cull Back
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc" float4 _LightColor0;
samplerCUBE _Cubemap;
float4 _SC;
float _GL;
float4 _Maintint;
float _nMips;
float _ReflAmount;
uniform sampler2D _MainTex;
float4 _MainTex_ST;
struct v2f {
float4 pos : SV_POSITION;
float2 uv_MainTex : TEXCOORD0;
float3 lightDir : TEXCOORD1;
float3 viewDir : TEXCOORD2;
float3 normal : TEXCOORD3; }; v2f vert(appdata_full v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);//切换到世界坐标
o.normal = v.normal;
o.lightDir = ObjSpaceLightDir(v.vertex);
o.viewDir = ObjSpaceViewDir(v.vertex);
o.uv_MainTex = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
#define PIE 3.1415926535 float4 frag(v2f i) :COLOR
{
float3 viewDir = normalize(i.viewDir);
float3 lightDir = normalize(i.lightDir);
float3 H = normalize(lightDir + viewDir);
float3 N = normalize(i.normal);
float _SP = pow(8192, _GL);
float d = (_SP + 2) / (8 * PIE) * pow(dot(N, H), _SP);
// float f = _SC + (1 - _SC)*pow((1 - dot(H, lightDir)), 5);
float f = _SC + (1 - _SC)*pow(2, -10 * dot(H, lightDir));
float k = min(1, _GL + 0.545);
float v = 1 / (k* dot(viewDir, H)*dot(viewDir, H) + (1 - k)); float all = d*f*v;
// float3 refDir = N - lightDir / 2;//H
float3 refDir = reflect(-viewDir,N);
float3 ref = texCUBElod(_Cubemap, float4(refDir, _nMips - _GL*_nMips)).rgb;//* _ReflAmount;
float3 c = tex2D(_MainTex, i.uv_MainTex);
float3 diff = dot(lightDir, N);
// diff /= PIE;
diff = (1 - all)*diff; // return float4(c *(diff + all), 1) * _LightColor0;
return float4(lerp(c, ref, _ReflAmount) *(diff*_Maintint + all), 1)*_LightColor0;
// return float4(ref*((_Maintint+0.2) * (1 - dot(lightDir, N))) + c *(diff*_Maintint + all), 1)*_LightColor0;
// return float4(lerp(c, ref, _ReflAmount) *(diff*(_Maintint + 0.2)* (1 - dot(lightDir, N)) + all), 1)*_LightColor0;
}
ENDCG
}
}
}

                                       ----- 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. [上传下载] C# UpLoadFiles文件上传类 (转载)

    点击下载 UpLoadFiles.zip 主要功能如下 /// <summary> /// 上传文件 /// </summary> /// <param name=&qu ...

  2. Android混淆那些事儿

    博客: 安卓之家 微博: 追风917 CSDN: 蒋朋的家 简书: 追风917 博客园:追风917 # Android混淆 Android混淆是Android开发者经常使用的一种用于代码防止被反编译的 ...

  3. 如何在Sql2008中获取表字段属性和注释?

    如何在Sql2008中获取表字段属性和注释? select b.[value] from sys.columns a left join sys.extended_properties b on a. ...

  4. 第一章 SQL基础

    第一部分:SQL基础1. 为什么学习SQL自人类社会形成之日起,社会的运转就在不断地产生和使用各种信息(文献.档案.资料.数据等):在如今所谓的信息时代,由于计算机和互联网的作用,信息的产生和使用达到 ...

  5. Android学习笔记(SQLite的简单使用)

    1.SQLite介绍 SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中.它是D.RichardHipp建立的公有领域项目.它的设计目标是嵌入式的,而且 ...

  6. 【转】iOS开发常用的第三方类库

    原文: http://blog.csdn.net/xiazailushang/article/details/9716043 在iOS开发中不可避免的会用到一些第三方类库,它们提供了很多实用的功能,使 ...

  7. centos git gitolite安装笔记

    export PATH=/home/git/bin:$PATH echo PATHgit branch 查看本地分支 git branch -a 查看远程分支 git fetch 获取远程分支 git ...

  8. 取值对比ture of false加引号与不加引号的问题-----Bug笔记-160219

    一.默认情况,当属性值为布尔值类型的时候对比判断不用加引号<input type="radio" name="city" value="BeiJ ...

  9. LESS快速入门

    Less 简介 简单来说,Less 就是让你在网页设计的时候,可以更方便地写 CSS 的工具. Less官网的说明: LESS 将 CSS 赋予了动态语言的特性,如 变量, 继承,运算,函数. LES ...

  10. 生产环境CentOS服务器系统安全配置

    转http://www.centoscn.com/CentosSecurity/CentosSafe/2014/1126/4192.html 账户安全及权限 禁用root以外的超级用户 删除不必要的账 ...