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. [RxJS] Combining Streams with CombineLatest

    Two streams often need to work together to produce the values you’ll need. This lesson shows how to ...

  2. [Javascript] Task queue & Event loop.

    Javascript with Chorme v8 engine works like this : For Chorme engine, v8, it has call stack. And all ...

  3. java实验7-多线程编程

    1 利用Thread和Runnable创建线程 [实验目的] (1)理解用实现Runnable接口的方法实现多线程. (2)掌握线程优先级的设置. (3)加深对线程状态转换的理解. [实验要求] 要求 ...

  4. Javascript进阶篇——(DOM—getAttribute()、setAttribute()方法)—笔记整理

    getAttribute()方法通过元素节点的属性名称获取属性的值.语法: elementNode.getAttribute(name) 1. elementNode:使用getElementById ...

  5. .NET开发人员必须知道的八个网站

    对于不熟悉.NET技术的朋友,需要说明一下,.NET提供了一个平台和一些相应的工具,.NET开发人员可以使用它们来在开发Windows桌面,互联网,甚至是手持移动设备上构建极富交互性的应用.很有可能你 ...

  6. js改变div宽度

    document.getElementById('Content_Right_id').style.width = document.documentElement.clientWidth - 250 ...

  7. Proguard 保留native methods的问题

    发现一个奇怪的问题,如果使用下面的配置来keep的话,native的方法还是被删掉了,百思不得其解. -keepclasseswithmembers class * {     native *; } ...

  8. C#界面设计疑问2:panel摆放问题

    1.问题1是这样的,网友意思让使用一个按键对应显示一个panel 即,http://zhidao.baidu.com/question/1924974374730559427.html 2.那么我在设 ...

  9. shell中的if语句

    语法格式 if command;then commands fi 其中的command包含如下: shell command 任何shell命令,如果shell命令返回0,代表true,否则,代表fa ...

  10. android之保存偏好设置信息到shareSharedPreferences,轻量级的保存数据的方法

    android之保存偏好设置信息到shareSharedPreferences,轻量级的保存数据的方法   SharedPreferences保存数据到xml文件 有时候要保存activity的某些状 ...