Unity上平面阴影的计算与实现

 //如何求顶点投影到平面上的点(阴影点)
//当平面上取不相等的任意两个点组成一个向量,与平面的法线总是垂直的,向量垂直点乘为0,因此可以通过一个点和一个法线来定义,
//plane方程如下:(P - P0)·N = 0 N=normal,P0表示平面上的一个点,P表示平面上的任意点,当P = P0时 0·N = 0
//射线方程 P = o + t * D,(o为射线起点,t为标量,表示射线原点到和平面交点的距离)联立两个方程式可求交点。方程如下: // ( O + D·t - P0 )·N = 0
// => ( O - P0 )·N + D·N·t = 0
// => t = ( P0 - O)·N / D·N ( 其中D·N ≠0 ,向量点积满足分配律)
// p0表示平面上一点中心点(0,0,0) o:顶点世界坐标 N:平面的法向量(0,1,0)D:直射光方向
//注意两点:
//当 D·N = 0 时,表示射线与平面垂直,则射线与平面平行。
//解出 t < 0 时,表示 射线沿着平面相反的半平面发射,也是不相交的(当然如果是直线就没关系啦) Shader "Pluto/PlanarShadow"
{
Properties
{
_ShadowColor ("Shadow Color",Color) = (0.25,0.25,0.25,0.25)
_Center("Center", Vector) = (,0.001,,)
_Normal("Normal", Vector) = (,,,)
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" "LightMode"="ForwardBase" }
LOD //渲染模型
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag #include "UnityCG.cginc" struct appdata
{
float4 vertex : POSITION; //模型空间中的顶点坐标
float2 uv : TEXCOORD0;
}; struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION; //裁剪空间中的顶点坐标
}; sampler2D _MainTex;
float4 _MainTex_ST; v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex); //将顶点从模型空间转换到裁剪空间中,更高效
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
} fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
ENDCG
} //渲染平面阴影Pass
Pass
{
ZWrite On
ZTest LEqual
Blend SrcAlpha OneMinusSrcAlpha // 模板测试的判断依据
// if((referenceValue & readMask) ComparisonFunction (stencilBufferValue & readMask))
// 通过像素
// else
// 抛弃像素 // 在这个公式中,主要分ComparisonFunction的左边部分和右边部分
// referenceValue是有Ref来定义的,这个是由程序员来定义的,readMask是模板值读取掩码,它和referenceValue进行按位与(&)操作作为公式左边的结果,默认值为255,即按位与(&)的结果就是referenceValue本身。
// stencilBufferValue是对应位置当前模板缓冲区的值,同样与readMask做按位掩码与操作,结果做为右边的部分。 //解决double blending,保证一个点只被渲染一次
Stencil{
Ref //设定参考值0,stencilbuffer里面的值会跟它进行比较,stencilBuffer值默认为0
Comp Equal //比较方式为"相等"
Pass IncrWrap //当模版测试和深度测试都通过的时候,当前模板缓冲中的是值+1
ZFail Keep //当模板测试通过并且深度测试失败,保存当前模板缓存中的内容不变
} CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc" struct appdata
{
float4 vertex : POSITION;
}; struct v2f
{
float4 vertex : SV_POSITION;
}; float4 _ShadowColor; //阴影颜色
float4 _Center; //平面上一点中心点
float4 _Normal; //平面法线 v2f vert (appdata v)
{
v2f o;
float4 wPos = mul(unity_ObjectToWorld ,v.vertex); //顶点世界坐标
float4 lightDir = normalize(_WorldSpaceLightPos0); //直射光的方向
float dist = dot(_Center.xyz - wPos.xyz, _Normal.xyz) / dot(lightDir, _Normal.xyz);
wPos = wPos + lightDir * dist;
o.vertex = mul( UNITY_MATRIX_VP,wPos); //转换到裁剪空间坐标
return o;
} fixed4 frag (v2f i) : SV_Target
{
return _ShadowColor; //直接返回影子颜色
} ENDCG
}
}
}

参考:https://www.jianshu.com/p/c8438bf6af0f

   http://nanjingjiangbiao-t.iteye.com/blog/1795310

     https://blog.csdn.net/onafioo/article/details/53943264

    

----码字不易,欢迎转载,但保留版权,请于明显处标明出处:http://www.cnblogs.com/beeasy/

Planar Shadow的更多相关文章

  1. shader之旅-7-平面阴影(planar shadow)

    根据<real-time shadow>这本书第二章中的推导,实现了最简单的阴影技术. planar shadow通过一个投影矩阵将被灯光照射的物体的顶点沿着光线方向投影到接受阴影的平面. ...

  2. shadow projection

    1.概述 shadow projection,又可成为planar shadow, 这是一种非常简单的绘制阴影的方法. 主要应用的应用场景:物体在平面投射阴影. 主要思想:把阴影看作是物体在平面上的投 ...

  3. 转:体积阴影(Shadow Volumes)生成算法

    下面以最快的速度简单谈谈阴影生成技术,目前普遍采用的一般有三种:Planar Shadow.Shadow Mapping和Shadow Volume,前者类似投影,计算最简单,缺点只能绘制抛射在平面上 ...

  4. VS2012下基于Glut 矩阵变换示例程序:

    也可以使用我们自己的矩阵运算来实现OpenGL下的glTranslatef相应的旋转变换.需要注意的是OpenGL下的矩阵是列优先存储的. 示例通过矩阵运算使得圆柱或者甜圈自动绕Y轴旋转,可以单击鼠标 ...

  5. WikiBooks/Cg Programming

    https://en.wikibooks.org/wiki/Cg_Programming Basics Minimal Shader(about shaders, materials, and gam ...

  6. 【shadow dom入UI】web components思想如何应用于实际项目

    回顾 经过昨天的优化处理([前端优化之拆分CSS]前端三剑客的分分合合),我们在UI一块做了几个关键动作: ① CSS入UI ② CSS作为组件的一个节点而存在,并且会被“格式化”,即选择器带id前缀 ...

  7. 让 OpenAL 也支持 S16 Planar(辅以 FFmpeg)

    正在制作某物品,现在做到音频部分了. 原本要采用 SDL2_mixer 的,不过实验结果表明其失真非常严重,还带有大量的电噪声.不知道是不是我打开的方式不对…… 一气之下去看 OpenAL,结果吃了闭 ...

  8. iOS 2D绘图 (Quartz2D)之阴影和渐变(shadow,Gradient)

    原博地址:http://blog.csdn.net/hello_hwc/article/details/49507881 Shadow Shadow(阴影) 的目的是为了使UI更有立体感,如图 sha ...

  9. CSS3 笔记三(Shadow/Text/Web Fonts)

    CSS3 Shadow Effects text-shadow box-shadow 1> text-shadow The text-shadow property adds shadow to ...

随机推荐

  1. mysql 权限管理 revoke 回收权限 命令

    回收所有库,所有表的所有权限 revoke all on *.* from 针对mike的账号 回收 所有库,所有表的select权限 mysql> revoke select on *.* f ...

  2. react-native run-android error: unknown host service

    D:\rnworkspace\Hello>react-native run-android JS server already running.Running D:\Android\sdk/pl ...

  3. windows安装并破解navicat.

    1:下载以下两个文件. patchNavicat.exe:  https://pan.baidu.com/s/1ZtV20GUGfZHcXHRTEb5tYg navicatforMysql.exe:  ...

  4. 获取Let`s Encrypt证书的三种方式

    1,acme.sh 方式 1)获取acme脚本 curl https://get.acme.sh | sh 2)开始获取证书 acme.sh强大之处在于,可以自动配置DNS,不用去域名后台操作解析记录 ...

  5. Java-二叉树算法

    二叉树算法的排序规则: 1.选择第一个元素作为根节点 2.之后如果元素大于根节点放在右子树,如果元素小于根节点,则放在左子树 3.最后按照中序遍历的方式进行输出,则可以得到排序的结果(左->根- ...

  6. 用liferay实现的增删改查例子-book管理系统

    liferay 这个框架是一个开源的项目,大家可以修改源代码,来实现自己的需求.但是关于liferay的开发资料中文的很少关于liferay的基础知识,大家可以百度学习一下,再来看下边的例子 首先需要 ...

  7. js中数组的字符串表示

    <html> <head> <title>数组的字符串表示</title> <script type="text/javascript& ...

  8. Webform和MVC,为什么MVC更好一些?(转)

    转自http://www.admin10000.com/document/5277.html 前言 如果你看了最近微软的议程,你会发现他们现在的焦点除了MVC,还是MVC.问题在于为什么微软如此热衷于 ...

  9. shell篇(二)

    Linux的shell种类比较多,常见的有:Bourne Shell(/user/bin/sh或者/bin/sh), Bourne Again Shell(/user/bin/bash或者/bin/b ...

  10. VS2010/MFC编程入门之四十六(MFC常用类:MFC异常处理)

    上一节中鸡啄米讲了CFile文件操作类,本节主要来说说MFC异常处理. 在鸡啄米C++编程入门系列的最后一节鸡啄米:C++编程入门系列之五十(异常处理)中,鸡啄米讲了C++标准异常的处理机制,如果你还 ...