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. /proc/meminfo

    /proc/meminfo  可以查看自己服务器 物理内存 注意这个文件显示的单位是kB而不是KB,1kB=1000B,但是实际上应该是KB,1KB=1024B 这个显示是不精确的,是一个已知的没有被 ...

  2. vue:Group XSwitch Actionsheet,Toast控件使用

    <template> <div> <div class="vux-demo"> <img class="logo" s ...

  3. literallycanvas的简介

    LiterallyCanvas是什么 Literally Canvas是一个可扩展的开源(BSD许可)HTML5绘图组件,可以用于网页中插入画图板,类似于windows自带的画图板.可以用可视化工具绘 ...

  4. 【剑指offer】包含min函数的栈

    一.题目: 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数. 二.思路: 无,Z(zhi)Z(zhang)式操作. 三.代码:    

  5. 让人抓狂的MySQL安装-8.0.12版本

    今天一个下午就做了一件事,把MySQL安装成功,安装的过程让人很狂躁.于是一边骂,一边查错,才把这个软件给安装成功了. 详细的安装步骤,这里就不赘述了.参见https://blog.csdn.net/ ...

  6. [LeetCode] 529. Minesweeper_ Medium_ tag: BFS

    Let's play the minesweeper game (Wikipedia, online game)! You are given a 2D char matrix representin ...

  7. jmeter处理带表单的接口请求

    如何用jmeter处理带选项的表单接口请求 下面是用到了F12 抓包的处理方法 下图是直接手动在页面上请求的结果 下面就是采用F12抓包抓到url 和FormData 分别把上面获取的url和Form ...

  8. 命名空间“Microsoft.Office.Interop”中不存在类型或命名空间名称“Excel”。是否缺少程序集引用 的另一种解决方案

    一直以来都是使用tfs进行源代码管理,系统部署也是由我本机生成后发布到服务器上,某一日,进行发布操作时,报了 [命名空间“Microsoft.Office.Interop”中不存在类型或命名空间名称“ ...

  9. Keepalived 安装

    Keepalived 安装安装环境 keepalived-1.2.18.tar.gz VM虚拟机redhat6.5-x64:192.168.1.201 Xshell4 部署方案 201部署 安装步骤  ...

  10. RHEL6.4 字符模式下安装图形界面图文教程

    本文转自:http://www.cnblogs.com/wahsonleung/p/3230325.html 第1步:当然就是启动redhat,设置映像文件. 第2步:命令行输入yum groupin ...