当前位置: 首页 > news >正文

【Unity3D】Particle粒子特效或3D物体显示在UGUI上的方案

目录

一、RawImage + Camera + RenderTexture方式

(1)扩展知识:实现射线检测RawImage内的3D物体

(2)扩展知识:实现粒子特效显示RawImage上

二、UI摄像机 + Canvas(Screen Space - Camera模式)方式

(1)尝试使用模板测试裁剪粒子特效(失败案例)

(2)传递Mask区域Rect数据进行裁剪粒子特效


一、RawImage + Camera + RenderTexture方式

(1)扩展知识:实现射线检测RawImage内的3D物体

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;public class SphereTest : MonoBehaviour
{//是否忽略UI检测public bool ignoreUICheck = false;//发送射线的摄像机public Camera rayCamera;public RectTransform canvasRectTrans;public Camera uiCamera;public RectTransform rawImageRectTrans;// Update is called once per framevoid Update(){if (Input.GetMouseButtonDown(0)){
#if (UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITORif (!ignoreUICheck && EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
#elseif (!ignoreUICheck && EventSystem.current.IsPointerOverGameObject(-1))
#endif{Debug.Log("点击到UI物体:" + EventSystem.current.currentSelectedGameObject);}else{//ScreenPointToRay仅适用于主摄像机的射线(主摄像机即MainCamera 直接渲染到屏幕的)//针对RawImage内的3D物体进行射线检测,首先要使用渲染3D物体的摄像机(非主摄像机,它深度会被我们调到比主摄像机低,以及CullingMask剔除掉这层的物体)//其次是无法使用ScreenPointToRay检测到的,即使你将3D物体和摄像机都挪到主摄像机相同的位置朝向..//使用ViewportPointToRay转用视角发射射线, 获取RawImage视角坐标需要将屏幕点击坐标转RawImage所在Canvas的UI坐标,再转到RawImage空间的视角坐标//1.利用API(RectTransformUtility.ScreenPointToLocalPointInRectangle)将屏幕坐标点击位置转化为UGUI坐标Vector2 uiPos;if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRectTrans, Input.mousePosition, uiCamera, out uiPos)){//2.转RawImage空间的视角坐标,需知道uiPos相对该空间的位置,以及该空间的宽高//2.1获取RawImage物体的x,y,width,height (位于Canvas空间内的)float width = rawImageRectTrans.rect.width;float height = rawImageRectTrans.rect.height;float x = rawImageRectTrans.localPosition.x - (width * rawImageRectTrans.pivot.x);float y = rawImageRectTrans.localPosition.y - (height * rawImageRectTrans.pivot.y);//2.2根据上述参数求出uiPos位于RawImage空间的相对位置float uiPosXRelativeRawImage = (uiPos.x - x) / width;float uiPosYRelativeRawImage = (uiPos.y - y) / height;Vector2 relativeRawImagePos = new Vector2(uiPosXRelativeRawImage, uiPosYRelativeRawImage);Ray ray = rayCamera.ViewportPointToRay(relativeRawImagePos);RaycastHit raycastHit;if (Physics.Raycast(ray, out raycastHit, 1000)){if (raycastHit.collider.gameObject != null){Debug.Log("点击3D物体:" + raycastHit.collider.gameObject);}}Debug.DrawLine(ray.origin, raycastHit.point, Color.red, 1);}}}}
}

(2)扩展知识:实现粒子特效显示RawImage上

由于粒子特效的ColorMask默认是RGB,没有A(透明通道),而渲染粒子特效的摄像机Background的Alpha是0,就会导致没有A通道的是无法被摄像机渲染出来的(反正测试是这样)

因此我们需要修改粒子特效的Shader,去官网下载对应Unity版本的Shader源码找到对应的shader文件拷贝到我们工程内开始修改。

Unity官方下载_Unity新版_从Unity Hub下载安装 | Unity中国官网

修改如下2个地方,以保证粒子特效渲染于透明层级以及开放RGBA通道渲染

Tags {"Queue" = "Transparent"
}ColorMask RGBA

二、UI摄像机 + Canvas(Screen Space - Camera模式)方式

 

注意ClearFlags是清空所有位于它前面的摄像机缓存到ColorBuffer和DeepBuffer的,位于前面是指深度小于当前摄像机的。

此处是仅清空了深度(Deep Only),背景颜色保持用主摄像机。

选中Canvas,右击创建粒子特效,会帮你默认处理将粒子特效的Layer设置为UI

想让粒子特效显示的层级高于UI的Image则使用如下图控制,大于Canvas的Order即可。

正常显示出粒子特效,但发现没法被Mask组件裁剪,因为Mask裁剪原理是模板测试裁剪,而粒子特效Shader并没有模板测试,也尝试过将模板测试写到粒子特效Shader中,但是观察FrameDebugger发现其渲染是在Mask恢复了模板值为0之后进行的,所以这种依赖模板测试的方式裁剪行不通,具体如下图说明一切。

(1)尝试使用模板测试裁剪粒子特效(失败案例)

 

如果我将粒子特效的模板值改为0去比较,那肯定通过测试,全都会被渲染出来

(2)传递Mask区域Rect数据进行裁剪粒子特效

原理:传递Mask区域的左下角和右上角世界坐标到粒子Shader进行一个是否在(左下角,右上角)区域内判定,若不在则将透明度设置为0,达到裁剪目的。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class MyMask : MonoBehaviour
{public Camera uiCamera;public ParticleSystem particle;public RectTransform canvasRectTrans;private void Start(){var renderer = particle.GetComponent<ParticleSystemRenderer>();Material particleMat = renderer.material;//获取Mask裁剪区域四个点坐标RectTransform rectTransform = this.gameObject.GetComponent<RectTransform>();Vector3[] worldPosArray = new Vector3[4];rectTransform.GetWorldCorners(worldPosArray);Vector3 lbPos = worldPosArray[0];Vector3 rtPos = worldPosArray[2];//针对3D物体裁剪(粒子特效也是3D),需传递3D空间坐标(即世界坐标)particleMat.SetVector("_CustomClipRect", new Vector4(lbPos.x, lbPos.y, rtPos.x, rtPos.y));//注意 若针对UI裁剪,这必须传递UI空间系的坐标,如下注释内容...//lbPos = uiCamera.WorldToScreenPoint(lbPos);//rtPos = uiCamera.WorldToScreenPoint(rtPos);//Vector2 lbLocalPos = Vector2.zero;//Vector2 rtLocalPos = Vector2.zero;//RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRectTrans, lbPos, uiCamera, out lbLocalPos);//RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRectTrans, rtPos, uiCamera, out rtLocalPos);//particleMat.SetVector("_CustomClipRect", new Vector4(lbLocalPos.x, lbLocalPos.y, rtLocalPos.x, rtLocalPos.y));}
}

        解释下为什么传递的是世界坐标系的Mask区域,因为Shader使用的是将vertex模型坐标转世界坐标后传递到frag,此时frag的worldPosition是精细化的粒子特效世界坐标,因此需要用同样是世界坐标的坐标进行计算。

        若是UI裁剪,则必须传递的是Canvas空间下的坐标,否则无法正常裁剪,原因猜测就是UI是隶属于Canvas的,其Shader内的世界坐标也只是对应于Canvas空间下的世界坐标,而粒子特效是3D物体,不隶属Canvas这种特殊空间,所以正常传递世界坐标。

 粒子特效Shader改动点如下:

Properties
{_CustomClipRect("CustomClipRect", vector) = (0,0,0,0)
}
Pass
{
Tags { Queue="Transparent" }Blend SrcAlpha OneMinusSrcAlpha                        CGPROGRAM#include "UnityUI.cginc"struct appdata_particles
{float4 vertex : POSITION;
};struct VertexOutput
{float4 worldPosition : TEXCOORD5;
};void vertParticleUnlit(appdata_particles v, out VertexOutput o)
{//o.worldPosition = v.vertex; //这行也是正常的,但稳妥起见还是转世界坐标o.worldPosition = mul(v.vertex, unity_ObjectToWorld);
}half4 fragParticleUnlit(VertexOutput IN) : SV_Target
{result.a *= UnityGet2DClipping(IN.worldPosition.xy, _CustomClipRect);
}ENDCG
}

Shader代码:(源码是针对Particles/Standard Unlit修改,注释了很多Pass...)

// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)Shader "Custom/Standard Unlit"
{Properties{_MainTex("Albedo", 2D) = "white" {}_Color("Color", Color) = (1,1,1,1)_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5_BumpScale("Scale", Float) = 1.0_BumpMap("Normal Map", 2D) = "bump" {}_EmissionColor("Color", Color) = (0,0,0)_EmissionMap("Emission", 2D) = "white" {}_DistortionStrength("Strength", Float) = 1.0_DistortionBlend("Blend", Range(0.0, 1.0)) = 0.5_SoftParticlesNearFadeDistance("Soft Particles Near Fade", Float) = 0.0_SoftParticlesFarFadeDistance("Soft Particles Far Fade", Float) = 1.0_CameraNearFadeDistance("Camera Near Fade", Float) = 1.0_CameraFarFadeDistance("Camera Far Fade", Float) = 2.0_StencilComp("Stencil Comparison", Float) = 8_Stencil("Stencil ID", Float) = 0_StencilOp("Stencil Operation", Float) = 0_StencilWriteMask("Stencil Write Mask", Float) = 255_StencilReadMask("Stencil Read Mask", Float) = 255_ColorMask("Color Mask", Float) = 15_CustomClipRect("CustomClipRect", vector) = (0,0,0,0)// Hidden properties[HideInInspector] _Mode("__mode", Float) = 0.0[HideInInspector] _ColorMode("__colormode", Float) = 0.0[HideInInspector] _FlipbookMode("__flipbookmode", Float) = 0.0[HideInInspector] _LightingEnabled("__lightingenabled", Float) = 0.0[HideInInspector] _DistortionEnabled("__distortionenabled", Float) = 0.0[HideInInspector] _EmissionEnabled("__emissionenabled", Float) = 0.0[HideInInspector] _BlendOp("__blendop", Float) = 0.0[HideInInspector] _SrcBlend("__src", Float) = 1.0[HideInInspector] _DstBlend("__dst", Float) = 0.0[HideInInspector] _ZWrite("__zw", Float) = 1.0[HideInInspector] _Cull("__cull", Float) = 2.0[HideInInspector] _SoftParticlesEnabled("__softparticlesenabled", Float) = 0.0[HideInInspector] _CameraFadingEnabled("__camerafadingenabled", Float) = 0.0[HideInInspector] _SoftParticleFadeParams("__softparticlefadeparams", Vector) = (0,0,0,0)[HideInInspector] _CameraFadeParams("__camerafadeparams", Vector) = (0,0,0,0)[HideInInspector] _ColorAddSubDiff("__coloraddsubdiff", Vector) = (0,0,0,0)[HideInInspector] _DistortionStrengthScaled("__distortionstrengthscaled", Float) = 0.0}Category{SubShader{Tags {"Queue" = "Transparent""IgnoreProjector" = "True""RenderType" = "Transparent"                  "PreviewType" = "Plane" "PerformanceChecks" = "False"             }BlendOp[_BlendOp]Blend[_SrcBlend][_DstBlend]ZWrite[_ZWrite]Lighting OffCull[_Cull]                ColorMask [_ColorMask]     Stencil{Ref[_Stencil]Comp[_StencilComp]Pass[_StencilOp]ReadMask[_StencilReadMask]WriteMask[_StencilWriteMask]}GrabPass{Tags { "LightMode" = "Always" }"_GrabTexture"}/*  Pass{Name "ShadowCaster"Tags { "LightMode" = "ShadowCaster" }BlendOp AddBlend One ZeroZWrite OnCull OffCGPROGRAM#pragma target 2.5#pragma shader_feature_local _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ALPHAMODULATE_ON#pragma shader_feature_local _ _COLOROVERLAY_ON _COLORCOLOR_ON _COLORADDSUBDIFF_ON#pragma shader_feature_local _REQUIRE_UV2#pragma multi_compile_shadowcaster#pragma multi_compile_instancing#pragma instancing_options procedural:vertInstancingSetup#pragma vertex vertParticleShadowCaster#pragma fragment fragParticleShadowCaster#include "UnityStandardParticleShadow.cginc"ENDCG}*//*  Pass{Name "SceneSelectionPass"Tags { "LightMode" = "SceneSelectionPass" }BlendOp AddBlend One ZeroZWrite OnCull OffCGPROGRAM#pragma target 2.5#pragma shader_feature_local _ALPHATEST_ON#pragma shader_feature_local _REQUIRE_UV2#pragma multi_compile_instancing#pragma instancing_options procedural:vertInstancingSetup#pragma vertex vertEditorPass#pragma fragment fragSceneHighlightPass#include "UnityStandardParticleEditor.cginc"ENDCG}*//* Pass{Name "ScenePickingPass"Tags{ "LightMode" = "Picking" }BlendOp AddBlend One ZeroZWrite OnCull OffCGPROGRAM#pragma target 2.5#pragma shader_feature_local _ALPHATEST_ON#pragma shader_feature_local _REQUIRE_UV2#pragma multi_compile_instancing#pragma instancing_options procedural:vertInstancingSetup#pragma vertex vertEditorPass#pragma fragment fragScenePickingPass#include "UnityStandardParticleEditor.cginc"ENDCG}*/Pass{Tags { "LightMode" = "ForwardBase" }Blend SrcAlpha OneMinusSrcAlpha                                        CGPROGRAM#pragma multi_compile __ SOFTPARTICLES_ON#pragma multi_compile_fog#pragma target 2.5#pragma shader_feature_local _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON _ALPHAMODULATE_ON#pragma shader_feature_local _ _COLOROVERLAY_ON _COLORCOLOR_ON _COLORADDSUBDIFF_ON#pragma shader_feature_local _NORMALMAP#pragma shader_feature _EMISSION#pragma shader_feature_local _FADING_ON#pragma shader_feature_local _REQUIRE_UV2#pragma shader_feature_local EFFECT_BUMP#pragma vertex vertParticleUnlit#pragma fragment fragParticleUnlit#pragma multi_compile_instancing#pragma instancing_options procedural:vertInstancingSetup//#include "UnityStandardParticles.cginc"// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)#ifndef UNITY_STANDARD_PARTICLES_INCLUDED
#define UNITY_STANDARD_PARTICLES_INCLUDED#if _REQUIRE_UV2
#define _FLIPBOOK_BLENDING 1
#endif#if EFFECT_BUMP
#define _DISTORTION_ON 1
#endif#include "UnityPBSLighting.cginc"
#include "UnityStandardParticleInstancing.cginc"
#include "UnityUI.cginc"// Particles surface shader has a lot of variants in it, but some of those do not affect
// code generation (i.e. don't have inpact on which Input/SurfaceOutput things are read or written into).
// Surface shader analysis done during import time skips "completely identical" shader variants, so to
// help this process we'll turn off some features that we know are not affecting the inputs/outputs.
//
// If you change the logic of what the below variants do, make sure to not regress code generation though,
// e.g. compare full "show generated code" output of the surface shader before & after the change.
#if defined(SHADER_TARGET_SURFACE_ANALYSIS)// All these only alter the color in various ways#undef _COLOROVERLAY_ON#undef _COLORCOLOR_ON#undef _COLORADDSUBDIFF_ON#undef _ALPHAMODULATE_ON#undef _ALPHATEST_ON// For inputs/outputs analysis SoftParticles and Fading are identical; so make sure to only keep one// of them ever defined.#if defined(SOFTPARTICLES_ON)#undef SOFTPARTICLES_ON#define _FADING_ON#endif
#endif// Vertex shader input
struct appdata_particles
{float4 vertex : POSITION;float3 normal : NORMAL;fixed4 color : COLOR;#if defined(_FLIPBOOK_BLENDING) && !defined(UNITY_PARTICLE_INSTANCING_ENABLED)float4 texcoords : TEXCOORD0;float texcoordBlend : TEXCOORD1;#elsefloat2 texcoords : TEXCOORD0;#endif#if defined(_NORMALMAP)float4 tangent : TANGENT;#endifUNITY_VERTEX_INPUT_INSTANCE_ID
};// Surface shader inputstruct Input{float4 color : COLOR;float2 texcoord;#if defined(_FLIPBOOK_BLENDING)float3 texcoord2AndBlend;#endif#if defined(SOFTPARTICLES_ON) || defined(_FADING_ON)float4 projectedPosition;#endif#if _DISTORTION_ONfloat4 grabPassPosition;#endif};// Non-surface shader v2f structurestruct VertexOutput{float4 vertex : SV_POSITION;float4 color : COLOR;UNITY_FOG_COORDS(0)float2 texcoord : TEXCOORD1;#if defined(_FLIPBOOK_BLENDING)float3 texcoord2AndBlend : TEXCOORD2;#endif#if defined(SOFTPARTICLES_ON) || defined(_FADING_ON)float4 projectedPosition : TEXCOORD3;#endif#if _DISTORTION_ONfloat4 grabPassPosition : TEXCOORD4;#endiffloat4 worldPosition : TEXCOORD5;UNITY_VERTEX_OUTPUT_STEREO};fixed4 readTexture(sampler2D tex, Input IN){fixed4 color = tex2D(tex, IN.texcoord);#ifdef _FLIPBOOK_BLENDINGfixed4 color2 = tex2D(tex, IN.texcoord2AndBlend.xy);color = lerp(color, color2, IN.texcoord2AndBlend.z);#endifreturn color;}fixed4 readTexture(sampler2D tex, VertexOutput IN){fixed4 color = tex2D(tex, IN.texcoord);#ifdef _FLIPBOOK_BLENDINGfixed4 color2 = tex2D(tex, IN.texcoord2AndBlend.xy);color = lerp(color, color2, IN.texcoord2AndBlend.z);#endifreturn color;}sampler2D _MainTex;float4 _MainTex_ST;half4 _Color;sampler2D _BumpMap;half _BumpScale;sampler2D _EmissionMap;half3 _EmissionColor;sampler2D _MetallicGlossMap;half _Metallic;half _Glossiness;UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);float4 _SoftParticleFadeParams;float4 _CameraFadeParams;half _Cutoff;#define SOFT_PARTICLE_NEAR_FADE _SoftParticleFadeParams.x#define SOFT_PARTICLE_INV_FADE_DISTANCE _SoftParticleFadeParams.y#define CAMERA_NEAR_FADE _CameraFadeParams.x#define CAMERA_INV_FADE_DISTANCE _CameraFadeParams.y#if _DISTORTION_ONsampler2D _GrabTexture;half _DistortionStrengthScaled;half _DistortionBlend;#endif#if defined (_COLORADDSUBDIFF_ON)half4 _ColorAddSubDiff;#endif#if defined(_COLORCOLOR_ON)half3 RGBtoHSV(half3 arg1){half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);half4 P = lerp(half4(arg1.bg, K.wz), half4(arg1.gb, K.xy), step(arg1.b, arg1.g));half4 Q = lerp(half4(P.xyw, arg1.r), half4(arg1.r, P.yzx), step(P.x, arg1.r));half D = Q.x - min(Q.w, Q.y);half E = 1e-10;return half3(abs(Q.z + (Q.w - Q.y) / (6.0 * D + E)), D / (Q.x + E), Q.x);}half3 HSVtoRGB(half3 arg1){half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);half3 P = abs(frac(arg1.xxx + K.xyz) * 6.0 - K.www);return arg1.z * lerp(K.xxx, saturate(P - K.xxx), arg1.y);}#endif// Color function#if defined(UNITY_PARTICLE_INSTANCING_ENABLED)#define vertColor(c) \vertInstancingColor(c);#else#define vertColor(c)#endif// Flipbook vertex function#if defined(UNITY_PARTICLE_INSTANCING_ENABLED)#if defined(_FLIPBOOK_BLENDING)#define vertTexcoord(v, o) \vertInstancingUVs(v.texcoords.xy, o.texcoord, o.texcoord2AndBlend);#else#define vertTexcoord(v, o) \vertInstancingUVs(v.texcoords.xy, o.texcoord); \o.texcoord = TRANSFORM_TEX(o.texcoord, _MainTex);#endif#else#if defined(_FLIPBOOK_BLENDING)#define vertTexcoord(v, o) \o.texcoord = v.texcoords.xy; \o.texcoord2AndBlend.xy = v.texcoords.zw; \o.texcoord2AndBlend.z = v.texcoordBlend;#else#define vertTexcoord(v, o) \o.texcoord = TRANSFORM_TEX(v.texcoords.xy, _MainTex);#endif#endif// Fading vertex function#if defined(SOFTPARTICLES_ON) || defined(_FADING_ON)#define vertFading(o) \o.projectedPosition = ComputeScreenPos (clipPosition); \COMPUTE_EYEDEPTH(o.projectedPosition.z);#else#define vertFading(o)#endif// Distortion vertex function#if _DISTORTION_ON#define vertDistortion(o) \o.grabPassPosition = ComputeGrabScreenPos (clipPosition);#else#define vertDistortion(o)#endif// Color blending fragment function#if defined(_COLOROVERLAY_ON)#define fragColorMode(i) \albedo.rgb = lerp(1 - 2 * (1 - albedo.rgb) * (1 - i.color.rgb), 2 * albedo.rgb * i.color.rgb, step(albedo.rgb, 0.5)); \albedo.a *= i.color.a;#elif defined(_COLORCOLOR_ON)#define fragColorMode(i) \half3 aHSL = RGBtoHSV(albedo.rgb); \half3 bHSL = RGBtoHSV(i.color.rgb); \half3 rHSL = fixed3(bHSL.x, bHSL.y, aHSL.z); \albedo = fixed4(HSVtoRGB(rHSL), albedo.a * i.color.a);#elif defined(_COLORADDSUBDIFF_ON)#define fragColorMode(i) \albedo.rgb = albedo.rgb + i.color.rgb * _ColorAddSubDiff.x; \albedo.rgb = lerp(albedo.rgb, abs(albedo.rgb), _ColorAddSubDiff.y); \albedo.a *= i.color.a;#else#define fragColorMode(i) \albedo *= i.color;#endif// Pre-multiplied alpha helper#if defined(_ALPHAPREMULTIPLY_ON)#define ALBEDO_MUL albedo#else#define ALBEDO_MUL albedo.a#endif// Soft particles fragment function#if defined(SOFTPARTICLES_ON) && defined(_FADING_ON)#define fragSoftParticles(i) \float softParticlesFade = 1.0f; \if (SOFT_PARTICLE_NEAR_FADE > 0.0 || SOFT_PARTICLE_INV_FADE_DISTANCE > 0.0) \{ \float sceneZ = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projectedPosition))); \softParticlesFade = saturate (SOFT_PARTICLE_INV_FADE_DISTANCE * ((sceneZ - SOFT_PARTICLE_NEAR_FADE) - i.projectedPosition.z)); \ALBEDO_MUL *= softParticlesFade; \}#else#define fragSoftParticles(i) \float softParticlesFade = 1.0f;#endif// Camera fading fragment function#if defined(_FADING_ON)#define fragCameraFading(i) \float cameraFade = saturate((i.projectedPosition.z - CAMERA_NEAR_FADE) * CAMERA_INV_FADE_DISTANCE); \ALBEDO_MUL *= cameraFade;#else#define fragCameraFading(i) \float cameraFade = 1.0f;#endif#if _DISTORTION_ON#define fragDistortion(i) \float4 grabPosUV = UNITY_PROJ_COORD(i.grabPassPosition); \grabPosUV.xy += normal.xy * _DistortionStrengthScaled * albedo.a; \half3 grabPass = tex2Dproj(_GrabTexture, grabPosUV).rgb; \albedo.rgb = lerp(grabPass, albedo.rgb, saturate(albedo.a - _DistortionBlend));#else#define fragDistortion(i)#endiffloat4 _CustomClipRect;void vert(inout appdata_particles v, out Input o){UNITY_INITIALIZE_OUTPUT(Input, o);float4 clipPosition = UnityObjectToClipPos(v.vertex);vertColor(v.color);vertTexcoord(v, o);vertFading(o);vertDistortion(o);}void surf(Input IN, inout SurfaceOutputStandard o){half4 albedo = readTexture(_MainTex, IN);albedo *= _Color;fragColorMode(IN);fragSoftParticles(IN);fragCameraFading(IN);#if defined(_METALLICGLOSSMAP)fixed2 metallicGloss = readTexture(_MetallicGlossMap, IN).ra * fixed2(1.0, _Glossiness);#elsefixed2 metallicGloss = fixed2(_Metallic, _Glossiness);#endif#if defined(_NORMALMAP)float3 normal = normalize(UnpackScaleNormal(readTexture(_BumpMap, IN), _BumpScale));#elsefloat3 normal = float3(0,0,1);#endif#if defined(_EMISSION)half3 emission = readTexture(_EmissionMap, IN).rgb * cameraFade * softParticlesFade;#elsehalf3 emission = 0;#endiffragDistortion(IN);o.Albedo = albedo.rgb;#if defined(_NORMALMAP)o.Normal = normal;#endifo.Emission = emission * _EmissionColor;o.Metallic = metallicGloss.r;o.Smoothness = metallicGloss.g;#if defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON) || defined(_ALPHAOVERLAY_ON)o.Alpha = albedo.a;#elseo.Alpha = 1;#endif#if defined(_ALPHAMODULATE_ON)o.Albedo = lerp(half3(1.0, 1.0, 1.0), albedo.rgb, albedo.a);#endif#if defined(_ALPHATEST_ON)clip(albedo.a - _Cutoff + 0.0001);#endif}void vertParticleUnlit(appdata_particles v, out VertexOutput o){UNITY_SETUP_INSTANCE_ID(v);UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);o.worldPosition = v.vertex;float4 clipPosition = UnityObjectToClipPos(v.vertex);o.vertex = clipPosition;o.color = v.color;                    vertColor(o.color);vertTexcoord(v, o);vertFading(o);vertDistortion(o);UNITY_TRANSFER_FOG(o, o.vertex);}half4 fragParticleUnlit(VertexOutput IN) : SV_Target{half4 albedo = readTexture(_MainTex, IN);albedo *= _Color;fragColorMode(IN);fragSoftParticles(IN);fragCameraFading(IN);#if defined(_NORMALMAP)float3 normal = normalize(UnpackScaleNormal(readTexture(_BumpMap, IN), _BumpScale));#elsefloat3 normal = float3(0,0,1);#endif#if defined(_EMISSION)half3 emission = readTexture(_EmissionMap, IN).rgb;#elsehalf3 emission = 0;#endiffragDistortion(IN);half4 result = albedo;#if defined(_ALPHAMODULATE_ON)result.rgb = lerp(half3(1.0, 1.0, 1.0), albedo.rgb, albedo.a);#endifresult.rgb += emission * _EmissionColor * cameraFade * softParticlesFade;#if !defined(_ALPHABLEND_ON) && !defined(_ALPHAPREMULTIPLY_ON) && !defined(_ALPHAOVERLAY_ON)result.a = 1;#endifresult.a *= UnityGet2DClipping(IN.worldPosition.xy, _CustomClipRect);#if defined(_ALPHATEST_ON)clip(albedo.a - _Cutoff + 0.0001);#endifUNITY_APPLY_FOG_COLOR(IN.fogCoord, result, fixed4(0,0,0,0));return result;}#endif // UNITY_STANDARD_PARTICLES_INCLUDEDENDCG}}}Fallback "VertexLit"//CustomEditor "StandardParticlesShaderGUI"
}

 测试针对UI(2D物体)的裁剪

相关文章:

【Unity3D】Particle粒子特效或3D物体显示在UGUI上的方案

目录 一、RawImage Camera RenderTexture方式 &#xff08;1&#xff09;扩展知识&#xff1a;实现射线检测RawImage内的3D物体 &#xff08;2&#xff09;扩展知识&#xff1a;实现粒子特效显示RawImage上 二、UI摄像机 Canvas(Screen Space - Camera模式)方式 &#…...

有没有检测吸烟的软件 ai视频检测分析厂区抽烟报警#Python

在现代厂区管理中&#xff0c;安全与规范是重中之重&#xff0c;而吸烟行为的管控则是其中关键一环。传统的禁烟管理方式往往依赖人工巡逻&#xff0c;效率低且存在监管死角&#xff0c;难以满足当下复杂多变的厂区环境需求。此时&#xff0c;AI视频检测技术应运而生&#xff0…...

《鸣潮》游戏运行时弹出“xinput1_3.dll文件缺失”错误的处理方法,“xinput1_3.dll文件缺失”详解!

一、xinput1_3.dll文件的重要性 xinput1_3.dll是DirectX组件中的一个重要文件&#xff0c;它负责处理与Xbox 360控制器相关的输入功能。尽管《鸣潮》可能并不直接依赖于Xbox控制器&#xff0c;但许多现代游戏和应用程序都会调用这个DLL文件来处理各种输入设备的功能。因此&…...

大模型应用—HivisionIDPhotos 证件照在线制作!支持离线、换装、美颜等

HivisionIDPhotos 证件照在线制作!支持离线、换装、美颜等 ivisionIDPhotos 是一款功能强大的开源证件照生成工具。用户只需上传一张人像照片,它就能智能裁剪为一寸、两寸等标准尺寸,同时自动去除背景并渲染新的背景颜色,例如蓝色、白色、红色,还支持渐变色和自定义颜色。…...

解决Ubuntu下无法装载 Windows D盘的问题

电脑安装了 Windows 和 Ubuntu 24.04 后&#xff0c;在Ubuntu系统上装载 D盘&#xff0c;发现无法装载错误如下&#xff1a; Error mounting /dev/nvme0n1p4 at /media/jackeysong/Data: wrong fs type, bad option, bad superblock on /dev/nvme0n1p4, missing codepage or h…...

一体成型电感

一体成型电感是通过铁粉模压成型而成的同封装条件下实现更大的额定电流&#xff0c;且更适合批量自动化生产&#xff0c;较传统绕线电感有成本优势。同时&#xff0c;一体成型电感与磁封胶结构电感相比具有更好的磁屏蔽效果&#xff0c;适合EMI无法调试通过的项目使用。 但一体…...

Reed-Muller(RM)码之编码

点个关注吧! 看了一些中文的博客,RM码没有很详细的资料,所以本文尝试给出推导原理。 推导 RM码由 ( r , m ) ( r , m ) (r,m...

【蓝桥杯——物联网设计与开发】基础模块8 - RTC

目录 一、RTC &#xff08;1&#xff09;资源介绍 &#x1f505;简介 &#x1f505;时钟与分频&#xff08;十分重要‼️&#xff09; &#xff08;2&#xff09;STM32CubeMX 软件配置 &#xff08;3&#xff09;代码编写 &#xff08;4&#xff09;实验现象 二、RTC接口…...

聚类算法DBSCAN 改进总结

目录 DBSCAN(Density-Based Spatial Clustering of Applications with Noise) 1. HDBSCAN (Hierarchical DBSCAN) 优点: 安装: 使用实例1 效果失败 使用实例2 3. DBSCAN++ (DBSCAN with Preprocessing) 4. DBSCAN with k-distance 5. Density Peaks Clustering (DP…...

uniapp开发微信小程序实现获取“我的位置”

1. 创建GetLocation项目 使用HBuilder X创建一个项目GetLocation,使用Vue3。 2. 在腾讯地图开放平台中创建应用 要获取位置,在小程序中需要使用腾讯地图或是高德地图。下面以腾讯地图为例。 (1)打开腾讯地图开放平台官方网址:腾讯位置服务 - 立足生态,连接未来 (2)注册…...

java中两个系统进行非对称加密,两个系统的公私钥可以用一套吗?

在非对称加密中&#xff0c;每个参与方应该拥有自己独立的一套公钥和私钥。非对称加密的基础在于公钥和私钥的配对使用&#xff1a;一个密钥用于加密信息&#xff0c;则另一个对应的密钥用于解密信息。具体来说&#xff1a; 如果A要发送一条保密消息给B&#xff0c;那么A会使用…...

无人设备遥控器之定向天线篇

一、定义与功能 定向天线&#xff0c;顾名思义&#xff0c;是通过改变天线的辐射方向&#xff0c;实现信号发射、接收和增强的天线。它可以让信号以更高的功率、更远的距离传输到指定区域&#xff0c;同时也能够降低与周围天线之间的干扰。在无人设备遥控器中&#xff0c;定向天…...

【电路笔记 信号】Metastability 平均故障间隔时间(MTBF)公式推导:进入亚稳态+退出亚稳态+同步器的可靠性计算

这是一个简化的电路分析模型。图2中的典型触发器包括主锁存器、从锁存器和去耦反相器(这个结构类似 主从边沿触发器)。 在亚稳态中&#xff0c;主锁存器的节点A、B的电压电平大致在逻辑“1”&#xff08;VDD&#xff09;和“0”&#xff08;GND&#xff09;之间。确切的电压电平…...

计算机视觉:原理、分类与应用

计算机视觉是当今科技领域中一个至关重要的分支&#xff0c;它赋予了计算机通过视觉感知和理解世界的能力。简单来说&#xff0c;计算机视觉实现了对图像、视频等视觉数据的分析、处理、识别和理解。这是一个跨学科的研究领域&#xff0c;涉及计算机科学、信息工程、数学、物理…...

Vue.js组件开发-使用watch进行深度观察

在Vue.js中&#xff0c;watch选项允许观察和响应Vue实例上数据的变化。当需要对某个数据属性进行深度观察&#xff0c;即在其内部嵌套的对象或数组发生变化时也能触发回调时&#xff0c;可以使用deep选项。 示例&#xff1a; new Vue({el: #app,data: {user: {name: John,age…...

明厨亮灶系统

校园食堂明厨亮灶AI分析系统通过yolov5网络模型技术&#xff0c;校园食堂明厨亮灶监控分析系统针对校园餐厅后厨不按要求戴口罩、不穿厨师帽、陌生人员进入后厨、厨师不穿厨师服、上班时间玩手机、老鼠识别等行为校园食堂明厨亮灶监控分析系统自动识别抓拍告警。Yolo算法&#…...

虚幻引擎结构之AActor

在虚幻引擎中&#xff0c;AActor 是一个核心类&#xff0c;作为游戏世界内所有可交互对象的基础。任何可以在关卡中放置或动态生成的对象&#xff0c;几乎都是从 AActor 类派生而来。这包括但不限于角色、道具、特效、静态和动态物体等。 1. AActor 的基本概念 AActor 作为基类…...

基于JAVA+SpringBoot+Vue的制造装备物联及生产管理ERP系统

基于JAVASpringBootVue的制造装备物联及生产管理ERP系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&am…...

JAVA HTTP压缩数据

/*** 压缩数据包** param code* param data* param resp* throws IOException*/protected void writeZipResult(int code, Object data, HttpServletResponse resp) throws IOException {resp.setHeader("Content-Encoding", "gzip");// write到客户端resp…...

VSCode 配置远程连接免密登录 插件

自我存档 远程连接免密登录 远程连接 在扩展界面搜remote ssh 安装完成后可以在侧边栏找到远程资源管理器 通过来添加或者点击打开ssh配置文件 点击的话以这种方式, 手动添加则按照相同格式输入即可 格式如下所示, Host后添加IP, User是登录ssh的用户, hostname是显示在…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...