PBR基础理论(二)
PBR基础介绍(二)本文将在unity中尝试复现上文提及的内容,主要参考了宋开心大佬的这篇
根据BRDF的渲染方程需要实现的主要部分:
直接光
直接光漫反射
直接光高光
法线分布函数 D
几何函数 G
菲涅尔函数 F
间接光
IBL
SH
实现之前Unity的linear空间与Gamma空间1234567// Shader中涉及到的参数如下_MainTex("Texture", 2D) = "white" {}_Tint("Tint", Color) = (1 ,1 ,1 ,1)// 金属度_Metallic("Metallic", Range(0, 1)) = 0 // 粗糙度_Smoothness("Smoothness", Range(0, 1)) = 0.5
需要注意的是设置金属度/光滑度贴图的时候,如果在linear空间下贴图设定勾选了SRGB的选项(这个勾选本质上就是对颜色做了一次pow(color,2.2)的操作),那么需要在开头添加 ...
PBR基础理论(一)
PBR基础介绍(一)主要了解PBR的各种部分的作用以及相关参数的影响,非物理意义推导
基础理论抛开自发光,渲染方程通常长成这个样子
简单的理解成以下几个部分:
Lo(v)表示从一个点反射出的光照强度。
f(l, v)表示该点入射光线强度和反射之间的比例,一般有BRDF, BTDF, BSDF和BSSRDF等。
Li(l) * (n · l)表示入射光照强度Li乘以衰减。
整个大的积分表示的是该点对应的半球积分的累加 — 这里积分是通过蒙特卡洛近似去求解的
而PBR中的渲染方程通常长这样,本质上其实是计算某一点在经过反射,折射后相关信息的比值。
和第上一条公式相比变化的地方可以理解为以下几个部分:
反射
漫反射项 + 漫反射比例 — Kd * C / PI
镜面反射项 + 镜面反射比例 — Ks * ( D * F * G / 4 * (Wo · n) * (Wi · n)
法线分布函数D — Normal Distribution
几何函数 G — Gemetric,有时候也会是 V (visibility)
菲涅尔 F — Fresnel
光源颜色以及其衰减 — L ...
FBX SDK简单使用(一)
FBX SDK简单使用(一)简介FBX是Autodesk的一个常用的跨平台的三维数据格式,应用很广泛,这里是官方API,这里是官方例子。FBX的安装可以参照这里,基本介绍可以参考这里。
查看FBX文件数据这是在整个使用过程中个人认为帮助很大的一个功能,3ds MAX中可以直接设置,在导出的时候可以选择二进制的格式或者ASCII的格式,如下图:
在FBX SDK中通过对FbxExporter设置可以得到一样的效果。
1234// FBX设置输出ASCII格式文件FbxExporter* fbxExporter = FbxExporter::Create(fbxManager, "");int fbxFormat = fbxManager->GetIOPluginRegistry()->FindWriterIDByDescription("FBX ascii(*.fbx)");bool exportStatus = fbxExporter->Initialize(fileOutput, fbxFormat, fbxManager- ...
屏幕后处理Re(一)
屏幕后处理Re(一)HDR,LDR首先需要了解Color Grading(颜色分级)又叫调色,是游戏后期处理中常见也必备的一个环节。通过调整它能够改变或者矫正最终图像的颜色和亮度。
Dynamic Range是一种用数学的方式来描述场景亮度层次范围的技术,是图像从暗到亮的亮度/灰度分级,分级越多能够表现的画面层次就越丰富。
HDR和LDR:
Low Dynamic Range(LDR)
LDR作为8位的颜色图片,使用RGB模型,每个颜色有256种亮度等级,总共能够表示256^3种颜色。但是和现实相比仍有局限,所以引入HDR
High Dynamic Range(HDR)
HDR常见有12位和16位,因为显示器限制,显示的值只能在0,1,但是光照计算可以没有这样的限制,这样可以表示更多层次的明暗细节,亮的部分能够很亮,暗的部分能够很暗。
LDR范围确定,但是HDR并不,所以同样是HDR可能范围并不相同。因为范围不同,但是最终需要统一到[0,1]供显示器使用,所以引入了Tone Mapping (色调映射)
色调映射(Tone Mapping)用于将HDR转换到LDR,Tone ...
线性空间和伽马空间
Gamma和Linear线性空间在线性空间下,我们感知到的强度和对应的数值强度是按比例对应的,也就是说如果有两个数值强度0.25和0.25那么他们相加的数值强度就是0.5。没有这样特性的空间就是非线性空间。
伽马空间之所以引入gamma空间一是因为显示器对颜色强度的感知是非线性的,另一个原因是人眼在较暗的环境下比起亮的环境能够更好的辨别细节。因此在图像压缩中我们希望能够在暗部获得更高的精确度,所以对图像每个像素引入了一个幂函数来进行处理。
上图(图片来自kinematicsoup)可以看到,当我们在0.45的gamma下,暗部区域有了更高的值,这样就为暗部获取了更高的精确度,但是亮部区域信息就被压缩了。以这样形式存储的图片就称为放在gamma空间中,在显示器上显示的时候会对图片进行一个gamma为2.2的幂的操作,在这里就抵消了0.45gamma的影响,因此能够显示正常。
常见流程在游戏中为了达到更真实的渲染结果 (常见于PBR),因此先去除gamma矫正再对图像进行操作
Unity中的设置在unity中通过Edit->Project Settings->Player ...
Thinfilm研究
薄膜干涉尝试记录实习需要用到薄膜干涉的效果,看到《王者荣耀》里,婉儿的皮肤,尝试用仅有的一点知识去模仿下(待继续优化)
分析康康目前我能做什么
在旋转模型的时候颜色会根据光照和视线的变换发生变化,因此需要注意法线和视线 — 菲涅尔现象,法线和光线对效果产生的影响。
基础的光照模型 — 反射相关
贴图贴图有两张,一张是通过在ps里ramp得到的
一张来自中国科普博览
尝试在最简单的材质球上实现的时候,先看NdotV的变换,中间为1,边缘为0与NdotV相符
接着添加一个贴图并通过NdotV进行采样,这个时候什么角度看都是一样的
接着加入光的影响,可以看到有根据希望的方向进行变化,既会收到光的影响也会收到视线的影响(背光面会有分界)
想到之前做过matcap的一个效果,首先尝试通过菲涅尔直接对贴图采样观察效果
1234half NdotV = dot(normal_dir, view_dir * _Tile);half fresnel = 1.0 - NdotV;half2 uv_thinfilm = half2(fresnel, 0.5);half4 matcap_colo ...
简易各向异性
各向异性高光主要参考来自ATI Research Inc的《Hair Rendering and Shading》
原理各向异性表现:光打到物体表面会在不同的表面发散
可以分为两部分处理:
发光方向的处理
拉丝感的处理
发光方向使用kajiya-kay模型,不再使用法线和半程向量dot(N,H)去计算高光,而是使用每根头发对应的tangent值和半程向量的sin值去计算:sin(T,H) = sqrt(1-dot(T,H) * dot(T,H))
H越接近横截面,越亮,sin的特性也是如此(越接近横截面的时候值越大),因此用sin表示
123456789// 半程向量half3 half_dir = normalize(light_dir + view_dir);// 计算TH点积,这里binormal的原因是unity中切线方向是u方向因此需要副法线half TdotH = dot(binormal_dir, half_dir);// 计算Sinhalf SinTH = sqrt(1-TdotH * TdotH);// 高光half3 spec = pow(max(0.0, S ...
Billboarding
Billboarding原理Billboarding通常会根据需求来旋转一个被纹理着色的多边形,本质上是构建一个旋转矩阵,通常是基于法线或者基于向上的方向,还需要设定锚点来确定多边形在空间中的位置。
难点在于法线和向上的方向常常不是垂直的,需要构建的矩阵由法线方向(normal),向上的方向(up)和向右的方向(right)组成
right = normal x up
up’ = normal x right
如图,通过视线作为一个轴,获取设定好的向上方向之后,获取向右的方向,因为向上的向量恒定不变,因此叉乘出来的向右向量由视线决定,在更新了向右向量之后再反过来影响向上的向量。(图片来自shader入门精要)
实现参考《Unity Shader入门精要》
123456789101112131415161718192021222324252627282930v2f vert (appdata v){ v2f o; // 设置模型空间中原点 float3 center = float3(0,0,0); // 模型空间中的视线 half3 view_model ...