延迟渲染的提出为了解决前向渲染中存在的问题,
在前向渲染中,当场景中包含大量的实时光源时,渲染的性能会急速下降,例如当我们在场景中某个区域放置了多个光源,这些光源互相叠加,为了得到最终的光照效果,就需要为该区域内的每个物体执行多个Pass来计算不同光源对该物体的光照效果,然后再颜色缓冲中对这些结果进行混合得到最终的光照。然而,每执行一个Pass我们都需要重新渲染一遍物体,存在大量计算的重复。
延迟渲染额外的利用了一些缓冲区称作G-Buffer 存储了表面法线、位置、光照计算的材质属性等。渲染时分两个Pass,第一个Pass不进行任何光照计算,仅计算哪些片元可见,如果片元可见就把对应的信息存入G-buffer,在第二个Pass时利用之前存各片元信息对屏幕进行逐像素的光照计算。
Pass 1{
for(each primitive in this model) {
for(each fragment covered by this primitive){
if(falied in depth test){
discard; //没通过深度测试的丢弃
} else{
// 可见的存储对应信息
writeGBuffer(materialInfo,pos,normal);
}
}
}
}
Pass 2{
for(each pixel in the screen){
if(the pixel is valid){
// 读取对应GBuffer信息
readGBuffer(pixel,materialInfo,pos,normal);
float4 color = Shading(materialInfo,pos,normal,lightDir,viewDir);
// 更新缓冲
writeFrameBuffer(pixel, color);
}
}
}
当然由于直接剔除了一些看不到的面片也会存在一些问题,包括不能处理半透明的物体,不支持真正抗锯齿。