shadow mapping实现动态shadow实现记录 【转】
http://blog.csdn.net/iaccepted/article/details/45826539
前段时间一直在弄一个室内场景,首先完成了render,效果还可以。然后给其加上shadow,使其更逼真。这里主要记录下在做的过程中遇到的问题。
1.是在导入场景的时候,由于场景比较大(200M)左右,所以在iOS上加载这么大的场景会频繁的memorywarning,然后就会被系统kill掉。这个问题的解决方法是通过改变数据类型来达到压缩的目的。顶点的坐标double是没法改变的,如果改变会严重影响场景的准确度。这里主要是改变normal和 uv的类型,其实在正常的精度范围内,normal和 uv不需要double或者float来存储,可以用一个short来存储,这里就要把normal 和 uv 加一个偏移值(比如乘以10000),这个样就可以节省大量的存储空间,初步测试,加载完整个场景内存占用大约为300M多点,现在的ipad完全可以承受。然后在shader中正真使用的时候只需要把数据还原就行,这样几乎没有多少效率的损失但是却极大的减少了内存的占用。
2.场景内不同的mesh的材质均各不相同,加载的时候可以将同一材质的mesh归在一起,这样在绘制的时候,可以方便的赋予材质信息。刚开始写了加载场景和材质的类,但是最后为了可靠性以及后续支持不同格式的模型加载,选择了使用开源库assimp来负责模型加载这一块。在github上找到源码进行编译,编译出支持armv7,arm64的版本然后在ios中使用。使用的过程中需要导入libz, libc++, libstdc++等等的框架。然后就可以在ios上使用该库。
3.shadow mapping的原理:简单的说就是先渲染场景的深度信息,即从光源的位置放置相机进行一遍渲染,当然这里只取得深度信息即可,为了方便使用,将深度信息渲染到一张深度纹理中,然后将该深度纹理传入shader,在正常相机位置渲染,在shader中将每个点经过模型转换后的深度值与深度纹理中的深度值作比较,若当前深度值大于深度纹理中的深度值,那么很显然该点处在shadow中,需要暗化处理,反之亦然。
4.生成纹理贴图之后,将其传入shader中,这里遇到的问题是,开始时深度信息一直错误,将深度纹理以正常纹理贴图的方式呈现出来是完全乱掉的。后来在opengl官网找到下面的一句话:
If a texture has a depth or depth-stencilimage format and has the depth comparison activated, it cannot be used with anormal sampler. Attemptingto do so results in undefined behavior. Such textures must be used with ashadow sampler.
在windows平台上倒是没有遇到这个问题,能正常的把包含depthimage format的texture正常的贴出来,但是在ios平台上使用OES2.0时不能正常工作,好像确实出现了未定义的现象。
5.将以上texture重新以sampler2DShadow的形式接受,并进行绘制时纹理仍然错误,这次错误的原因很好定位,主要是忘记将坐标空间转到纹理空间(0-1),通过shadowMVP矩阵转换的坐标的x和y值均在[-1, 1]区间,所以要使用一个bias矩阵进行转换将[-1, 1]转换到[0, 1]。
6.转换完成之后可以使用shadow2DProj函数来完成深度值的比较,当然这里也可以自己比较,但是自己比较的时候要注意将x和y的值除以w分量然后再取出深度值,这其实也是shadow2DProj中的实现方式,这个函数会先将x和y分量除以w分量然后再取出深度值与深度纹理中的值进行比较,若深度测试成功(即深度值小于深度纹理中的深度值)则返回1,若深度测试失败则返回0。这样我们就可以进行shadow的处理。
7.以上都能正确之后,shadow效果应该是可以做出来了,但是可能会出现z-fighting的问题,而且可能相当的严重,如果上面我们不是用shadow2DProj来进行深度值比较的话,那么我们可以在比较深度值的时候加一个小的容错误差,当然这个值的大小要亲自多次试验看效果才能选定,因为对不同的场景,不同的机器这个值的差异可能很大,我这里简单试了一下,去0.006时的效果还是比较好的。但是如果我们使用了shadow2DProj的话,那么比较函数不是我们自己实现的,那么我们就没办法加上这个小的容错误差。这时候我们可以在绘制的时候使用polygonoffset来避免z-fighting的问题,试了下这样的效果也的确是非常棒。
以上就是在shadowmapping实现过程中遇到的几个问题。
虽然shadowmapping的原理很简单,但是正真实现一个效果比较好的shadowmapping还是有点麻烦的。
下一步要打算实现SSAO。
shadow mapping实现动态shadow实现记录 【转】的更多相关文章
- Tutorial - Deferred Rendering Shadow Mapping 转
http://www.codinglabs.net/tutorial_opengl_deferred_rendering_shadow_mapping.aspx Tutorial - Deferred ...
- Shadow mapping
http://www.cnblogs.com/cxrs/archive/2009/10/17/1585038.html 1.什么是Shadow Maping? Shadow Mapping是 ...
- OpenGL 阴影之Shadow Mapping和Shadow Volumes
先说下开发环境.VS2013,C++空项目,引用glut,glew.glut包含基本窗口操作,免去我们自己新建win32窗口一些操作.glew使我们能使用最新opengl的API,因winodw本身只 ...
- OpenGL阴影,Shadow Mapping(附源程序)
实验平台:Win7,VS2010 先上结果截图(文章最后下载程序,解压后直接运行BIN文件夹下的EXE程序): 本文描述图形学的两个最常用的阴影技术之一,Shadow Mapping方法(另一种是Sh ...
- opengl 教程(24) shadow mapping (2)
原帖地址:http://ogldev.atspace.co.uk/www/tutorial24/tutorial24.html 本篇教程中,我们通过shadowmap来实现阴影渲染. 我们知道shad ...
- (转)Shadow Mapping
原文:丢失,十分抱歉,这篇是在笔记上发现的.SmaEngine 阴影和级联部分是模仿UE的结构设计 This tutorial will cover how to implement shadow ...
- OpenGL核心技术之Shadow Mapping改进版
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解 ...
- OpenGL核心技术之Shadow Mapping
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D ...
- Shadow Mapping 的原理与实践(二)
3) 定义并生成Shadow Map纹理 texture2D Lamp0ShadowMapColor : RENDERCOLORTARGET < float2 ViewPortRatio = { ...
随机推荐
- php文件上传需要的配置
服务端配置(php.ini) 1.file_uploads=On //支持HTTP上传 2.upload_tmp_dir =”” //临时文件保存的目录 3.upload_max_filesize ...
- asp.net的Server.MapPath方法
Server.MapPath()的功能: 返回与 Web 服务器上的指定虚拟路径相对应的物理文件路径. 命名空间: System.Web 程序集: System.Web(在 System.Web.dl ...
- hdu 1430(BFS+康托展开+映射+输出路径)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
- 如何在SQL Server中的SELECT TOP 中使用变量
语法 [ TOP (expression) [PERCENT] [ WITH TIES ] ] 注意:expression 是在一对圆括号内的,而之后又有如下的例子 在 TOP 中使用变量 以下示 ...
- idea优秀插件(Java开发常用)
http://blog.csdn.net/sujun10/article/details/72852939 1.findBugs-IDEA 可以查看代码中基础错误,这个eclipse中也有,操作也方便 ...
- 【BZOJ 2809】2809: [Apio2012]dispatching (左偏树)
2809: [Apio2012]dispatching Description 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Maste ...
- 2017 Multi-University Training 1 解题报告
Add More Zero Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)T ...
- 【推导】Codeforces Round #364 (Div. 2) D. As Fast As Possible
一种方法是二分总时间,复杂度O(nlogn). 另外我们可以证明,当所有人同时到达终点的时候,是最优的,因为没有人的时间“浪费”了. 我们又发现,每个人的运动过程总是两段,要么是走路,要么是坐车.于是 ...
- 【数论】【欧拉函数】CDOJ1724 为了我们心爱的京电
京州电子科技大学遭遇废校危机,为了保护我们心爱的学校,N位魔法少女站了出来,她们能做的就是……成为偶像! 每个魔法少女都拥有一定的人气,他们中的每个人的人气计算方式如下: 假设某个魔法少女的学号为a, ...
- TCP,UDP,IP总结
一.传输层的主要功能是什么? 分割并重新组装上层提供的数据流,为数据流提供端到端的传输服务. 二.传输层如何区分不同应用程序的数据流? 因为,对应传输层而言,它只需要知道目标主机上的哪个服务程序来响应 ...