概述

该demo是模仿王者荣耀的实时阴影,读者可以从中理解到实时阴影的实现原理。

详细

代码下载:http://www.demodashi.com/demo/11999.html

一、准备工作

解压ShadowDemo.zip压缩包,用Unity 5.3.7f1 (64-bit)及以上版本打开项目,打开Demo场景,就可以测试了。以下为压缩包的结构:

二、实现原理

原理:可能有点复杂,为了简单些,转化为2d视角来分析。阴影的产生正如下图所示

由上图可知,阴影的a点与遮挡物的b点在光照方向的垂直面上其实映射的是同一个点d。这很容易让我们联想到MVP当中的投影变换。其实是一样的。我们将于光照方向当做照相机的视线,而与光照方向垂直的面,就是投影变换最后的盒子的正面。这意味着我们可以制作一个正交照相机,使得它与光照方向一致,再将地面模型的各个顶点投影到该照相机上,这时候照相机的纹理UV坐标范围是0~1,地面投影到了照相机,也将其坐标映射到0~1之间,由此与照相机的纹理一一对应,于是将照相机照出来的纹理叠加在地面上,就形成了阴影。

三、程序实现

using UnityEngine;
using System.Collections;public class Shadow : MonoBehaviour {public Camera m_ShadowCamera;private RenderTexture m_RT;public Material m_Mat;void Start(){//创建一个纹理,用来捕获照相机的看到的(该纹理既为我们需要的影子的源纹理)m_RT = new RenderTexture(Screen.width, Screen.height, 0, RenderTextureFormat.ARGB32);m_RT.anisoLevel = 8;m_ShadowCamera.targetTexture = m_RT;//将上面的纹理传入材质球中,用来将它处理为影子m_Mat.SetTexture("_MainTex", m_RT);}void Update(){//实时将生成影子需要的纹理的照相机的矩阵传入材质球,这两个矩阵在下面的着色器代码中使用m_Mat.SetMatrix("_WorldToCameraMatrix", m_ShadowCamera.worldToCameraMatrix);m_Mat.SetMatrix("_ProjectionMatrix", m_ShadowCamera.projectionMatrix);}
}

上面c#代码需要用的shader

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'Shader "Hidden/Shadow"
{Properties{_MainTex("Texture", 2D) = "white" {}}SubShader{Tags{"Queue" = "Transparent+100"}zwrite offPass{Blend SrcAlpha OneMinusSrcAlphaCGPROGRAM
#pragma vertex vert
#pragma fragment frag#include "UnityCG.cginc"uniform float4x4 _WorldToCameraMatrix;uniform float4x4 _ProjectionMatrix;struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};v2f vert(appdata v){v2f o;o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);//将该模型投影到影子生成的纹理的照相机的空间中,便可以将纹理一一对应上float4 worldCoord = mul(_Object2World, v.vertex);float4 cameraCoord = mul(_WorldToCameraMatrix, worldCoord);float4 projectionCoord = mul(_ProjectionMatrix, cameraCoord);o.uv = projectionCoord / projectionCoord.w;o.uv = 0.5f*o.uv + float2(0.5f, 0.5f);return o;}sampler2D _MainTex;fixed4 frag(v2f i) : SV_Target{float dis = (i.uv.x - 0.5f)*(i.uv.x - 0.5f) + (i.uv.y - 0.5f)*(i.uv.y - 0.5f);fixed4 col = tex2D(_MainTex, i.uv);if(col.r + col.g + col.b + col.a > 0){col.a = 1.0f;}col.rgb = 0;//这里将纹理沿着边缘虚幻处理col.a = (col.a - dis*4.0f)*0.3f;if (i.uv.y < 0.0f || i.uv.y > 1.0f || i.uv.x < 0.0f || i.uv.x > 1.0f){discard;}return col;}ENDCG}}
}

王者荣耀的阴影做了一个细节上的处理,所以我在这里也做了同样的处理,既阴影往边界虚化的效果。

三、运行效果

四、项目截图

代码下载:http://www.demodashi.com/demo/11999.html

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

模仿王者荣耀的实时阴影相关推荐

  1. 王者荣耀全国最低战区推荐查询,王者荣耀战区实时查询秒上省标

    修改战区注意事项 只有周一早上6点到晚上24点这段时间可以改定位的,周二到周日无法更改定位. 如果想定位自己目前在的位置,把手机定位开起来,同时游戏也要开启定位功能(能允许定位功能启用),这样进入游戏 ...

  2. Python练习--模仿王者荣耀定义两个英雄类

    需求: 英雄需要有昵称.攻击力.生命值等属性: 实例化出两个英雄对象: 英雄之间可以互殴,被殴打的一方掉血,血量小于0则判定为死亡. 实例代码如下: class Garen:camp = 'Demac ...

  3. 面向对象-王者荣耀英雄类

    模仿王者荣耀定义两个英雄类, (10分钟) 要求: 英雄需要有昵称.攻击力.生命值等属性: 实例化出两个英雄对象: 英雄之间可以互殴,被殴打的一方掉血,血量小于0则判定为死亡. class Gaven ...

  4. 王者ios系统怎么查自己在哪个服务器,安卓王者荣耀怎么查看iOS系统的 | 手游网游页游攻略大全...

    发布时间:2016-06-29 王者荣耀PVE六国远征系统玩法,冒险模式是非常有意思的玩法,需要合理搭配参战英雄和适当的策略,小编为大家带来了王者荣耀PVE六国远征详解. --知己知彼了解六国远征规则 ...

  5. 自定义控件-王者荣耀之五芒星图

    模仿王者荣耀的赛季战后数据显示:五芒星图 效果图: 头文件 #ifndef QWHPENTAGONALCHART_H #define QWHPENTAGONALCHART_H#include < ...

  6. 王者荣耀在线服务器,王者荣耀实时对战服务器Photon之PUN介绍

    PUN基础教程是基于Unity3D的教程. 它将向您展示如何开发由Photon Cloud提供支持的多人实时在线应用程序,以及如何使用Animator使用人物进行动画处理. 我们将随着许多重要的功能和 ...

  7. 王者荣耀背后的实时大数据平台用了什么黑科技?

    简介:实时方面主要是补足我们对游戏运营的体验,比如说在游戏里玩完一局或者做完一个任务后,立马就能得到相应的奖励,或者下一步的玩法指引.对用户来说,这种及时的刺激和干预,对于他们玩游戏的体验会更好.其实 ...

  8. 2020双十一实时大屏_王者荣耀2020双十一活动怎么玩 王者荣耀2020双十一活动玩法攻略...

    <王者荣耀>5V5英雄公平对战手游,腾讯最新MOBA大作!5V5.3v3.1v1,多样模式一键体验,海量英雄随心选择!10秒实时跨区匹配,与好友组队... 王者荣耀2020双十一活动怎么玩 ...

  9. 王者荣誉语音服务器,王者荣耀12.10体验服调整 游戏实时语音优化

    王者荣耀12.10体验服调整 游戏实时语音优化 (一)游戏实时语音优化 王者的实时语音一直是王者交流模块中最重要的一个模块,召唤师通过实时语音交流更好的与朋友开黑,更方便的交流战术.之前版本的实时语音 ...

最新文章

  1. java 继承 注解_在java中实现组合注解原理分析(注解继承)
  2. 核弹级漏洞!我把log4j扒给你看!
  3. 如何生成符合高斯分布的数据集
  4. net 控制台 定时_.NET Core实现基于Quart.Net的任务管理
  5. 如何构建一个拖垮整个公司的备份系统
  6. java 栈 大小_java – JVM堆栈大小规范
  7. linux的安全性能,技术|Linux 系统安全性能检查小记
  8. 案例:Oracle 11g RAC 数据库连接数过高处理办法
  9. scapy spider.start_requests
  10. 三跨考研浙江大学计算机,在职三跨浙江大学教育硕士333非全日制考研经验贴
  11. java count rows_Java统计个人编写的Java文件个数及代码行数
  12. 100行Html5+CSS3+JS代码实现元旦倒计时界面
  13. 英语单词词性顺口溜_英语单词词性顺口溜
  14. 【论文研读】-用于约束多目标优化的新型双阶段双种群进化算法补充材料
  15. mysql通用精确计算年龄方式
  16. Mac OS X 窗口操作快捷键
  17. 我的世界服务器启动txt文件,我的世界服务器开启设置全攻略 我的世界开服图文详细教程...
  18. yapi文档转换jmx脚本
  19. CST学习------网格类型及设置方法和技巧
  20. 当黑夜自此笼罩-白夜行之感想一二

热门文章

  1. 1007.422通信问题
  2. micropython教程nucleo-f767zi开发板_教你做CMSIS-DAP仿真器(基于Nucleo-F767ZI)
  3. oracle 行数大于一时,oracle – PL / SQL ORA-01422:精确的提取返回超过请求的行数
  4. 数据结构与算法分析(十)——母牛的故事
  5. ARM系统中断产生流程
  6. 6410的系统时钟设置(下)---几个常用函数的C源码
  7. spring-boot actuator(监控)配置和使用
  8. oracle命令分析3
  9. kafka tool报错:Error fetching datea.Offset out of range
  10. java 连接mongodb