Skip to content

Instantly share code, notes, and snippets.

@MouseChannel
Last active April 27, 2024 08:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MouseChannel/5a51d571f7a139d2399af962275e57a3 to your computer and use it in GitHub Desktop.
Save MouseChannel/5a51d571f7a139d2399af962275e57a3 to your computer and use it in GitHub Desktop.
图形学.md

渲染方程

$$ L_o(x,w_o) = L_e(x,w_0)+\int_{H^2}f_r(x,w_0,w_i)L_i(x,w_i)cos\theta_idw_i $$ $$ x = point-to-shading $$

$$ w_o = 观察角$$

$$ L_e = x点自发光的值$$

$$ 积分代表的是x点接受多个光源后,反射到w_o观测角度的值 $$

$$ L_i为角度为w_i射入到点的radiance $$

$$ f_r即BRDF,表示入射角度为w_i的radiance,对出射角度w_o的radiance的贡献为多少 $$

PBR/BRDF

现在常用的 BRDF 模型是 Cook-Torrance BRDF。

$$ f_r = k_df_{lambert}+k_sf_{cook-torrance} $$

其中漫反射 $$f_r = \frac{p}{\pi},p = albedo$$

其中镜面反射

$$f = \frac{F(i,o)G(i,o,h)D(h)}{4(n,i)(n,o)}$$

$$ F=菲涅耳:入射角和桌面法线方向越接近 的时候,光线反射比例越大$$

$$ D = 法线分布:常用的有GGX, $$

$$ G = 阴影遮蔽项 :当观察角度和法线达到90度时,此时菲涅耳项为1,会导致边缘发光,G项主要是为了中和菲涅耳项,物理解释为:考虑不同微表面之间的相互遮挡关系 $$

Blinn-phong

$$ L = L_{ambient}+ L_{diffse}+L_{Specular} $$

$$ 环境光+ 漫反射值+ 高光反射 $$

$$ ambient = 0.5*color $$

$$ diffuse = max(dot(light_dir, in_nrm), 0.) * color; $$

$$ spec = pow(max(dot(halfDir, in_nrm), 0.), 16.); $$

blinn-phong 和 phong 之间的区别是高光项 blinn-phong 通过半程向量和法线 phong是计算反射角度和观察角度, 计算反射角度计算量大一点

ShadowMap

第一个Pass:从光源出发,记录最浅的深度

第二个Pass:从摄像机出发,对应看到的每个点,都比较,该点相对于光源的深度和shadowMap里存的深度,如果过一样则没被遮挡,如果超过shadowMap的值则是阴影

自遮挡问题 由于shadowmap是一张图片,每个像素对应一块位置,即这整块位置的深度为一个相同的常值,当地平线场景下的光照时,某一个点的深度会被上一个点的深度自遮挡

RSM reflect shadow map

实时全局光照,假设每个 shading point 都会接受来自周围点反射的radiance(次级光源),然后在一张shadowMap中记录每个shading point周围点对其的贡献,这里作了两个假设

  • 计算周围贡献的时候,假设周围全是纯specular的,纯镜面反射
  • 假设shadowMap相邻的点世界空间坐标也相邻,所以直接从shadowMap像素点周围采样

PCF和PCSS

PCF是将某一点与shadowMap对应的点周围3x3范围内的点进行比较,最后加权得到一个0-1的数(e.g. 0.66),解决了Shadowmap锯齿 PCSS景深,即阴影离物体越远则阴影越软,离物体越近则阴影越硬,相较于PCF的区别为:动态卷积核大小,越软则卷积核越大

CSM 级联阴影贴图

测试

  • 透明度测试
  • 模板测试
  • 深度测试
  • 颜色混合

KD树原理

BVH加速结构

对物体进行排序,然后按照最长的那个轴,以中位数物体为轴构建两个AABB,然后递归地对两个AABB盒子进行构建

earlyz

指的是在fragment shader之前,光栅化之后,算出片元的深度信息,如果被遮挡则直接丢弃,不进入fragment shader阶段

radiance和irradiance

radiance指的是单位面积,单位立体角,单位时间,沿着某个方向的光线强度 irradiance指的是单位面积接受到的能量

延迟渲染 与 前向渲染

前向渲染 :n个物体,m个光源则复杂度为MxN,可能有些片元计算光照后被裁剪或者而丢弃了,造成性能浪费 延迟渲染:将所有物体都绘制到GBuffer上,只需要计算最终会被绘制到屏幕上的点的光照信息,即先做深度测试,再做光照计算 将场景信息渲染到GBuffer中,然后对于每个光源计算光照效果

MSAA

通过在屏幕上的每个像素位置执行多次采样,并将这些采样结果合并来抵消锯齿。 在延迟渲染中使用MSAA,MSAA是发生在光栅化阶段,fragment shader之前,需要用到几何信息,想要在延迟渲染中使用MSAA,需要把几何信息记录到fragment shader中

Image Based Lighting(IBL)

IBL用作环境光光照

根据渲染方程

$$ L_o(p,w_o) = \int_\Omega k_d\frac{c}{\pi}+k_s \frac{DFG}{4(w_o \cdot n)(w_i \cdot n )} L_i(p,w_i)(n\cdot w_i) dw_i $$

$$ w_o = V = 观测方向 $$

$$ w_i = L = 入射方向 $$

$$ n = 法线方向$$

$$ L_o(p,w_o) = \int_\Omega L_i(p,w_i) f_r(p,w_i,w_o)(n\cdot w_i)dw_i $$

after split sum approximation

split sum approximation need 2

  • narrow support / small domain(fit specular)
  • smooth value in support (fit diffuse)

$$ L_o(p,w_o) = \int_\Omega L_i(p,w_i)dw_i*\int_\Omega f_r(p,w_i,w_o)(n\cdot w_i)dw_i $$

preview one is given from SKY-Cubemap,last one we need pre_compute it

前面直接从环境光贴图skybox里读取,现在主要是预计算后面一项

$$ let: f = \frac{DG}{4(w_o \cdot n )(w_i \cdot n)} = \frac{f_r(p,w_i,w_o)}{F} $$

$$ \int_\Omega f_r(p,w_i,w_o)(n\cdot w_i)dw_i$$

$$ = \int_\Omega \frac{DGF}{4(w_o \cdot n )(w_i \cdot n)}(n\cdot w_i)dw_i$$

$$ = \int_\Omega Ff(n\cdot w_i)dw_i$$

$F$ with the Fresnel-Schlick approximation $F =F_0+(1 - F_0)(1 - w_o \cdot h)^5 $

$$ \int_\Omega \left[ F_0+(1 - F_0)(1 - w_o \cdot h)^5\right] f(n\cdot w_i)dw_i$$

$$ = \int_\Omega F_of(n\cdot w_i)dw_i+ \int_\Omega (1 - F_0)(1 - w_o \cdot h)^5f(n\cdot w_i)dw_i $$

$$ = F_o\int_\Omega f(n\cdot w_i)(1 - (1-w_o\cdot h)^5)dw_i + \int_\Omega(1 - w_o\cdot h)^5f(n \cdot w_i)dw_i$$

$$ = F_oA+B$$

extract $F_o$ successfully, and we need pre-compute $A$ and $B$

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment