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 ...
随机推荐
- crontab 定时任务简单备份数据库
备份数据库/usr/local/mysql5.5/bin/mysqldump -uroot -p1234abcd wordpress >~/wordpress_20151206.sql 59 2 ...
- 定制你的“魅力”报告--Allure
“人世间是一个大囚笼,每个人都在狱中,砥砺前行.九狱台中的刺,是生活中所要面对的砥砺,是锋利的刺,将自己肉身刺得千疮百孔,将自己的道心刺得千疮百孔.” ---<牧神记·九狱锁道心> 一.简 ...
- Chrome出现“浏览器由所属组织管理”如何解决
之前碰到了这个问题,删除注册表解决了.当时没记下来,今天又碰到了.那就写下来以备之后再碰到吧 删除了注册表\HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Ch ...
- Elasticsearch 索引文档如何使用自动生成 Id?
一个文档的 _index . _type 和 _id 唯一标识一个文档. 我们可以提供自定义的 _id 值,或者让 index API 自动生成. 如果你的数据没有自然的 ID, Elasticsea ...
- gettid和pthread_self区别
http://blog.csdn.net/rsyp2008/article/details/45150621 1 线程ID获取方法 Linux下获取线程有两种方法: 1)gettid或者类似getti ...
- python实现用户登录、注册实例
python面向函数式编程,模拟用户登录验证.注册的代码实现. 主要有以下两个文件: 1.user.txt文档文件,相当于数据库的用户信息表,主要是记录用户名和密码. 注意:1)此文档需要与.py文件 ...
- 强大的接口调试工具-Postman图文详解
前言 在前后端分离开发时,后端工作人员完成系统接口开发后,需要与前端人员对接,测试调试接口,验证接口的正确性可用性.而这要求前端开发进度和后端进度保持基本一致,任何一方的进度跟不上,都无法及时完成功能 ...
- 指针*和取地址&函数输入使用
函数输入问题: 1 带&和不带& (参数本身还是拷贝一份参数) 2 函数输入指针 #include <iostream> using namespace std; int ...
- 搭建java环境时,DOS输入java有反应,javac没反应的解决办法。
2018-11-12 搭java环境踩了许多坑,之前搭环境时在命令台输入java有反应,javac没反应,后来试了很多方法都一样,然后就把java的所有的环境变量都删了,在控制面板里的卸载程序把所有的 ...
- luoguP3374 【模板】树状数组 1 cdq
链接 luogu 思路 可耐我连cdq都不会,Orz 陈丹琦 代码 #include <bits/stdc++.h> using namespace std; const int N = ...