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实现记录 【转】的更多相关文章

  1. Tutorial - Deferred Rendering Shadow Mapping 转

    http://www.codinglabs.net/tutorial_opengl_deferred_rendering_shadow_mapping.aspx Tutorial - Deferred ...

  2. Shadow mapping

    http://www.cnblogs.com/cxrs/archive/2009/10/17/1585038.html 1.什么是Shadow Maping?      Shadow Mapping是 ...

  3. OpenGL 阴影之Shadow Mapping和Shadow Volumes

    先说下开发环境.VS2013,C++空项目,引用glut,glew.glut包含基本窗口操作,免去我们自己新建win32窗口一些操作.glew使我们能使用最新opengl的API,因winodw本身只 ...

  4. OpenGL阴影,Shadow Mapping(附源程序)

    实验平台:Win7,VS2010 先上结果截图(文章最后下载程序,解压后直接运行BIN文件夹下的EXE程序): 本文描述图形学的两个最常用的阴影技术之一,Shadow Mapping方法(另一种是Sh ...

  5. opengl 教程(24) shadow mapping (2)

    原帖地址:http://ogldev.atspace.co.uk/www/tutorial24/tutorial24.html 本篇教程中,我们通过shadowmap来实现阴影渲染. 我们知道shad ...

  6. (转)Shadow Mapping

    原文:丢失,十分抱歉,这篇是在笔记上发现的.SmaEngine 阴影和级联部分是模仿UE的结构设计   This tutorial will cover how to implement shadow ...

  7. OpenGL核心技术之Shadow Mapping改进版

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解 ...

  8. OpenGL核心技术之Shadow Mapping

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D ...

  9. Shadow Mapping 的原理与实践(二)

    3) 定义并生成Shadow Map纹理 texture2D Lamp0ShadowMapColor : RENDERCOLORTARGET < float2 ViewPortRatio = { ...

随机推荐

  1. hdu 3605(二分图多重匹配)

    Escape Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  2. 查看linux版本及lsb_release安装及一些想法

    https://blog.csdn.net/darkdragonking/article/details/61194308

  3. PHP PDO类

    <?php //数据库连接类,不建议直接使用DB,而是对DB封装一层 //这个类不会被污染,不会被直接调用 class DB { //pdo对象 private $_pdo = null; // ...

  4. centos7.5英文环境切换到中文环境,再切回中文环境后 ,terminal不能用

    1.查看系统日志 less /var/logs/message May 12 21:54:41 localhost python: SELinux is preventing /usr/libexec ...

  5. SpringMVC组件配置

    web.xml . springmvc-servlet.xml 配置SpringMVC四大组件. web.xml 配置前端控制器:前端控制器就是个servlet <!-- 配置前端控制器 --& ...

  6. linux在命令执行过程中ctrl +z 后[1]+ Stopped

    进程挂起 stopped 代表有进程挂起 [1]是id号 可以通过Linux命令:jobs 查看挂起进程 fg 1 把任务1放到前台 bg 1 把任务1放到后台

  7. 验证二叉查找树(LintCode)

    验证二叉查找树 给定一个二叉树,判断它是否是合法的二叉查找树(BST) 一棵BST定义为: 节点的左子树中的值要严格小于该节点的值. 节点的右子树中的值要严格大于该节点的值. 左右子树也必须是二叉查找 ...

  8. 洛谷——P1223 排队接水

    P1223 排队接水 题目描述 有n个人在一个水龙头前排队接水,假如每个人接水的时间为Ti,请编程找出这n个人排队的一种顺序,使得n个人的平均等待时间最小. 输入输出格式 输入格式: 输入文件共两行, ...

  9. Sqli-labs less 7

    Less-7 本关的标题是dump into outfile,意思是本关我们利用文件导入的方式进行注入.而在background-3中我们已经学习了如何利用dump into file. 这里首先还是 ...

  10. [BZOJ5248][九省联考2018]一双木棋(连通性DP,对抗搜索)

    5248: [2018多省省队联测]一双木棋 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 43  Solved: 34[Submit][Status ...