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. swift 模式

    原文:http://www.cocoachina.com/newbie/basic/2014/0612/8800.html 模式(pattern)代表了单个值或者复合值的结构.比如,元组(1, 2)的 ...

  2. 实战ffs函数

    这个函数是返回整形的最低位1的位置 自己写是这个样子的: /* Find the first bit set in I. */ int lx_ffs(int i) { int index = 0, r ...

  3. 深入浅出理解iOS经常使用的正則表達式—基础篇[Foundation]

    參考资料:cocoachina的zys475481075的文章 几个单词 Regular ['regjʊlə]adj. 定期的:有规律的 Expression[ɪk'spreʃ(ə)n; ek-] n ...

  4. Play Framework Web开发教程(33): 结构化页面-组合使用模板

    和你编写代码相似,你编写的页面也能够由多个小的片段组合而成,这些小的片段本身也能够由更小的片段构成.这些小片段一般是能够在其他页面反复使用的:有些部分能够用在全部页面,而有些部分是某些页面特定的.本篇 ...

  5. LoadRunner测试下载功能点脚本(方法二)

    在上一篇<LoadRunner下载功能点脚本(方法一)>中,实现的脚本仅是录制下载功能点的脚本,现在性能需求的场景更改如下: 性能需求:对系统某页面中,点击下载并将下载文件保存到本地电脑的 ...

  6. C#控制台吹泡泡算法

    代码如下: static void Main(string[] args) { Bubbling(100, 100, "O", 1000); Console.ReadLine(); ...

  7. vsim仿真VHDL输出fsdb格式文件

    vsim(modelsim)仿真VHDL输出fsdb格式文件 1.Dump准备 (1) 将下列设置放到顶层testbench tb.vhd文件中[注意放置的位置:关系如图] library novas ...

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

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

  9. ORACLE触发器的管理与实际应用【weber出品】

    一.INSTEAD OF触发器 对于简单的视图可以执行INSERT,UPDATE和DELETE操作,但是对于复杂视图,不允许直接执行INSERT,UPDATE,DELETE操作,当视图出现以下任何一种 ...

  10. 11 java 反射机制

    Java反射机制的适用场景及其利与弊: http://blog.csdn.net/zolalad/article/details/29370565 http://my.oschina.net/u/10 ...