3D中实现实时阴影技术中比较常见的方式是阴影映射(Shadow Mapping),我们这里也以这种技术来实现实时阴影。

阴影映射背后的思路非常简单:我们先以光的位置为视角进行渲染,我们能看到的东西都将被点亮,看不见的一定是在阴影之中了(这里会将是否可视的信息作为深度贴图进行渲染)。假设有一个地板,在光源和它之间有一个大盒子。由于光源处向光线方向看去,可以看到这个盒子,但看不到地板的一部分,这部分就应该在阴影中了。

平行光的阴影实现方式

相对来说,平行光的实现要简单得多,下面我们看看平行光的阴影实现原理:

  1. 创建一个帧缓冲对象,用来渲染深度贴图;
  2. 创建一个和光源方向一致的摄像机对象;
  3. 创建接收深度的贴图对象;
  4. 通过自己编写的着色器,渲染深度信息到贴图中;
  5. 渲染模型时,将之前渲染好的阴影深度贴图传入,通过计算出每个像素相对于平行光的深度之后,和阴影深度贴图上的可显示深度进行对比,如果是不可显示的像素,则当前像素值乘于阴影颜色即可;

示例请查看:https://hammerc.github.io/dou3d-ts/learning/learningNotes/lesson_10/Shadow.html

马赫带

片段着色器中判断当前像素是否处于阴影之中的代码如下:

float visibility = (shadowCoord.z > depth) ? 0.7 : 1.0;

这么写的话,会出现一条一条的纹路,被称为马赫带,解决办法是给深度加上 0.005 的分量,如下:

float visibility = (shadowCoord.z > depth + 0.005) ? 0.7 : 1.0;

阴影生成时使用的透视矩阵类型

一般来说模拟平行光时,生成阴影贴图使用可以使用正交相机,当然也可以使用透视相机来实现距离越近阴影越大的效果;

点光源,点光源不同于平行光,是向所有方向发射光源,所以不能简单的使用平行光的方法来实现,主要的区别在于平行光使用了一个平面贴图,而点光源需要使用一个立方体贴图来实现,具体可以参考:https://blog.csdn.net/jxw167/article/details/57477261

提高精度

上面我们实现了阴影,不过有一个问题,当我们把光照的位置拉远之后(仅使用透视矩阵生成阴影贴图时),会发现阴影消失了:

var LIGHT_X = 0, LIGHT_Y = 40, LIGHT_Z = 2;

这是因为,我们把 gl_FragCoord.z 的深度值存储在只有 8 位的红色分量中导致的,所以距离过远之后,8 位的红色分量就存储不下了,好的方法是所有的分量都用上来存储;

修改后的示例如下:https://hammerc.github.io/dou3d-ts/learning/learningNotes/lesson_10/Shadow_highp.html

阴影投影到球体

除了可以投影到平面,阴影也可以投影到任意模型上,比如球体:https://hammerc.github.io/dou3d-ts/learning/learningNotes/lesson_10/Shadow_highp_sphere.html

WebGL学习笔记(九):阴影的更多相关文章

  1. 多线程学习笔记九之ThreadLocal

    目录 多线程学习笔记九之ThreadLocal 简介 类结构 源码分析 ThreadLocalMap set(T value) get() remove() 为什么ThreadLocalMap的键是W ...

  2. MDX导航结构层次:《Microsoft SQL Server 2008 MDX Step by Step》学习笔记九

    <Microsoft SQL Server 2008 MDX Step by Step>学习笔记九:导航结构层次   SQL Server 2008中SQL应用系列及BI笔记系列--目录索 ...

  3. python3.4学习笔记(九) Python GUI桌面应用开发工具选择

    python3.4学习笔记(九) Python GUI桌面应用开发工具选择 Python GUI开发工具选择 - WEB开发者http://www.admin10000.com/document/96 ...

  4. Go语言学习笔记九: 指针

    Go语言学习笔记九: 指针 指针的概念是当时学C语言时了解的.Go语言的指针感觉与C语言的没啥不同. 指针定义与使用 指针变量是保存内存地址的变量.其他变量保存的是数值,而指针变量保存的是内存地址.这 ...

  5. webgl学习笔记五-纹理

    写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 术语 : 纹理 :图像 图形装配区域 :顶点着色器顶点坐标 ...

  6. webgl学习笔记四-动画

    写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放   下面我们将讲解下如何让一个正方形动起来~不断擦除和重绘 ...

  7. webgl学习笔记三-平移旋转缩放

    写在前面 建议先阅读下前面我的两篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 平移 1.关键点说明 顶点着色器需要加上 uniform vec4 u_Translation ...

  8. webgl学习笔记二-绘图多点

    写在前面 建议先看下第一篇webgl学习笔记一-绘图单点 第一篇文章,介绍了如何用webgl绘图一个点.接下来本文介绍的是如何绘制多个点.形成一个面. webgl提供了一种很方便的机制,即缓冲区对象, ...

  9. WebGL学习笔记二——绘制基本图元

    webGL的基本图元点.线.三角形 gl.drawArrays(mode, first,count) first,代表从第几个点开始绘制即顶点的起始位置 count,代表绘制的点的数量. mode,代 ...

  10. go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin)

    目录 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin) zipkin使用demo 数据持久化 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin ...

随机推荐

  1. 树莓派无显示屏连接wifi

    在烧好Raspbian系统的TF卡boot分区新建 wpa_supplicant.conf 文件,内容如下(修改自己的WIFI名和密码,key_mgmt根据路由器配置),保存后启动树莓派即可自动连接W ...

  2. K8s管理机密信息

    1. 启动应用安全信息的保护 Secret介绍 应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名密码或者秘钥.将这些信息直接保存在容器镜像中显然不妥,Kubernetes 提供的解决方案是 ...

  3. Linux core dump总结

    文章链接:https://www.cnblogs.com/Anker/p/6079580.html 1.前言 一直在从事linux下后台开发,经常与core文件打交道.还记得刚开始从事linux下开发 ...

  4. jmeter针对websocket协议的压测

    之前一直没有接触过websocket协议,所以一直对websocket的压测存在疑惑,在网上参考文章并不断尝试之后,终于有所得:第一次用jmeter的websoket插件,用的ws非加密协议,请求都能 ...

  5. selenium安装

    pip安装 pqi优化pip下载速度 pip install selenium pip install --upgrade selenium pip show selenium 离线安装 官网下载se ...

  6. 项目Beta冲刺(团队)--7/7

    课程名称:软件工程1916|W(福州大学) 作业要求:项目Beta冲刺 团队名称:葫芦娃队 作业目标:进行新一轮的项目冲刺,尽力完成并完善项目 团队博客 队员学号 队员昵称 博客地址 04160242 ...

  7. “SkyReach”对“待就业六人组”和“葫芦娃”的Beta产品测试报告

    对"待就业六人组"的Beta产品测试报告 安装成功截图 第一次上手体验感觉如何?能否正常运行? 第一次上手体验,界面简洁明了,简约的风格比较迎合个人的口味:能够正常运行: 该产品具 ...

  8. 20180524模拟赛T3——Word

    [题目描述] 有一个星球要创造新的单词,单词有一些条件: 字母集有\(p\)个元音和\(q\)个辅音,单词由字母构成 每个单词最多有\(n\)个元音和\(n\)个辅音(同一元音或辅音可重复使用) 每个 ...

  9. wordpress定时发布失败Missed Schedule解决方法

    今天一位客户的网站设置了文章定时发布但却没有发布成功,提示Missed Schedule错误,把所有的插件都暂停了再设置定时发布也不行,那就只能寻找其他的解决方案了.ytkah查看一下有没相关修复插件 ...

  10. js版本规范的表示:ES6 == ES 6 == ECMAScript 6 == ECMA-262 6

    Ecma 国际大会宣布正式批准ECMA-262第 6 版,亦即 ECMAScript 2015(曾用名:ECMAScript 6.ES6)的语言规范. 关系 ECMA-262 == ECMAScrip ...