渲染课程总结
渲染综述
色彩空间
- 线性空间:物理世界的色彩空间,如果光照强一倍,亮度也会增强一倍
- 伽马(Gamma)空间: 显示器用于颜色矫正,通常值为2.2,对颜色进行灰度,亮度矫正
打个比方,功率为50%的灰色,人眼实际感知亮度为:0.5的2.2开根 = 0.7297
而人眼认为的50%中灰色,实际功率为:0.5的2.2次幂 = 0.2176 - sRGB色彩空间:sRGB对应的是Gamma0.45所在的空间,如储存的照片相当于对图片先进行了Gamma0.45的矫正,在显示器输出时又进行了Gamma2.2矫正
通常使用时,基础颜色等都勾选sRGB,如法线/粗糙度/金属度等贴图需要取消勾选sRGB
渲染技术术语
- 坐标系:在渲染过程中需要将坐标点以及向量等在不同坐标空间转换(模型空间,齐次裁剪空间,屏幕空间,相机空间,世界空间,光源空间等)
- 顶点,片段,像素:模型上的顶点,片段是光栅化的产物,像素是屏幕空间像素
- 深度测试,蒙版测试:
1
2
3
4
5
6
7
8
9
10
11
12
13
14深度测试:
ZTest 可取值为:Greater , GEqual , Less , LEqual , Equal , NotEqual , Always , Never , Off,默认是 LEqual,ZTest Off 等同于 ZTest Always。
ZWrite 可取值为:On , Off,默认是 On。
蒙版测试:
Stencil
{
Ref 1 //Reference Value
ReadMask 255 //读取的时候将该值 maskValue 与 referenceValue 和 stencilBufferValue 分别进行按位与(&)操作
WriteMask 255 //写入的时候将该值与 referenceValue 和 stencilBufferValue 分别进行按位与(&)操作
Comp Always //拿当前参考值与像素缓存值比较
Pass Replace //两个测试都通过了 进行处理
Fail Keep //两个测试都没通过 进行处理
ZFail Replace //模板测试通过而深度测试没通过 进行处理
} - Shader:
渲染管线
- 裁剪(Culling):
- 对象级裁剪:类型裁剪,几何体裁剪,遮挡裁剪
- 顶点级裁剪:视口裁剪
- 像素级裁剪:EarlyZ
- 渲染物件:
- 渲染状态
- 材质,纹理,各种参数
- 渲染顺序
- 后处理(Post Processing):对屏幕渲染结果进行加工
光照框架
对于N个物体受M盏光的影响
框架|算法复杂度|优点|缺点
:–|:–|:–|:–
forward shading(前向渲染)|O(N*M)|实现简单,兼容性好|性能较低,光源个数限制严格
deffered shading(延迟渲染)|O(N+M)|支持多光源,性能较好|
forward+ shading(前向+渲染)|||
硬件
- GPU:寄存器,Cache,显存 (GPU读取顺序:寄存器找不到->Cache->显存->CPU)
- 带宽
图形API
- DirectX,OpenGL,OpenGL ES,WebGL,Vulkan,Metal
渲染应用方式
- 离线渲染:电影,动画,烘培LightMap
- 实时渲染:游戏,VR
基础光照模型
- Lambert: max(0,dot(L,N))
- HalfLambert: max(0,dot(L,N)) * 0.5 + 0.5
- Phong: pow(max(0,dot(reflect(-L,N), V)), Gloss)
- BlinnPhong: pow(max(0,dot(normalize(L+V), N)), Gloss)
PBR
- 满足以下几点的光照模型,符合PBR模型:
- 微表面:不同材质的平面,有很多不同朝向不一的微小平面
- 能量守恒:出射光的总量不超过入射光的总量
- 反射方程:使用基于物理的BRDF(双向反射分布函数)
PBR反射方程:L(o) = f(fr(p,wi,wo) * Li(p,wi) * dot(n,wi) * dwi)
brdf方程:
- fr(p,wi,wo) = k(d)*f(lambert) + K(s)*f(cook-torrance)
- f(lamber) = c / Π
- ∫(cook-torrance) = DFG / (4*dot(wo,n)*dot(wi,n))
- D:法线分布函数(NDF),估算微平面的整体取向,公式:a^2 / (Π * (NdotH^2) * (a^2-1) + 1)^2 (注:a表示粗糙度)
- F: 菲尼尔方程,用于描述表面反射光所占比例, 公式: F0 + (1 - F0) * pos(1 - cosTheta, 5) (注:F0表示不同材质的垂直方向的反射率,直接光照中cosTheta:HdotV或HdotL,间接光照中cosTheta:NdotV)
- G:几何函数,用于计算微表面,自阴影, 公式:NdotV / (NdotV(1.0 - k) + k) (注:k由粗糙度a计算,直接光照:k=(a+1)^2 / 8, 间接光照:k=a^2 / 2)
- K(d):(1-F)*(1-metallic)
1 | //计算直接光照 |
- IBL间接光照
- CubeMap IrradianceMap 或者ShadeSH9() 计算间接光照的diffuse
- 预高光积分图,或者高光积分算法计算间接光照的specular
1 | //计算间接光照 |
- PBR两种工作流
- metaillic/roughness工作流(金属/粗糙度)
- specular/glossness工作流(高光/光泽度)
区别:
渲染管线
Bulid-in
内置管线,不可自定义
SRP
可编程的渲染管线
URP
通用渲染管线:Unity 2019.2.0版本后支持Universal Render Pipeline
HDRP
高清渲染管线
LWRP
URP的前身
后处理
- LUT(ColorGrading) 颜色分级(调整暖色/饱和度这种)
- Bloom 全屏泛光
- GaussianBlur 高斯模糊
- DepthOfField 景深模糊
- RadialBlur 径向模糊
Post-ProcessStack
角色渲染
头发
- 各项异性光照
- Kajiya-Kay光照模型:使用切线/副切线计算高光,高光计算两层,往法线方向偏移。
1 | // 计算高光值 |
皮肤
- 次表面散射(SSS)
阴影渲染
标准阴影算法步骤:
(1) 以光源空间绘制:生成深度图
(2) 以相机空间绘制:将顶点坐标转换值光源空间的顶点z值得到d值
(3) 以顶点再光源空间的xy值为uv采样ShadowMap,获取阴影z值
(4) d >= z 阴影内, d < z阴影外软阴影:通常使用PCF,PCSS
PCF:从目标点周围多个点做偏移采样,取平均阴影值
PCSS:
阴影失真:Shadow Acne,Peter Panning
级联阴影 Cascade Shadowmap:
ScreenSpaceShadow:
ShadowVolume:
GI
- Ray Tracing
- Path Tracing
Shader调试工具
Frame Debuger
Renderdoc
XCode
环境效果
动画与特效
NPR(Non Photorealistic Rendering) 非真实渲染
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Skier!