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. mysql-表完整性约束

    阅读目录 一 介绍 二 not null与default 三 unique 四 primary key 五 auto_increment 六 foreign key 七 总结     一 介绍 回到顶 ...

  2. DuplicateHandle

    功能:将一个进程内的伪句柄,转化为可以用来进程间通信的实句柄 BOOL DuplicateHandle(  HANDLE hSourceProcessHandle,  HANDLE hSourceHa ...

  3. 兼容python3的SSDB客户端

    SSDB.py import socket class SSDB_Response(object): def __init__(self, code='', data_or_message=None) ...

  4. centos7.5安装seafile

    1.配置yum源 [root@localhost yum.repos.d]# uname -r3.10.0-693.el7.x86_64 [root@localhost yum.repos.d]# c ...

  5. lr手工添加关联函数的步骤:

    点击“确定”后: 如何修改已经创建好的关联规则:

  6. HDMI 电视 点对点 桌面超出屏幕

    一直在用电视作显示器,但是没有注意点对点到问题,只是感觉字体发虚.直到今天装win10,桌面会超出屏幕,使用intel控制面板调整分辨率后正常,但是注销或重启会再次回复.百度无果,自己摸索,不仅解决了 ...

  7. ngx_lua_waf完整安装说明

    测试环境:centos5.6 x32,nginx1.4.4,LuaJIT-2.0.3,ngx_devel_kit-0.2.19.lua-nginx-module-0.9.11,ngx_lua_waf ...

  8. JqGrid的学习

    http://blog.csdn.net/yangbobo1992/article/category/1227409

  9. 转:windbg常用命令

  10. oracle中 char,varchar,varchar2的区别

    区别:      1. CHAR的长度是固定的,而VARCHAR2的长度是可以变化的, 比如,存储字符串“abc",对于CHAR (20),表示你存储的字符将占20个字节(包括17个空字符) ...