zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    esp32(M5STACK)在线体验(Ubuntu)
    esp32(M5STACK)程序烧写(Ubuntu)
    在Ubuntu环境下搭建esp32开发环境
    markdown让文字居中和带颜色
    Doxyfile中插入图片
    System.load 与 System.loadLibrary 的使用
    常见mysql的数据迁移
    mysql中有关树的函数
    spring整合quartz实现动态定时器
    javaweb项目中发布webservices服务
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3167978.html
Copyright © 2011-2022 走看看