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

发布于:2025-02-11 ⋅ 阅读:(59) ⋅ 点赞:(0)

目录

一、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 frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
#if (UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITOR
        if (!ignoreUICheck && EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
#else
            if (!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 Off
                Cull[_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 Add
                    Blend One Zero
                    ZWrite On
                    Cull Off

                    CGPROGRAM
                    #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 Add
                    Blend One Zero
                    ZWrite On
                    Cull Off

                    CGPROGRAM
                    #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 Add
                    Blend One Zero
                    ZWrite On
                    Cull Off

                    CGPROGRAM
                    #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;
    #else
    float2 texcoords : TEXCOORD0;
    #endif
    #if defined(_NORMALMAP)
    float4 tangent : TANGENT;
    #endif
    UNITY_VERTEX_INPUT_INSTANCE_ID
};

                // Surface shader input
                struct 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_ON
                    float4 grabPassPosition;
                    #endif
                };

                // Non-surface shader v2f structure
                struct 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_ON
                    float4 grabPassPosition : TEXCOORD4;
                    #endif
                    float4 worldPosition : TEXCOORD5;
                    UNITY_VERTEX_OUTPUT_STEREO

                };

                fixed4 readTexture(sampler2D tex, Input IN)
                {
                    fixed4 color = tex2D(tex, IN.texcoord);
                    #ifdef _FLIPBOOK_BLENDING
                    fixed4 color2 = tex2D(tex, IN.texcoord2AndBlend.xy);
                    color = lerp(color, color2, IN.texcoord2AndBlend.z);
                    #endif
                    return color;
                }

                fixed4 readTexture(sampler2D tex, VertexOutput IN)
                {
                    fixed4 color = tex2D(tex, IN.texcoord);
                    #ifdef _FLIPBOOK_BLENDING
                    fixed4 color2 = tex2D(tex, IN.texcoord2AndBlend.xy);
                    color = lerp(color, color2, IN.texcoord2AndBlend.z);
                    #endif
                    return 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_ON
                sampler2D _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)
                #endif

                float4 _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);
                    #else
                    fixed2 metallicGloss = fixed2(_Metallic, _Glossiness);
                    #endif

                    #if defined(_NORMALMAP)
                    float3 normal = normalize(UnpackScaleNormal(readTexture(_BumpMap, IN), _BumpScale));
                    #else
                    float3 normal = float3(0,0,1);
                    #endif

                    #if defined(_EMISSION)
                    half3 emission = readTexture(_EmissionMap, IN).rgb * cameraFade * softParticlesFade;
                    #else
                    half3 emission = 0;
                    #endif

                    fragDistortion(IN);

                    o.Albedo = albedo.rgb;
                    #if defined(_NORMALMAP)
                    o.Normal = normal;
                    #endif
                    o.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;
                    #else
                    o.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));
                    #else
                    float3 normal = float3(0,0,1);
                    #endif

                    #if defined(_EMISSION)
                    half3 emission = readTexture(_EmissionMap, IN).rgb;
                    #else
                    half3 emission = 0;
                    #endif

                    fragDistortion(IN);

                    half4 result = albedo;

                    #if defined(_ALPHAMODULATE_ON)
                    result.rgb = lerp(half3(1.0, 1.0, 1.0), albedo.rgb, albedo.a);
                    #endif

                    result.rgb += emission * _EmissionColor * cameraFade * softParticlesFade;

                    #if !defined(_ALPHABLEND_ON) && !defined(_ALPHAPREMULTIPLY_ON) && !defined(_ALPHAOVERLAY_ON)
                    result.a = 1;
                    #endif

                    result.a *= UnityGet2DClipping(IN.worldPosition.xy, _CustomClipRect);

                    #if defined(_ALPHATEST_ON)
                    clip(albedo.a - _Cutoff + 0.0001);
                    #endif

                    UNITY_APPLY_FOG_COLOR(IN.fogCoord, result, fixed4(0,0,0,0));
                    return result;
                }

                #endif // UNITY_STANDARD_PARTICLES_INCLUDED


                    ENDCG
                }
            }
        }

            Fallback "VertexLit"
            //CustomEditor "StandardParticlesShaderGUI"
}

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


网站公告

今日签到

点亮在社区的每一天
去签到