ios平台中glsl中shadow2DProjEXT函数的简单说明以及变换矩阵的小注意点

一.shadow2DProjEXT函数需要传入一张深度纹理和一个点的坐标(4维)

1.这里首先注意的是这张纹理必须使用采样器类型为sampler2DShadow才可以,直接使用sampler2D是不行的,会出错。

2.深度纹理必须设置正确的格式GL_DEPTH_COMPONENT,另外要指定相应的比较函数,可以通过glTexParameteri来设置GL_TEXTURE_COMPARE_FUNC_EXT为GL_LEQUAL,GL_TEXTURE_COMPARE_MODE_EXT为GL_COMPARE_REF_TO_TEXTURE_EXT

3.传入的坐标是4维的(x,y,z,w),shadow2DProjEXT函数内部会这样做

shadow2DProjEXT(depthTexture, shadowCoord);其实是分两步,第一步会取出真正的纹理坐标即shadowCoord.xy / shadowCoord.w并存depthTexture中对应位置取出相应的深度值,相当于执行float depth = texture2D(depthTexture,shadowCoord.xy/shadowCoord.w)。第二步则是对纹理中的深度值与坐标中的深度值进行比较纹理中的深度值就是depth,而坐标中的深度值要通过计算:float
depth1 = shadowCoord.z / shadowCoord.w,然后将depth 与depth1做比较。

4.返回值问题,此函数的返回值为0或者1,若depth < depth1 则返回0表示深度测试未通过,反之为1表示深度测试通过。

二、上面计算时有一点需要注意,就是第三步的时候,在进行纹理坐标计算和坐标中的深度值计算时要注意shadowCoord是经过转换后的坐标,这里的转换后的意思是必须将shadowCoord的x,y,z由[-1,1]转换到[0,1],所以通常在实现的时候直接在mvp矩阵的前面乘上一个偏移矩阵,

bias = 0.5, 0.0, 0.0, 0.5

0.0,0.5, 0.0,0.5

0.0, 0.0,0.5,0.5

0.0, 0.0,0.0,1.0

这样bias * (x,y,z,w),然后在除掉第四个分量之后就是(x +1)*0.5,(y+1)*0.5,(z+1)*0.5,这样就实现了转换。

但是由于opengl的矩阵是列优先的,所以我们在进行矩阵设置的时候要把矩阵进行转置才可以,

bias =

0.5, 0.0, 0.0, 0.0

0.0,0.5, 0.0,0.0

0.0, 0.0,0.5,0.0

0.5, 0.5,0.5,1.0

这样就ok了。

在通常的过程中我们唔需要考虑行列主序的问题,因为我们计算得到的矩阵(比如通过lookAt,或者glm的相关函数得到的矩阵)与shader中需要的格式是一致的,所以我们传入就可以使用,只有一种情况下我们需要考虑矩阵的列主序或者行主序关系,那就是将GLSL矩阵放入自定义的内存块是,当将矩阵传递到uniform块中式,就需要考虑这个问题,例如上面,我们自己写了一个矩阵存储在自定义的内存块中,所以我们向shader中传递的时候就要进行行列转置,这样才能正确的使用矩阵。

时间: 2024-11-09 15:26:46

ios平台中glsl中shadow2DProjEXT函数的简单说明以及变换矩阵的小注意点的相关文章

JS中回调函数的简单用法

a能拿b,b能拿到c,c能拿到d,实现a拿到d的东西. function a() { b(function (data) { console.log(data); }); } function b(cb) { c(function (data) { cb(data); }); } function c(cb) { d(function (data) { cb(data); }); } function d(cb) { setTimeout(() => { let data = "彩虹&qu

js中trim函数的简单实现

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>test</title> <script type="text/javascript"> String.prototype.trim = function() { return this.replace(/(^\s*)|(\s*

【iOS学习笔记】Objective-C中根据函数名调用函数

原文出自:http://blog.csdn.net/hopedark/article/details/7970370 Objective-C中调用函数的方法是“消息传递”,这个和普通的函数调用的区别是,你可以随时对一个对象传递任何消息,而不需要在编译的时候声明这些方法.所以Objective-C可以在runtime的时候传递消息. 主要用到:SEL和@selector,当然还有performSelector 看例子: 先是三个函数: [cpp] view plaincopy -(void)Cal

(转) unity 在移动平台中,文件操作路径详解

http://www.unitymanual.com/thread-23491-1-1.html 今天,这篇文章其实是个老生常谈的问题咯,在网上类似的文章也比比皆是,在此我只是做个详细总结方便大家能够更好.更快的掌握,当然,如有不足的地方 欢迎指正!!! 相信大家在开发过程中,难免会保存一些文件在客户端进行本地化操作.如:配置文件,状态文件,Assetbundle文件等等... 最近总有人问我:1.保存了一个xml在客户端,能读取里面的数据,可是不能修改,甚至一修改就报错...2.我在电脑上操作

unity 在移动平台中,文件操作路径详解

转载自:http://www.unitymanual.com/thread-23491-1-1.html 今天,这篇文章其实是个老生常谈的问题咯,在网上类似的文章也比比皆是,在此我只是做个详细总结方便大家能够更好.更快的掌握,当然,如有不足的地方 欢迎指正!!! 相信大家在开发过程中,难免会保存一些文件在客户端进行本地化操作.如:配置文件,状态文件,Assetbundle文件等等... 最近总有人问我:1.保存了一个xml在客户端,能读取里面的数据,可是不能修改,甚至一修改就报错...2.我在电

windows平台中让函数在main函数之前执行的方法

1.将要执行的代码写到类的构造函数中,并定义对应的全局变量2.将要执行的代码写到TLS回调函数中在c/c++中,我们都知道main函数是程序开始执行的地方,但是在进行反调试的时候,很多时候都需要调试检测函数在main函数之前执行. 1.将要执行的代码写到类的构造函数中,并定义对应的全局变量在windows平台中,执行我们手写的main函数之前,系统会执行一段CRTstartup代码,对系统的堆栈.全局变量.命令行参数.环境变量等进行初始化操作.该方法就是利用windows在执行main函数之前先

剖析云平台中的“共享型数据库”

摘要: 随着云计算的出现,出现了很多新的名词,像弹性扩容,平缓迁移,资源隔离等.目前我就“共享型数据库”做一下解释,下面就以京东云擎的云数据库为例,给大家剖析什么叫“共享性数据库”.  这个是我第一篇帖子,我首先自我介绍一下,我从事IT行业10年,在多年以前是一名架构师,现在在一家互联网企业做产品经理,下面的仅仅是因为个人与行业一些从业人员交流得到的心得以及总结,有不妥之处请见谅. “共享型数据库”是对比“独享性数据库”的一种针对用户资源所有权的数据库称谓,它是伴随着云计算出来之后的一种数据库创

Windows中openProcess函数返回ERROR_ACCESS_DENIED的解决方法

辛辛苦苦开始了创业,好不容易见到了天使投资人,如何去打动明星投资人?如何能拿到那一笔"救命"钱?看徐小平.雷军这样说. 1. 天使投资人偏爱投什么样的创业者? 雷军:你有强烈的渴望做成一件伟大的事情,并且能让投资者相信你能做得成这件事情.掏自己的钱创业是创业成功率最高的一种,因为在那一瞬间你重视了,你花的每一分钱都是自己的血汗钱和别人的血汗钱,不会轻松把别的投资人的钱打水漂. 曾李青:我们体系内投了好几家公司,发现我们投资成功的公司要么是有做大公司的成功经验,要么是名校毕业.好学校不一

iOS 通知观察者的被调函数不一定运行在主线程

Tony in iOS | 08/08/2013 iOS 通知观察者的被调函数不一定运行在主线程 今天修复Bug时候发现的一个小细节,记录下. 问题描述 事情是这样的:我在A视图(UITableView)注册了一个通知,当接收到此通知时,就重新读取数据并调用[tableView reloadData].但是视图有时刷新后的显示的内容不对,再重新切换下视图又正常了. 代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 //A视图在初始化时注册通知 - (voi