Unity实现手电筒效果

2023-10-22 09:59
文章标签 实现 效果 unity 手电筒

本文主要是介绍Unity实现手电筒效果,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

用Unity开发手电筒的效果,原理就是将背景图片放在最底层,在图片上面盖一层黑色遮罩,再用Shader在遮罩上开出来几个圆形透明的“孔”,后期可以用鼠标或者Kinect控制光束的位置,我的项目是用Kinect控制的,人体感应控制手电筒,最终实现了一个探索文化的效果。

在这里插入图片描述

源代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
public class DarkEffect : MonoBehaviour
{[System.Serializable]public class Item{[SerializeField]public Transform target;[SerializeField]public int radius;public Vector3 GetScreenPosition(Camera cam){return cam.WorldToScreenPoint(target.position);}}//渐变像素数量public int _smoothLength = 20;//遮罩混合颜色public Color _darkColor = Color.black;//目标物体public List<Item> _items = new List<Item>();protected Material _mainMaterial;protected Camera _mainCamera;Vector4[] _itemDatas;Item _tmpItem;Vector4 _tmpVt;Vector3 _tmpPos;int _tmpScreenHeight;private void OnEnable(){_mainMaterial = new Material(Shader.Find("Peter/DarkEffect"));_mainCamera = GetComponent<Camera>();}private void OnRenderImage(RenderTexture source, RenderTexture destination){if (_itemDatas == null || _itemDatas.Length != _items.Count){_itemDatas = new Vector4[_items.Count];}_tmpScreenHeight = Screen.height;for (int i = 0; i < _items.Count; i++){_tmpItem = _items[i];_tmpPos = _tmpItem.GetScreenPosition(_mainCamera);_tmpVt.x = _tmpPos.x;_tmpVt.y = _tmpScreenHeight - _tmpPos.y;_tmpVt.z = _tmpItem.radius;_tmpVt.w = 0;_itemDatas[i] = _tmpVt;}_mainMaterial.SetInt("_SmoothLength", _smoothLength);_mainMaterial.SetColor("_DarkColor", _darkColor);_mainMaterial.SetInt("_ItemCnt", _itemDatas.Length);_mainMaterial.SetVectorArray("_Item", _itemDatas);Graphics.Blit(source, destination, _mainMaterial);}
}

Shader:
Shader “Peter/DarkEffect”
{
Properties
{
_MainTex(“Texture”, 2D) = “white” {}
}

    SubShader
{// No culling or depthCull Off ZWrite Off ZTest AlwaysPass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"//追踪物体最多个数#define ItemSize 9struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};sampler2D _MainTex;fixed4 _DarkColor;float _SmoothLength;fixed _ItemCnt;float4 _Item[ItemSize];v2f vert(appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.uv;return o;}fixed CalcAlpha(float4 vt, float4 pt){if (pt.z < 0){return 1;}float distPow2 = pow(vt.x - pt.x, 2) + pow(vt.y - pt.y, 2);float dist = (distPow2 > 0) ? sqrt(distPow2) : 0;float smoothLength = _SmoothLength;if (smoothLength < 0){smoothLength = 0;}float maxValue = pt.z;float minValue = pt.z - smoothLength;if (minValue < 0){minValue = 0;smoothLength = pt.z;}if (dist <= minValue){return 0;}else if (dist > maxValue){return 1;}fixed retVal = (dist - minValue) / smoothLength;return retVal;}fixed4 frag(v2f i) : SV_Target{fixed alphaVal = 1;fixed tmpVal = 1;for (fixed index = 0; index < _ItemCnt; ++index){tmpVal = CalcAlpha(i.vertex, _Item[index]);if (tmpVal < alphaVal){alphaVal = tmpVal;}}alphaVal *= _DarkColor.a;return tex2D(_MainTex, i.uv) * (1 - alphaVal) + _DarkColor * alphaVal;}ENDCG}
}

}

这篇关于Unity实现手电筒效果的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/260710

相关文章

python+OpenCV反投影图像的实现示例详解

《python+OpenCV反投影图像的实现示例详解》:本文主要介绍python+OpenCV反投影图像的实现示例详解,本文通过实例代码图文并茂的形式给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前言二、什么是反投影图像三、反投影图像的概念四、反向投影的工作原理一、利用反向投影backproj

Django之定时任务django-crontab的实现

《Django之定时任务django-crontab的实现》Django可以使用第三方库如django-crontab来实现定时任务的调度,本文主要介绍了Django之定时任务django-cront... 目录crontab安装django-crontab注册应用定时时间格式定时时间示例设置定时任务@符号

Python中edge-tts实现便捷语音合成

《Python中edge-tts实现便捷语音合成》edge-tts是一个功能强大的Python库,支持多种语言和声音选项,本文主要介绍了Python中edge-tts实现便捷语音合成,具有一定的参考价... 目录安装与环境设置文本转语音查找音色更改语音参数生成音频与字幕总结edge-tts 是一个功能强大的

Java实现按字节长度截取字符串

《Java实现按字节长度截取字符串》在Java中,由于字符串可能包含多字节字符,直接按字节长度截取可能会导致乱码或截取不准确的问题,下面我们就来看看几种按字节长度截取字符串的方法吧... 目录方法一:使用String的getBytes方法方法二:指定字符编码处理方法三:更精确的字符编码处理使用示例注意事项方

使用Python和PaddleOCR实现图文识别的代码和步骤

《使用Python和PaddleOCR实现图文识别的代码和步骤》在当今数字化时代,图文识别技术的应用越来越广泛,如文档数字化、信息提取等,PaddleOCR是百度开源的一款强大的OCR工具包,它集成了... 目录一、引言二、环境准备2.1 安装 python2.2 安装 PaddlePaddle2.3 安装

嵌入式Linux之使用设备树驱动GPIO的实现方式

《嵌入式Linux之使用设备树驱动GPIO的实现方式》:本文主要介绍嵌入式Linux之使用设备树驱动GPIO的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、设备树配置1.1 添加 pinctrl 节点1.2 添加 LED 设备节点二、编写驱动程序2.1

Android 实现一个隐私弹窗功能

《Android实现一个隐私弹窗功能》:本文主要介绍Android实现一个隐私弹窗功能,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 效果图如下:1. 设置同意、退出、点击用户协议、点击隐私协议的函数参数2. 《用户协议》、《隐私政策》设置成可点击的,且颜色要区分出来res/l

spring IOC的理解之原理和实现过程

《springIOC的理解之原理和实现过程》:本文主要介绍springIOC的理解之原理和实现过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、IoC 核心概念二、核心原理1. 容器架构2. 核心组件3. 工作流程三、关键实现机制1. Bean生命周期2.

Redis实现分布式锁全解析之从原理到实践过程

《Redis实现分布式锁全解析之从原理到实践过程》:本文主要介绍Redis实现分布式锁全解析之从原理到实践过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、背景介绍二、解决方案(一)使用 SETNX 命令(二)设置锁的过期时间(三)解决锁的误删问题(四)Re

Java根据IP地址实现归属地获取

《Java根据IP地址实现归属地获取》Ip2region是一个离线IP地址定位库和IP定位数据管理框架,这篇文章主要为大家详细介绍了Java如何使用Ip2region实现根据IP地址获取归属地,感兴趣... 目录一、使用Ip2region离线获取1、Ip2region简介2、导包3、下编程载xdb文件4、J