Files
ichni_Official/Packages/NBShaders/Shader/HLSL/ParticlesUnlitInputNew.hlsl
SoulliesOfficial 4031b29245 111
2025-08-27 21:45:18 -04:00

1346 lines
47 KiB
HLSL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef PARTICLESUNLITINPUT
#define PARTICLESUNLITINPUT
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
//---------------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 _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 _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;
half4 _DissolveLineColor;
half4 _DissolveRampColor;
float4 _DissolveVoronoi_Vec;
half4 _DissolveVoronoi_Vec2;
float4 _DissolveVoronoi_Vec3;
float4 _DissolveVoronoi_Vec4;
half4 _DissolveRampMap_ST;
half4 _Dissolve_Vec2;
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;
half _ParallaxMapping_Intensity;
half4 _ParallaxMapping_Map_ST;
half4 _ParallaxMapping_Vec;
uint _W9ParticleShaderFlags;
uint _W9ParticleShaderFlags1;
uint _W9ParticleShaderWrapFlags;
uint _W9ParticleCustomDataFlag0;
uint _W9ParticleCustomDataFlag1;
uint _W9ParticleCustomDataFlag2;
uint _W9ParticleCustomDataFlag3;
uint _UVModeFlag0;
uint _W9ParticleShaderColorChannelFlag;
CBUFFER_END
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;
half4 SampleTexture2DWithWrapFlags(Texture2D tex,float2 uv,uint bits,bool sampleLOD = false,int lod = 0)
{
const int wrapMode = CheckLocalWrapFlags(bits);
switch (wrapMode)
{
case 0:
if (sampleLOD)
{
return SAMPLE_TEXTURE2D_LOD(tex,sampler_linear_repeat,uv,lod);
}
else
{
return tex.Sample(sampler_linear_repeat,uv);
}
break;
case 1:
if (sampleLOD)
{
return SAMPLE_TEXTURE2D_LOD(tex,sampler_linear_clamp,uv,lod);
}
else
{
return tex.Sample(sampler_linear_clamp,uv);
}
break;
case 2:
if (sampleLOD)
{
return SAMPLE_TEXTURE2D_LOD(tex,sampler_linear_RepeatU_ClampV,uv,lod);
}
else
{
return tex.Sample(sampler_linear_RepeatU_ClampV,uv);
}
break;
case 3:
if (sampleLOD)
{
return SAMPLE_TEXTURE2D_LOD(tex,sampler_linear_ClampU_RepeatV,uv,lod);
}
else
{
return tex.Sample(sampler_linear_ClampU_RepeatV,uv);
}
break;
default:
if (sampleLOD)
{
return SAMPLE_TEXTURE2D_LOD(tex,sampler_linear_repeat,uv,lod);
}
else
{
return tex.Sample(sampler_linear_repeat,uv);
}
break;
}
}
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;
}
#include "../HLSL/EffectFlags.hlsl"
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 _SCREEN_DISTORT_MODE
Texture2D _ScreenColorCopy1;
#endif
#ifdef _MATCAP
#endif
Texture2D _MatCapTex;
// 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
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;
};
BaseUVs ProcessBaseUVs(float4 meshTexcoord0, float2 specialUVInTexcoord3,float4 VaryingsP_Custom1,float4 VaryingsP_Custom2,float3 postionOS)
{
//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;
return baseUVs;
}
void ParticleProcessUV(float4 meshTexcoord0, float2 specialUVInTexcoord3,inout ParticleUVs particleUVs,float4 VaryingsP_Custom1,float4 VaryingsP_Custom2,float2 screenUV,float3 postionOS)
{
BaseUVs baseUVs= ProcessBaseUVs(meshTexcoord0,specialUVInTexcoord3,VaryingsP_Custom1,VaryingsP_Custom2,postionOS);
particleUVs.specUV = baseUVs.specialUVChannel;
float2 baseMapUV = GetUVByUVMode(_UVModeFlag0,FLAG_BIT_UVMODE_POS_0_MAINTEX,baseUVs);
#ifdef _FLIPBOOKBLENDING_ON //开启序列帧融合
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_ANIMATION_SHEET_HELPER))
{
//走AnimationSheetHelper脚本的情况永远和baseMap同步。
particleUVs.animBlendUV = baseMapUV*_BaseMap_AnimationSheetBlend_ST.xy+_BaseMap_AnimationSheetBlend_ST.zw;
}
else
{
//走粒子的情况
particleUVs.animBlendUV = meshTexcoord0.zw;
}
#endif
#ifdef _SCREEN_DISTORT_MODE
particleUVs.mainTexUV = screenUV;
#else
_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;//精灵主贴图不调整。
particleUVs.mainTexUV = originUV*_UI_MainTex_ST.xy+_UI_MainTex_ST.zw;
}
else
{
particleUVs.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);
particleUVs.mainTexUV = TRANSFORM_TEX(baseMapUV, _BaseMap); //主帖图UV重复和偏移
}
particleUVs.mainTexUV = UVOffsetAnimaiton(particleUVs.mainTexUV,_BaseMapMaskMapOffset.xy);
#endif
#if defined(_NORMALMAP)
if (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_BUMP_TEX_UV_FOLLOW_MAINTEX))
{
particleUVs.bumpTexUV = particleUVs.mainTexUV;
}
else
{
float2 bumpTexUV = GetUVByUVMode(_UVModeFlag0,FLAG_BIT_UVMODE_POS_0_BUMPTEX,baseUVs);
bumpTexUV = TRANSFORM_TEX(bumpTexUV, _BumpTex);
particleUVs.bumpTexUV = bumpTexUV;
}
#endif
#if defined(_MASKMAP_ON)
float2 MaskMapuv = GetUVByUVMode(_UVModeFlag0,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;
UNITY_BRANCH
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_MASK_MAP2))
{
float2 maskMap2UV = GetUVByUVMode(_UVModeFlag0,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;
}
UNITY_BRANCH
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_MASK_MAP3))
{
float2 maskMap3UV = GetUVByUVMode(_UVModeFlag0,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
#if defined(_EMISSION)
if (CheckLocalFlags(FLAG_BIT_PARTICLE_EMISSION_FOLLOW_MAINTEX_UV))
{
particleUVs.emissionUV = particleUVs.mainTexUV;
}
else
{
float2 emissionUV = GetUVByUVMode(_UVModeFlag0,FLAG_BIT_UVMODE_POS_0_EMISSION_MAP,baseUVs);
particleUVs.emissionUV = ParticleUVCommonProcess(emissionUV,_EmissionMap_ST,_EmissionMapUVOffset.xy,_EmissionMapUVRotation);
}
#endif
#if defined(_DISSOLVE)
// if(CheckLocalFlags1(FLAG_BIT_PARTICLE_CUSTOMDATA1X_DISSOLVETEXOFFSETX))
// {
// _DissolveMap_ST.z += VaryingsP_Custom1.x;
// }
// if(CheckLocalFlags1(FLAG_BIT_PARTICLE_CUSTOMDATA1Y_DISSOLVETEXOFFSETY))
// {
// _DissolveMap_ST.w += VaryingsP_Custom1.y;
// }
_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,FLAG_BIT_UVMODE_POS_0_DISSOLVE_MAP,baseUVs);
particleUVs.dissolve_uv = ParticleUVCommonProcess(dissolveUV,_DissolveMap_ST,_DissolveOffsetRotateDistort.xy,_DissolveOffsetRotateDistort.z);
if(CheckLocalFlags(FLAG_BIT_PARTICLE_DISSOLVE_MASK))
{
float2 dissolveMaskUV = GetUVByUVMode(_UVModeFlag0,FLAG_BIT_UVMODE_POS_0_DISSOLVE_MASK_MAP,baseUVs);
particleUVs.dissolve_mask_uv = ParticleUVCommonProcess(dissolveMaskUV,_DissolveMaskMap_ST,float2(0,0),_DissolveOffsetRotateDistort.z);
}
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_DISSOVLE_VORONOI))
{
float2 halfUV = dissolveUV;
// halfUV.x = abs(halfUV.x-0.5);//20240729不明白当时为什么要做这个ABS处理。先注销掉看看。
_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);
_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_noise1_UV = halfUV * _DissolveVoronoi_Vec.xy + _DissolveVoronoi_Vec4.xy + time*_DissolveVoronoi_Vec3.xy;
particleUVs.dissolve_noise2_UV = halfUV * _DissolveVoronoi_Vec.zw + _DissolveVoronoi_Vec4.zw + time*_DissolveVoronoi_Vec3.zw;
}
#endif
#ifdef _COLORMAPBLEND
if (CheckLocalFlags(FLAG_BIT_PARTICLE_COLOR_BLEND_FOLLOW_MAINTEX_UV))
{
particleUVs.colorBlendUV = particleUVs.mainTexUV;
}
else
{
float2 colorBlendUV = GetUVByUVMode(_UVModeFlag0,FLAG_BIT_UVMODE_POS_0_COLOR_BLEND_MAP,baseUVs);
particleUVs.colorBlendUV = ParticleUVCommonProcess(colorBlendUV,_ColorBlendMap_ST,_ColorBlendMapOffset.xy,_ColorBlendVec.w);
}
#endif
#ifdef _COLOR_RAMP
float2 colorRampMapUV = GetUVByUVMode(_UVModeFlag0,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,FLAG_BIT_UVMODE_POS_0_NOISE_MAP,baseUVs);
particleUVs.noiseMapUV = ParticleUVCommonProcess(noiseMapUV,_NoiseMap_ST,half2(0,0),_NoiseMapUVRotation);
UNITY_BRANCH
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_NOISE_MASKMAP))
{
float2 noiseMaskMapUV = GetUVByUVMode(_UVModeFlag0,FLAG_BIT_UVMODE_POS_0_NOISE_MASK_MAP,baseUVs);
particleUVs.noiseMaskMapUV = ParticleUVCommonProcess(noiseMaskMapUV,_NoiseMaskMap_ST,half2(0,0),0);
}
#endif
}
Texture2D _VertexOffset_Map;
Texture2D _VertexOffset_MaskMap;
// half3 _VertexOffset_Vec;
// half3 _VertexOffset_CustomDir;
// half4 _VertexOffset_Map_ST;
half3 VetexOffset(half3 positionOS,half2 originUV,half2 originMaskUV,half3 normalOS)
{
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_VERTEXOFFSET_MASKMAP,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;
}
half3 finalPos;
half vertexOffsetMask = 1;
if (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_VERTEXOFFSET_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);
}
UNITY_BRANCH
if(CheckLocalFlags(FLAG_BIT_PARTICLE_VERTEX_OFFSET_NORMAL_DIR))
{
finalPos = positionOS + normalOS*_VertexOffset_Vec.z*vertexOffsetSample*vertexOffsetMask;
}
else
{
finalPos = positionOS + _VertexOffset_CustomDir*_VertexOffset_Vec.z*vertexOffsetSample*vertexOffsetMask;
}
return finalPos;
}
//向UV横向两边的色散。
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;
}
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));
}
bool needSceneDepth()
{
#if defined(_DEPTH_DECAL) || defined(_SOFTPARTICLES_ON)
return true;
#endif
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_DEPTH_OUTLINE))
{
return true;
}
return false;
}
bool needEyeDepth()
{
#if defined(_SOFTPARTICLES_ON)
return true;
#endif
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_DEPTH_OUTLINE)||CheckLocalFlags(FLAG_BIT_PARTICLE_DISTANCEFADE_ON))
{
return true;
}
return false;
}
bool ignoreFresnel()
{
#if defined(PARTICLE_BACKFACE_PASS)
return true;
#endif
return false;
}
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;
}
half2 ParallaxOcclusionMapping(half2 texCoords, half3 viewDir)
{
// 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)
half2 P = viewDir.xy / viewDir.z * _ParallaxMapping_Intensity;
half2 deltaTexCoords = P / numLayers;
// get initial values
half2 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)
half2 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);
half2 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;
#endif
#if defined(_PARALLAX_MAPPING) || defined(_NORMALMAP) || defined(_FX_LIGHT_MODE_SIX_WAY)
float4 tangentOS : TANGENT;
#endif
float4 Custom1: TEXCOORD1;
float4 Custom2: TEXCOORD2;
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;
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;
float4 texcoordMaskMap2 : TEXCOORD14;
#ifdef _PARALLAX_MAPPING
half3 tangentViewDir : TEXCOORD16;
#endif
#ifndef _FX_LIGHT_MODE_UNLIT
half3 vertexSH :TEXCOORD17;
#ifdef _ADDITIONAL_LIGHTS_VERTEX
half3 vertexLight :TEXCOORD18;
#endif
#endif
#if defined(_NORMALMAP) || defined(_FX_LIGHT_MODE_SIX_WAY)
half4 tangentWS : TEXCOOR19;
#endif
#if defined (_NORMALMAP) || defined(_COLOR_RAMP)
float4 bumpTexAndColorRampMapTexcoord : TEXCOOR20;
#endif
#ifdef _FX_LIGHT_MODE_SIX_WAY
half3 bakeDiffuseLighting0 :TEXCOOR21;
half3 bakeDiffuseLighting1 :TEXCOOR22;
half3 bakeDiffuseLighting2 :TEXCOOR23;
half3 backBakeDiffuseLighting0 :TEXCOOR24;
half3 backBakeDiffuseLighting1 :TEXCOOR25;
half3 backBakeDiffuseLighting2 :TEXCOOR26;
#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)
return true;
#endif
return false;
}
#ifndef _FX_LIGHT_MODE_UNLIT
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
void InitializeInputData(VaryingsParticle input, half3 normalTS, out InputData inputData)
{
inputData = (InputData)0;
#if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
inputData.positionWS = input.positionWS;
#endif
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.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
inputData.bakedGI = SampleSHPixel(input.vertexSH, inputData.normalWS);
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
inputData.vertexSH = input.vertexSH;
#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)
{
int2 indexes = GetGradientIndex(timeArr, arrCount, gradientTime);
if (indexes.x < 0) return colorArr[0];
if (indexes.y >= arrCount ) return colorArr[arrCount - 1];
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)
{
int2 indexes = GetGradientIndex(timeArr, arrCount, gradientTime);
if (indexes.x < 0) return alphaArr[0];
if (indexes.y >= arrCount ) return alphaArr[arrCount - 1];
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 ;
}
#endif