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

1039 lines
44 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 PARTICLESUNLITFORWARDPASS
#define PARTICLESUNLITFORWARDPASS
#include "HLSL/ParticlesUnlitInputNew.hlsl"
#include "HLSL/SixWaySmokeLit.hlsl"
///////////////////////////////////////////////////////////////////////////////
// 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);
#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
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;
#if defined (_NORMALMAP) || defined(_COLOR_RAMP)
output.bumpTexAndColorRampMapTexcoord.xy = particleUVs.bumpTexUV;
output.bumpTexAndColorRampMapTexcoord.zw = particleUVs.colorRampMapUV;
#endif
#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;
float2 BumpTex_uv;
float2 colorRamp_uv;
//如果同时在粒子系统里开启序列帧融帧和特殊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);
BumpTex_uv = particleUVs.bumpTexUV;
colorRamp_uv = particleUVs.colorRampMapUV;
}
else
{
MaskMapuv = input.texcoord.zw;
MaskMapuv2 = input.texcoordMaskMap2.xy;
MaskMapuv3 = input.texcoordMaskMap2.zw;
#if defined (_NORMALMAP)||defined(_COLOR_RAMP)
BumpTex_uv = input.bumpTexAndColorRampMapTexcoord.xy;
colorRamp_uv = input.bumpTexAndColorRampMapTexcoord.zw;
#endif
#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;
}
noiseMask *= noiseSample.a;
UNITY_BRANCH
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_NOISE_MASKMAP))
{
half4 noiseMaskSample = SampleTexture2DWithWrapFlags(_NoiseMaskMap,noiseMaskMap_uv,FLAG_BIT_WRAPMODE_NOISE_MASKMAP);
noiseMask *= GetColorChannel(noiseMaskSample,FLAG_BIT_COLOR_CHANNEL_POS_0_NOISE_MASK);
}
_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;//主贴图纹理扭曲
blendUv.xy += mainTexNoise;
#endif
// SampleAlbedo--------------------
half4 albedo = 0;
#if defined(_SCREEN_DISTORT_MODE)
albedo = half4(cum_noise_xy, 1.0, noiseMask);
#else
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
{
albedo = BlendTexture(baseMap, uv, blendUv,FLAG_BIT_WRAPMODE_BASEMAP);
}
albedo.a = GetColorChannel(albedo,FLAG_BIT_COLOR_CHANNEL_POS_0_MAINTEX_ALPHA);
albedo *= _BaseColor ;
albedo.rgb *= _BaseColorIntensityForTimeline;
#endif
half alpha = albedo.a;
half3 result = albedo.rgb;
#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
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);
}
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
//流光部分
half4 emission = half4(0, 0, 0,1);
#if defined(_EMISSION)
#ifdef _NOISEMAP
if (!CheckLocalFlags(FLAG_BIT_PARTICLE_EMISSION_FOLLOW_MAINTEX_UV))
{
emission_uv += cum_noise * _Emi_Distortion_intensity;
}
#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;
#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
//溶解部分
#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
half4 dissolveMapSample = SampleTexture2DWithWrapFlags(_DissolveMap,dissolve_uv,FLAG_BIT_WRAPMODE_DISSOLVE_MAP);
half dissolveValue = GetColorChannel(dissolveMapSample,FLAG_BIT_COLOR_CHANNEL_POS_0_DISSOLVE_MAP);
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);
}
// dissolveValue = SimpleSmoothstep(_Dissolve_Vec2.x,_Dissolve_Vec2.y,dissolveValue);
dissolveValue = pow(dissolveValue,_Dissolve.y);
UNITY_BRANCH
if(CheckLocalFlags(FLAG_BIT_PARTICLE_DISSOLVE_MASK))
{
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);
_Dissolve.z += GetCustomData(_W9ParticleCustomDataFlag1,FLAGBIT_POS_1_CUSTOMDATA_DISSOLVE_MASK_INTENSITY,0,input.VaryingsP_Custom1,input.VaryingsP_Custom2);
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
}
#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);
alpha *= dissolveValue;
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_DISSOVLE_USE_RAMP))
{
// half rampRange = (dissolveValueBeforeSoftStep - _Dissolve_Vec2.x)*_Dissolve_Vec2.y;
half rampRange = dissolveValueBeforeSoftStep;
rampRange = rampRange * _DissolveRampMap_ST.x +_DissolveRampMap_ST.z;
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);
}
}
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);
}
//
#endif
//颜色渐变
#ifdef _COLORMAPBLEND
#if defined(_NOISEMAP)
if (!CheckLocalFlags(FLAG_BIT_PARTICLE_COLOR_BLEND_FOLLOW_MAINTEX_UV))
{
colorBlendMap_uv += cum_noise * _ColorBlendVec.x; //加入扭曲效果
}
#endif
half4 colorBlend = SampleTexture2DWithWrapFlags(_ColorBlendMap,colorBlendMap_uv,FLAG_BIT_WRAPMODE_COLORBLENDMAP);
colorBlend.rgb = colorBlend.rgb * _ColorBlendColor.rgb;
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);
}
#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);;
// half fresnelHardness = - _FresnelUnit.w*0.5 +0.5;
fresnelValue = NB_Remap(fresnelValue,_FresnelUnit.x,_FresnelUnit.x + 1.01 - _FresnelUnit.w,0,1);
UNITY_BRANCH
if(!CheckLocalFlags(FLAG_BIT_PARTICLE_FRESNEL_INVERT_ON))
{
fresnelValue = 1- fresnelValue;
}
fresnelValue = pow(fresnelValue,_FresnelUnit.y);
// fresnelValue = smoothstep(0.5-fresnelHardness,0.5+fresnelHardness,fresnelValue);
}
UNITY_BRANCH
if(CheckLocalFlags(FLAG_BIT_PARTICLE_FRESNEL_COLOR_ON))
{
float fresnelColorIntensity = fresnelValue*_FresnelColor.a*_FresnelUnit.z;
result = lerp(result,_FresnelColor.rgb,fresnelColorIntensity);
if (!CheckLocalFlags(FLAG_BIT_PARTICLE_FRESNEL_COLOR_AFFETCT_BY_ALPHA))
{
alpha = max(alpha,fresnelColorIntensity);//颜色要不要不被主贴图Alpha影响呢
}
}
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
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);
}
UNITY_BRANCH
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_MASK_MAP2))
{
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;
}
UNITY_BRANCH
if(CheckLocalFlags1(FLAG_BIT_PARTICLE_1_MASK_MAP3))
{
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;
}
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);
alpha *= mask1; //mask边缘
#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);
// #ifndef _SCREEN_DISTORT_MODE
// result.rgb = result.rgb * alpha;
// #endif
UNITY_FLATTEN
if(CheckLocalFlags(FLAG_BIT_PARTICLE_LINEARTOGAMMA_ON))
{
result.rgb = LinearToGammaSpace(result.rgb);
}
alpha *= _AlphaAll;
#if defined (_ALPHAPREMULTIPLY_ON) || defined(_ALPHAMODULATE_ON)
result *= alpha;
#ifdef _ALPHAPREMULTIPLY_ON
alpha *= _AdditiveToPreMultiplyAlphaLerp;
#endif
#endif
half4 color = half4(result, alpha);
#ifdef _ALPHATEST_ON
clip(color.a - _Cutoff);
#endif
color = min(color,1000);
return color;
}
#endif