实时渲染——GPU与渲染流水线
实时渲染——GPU与渲染流水线
Recap
绘制方程(Kajiya)
求解方程的难点:入射光项的计算(间接光照)
离线渲染中的两种方法:
光线跟踪
有限元求解
Real-time Rendering 引入Intro
实时渲染的挑战
Time-budget(Time-critical) rendering
Rendering in a fixed budget of time
Rendering very fast:
Traditional Criteria: >= 30 FPS
Now >= 60 FPS
For VR: >= 90 FPS
解决方法
Local Shading
$ L_o(x,\omega _o) = L_i(x,\omega _i)f_r(x,\omega _i \rightarrow \omega _o)cos(\theta _i) $
去掉积分、去掉间接光照,只考虑主光源
节省了计算时间,但没有了阴影/间接光照等,视觉不正确,需要使用GI等方法进行修正。
Rendering PipeLine
GeometryEngine SGI(19 ...
离线渲染——真实感材质建模
离线渲染——真实感材质建模
南京大学 王贝贝 2024.8.7
王老师主要讲解了渲染中的基本概念以及常见的材质模型。
课程目标:
一个shader
一个感兴趣的材质方向
材质模型的基本概念
辐射度量学 Radiometry
中学物理知识告诉我们使用Q焦耳描述能量。由于光也携带能量,在辐射度量学固然也是如此。
辐射通量 Radiant flux
flux用于描述单位时间通过的能量。
单位:瓦特 W,Watt(流明,lm,lumen)
$ \phi = \frac {dQ} {dt} $
辐射强度 Radiant Intensity
intensity用于描述每单位角的通量。
$ I(\omega) = \frac {d\phi}{d\omega} $
辐照度 irradiance
irradiance用于描述通过单位面积的流明。
单位:lux ($ \frac{W}{m^2} $)
$ E(x) = \frac {d\phi(x)}{dA} $
辐射率/辐射亮度 radiance
radiance用于描述每单位角每投影面积的能量。
单位:尼特 nit ($ \frac{W}{sr m ...
光线追踪理论
概率论基础
采样方法
逆变换采样方法
拒绝采样方法
二维流形采样
间接光照估计
当一根光线打到材质表面时(暂时不考虑体渲染),应该在半球上怎样采样才能得到均匀的光线出射方向呢?
蒙特卡洛积分 Monte Carlo
多重重要性采样 MIS
根据上面的介绍可以看到,根据蒙特卡洛积分的方差公式。可以得到两个减小方差的途径:
增加采样数,相应的会使得渲染时间更长
选择合适的采样函数P(x),这是相较增加采样数更为实际的方法。
其中的P(x)就是重要性采样函数,也是许多方法的关注点。
Navie方法
分层采样
拟蒙特卡洛方法
BRDF重要性采样
Next Event Emmision(NEE)
俄罗斯轮盘赌
直接光照估计
使用重要性采样计算直接光照的计算。徐昆老师介绍了两种方法:
利用BRDF进行重要性采样
主要思想:
利用物体材质的BRDF函数的出射方向,检查是否与光源相交。
适用条件:
适用于面光源等面积较大的光源
适用于glossy的材质(?没记清楚)
光源重要性采样
主要思想:
将光线与物体表面的相交点与光源连线。
适用条件:
适用于点光源等小光源。
适用于非glossy的材 ...
光线追踪理论与实践
前言
作于2024年CCF图形学启明星计划夏令营期间。主要依据是徐昆老师讲解的光线追踪理论基础部分。
光线追踪的发展历程
光栅化渲染管线将场景中的所有物体进行MVP变换,是一种物体视角的渲染思路。
光线追踪渲染管线中场景中的物体不再变换,而是从相机一端以像素为单位投射光线,是一种相机视角的渲染思路。
光线投射 Ray Casting
光线投射由Arthur Appel在一篇名为《 Some techniques for shading machine rendering of solids》中提出。这是光线追踪的第一步,需要将屏幕空间转换到世界坐标下,然后以每个像素为起点向场景中发射一条光线,并根据与光线相交的第一个物体表面的能量进行渲染。
光线追踪 Ray Tracing
Whitted-Style光线追踪在光线投射的基础上使用了递归式的光线追踪。当光线与材质表面相交时根据不同表面进行计算。但Whitted-Style并没有考虑直接光照,且物体材质的表现并不全面(没有glossy、diffuse项)。
路径追踪 Path Tracing
1986年,Kajiya提出了路径追踪方法。K ...
C++多态
静态多态
静态多态通过重载实现多态
重载函数
函数同名,参数不同类型
123456void Func1(int a) { cout << "This is Func1(int), Parameter = "<< a << endl;}void Func1(float a) { cout << "This is Func1(float), Parameter = " << a << endl;}
重载运算符
123friend ostream& operator << (ostream o,const A& a) { return o<<a.a;}
动态多态
动态多态通过虚函数实现多态。使用动态多态必须通过指针或引用才能调用函数。
虚函数
虚函数的声明和调用
12345678910111213141516171819202122232425262728293 ...
C++继承
继承
访问属性
私有 private
仅能在类内访问,不可继承,子类不可访问。
保护 protected
仅能在类内访问,可继承,子类可访问。
公有 public
可在类内或类外访问,可继承,子类可访问。
继承方式
私有继承 private
父类中的public、protected成员以private属性继承至子类中。(访问权限降为private)
保护继承 protected
父类中的public、protected成员以protected属性继承至子类中。(访问权限降为protected)
公有继承 public
父类中的public、protected成员以原有属性继承至子类中。(保持原有访问权限)
类型转换
一个公有派生类的对象在使用上可以被当作基类的对象,反之则不可。
具体表现在:
派生类的对象可以隐含转换为基类对象。
派生类的对象可以初始化基类的引用。
派生类的指针可以隐含转换为基类的指针。
通过基类对象名、指针只能使用从基类继承的成员,派生类新增的成员不能使用。
构造函数与析构函数
构造函数在创建该类对象时调用。必须使用new、malloc等创建该类对象的指针或引用 ...
C++封装
类
类的成员
一个类包含:
变量
函数
构造函数
析构函数
内联成员函数 inline
使用inline关键字将函数声明为内联函数。
**作用:**在编译阶段内联函数会将函数体替换到函数调用处,也就是说内联函数省去了调用函数花费的时间。
声明方法:
类内声明 直接在类内声明函数体会将函数隐式的声明为内联函数。
1234567class A{public: //隐式地声明为内联函数 void func(){ std::cout<<"Call Function"<<std::endl; }}
类外声明 类外声明的函数使用inline关键字将函数声明为内联函数。
12345678class A{public: void func();}//显式地声明为内联函数inline void A::func(){ std::cout<<"Call Function"<<std::endl;& ...