1764 lines
62 KiB
HLSL
1764 lines
62 KiB
HLSL
#ifndef NBSHADER_INPUT
|
||
#define NBSHADER_INPUT
|
||
|
||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
|
||
#include "NBShaderFlags.hlsl"
|
||
|
||
#if defined(_PROGRAM_NOISE) && (defined(_PROGRAM_NOISE_SIMPLE) || defined(_PROGRAM_NOISE_VORONOI))
|
||
#define _PROGRAM_NOISE_ACTIVE
|
||
#endif
|
||
|
||
|
||
//---------------particleInput-------------------
|
||
CBUFFER_START(UnityPerMaterial)
|
||
float4 _SoftParticleFadeParams;
|
||
float4 _CameraFadeParams;
|
||
// #ifdef _INTERSECT_ON
|
||
float _IntersectRadius;
|
||
half4 _IntersectColor;
|
||
// #endif
|
||
half _AdditiveToPreMultiplyAlphaLerp;
|
||
half _Saturability;
|
||
half _HueShift;
|
||
half _Contrast;
|
||
half3 _ContrastMidColor;
|
||
half4 _BaseMapColorRefine;
|
||
half _AlphaAll;
|
||
float4 _BaseMap_ST;
|
||
float4 _BaseMap_AnimationSheetBlend_ST;//20240826 暂时只是给AnimationSheetHelper用。
|
||
half _AnimationSheetHelperBlendIntensity;
|
||
float4 _MaskMap_ST;
|
||
half4 _BaseColor;
|
||
half4 _BaseBackColor;
|
||
half _BaseColorIntensityForTimeline;
|
||
half4 _EmissionMap_ST;
|
||
half4 _NoiseMap_ST;
|
||
half4 _NoiseMaskMap_ST;
|
||
half4 _DistortionDirection;
|
||
half4 _BaseColorAddSubDiff;
|
||
half _fogintensity;
|
||
half _Emi_Distortion_intensity;
|
||
half _BaseMapUVRotation;
|
||
half _BaseMapUVRotationSpeed;
|
||
float _MaskMapUVRotation;
|
||
float _NoiseMapUVRotation;
|
||
half _ScreenDistortIntensity;
|
||
half _ScreenDistortAlphaPow;
|
||
half _ScreenDistortAlphaAdd;
|
||
half _ScreenDistortAlphaMulti;
|
||
half _NoiseIntensity;
|
||
half _RefractionIOR;
|
||
half _uvRapSoft;
|
||
half4 _EmissionMapColor;
|
||
half _EmissionMapColorIntensity;
|
||
|
||
|
||
//--------------光照部分-------------
|
||
float4 _BumpTex_ST;
|
||
half _BumpScale;
|
||
half4 _MaterialInfo;
|
||
half4 _SpecularColor;
|
||
//-----------SixWayLight----------
|
||
half4 _SixWayInfo;
|
||
half4 _SixWayEmissionColor;
|
||
|
||
half4 _MatCapColor;
|
||
half4 _MatCapInfo;
|
||
|
||
half _EdgeFade;
|
||
half4 _NoiseOffset;
|
||
half4 _EmissionMapUVOffset;
|
||
half _EmissionMapUVRotation;
|
||
half _EmissionSelfAlphaWeight;
|
||
half _TexDistortion_intensity;
|
||
// //half _RJ_Distortion_intensity;
|
||
// half _XianXingCH_UVRota;
|
||
// half _jingxiangCH_dire;
|
||
|
||
half _MaskDistortion_intensity;
|
||
half4 _BaseMapMaskMapOffset;
|
||
half4 _MaskMapOffsetAnition;
|
||
half4 _MaskMap3OffsetAnition;
|
||
half4 _MaskMapVec;
|
||
half4 _MaskRefineVec;
|
||
|
||
int _MaskMapGradientCount;
|
||
half4 _MaskMapGradientFloat0;
|
||
half4 _MaskMapGradientFloat1;
|
||
half4 _MaskMapGradientFloat2;
|
||
int _MaskMap2GradientCount;
|
||
half4 _MaskMap2GradientFloat0;
|
||
half4 _MaskMap2GradientFloat1;
|
||
half4 _MaskMap2GradientFloat2;
|
||
int _MaskMap3GradientCount;
|
||
half4 _MaskMap3GradientFloat0;
|
||
half4 _MaskMap3GradientFloat1;
|
||
half4 _MaskMap3GradientFloat2;
|
||
|
||
float4 _PCCenter;
|
||
float4 _TWParameter;
|
||
float _TWStrength;
|
||
float4 _Fade;
|
||
float _OverrideZValue;
|
||
float _MaskMapRotationSpeed;
|
||
|
||
|
||
half _FrePower;
|
||
half _FresnelInOutSlider;
|
||
half4 _FresnelRotation;
|
||
half _FresnelSelfAlphaWeight;
|
||
half4 _FresnelUnit;
|
||
half4 _FresnelUnit2;
|
||
half4 _DepthOutline_Vec;
|
||
half4 _DepthOutline_Color;
|
||
half4 _FresnelColor;
|
||
half4 _ColorA;
|
||
float4 _ClipRect;
|
||
|
||
float4 _CylinderMatrix0;
|
||
float4 _CylinderMatrix1;
|
||
float4 _CylinderMatrix2;
|
||
float4 _CylinderMatrix3;
|
||
|
||
half4 _Color;
|
||
float4 _UI_MainTex_ST;//在UI中,RawImage组件的功能和正常的TexST不一致,所以这里使用另外传的方式。
|
||
float4 _MainTex_Reverse_ST;
|
||
|
||
half _Cutoff;
|
||
|
||
float4 _MaskMap2_ST;
|
||
float4 _MaskMap3_ST;
|
||
|
||
float time;
|
||
half _FresnelFadeDistance;
|
||
|
||
half4 LB_RT;
|
||
|
||
half4 _Dissolve;
|
||
half4 _DissolveMap_ST;
|
||
half4 _DissolveOffsetRotateDistort;
|
||
half4 _DissolveMaskMap_ST;
|
||
half _DissolveMaskMode;
|
||
|
||
half4 _DissolveLineColor;
|
||
half4 _DissolveRampColor;
|
||
float4 _DissolveVoronoi_Vec;
|
||
half4 _DissolveVoronoi_Vec2;
|
||
float4 _DissolveVoronoi_Vec3;
|
||
float4 _DissolveVoronoi_Vec4;
|
||
half4 _DissolveRampMap_ST;
|
||
half4 _Dissolve_Vec2;
|
||
half _ProgramNoise_Rotate;
|
||
|
||
half4 _SharedUV_ST;
|
||
half4 _SharedUV_Vec;
|
||
// half _SharedUV_Distort_Intensity;
|
||
|
||
half4 _ColorBlendMap_ST;
|
||
float4 _ColorBlendMapOffset;
|
||
half4 _ColorBlendColor;
|
||
half4 _ColorBlendVec;
|
||
|
||
half4 _RampColor0;
|
||
half4 _RampColor1;
|
||
half4 _RampColor2;
|
||
half4 _RampColor3;
|
||
half4 _RampColor4;
|
||
half4 _RampColor5;
|
||
half4 _RampColorAlpha0;
|
||
half4 _RampColorAlpha1;
|
||
half4 _RampColorAlpha2;
|
||
uint _RampColorCount;
|
||
half4 _RampColorBlendColor;
|
||
float4 _RampColorMapOffset;
|
||
half4 _RampColorMap_ST;
|
||
|
||
half4 _DissolveRampColor0;
|
||
half4 _DissolveRampColor1;
|
||
half4 _DissolveRampColor2;
|
||
half4 _DissolveRampColor3;
|
||
half4 _DissolveRampColor4;
|
||
half4 _DissolveRampColor5;
|
||
half4 _DissolveRampAlpha0;
|
||
half4 _DissolveRampAlpha1;
|
||
half4 _DissolveRampAlpha2;
|
||
uint _DissolveRampCount;
|
||
|
||
|
||
half3 _VertexOffset_Vec;
|
||
half3 _VertexOffset_CustomDir;
|
||
half4 _VertexOffset_Map_ST;
|
||
|
||
half4 _VertexOffset_MaskMap_ST;
|
||
half3 _VertexOffset_MaskMap_Vec;
|
||
|
||
float _VAT_Toggle;
|
||
float _VATMode;
|
||
float _ImportScale;
|
||
float _TyFlowVATSubMode;
|
||
float _DeformingSkin;
|
||
float _SkinBoneCount;
|
||
float _RGBAEncoded;
|
||
float _RGBAHalf;
|
||
float _LinearToGamma;
|
||
float _VATIncludesNormals;
|
||
float _AffectsShadows;
|
||
float _Frame;
|
||
float _Frames;
|
||
float _FrameInterpolation;
|
||
float _Loop;
|
||
float _InterpolateLoop;
|
||
float _Autoplay;
|
||
float _AutoplaySpeed;
|
||
|
||
half _ParallaxMapping_Intensity;
|
||
half4 _ParallaxMapping_Map_ST;
|
||
half4 _ParallaxMapping_Vec;
|
||
half _WorldSpaceUVModeSelector;
|
||
half _ObjectSpaceUVModeSelector;
|
||
|
||
uint _W9ParticleShaderFlags;
|
||
|
||
uint _W9ParticleShaderFlags1;
|
||
|
||
uint _W9ParticleShaderWrapFlags;
|
||
|
||
uint _W9ParticleCustomDataFlag0;
|
||
uint _W9ParticleCustomDataFlag1;
|
||
uint _W9ParticleCustomDataFlag2;
|
||
uint _W9ParticleCustomDataFlag3;
|
||
|
||
uint _UVModeFlag0;
|
||
uint _UVModeFlagType0;
|
||
|
||
|
||
uint _W9ParticleShaderColorChannelFlag;
|
||
uint _W9ParticleShaderPNoiseBlendFlag;
|
||
half _ProgramNoiseBaseBlendOpacity;
|
||
half _MaskPNoiseBlendOpacity;
|
||
half _DissolvePNoiseBlendOpacity;
|
||
half _DistortPNoiseBlendOpacity;
|
||
float4x4 _CustomLocalTransformLocalToWorld;
|
||
float4x4 _CustomLocalTransformWorldToLocal;
|
||
|
||
CBUFFER_END
|
||
|
||
#define NB_SHADER_FLAGS _W9ParticleShaderFlags
|
||
#define NB_SHADER_FLAGS1 _W9ParticleShaderFlags1
|
||
#define NB_SHADER_WRAP_FLAGS _W9ParticleShaderWrapFlags
|
||
#define NB_SHADER_COLOR_CHANNEL_FLAG _W9ParticleShaderColorChannelFlag
|
||
#define NB_SHADER_PNOISE_BLEND_FLAG _W9ParticleShaderPNoiseBlendFlag
|
||
#define NB_CUSTOM_DATA_FLAG_0 _W9ParticleCustomDataFlag0
|
||
#define NB_CUSTOM_DATA_FLAG_1 _W9ParticleCustomDataFlag1
|
||
#define NB_CUSTOM_DATA_FLAG_2 _W9ParticleCustomDataFlag2
|
||
#define NB_CUSTOM_DATA_FLAG_3 _W9ParticleCustomDataFlag3
|
||
|
||
float3x3 GetCustomLocalToWorld3x3()
|
||
{
|
||
return (float3x3)_CustomLocalTransformLocalToWorld;
|
||
}
|
||
|
||
float3x3 GetCustomWorldToLocal3x3()
|
||
{
|
||
return (float3x3)_CustomLocalTransformWorldToLocal;
|
||
}
|
||
|
||
float3 TransformWorldToObject_NB(float3 positionWS)
|
||
{
|
||
#ifdef _CUSTOM_LOCAL_TRANSFORM
|
||
return mul(_CustomLocalTransformWorldToLocal, float4(positionWS, 1.0)).xyz;
|
||
#else
|
||
return mul(unity_WorldToObject, float4(positionWS, 1.0)).xyz;
|
||
#endif
|
||
}
|
||
|
||
float3 TransformObjectToWorld_NB(float3 positionOS)
|
||
{
|
||
#ifdef _CUSTOM_LOCAL_TRANSFORM
|
||
return mul(_CustomLocalTransformLocalToWorld, float4(positionOS, 1.0)).xyz;
|
||
#else
|
||
return mul(unity_ObjectToWorld, float4(positionOS, 1.0)).xyz;
|
||
#endif
|
||
}
|
||
|
||
float4 TransformObjectToHClip_NB(float3 positionOS)
|
||
{
|
||
#ifdef _CUSTOM_LOCAL_TRANSFORM
|
||
return TransformWorldToHClip(TransformObjectToWorld_NB(positionOS));
|
||
#else
|
||
return TransformObjectToHClip(positionOS);
|
||
#endif
|
||
}
|
||
|
||
float3 TransformWorldToObjectDir_NB(float3 dirWS, bool doNormalize = true)
|
||
{
|
||
#ifdef _CUSTOM_LOCAL_TRANSFORM
|
||
float3 dirOS = mul(GetCustomWorldToLocal3x3(), dirWS);
|
||
return doNormalize ? SafeNormalize(dirOS) : dirOS;
|
||
#else
|
||
float3 dirOS = mul((float3x3)unity_WorldToObject, dirWS);
|
||
return doNormalize ? SafeNormalize(dirOS) : dirOS;
|
||
#endif
|
||
}
|
||
|
||
float3 TransformWorldToObjectNormal_NB(float3 normalWS)
|
||
{
|
||
#ifdef _CUSTOM_LOCAL_TRANSFORM
|
||
return SafeNormalize(mul(normalWS, GetCustomLocalToWorld3x3()));
|
||
#else
|
||
return SafeNormalize(mul(normalWS, (float3x3)unity_ObjectToWorld));
|
||
#endif
|
||
}
|
||
|
||
float3 TransformObjectToWorldDir_NB(float3 dirOS, bool doNormalize = true)
|
||
{
|
||
#ifdef _CUSTOM_LOCAL_TRANSFORM
|
||
float3 dirWS = mul(GetCustomLocalToWorld3x3(), dirOS);
|
||
return doNormalize ? SafeNormalize(dirWS) : dirWS;
|
||
#else
|
||
return TransformObjectToWorldDir(dirOS, doNormalize);
|
||
#endif
|
||
}
|
||
|
||
float3 TransformObjectToWorldNormal_NB(float3 normalOS)
|
||
{
|
||
#ifdef _CUSTOM_LOCAL_TRANSFORM
|
||
return SafeNormalize(mul(normalOS, GetCustomWorldToLocal3x3()));
|
||
#else
|
||
return TransformObjectToWorldNormal(normalOS);
|
||
#endif
|
||
}
|
||
|
||
real3 NBTransformWorldToTangentDir(real3 dirWS, real3x3 tangentToWorld, bool doNormalize = false)
|
||
{
|
||
// Unity 2021 / URP 12 does not expose TransformWorldToTangentDir.
|
||
real3 result = mul(tangentToWorld, dirWS);
|
||
return doNormalize ? SafeNormalize(result) : result;
|
||
}
|
||
|
||
float3 GetCustomLocalSpaceNormalizeViewDir(float3 positionOS)
|
||
{
|
||
#ifdef _CUSTOM_LOCAL_TRANSFORM
|
||
float3 viewDir = TransformWorldToObject_NB(_WorldSpaceCameraPos) - positionOS;
|
||
return SafeNormalize(viewDir);
|
||
#else
|
||
return GetObjectSpaceNormalizeViewDir(positionOS);
|
||
#endif
|
||
}
|
||
|
||
float GetCustomLocalOddNegativeScale()
|
||
{
|
||
#ifdef _CUSTOM_LOCAL_TRANSFORM
|
||
return determinant(GetCustomLocalToWorld3x3()) < 0.0 ? -1.0 : 1.0;
|
||
#else
|
||
return GetOddNegativeScale();
|
||
#endif
|
||
}
|
||
|
||
|
||
bool CheckLocalFlags(uint bits)
|
||
{
|
||
return (_W9ParticleShaderFlags&bits) != 0;
|
||
}
|
||
bool CheckLocalFlags1(uint bits)
|
||
{
|
||
return (_W9ParticleShaderFlags1&bits) != 0;
|
||
}
|
||
int CheckLocalWrapFlags(uint bits)
|
||
{
|
||
bool bit0 = (_W9ParticleShaderWrapFlags&bits) != 0;
|
||
bool bit1 = (_W9ParticleShaderWrapFlags&(bits<<16)) != 0;
|
||
if(!bit0 && !bit1)
|
||
{
|
||
return 0;
|
||
}
|
||
else if(bit0 && !bit1)
|
||
{
|
||
return 1;
|
||
}
|
||
else if(!bit0 && bit1)
|
||
{
|
||
return 2;
|
||
}
|
||
else if(bit0 && bit1)
|
||
{
|
||
return 3;
|
||
}
|
||
else
|
||
{
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
|
||
SamplerState sampler_linear_repeat;
|
||
SamplerState sampler_linear_clamp;
|
||
SamplerState sampler_linear_RepeatU_ClampV;
|
||
SamplerState sampler_linear_ClampU_RepeatV;
|
||
SamplerState sampler_point_clamp;
|
||
|
||
|
||
|
||
half4 SampleTexture2D(Texture2D tex,float2 uv,SAMPLER( textureSampler),bool sampleLOD = false,int lod = 0)
|
||
{
|
||
if (sampleLOD)
|
||
{
|
||
return SAMPLE_TEXTURE2D_LOD(tex,textureSampler,uv,lod);
|
||
|
||
}
|
||
else
|
||
{
|
||
return SAMPLE_TEXTURE2D(tex,textureSampler,uv);
|
||
}
|
||
}
|
||
|
||
|
||
half4 SampleTexture2DWithWrapFlags(Texture2D tex,float2 uv,uint bits,bool sampleLOD = false,int lod = 0)
|
||
{
|
||
#ifdef _CAMERA_OPAQUE_DISTORT_PASS
|
||
int wrapMode;
|
||
if (bits == FLAG_BIT_WRAPMODE_BASEMAP)
|
||
{
|
||
wrapMode = 1;
|
||
}
|
||
else
|
||
{
|
||
wrapMode = CheckLocalWrapFlags(bits);
|
||
}
|
||
|
||
#else
|
||
const int wrapMode = CheckLocalWrapFlags(bits);
|
||
#endif
|
||
|
||
|
||
#if defined(SHADER_TARGET_GLSL) ||defined (SHADER_API_GLES)|| defined(SHADER_API_GLES3)
|
||
switch (wrapMode)
|
||
{
|
||
case 0: uv = frac(uv);break;
|
||
case 1: uv = saturate(uv);break;
|
||
case 2: uv = float2(frac(uv.x),saturate(uv.y));break;
|
||
case 3: uv = float2(saturate(uv.x),frac(uv.y));break;
|
||
}
|
||
if (sampleLOD)
|
||
{
|
||
return SAMPLE_TEXTURE2D_LOD(tex,sampler_linear_clamp,uv,lod);//SamplerWillIgnore;需要在GLSL相关平台打包时强制设置为Clamp循环。
|
||
|
||
}
|
||
else
|
||
{
|
||
return SAMPLE_TEXTURE2D(tex,sampler_linear_clamp,uv);//SamplerWillIgnore;需要在GLSL相关平台打包时强制设置为Clamp循环。
|
||
}
|
||
|
||
#else
|
||
|
||
switch (wrapMode)
|
||
{
|
||
case 0:
|
||
return SampleTexture2D(tex,uv,sampler_linear_repeat,sampleLOD,lod);
|
||
break;
|
||
case 1:
|
||
return SampleTexture2D(tex,uv,sampler_linear_clamp,sampleLOD,lod);
|
||
case 2:
|
||
return SampleTexture2D(tex,uv,sampler_linear_RepeatU_ClampV,sampleLOD,lod);
|
||
break;
|
||
case 3:
|
||
return SampleTexture2D(tex,uv,sampler_linear_ClampU_RepeatV,sampleLOD,lod);
|
||
break;
|
||
default:
|
||
return SampleTexture2D(tex,uv,sampler_linear_repeat,sampleLOD,lod);
|
||
break;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
half GetColorChannel(half4 color, int bitPos)
|
||
{
|
||
uint bits = _W9ParticleShaderColorChannelFlag >> bitPos;
|
||
bits = bits & 3;
|
||
if (bits == 0) return color.x;
|
||
if (bits == 1) return color.y;
|
||
if (bits == 2) return color.z;
|
||
return color.w;
|
||
}
|
||
|
||
samplerCUBE _FresnelHDRITex;
|
||
sampler2D _MainTex;
|
||
|
||
|
||
|
||
#define SOFT_PARTICLE_NEAR_FADE _SoftParticleFadeParams.x //<2F>궨<EFBFBD><EAB6A8>SOFT_PARTICLE_NEAR_FADE <20><>Ϊ_SoftParticleFadeParams<6D><73><EFBFBD>Ե<EFBFBD>x<EFBFBD><78><EFBFBD><EFBFBD>~
|
||
#define SOFT_PARTICLE_INV_FADE_DISTANCE _SoftParticleFadeParams.y
|
||
|
||
#define CAMERA_NEAR_FADE _CameraFadeParams.x
|
||
#define CAMERA_INV_FADE_DISTANCE _CameraFadeParams.y
|
||
|
||
Texture2D _BaseMap;
|
||
Texture2D _NoiseMap;
|
||
Texture2D _NoiseMaskMap;
|
||
Texture2D _EmissionMap;
|
||
Texture2D _MaskMap;
|
||
Texture2D _MaskMap2;
|
||
Texture2D _MaskMap3;
|
||
#ifdef _NORMALMAP
|
||
Texture2D _BumpTex;
|
||
#endif
|
||
|
||
#ifdef _FX_LIGHT_MODE_SIX_WAY
|
||
Texture2D _RigRTBk;
|
||
Texture2D _RigLBtF;
|
||
Texture2D _SixWayEmissionRamp;
|
||
#endif
|
||
|
||
#ifdef _CAMERA_OPAQUE_DISTORT_PASS
|
||
Texture2D _CameraOpaqueTexture;
|
||
#endif
|
||
|
||
#ifdef _MATCAP
|
||
Texture2D _MatCapTex;
|
||
#endif
|
||
|
||
// Pre-multiplied alpha helper
|
||
#if defined(_ALPHAPREMULTIPLY_ON) //if( blend: One OneMinusSrcAlpha)
|
||
#define ALBEDO_MUL albedo
|
||
#else
|
||
#define ALBEDO_MUL albedo.a
|
||
#endif
|
||
|
||
|
||
#ifdef SOFT_UI_FRAME
|
||
sampler2D _SoftUIFrameMask;
|
||
// half4 LB_RT;
|
||
#endif
|
||
|
||
#ifdef _DISSOLVE
|
||
Texture2D _DissolveMap;
|
||
Texture2D _DissolveMaskMap;
|
||
Texture2D _DissolveRampMap;
|
||
#endif
|
||
|
||
# ifdef _COLORMAPBLEND
|
||
Texture2D _ColorBlendMap;
|
||
#endif
|
||
|
||
#ifdef _COLOR_RAMP
|
||
Texture2D _RampColorMap;
|
||
#endif
|
||
|
||
Texture2D _VATTex;
|
||
float4 _VATTex_TexelSize;
|
||
|
||
|
||
|
||
half4 tex2D_TryLinearizeWithoutAlphaFX(sampler2D tex, float2 uv)
|
||
{
|
||
half4 outColor = 0;
|
||
|
||
#if defined(PARTICLE)//UI下使用ParticleBase不需要做 Gamma2Linear 转换
|
||
UNITY_FLATTEN
|
||
if(CheckLocalFlags(FLAG_BIT_PARTICLE_UIEFFECT_ON))
|
||
{
|
||
outColor = tex2D(tex, uv);
|
||
}
|
||
else
|
||
{
|
||
outColor = TryLinearizeWithoutAlpha(tex2D(tex, uv));
|
||
}
|
||
#endif
|
||
return outColor;
|
||
}
|
||
//
|
||
// Color blending fragment function
|
||
float4 MixParticleColor(float4 baseColor, float4 particleColor, float4 colorAddSubDiff)
|
||
{
|
||
#if defined(_COLOROVERLAY_ON) // Overlay blend
|
||
float4 output = baseColor;
|
||
output.rgb = lerp(1 - 2 * (1 - baseColor.rgb) * (1 - particleColor.rgb), 2 * baseColor.rgb * particleColor.rgb, step(baseColor.rgb, 0.5));
|
||
output.a *= particleColor.a;
|
||
return output;
|
||
#elif defined(_COLORCOLOR_ON) // Color blend
|
||
half3 aHSL = RgbToHsv(baseColor.rgb);
|
||
half3 bHSL = RgbToHsv(particleColor.rgb);
|
||
half3 rHSL = half3(bHSL.x, bHSL.y, aHSL.z);
|
||
return half4(HsvToRgb(rHSL), baseColor.a * particleColor.a);
|
||
#elif defined(_COLORADDSUBDIFF_ON) // Additive, Subtractive and Difference blends based on 'colorAddSubDiff'
|
||
float4 output = baseColor;
|
||
output.rgb = baseColor.rgb + particleColor.rgb * colorAddSubDiff.x;
|
||
output.rgb = lerp(output.rgb, abs(output.rgb), colorAddSubDiff.y);
|
||
output.a *= particleColor.a;
|
||
return output;
|
||
#else // Default to Multiply blend
|
||
return baseColor * particleColor;
|
||
#endif
|
||
}
|
||
|
||
// Soft particles - returns alpha value for fading particles based on the depth to the background pixel
|
||
float SoftParticles(float near, float far, float sceneZ,float thisZ)
|
||
{
|
||
float fade = 1;
|
||
if (near > 0.0 || far > 0.0)
|
||
{
|
||
// fade = saturate(far * ((sceneZ - near) - thisZ));
|
||
float dist = sceneZ - thisZ;
|
||
fade = NB_Remap(dist, near,far,0,1);
|
||
}
|
||
return fade;
|
||
}
|
||
|
||
|
||
// Camera fade - returns alpha value for fading particles based on camera distance
|
||
half CameraFade(float near, float far, float thisZ)
|
||
{
|
||
return saturate((thisZ - near) * far);
|
||
}
|
||
|
||
//相交位置渐变功能
|
||
half4 Intersect(float IntersectRadius,half4 IntersectColor,float sceneZ,float thisZ)
|
||
{
|
||
half fade = sceneZ - thisZ;
|
||
fade =1- NB_Remap(fade,0,IntersectRadius,0,1);
|
||
|
||
half4 c = 0;
|
||
c.rgb = IntersectColor.rgb;
|
||
c.a = fade*IntersectColor.a;
|
||
|
||
return c;
|
||
}
|
||
|
||
//遮挡穿透显示功能。
|
||
half OccludeOpacity(half preAlpha,half _OccludeOpacity,half sceneZ,half thisZ)
|
||
{
|
||
half fakeZtest = step(thisZ,sceneZ);
|
||
return lerp(preAlpha*_OccludeOpacity,preAlpha,fakeZtest);
|
||
}
|
||
|
||
|
||
// Sample a texture and do blending for texture sheet animation if needed
|
||
half4 BlendTexture(sampler2D _Texture, float2 uv, float3 blendUv)
|
||
{
|
||
half4 color = tex2D_TryLinearizeWithoutAlphaFX(_Texture, uv);
|
||
|
||
half4 color2;
|
||
#ifdef _FLIPBOOKBLENDING_ON
|
||
color2 = tex2D_TryLinearizeWithoutAlphaFX(_Texture, blendUv.xy);
|
||
color = lerp(color, color2, blendUv.z);
|
||
#endif
|
||
|
||
// if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_ANIMATION_SHEET_HELPER))
|
||
// {
|
||
// color2 = tex2D_TryLinearizeWithoutAlphaFX(_Texture, blendUv.xy);
|
||
// color = lerp(color, color2, blendUv.z);
|
||
// }
|
||
return color;
|
||
}
|
||
|
||
half4 BlendTexture(Texture2D _Texture, float2 uv, float3 blendUv,uint bits)
|
||
{
|
||
half4 color = SampleTexture2DWithWrapFlags(_Texture,uv,bits);
|
||
half4 color2;
|
||
#ifdef _FLIPBOOKBLENDING_ON
|
||
color2 = SampleTexture2DWithWrapFlags(_Texture,blendUv.xy,bits);
|
||
color = lerp(color, color2, blendUv.z);
|
||
#endif
|
||
|
||
// if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_ANIMATION_SHEET_HELPER))
|
||
// {
|
||
// color2 = SampleTexture2DWithWrapFlags(_Texture, blendUv.xy,bits);
|
||
// color = lerp(color, color2, blendUv.z);
|
||
// }
|
||
return color;
|
||
}
|
||
|
||
float2 UVOffsetAnimaiton(float2 UV,half2 OffsetSpeed)
|
||
{
|
||
float2 newUV = float2(OffsetSpeed.x*time+UV.x,OffsetSpeed.y*time+UV.y);
|
||
return newUV;
|
||
}
|
||
|
||
// 采样噪波
|
||
half4 SampleNoise(half4 NoiseOffset, Texture2D _Texture,float2 UV, half3 wordPos)
|
||
{
|
||
|
||
float2 UV2 = float2(NoiseOffset.x * time + UV.x, NoiseOffset.y * time + UV.y); //_Time.y
|
||
|
||
half4 color = SampleTexture2DWithWrapFlags(_Texture, UV2 ,FLAG_BIT_WRAPMODE_NOISEMAP);
|
||
// color.xy *= color.a;
|
||
|
||
return color;
|
||
}
|
||
|
||
|
||
// // 替换颜色
|
||
// half3 ReplaceColor_float(float3 In, float3 From, float3 To, float Range, float Fuzziness)
|
||
// {
|
||
// float Distance = distance(From, In);
|
||
// half3 Out = lerp(To, In, saturate((Distance - Range) / max(Fuzziness, 0.001))); //e-f? 0.00001
|
||
// return Out;
|
||
// }
|
||
|
||
//漩涡 圆形区域内变形。圆圈中心处的像素会旋转指定角度;圆圈中其他像素的旋转会随着相对于中心距离的变化而减小,在圆圈边缘处减小为零
|
||
float2 UTwirl(float2 UV, float2 Center, float Strength)
|
||
{
|
||
float2 delta = UV - Center;
|
||
float angle = Strength * length(delta);
|
||
float x = cos(angle) * delta.x - sin(angle) * delta.y;
|
||
float y = sin(angle) * delta.x + cos(angle) * delta.y;
|
||
return float2(x + Center.x , y + Center.y );
|
||
|
||
}
|
||
|
||
//Fresnel
|
||
half4 Unity_FresnelEffect(float3 Normal, float3 ViewDir, float Power, float Dire,half fresnelPos)
|
||
{
|
||
// half aa = saturate(dot(normalize(Normal), (ViewDir)));
|
||
half aa = dot(normalize(Normal), (ViewDir));
|
||
aa = (aa+1)*0.5;
|
||
aa = NB_Remap(aa,fresnelPos,1,0,1);
|
||
aa = lerp(aa, (1 - aa), Dire);
|
||
half Out = pow( aa, Power);
|
||
return Out;
|
||
}
|
||
|
||
half3 Rotation(half3 normalizedDirection,half3 rotation)
|
||
{
|
||
half4 Dir = half4(normalizedDirection,1);
|
||
float4x4 M_RotationX = float4x4(
|
||
|
||
1,0,0,0,
|
||
0,cos(rotation.x),sin(rotation.x),0,
|
||
0,-sin(rotation.x),cos(rotation.x),0,
|
||
0,0,0,1
|
||
|
||
);
|
||
float4x4 M_RotationY = float4x4(
|
||
|
||
cos(rotation.y),0,sin(rotation.y),0,
|
||
0,1,0,0,
|
||
-sin(rotation.y),0,cos(rotation.y),0,
|
||
0,0,0,1
|
||
|
||
);
|
||
float4x4 M_RotationZ = float4x4(
|
||
|
||
cos(rotation.z),sin(rotation.z),0,0,
|
||
-sin(rotation.z),cos(rotation.z),0,0,
|
||
0,0,1,0,
|
||
0,0,0,1
|
||
|
||
);
|
||
|
||
return mul(M_RotationZ,mul(M_RotationY,mul(M_RotationX,Dir)));
|
||
|
||
}
|
||
|
||
//----------------公告板功能-----------------//
|
||
half3 BillBoard(float3 camPos, float3 vertexPos, int billboardType, int _ReverseZ)
|
||
{
|
||
float3 Z = normalize(mul(unity_WorldToObject, float4(_WorldSpaceCameraPos,1)));
|
||
if(_ReverseZ == 1)
|
||
{
|
||
Z *= -1;
|
||
}
|
||
Z.y *= billboardType;
|
||
|
||
float3 Y = float3(0,1,0);
|
||
float3 X = normalize(cross(Z,Y));
|
||
Y = normalize(cross(X,Z));
|
||
float4x4 M = float4x4(
|
||
X.x, Y.x, Z.x, 0,
|
||
X.y, Y.y, Z.y, 0,
|
||
X.z, Y.z, Z.z, 0,
|
||
0,0,0,1
|
||
);
|
||
float3 newPos = mul(M, vertexPos);
|
||
return newPos;
|
||
}
|
||
|
||
half3 BillBoardNormal(float3 camPos, float3 vertexPos, int billboardType, int _ReverseZ)
|
||
{
|
||
float3 Z = normalize(mul(unity_WorldToObject, float4(_WorldSpaceCameraPos,1)));
|
||
if(_ReverseZ == 1)
|
||
{
|
||
Z *= -1;
|
||
}
|
||
Z.y *= billboardType;
|
||
|
||
float3 Y = float3(0,1,0);
|
||
float3 X = normalize(cross(Y,Z));
|
||
Y = normalize(cross(X,Z));
|
||
float4x4 M = float4x4(
|
||
X.x, Y.x, Z.x, 0,
|
||
X.y, Y.y, Z.y, 0,
|
||
X.z, Y.z, Z.z, 0,
|
||
0,0,0,1
|
||
);
|
||
float3 newPos = -mul(M, vertexPos);
|
||
return newPos;
|
||
}
|
||
|
||
|
||
float2 ParticleUVCommonProcess(float2 originUVAfterTwirlPolar,float4 scaleTilling,float2 offset = float2(0,0),float rotation = 0,float2 rotationCenter = float2(0.5,0.5))
|
||
{
|
||
float2 uv = originUVAfterTwirlPolar;
|
||
uv = Rotate_Radians_float(uv,rotationCenter,rotation);
|
||
uv = uv*scaleTilling.xy + scaleTilling.zw;
|
||
|
||
uv = UVOffsetAnimaiton(uv,offset);
|
||
|
||
return uv;
|
||
}
|
||
|
||
struct ParticleUVs
|
||
{
|
||
float2 mainTexUV;
|
||
float2 specUV;
|
||
float2 animBlendUV;
|
||
float2 maskMapUV;
|
||
float2 maskMap2UV;
|
||
float2 maskMap3UV;
|
||
float2 emissionUV;
|
||
float2 dissolve_uv;
|
||
float2 dissolve_mask_uv;
|
||
float2 dissolve_noise1_UV;
|
||
float2 dissolve_noise2_UV;
|
||
float2 colorBlendUV;
|
||
float2 noiseMapUV;
|
||
float2 noiseMaskMapUV;
|
||
float2 bumpTexUV;
|
||
float2 colorRampMapUV;
|
||
float2 sharedUV;
|
||
};
|
||
|
||
float2 getPosUVByPosUVMode(float3 pos,half posUVMode)
|
||
{
|
||
switch ((int)posUVMode)
|
||
{
|
||
case 0:
|
||
return pos.xy;
|
||
case 1:
|
||
return pos.xz;
|
||
case 2:
|
||
return pos.yz;
|
||
default:
|
||
return pos.xz;
|
||
}
|
||
}
|
||
|
||
BaseUVs ProcessBaseUVs(float4 meshTexcoord0, float2 specialUVInTexcoord3,float4 VaryingsP_Custom1,float4 VaryingsP_Custom2,float3 postionOS,float3 positionWS,float2 screenUV)
|
||
{
|
||
//UV2的内容在外边就决定好。
|
||
float2 defaultUVChannel = meshTexcoord0.xy;
|
||
float2 specialUVChannel = meshTexcoord0.zw;
|
||
#if _FLIPBOOKBLENDING_ON
|
||
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_IS_PARTICLE_SYSTEM) & CheckLocalFlags1(FLAG_BIT_PARTICLE_1_USE_TEXCOORD2))
|
||
{
|
||
specialUVChannel = specialUVInTexcoord3;
|
||
}
|
||
#else
|
||
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_UV_FROM_MESH))
|
||
{
|
||
//Mesh条件下开启使用特殊UV通道的情况
|
||
if (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_USE_TEXCOORD1))
|
||
{
|
||
specialUVChannel = VaryingsP_Custom1.xy;
|
||
}
|
||
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_USE_TEXCOORD2))
|
||
{
|
||
specialUVChannel = VaryingsP_Custom2.xy;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//只有在粒子系统下开启特殊通道的情况,会在面板层引导合并相关内容。UI/Mesh不开启特殊通道没有意义。
|
||
specialUVChannel = meshTexcoord0.zw;
|
||
}
|
||
#endif
|
||
|
||
|
||
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_UIEFFECT_SPRITE_MODE))
|
||
{
|
||
defaultUVChannel = defaultUVChannel*_MainTex_Reverse_ST.xy +_MainTex_Reverse_ST.zw;
|
||
}
|
||
//TODO:补写MeshUV的实现
|
||
float2 cylinderUV = meshTexcoord0.xy;
|
||
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_CYLINDER_CORDINATE))
|
||
{
|
||
float4x4 _CylinderUVMatrix = float4x4(_CylinderMatrix0,_CylinderMatrix1,_CylinderMatrix2,_CylinderMatrix3);
|
||
postionOS = mul(_CylinderUVMatrix,float4(postionOS,1));
|
||
cylinderUV = CylinderCoordinate(postionOS);
|
||
}
|
||
|
||
float2 UVAfterTwirlPolar = defaultUVChannel;
|
||
if(CheckLocalFlags(FLAG_BIT_PARTICLE_UTWIRL_ON))
|
||
{
|
||
UVAfterTwirlPolar = UTwirl(defaultUVChannel,_TWParameter.xy, _TWStrength);
|
||
}
|
||
if(CheckLocalFlags(FLAG_BIT_PARTICLE_POLARCOORDINATES_ON))
|
||
{
|
||
float2 UVAfterTwirl = UVAfterTwirlPolar;
|
||
UVAfterTwirlPolar = PolarCoordinates(UVAfterTwirlPolar,_PCCenter.xy);
|
||
UVAfterTwirlPolar = lerp(UVAfterTwirl,UVAfterTwirlPolar,_PCCenter.z);
|
||
}
|
||
BaseUVs baseUVs = (BaseUVs)0;
|
||
baseUVs.defaultUVChannel = defaultUVChannel;
|
||
baseUVs.specialUVChannel = specialUVChannel;
|
||
baseUVs.uvAfterTwirlPolar = UVAfterTwirlPolar;
|
||
baseUVs.cylinderUV = cylinderUV;
|
||
|
||
baseUVs.screenUV = screenUV;
|
||
baseUVs.worldPosUV = getPosUVByPosUVMode(positionWS,_WorldSpaceUVModeSelector);
|
||
baseUVs.objectPosUV = getPosUVByPosUVMode(postionOS,_ObjectSpaceUVModeSelector);
|
||
|
||
baseUVs.sharedUV = defaultUVChannel;
|
||
float2 sharedUV = GetUVByUVMode(_UVModeFlag0,_UVModeFlagType0,FLAG_BIT_UVMODE_POS_0_SHAREDUV,baseUVs);
|
||
_SharedUV_Vec.z += time * _SharedUV_Vec.w;
|
||
sharedUV = Rotate_Radians_float(sharedUV, half2(0.5, 0.5), _SharedUV_Vec.z); //主贴图旋转
|
||
|
||
sharedUV.x += GetCustomData(_W9ParticleCustomDataFlag3,FLAGBIT_POS_3_CUSTOMDATA_SHARED_UV_OFFSET_X,0,VaryingsP_Custom1,VaryingsP_Custom2);
|
||
sharedUV.y += GetCustomData(_W9ParticleCustomDataFlag3,FLAGBIT_POS_3_CUSTOMDATA_SHARED_UV_OFFSET_Y,0,VaryingsP_Custom1,VaryingsP_Custom2);
|
||
sharedUV = sharedUV *_SharedUV_ST.xy +_SharedUV_ST.zw ; //主帖图UV重复和偏移
|
||
|
||
sharedUV = UVOffsetAnimaiton(sharedUV,_SharedUV_Vec.xy);
|
||
baseUVs.sharedUV = sharedUV;
|
||
|
||
baseUVs.mainTexUV = defaultUVChannel;
|
||
float2 baseMapUV = GetUVByUVMode(_UVModeFlag0,_UVModeFlagType0,FLAG_BIT_UVMODE_POS_0_MAINTEX,baseUVs);
|
||
|
||
float2 mainTexUV = 0;
|
||
_BaseMapUVRotation += time * _BaseMapUVRotationSpeed;
|
||
baseMapUV = Rotate_Radians_float(baseMapUV, half2(0.5, 0.5), _BaseMapUVRotation); //主贴图旋转
|
||
UNITY_BRANCH
|
||
if(CheckLocalFlags(FLAG_BIT_PARTICLE_UIEFFECT_ON) & !CheckLocalFlags1(FLAG_BIT_PARTICLE_1_UIEFFECT_BASEMAP_MODE))
|
||
{
|
||
if (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_UIEFFECT_SPRITE_MODE))
|
||
{
|
||
float2 originUV = meshTexcoord0.xy;//精灵主贴图不调整。
|
||
mainTexUV = originUV*_UI_MainTex_ST.xy+_UI_MainTex_ST.zw;
|
||
}
|
||
else
|
||
{
|
||
mainTexUV = baseMapUV*_UI_MainTex_ST.xy+_UI_MainTex_ST.zw;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
baseMapUV.x += GetCustomData(_W9ParticleCustomDataFlag0,FLAGBIT_POS_0_CUSTOMDATA_MAINTEX_OFFSET_X,0,VaryingsP_Custom1,VaryingsP_Custom2);
|
||
baseMapUV.y += GetCustomData(_W9ParticleCustomDataFlag0,FLAGBIT_POS_0_CUSTOMDATA_MAINTEX_OFFSET_Y,0,VaryingsP_Custom1,VaryingsP_Custom2);
|
||
mainTexUV = TRANSFORM_TEX(baseMapUV, _BaseMap); //主帖图UV重复和偏移
|
||
}
|
||
mainTexUV = UVOffsetAnimaiton(mainTexUV,_BaseMapMaskMapOffset.xy);
|
||
baseUVs.mainTexUV = mainTexUV;
|
||
|
||
return baseUVs;
|
||
}
|
||
|
||
|
||
void ParticleProcessUV(inout ParticleUVs particleUVs,float4 meshTexcoord0,float4 VaryingsP_Custom1,float4 VaryingsP_Custom2,BaseUVs baseUVs)
|
||
{
|
||
particleUVs.specUV = baseUVs.specialUVChannel;
|
||
|
||
particleUVs.mainTexUV = baseUVs.mainTexUV;
|
||
//-------------------------------------------------
|
||
#ifdef _FLIPBOOKBLENDING_ON //开启序列帧融合
|
||
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_ANIMATION_SHEET_HELPER))
|
||
{
|
||
// float2 baseMapUV = (baseUVs.mainTexUV - _BaseMap_ST.zw)/_BaseMap_ST.xy;
|
||
//走AnimationSheetHelper脚本的情况,永远和baseMap同步。
|
||
particleUVs.animBlendUV = meshTexcoord0.xy*_BaseMap_AnimationSheetBlend_ST.xy+_BaseMap_AnimationSheetBlend_ST.zw;
|
||
}
|
||
else
|
||
{
|
||
//走粒子的情况
|
||
particleUVs.animBlendUV = meshTexcoord0.zw;
|
||
}
|
||
#endif
|
||
|
||
|
||
#if defined(_NORMALMAP)
|
||
float2 bumpTexUV = GetUVByUVMode(_UVModeFlag0,_UVModeFlagType0,FLAG_BIT_UVMODE_POS_0_BUMPTEX,baseUVs);
|
||
bumpTexUV = TRANSFORM_TEX(bumpTexUV, _BumpTex);
|
||
particleUVs.bumpTexUV = bumpTexUV;
|
||
|
||
#endif
|
||
|
||
|
||
|
||
#if defined(_MASKMAP_ON)
|
||
|
||
float2 MaskMapuv = GetUVByUVMode(_UVModeFlag0,_UVModeFlagType0,FLAG_BIT_UVMODE_POS_0_MASKMAP,baseUVs);
|
||
|
||
UNITY_BRANCH
|
||
if(CheckLocalFlags(FLAG_BIT_PARTILCE_MASKMAPROTATIONANIMATION_ON))
|
||
{
|
||
_MaskMapUVRotation += time * _MaskMapRotationSpeed;
|
||
}
|
||
|
||
MaskMapuv= Rotate_Radians_float(MaskMapuv, half2(0.5, 0.5), _MaskMapUVRotation);
|
||
|
||
MaskMapuv = TRANSFORM_TEX(MaskMapuv, _MaskMap);
|
||
|
||
MaskMapuv.x += GetCustomData(_W9ParticleCustomDataFlag0,FLAGBIT_POS_0_CUSTOMDATA_MASK_OFFSET_X,0,VaryingsP_Custom1,VaryingsP_Custom2);
|
||
MaskMapuv.y += GetCustomData(_W9ParticleCustomDataFlag0,FLAGBIT_POS_0_CUSTOMDATA_MASK_OFFSET_Y,0,VaryingsP_Custom1,VaryingsP_Custom2);
|
||
|
||
MaskMapuv = UVOffsetAnimaiton(MaskMapuv,_MaskMapOffsetAnition.xy);
|
||
particleUVs.maskMapUV = MaskMapuv;
|
||
|
||
#if defined(_MASKMAP2_ON)
|
||
{
|
||
float2 maskMap2UV = GetUVByUVMode(_UVModeFlag0,_UVModeFlagType0,FLAG_BIT_UVMODE_POS_0_MASKMAP_2,baseUVs);
|
||
maskMap2UV = Rotate_Radians_float(maskMap2UV,half2(0.5,0.5),_MaskMapVec.y);
|
||
maskMap2UV = maskMap2UV * _MaskMap2_ST.xy + _MaskMap2_ST.zw;
|
||
|
||
maskMap2UV = UVOffsetAnimaiton(maskMap2UV,_MaskMapOffsetAnition.zw);
|
||
particleUVs.maskMap2UV = maskMap2UV;
|
||
}
|
||
#endif
|
||
|
||
#if defined(_MASKMAP3_ON)
|
||
{
|
||
float2 maskMap3UV = GetUVByUVMode(_UVModeFlag0,_UVModeFlagType0,FLAG_BIT_UVMODE_POS_0_MASKMAP_3,baseUVs);
|
||
maskMap3UV = Rotate_Radians_float(maskMap3UV,half2(0.5,0.5),_MaskMapVec.z);
|
||
|
||
maskMap3UV = maskMap3UV* _MaskMap3_ST.xy + _MaskMap3_ST.zw;
|
||
|
||
maskMap3UV = UVOffsetAnimaiton(maskMap3UV,_MaskMap3OffsetAnition.xy);
|
||
particleUVs.maskMap3UV = maskMap3UV;
|
||
}
|
||
#endif
|
||
|
||
#endif
|
||
|
||
|
||
#if defined(_EMISSION)
|
||
float2 emissionUV = GetUVByUVMode(_UVModeFlag0,_UVModeFlagType0,FLAG_BIT_UVMODE_POS_0_EMISSION_MAP,baseUVs);
|
||
emissionUV.x += GetCustomData(_W9ParticleCustomDataFlag3,FLAGBIT_POS_3_CUSTOMDATA_EMISSION_OFFSET_X,0,VaryingsP_Custom1,VaryingsP_Custom2);
|
||
emissionUV.y += GetCustomData(_W9ParticleCustomDataFlag3,FLAGBIT_POS_3_CUSTOMDATA_EMISSION_OFFSET_Y,0,VaryingsP_Custom1,VaryingsP_Custom2);
|
||
particleUVs.emissionUV = ParticleUVCommonProcess(emissionUV,_EmissionMap_ST,_EmissionMapUVOffset.xy,_EmissionMapUVRotation);
|
||
#endif
|
||
|
||
#if defined(_DISSOLVE)
|
||
_DissolveMap_ST.z += GetCustomData(_W9ParticleCustomDataFlag1,FLAGBIT_POS_1_CUSTOMDATA_DISSOLVE_OFFSET_X,0,VaryingsP_Custom1,VaryingsP_Custom2);
|
||
_DissolveMap_ST.w += GetCustomData(_W9ParticleCustomDataFlag1,FLAGBIT_POS_1_CUSTOMDATA_DISSOLVE_OFFSET_Y,0,VaryingsP_Custom1,VaryingsP_Custom2);
|
||
|
||
float2 dissolveUV = GetUVByUVMode(_UVModeFlag0,_UVModeFlagType0,FLAG_BIT_UVMODE_POS_0_DISSOLVE_MAP,baseUVs);
|
||
particleUVs.dissolve_uv = ParticleUVCommonProcess(dissolveUV,_DissolveMap_ST,_DissolveOffsetRotateDistort.xy,_DissolveOffsetRotateDistort.z);
|
||
#if defined(_DISSOLVE_MASK)
|
||
{
|
||
float2 dissolveMaskUV = GetUVByUVMode(_UVModeFlag0,_UVModeFlagType0,FLAG_BIT_UVMODE_POS_0_DISSOLVE_MASK_MAP,baseUVs);
|
||
particleUVs.dissolve_mask_uv = ParticleUVCommonProcess(dissolveMaskUV,_DissolveMaskMap_ST,float2(0,0),_DissolveOffsetRotateDistort.z);
|
||
}
|
||
#endif
|
||
#endif
|
||
|
||
#ifdef _PROGRAM_NOISE_ACTIVE
|
||
float2 programNoiseUV = GetUVByUVMode(_UVModeFlag0,_UVModeFlagType0,FLAG_BIT_UVMODE_POS_0_PROGRAM_NOISE,baseUVs);
|
||
programNoiseUV = Rotate_Radians_float(programNoiseUV,half2(0.5,0.5),_ProgramNoise_Rotate);
|
||
#if defined(_PROGRAM_NOISE_SIMPLE)
|
||
{
|
||
_DissolveVoronoi_Vec4.x += GetCustomData(_W9ParticleCustomDataFlag2,FLAGBIT_POS_2_CUSTOMDATA_DISSOLVE_NOISE1_OFFSET_X,0,VaryingsP_Custom1,VaryingsP_Custom2);
|
||
_DissolveVoronoi_Vec4.y += GetCustomData(_W9ParticleCustomDataFlag2,FLAGBIT_POS_2_CUSTOMDATA_DISSOLVE_NOISE1_OFFSET_Y,0,VaryingsP_Custom1,VaryingsP_Custom2);
|
||
particleUVs.dissolve_noise1_UV = programNoiseUV * _DissolveVoronoi_Vec.xy + _DissolveVoronoi_Vec4.xy + time*_DissolveVoronoi_Vec3.xy;
|
||
|
||
}
|
||
#endif
|
||
#if defined(_PROGRAM_NOISE_VORONOI)
|
||
{
|
||
_DissolveVoronoi_Vec4.z += GetCustomData(_W9ParticleCustomDataFlag2,FLAGBIT_POS_2_CUSTOMDATA_DISSOLVE_NOISE2_OFFSET_X,0,VaryingsP_Custom1,VaryingsP_Custom2);
|
||
_DissolveVoronoi_Vec4.w += GetCustomData(_W9ParticleCustomDataFlag2,FLAGBIT_POS_2_CUSTOMDATA_DISSOLVE_NOISE2_OFFSET_Y,0,VaryingsP_Custom1,VaryingsP_Custom2);
|
||
particleUVs.dissolve_noise2_UV = programNoiseUV * _DissolveVoronoi_Vec.zw + _DissolveVoronoi_Vec4.zw + time*_DissolveVoronoi_Vec3.zw;
|
||
}
|
||
#endif
|
||
#endif
|
||
|
||
|
||
#ifdef _COLORMAPBLEND
|
||
float2 colorBlendUV = GetUVByUVMode(_UVModeFlag0,_UVModeFlagType0,FLAG_BIT_UVMODE_POS_0_COLOR_BLEND_MAP,baseUVs);
|
||
colorBlendUV.x += GetCustomData(_W9ParticleCustomDataFlag3,FLAGBIT_POS_3_CUSTOMDATA_COLOR_BLEND_OFFSET_X,0,VaryingsP_Custom1,VaryingsP_Custom2);
|
||
colorBlendUV.y += GetCustomData(_W9ParticleCustomDataFlag3,FLAGBIT_POS_3_CUSTOMDATA_COLOR_BLEND_OFFSET_Y,0,VaryingsP_Custom1,VaryingsP_Custom2);
|
||
particleUVs.colorBlendUV = ParticleUVCommonProcess(colorBlendUV,_ColorBlendMap_ST,_ColorBlendMapOffset.xy,_ColorBlendVec.w);
|
||
|
||
#endif
|
||
#ifdef _COLOR_RAMP
|
||
float2 colorRampMapUV = GetUVByUVMode(_UVModeFlag0,_UVModeFlagType0,FLAG_BIT_UVMODE_POS_0_RAMP_COLOR_MAP,baseUVs);
|
||
particleUVs.colorRampMapUV = ParticleUVCommonProcess(colorRampMapUV,_RampColorMap_ST,_RampColorMapOffset.xy,_RampColorMapOffset.w);
|
||
#endif
|
||
half cum_noise = 0;
|
||
|
||
//TODO
|
||
|
||
#if defined(_NOISEMAP)
|
||
|
||
//和ParticleUVCommonProcess相比,此处没有UV动画,NoiseMap的UV流动在最终的SampleNoise中进行
|
||
float2 noiseMapUV = GetUVByUVMode(_UVModeFlag0,_UVModeFlagType0,FLAG_BIT_UVMODE_POS_0_NOISE_MAP,baseUVs);
|
||
particleUVs.noiseMapUV = ParticleUVCommonProcess(noiseMapUV,_NoiseMap_ST,half2(0,0),_NoiseMapUVRotation);
|
||
|
||
#if defined(_NOISE_MASKMAP)
|
||
{
|
||
float2 noiseMaskMapUV = GetUVByUVMode(_UVModeFlag0,_UVModeFlagType0,FLAG_BIT_UVMODE_POS_0_NOISE_MASK_MAP,baseUVs);
|
||
particleUVs.noiseMaskMapUV = ParticleUVCommonProcess(noiseMaskMapUV,_NoiseMaskMap_ST,half2(0,0),0);
|
||
|
||
}
|
||
#endif
|
||
#endif
|
||
|
||
|
||
|
||
}
|
||
|
||
#if defined(_VERTEX_OFFSET)
|
||
Texture2D _VertexOffset_Map;
|
||
#if defined(_VERTEX_OFFSET_MASKMAP)
|
||
Texture2D _VertexOffset_MaskMap;
|
||
#endif
|
||
|
||
// half3 _VertexOffset_Vec;
|
||
// half3 _VertexOffset_CustomDir;
|
||
// half4 _VertexOffset_Map_ST;
|
||
|
||
half3 VetexOffset(half3 positionOS,half2 originUV,half2 originMaskUV,half3 normalOS,out half3 offsetOS)
|
||
{
|
||
half2 uv = TRANSFORM_TEX(originUV,_VertexOffset_Map);
|
||
uv = UVOffsetAnimaiton(uv,_VertexOffset_Vec.xy);
|
||
// half vertexOffsetSample = tex2Dlod(_VertexOffset_Map,half4(uv,0,0));
|
||
half vertexOffsetSample = SampleTexture2DWithWrapFlags(_VertexOffset_Map,uv,FLAG_BIT_WRAPMODE_VERTEXOFFSETMAP,true,0);
|
||
// UNITY_BRANCH
|
||
// if(CheckLocalWrapFlags(FLAG_BIT_WRAPMODE_VERTEXOFFSETMAP))
|
||
// {
|
||
// vertexOffsetSample = SAMPLE_TEXTURE2D_LOD(_VertexOffset_Map,sampler_linear_clamp,uv,0);
|
||
// }
|
||
// else
|
||
// {
|
||
// vertexOffsetSample = SAMPLE_TEXTURE2D_LOD(_VertexOffset_Map,sampler_linear_repeat,uv,0);
|
||
// }
|
||
|
||
if (!CheckLocalFlags1(FLAG_BIT_PARTICLE_1_VERTEXOFFSET_START_FROM_ZERO))
|
||
{
|
||
vertexOffsetSample = vertexOffsetSample*2-1;
|
||
}
|
||
|
||
half vertexOffsetMask = 1;
|
||
#if defined(_VERTEX_OFFSET_MASKMAP)
|
||
{
|
||
half2 maskUV = TRANSFORM_TEX(originMaskUV,_VertexOffset_MaskMap);
|
||
maskUV = UVOffsetAnimaiton(maskUV,_VertexOffset_MaskMap_Vec.xy);
|
||
half vertexOffsetMaskSample = SampleTexture2DWithWrapFlags(_VertexOffset_MaskMap,maskUV,FLAG_BIT_WRAPMODE_VERTEXOFFSET_MASKMAP,true,0);
|
||
vertexOffsetMask = lerp(1,vertexOffsetMaskSample,_VertexOffset_MaskMap_Vec.z);
|
||
}
|
||
#endif
|
||
|
||
UNITY_BRANCH
|
||
if(CheckLocalFlags(FLAG_BIT_PARTICLE_VERTEX_OFFSET_NORMAL_DIR))
|
||
{
|
||
offsetOS = normalOS*_VertexOffset_Vec.z*vertexOffsetSample*vertexOffsetMask;
|
||
}
|
||
else
|
||
{
|
||
offsetOS = _VertexOffset_CustomDir*_VertexOffset_Vec.z*vertexOffsetSample*vertexOffsetMask;
|
||
}
|
||
|
||
return positionOS + offsetOS;
|
||
|
||
}
|
||
#endif
|
||
|
||
//向UV横向两边的色散。
|
||
#if defined(_CHROMATIC_ABERRATION)
|
||
half4 DistortionChoraticaberrat(Texture2D baseTexture,half2 originUV, half2 uvAfterNoise,half ChoraticaberratIntensity,uint bits)
|
||
{
|
||
half2 delta = half2(originUV.x *2-1,0);
|
||
|
||
if(CheckLocalFlags(FLAG_BIT_PARTICLE_NOISE_CHORATICABERRAT_WITH_NOISE))
|
||
{
|
||
half2 NoiseIntensity = uvAfterNoise - originUV;
|
||
// half noiseXIntensity = abs(NoiseIntensity.x);
|
||
// delta *= ChoraticaberratIntensity*noiseXIntensity;
|
||
delta = NoiseIntensity*ChoraticaberratIntensity*10;
|
||
}
|
||
else
|
||
{
|
||
delta *= ChoraticaberratIntensity;
|
||
}
|
||
|
||
half2 ra = SampleTexture2DWithWrapFlags(baseTexture,uvAfterNoise,bits).xw;
|
||
ra.r *= ra.y;
|
||
half2 ga = SampleTexture2DWithWrapFlags(baseTexture,uvAfterNoise - delta,bits).yw;
|
||
ga.r *= ga.y;
|
||
half2 ba = SampleTexture2DWithWrapFlags(baseTexture,uvAfterNoise - delta*2,bits).zw;
|
||
ba.r *= ba.y;
|
||
return half4(ra.r,ga.r,ba.r,clamp(ra.y*0.5+ga.y*0.5+ba.y*0.5,0,1));
|
||
}
|
||
#endif
|
||
|
||
bool needSceneDepth()
|
||
{
|
||
#if defined(_DEPTH_DECAL) || defined(_SOFTPARTICLES_ON) || defined(_DEPTH_OUTLINE)
|
||
return true;
|
||
#endif
|
||
|
||
return false;
|
||
}
|
||
|
||
bool needEyeDepth()
|
||
{
|
||
#if defined(_SOFTPARTICLES_ON) || defined(_DEPTH_OUTLINE) || defined(_DISTANCE_FADE)
|
||
return true;
|
||
#endif
|
||
|
||
return false;
|
||
}
|
||
|
||
bool needPositionVS()
|
||
{
|
||
#if defined(_MATCAP)
|
||
return true;
|
||
#endif
|
||
|
||
if (unity_OrthoParams.w == 1)
|
||
{
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
bool ignoreFresnel()
|
||
{
|
||
#if defined(PARTICLE_BACKFACE_PASS)
|
||
return true;
|
||
#endif
|
||
return false;
|
||
}
|
||
|
||
float3 CustomRefract(float3 incident, float3 normal, float eta)
|
||
{
|
||
float N_dot_I = dot(normal, incident);
|
||
float k = 1.0f - eta * eta * (1.0f - N_dot_I * N_dot_I);
|
||
|
||
// 检查全内反射
|
||
if (k < 0.0)
|
||
{
|
||
// 全内反射时返回零向量
|
||
return float3(0, 0, 0);
|
||
}
|
||
else
|
||
{
|
||
// 计算折射方向
|
||
return eta * incident - (eta * N_dot_I + sqrt(k)) * normal;
|
||
}
|
||
}
|
||
|
||
Texture2D _ParallaxMapping_Map;
|
||
|
||
half2 ParallaxMappingSimple(half2 texCoords, half3 viewDir)
|
||
{
|
||
float height = SampleTexture2DWithWrapFlags(_ParallaxMapping_Map,texCoords,FLAG_BIT_WRAPMODE_PARALLAXMAPPINGMAP).r;
|
||
height *= _ParallaxMapping_Intensity;
|
||
viewDir = normalize(viewDir);
|
||
viewDir.xy /= (viewDir.z);
|
||
texCoords -= viewDir.xy * height;
|
||
return texCoords;
|
||
}
|
||
|
||
half2 ParallaxMappingPeelDepth(half2 texCoords, half3 viewDir)
|
||
{
|
||
const float minLayers = 2;
|
||
const float maxLayers = 32;
|
||
float numLayers = lerp(maxLayers, minLayers, abs(dot(half3(0.0, 0.0, 1.0), viewDir)));//视线越垂直于表面,层数越少,反之越多。
|
||
float layerDepth = 1/numLayers;
|
||
float currentLayerDepth = 0;
|
||
// viewDir.xy/=viewDir.z;
|
||
half2 p = viewDir.xy*_ParallaxMapping_Intensity;
|
||
half2 deltaTexcoord = p/numLayers;
|
||
|
||
half2 currentTexcoords = texCoords;
|
||
float currentMapDepthValue = SampleTexture2DWithWrapFlags(_ParallaxMapping_Map,currentTexcoords,FLAG_BIT_WRAPMODE_PARALLAXMAPPINGMAP).r;
|
||
|
||
[loop]
|
||
while (currentLayerDepth < currentMapDepthValue )
|
||
{
|
||
currentTexcoords -= deltaTexcoord;
|
||
currentMapDepthValue = SampleTexture2DWithWrapFlags(_ParallaxMapping_Map,currentTexcoords,FLAG_BIT_WRAPMODE_PARALLAXMAPPINGMAP).r;
|
||
currentLayerDepth += layerDepth;
|
||
}
|
||
|
||
return currentTexcoords;
|
||
|
||
}
|
||
float2 ParallaxOcclusionMapping(float2 texCoords, float3 viewDir)
|
||
{
|
||
texCoords = texCoords * _ParallaxMapping_Map_ST + _ParallaxMapping_Map_ST.zw;
|
||
// number of depth layers
|
||
// const float minLayers = 10;
|
||
// const float maxLayers = 10;
|
||
const float minLayers = _ParallaxMapping_Vec.x;
|
||
const float maxLayers = _ParallaxMapping_Vec.y;
|
||
float numLayers = lerp(maxLayers, minLayers, abs(dot(half3(0.0, 0.0, 1.0), viewDir)));
|
||
// calculate the size of each layer
|
||
float layerDepth = 1.0 / numLayers;
|
||
// depth of current layer
|
||
float currentLayerDepth = 0.0;
|
||
// the amount to shift the texture coordinates per layer (from vector P)
|
||
float2 P = viewDir.xy / viewDir.z * _ParallaxMapping_Intensity;
|
||
float2 deltaTexCoords = P / numLayers;
|
||
|
||
// get initial values
|
||
float2 currentTexCoords = texCoords;
|
||
float currentDepthMapValue = SampleTexture2DWithWrapFlags(_ParallaxMapping_Map, currentTexCoords,FLAG_BIT_WRAPMODE_PARALLAXMAPPINGMAP).r;
|
||
currentLayerDepth = clamp(currentLayerDepth,0,1);
|
||
|
||
int i = 0;
|
||
[loop]
|
||
while(currentLayerDepth < currentDepthMapValue && i<numLayers)
|
||
{
|
||
// shift texture coordinates along direction of P
|
||
currentTexCoords -= deltaTexCoords;
|
||
// get depthmap value at current texture coordinates
|
||
currentDepthMapValue = SampleTexture2DWithWrapFlags(_ParallaxMapping_Map, currentTexCoords,FLAG_BIT_WRAPMODE_PARALLAXMAPPINGMAP).r;
|
||
// get depth of next layer
|
||
currentLayerDepth += layerDepth;
|
||
i++;
|
||
}
|
||
|
||
// -- parallax occlusion mapping interpolation from here on
|
||
// get texture coordinates before collision (reverse operations)
|
||
float2 prevTexCoords = currentTexCoords + deltaTexCoords;
|
||
|
||
// get depth after and before collision for linear interpolation
|
||
float afterDepth = currentDepthMapValue - currentLayerDepth;
|
||
float beforeDepth = SampleTexture2DWithWrapFlags(_ParallaxMapping_Map, prevTexCoords,FLAG_BIT_WRAPMODE_PARALLAXMAPPINGMAP).r - currentLayerDepth + layerDepth;
|
||
|
||
// interpolation of texture coordinates
|
||
float weight = afterDepth / (afterDepth - beforeDepth);
|
||
float2 finalTexCoords = prevTexCoords * weight + currentTexCoords * (1.0 - weight);
|
||
|
||
return finalTexCoords;
|
||
}
|
||
|
||
//--------------MatCap------------------
|
||
|
||
//-
|
||
|
||
struct AttributesParticle//即URP语境下的appdata
|
||
{
|
||
float4 vertex: POSITION;
|
||
float3 normalOS: NORMAL;
|
||
half4 color: COLOR;
|
||
#if defined(_FLIPBOOKBLENDING_ON)
|
||
float4 texcoords: TEXCOORD0; //texcoords.zw就是粒子那边新建的UV2
|
||
float3 texcoordBlend: TEXCOORD3;//注意,假如需要UI支持,則Canvas要開放相關Channel
|
||
#else
|
||
float4 texcoords: TEXCOORD0;
|
||
float2 vatTexcoord4: TEXCOORD3;
|
||
#endif
|
||
|
||
#if defined(_PARALLAX_MAPPING) || defined(_NORMALMAP) || defined(_FX_LIGHT_MODE_SIX_WAY)
|
||
float4 tangentOS : TANGENT;
|
||
#endif
|
||
|
||
float4 Custom1: TEXCOORD1;
|
||
float4 Custom2: TEXCOORD2;
|
||
float2 vatTexcoord5: TEXCOORD4;
|
||
float2 vatTexcoord6: TEXCOORD5;
|
||
float2 vatTexcoord7: TEXCOORD6;
|
||
float2 vatTexcoord8: TEXCOORD7;
|
||
|
||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||
};
|
||
|
||
struct VaryingsParticle//即URP语境下的v2f
|
||
{
|
||
float4 clipPos: SV_POSITION;
|
||
|
||
half4 color: COLOR;
|
||
float4 texcoord: TEXCOORD0; // 主帖图 和 mask
|
||
|
||
#if defined (_EMISSION) || defined(_COLORMAPBLEND)
|
||
float4 emissionColorBlendTexcoord: TEXCOORD1; // 流光
|
||
#endif
|
||
|
||
#ifdef _NOISEMAP
|
||
float4 noisemapTexcoord:TEXCOORD2;//Noise
|
||
#endif
|
||
|
||
#if defined(_DISSOLVE)
|
||
|
||
float4 dissolveTexcoord:TEXCOORD15;
|
||
|
||
#endif
|
||
#ifdef _PROGRAM_NOISE_ACTIVE
|
||
float4 dissolveNoiseTexcoord: TEXCOORD5;
|
||
#endif
|
||
|
||
|
||
float4 positionWS: TEXCOORD3;
|
||
float4 positionOS: TEXCOORD12;
|
||
|
||
float4 texcoord2AndSpecialUV: TEXCOORD6; // UV2和SpecialUV
|
||
|
||
float4 positionNDC: TEXCOORD7;
|
||
|
||
|
||
float4 VaryingsP_Custom1: TEXCOORD8;
|
||
float4 VaryingsP_Custom2: TEXCOORD9;
|
||
|
||
|
||
float4 normalWSAndAnimBlend: TEXCOORD10;
|
||
|
||
// float3 fresnelViewDir :TEXCOORD11;
|
||
|
||
// float3 viewDirWS :TEXCOORD13;
|
||
#if defined(_MASKMAP2_ON) || defined(_MASKMAP3_ON)
|
||
float4 texcoordMaskMap2 : TEXCOORD14;
|
||
#endif
|
||
|
||
#ifndef _FX_LIGHT_MODE_UNLIT
|
||
#if !defined(_FX_LIGHT_MODE_SIX_WAY)
|
||
half3 vertexSH :TEXCOORD17;
|
||
#endif
|
||
#ifdef _ADDITIONAL_LIGHTS_VERTEX
|
||
half3 vertexLight :TEXCOORD18;
|
||
#endif
|
||
#endif
|
||
|
||
#if (defined(_PARALLAX_MAPPING) || defined(_NORMALMAP)) && !defined(_FX_LIGHT_MODE_SIX_WAY)
|
||
half4 tangentWS : TEXCOORD19;
|
||
#endif
|
||
#if defined (_NORMALMAP) || defined(_COLOR_RAMP)
|
||
float4 bumpTexAndColorRampMapTexcoord : TEXCOORD20;
|
||
#endif
|
||
|
||
#ifdef _FX_LIGHT_MODE_SIX_WAY
|
||
half4 bakeDiffuseLighting0 :TEXCOORD21;
|
||
half4 bakeDiffuseLighting1 :TEXCOORD22;
|
||
half4 bakeDiffuseLighting2 :TEXCOORD23;
|
||
half4 backBakeDiffuseLighting0 :TEXCOORD24;
|
||
half4 backBakeDiffuseLighting1 :TEXCOORD25;
|
||
half4 backBakeDiffuseLighting2 :TEXCOORD26;
|
||
#endif
|
||
|
||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||
UNITY_VERTEX_OUTPUT_STEREO
|
||
};
|
||
|
||
bool isProcessUVInFrag()
|
||
{
|
||
if(CheckLocalFlags(FLAG_BIT_PARTICLE_POLARCOORDINATES_ON) || CheckLocalFlags(FLAG_BIT_PARTICLE_UTWIRL_ON))
|
||
{
|
||
return true;
|
||
}
|
||
#if defined(_DEPTH_DECAL) || defined(_PARALLAX_MAPPING) || defined(_SCREEN_DISTORT_MODE) || defined(_CAMERA_OPAQUE_DISTORT_PASS)
|
||
return true;
|
||
#endif
|
||
return false;
|
||
}
|
||
|
||
#ifndef _FX_LIGHT_MODE_UNLIT
|
||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||
|
||
|
||
|
||
void InitializeInputData(VaryingsParticle input,half3x3 tangentToWorld, half3 viewDirWS, out InputData inputData)
|
||
{
|
||
inputData = (InputData)0;
|
||
|
||
#if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
|
||
inputData.positionWS = input.positionWS;
|
||
#endif
|
||
//Normal转到外面执行
|
||
// half3 viewDirWS = GetWorldSpaceNormalizeViewDir(input.positionWS);
|
||
// #if defined(_NORMALMAP) || defined(_DETAIL)
|
||
// float sgn = input.tangentWS.w; // should be either +1 or -1
|
||
// float3 bitangent = sgn * cross(input.normalWSAndAnimBlend.xyz, input.tangentWS.xyz);
|
||
// half3x3 tangentToWorld = half3x3(input.tangentWS.xyz, bitangent.xyz, input.normalWSAndAnimBlend.xyz);
|
||
//
|
||
// #if defined(_NORMALMAP)
|
||
// inputData.tangentToWorld = tangentToWorld;
|
||
// #endif
|
||
// inputData.normalWS = TransformTangentToWorld(normalTS, tangentToWorld);
|
||
// #else
|
||
// inputData.normalWS = input.normalWSAndAnimBlend.xyz;
|
||
// #endif
|
||
//
|
||
// inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
|
||
inputData.tangentToWorld = tangentToWorld;
|
||
inputData.normalWS = input.normalWSAndAnimBlend.xyz;
|
||
inputData.viewDirectionWS = viewDirWS;
|
||
|
||
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
|
||
inputData.shadowCoord = input.shadowCoord;
|
||
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
|
||
inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
|
||
#else
|
||
inputData.shadowCoord = float4(0, 0, 0, 0);
|
||
#endif
|
||
#ifdef _ADDITIONAL_LIGHTS_VERTEX
|
||
inputData.fogCoord = InitializeInputDataFog(float4(input.positionWS, 1.0), input.fogFactorAndVertexLight.x);
|
||
inputData.vertexLighting = input.fogFactorAndVertexLight.yzw;
|
||
#else
|
||
inputData.fogCoord = InitializeInputDataFog(float4(input.positionWS.xyz, 1.0), input.positionWS.w);
|
||
#endif
|
||
|
||
// #if defined(DYNAMICLIGHTMAP_ON)
|
||
// inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV, input.vertexSH, inputData.normalWS);
|
||
// #else
|
||
// inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.vertexSH, inputData.normalWS);
|
||
// #endif
|
||
|
||
#if defined(_FX_LIGHT_MODE_SIX_WAY)
|
||
inputData.bakedGI = 0;
|
||
#else
|
||
inputData.bakedGI = SampleSHPixel(input.vertexSH, inputData.normalWS);
|
||
#endif
|
||
|
||
inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.clipPos);
|
||
inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV);
|
||
|
||
#if defined(DEBUG_DISPLAY)
|
||
#if defined(DYNAMICLIGHTMAP_ON)
|
||
inputData.dynamicLightmapUV = input.dynamicLightmapUV;
|
||
#endif
|
||
#if defined(LIGHTMAP_ON)
|
||
inputData.staticLightmapUV = input.staticLightmapUV;
|
||
#else
|
||
#if !defined(_FX_LIGHT_MODE_SIX_WAY)
|
||
inputData.vertexSH = input.vertexSH;
|
||
#endif
|
||
#endif
|
||
#endif
|
||
}
|
||
#endif
|
||
|
||
|
||
int2 GetGradientIndex(half timeArr[6], int arrCount, half gradientTime)
|
||
{
|
||
|
||
// // 边界情况处理
|
||
// if (gradientTime < timeArr[0]) {
|
||
// return int2(-1, 0); // 小于最小值
|
||
// }
|
||
// if (gradientTime >= timeArr[arrCount - 1]) {
|
||
// return int2(arrCount - 1, arrCount); // 大于等于最大值
|
||
// }
|
||
|
||
// 顺序查找第一个大于X的元素索引
|
||
[unroll]
|
||
for (int i = 0; i < arrCount; i++) {
|
||
if (timeArr[i] > gradientTime) {
|
||
return int2(i - 1, i); // 返回区间索引
|
||
}
|
||
}
|
||
return int2(-1, 0); // 理论上不会执行此处
|
||
}
|
||
half GetGradientIndexInterval(half timeArr[6],int arrCount,int2 indexes,half gradientTime)
|
||
{
|
||
//超出范围的直接在外面就判断好。
|
||
// half smallVal = indexes.x < 0 ? 0:timeArr[indexes.x];
|
||
half smallVal = timeArr[indexes.x];
|
||
// half bigVal = indexes.y >= arrCount ? 1 : timeArr[indexes.y];
|
||
half bigVal = timeArr[indexes.y];
|
||
return (gradientTime - smallVal) / (bigVal - smallVal);
|
||
}
|
||
|
||
half3 GetGradientColorValue(half3 colorArr[6],half timeArr[6], int arrCount,half gradientTime)
|
||
{
|
||
if (gradientTime <= timeArr[0])
|
||
{
|
||
return colorArr[0];
|
||
}
|
||
else if (gradientTime >= timeArr[arrCount - 1] )
|
||
{
|
||
return colorArr[arrCount - 1];
|
||
}
|
||
else
|
||
{
|
||
int2 indexes = GetGradientIndex(timeArr, arrCount, gradientTime);
|
||
half interval = GetGradientIndexInterval(timeArr, arrCount, indexes, gradientTime);
|
||
interval = SmoothStep01(interval);
|
||
return lerp(colorArr[indexes.x], colorArr[indexes.y], interval);
|
||
}
|
||
}
|
||
|
||
half GetGradientAlphaValue(half alphaArr[6],half timeArr[6], int arrCount,half gradientTime)
|
||
{
|
||
if (gradientTime <= timeArr[0])
|
||
{
|
||
return alphaArr[0];
|
||
}
|
||
else if (gradientTime >= timeArr[arrCount - 1] )
|
||
{
|
||
return alphaArr[arrCount - 1];
|
||
}
|
||
else
|
||
{
|
||
int2 indexes = GetGradientIndex(timeArr, arrCount, gradientTime);
|
||
half interval = GetGradientIndexInterval(timeArr, arrCount, indexes, gradientTime);
|
||
interval = SmoothStep01(interval);//TODO:消耗很大,如何避免?
|
||
half alpha = lerp(alphaArr[indexes.x], alphaArr[indexes.y], interval);
|
||
alpha *= alpha;//Make Alpha Smoother
|
||
return alpha ;
|
||
}
|
||
}
|
||
|
||
half3 GetPackedGradientColorKey(half4 key0, half4 key1, half4 key2, half4 key3, half4 key4, half4 key5, int index)
|
||
{
|
||
if (index <= 0) return key0.rgb;
|
||
if (index == 1) return key1.rgb;
|
||
if (index == 2) return key2.rgb;
|
||
if (index == 3) return key3.rgb;
|
||
if (index == 4) return key4.rgb;
|
||
return key5.rgb;
|
||
}
|
||
|
||
half GetPackedGradientColorTime(half4 key0, half4 key1, half4 key2, half4 key3, half4 key4, half4 key5, int index)
|
||
{
|
||
if (index <= 0) return key0.a;
|
||
if (index == 1) return key1.a;
|
||
if (index == 2) return key2.a;
|
||
if (index == 3) return key3.a;
|
||
if (index == 4) return key4.a;
|
||
return key5.a;
|
||
}
|
||
|
||
half GetPackedGradientAlphaKey(half4 pack0, half4 pack1, half4 pack2, int index)
|
||
{
|
||
if (index <= 0) return pack0.x;
|
||
if (index == 1) return pack0.z;
|
||
if (index == 2) return pack1.x;
|
||
if (index == 3) return pack1.z;
|
||
if (index == 4) return pack2.x;
|
||
return pack2.z;
|
||
}
|
||
|
||
half GetPackedGradientAlphaTime(half4 pack0, half4 pack1, half4 pack2, int index)
|
||
{
|
||
if (index <= 0) return pack0.y;
|
||
if (index == 1) return pack0.w;
|
||
if (index == 2) return pack1.y;
|
||
if (index == 3) return pack1.w;
|
||
if (index == 4) return pack2.y;
|
||
return pack2.w;
|
||
}
|
||
|
||
int2 GetPackedGradientColorIndex(half4 key0, half4 key1, half4 key2, half4 key3, half4 key4, half4 key5, int arrCount, half gradientTime)
|
||
{
|
||
int2 indexes = int2(-1, 0);
|
||
bool found = false;
|
||
[unroll]
|
||
for (int i = 0; i < 6; i++)
|
||
{
|
||
if (!found && i < arrCount && GetPackedGradientColorTime(key0, key1, key2, key3, key4, key5, i) > gradientTime)
|
||
{
|
||
indexes = int2(i - 1, i);
|
||
found = true;
|
||
}
|
||
}
|
||
return indexes;
|
||
}
|
||
|
||
int2 GetPackedGradientAlphaIndex(half4 pack0, half4 pack1, half4 pack2, int arrCount, half gradientTime)
|
||
{
|
||
int2 indexes = int2(-1, 0);
|
||
bool found = false;
|
||
[unroll]
|
||
for (int i = 0; i < 6; i++)
|
||
{
|
||
if (!found && i < arrCount && GetPackedGradientAlphaTime(pack0, pack1, pack2, i) > gradientTime)
|
||
{
|
||
indexes = int2(i - 1, i);
|
||
found = true;
|
||
}
|
||
}
|
||
return indexes;
|
||
}
|
||
|
||
half3 SamplePackedGradientColor(half4 key0, half4 key1, half4 key2, half4 key3, half4 key4, half4 key5, int arrCount, half gradientTime)
|
||
{
|
||
if (gradientTime <= GetPackedGradientColorTime(key0, key1, key2, key3, key4, key5, 0))
|
||
{
|
||
return GetPackedGradientColorKey(key0, key1, key2, key3, key4, key5, 0);
|
||
}
|
||
else if (gradientTime >= GetPackedGradientColorTime(key0, key1, key2, key3, key4, key5, arrCount - 1))
|
||
{
|
||
return GetPackedGradientColorKey(key0, key1, key2, key3, key4, key5, arrCount - 1);
|
||
}
|
||
else
|
||
{
|
||
int2 indexes = GetPackedGradientColorIndex(key0, key1, key2, key3, key4, key5, arrCount, gradientTime);
|
||
half smallVal = GetPackedGradientColorTime(key0, key1, key2, key3, key4, key5, indexes.x);
|
||
half bigVal = GetPackedGradientColorTime(key0, key1, key2, key3, key4, key5, indexes.y);
|
||
half interval = SmoothStep01((gradientTime - smallVal) / (bigVal - smallVal));
|
||
return lerp(
|
||
GetPackedGradientColorKey(key0, key1, key2, key3, key4, key5, indexes.x),
|
||
GetPackedGradientColorKey(key0, key1, key2, key3, key4, key5, indexes.y),
|
||
interval);
|
||
}
|
||
}
|
||
|
||
half SamplePackedGradientAlpha(half4 pack0, half4 pack1, half4 pack2, int arrCount, half gradientTime)
|
||
{
|
||
if (gradientTime <= GetPackedGradientAlphaTime(pack0, pack1, pack2, 0))
|
||
{
|
||
return GetPackedGradientAlphaKey(pack0, pack1, pack2, 0);
|
||
}
|
||
else if (gradientTime >= GetPackedGradientAlphaTime(pack0, pack1, pack2, arrCount - 1))
|
||
{
|
||
return GetPackedGradientAlphaKey(pack0, pack1, pack2, arrCount - 1);
|
||
}
|
||
else
|
||
{
|
||
int2 indexes = GetPackedGradientAlphaIndex(pack0, pack1, pack2, arrCount, gradientTime);
|
||
half smallVal = GetPackedGradientAlphaTime(pack0, pack1, pack2, indexes.x);
|
||
half bigVal = GetPackedGradientAlphaTime(pack0, pack1, pack2, indexes.y);
|
||
half interval = SmoothStep01((gradientTime - smallVal) / (bigVal - smallVal));
|
||
half alpha = lerp(
|
||
GetPackedGradientAlphaKey(pack0, pack1, pack2, indexes.x),
|
||
GetPackedGradientAlphaKey(pack0, pack1, pack2, indexes.y),
|
||
interval);
|
||
alpha *= alpha;
|
||
return alpha;
|
||
}
|
||
}
|
||
|
||
void ColorAdjustment(inout half3 result,inout half alpha,half4 customData1,half4 customData2)
|
||
{
|
||
UNITY_BRANCH
|
||
if(CheckLocalFlags(FLAG_BIT_HUESHIFT_ON))
|
||
{
|
||
half3 hsv = RgbToHsv(result);
|
||
_HueShift = GetCustomData(_W9ParticleCustomDataFlag0,FLAGBIT_POS_0_CUSTOMDATA_HUESHIFT,_HueShift,customData1,customData2);
|
||
hsv.r += _HueShift;
|
||
result = HsvToRgb(hsv);
|
||
}
|
||
|
||
UNITY_BRANCH
|
||
if (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_MAINTEX_CONTRAST))
|
||
{
|
||
_Contrast = GetCustomData(_W9ParticleCustomDataFlag2,FLAGBIT_POS_2_CUSTOMDATA_MAINTEX_CONTRAST,_Contrast,customData1,customData2);
|
||
result.rgb = lerp(_ContrastMidColor,result.rgb,_Contrast);
|
||
}
|
||
|
||
UNITY_BRANCH
|
||
if(CheckLocalFlags(FLAG_BIT_SATURABILITY_ON))
|
||
{
|
||
half3 resultWB = luminance(result);
|
||
_Saturability = GetCustomData(_W9ParticleCustomDataFlag1,FLAGBIT_POS_1_CUSTOMDATA_SATURATE,_Saturability,customData1,customData2);
|
||
result.rgb = lerp(resultWB.rgb, result.rgb, _Saturability);
|
||
}
|
||
|
||
|
||
|
||
if (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_MAINTEX_COLOR_REFINE))
|
||
{
|
||
half3 colorA = result.rgb*_BaseMapColorRefine.x;
|
||
half3 colorB = pow(result.rgb,_BaseMapColorRefine.y)*_BaseMapColorRefine.z;
|
||
result.rgb = lerp(colorA,colorB,_BaseMapColorRefine.w);
|
||
}
|
||
|
||
if (CheckLocalFlags(FLAG_BIT_PARTICLE_COLOR_MULTI_ALPHA))
|
||
{
|
||
result.rgb *= alpha;
|
||
}
|
||
|
||
|
||
}
|
||
|
||
#endif
|