OpenGL3.3_C++_Windows(24)

渲染平行光阴影

  • 阴影作用:

  • 有了阴影的渲染,更容易地区分出物体之间的位置关系,
  • 如何判断片段是否在阴影中?
  • 普通思路:

  • 以光的位置为视角进行渲染,我们绘制一条从光源出发的射线,测试更新射线经过的所有片段,与当前min最近片段比较,如果更远,就在阴影中
  • 弊端:

  • 射线上的成千上万个点进行遍历是个极端消耗性能,所以换种思路,利用深度缓冲
  • 深度缓冲:

  • 深度缓冲大小符合窗口的宽高,当运行深度测试时,每个像素的深度值和已经存储在这个像素的深度值(深度缓冲)进行比较,根据深度测试函数,决定片段是否丢弃
  • 深度/阴影/shadow Mapping贴图

  • 从光源的透视图来渲染场景,并把深度值的结果储存到纹理中,深度值因为会不断测试更新,最后的结果,就是最近的片段的深度值,通过纹理坐标,可以对它进行采样,获取深度值
  • T变换

  • 来自光源的视图投影矩阵,可以将任何三维位置(从世界坐标)转变到光源的可见坐标空间
  • 如何利用深度贴图判断片段是否在阴影中?

  • 首先T变换到光源的坐标空间里,使用生成的深度贴图计算片段是否在阴影之中,z深度 如果 > 片段的深度缓冲的深度值,则在阴影中

运算:

  • 创建新的帧缓冲

  • 因为要对深度值采样,所以应存储在纹理附件(非渲染缓冲对象附件),应用的纹理格式为GL_DEPTH_COMPONENT,
  • 注意:不包含颜色缓冲的帧缓冲对象是不完整的,所以我们需要显式告诉OpenGL我们不适用任何颜色数据进行渲染。glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE);
  • 平行光源空间的T变换矩阵

  • LookAt()计算光(位置+看的方向)的view矩阵(实质,将物体坐标变换到相机坐标的视角下),

  • 如果使用一个所有光线都平行的定向光,使用正交投影矩阵,否则点光源和聚光灯,使用透视投影矩阵(因为投影矩阵实质,是决定可见的范围,以及范围的形状,光空间的范围,即光线的散射组成的范围,被光覆盖的范围)

  • 渲染到深度贴图

  • 启用帧缓冲,渲染场景,使用的新glsl中,将每个顶点变换到光空间,从而深度值保存到了深度纹理附件中,fragment什么都不用做,我们只需要深度缓冲(默认更新),也可以手动设置gl_FragDepth = gl_FragCoord.z;
  • //深度缓冲视觉化

  • 这次渲染quad,并应用深度纹理附件作为quad 的纹理。
  • 但是注意:正交不受深度值影响,透视投影矩阵,当深度缓冲视觉化经常会得到一个几乎全白的结果,深度变成了非线性的深度值,只有距离很近,颜色亮度才会骤降。
  • 解决方案就是变为线性深度值。
深度缓冲视觉化
  • 渲染阴影:Fragment glsl

  • 将要产生阴影的物体,在vs中将世界空间顶点位置转换为光空间,传入fs,计算出一个shadow值,当fragment在阴影中时是1.0,在阴影外是0.0
  • 将(1 - shadow )* 其他冯氏颜色分量(由于当shadow = 1的时候(在阴影),结果颜色为0),由于阴影不会是全黑的,把ambient分量从乘法中剔除。
  • 这样保证,当片断位于阴影,结果为ambient * 其他冯氏颜色分量,当非阴影 = ((ambient + 1 * 其他冯氏颜色分量
  • 计算阴影():

  • 光空间的片段位置(被判断的像素)和第一个渲染阶段得到的深度贴图(取深度值)
    • 光空间片段位置转换为裁切空间的标准化设备坐标。
    • 当运行到gl_Position时,OpenGL自动进行一个透视除法,x、y、z元素除以向量的w元素来实现,我们必须自己做透视除法
    • 因为来自深度贴图的深度在0到1的范围,我们再次将NDC坐标变换为0到1的范围
    • 从深度贴图,采样片段坐标,对应的深度值,如果片段的z高于采样的深度值,则表明片段在阴影中,返回1,否则返回0 
  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值