Deferred rendering Gbuffer优化: 单张Float16纹理存储更多信息来“模拟“MRT

请见Demo:Rendering & Art

光照在 Deferred rendering 机制下性能会更好, 尤其是基于tile base rendering 或者 cluster rendering 的光照数据检索原理,会让性能更优。但是gbuffer在使用的时候,一般都需要硬件对MRT的支持, 即使支持MRT也都希望在单张纹理里面放入更多的数据。这里给的样例就是在单张 float16数据格式的纹理中放入: Normal, RGB, Position。有了这三类数据,就能做延迟光照了。例如移动端这种对性能带宽要求更加苛刻的设备上,这个方式可能会很有价值。例如在只支持webgl1(gles2)的设备上完成Deferred Rendering。

注意,虽然这里的法线损精度降低,但是基本够用。

上图的整个有半部分, 展示的是延迟光照的渲染结果。左下部分是法线,左上部分是原始的纹理RGB展示。

gbuffer 片段着色器代码,展示如何将对应数据塞入到 float16格式的浮点数中(这一点非常重要,要注意取值范围和浮点数的存储方式)

// gbuffer fragment shader

vec4 color0 = texture(u_sampler0,v_texUV.xy);
vec3 color = floor(color0.rgb * 90.0) * 0.1;
vec3 floor_pnv = floor(98.0 * v_pnvs) * 10.0;
vec3 tnv = floor_pnv + vec3(0.00001);
floor_pnv += (tnv / abs(tnv)) * color;
OutputColor = vec4(floor_pnv, v_viewZ);
// 这个v_viewZ 指的是片段对应的摄像机空间的位置到摄像机坐标原点的距离

使用gbuffer 纹理数据得到 Normal, RGB, Camera View Space Position 的fragment shader 的代码:

// 获得 Camera View Space Position的函数
vec3 clacViewPosFromSPosAndVZ(vec2 screenPos, float viewZ)
{
    vec3 mpnv = vec3(screenPos.x * u_frustumParam.z,screenPos.y * u_frustumParam.w,u_frustumParam.x);
    mpnv = normalize(mpnv);
    mpnv = mpnv * (viewZ / mpnv.z);
    return mpnv;
}

// 还原 Normal, RGB, View Space Position
// v_texUV(取值范围为: 0.0->1.0)
vec4 baseColor = texture(u_sampler0,v_texUV.xy);
vec3 geomRGB = abs(baseColor.rgb);
geomRGB = u_color.a * fract(geomRGB* 0.1) / 0.9;
vec3 nv = floor(baseColor.rgb * 0.1);
nv = nv / 98.0;
nv = normalize(nv);
vec2 screenPos = (v_texUV - 0.5 ) / vec2(0.5,0.5);
vec3 viewSpacePos = clacViewPosFromSPosAndVZ(screenPos, baseColor.a);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值