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. 输出log到指定文件

    0:pom.xml中添加依赖 <!--log4j--> <!--有错误时,可能版本不对,或者依赖没有加全 'org.apache.logging.log4j:log4j-core:2 ...

  2. [py]列表生成式-支持条件,多值的拼接

    列表生成式 代码简洁一些 支持多条件, 过滤,或拼接某些值 支持返回多值 是一种生成式 # 生成一个列表 print(list(range(1, 11))) # 生成一个列表x^2 ## 方法1: 返 ...

  3. Dokcerfile部署webpy,安装imagehash库并运行py脚本获取图片dhash值

    Dockerfile FROM lmurawsk/python2.7 RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple image ...

  4. HDU1712:ACboy needs your help(分组背包模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=1712 Problem Description ACboy has N courses this term, an ...

  5. C#可扩展数组转变为String[]数组

    简单备忘: 由于需要将数据最终以逗号隔开来拼接,因而写了下面的处理方法. public void GetJoinString() { ArrayList arr = new ArrayList(); ...

  6. html10

    1.动画fadeIn() - 淡入fadeOut() - 淡出 -通过改变透明度(opacity隐藏之后依旧占着位置)实现节点的显示和隐藏show() - 显示hide() - 隐藏 -同时改变节点的 ...

  7. JS参差不齐的数组

    <html><head> <title>参差不齐的数组</title> <meta charset="utf-8"> & ...

  8. 027-chown命令

    (1)只有文件主和超级用户才可以便用该命令.

  9. CFA

    拜耳色彩滤波阵列(Bayer Color Filter Array, CFA)是非常有名的彩色图片的数字采集格式.由1/2的G,1/4得R,1/4的B组成. 当Image Sensor向外逐行输出数据 ...

  10. SQL语句常见优化方法

    Sql优化方法 先进行选择运算(where limit)再进行连接运算 where子句中应把过滤性最强的条件放在最前面 where子句中字段的顺序应和组合索引中字段顺序一致 使用索引 使用覆盖索引来避 ...