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的更多相关文章

  1. Android定位&地图&导航——自定义公交路线代码

    一.问题描述 基于百度地图实现检索指定城市指定公交的交通路线图,效果如图所示 二.通用组件Application类,主要创建并初始化BMapManager public class App exten ...

  2. Unity日常记录 - QualitySettings 性能设置

    unity打包时,可通过QualitySettings优化图像性能,这是最常设置也是最明显的图像性能体现 设置图形质量的水平,一般来说,质量是以牺牲性能为代价的,所以最好不要追求移动设备或旧硬件的最高 ...

  3. Android教程:在百度地图上画出轨迹

    [日期:2013-04-14] 来源:Linux社区  作者:crazyxin1988 [字体:大 中 小]     接着上面的项目<Android访问webservice.客户端登录注册> ...

  4. Unity3D中的Quality

    Quality Level:质量等级,默认为打包最低的那个等级 Name:质量级别的名称 Pixel Light Count:像素灯数量(前向渲染使用的像素灯的最大数量) Texture Qualit ...

  5. 关于Unity中的光照(三)

    法线贴图 次时代游戏用的比较多 1:法线贴图是凹凸贴图技术上 的一种应用,有时也称为Dot3(仿立体)凹凸纹理贴图;2: 法线贴图是不增加多边形的情况下,增强模型的细节;3: 法线贴图是高精度模型导出 ...

  6. unity灯光烘焙设置详解

    游戏场景中灯光照明的构成 现实生活中的光线是有反射.折射.衍射等特性的.对这些基本特性的模拟一直以来都是计算机图形图像学的重要研究方向. 在CG中,默认的照明方式都是不考虑这些光线特性的,因此出来的效 ...

  7. unity 质量设置 Quality Settings

    Unity allows you to set the level of graphical quality it will attempt to render. Generally speaking ...

  8. android 百度地图开发实例(转载)

    因为在我的寝室google基站定位返回的数据总是为空,所以换成百度地图,发现百度地图开发起来非常方便,提供了许多有用的工具,地图的加载速度也比google地图快许多. 为了加强记忆,写一点androi ...

  9. 初探UE4中的Profiling【转】

    http://blog.ch-wind.com/ue4-profiling-preview/ Profililng是成品制作过程中非常重要的一个步骤,通过Profiling才能提高运行效率使得作品达到 ...

随机推荐

  1. Android Studio编译好的apk放在哪里?

    Eclipse中编译好的apk文件时在bin文件中面的,可是在Android Studio有一个比較大的修改了,编译好的apk在android studio里面是直接看不到了,并且apk文件所在文件夹 ...

  2. WHY IE AGAIN? - string.charAt(x) or string[x]?

    近期今天在写一个"删除字符串中反复字符串"的函数,代码例如以下: 开门见山,重点 string.charAt(index) 取代 string[index] function re ...

  3. PCM文件格式简单介绍

    PCM文件格式简单介绍 PCM文件:模拟音频信号经模数转换(A/D变换)直接形成的二进制序列,该文件没有附加的文件头和文件结束标志.Windows的Convert工具能够把PCM音频格式的文件转换成M ...

  4. Oracle用户解锁的三种办法及默认的用户与密码

    ORA-28000: the account is locked-的解决办法 2009-11-11 18:51 ORA-28000: the account is locked 第1步:使用PL/SQ ...

  5. C#基础:集合

        C#中的数组实现为 System.Array 类的实例,它们只是集合类(Collection Classes)中的一种类型.集合类一般用于处理对象列表,其功能比简单数组要多,功能大多是通过实现 ...

  6. 《第一行代码》学习笔记11-活动Activity(9)

    1.android:theme,是用于给当前活动指定主题的,Android系统内置很多主题可以选择,@android:style/Theme.Dialog则是 让DialogActivity使用对话框 ...

  7. Java中关于OOM的场景及解决方法

    原文地址:http://developer.51cto.com/art/201112/305696.htm 1.OOM for Heap=>例如:java.lang.OutOfMemoryErr ...

  8. 如何修改UIButton按下后默认的蓝色效果

    其实有两个简单方法:1.修改xib属性检查器Highlight Tint的值: 2.通过代码修改:btn.tintColor=[UIColor grayColor];或者[btn setTintCol ...

  9. [OC笔记] static 关键字

    在变量声明前加上static关键字,可以使局部变量保留多次方法调用所得到的值.当多个方法对一个静态变量进行操作时,多个方法共享同一个静态变量的值.

  10. C#之获取本地IP地址

    最近协助一个项目解决了一个获取IP地址的问题,手机客户端与WebService进行通讯,然后WebService通过TCP通讯把指令传递到另一台PC机上.在测试的过程中,总是会出现WebService ...