Unity制作护盾——2、力场冲击波护盾

Unity制作力场护盾

大家好,我是阿赵。
  继续做护盾,这一期做一个力场冲击波护盾。

一、效果展示

在这里插入图片描述

  主要的效果并不是这个球,而是护盾在被攻击的时候,会出现一个扩散的冲击波。比如上图在右边出现了冲击波
在这里插入图片描述

如果在左边被攻击,冲击波会出现在左边,并且慢慢扩散,渐隐消失。

二、原理

在这里插入图片描述
在这里插入图片描述

  把用于装饰的球体去掉之后,实际上我们要做的事情其实很简单,就是要计算一个沿着球体的环形范围显示。

1、准备工作

这里我们需要几个东西
1.一个球形模型
在这里插入图片描述

  用于获取碰撞点,还有显示冲击波
2.碰撞点的坐标
  比如我们用鼠标点击来模拟攻击护盾,那么从屏幕的鼠标位置发射射线碰撞到上面的球体,得到一个球体上的坐标,用于计算扩散的中心点
3.扩散范围的大小
  在每次点击护盾获取到碰撞点之后,这个值应该是动态改变的,从小到大,用于控制扩散的幅度
4.一张渐变图
在这里插入图片描述

  这张渐变图其实就是上面看到的环形效果所采样的贴图了。

2、计算过程

接下来看看是怎样计算的
1.计算碰撞点的坐标和球体的顶点坐标的距离distance
2.距离distance减去一个size,得到一个扩散范围range
3.扩散范围除以一个扩散值diffuse,用于扩散范围的拉伸
4.上面得到的值,作为UV坐标的u坐标,然后v坐标是0.5。其实v坐标是0-1随便一个值都可以,因为  我们的渐变图只有x轴有变化。用这个uv值去采样渐变图,就能得到一个沿着球体的环形贴图效果
在这里插入图片描述
在这里插入图片描述

  通过控制size的大小,就能让这个 环形从小到大的变化。
  如果觉得这个环太整齐了,可以在第2步计算范围之后,再减去一个噪声图采样,这样,环形的边缘就会出现不规则的变化
在这里插入图片描述

  看着好像很复杂的效果,其实做起来是很简单的。接下来写一个很简单的C#脚本,获取碰撞点,把坐标传入到材质球里面,然后在C#写一个size从小到大变化的控制,让环形从小到大的扩散,最后消失就可以了。

3、特别说明

1.多个冲击波

  上面这样做之后,我们每次就只能点击出一个冲击波,如果点击第二个的时候,第一个会消失。为了可以多个冲击波同时存在,可以通过C#端的SetVectorArray方法和SetFloatArray方法使用数组去传冲击波中心点和扩散的size,然后在shader里面用循环的方式计算多个中心点和扩散size,得到多个冲击波同时出现的效果

2.三平面采样

  然后还有一个需要说明的是,如果我们单纯的用UV坐标去采样噪声图,在球形的UV接缝位置,会出现断裂的情况。所以我这里使用了一个三平面采样的技术

inline float4 TriplanarSampling44(sampler2D topTexMap, float3 worldPos, float3 worldNormal, float falloff, float2 tiling, float3 normalScale, float3 index)
{
	float3 projNormal = (pow(abs(worldNormal), falloff));
	projNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;
	float3 nsign = sign(worldNormal);
	half4 xNorm; half4 yNorm; half4 zNorm;
	xNorm = tex2D(topTexMap, tiling * worldPos.zy * float2(nsign.x, 1.0));
	yNorm = tex2D(topTexMap, tiling * worldPos.xz * float2(nsign.y, 1.0));
	zNorm = tex2D(topTexMap, tiling * worldPos.xy * float2(-nsign.z, 1.0));
	return xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;
}

使用起来也很简单
直接使用UV坐标采样,一般是这样写:

float2 noiseUV = i.uv*_noiseTex_ST.xy + _noiseTex_ST.zw;
float4 noiseCol = tex2D(_noiseTex, noiseUV);

现在改成

float4 noiseCol = TriplanarSampling44(_noiseTex, i.vertex_world, i.normal_world, 1.0, _noiseTilling, 1, 0);

3.装饰球体的制作

在这里插入图片描述

  最后,那个用于装饰用的球,其实Shader代码更简单,就是一个菲涅尔边缘光,加上一个Flow流动效果,用一张噪声图做流动而已。Flow的源码在上一篇闪电护盾给过了,所以这里就不给了,各位有兴趣可以自己试试。

三、代码

  c#代码就不给了,实在太简单,就是一个射线拾取碰撞点的代码。
  给一下Shader的源码吧:

Shader "azhao/ShockWave"
{
    Properties
    {
		_diffuse("kuosan",float) = 0
		_noiseTex("noiseTex",2D) = "black"{}
		_gradient("gradientTex",2D) = "black"{}
		_baseColor("baseColor",Color) = (1,1,1,1)
		_noisePow("noisePow",float) = 1
		_addSize("addSize",float) = 0
		_divSize("divSize",float) = 1
		_noiseTilling("noiseTilling",Vector) = (1,1,1,1)
		_hitSpeed("hitSpeed",float) = 10

    }
    SubShader
    {
        Tags { "Queue"="Transparent" }
        LOD 100

        Pass
        {
			Blend SrcAlpha OneMinusSrcAlpha
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
  

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
				float3 normal:NORMAL;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
				float4 vertex_world:TEXCOORD1;
				float3 normal_world:TEXCOORD2;
            };

			float3 _hitCenter[10];
			float _hitSize[10];
			float _diffuse;
			sampler2D _noiseTex;
			float4 _noiseTex_ST;
			sampler2D _gradient;
			float4 _baseColor;
			float _noisePow;
			float _addSize;
			float _divSize;
			float2 _noiseTilling;
			float _hitSpeed;

			inline float4 TriplanarSampling44(sampler2D topTexMap, float3 worldPos, float3 worldNormal, float falloff, float2 tiling, float3 normalScale, float3 index)
			{
				float3 projNormal = (pow(abs(worldNormal), falloff));
				projNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;
				float3 nsign = sign(worldNormal);
				half4 xNorm; half4 yNorm; half4 zNorm;
				xNorm = tex2D(topTexMap, tiling * worldPos.zy * float2(nsign.x, 1.0));
				yNorm = tex2D(topTexMap, tiling * worldPos.xz * float2(nsign.y, 1.0));
				zNorm = tex2D(topTexMap, tiling * worldPos.xy * float2(-nsign.z, 1.0));
				return xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;
			}
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = v.uv;
				o.vertex_world = mul(v.vertex, unity_ObjectToWorld);
				o.normal_world = mul(unity_WorldToObject, v.normal);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
				float alpha = 0;
				for (int j = 0;j < 10;j++)
				{
					float dis = distance(_hitCenter[j], i.vertex_world);
					float hitMaskVal = (1 - (dis - _addSize)) / (max(_divSize, 0.001f));

					float hitSizeVal = (dis - (_hitSize[j] * _hitSpeed)) / _diffuse;

					//float2 noiseUV = i.uv*_noiseTex_ST.xy + _noiseTex_ST.zw;
					//float4 noiseCol = tex2D(_noiseTex, noiseUV);
					float4 noiseCol = TriplanarSampling44(_noiseTex, i.vertex_world, i.normal_world, 1.0, _noiseTilling, 1, 0);
					float noisePowerVal = pow(noiseCol.r, _noisePow);

					float hitRange = clamp(hitSizeVal - noisePowerVal, 0, 1);

					float2 jianbianUV = float2(hitRange, 0);
					float4 jianbianCol = tex2D(_gradient, jianbianUV);

					alpha = alpha + clamp(hitMaskVal* jianbianCol.r, 0, 1);
				}
				alpha *= _baseColor.a;

                return float4(_baseColor.rgb, alpha);
            }
            ENDCG
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/66490.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java——基础语法(二)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

Pytorch深度学习-----现有网络模型的使用及修改(VGG16模型)

系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用&#xff08;ToTensor&#xff0c;Normalize&#xff0c;Resize &#xff0c;Co…

Spring(13) IOC的工作流程

目录 一、定义二、Bean的声明方式三、IOC的工作流程 一、定义 IOC&#xff1a;全称是 Inversion Of Control&#xff0c;也就是控制反转&#xff0c;它的核心思想是把对象的管理权限交给容器。应用程序如果需要使用某个对象的实例&#xff0c;那么直接从 IOC 容器里面去获取就…

【自动化测试框架】关于unitttest你需要知道的事

一、UnitTest单元测试框架提供了那些功能 1.提供用例组织和执行 如何定义一条“测试用例”? 如何灵活地控制这些“测试用例”的执行? 2.提供丰定的断言方法 当测试用例的执行结果与预期结果不一致时&#xff0c;判定测试用例失败。在自动化测试中&#xff0c;通过“断言”…

PPT分割图片

想把一个图片拆分成很多部分改怎么做呢? 如下图所示: 图片填充法 第一步, 画一些线条, 与图片对齐: 第二步, 全选所有线条, 组合 第三步, 填充图片. 先复制图片&#xff0c;然后选中组合后的形状&#xff0c;设置形状格式&#xff0c;填充选择为图片或纹理填充&#xff0…

详细介绍渗透测试与漏洞扫描

一、概念 渗透测试&#xff1a; 渗透测试并没有一个标准的定义&#xff0c;国外一些安全组织达成共识的通用说法&#xff1b;通过模拟恶意黑客的攻击方法&#xff0c;来评估计算机网络系统安全的一种评估方法。这个过程包括对系统的任何弱点、技术缺陷或漏洞的主动的主动分析…

Web安全——Burp Suite基础上

Burp Suite基础 一、Burp Suite安装和环境配置如何命令行启动Burp Suite 二、Burp Suite代理和浏览器设置FireFox设置 三、如何使用Burp Suite代理1、Burp Proxy基本使用2、数据拦截与控制3、可选项配置Options客户端请求消息拦截服务器端返回消息拦截服务器返回消息修改正则表…

2023.8.7论文阅读

文章目录 CMUNeXt: An Efficient Medical Image Segmentation Network based on Large Kernel and Skip Fusion摘要本文方法实验结果 Boundary Difference Over Union Loss For Medical Image Segmentation&#xff08;损失函数&#xff09;摘要本文方法实验结果 CMUNeXt: An E…

QColorDialog

QColorDialog 颜色类 QColor颜色对话框API简单的使用 QColorDialog类是QDialog的子类, 通过这个类我们可以得到一个选择颜色的对话框窗口 颜色类 QColor 关于颜色的属性信息, 在QT框架中被封装到了一个叫QColor的类中。 各种颜色都是基于红, 绿, 蓝这三种颜色调配而成的, 并…

6. CSS(三)

目录 一、盒子模型 &#xff08;一&#xff09;网页布局的本质 &#xff08;二&#xff09;盒子模型组成 &#xff08;三&#xff09;边框&#xff08;border&#xff09; &#xff08;四&#xff09;表格的细线边框 &#xff08;五&#xff09;内边距&#xff08;padding…

RISC-V走向开放服务器规范

原文&#xff1a;RISC-V Moving Toward Open Server Specification 作者&#xff1a;Agam Shah 转载自&#xff1a;https://www.hpcwire.com/2023/07/24/risc-v-moving-toward-open-server-specification/ 中文翻译&#xff1a; 2023年7月24日 RISC-V International目前正…

适配器模式(C++)

定义 将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 应用场景 在软件系统中&#xff0c;由于应用环境的变化&#xff0c;常常需要将“一些现存的对象 ”放在新的环境中应用&#xff0c;但是新环境要求…

源码分析——ConcurrentHashMap源码+底层数据结构分析

文章目录 1. ConcurrentHashMap 1.71. 存储结构2. 初始化3. put4. 扩容 rehash5. get 2. ConcurrentHashMap 1.81. 存储结构2. 初始化 initTable3. put4. get 3. 总结 1. ConcurrentHashMap 1.7 1. 存储结构 Java 7 中 ConcurrentHashMap 的存储结构如上图&#xff0c;Concurr…

构建IT项目价值管理体系︱陆金所控股有限公司项目管理专家朱磊

陆金所控股有限公司项目管理专家朱磊先生受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;陆控-构建IT项目价值管理体系。大会将于8月12-13日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&#xff1a; IT资源有限&#xff0c;…

(八)穿越多媒体奇境:探索Streamlit的图像、音频与视频魔法

文章目录 1 前言2 st.image&#xff1a;嵌入图像内容2.1 图像展示与描述2.2 调整图像尺寸2.3 使用本地文件或URL 3 st.audio&#xff1a;嵌入音频内容3.1 播放音频文件3.2 生成音频数据播放 4 st.video&#xff1a;嵌入视频内容4.1 播放视频文件4.2 嵌入在线视频 5 结语&#x…

二、MySql库的操作

文章目录 一、库的操作&#xff08;一&#xff09;创建数据库&#xff08;二&#xff09;创建数据库案例&#xff08;三&#xff09;字符集和校验规则1、 查看系统默认字符集以及校验规则2、查看数据库支持的字符集3、查看数据库支持的字符集校验规则4、校验规则对数据库的影响…

20230809在WIN10下使用python3批量将TXT文件转换为SRT文件

20230809在WIN10下使用python3批量将TXT文件转换为SRT文件 2023/8/9 17:30 由于喜欢看纪录片等外文视频&#xff0c;通过剪映/PR2023/AUTOSUB识别字幕之后&#xff0c;可以通过google翻译识别为简体中文的DOCX文档。 DOCX文档转换为TXT文档之后&#xff0c;还需要转换为SRT文档…

12v转5v降压模块

问&#xff1a;什么是12V转5V降压模块&#xff1f;它的功能是什么&#xff1f; 答&#xff1a;12V转5V降压模块是一种电子设备&#xff0c;用于将输入电压为12V的直流电转换为输出电压为5V的直流电。它的主要功能是为电子设备提供所需的适当电压&#xff0c;以便它们能够正常运…

PCB制造中铜厚度的重要性

电子产品中的PCB是现代电子设备中不可或缺的一部分。在PCB制造过程中&#xff0c;铜厚度是一个非常重要的因素。正确的铜厚度可以保证电路板的质量和性能&#xff0c;同时也影响着电子产品的可靠性和稳定性。 一般我们常见的铜厚有17.5um&#xff08;0.5oz&#xff09;&#x…

最大子数组和【力扣53】

一、解题思路 Max[i]表示&#xff1a;以nums[i]为开头的所有连续子数组和的最大值。 由此可以推出Max[i-1]和Max[i]的关系&#xff1a; 若Max[i]>0&#xff1a;Max[i-1]nums[i-1]Max[i]&#xff1b; 否则&#xff1a;Max[i-1]nums[i-1]&#xff1b; 则ansMAX&#xff0…
最新文章