Unity3d 基于物理渲染Physically-Based Rendering之最终篇
前情提要:
讲求基本算法
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 http://blog.csdn.net/wolf96
Unity3d 基于物理渲染Physically-Based Rendering之最终篇相关推荐
- opengl-PBR基于物理的渲染(Physically Based Rendering):理论基础
PBR文档链接 PBR-learnOpengl官方文档 理论基础 PBR概念 PBR基于物理的渲染(Physically Based Rendering),它指的是一些在不同程度上都基于与现实世界的物 ...
- Unity3d 基于物理渲染Physically-Based Rendering之specular BRDF
在实时渲染中Physically-Based Rendering(PBR)中文为基于物理的渲染 它能为渲染的物体带来更真实的效果,而且能量守恒 稍微解释一下字母的意思,为对后文的理解有帮助, 从右到左 ...
- unity3d 基于物理渲染的问题解决
最近1个月做了unity 次世代开发的一些程序方面的支持工作,当然也是基于物理渲染相关的,主要还是skyshop marmoset的使用吧,他算是unity4.x版本 PBR的优秀方案之一了 但在使用 ...
- PBR:基于物理的渲染(Physically Based Rendering)+理论相关
一: 关于能量守恒 出射光线的能量永远不能超过入射光线的能量(发光面除外).如图示我们可以看到,随着粗糙度的上升镜面反射区域的会增加,但是镜面反射的亮度却会下降.如果不管反射轮廓的大小而让每个像素的镜 ...
- Physically Based Rendering,PBRT(光线跟踪:基于物理的渲染) 笔记
提起PBRT(Physically Based Rendering: From Theory to Implementation)这本书, 在图形学业界可是鼎鼎大名, 该书获得2005年软件界J ...
- Learn OpenGL 笔记7.1 PBR Theory(physically based rendering基于物理的渲染 理论)
PBR,或更通常称为基于物理的渲染,是一组渲染技术,它们或多或少基于与物理世界更接近的相同基础理论.由于基于物理的渲染旨在以物理上合理的方式模拟光线,因此与我们的原始光照算法(如 Phong 和 Bl ...
- Unity3D 的物理渲染和光照模型
阅读目录 漫反射面:郎伯模型 朗伯着色器(Lambertian shader) Toon shading 镜面: Blinn-Phong模型 在Unity5中物理渲染 Unity 中使用的着色技术 结 ...
- Physically Based Rendering——史上最容易理解的BRDF中D函数NDF的中文资料
粗糙度决定了D函数的分布,一般粗糙度是D函数的方差 本文假定读者已经对PBR即Physcially Based Rendering 基于物理的渲染有了初步的了解,对于PBR的入门有很多文章都介绍的不错 ...
- PBR (Physically Based Rendering)概念篇
一.PBR是什么? Physically Based Rendering:基于物理的渲染 PBR:是一套框架,通过PBR保证整体的色调以及画面的统一 什么是基于物理渲染? 对现实世界中的一种近似,而不 ...
最新文章
- __purecall 链接错误
- UVA, 580 Critical Mass
- ffmpeg结构体(二)
- 电容过大导致电压下降_现场| 典型的断直流电源导致开关误分合案例分析
- dnse 2.0音效厉害还是full sound厉害点呢?谢谢!!
- 信息学奥赛一本通C++语言——1041:奇偶数判断
- 【ElasticSearch】Es 源码之 PeerRecoverySourceService 源码解读
- 【java】Java内省Introspector
- TCP的可靠传输実现
- c++学习笔记---指针
- python 核心编程 练习题
- OWASP A6 Vulnerable and Outdated Components (自带缺陷和过时的组件)
- 空间管理系统有哪些管理模块?
- 计算机组成原理源码,计算机组成原理源码两位乘课程设计报告.docx
- 探讨SEO之项目管理
- 南邮 OJ 2026 Keroro侵略地球
- 华氏摄氏温度转换程序
- matlab里newff,新版matlab中神经网络训练函数newff的使用方法
- Kindle在线推书网站 强烈推荐
- final class java_Java 中常见的 final 类