Unity&Shader案例篇—绘制雨滴

2023-11-11

一、前言

转载请注明出处凯尔八阿哥专栏

惯例先上效果图,本文不只是简单的绘制雨滴,同时处理了摄像机不同朝向看到的雨滴下落的方向也不一样。

、方法

1、绘制雨线:绘制雨使用的是C#脚本绘制的,脚本为:

using UnityEngine;
using System.Collections;

public class Debris : MonoBehaviour
{
	const int POINT_MAX = 4096;
	private Vector3[] vertices_;
	private int[] indices_;
	private Color[] colors_;
	private Vector2[] uvs_;
	private float range_;
	private float rangeR_;
	private float move_ = 0f;
	private Matrix4x4 prev_view_matrix_;

	void Start ()
	{
		range_ = 32f;
		rangeR_ = 1.0f/range_;
		vertices_ = new Vector3[POINT_MAX*3];
        //先制作随机的点
		for (var i = 0; i < POINT_MAX; ++i) {
			float x = Random.Range (-range_, range_);
			float y = Random.Range (-range_, range_);
			float z = Random.Range (-range_, range_);
			var point = new Vector3(x, y, z);
			vertices_ [i*3+0] = point;
			vertices_ [i*3+1] = point;
			vertices_ [i*3+2] = point;
		}
		indices_ = new int[POINT_MAX*3];
		for (var i = 0; i < POINT_MAX*3; ++i) {
			indices_ [i] = i;
		}
		colors_ = new Color[POINT_MAX*3];
        
		for (var i = 0; i < POINT_MAX; ++i) {
            //线的间隔之间有透明部分,使得看起来不是完整的连线
			colors_ [i*3+0] = new Color (1f, 1f, 1f, 0f);
			colors_ [i*3+1] = new Color (1f, 1f, 1f, 1f);
			colors_ [i*3+2] = new Color (1f, 1f, 1f, 0f);
		}
		uvs_ = new Vector2[POINT_MAX*3];
        //将随机的点进行连线
        for (var i = 0; i < POINT_MAX; ++i) {
            //使得线保持弯折
			uvs_ [i*3+0] = new Vector2 (1f, 0f);
			uvs_ [i*3+1] = new Vector2 (1f, 0f);
			uvs_ [i*3+2] = new Vector2 (0f, 1f);
		}
		Mesh mesh = new Mesh ();
		mesh.name = "debris";
		mesh.vertices = vertices_;
		mesh.colors = colors_;
		mesh.uv = uvs_;
		mesh.bounds = new Bounds(Vector3.zero, Vector3.one * 99999999);
		var mf = GetComponent<MeshFilter> ();
		mf.sharedMesh = mesh;
		mf.mesh.SetIndices (indices_, MeshTopology.Lines, 0);
		prev_view_matrix_ = Camera.main.worldToCameraMatrix;
	}
	
	// Update is called once per frame
	void Update ()
	{
		var target_position = Camera.main.transform.TransformPoint(Vector3.forward * range_);
		var matrix = prev_view_matrix_ * Camera.main.cameraToWorldMatrix; // prev-view * inverted-cur-view
		var mr = GetComponent<Renderer> ();
		const float raindrop_speed = -1f;
		mr.material.SetFloat ("_Range", range_);
		mr.material.SetFloat ("_RangeR", rangeR_);
		mr.material.SetFloat ("_MoveTotal", move_);
		mr.material.SetFloat ("_Move", raindrop_speed);
		mr.material.SetVector ("_TargetPosition", target_position);
		mr.material.SetMatrix ("_PrevInvMatrix", matrix);
		move_ += raindrop_speed;
		move_ = Mathf.Repeat(move_, range_ * 2f);
		prev_view_matrix_ = Camera.main.worldToCameraMatrix;
	}
}

在Start()方法中先绘制随机的点,然后再将点进行弯折连接,并保证连接的两条线间隔透明,如图所示


然后在Update()函数里更新着色器的渲染状态。通过计算实际雨线轨迹的着色,并始终保持雨线出现在镜头前面

2、渲染:渲染的Shader脚本为

Shader "Custom/debris" {
	SubShader {
   		Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
		ZWrite Off
		Blend SrcAlpha OneMinusSrcAlpha // alpha blending
//		Blend SrcAlpha One 				// alpha additive
		
        Pass {
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
 			#pragma target 3.0
 
 			
 			#include "UnityCG.cginc"

 			struct appdata_custom {
				float4 vertex : POSITION;
				fixed4 color : COLOR;
				float4 texcoord : TEXCOORD0;
			};

 			struct v2f
 			{
 				float4 pos:SV_POSITION;
 				fixed4 color:COLOR;
 			};
 			
 			float4x4 _PrevInvMatrix;
			float3   _TargetPosition;
			float    _Range;//雨滴的范围
			float    _RangeR;//_Range的倒数
			float    _MoveTotal;//整体雨滴的移动位移
			float    _Move;//每一帧的整体雨滴的移动位移
   
            v2f vert(appdata_custom v)
            {
				v.vertex.y += _MoveTotal;
				float3 target = _TargetPosition;
				float3 trip;
				trip = floor( ((target - v.vertex.xyz)*_RangeR + 1) * 0.5 );
				trip *= (_Range * 2);
				v.vertex.xyz += trip;

            	float4 tv0 = v.vertex * v.texcoord.x;
            	tv0 = mul (UNITY_MATRIX_MVP, tv0);
            	
				v.vertex.y -= _Move;
            	float4 tv1 = v.vertex * v.texcoord.y;
            	tv1 = mul (UNITY_MATRIX_MV, tv1);
            	tv1 = mul (_PrevInvMatrix, tv1);
            	tv1 = mul (UNITY_MATRIX_P, tv1);
            	
            	v2f o;
            	o.pos = tv0 + tv1;
            	float depth = o.pos.z * 0.02;
            	float normalized_depth = (1 - depth);
            	o.color = v.color;
            	o.color.a *= (normalized_depth);
            	return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                return i.color;
            }

            ENDCG
        }
    }
}
3、最后:创建一个新的空物体,给空物体一个MeshRender组件。最后,将上面的C#脚本和附有上面的Shader的材质球赋给这个物体。

三、还是附上工程文件吧

喜欢的童鞋可以下来自己慢慢研究,工程里有效果图中的天空盒子可以作为场景搭建的素材。百度网盘下载地址:

点击打开链接



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity&Shader案例篇—绘制雨滴 的相关文章

  • Unity用Vuforia做AR实现脱卡效果

    有时在识别目标丢失后我们仍希望虚拟物体能够出现在摄像机前 或者到一个特定的位置 我们能对其进行操作 这就是脱卡功能 自带的脱卡功能应该是ExtendedTracking 允许模型在识别图丢失的时候还存在 位置不变 在丢失的时候的位置 这样也
  • Unity—UGUI

    每日一句 读数 学习 去更远的地方 才能摆脱那些你不屑一顾的圈子 目录 InputFiled输入框 例 用户名和密码 Toggle组件 案例 冷却效果 InputFiled输入框 Text Component 输入文本组件 Text输入内容
  • unity game界面按下play会不断闪烁,按下暂停键(pause)或者中止/下一步(step),game界面的画面会接连变化

    没找到答案 改了两个下午的程序 改完还是这样 后来发现是FixedUpdate Update与OnDrawGizmos的问题 OnDrawGizmos是每帧都会绘制 用FixedUpdate理所当然就那啥了 分析的时候 就突然想到是不是这俩
  • Unity 资源加载卸载过程

    什么时候才是UnusedAssets 看一个例子 Object obj Resources Load MyPrefab GameObject instance Instantiate obj as GameObject Destroy in
  • Unity中loading页加载的实现

    首先创建一个Global cs 使用单例用于存储场景的名字 便于后续脚本的调用 此脚本不必挂载在游戏物体上 using UnityEngine using System Collections public class Global Mon
  • Unity 粒子特效、材质发光 HDR ShaderGraph图文教程[完成lit发光设置]

    效果如图 准备工作 在hdr模式下 关闭Directional Light 相机设置 移动球挂一个点光源作为子节点 设置自行调节 0 创建移动球的材质及shader shader gt 在Project Create Shader Grap
  • FBX导入Unity中模型没有材质的处理

    一 3dMax导出FBX时的注意事项 导出时 确保maps文件存在 里面放着fbx用到的image 二 在Unity中的设置 1 文件拖入Unity的Assets文件夹中 2 查看模型的材质是否存在 如下所示 材质为None 此时拖入sce
  • Unity中UI框架的使用1-添加面板、显示Loading页面

    其中BasePanel和Canvas都是挂在面板的预制物上的 1 导入我们的UI框架 本篇文章中有用的是两个UIPanelType NUIManager和NBasePanel 会放在文章最后供大家使用 2 先将我们做好的Panel设置成预制
  • unity: C#的Action Event Delegate的异同

    目录 一 Action 二 Event 三 Action和Event区别 四 Delegate 总结 Action Event Delegate的异同 前言 Action Event和Delegate都是C 语言中的重要概念 分别用于管理函
  • VLC for unity 插件如何使用

    VLC for unity 插件如何使用 先去下载一个VLC播放器 安装完成后 然后导入插件链接https download csdn net my 这个插件我的另一个上传资源里有 或者到商店去下载 这个插件链接下载完是一个txt文档 里面
  • unity 性能查看工具Profiler

    文章目录 前言 profiler工具介绍 菜单栏 帧视图 模块视图 模块详细信息 通过profiler分析优化游戏性能 最后 前言 每次进行游戏优化的时候都用这个工具查看内存泄漏啊 代码优化啊之类的东西 真的好用 但是之前也就是自己摸索一下
  • unity dots jobSystem 记录

    Looking for a way to get started writing safe multithreaded code Learn the principles behind our Job System and how it w
  • unity3d image组件不显示

    需要将UI组件放到画布下面
  • 【原神游戏开发日志1】缘起

    原神游戏开发日志1 缘起 版权声明 本文为 优梦创客 原创文章 您可以自由转载 但必须加入完整的版权声明 文章内容不得删减 修改 演绎 相关学习资源见文末 大家好 最近看到原神在TGA上频频获奖 作为一个14年经验的游戏开发行业的老兵 我就
  • 【Unity】如何让Unity程序一打开就运行命令行命令

    背景 Unity程序有时依赖于某些服务去实现一些功能 此时可能需要类似打开程序就自动运行Windows命令行命令的功能 方法 using UnityEngine using System Diagnostics using System T
  • Unity中URP下的指数雾

    文章目录 前言 一 指数雾 雾效因子 1 FOG EXP 2 FOG EXP2 二 MixFog 1 ComputeFogIntensity 雾效强度计算 2 lerp fogColor fragColor fogIntensity 雾效颜
  • U3D游戏开发中摇杆的制作(NGUI版)

    在PC端模拟摇杆 实现控制摇杆让玩家或者物体移动 以下是完整代码 using System Collections using System Collections Generic using UnityEngine public clas
  • 游戏开发创建操作之玩家信息系统的建立

    游戏一般都需要玩家信息系统 那么我们应该如何搭建玩家信息系统 接下来我将展示一种简单的方法 完整代码如下 using System Collections using System Collections Generic using Uni
  • 游戏开发常见操作梳理系列之——玩家信息的显示系统

    在游戏中 有不少游戏在左上角会出现玩家的头像和等级以及血量 这就是玩家的信息显示系统 那么这些是如何制作的呢 接下来我将讲讲代码的操作 其它操作我会在其它笔记中一一说明 敬请期待 信息的显示相当简单就是控制一些UI 然后在其它系统里面填写相
  • 游戏开发中常见系统梳理之背包系统的实现一

    游戏中几乎都存在大大小小的背包系统 接下来我将讲述背包系统具体是如何实现的 完整源码 以下是使用unity NGUI实现 使用txt配置的方法 后续更新UGUI Json实现的背包系统敬请期待 背包中的物品我们常常将其制作成预设体 通过改变

随机推荐

  • VMware如何导出和导入OVF文件

    开源虚拟化格式 OVF文件 是一种开源的文件规范 是一种开源 安全 有效 可拓展的便携式虚拟打包格式 由ovf文件 mf文件 cert文件 vmdk文件和iso文件等组成 可以用于虚拟机在不同虚拟化平台上的迁移 本文介绍VMware如何导出
  • Windows10访问共享总是提示输入网络凭证不正确

    场景 安装了windows10系统后 访问共享时总是提示输入网络凭证 输入什么都提示不正确 被访问机也是windows 10 操作系统 使用windows7不需要输入密码就可以访问 即使在被访问机上增加新的用户或者用guest账号去登录也会
  • GB9706.1-2007名词解释:电压

    电压 1 高电压 任何超过 1000V 交流或 1500V 直流或 1500V 峰值的电压 2 网电源电压 多相供电网中两相线之间的电压 或单相供电网中相线与中性线之间的电压 3 安全特低电压 在用安全特低电压变压器或等效隔离程度的装置与供
  • typora

    关于typora的一篇博客 https blog csdn net mingzhuo 126 article details 79941450
  • faceswap使用记录

    1 没有显示 fs cache文件夹 当时我是使用云gpu来运行文件代码的 里面提示我安装两个配置文件放置到 fs cache文件夹 但是当前文件夹里面并没有显示 fa cache文件夹 虽然不知道是什么原因 但这个文件夹其实是存在的 你下
  • java读取文件的方法是_java读取文件的方法有几种

    java读取文件的方法有几种 发布时间 2020 06 26 14 56 33 来源 亿速云 阅读 104 作者 Leah 这篇文章将为大家详细讲解有关java读取文件的方法 文章内容质量较高 因此小编分享给大家做个参考 希望大家阅读完这篇
  • 【python】Counter 函数的用法

    https docs python org 3 6 library collections html collections Counter 原文链接 https blog csdn net u010339879 article detai
  • 使用CocosBuilder2.1结合cocos2d-x2.0.3创建动画场景

    原文地址 http article ityran com archives 2140 本为由泰然教程组成员 浅底 原创 作为一位经验丰富的游戏开发人员 这次浅底将CocosBuilder经验分享给大家 希望大家喜欢 欢迎拍砖 转载请注明出处
  • yolov5加入CBAM,SE,CA,ECA注意力机制,纯代码(22.3.1还更新)

    本文所涉及到的yolov5网络为5 0版本 后续有需求会更新6 0版本 CBAM注意力 class ChannelAttention nn Module def init self in planes ratio 16 super Chan
  • 答辩准备细节 - 推荐第三本书很棒的书

    之前介绍了 PPT演讲力 重要时刻 不要输在表达上 和 金字塔原理 本次准备来介绍一本非常好的设计书 写给大家看的设计书 01 设计的必要性 写简历 做PPT等都可以用到 我们虽然不是专门的设计人员 但是我们仍然可以追求内容更好看 人们对于
  • XDOJ寻找最长的行

    寻找最长的行 类别 字符串 时间限制 1S 内存限制 1000Kb 问题描述 寻找若干行文本中最长的一行 输入说明 输入为多个字符串 每个字符串长度不超过100个字符 每个字符串占一行 输入的行为 end 时表示输入结束 输出说明 输出其中
  • Elasticsearch 实现分组统计

    之前有个查询es分组求和的需求 类似关系型数据库 select a b sum c from table group by a b 当时用DSL查询语句实现 这边记录下 GET my index my type search from 0
  • C++中new与delete问题学习

    C 中new与delete问题学习 一 new char与delete问题 1 问题程序 include
  • 普歌-云言团队-Spring的AOP简介

    什么是AOP AOP 为 Aspect Oriented Programming 的缩写 意思为面向切面编程 是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术 AOP 是 OOP 的延续 是软件开发中的一个热点 也是Spri
  • 【ES实战】索引mapping的动态设置

    动态mapping 文章目录 动态mapping 动态mapping规则 语法规则 match mapping type match and unmatch match pattern path match and path unmatch
  • signature=8a03839902ac8eb66fcf33ab62032d86,swch-20200612

    0001710583 20 000020 txt 20200618 0001710583 20 000020 hdr sgml 20200618 20200618161953 ACCESSION NUMBER 0001710583 20 0
  • 了解Nginx配置文件结构与配置上下文

    提供 ZStack云计算 系列教程 本教程为如何在Ubuntu 14 04上实现Nginx与LEMP系列四篇中的第四篇 内容介绍 Nginx是一套高性能Web服务器 负责处理互联网上各大型站点的日常负载 其特别擅长处理高并发连接与大量静态内
  • c++语法

    文章目录 0 0 编译运行 单个程序编辑调试 库文件编译调试 1 变量 1 1 变量的声明和定义 1 2 变量的作用域 1 3 namespace命名空间 标准空间std 2 关键字 2 1 extern 3 常量 1 define 定义
  • 插值1算法

    一 基本概念 插值是指通过对数据进行线性 非线性或其他类型的逼近 将一组离散数据映射到连续的函数值 在数学中 插值通常用于将数据点连接起来 以形成连续的函数图像 特别是在数值计算和图像处理中 插值可以用于在空间中预测对象的位置 速度和加速度
  • Unity&Shader案例篇—绘制雨滴

    一 前言 转载请注明出处凯尔八阿哥专栏 惯例先上效果图 本文不只是简单的绘制雨滴 同时处理了摄像机不同朝向看到的雨滴下落的方向也不一样 二 方法 1 绘制雨线 绘制雨使用的是C 脚本绘制的 脚本为 using UnityEngine usi