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

平行光的阴影实现方式
相对来说,平行光的实现要简单得多,下面我们看看平行光的阴影实现原理:
- 创建一个帧缓冲对象,用来渲染深度贴图;
- 创建一个和光源方向一致的摄像机对象;
- 创建接收深度的贴图对象;
- 通过自己编写的着色器,渲染深度信息到贴图中;
- 渲染模型时,将之前渲染好的阴影深度贴图传入,通过计算出每个像素相对于平行光的深度之后,和阴影深度贴图上的可显示深度进行对比,如果是不可显示的像素,则当前像素值乘于阴影颜色即可;
示例请查看: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学习笔记(九):阴影的更多相关文章
- 多线程学习笔记九之ThreadLocal
目录 多线程学习笔记九之ThreadLocal 简介 类结构 源码分析 ThreadLocalMap set(T value) get() remove() 为什么ThreadLocalMap的键是W ...
- MDX导航结构层次:《Microsoft SQL Server 2008 MDX Step by Step》学习笔记九
<Microsoft SQL Server 2008 MDX Step by Step>学习笔记九:导航结构层次 SQL Server 2008中SQL应用系列及BI笔记系列--目录索 ...
- python3.4学习笔记(九) Python GUI桌面应用开发工具选择
python3.4学习笔记(九) Python GUI桌面应用开发工具选择 Python GUI开发工具选择 - WEB开发者http://www.admin10000.com/document/96 ...
- Go语言学习笔记九: 指针
Go语言学习笔记九: 指针 指针的概念是当时学C语言时了解的.Go语言的指针感觉与C语言的没啥不同. 指针定义与使用 指针变量是保存内存地址的变量.其他变量保存的是数值,而指针变量保存的是内存地址.这 ...
- webgl学习笔记五-纹理
写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 术语 : 纹理 :图像 图形装配区域 :顶点着色器顶点坐标 ...
- webgl学习笔记四-动画
写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 下面我们将讲解下如何让一个正方形动起来~不断擦除和重绘 ...
- webgl学习笔记三-平移旋转缩放
写在前面 建议先阅读下前面我的两篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 平移 1.关键点说明 顶点着色器需要加上 uniform vec4 u_Translation ...
- webgl学习笔记二-绘图多点
写在前面 建议先看下第一篇webgl学习笔记一-绘图单点 第一篇文章,介绍了如何用webgl绘图一个点.接下来本文介绍的是如何绘制多个点.形成一个面. webgl提供了一种很方便的机制,即缓冲区对象, ...
- WebGL学习笔记二——绘制基本图元
webGL的基本图元点.线.三角形 gl.drawArrays(mode, first,count) first,代表从第几个点开始绘制即顶点的起始位置 count,代表绘制的点的数量. mode,代 ...
- go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin)
目录 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin) zipkin使用demo 数据持久化 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin ...
随机推荐
- 百度地图公交线路查询,并绘制到地图上并获取所有路径经纬度点(可供echarts 路径图使用)
github地址 https://github.com/a1115040996/MyHTML/tree/gh-pages/BDMap 源代码 <!DOCTYPE html PUBLIC &quo ...
- python 导入导出依赖包命令
程序中必须包含一个 requirements.txt 文件,用于记录所有依赖包及其精确的版本号.如果 要在另一台电脑上重新生成虚拟环境,这个文件的重要性就体现出来了,例如部署程序时 使用的电脑.pip ...
- X509Store 类
标题:X509Store 类 地址:https://docs.microsoft.com/zh-cn/dotnet/api/system.security.cryptography.x509certi ...
- C++学习(8)—— 封装
C++面向对象的三大特性:封装.继承.多态 C++认为万事万物都可以为对象,对象上有其属性和行为 具有相同性质的对象,可以抽象为类 1. 封装的意义 封装是C++面向对象三大特性之一 封装的意义: ...
- FTPClient中使用completePendingCommand方法注意事项
方法介绍: * There are a few FTPClient methods that do not complete the * entire sequence of FTP commands ...
- day008-python内置函数
一.ptthon内置函数 二.内置函数详细概述 2.1 abs(x):函数返回数字的绝对值. 注意: 1)x -- 数值表达式,可以是整数,浮点数,复数. 2)如果参数是一个复数,则返回它的大小. ...
- 如何高效的阅读uni-app框架?(建议收藏)
作者 | Jeskson来源 | 达达前端小酒馆 uni-app的框架,配置:page.json,manifest.json,package.json,vue.config.js.脚本,应用程序,ma ...
- k8s实现灰度发布
灰度发布在实际生产部署中是经常被使用的方式,常规的方法是手动从前端LB(负载均衡)上将后端服务器摘掉,然后,停服务,最后上传代码,完成软连接更新.在使用CI/CD工具时,这个过程变得自动化了,我们只需 ...
- cBioPortal 数据库
http://www.cbioportal.org/ 参考连接 http://www.geneseed.com.cn/page464?article_id=413
- IO多路复用之Reactor
参考文档: http://blog.csdn.net/u013074465/article/details/46276967 https://www.cnblogs.com/ivaneye/p/573 ...