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. [LeetCode] 529. Minesweeper_ Medium_ tag: BFS

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

  2. numpy.random.rand()/randn()/randint()/normal()/choice()/RandomState()

    这玩意用了很多次,但每次用还是容易混淆,今天来总结mark一下~~~ 1. numpy.random.rand(d0,d1,...,dn) 生成一个[0,1)之间的随机数或N维数组 np.random ...

  3. 浅谈Android View事件分发机制

    引言 前面的文章介绍了View的基础知识和View的滑动,今天我们来介绍View的另一个核心知识,View的事件分发机制. 点击事件的传递规则 所谓的点击事件的分发机制,其实就是对MotionEven ...

  4. Leetcode: Pow(x, n) and Summary: 负数补码总结

    Implement pow(x, n). Analysis:  Time Complexity: O(LogN) Iterative code: refer to https://discuss.le ...

  5. javascript函数定义以及常见用法

                  我们知道,js函数有多种写法,函数声明 ,函数表达式,Function式构造函数,自执行函数,包括Es6的箭头函数,Class类写法,高阶函数,函数节流/函数防抖,下面我就 ...

  6. Object-C-NSString

    NSString *info=@"Hello world"; NSString *info=[[NSString alloc]initWithFormat:@"my na ...

  7. Codeforces Round #247 (Div. 2) C D

    这题是一个背包问题 这样的 在一个k子树上 每个节点都有自己的k个孩子 然后 从原点走 走到 某个点的 和为 N 且每条的 长度不小于D 就暂停问这样的 路有多少条,  呵呵 想到了 这样做没有把他敲 ...

  8. 2016-2017-2 20155309南皓芯java第五周学习总结

    教材内容总结 这一周学习的进度和前几周比较的话是差不多的,都是学习两章. 异常处理 1.理解异常架构 2.牚握try...catch...finally处理异常的方法 3.会用throw,throws ...

  9. Python: re.compile()

    compile(pattern,flags=0) 1.编译一个正则表达式模式,返回一个模式对象 2.第二个参数flags是匹配模式,可以使用按位或‘|'表示同时生效,也可以在正则表达式字符串中指定 P ...

  10. EXKMP

    (我和lesphere,reverse研究了这个东西一上午)QAQ kmp是求字符串S的任意前缀与字符串T的最长的相同的前缀和后缀 exkmp第求字符串S的任意后缀与字符串T的最长公共前缀 与kmp相 ...