shadow projection
1、概述
shadow projection,又可成为planar shadow, 这是一种非常简单的绘制阴影的方法。
主要应用的应用场景:物体在平面投射阴影。
主要思想:把阴影看作是物体在平面上的投影(projection),然后将该projection绘制出来即可。
2、具体方法
具体实现:
给定光源的位置L,物体上的任意一点V, 平面s的法向量N. 求V在平面s上的投影点P.
由简单的几何知识可知,
光源L和顶点V之间的光线方程为:
平面s的方程为 :, 其中Q为平面上的任意一点。
由图可知,投影点P是光线与平面的交点,所以
即
易知
故
这样就得到了shadow matrix
3、代码
void shadowMatrix(GLfloat shadowMat[16], const GLfloat planeParameter[4], const GLfloat lightPos[4])
{
GLfloat dot = planeParameter[0] * lightPos[0]
+ planeParameter[1] * lightPos[1]
+ planeParameter[2] * lightPos[2]
+ planeParameter[3] * lightPos[3]; shadowMat[0] = dot - lightPos[0] * planeParameter[0];
shadowMat[4] = 0.0 - lightPos[0] * planeParameter[1];
shadowMat[8] = 0.0 - lightPos[0] * planeParameter[2];
shadowMat[12] = 0.0 - lightPos[0] * planeParameter[3]; shadowMat[1] = 0.0 - lightPos[1] * planeParameter[0];
shadowMat[5] = dot - lightPos[1] * planeParameter[1];
shadowMat[9] = 0.0 - lightPos[1] * planeParameter[2];
shadowMat[13] = 0.0 - lightPos[1] * planeParameter[3]; shadowMat[2] = 0.0 - lightPos[2] * planeParameter[0];
shadowMat[6] = 0.0 - lightPos[2] * planeParameter[1];
shadowMat[10] = dot - lightPos[2] * planeParameter[2];
shadowMat[14] = 0.0 - lightPos[2] * planeParameter[3]; shadowMat[3] = 0.0 - lightPos[3] * planeParameter[0];
shadowMat[7] = 0.0 - lightPos[3] * planeParameter[1];
shadowMat[11] = 0.0 - lightPos[3] * planeParameter[2];
shadowMat[15] = dot - lightPos[3] * planeParameter[3]; } //Ax+By+Cz+D=0, (A, B, C) is the normal vector
void calculatePlane(GLfloat planeParameter[4], const GLfloat p0[3], const GLfloat p1[3], const GLfloat p2[3])
{
GLfloat vec0[3], vec1[3]; vec0[0] = p1[0] - p0[0];
vec0[1] = p1[1] - p0[1];
vec0[2] = p1[2] - p0[2]; vec1[0] = p2[0] - p0[0];
vec1[1] = p2[1] - p0[1];
vec1[2] = p2[2] - p0[2]; //cross product
planeParameter[0] = vec0[1] * vec1[2] - vec0[2] * vec1[1];
planeParameter[1] = vec0[2] * vec1[0] - vec0[0] * vec1[2];
planeParameter[2] = vec0[0] * vec1[1] - vec0[1] * vec1[0]; //normalize
GLfloat len = sqrt(planeParameter[0] * planeParameter[0]
+ planeParameter[1] * planeParameter[1]
+ planeParameter[2] * planeParameter[2]); if (len != 0)
{
planeParameter[0] /= len;
planeParameter[1] /= len;
planeParameter[2] /= len;
}
else
{
planeParameter[0] = 1.0f;
planeParameter[1] = 0.0f;
planeParameter[2] = 0.0f;
} planeParameter[3] = -(planeParameter[0] * p0[0] + planeParameter[1] * p0[1] + planeParameter[2] * p0[2]); }
4、效果
5、优缺点
优势:易实现,跨平台
缺点:(1)投影到曲面上很难处理
(2)阴影的颜色不好控制
6、参考资料
http://excelsior.cs.ucsb.edu/courses/cs180/discussion/Shadows.pdf
http://www.cse.ohio-state.edu/~whmin/courses/cse5542-2013-spring/19-shadow.pdf
http://www.ia.hiof.no/~borres/cgraph/explain/shadow/p-shadow.html
http://math.stackexchange.com/questions/320527/projecting-a-point-on-a-plane-through-a-matrix
shadow projection的更多相关文章
- Android定位&地图&导航——自定义公交路线代码
一.问题描述 基于百度地图实现检索指定城市指定公交的交通路线图,效果如图所示 二.通用组件Application类,主要创建并初始化BMapManager public class App exten ...
- Unity日常记录 - QualitySettings 性能设置
unity打包时,可通过QualitySettings优化图像性能,这是最常设置也是最明显的图像性能体现 设置图形质量的水平,一般来说,质量是以牺牲性能为代价的,所以最好不要追求移动设备或旧硬件的最高 ...
- Android教程:在百度地图上画出轨迹
[日期:2013-04-14] 来源:Linux社区 作者:crazyxin1988 [字体:大 中 小] 接着上面的项目<Android访问webservice.客户端登录注册> ...
- Unity3D中的Quality
Quality Level:质量等级,默认为打包最低的那个等级 Name:质量级别的名称 Pixel Light Count:像素灯数量(前向渲染使用的像素灯的最大数量) Texture Qualit ...
- 关于Unity中的光照(三)
法线贴图 次时代游戏用的比较多 1:法线贴图是凹凸贴图技术上 的一种应用,有时也称为Dot3(仿立体)凹凸纹理贴图;2: 法线贴图是不增加多边形的情况下,增强模型的细节;3: 法线贴图是高精度模型导出 ...
- unity灯光烘焙设置详解
游戏场景中灯光照明的构成 现实生活中的光线是有反射.折射.衍射等特性的.对这些基本特性的模拟一直以来都是计算机图形图像学的重要研究方向. 在CG中,默认的照明方式都是不考虑这些光线特性的,因此出来的效 ...
- unity 质量设置 Quality Settings
Unity allows you to set the level of graphical quality it will attempt to render. Generally speaking ...
- android 百度地图开发实例(转载)
因为在我的寝室google基站定位返回的数据总是为空,所以换成百度地图,发现百度地图开发起来非常方便,提供了许多有用的工具,地图的加载速度也比google地图快许多. 为了加强记忆,写一点androi ...
- 初探UE4中的Profiling【转】
http://blog.ch-wind.com/ue4-profiling-preview/ Profililng是成品制作过程中非常重要的一个步骤,通过Profiling才能提高运行效率使得作品达到 ...
随机推荐
- PHP 生成.csv 文件并下载到浏览器
近期做了一个项目须要把订单的信息显示出来.而且可以把相关信息放到一个.csv 文件里,下载到浏览器.首先我要说明的是.csv 文件,PHP 有专门的函数去解析该类型的文件,相关函数大家可以去官网查看. ...
- Eclipse 将projectBuild Path中引用的jar包自己主动复制到WEB-INF下的lib目录下
在用用 Eclipse进行Java Web开发时,web应用中引用的jar须要复制到WEB-INF下的lib目录下,否则常常出现ClassNotFound异常. 通过以下方法,能够不用手动拷贝jar包 ...
- 安装MySQL和Navicat,并与MyEclipse连接
1.下载安装MySQL 1)到http://dev.mysql.com/downloads/下载MySQL社区版Server,和用于JDBC的Connector.一路默认安装就可以,须要注意的是记住M ...
- android AsyncTask 详细例子
一个典型AsyncTask的. 01 public class DialogTestActivity extends Activity { 02 private Button button1; ...
- 查看linux版本和内核信息
一.查看Linux内核版本命令(两种方法): 1.cat /proc/version [root@localhost ~]# cat /proc/versionLinux version 2.6.32 ...
- python-文件操作(1)
本文内容涉及python打开/创建文件对象,文件的读写.文件指针位置的移动.获取命令行参数. 1. open() open函数以指定模式返回一个file对象,如: file_object = open ...
- JS高级程序设计学习笔记之基本包装类型
概述 基本类型:string.boolean.number 每当读取一个基本类型的值的时候,后台就会创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据. 使用new操作符创建的 ...
- ControlStyles(枚举)
指定控件的样式和行为. 此枚举有一个 FlagsAttribute 特性,通过该特性可使其成员值按位组合.属性: ContainerControl:如果为true,则控件是类似容器的控件. UserP ...
- FineUI布局应用(二)
一.FineUI页面布局分为 1.Fit布局 <f:Panel ID="Panel1" Title="布局Fit(Layout=Fit)" runat=& ...
- OD调试6—使未注册版软件的功能得以实现
OD调试6—使未注册版软件的功能得以实现 本节使用的软件下载链接 (想动手试验的朋友可以下载来试试) 继续开始我OD调试教程的学习笔记. 本次试验对真正的程序进行逆向.(之前的都是为破解而专门设计的小 ...