Files
ichni_Official/Packages/NBShaders/Shader/HLSL/ParticlesUnlitForwardPassNew.hlsl

1039 lines
44 KiB
HLSL
Raw Normal View History

2025-07-21 05:42:20 -04:00
#ifndef PARTICLESUNLITFORWARDPASS
#define PARTICLESUNLITFORWARDPASS
2025-08-27 21:45:18 -04:00
#include "HLSL/ParticlesUnlitInputNew.hlsl"
#include "HLSL/SixWaySmokeLit.hlsl"
2025-07-21 05:42:20 -04:00
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
VaryingsParticle vertParticleUnlit(AttributesParticle input)
{
VaryingsParticle output = (VaryingsParticle)0;
output.VaryingsP_Custom1 = input.Custom1;
output.VaryingsP_Custom2 = input.Custom2;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
time = _Time.y;
float4 positionOS = input.vertex;
if(CheckLocalFlags(FLAG_BIT_PARTICLE_VERTEX_OFFSET_ON))
{
//因为极坐标和旋转会强制到Frag计算所以顶点在这边特殊处理一遍。
BaseUVs baseUVsForVertexOffset = ProcessBaseUVs(input.texcoords,0,output.VaryingsP_Custom1,output.VaryingsP_Custom2,positionOS);
_VertexOffset_Map_ST.z += GetCustomData(_W9ParticleCustomDataFlag1,FLAGBIT_POS_1_CUSTOMDATA_VERTEX_OFFSET_X,0,input.Custom1,input.Custom2);
_VertexOffset_Map_ST.w += GetCustomData(_W9ParticleCustomDataFlag1,FLAGBIT_POS_1_CUSTOMDATA_VERTEX_OFFSET_Y,0,input.Custom1,input.Custom2);
_VertexOffset_Vec.z = GetCustomData(_W9ParticleCustomDataFlag1,FLAGBIT_POS_1_CUSTOMDATA_VERTEXOFFSET_INTENSITY,_VertexOffset_Vec.z,input.Custom1,input.Custom2);
if (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_VERTEXOFFSET_MASKMAP))
{
_VertexOffset_MaskMap_ST.z += GetCustomData(_W9ParticleCustomDataFlag3,FLAGBIT_POS_3_CUSTOMDATA_VERTEX_OFFSET_MASK_X,0,input.Custom1,input.Custom2);
_VertexOffset_MaskMap_ST.w += GetCustomData(_W9ParticleCustomDataFlag3,FLAGBIT_POS_3_CUSTOMDATA_VERTEX_OFFSET_MASK_Y,0,input.Custom1,input.Custom2);
}
float2 vertexOffsetUVs = GetUVByUVMode(_UVModeFlag0,FLAG_BIT_UVMODE_POS_0_VERTEX_OFFSET_MAP,baseUVsForVertexOffset);
float2 vertexOffsetMaskUVs = GetUVByUVMode(_UVModeFlag0,FLAG_BIT_UVMODE_POS_0_VERTEX_OFFSET_MASKMAP,baseUVsForVertexOffset);
positionOS.xyz = VetexOffset(positionOS,vertexOffsetUVs,vertexOffsetMaskUVs,input.normalOS);
}
// position ws is used to compute eye depth in vertFading
output.positionWS.xyz = mul(unity_ObjectToWorld, positionOS).xyz;
output.positionOS.xyz = positionOS;
output.clipPos = TransformObjectToHClip(positionOS);
#ifdef _PARALLAX_MAPPING
//视差贴图需要在Tangent空间下计算。
float3x3 objectToTangent =
float3x3(
input.tangentOS.xyz,
cross(input.normalOS,input.tangentOS.xyz) * input.tangentOS.w,//Bitangent
input.normalOS
);
output.tangentViewDir = mul(objectToTangent,GetObjectSpaceNormalizeViewDir(positionOS));
#endif
float unityFogFactor = ComputeFogFactor(output.clipPos.z);
output.positionWS.w = unityFogFactor;
output.color = TryLinearize(input.color);
output.viewDirWS = GetWorldSpaceNormalizeViewDir(output.positionWS.xyz);
output.normalWSAndAnimBlend.xyz = TransformObjectToWorldNormal(input.normalOS.xyz);
2025-08-27 21:45:18 -04:00
#if defined(_NORMALMAP)||defined(_FX_LIGHT_MODE_SIX_WAY)
real sign = input.tangentOS.w * GetOddNegativeScale();
half3 tangentWS = TransformObjectToWorldDir(input.tangentOS.xyz);
output.tangentWS = half4(tangentWS,sign);
#endif
#ifndef _FX_LIGHT_MODE_UNLIT
#ifdef _FX_LIGHT_MODE_SIX_WAY
float3 bitangent = sign * cross(output.normalWSAndAnimBlend.xyz, output.tangentWS.xyz);
// GetSixWayBakeDiffuseLight(output.normalWSAndAnimBlend.xyz,output.tangentWS,bitangent,
// output.bakeDiffuseLighting0,output.bakeDiffuseLighting1,output.bakeDiffuseLighting2,
// output.backBakeDiffuseLighting0,output.backBakeDiffuseLighting1,output.backBakeDiffuseLighting2);
GetSixWayBakeDiffuseLight(output.normalWSAndAnimBlend.xyz,output.tangentWS,bitangent,
output.bakeDiffuseLighting0,output.bakeDiffuseLighting1,output.bakeDiffuseLighting2,
output.backBakeDiffuseLighting0,output.backBakeDiffuseLighting1,output.backBakeDiffuseLighting2);
#else
OUTPUT_SH(output.normalWSAndAnimBlend.xyz, output.vertexSH);
#ifdef _ADDITIONAL_LIGHTS_VERTEX
output.vertexLight = VertexLighting(output.positionWS.xyz, output.normalWSAndAnimBlend.xyz);
#endif
#endif
#endif
2025-07-21 05:42:20 -04:00
UNITY_FLATTEN
if(CheckLocalFlags(FLAG_BIT_PARTICLE_FRESNEL_ON))
{
output.fresnelViewDir = output.viewDirWS;
}
output.texcoord.xy = input.texcoords.xy;
//顶点处理的原则:
//Twirl和极坐标,贴花处理在片段着色器层处理UV。
//BaseMap遮罩MaskNoise高光自发光 和极坐标处理相关。
if(!isProcessUVInFrag())
{
float2 specialUVInTexcoord3 = 0;
//如果同时在粒子系统里开启序列帧融帧和特殊UV通道模式。
#if _FLIPBOOKBLENDING_ON
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_IS_PARTICLE_SYSTEM) & (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_USE_TEXCOORD1)|CheckLocalFlags1(FLAG_BIT_PARTICLE_1_USE_TEXCOORD2)))
{
specialUVInTexcoord3 = input.texcoordBlend.yz;
output.texcoord2AndSpecialUV.zw = specialUVInTexcoord3;
}
#endif
ParticleUVs particleUVs = (ParticleUVs)0;
float2 screenUV = 0;
ParticleProcessUV(input.texcoords, specialUVInTexcoord3,particleUVs,output.VaryingsP_Custom1,output.VaryingsP_Custom2,screenUV,output.positionOS.xyz);
output.texcoord2AndSpecialUV.xy = particleUVs.animBlendUV;
output.texcoord2AndSpecialUV.zw= particleUVs.specUV;
output.texcoord.xy = particleUVs.mainTexUV;
output.texcoord.zw = particleUVs.maskMapUV;
output.texcoordMaskMap2.xy = particleUVs.maskMap2UV;
output.texcoordMaskMap2.zw = particleUVs.maskMap3UV;
2025-08-27 21:45:18 -04:00
#if defined (_NORMALMAP) || defined(_COLOR_RAMP)
output.bumpTexAndColorRampMapTexcoord.xy = particleUVs.bumpTexUV;
output.bumpTexAndColorRampMapTexcoord.zw = particleUVs.colorRampMapUV;
#endif
2025-07-21 05:42:20 -04:00
#if defined (_EMISSION) || defined(_COLORMAPBLEND)
output.emissionColorBlendTexcoord.xy = particleUVs.emissionUV;
output.emissionColorBlendTexcoord.zw = particleUVs.colorBlendUV;
#endif
#ifdef _NOISEMAP
output.noisemapTexcoord.xy = particleUVs.noiseMapUV;
output.noisemapTexcoord.zw = particleUVs.noiseMaskMapUV;
#endif
#if defined(_DISSOLVE)
output.dissolveTexcoord.xy = particleUVs.dissolve_uv;
output.dissolveTexcoord.zw = particleUVs.dissolve_mask_uv;
output.dissolveNoiseTexcoord.xy = particleUVs.dissolve_noise1_UV;
output.dissolveNoiseTexcoord.zw = particleUVs.dissolve_noise2_UV;
#endif
}
else
{
output.texcoord = input.texcoords;
#if _FLIPBOOKBLENDING_ON
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_IS_PARTICLE_SYSTEM) & CheckLocalFlags1(FLAG_BIT_PARTICLE_1_USE_TEXCOORD2))
{
output.texcoord2AndSpecialUV.zw = input.texcoordBlend.yz;
}
#endif
}
#ifdef _FLIPBOOKBLENDING_ON
//粒子帧融合的情况,兼容一下。
output.normalWSAndAnimBlend.w = input.texcoordBlend.x;
#endif
UNITY_BRANCH
if(needEyeDepth())
{
float4 ndc = output.clipPos*0.5f;
output.positionNDC.xy = float2(ndc.x, ndc.y * _ProjectionParams.x) + ndc.w;
output.positionNDC.zw = output.clipPos.zw;
}
return output;
}
///////////////////////Fragment functions ////////////////////////
half4 fragParticleUnlit(VaryingsParticle input, half facing : VFACE): SV_Target
{
input.viewDirWS = normalize(input.viewDirWS );
UNITY_SETUP_INSTANCE_ID(input);
time = _Time.y;
float2 screenUV = input.clipPos.xy / _ScaledScreenParams.xy;
real sceneZBufferDepth = 0;
real sceneZ = 0;
UNITY_BRANCH
if(needSceneDepth())
{
#if UNITY_REVERSED_Z
sceneZBufferDepth = SampleSceneDepth(screenUV);
#else
// Adjust z to match NDC for OpenGL
sceneZBufferDepth = lerp(UNITY_NEAR_CLIP_VALUE, 1, SampleSceneDepth(screenUV));
#endif
sceneZ = (unity_OrthoParams.w == 0) ? LinearEyeDepth(sceneZBufferDepth, _ZBufferParams) : LinearDepthToEyeDepth(sceneZBufferDepth);//场景当前深度
}
real thisZ = 0;
if(needEyeDepth())
{
thisZ = LinearEyeDepth(input.positionNDC.z / input.positionNDC.w, _ZBufferParams);//当前Frag深度。
}
#ifdef _DEPTH_DECAL
float3 fragWorldPos = ComputeWorldSpacePosition(screenUV, sceneZBufferDepth, UNITY_MATRIX_I_VP);
float3 fragobjectPos = TransformWorldToObject(fragWorldPos);
float3 absFragObjectPos = abs(fragobjectPos);
half clipValue = step(absFragObjectPos.x,0.5);
clipValue *= step(absFragObjectPos.y,0.5);
clipValue *= step(absFragObjectPos.z,0.5);
half decalAlpha = NB_Remap (abs(fragobjectPos.y),0.1,0.5,1,0);
decalAlpha *= clipValue;
float2 decalUV = fragobjectPos.xz + 0.5;
#endif
float4 uv = input.texcoord;
#ifdef _DEPTH_DECAL
uv.xy = decalUV;
#endif
float3 blendUv;
blendUv.xy = input.texcoord2AndSpecialUV.xy;
blendUv.z = input.normalWSAndAnimBlend.w;
float2 MaskMapuv;
float2 MaskMapuv2;
float2 MaskMapuv3;
float2 noiseMap_uv;
float2 noiseMaskMap_uv;
float2 colorBlendMap_uv;
float2 emission_uv;
float2 dissolve_uv;
float2 dissolve_mask_uv;
float4 dissolve_noise_uv;
2025-08-27 21:45:18 -04:00
float2 BumpTex_uv;
float2 colorRamp_uv;
2025-07-21 05:42:20 -04:00
//如果同时在粒子系统里开启序列帧融帧和特殊UV通道模式。
if(isProcessUVInFrag())
{
float2 specialUVInTexcoord3 = 0;
#if _FLIPBOOKBLENDING_ON
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_IS_PARTICLE_SYSTEM) & (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_USE_TEXCOORD2)))
{
specialUVInTexcoord3 = input.texcoord2AndSpecialUV.zw;
}
#endif
ParticleUVs particleUVs = (ParticleUVs)0;
ParticleProcessUV(uv,specialUVInTexcoord3,particleUVs,input.VaryingsP_Custom1,input.VaryingsP_Custom2,screenUV,input.positionOS.xyz);
uv.xy = particleUVs.mainTexUV;
blendUv.xy = particleUVs.animBlendUV;
MaskMapuv = particleUVs.maskMapUV;
MaskMapuv2 = particleUVs.maskMap2UV;
MaskMapuv3 = particleUVs.maskMap3UV;
emission_uv = particleUVs.emissionUV;
dissolve_uv = particleUVs.dissolve_uv;
dissolve_mask_uv = particleUVs.dissolve_mask_uv;
colorBlendMap_uv = particleUVs.colorBlendUV;
noiseMap_uv = particleUVs.noiseMapUV;
noiseMaskMap_uv = particleUVs.noiseMaskMapUV;
dissolve_noise_uv = float4(particleUVs.dissolve_noise1_UV,particleUVs.dissolve_noise2_UV);
2025-08-27 21:45:18 -04:00
BumpTex_uv = particleUVs.bumpTexUV;
colorRamp_uv = particleUVs.colorRampMapUV;
2025-07-21 05:42:20 -04:00
}
else
{
MaskMapuv = input.texcoord.zw;
MaskMapuv2 = input.texcoordMaskMap2.xy;
MaskMapuv3 = input.texcoordMaskMap2.zw;
2025-08-27 21:45:18 -04:00
#if defined (_NORMALMAP)||defined(_COLOR_RAMP)
BumpTex_uv = input.bumpTexAndColorRampMapTexcoord.xy;
colorRamp_uv = input.bumpTexAndColorRampMapTexcoord.zw;
#endif
2025-07-21 05:42:20 -04:00
#ifdef _NOISEMAP
noiseMap_uv = input.noisemapTexcoord.xy;
noiseMaskMap_uv = input.noisemapTexcoord.zw;
#endif
#if defined (_EMISSION) || defined(_COLORMAPBLEND)
emission_uv = input.emissionColorBlendTexcoord.xy;
colorBlendMap_uv = input.emissionColorBlendTexcoord.zw;
#endif
#ifdef _DISSOLVE
dissolve_uv = input.dissolveTexcoord.xy;
dissolve_mask_uv = input.dissolveTexcoord.zw;
dissolve_noise_uv = input.dissolveNoiseTexcoord;
#endif
}
half2 originUV = uv;
#ifdef _PARALLAX_MAPPING
uv.xy = ParallaxOcclusionMapping(uv,input.tangentViewDir);
#endif
half2 cum_noise = 0;
half2 cum_noise_xy = 0.5;
half noiseMask = 1;
#if defined(_NOISEMAP)
half4 noiseSample = SampleNoise(_NoiseOffset, _NoiseMap, noiseMap_uv, input.positionWS.xyz);
cum_noise = noiseSample.xy;
UNITY_FLATTEN
if(CheckLocalFlags(FLAG_BIT_PARTICLE_NOISEMAP_NORMALIZEED_ON))
{
cum_noise = cum_noise * 2 - 1;
}
2025-08-27 21:45:18 -04:00
noiseMask *= noiseSample.a;
2025-07-21 05:42:20 -04:00
UNITY_BRANCH
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_NOISE_MASKMAP))
{
2025-08-27 21:45:18 -04:00
half4 noiseMaskSample = SampleTexture2DWithWrapFlags(_NoiseMaskMap,noiseMaskMap_uv,FLAG_BIT_WRAPMODE_NOISE_MASKMAP);
noiseMask *= GetColorChannel(noiseMaskSample,FLAG_BIT_COLOR_CHANNEL_POS_0_NOISE_MASK);
2025-07-21 05:42:20 -04:00
}
_TexDistortion_intensity = GetCustomData(_W9ParticleCustomDataFlag1,FLAGBIT_POS_1_CUSTOMDATA_NOISE_INTENSITY,_TexDistortion_intensity,input.VaryingsP_Custom1,input.VaryingsP_Custom2);
_DistortionDirection.x += GetCustomData(_W9ParticleCustomDataFlag2,FLAGBIT_POS_2_CUSTOMDATA_NOISE_DIRECTION_X,0,input.VaryingsP_Custom1,input.VaryingsP_Custom2);
_DistortionDirection.y += GetCustomData(_W9ParticleCustomDataFlag2,FLAGBIT_POS_2_CUSTOMDATA_NOISE_DIRECTION_Y,0,input.VaryingsP_Custom1,input.VaryingsP_Custom2);
// 将扭曲放到post去做
#if defined(_SCREEN_DISTORT_MODE)
cum_noise_xy = cum_noise * _TexDistortion_intensity * _DistortionDirection.xy;
cum_noise_xy = cum_noise_xy * 1.25 + 0.5;
#endif
float2 mainTexNoise = cum_noise * noiseMask * _TexDistortion_intensity * _DistortionDirection.xy;
uv.xy += mainTexNoise;//主贴图纹理扭曲
2025-08-27 21:45:18 -04:00
blendUv.xy += mainTexNoise;
2025-07-21 05:42:20 -04:00
#endif
2025-08-27 21:45:18 -04:00
2025-07-21 05:42:20 -04:00
// SampleAlbedo--------------------
half4 albedo = 0;
#if defined(_SCREEN_DISTORT_MODE)
albedo = half4(cum_noise_xy, 1.0, noiseMask);
#else
2025-08-27 21:45:18 -04:00
2025-07-21 05:42:20 -04:00
UNITY_FLATTEN
if(CheckLocalFlags(FLAG_BIT_PARTICLE_BACKCOLOR))
{
_BaseColor = facing > 0 ? _BaseColor : _BaseBackColor;
}
Texture2D baseMap;
#ifdef _SCREEN_DISTORT_MODE
baseMap = _ScreenColorCopy1;
#else
baseMap = _BaseMap;
#endif
UNITY_BRANCH
if (CheckLocalFlags(FLAG_BIT_PARTICLE_UIEFFECT_ON) & !CheckLocalFlags1(FLAG_BIT_PARTICLE_1_UIEFFECT_BASEMAP_MODE))
{
albedo = BlendTexture(_MainTex, uv, blendUv) * _Color;
}
else if (CheckLocalFlags(FLAG_BIT_PARTICLE_CHORATICABERRAT))
{
_DistortionDirection.z = GetCustomData(_W9ParticleCustomDataFlag0,FLAGBIT_POS_0_CUSTOMDATA_CHORATICABERRAT_INTENSITY,_DistortionDirection.z,input.VaryingsP_Custom1,input.VaryingsP_Custom2);
_DistortionDirection.z *= 0.1;
albedo = DistortionChoraticaberrat(baseMap,originUV,uv,_DistortionDirection.z,FLAG_BIT_WRAPMODE_BASEMAP);
}
else
{
2025-08-27 21:45:18 -04:00
2025-07-21 05:42:20 -04:00
albedo = BlendTexture(baseMap, uv, blendUv,FLAG_BIT_WRAPMODE_BASEMAP);
}
2025-08-27 21:45:18 -04:00
albedo.a = GetColorChannel(albedo,FLAG_BIT_COLOR_CHANNEL_POS_0_MAINTEX_ALPHA);
2025-07-21 05:42:20 -04:00
albedo *= _BaseColor ;
albedo.rgb *= _BaseColorIntensityForTimeline;
#endif
half alpha = albedo.a;
half3 result = albedo.rgb;
2025-08-27 21:45:18 -04:00
#ifdef _FX_LIGHT_MODE_SIX_WAY
float4 rigRTBkSample = BlendTexture(_RigRTBk, uv, blendUv,FLAG_BIT_WRAPMODE_BASEMAP);
float4 rigLBtFSample = BlendTexture(_RigLBtF, uv, blendUv,FLAG_BIT_WRAPMODE_BASEMAP);
#endif
2025-07-21 05:42:20 -04:00
UNITY_BRANCH
if(CheckLocalFlags(FLAG_BIT_HUESHIFT_ON))
{
half3 hsv = RgbToHsv(result);
_HueShift = GetCustomData(_W9ParticleCustomDataFlag0,FLAGBIT_POS_0_CUSTOMDATA_HUESHIFT,_HueShift,input.VaryingsP_Custom1,input.VaryingsP_Custom2);
hsv.r += _HueShift;
result = HsvToRgb(hsv);
}
if (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_MAINTEX_CONTRAST))
{
_Contrast = GetCustomData(_W9ParticleCustomDataFlag2,FLAGBIT_POS_2_CUSTOMDATA_MAINTEX_CONTRAST,_Contrast,input.VaryingsP_Custom1,input.VaryingsP_Custom2);
result.rgb = lerp(_ContrastMidColor,result.rgb,_Contrast);
}
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);
}
2025-08-27 21:45:18 -04:00
half3 normalTS = half3(0, 0, 1);//TODO
if (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_BUMP_TEX_UV_FOLLOW_MAINTEX))
{
BumpTex_uv = uv;
}
half metallic = 1;
half smoothness = 1;
#ifdef _NORMALMAP
half4 normalMapSample = SampleTexture2DWithWrapFlags(_BumpTex,BumpTex_uv,FLAG_BIT_WRAPMODE_BUMPTEX);
if (CheckLocalFlags(FLAG_BIT_PARTICLE_NORMALMAP_MASK_MODE))
{
normalTS = UnpackNormalRGB(half4(normalMapSample.xy,0,1),_BumpScale);
metallic *= normalMapSample.z;
smoothness *= normalMapSample.w;
}
else
{
normalTS = UnpackNormalScale(half4(normalMapSample),_BumpScale);
}
#endif
//光照模式
#ifndef _FX_LIGHT_MODE_UNLIT
InputData inputData;
InitializeInputData(input, normalTS, inputData);
metallic *= _MaterialInfo.x;
half3 specular = 0;
smoothness *= _MaterialInfo.y;
half occlusion = 1;
half3 pbrEmission = 0;
// return half4(inputData.bakedGI,1);
#if defined (_FX_LIGHT_MODE_BLINN_PHONG) || defined(_FX_LIGHT_MODE_HALF_LAMBERT)
half4 specularGloss = _SpecularColor;
#ifdef _FX_LIGHT_MODE_BLINN_PHONG
half4 blinnPhong = UniversalFragmentBlinnPhong(inputData,result.rgb, specularGloss, smoothness, pbrEmission, alpha,normalTS);
#else //_FX_LIGHT_MODE_HALF_LAMBERT
half4 blinnPhong = UniversalFragmentHalfLambert(inputData,result.rgb, specularGloss, smoothness, pbrEmission, alpha,normalTS);
#endif
result = blinnPhong.rgb;
alpha = blinnPhong.a;
#elif _FX_LIGHT_MODE_PBR
half4 pbr = UniversalFragmentPBR(inputData,result.rgb, metallic, specular, smoothness, occlusion, pbrEmission, alpha);
result = pbr.rgb;
alpha = pbr.a;
#elif _FX_LIGHT_MODE_SIX_WAY
BSDFData bsdfData = (BSDFData)0;
bsdfData.absorptionRange = GetAbsorptionRange(_SixWayInfo.x);
bsdfData.diffuseColor = albedo;
bsdfData.normalWS = inputData.normalWS;
bsdfData.tangentWS = input.tangentWS;//Check this
bsdfData.rigRTBk = rigRTBkSample.xyz * INV_PI;//AccordingTo SixWayForwardPass
bsdfData.rigLBtF = rigLBtFSample.xyz * INV_PI;//AccordingTo SixWayForwardPass
bsdfData.bakeDiffuseLighting0 = input.bakeDiffuseLighting0;
bsdfData.bakeDiffuseLighting1 = input.bakeDiffuseLighting1;
bsdfData.bakeDiffuseLighting2 = input.bakeDiffuseLighting2;
bsdfData.backBakeDiffuseLighting0 = input.backBakeDiffuseLighting0;
bsdfData.backBakeDiffuseLighting1 = input.backBakeDiffuseLighting1;
bsdfData.backBakeDiffuseLighting2 = input.backBakeDiffuseLighting2;
bsdfData.emissionInput = rigLBtFSample.a;
GetSixWayEmission(bsdfData,_SixWayEmissionRamp,_SixWayEmissionColor,CheckLocalFlags1(FLAG_BIT_PARTICLE_1_SIXWAY_RAMPMAP));//Init Emission
bsdfData.alpha = rigRTBkSample.a * _BaseColor.a;
ModifyBakedDiffuseLighting(bsdfData,inputData.bakedGI);
half4 sixWay = UniversalFragmentSixWay(inputData,bsdfData);
// half3 dir = _MainLightPosition.xyz;
// dir = TransformToLocalFrame(dir, bsdfData);
// return half4(dir,1);
result = sixWay.rgb;
alpha = sixWay.a;
#endif
#ifdef _ADDITIONAL_LIGHTS_VERTEX
result.rgb *= input.vertexLight;
#endif
input.normalWSAndAnimBlend.xyz = inputData.normalWS;
#else
#ifdef _NORMALMAP
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);
input.normalWSAndAnimBlend.xyz = TransformTangentToWorld(normalTS, tangentToWorld);
#endif
#endif
#ifdef _MATCAP
// URP
half3 normalVS = mul(input.normalWSAndAnimBlend.xyz, (float3x3)UNITY_MATRIX_I_V); // 逆转置矩阵
half3 positionVS = TransformWorldToView(input.positionWS);
float3 r = reflect(positionVS, normalVS);
r = normalize(r);
float m = 2.828427f * sqrt(r.z + 1.0);
float2 matCapUV = r.xy / m + 0.5;
half3 matCapSample = SAMPLE_TEXTURE2D(_MatCapTex,sampler_linear_clamp,matCapUV);
matCapSample *= _MatCapColor.rgb;
half3 matCapMutilResult = result * matCapSample;
half3 matAddResult = result + matCapSample;
half3 matCapResult = lerp(matAddResult,matCapMutilResult,_MatCapInfo.x);
result = lerp(result,matCapResult,_MatCapColor.a);
#endif
2025-07-21 05:42:20 -04:00
//流光部分
half4 emission = half4(0, 0, 0,1);
#if defined(_EMISSION)
#ifdef _NOISEMAP
2025-08-27 21:45:18 -04:00
if (!CheckLocalFlags(FLAG_BIT_PARTICLE_EMISSION_FOLLOW_MAINTEX_UV))
{
2025-07-21 05:42:20 -04:00
emission_uv += cum_noise * _Emi_Distortion_intensity;
2025-08-27 21:45:18 -04:00
}
2025-07-21 05:42:20 -04:00
#endif
// emission = tex2D_TryLinearizeWithoutAlphaFX(_EmissionMap,emission_uv);
emission = SampleTexture2DWithWrapFlags(_EmissionMap,emission_uv,FLAG_BIT_WRAPMODE_EMISSIONMAP);
emission.xyz *= emission.a;
_EmissionMapColor *= _EmissionMapColorIntensity;
emission.xyz *= _EmissionMapColor;
#endif
result += emission;
2025-08-27 21:45:18 -04:00
#if defined(_COLOR_RAMP)
half rampValue = 0;
if (CheckLocalFlags(FLAG_BIT_PARTICLE_RAMP_COLOR_MAP_MODE_ON))
{
half4 RampColorSample = SampleTexture2DWithWrapFlags(_RampColorMap,colorRamp_uv,FLAG_BIT_WRAPMODE_RAMP_COLOR_MAP);
rampValue = GetColorChannel(RampColorSample,FLAG_BIT_COLOR_CHANNEL_POS_0_RAMP_COLOR_MAP);
}
else
{
const int rampColorWrapMode = CheckLocalWrapFlags(FLAG_BIT_WRAPMODE_RAMP_COLOR_MAP);
if (rampColorWrapMode == 0 || rampColorWrapMode == 2)
{
rampValue = frac(colorRamp_uv.x);
}
else
{
rampValue = saturate(colorRamp_uv.x);
}
}
half3 colorRampColorArr[] = {_RampColor0.rgb,_RampColor1.rgb,_RampColor2.rgb,_RampColor3.rgb,_RampColor4.rgb,_RampColor5.rgb};
half colorRampColorTimeArr[] = {_RampColor0.a,_RampColor1.a,_RampColor2.a,_RampColor3.a,_RampColor4.a,_RampColor5.a};
int colorRampColorCount = _RampColorCount & 0xFFFF;
half colorRampAlphaArr[] = {_RampColorAlpha0.x,_RampColorAlpha0.z,_RampColorAlpha1.x,_RampColorAlpha1.z,_RampColorAlpha2.x,_RampColorAlpha2.z};
half colorRampAlphaTimeArr[] = {_RampColorAlpha0.y,_RampColorAlpha0.w,_RampColorAlpha1.y,_RampColorAlpha1.w,_RampColorAlpha2.y,_RampColorAlpha2.w};
int colorRampAlphaCount = _RampColorCount >> 16;
half4 rampColor;
rampColor.rgb = GetGradientColorValue(colorRampColorArr,colorRampColorTimeArr,colorRampColorCount,rampValue);
rampColor.a = GetGradientAlphaValue(colorRampAlphaArr,colorRampAlphaTimeArr,colorRampAlphaCount,rampValue);
rampColor *= _RampColorBlendColor;
if (CheckLocalFlags(FLAG_BIT_PARTICLE_RAMP_COLOR_BLEND_ADD))
{
result += rampColor;
alpha += rampColor.a;
}
else
{
result *= rampColor;
alpha *= rampColor.a;
}
#endif
2025-07-21 05:42:20 -04:00
//溶解部分
#if defined(_DISSOLVE)
#ifdef _NOISEMAP
dissolve_uv += cum_noise * _DissolveOffsetRotateDistort.w;
UNITY_FLATTEN
if(CheckLocalFlags(FLAG_BIT_PARTICLE_DISSOLVE_MASK))
{
dissolve_mask_uv += cum_noise * _DissolveOffsetRotateDistort.w;
}
#endif
2025-08-27 21:45:18 -04:00
half4 dissolveMapSample = SampleTexture2DWithWrapFlags(_DissolveMap,dissolve_uv,FLAG_BIT_WRAPMODE_DISSOLVE_MAP);
half dissolveValue = GetColorChannel(dissolveMapSample,FLAG_BIT_COLOR_CHANNEL_POS_0_DISSOLVE_MAP);
2025-07-21 05:42:20 -04:00
UNITY_BRANCH
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_DISSOVLE_VORONOI))
{
half cell;
half noise1;
noise1 = SimplexNoise(dissolve_noise_uv.xy,_Time.y*_DissolveVoronoi_Vec2.z);
half noise2;
Unity_Voronoi_float(dissolve_noise_uv.zw,_Time.y*_DissolveVoronoi_Vec2.w,_DissolveVoronoi_Vec.zw,noise2,cell);
half overlayVoroni;
half dissolveSample = dissolveValue;
Unity_Blend_HardLight_half(noise1,noise2,_DissolveVoronoi_Vec2.x,overlayVoroni);
Unity_Blend_HardLight_half(overlayVoroni,dissolveSample,_DissolveVoronoi_Vec2.y,dissolveValue);
}
2025-08-27 21:45:18 -04:00
// dissolveValue = SimpleSmoothstep(_Dissolve_Vec2.x,_Dissolve_Vec2.y,dissolveValue);
dissolveValue = pow(dissolveValue,_Dissolve.y);
2025-07-21 05:42:20 -04:00
2025-08-27 21:45:18 -04:00
2025-07-21 05:42:20 -04:00
UNITY_BRANCH
if(CheckLocalFlags(FLAG_BIT_PARTICLE_DISSOLVE_MASK))
{
2025-08-27 21:45:18 -04:00
half dissolveMaskValue = 0;
half4 dissolveMaskSample = SampleTexture2DWithWrapFlags(_DissolveMaskMap,dissolve_mask_uv,FLAG_BIT_WRAPMODE_DISSOLVE_MASKMAP);
dissolveMaskValue = GetColorChannel(dissolveMaskSample,FLAG_BIT_COLOR_CHANNEL_POS_0_DISSOLVE_MASK_MAP);
2025-07-21 05:42:20 -04:00
_Dissolve.z += GetCustomData(_W9ParticleCustomDataFlag1,FLAGBIT_POS_1_CUSTOMDATA_DISSOLVE_MASK_INTENSITY,0,input.VaryingsP_Custom1,input.VaryingsP_Custom2);
2025-08-27 21:45:18 -04:00
dissolveMaskValue += _Dissolve.z;
// dissolveValue = dissolveMaskValue*dissolveValue;
//
// half mixedDisolveValue ;
// Blend_HardLight_half(dissolveValue,dissolveMaskValue,mixedDisolveValue);
// dissolveValue = mixedDisolveValue;
dissolveValue = (dissolveValue +dissolveMaskValue)*0.5;//Smart Way By Panda
2025-07-21 05:42:20 -04:00
}
2025-08-27 21:45:18 -04:00
#ifdef _DISSOLVE_EDITOR_TEST //后续Test类的关键字要找机会排除
return half4(dissolveValue.rrr,1);
#endif
half dissolveStrenth = _Dissolve.x + GetCustomData(_W9ParticleCustomDataFlag0,FLAGBIT_POS_0_CUSTOMDATA_DISSOLVE_INTENSITY,0,input.VaryingsP_Custom1,input.VaryingsP_Custom2);
half invSoftStep = 1/_Dissolve.w;
half dissolveValueBeforeSoftStep = dissolveValue - ((dissolveStrenth)*(invSoftStep + 1)-1)*_Dissolve.w ;
dissolveValue = dissolveValue*invSoftStep -(1+invSoftStep)*dissolveStrenth +1;
// dissolveValue = smoothstep(dissolveStrenth-_Dissolve.w,dissolveStrenth,dissolveValue);//Smart Way By Panda
dissolveValue = saturate(dissolveValue);
2025-07-21 05:42:20 -04:00
2025-08-27 21:45:18 -04:00
2025-07-21 05:42:20 -04:00
alpha *= dissolveValue;
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_DISSOVLE_USE_RAMP))
{
2025-08-27 21:45:18 -04:00
// half rampRange = (dissolveValueBeforeSoftStep - _Dissolve_Vec2.x)*_Dissolve_Vec2.y;
half rampRange = dissolveValueBeforeSoftStep;
2025-07-21 05:42:20 -04:00
rampRange = rampRange * _DissolveRampMap_ST.x +_DissolveRampMap_ST.z;
2025-08-27 21:45:18 -04:00
half4 rampSample ;
if (CheckLocalFlags(FLAG_BIT_PARTICLE_DISSOLVE_RAMP_MAP))
{
rampSample = SampleTexture2DWithWrapFlags(_DissolveRampMap,half2(rampRange,0.5),FLAG_BIT_WRAPMODE_DISSOLVE_RAMPMAP);
}
else
{
half3 dissolveRampColorArr[] = {_DissolveRampColor0.rgb,_DissolveRampColor1.rgb,_DissolveRampColor2.rgb,_DissolveRampColor3.rgb,_DissolveRampColor4.rgb,_DissolveRampColor5.rgb};
half dissolveRampColorTimeArr[] = {_DissolveRampColor0.a,_DissolveRampColor1.a,_DissolveRampColor2.a,_DissolveRampColor3.a,_DissolveRampColor4.a,_DissolveRampColor5.a};
int dissolveRampColorCount = _DissolveRampCount & 0xFFFF;
half dissolveRampAlphaArr[] = {_DissolveRampAlpha0.x,_DissolveRampAlpha0.z,_DissolveRampAlpha1.x,_DissolveRampAlpha1.z,_DissolveRampAlpha2.x,_DissolveRampAlpha2.z};
half dissolveRampAlphaTimeArr[] = {_DissolveRampAlpha0.y,_DissolveRampAlpha0.w,_DissolveRampAlpha1.y,_DissolveRampAlpha1.w,_DissolveRampAlpha2.y,_DissolveRampAlpha2.w};
int dissolveRampAlphaCount = _DissolveRampCount >> 16;
const int rampWrapMode = CheckLocalWrapFlags(FLAG_BIT_WRAPMODE_DISSOLVE_RAMPMAP);
if (rampWrapMode == 0 || rampWrapMode == 2)
{
rampRange = frac(rampRange);
}
else
{
rampRange = saturate(rampRange);
}
rampSample.rgb = GetGradientColorValue(dissolveRampColorArr,dissolveRampColorTimeArr,dissolveRampColorCount,rampRange);
rampSample.a = GetGradientAlphaValue(dissolveRampAlphaArr,dissolveRampAlphaTimeArr,dissolveRampAlphaCount,rampRange);
}
if (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_DISSOLVE_RAMP_MULITPLY))
{
result = result * lerp(1,rampSample.rgb*_DissolveRampColor.rgb,rampSample.a*_DissolveRampColor.a);
}
else
{
result = lerp(result,rampSample.rgb*_DissolveRampColor.rgb,rampSample.a*_DissolveRampColor.a);
}
2025-07-21 05:42:20 -04:00
}
2025-08-27 21:45:18 -04:00
if (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_DISSOLVE_LINE_MASK))
{
half lineMask = dissolveValueBeforeSoftStep;//SmoothStep要优化
lineMask = saturate(NB_Remap01(lineMask,_Dissolve_Vec2.x-_Dissolve_Vec2.y,_Dissolve_Vec2 + _Dissolve_Vec2.y));
lineMask = 1- lineMask;
result = lerp(result,_DissolveLineColor.rgb,lineMask*_DissolveLineColor.a);
}
//
2025-07-21 05:42:20 -04:00
#endif
//颜色渐变
#ifdef _COLORMAPBLEND
2025-08-27 21:45:18 -04:00
#if defined(_NOISEMAP)
if (!CheckLocalFlags(FLAG_BIT_PARTICLE_COLOR_BLEND_FOLLOW_MAINTEX_UV))
{
colorBlendMap_uv += cum_noise * _ColorBlendVec.x; //加入扭曲效果
}
#endif
2025-07-21 05:42:20 -04:00
half4 colorBlend = SampleTexture2DWithWrapFlags(_ColorBlendMap,colorBlendMap_uv,FLAG_BIT_WRAPMODE_COLORBLENDMAP);
colorBlend.rgb = colorBlend.rgb * _ColorBlendColor.rgb;
2025-08-27 21:45:18 -04:00
colorBlend.a = lerp(1,colorBlend.a*_ColorBlendColor.a,_ColorBlendVec.z);
if (CheckLocalFlags(FLAG_BIT_PARTICLE_COLOR_BLEND_ALPHA_MULTIPLY_MODE))
{
result *= colorBlend.rgb;
alpha *= colorBlend.a;
}
else
{
result.rgb = lerp(result.rgb,result.rgb * colorBlend.rgb,colorBlend.a);
}
2025-07-21 05:42:20 -04:00
#endif
//菲涅
UNITY_BRANCH
if(CheckLocalFlags(FLAG_BIT_PARTICLE_FRESNEL_ON))
{
half fresnelValue = 0;
if(!ignoreFresnel())
{
half3 fresnelDir = normalize(input.fresnelViewDir+_FresnelRotation.rgb);
half dotNV = dot(fresnelDir,input.normalWSAndAnimBlend.xyz) ;
fresnelValue = dotNV;
_FresnelUnit.x += GetCustomData(_W9ParticleCustomDataFlag0,FLAGBIT_POS_0_CUSTOMDATA_FRESNEL_OFFSET,0,input.VaryingsP_Custom1,input.VaryingsP_Custom2);;
2025-08-27 21:45:18 -04:00
// half fresnelHardness = - _FresnelUnit.w*0.5 +0.5;
fresnelValue = NB_Remap(fresnelValue,_FresnelUnit.x,_FresnelUnit.x + 1.01 - _FresnelUnit.w,0,1);
2025-07-21 05:42:20 -04:00
UNITY_BRANCH
if(!CheckLocalFlags(FLAG_BIT_PARTICLE_FRESNEL_INVERT_ON))
{
fresnelValue = 1- fresnelValue;
}
fresnelValue = pow(fresnelValue,_FresnelUnit.y);
2025-08-27 21:45:18 -04:00
// fresnelValue = smoothstep(0.5-fresnelHardness,0.5+fresnelHardness,fresnelValue);
2025-07-21 05:42:20 -04:00
}
UNITY_BRANCH
if(CheckLocalFlags(FLAG_BIT_PARTICLE_FRESNEL_COLOR_ON))
{
float fresnelColorIntensity = fresnelValue*_FresnelColor.a*_FresnelUnit.z;
result = lerp(result,_FresnelColor.rgb,fresnelColorIntensity);
2025-08-27 21:45:18 -04:00
if (!CheckLocalFlags(FLAG_BIT_PARTICLE_FRESNEL_COLOR_AFFETCT_BY_ALPHA))
{
alpha = max(alpha,fresnelColorIntensity);//颜色要不要不被主贴图Alpha影响呢
}
2025-07-21 05:42:20 -04:00
}
UNITY_BRANCH
if(CheckLocalFlags(FLAG_BIT_PARTICLE_FRESNEL_FADE_ON))
{
fresnelValue *= alpha;
alpha = lerp(alpha,fresnelValue,_FresnelUnit.z);
}
}
UNITY_BRANCH
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_DEPTH_OUTLINE))
{
half depthOutlineValue = 1- SoftParticles(_DepthOutline_Vec.x, _DepthOutline_Vec.y, sceneZ,thisZ);
depthOutlineValue *= _DepthOutline_Color.a;
half3 originResult = result;
//如何在一个pass里完美的给出两个颜色的Fade。这个问题没有想清楚。
result = lerp(result,_DepthOutline_Color.rgb,clamp(depthOutlineValue*3,0,1));
result = lerp(result,originResult,clamp(alpha-depthOutlineValue,0,1));
alpha = max(alpha,depthOutlineValue);
}
//遮罩部分
#if defined(_MASKMAP_ON)
#if defined(_NOISEMAP)
MaskMapuv += cum_noise * _MaskDistortion_intensity; //加入扭曲效果
#endif
2025-08-27 21:45:18 -04:00
half mask1 = 1;
if (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_MASKMAP_GRADIENT))
{
const int maskMapWrapMode = CheckLocalWrapFlags(FLAG_BIT_WRAPMODE_MASKMAP);
half maskMapTimeValue;
if (maskMapWrapMode == 0 || maskMapWrapMode == 2)
{
maskMapTimeValue = frac(MaskMapuv.x);
}
else
{
maskMapTimeValue = saturate(MaskMapuv.x);
}
half maskMapAlphaArr[] = {_MaskMapGradientFloat0.x,_MaskMapGradientFloat0.z,_MaskMapGradientFloat1.x,_MaskMapGradientFloat1.z,_MaskMapGradientFloat2.x,_MaskMapGradientFloat2.z};
half maskMapAlphaTimeArr[] = {_MaskMapGradientFloat0.y,_MaskMapGradientFloat0.w,_MaskMapGradientFloat1.y,_MaskMapGradientFloat1.w,_MaskMapGradientFloat2.y,_MaskMapGradientFloat2.w};
int maskMapAlphaCount = _MaskMapGradientCount;
mask1 = GetGradientAlphaValue(maskMapAlphaArr,maskMapAlphaTimeArr,maskMapAlphaCount,maskMapTimeValue);
}
else
{
half4 maskmap1Sample = SampleTexture2DWithWrapFlags(_MaskMap, MaskMapuv,FLAG_BIT_WRAPMODE_MASKMAP);
mask1 = GetColorChannel(maskmap1Sample,FLAG_BIT_COLOR_CHANNEL_POS_0_MASKMAP1);
}
2025-07-21 05:42:20 -04:00
UNITY_BRANCH
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_MASK_MAP2))
{
2025-08-27 21:45:18 -04:00
half mask2 = 1;
if (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_MASKMAP_2_GRADIENT))
{
const int maskMap2WrapMode = CheckLocalWrapFlags(FLAG_BIT_WRAPMODE_MASKMAP2);
half maskMap2TimeValue;
if (maskMap2WrapMode == 0 || maskMap2WrapMode == 3)
{
maskMap2TimeValue = frac(MaskMapuv2.y);
}
else
{
maskMap2TimeValue = saturate(MaskMapuv2.y);
}
half maskMap2AlphaArr[] = {_MaskMap2GradientFloat0.x,_MaskMap2GradientFloat0.z,_MaskMap2GradientFloat1.x,_MaskMap2GradientFloat1.z,_MaskMap2GradientFloat2.x,_MaskMap2GradientFloat2.z};
half maskMap2AlphaTimeArr[] = {_MaskMap2GradientFloat0.y,_MaskMap2GradientFloat0.w,_MaskMap2GradientFloat1.y,_MaskMap2GradientFloat1.w,_MaskMap2GradientFloat2.y,_MaskMap2GradientFloat2.w};
int maskMap2AlphaCount = _MaskMap2GradientCount;
mask2 = GetGradientAlphaValue(maskMap2AlphaArr,maskMap2AlphaTimeArr,maskMap2AlphaCount,maskMap2TimeValue);
}
else
{
half4 maskMap2Sample = SampleTexture2DWithWrapFlags(_MaskMap2, MaskMapuv2,FLAG_BIT_WRAPMODE_MASKMAP2);
mask2 = GetColorChannel(maskMap2Sample,FLAG_BIT_COLOR_CHANNEL_POS_0_MASKMAP2);
}
mask1 *= mask2;
2025-07-21 05:42:20 -04:00
}
UNITY_BRANCH
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_MASK_MAP3))
{
2025-08-27 21:45:18 -04:00
half mask3 = 1;
if (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_MASKMAP_3_GRADIENT))
{
const int maskMap3WrapMode = CheckLocalWrapFlags(FLAG_BIT_WRAPMODE_MASKMAP3);
half maskMap3TimeValue;
if (maskMap3WrapMode == 0 || maskMap3WrapMode == 2)
{
maskMap3TimeValue = frac(MaskMapuv3.x);
}
else
{
maskMap3TimeValue = saturate(MaskMapuv3.x);
}
half maskMap3AlphaArr[] = {_MaskMap3GradientFloat0.x,_MaskMap3GradientFloat0.z,_MaskMap3GradientFloat1.x,_MaskMap3GradientFloat1.z,_MaskMap3GradientFloat2.x,_MaskMap3GradientFloat2.z};
half maskMap3AlphaTimeArr[] = {_MaskMap3GradientFloat0.y,_MaskMap3GradientFloat0.w,_MaskMap3GradientFloat1.y,_MaskMap3GradientFloat1.w,_MaskMap3GradientFloat2.y,_MaskMap3GradientFloat2.w};
int maskMap3AlphaCount = _MaskMap3GradientCount;
mask3 = GetGradientAlphaValue(maskMap3AlphaArr,maskMap3AlphaTimeArr,maskMap3AlphaCount,maskMap3TimeValue);
}
else
{
half4 maskMap3Sample = SampleTexture2DWithWrapFlags(_MaskMap3, MaskMapuv3,FLAG_BIT_WRAPMODE_MASKMAP3);
mask3 = GetColorChannel(maskMap3Sample,FLAG_BIT_COLOR_CHANNEL_POS_0_MASKMAP3);
}
mask1 *= mask3;
2025-07-21 05:42:20 -04:00
}
2025-08-27 21:45:18 -04:00
if (CheckLocalFlags1(FLAG_BIT_PARTICLE_1_MASK_REFINE))
{
mask1 = pow(mask1,_MaskRefineVec.x);
mask1 = mask1 * _MaskRefineVec.y;
mask1 += _MaskRefineVec.z;
}
mask1 = lerp(1,mask1,_MaskMapVec.x);
mask1 = saturate(mask1);
2025-07-21 05:42:20 -04:00
2025-08-27 21:45:18 -04:00
alpha *= mask1; //mask边缘
2025-07-21 05:42:20 -04:00
#endif
//可以看https://www.cyanilux.com/tutorials/depth/
// float4 projectedPosition = input.positionNDC;
// float thisZ1 = LinearEyeDepth(projectedPosition.z / projectedPosition.w, _ZBufferParams);
UNITY_BRANCH
if(CheckLocalFlags(FLAG_BIT_PARTICLE_DISTANCEFADE_ON))
{
half fade = DepthFactor(thisZ, _Fade.x, _Fade.y);
alpha *= fade;
}
#if defined(_SOFTPARTICLES_ON)
half softAlpha = SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, sceneZ,thisZ);
alpha *= softAlpha;
#endif
UNITY_BRANCH
if(CheckLocalFlags(FLAG_BIT_SATURABILITY_ON))
{
half3 resultWB = luminance(result);
_Saturability = GetCustomData(_W9ParticleCustomDataFlag1,FLAGBIT_POS_1_CUSTOMDATA_SATURATE,_Saturability,input.VaryingsP_Custom1,input.VaryingsP_Custom2);
result.rgb = lerp(resultWB.rgb, result.rgb, _Saturability);
}
//和粒子颜色信息运算。雨轩:乘顶点色。
if(!CheckLocalFlags1(FLAG_BIT_PARTICLE_1_IGNORE_VERTEX_COLOR))
{
result *= input.color.rgb;
alpha *= input.color.a;
}
// 程序额外的颜色
result *= _ColorA.rgb;
alpha *= _ColorA.a;
// // alpha *= _ColorA * 0.8;
#ifdef _DEPTH_DECAL
alpha *= decalAlpha;
#endif
half3 beforeFogResult = result;
result = MixFog(result,input.positionWS.w);
result = lerp(beforeFogResult, result, _fogintensity);
2025-08-27 21:45:18 -04:00
// #ifndef _SCREEN_DISTORT_MODE
// result.rgb = result.rgb * alpha;
// #endif
2025-07-21 05:42:20 -04:00
2025-08-27 21:45:18 -04:00
UNITY_FLATTEN
if(CheckLocalFlags(FLAG_BIT_PARTICLE_LINEARTOGAMMA_ON))
{
result.rgb = LinearToGammaSpace(result.rgb);
}
2025-07-21 05:42:20 -04:00
alpha *= _AlphaAll;
2025-08-27 21:45:18 -04:00
#if defined (_ALPHAPREMULTIPLY_ON) || defined(_ALPHAMODULATE_ON)
result *= alpha;
#ifdef _ALPHAPREMULTIPLY_ON
alpha *= _AdditiveToPreMultiplyAlphaLerp;
#endif
#endif
2025-07-21 05:42:20 -04:00
half4 color = half4(result, alpha);
2025-08-27 21:45:18 -04:00
2025-07-21 05:42:20 -04:00
#ifdef _ALPHATEST_ON
clip(color.a - _Cutoff);
#endif
2025-08-27 21:45:18 -04:00
color = min(color,1000);
2025-07-21 05:42:20 -04:00
return color;
}
#endif