目录
一、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是精细化的粒子特效模型坐标,而粒子特效位于3D空间下,不属于Canvas空间的,这个模型坐标实际就是世界坐标,因此需要用同样是世界坐标的坐标进行计算。反之,若裁剪的对象是一个UGUI(属于Canvas空间下的)那这个裁剪物体的模型空间就是Canvas空间,需要使用将注释的代码恢复,将坐标一步步转为Canvas空间。
上面这个解释模型空间就是3D空间的世界坐标感觉有点怪怪的...上面红色那段我只能这么理解它才能进行裁剪。
粒子特效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;
}
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物体)的裁剪