Files
2026-02-23 22:01:07 +07:00

411 lines
14 KiB
HLSL

#ifndef ALLIN13DSHADER_FRAGMENT_EFFECTS
#define ALLIN13DSHADER_FRAGMENT_EFFECTS
//<EffectsCode>
float3 HueShift(float3 inputColor, float hueShift, float hueSaturation, float hueBrightness)
{
float3 res = inputColor;
float cosHsv = hueBrightness * hueSaturation * cos(hueShift * 3.14159265 / 180);
float sinHsv = hueBrightness * hueSaturation * sin(hueShift * 3.14159265 / 180);
res.r = (.299 * hueBrightness + .701 * cosHsv + .168 * sinHsv) * inputColor.x
+ (.587 * hueBrightness - .587 * cosHsv + .330 * sinHsv) * inputColor.y
+ (.114 * hueBrightness - .114 * cosHsv - .497 * sinHsv) * inputColor.z;
res.g = (.299 * hueBrightness - .299 * cosHsv - .328 * sinHsv) *inputColor.x
+ (.587 * hueBrightness + .413 * cosHsv + .035 * sinHsv) * inputColor.y
+ (.114 * hueBrightness - .114 * cosHsv + .292 * sinHsv) * inputColor.z;
res.b = (.299 * hueBrightness - .3 * cosHsv + 1.25 * sinHsv) * inputColor.x
+ (.587 * hueBrightness - .588 * cosHsv - 1.05 * sinHsv) * inputColor.y
+ (.114 * hueBrightness + .886 * cosHsv - .203 * sinHsv) * inputColor.z;
return res;
}
float3 ContrastBrightness(float3 inputColor, float contrast, float brightness)
{
float3 res = max(0, (inputColor - float3(0.5, 0.5, 0.5)) * contrast + float3(0.5, 0.5, 0.5) + brightness);
return res;
}
#if defined(_AFFECTED_BY_LIGHTMAPS_ON) && defined(_LIGHTMAP_COLOR_CORRECTION_ON)
float3 LightmapColorCorrection(float3 lightmap)
{
float3 res = lightmap;
res = HueShift(res, ACCESS_PROP_FLOAT(_HueShiftLM), ACCESS_PROP_FLOAT(_HueSaturationLM), ACCESS_PROP_FLOAT(_HueBrightnessLM));
res = ContrastBrightness(res, ACCESS_PROP_FLOAT(_ContrastLM), ACCESS_PROP_FLOAT(_BrightnessLM));
return res;
}
#endif
//</EffectsCode>
#ifdef _HUE_SHIFT_ON
float3 HueShift(float3 inputColor)
{
float3 res = HueShift(inputColor, ACCESS_PROP_FLOAT(_HueShift), ACCESS_PROP_FLOAT(_HueSaturation), ACCESS_PROP_FLOAT(_HueBrightness));
return res;
}
#endif
#ifdef _ALBEDO_VERTEX_COLOR_ON
float4 AlbedoVertexColor(float4 inputColor, EffectsData data)
{
float4 res = inputColor;
#ifdef _ALBEDOVERTEXCOLORMODE_MULTIPLY
float3 multipliedColor = res.rgb * data.vertexColor.rgb;
res.rgb = lerp(res.rgb, multipliedColor, ACCESS_PROP_FLOAT(_VertexColorBlending));
#else
res.rgb = lerp(inputColor.rgb, data.vertexColor.rgb, ACCESS_PROP_FLOAT(_VertexColorBlending));
#endif
return res;
}
#endif
#if defined(_TEXTURE_BLENDING_ON)
float4 TextureBlending(float4 inputColor, EffectsData data)
{
float4 res = inputColor;
#if defined(_TEXTUREBLENDINGSOURCE_TEXTURE)
float2 blendingMaskUV = SIMPLE_CUSTOM_TRANSFORM_TEX(data.rawMainUV, _TexBlendingMask);
float3 maskColor = SAMPLE_TEX2D(_TexBlendingMask, blendingMaskUV).rgb;
#if defined(_TEXTUREBLENDINGMODE_RGB)
float maskG = smoothstep(ACCESS_PROP_FLOAT(_BlendingMaskCutoffG), ACCESS_PROP_FLOAT(_BlendingMaskCutoffG) + ACCESS_PROP_FLOAT(_BlendingMaskSmoothnessG), maskColor.g);
float maskB = smoothstep(ACCESS_PROP_FLOAT(_BlendingMaskCutoffB), ACCESS_PROP_FLOAT(_BlendingMaskCutoffB) + ACCESS_PROP_FLOAT(_BlendingMaskSmoothnessB), maskColor.b);
maskColor = float3(1.0, maskG, maskB);
#else
float maskBlackAndWhite = smoothstep(ACCESS_PROP_FLOAT(_BlendingMaskCutoffWhite), ACCESS_PROP_FLOAT(_BlendingMaskCutoffWhite) + ACCESS_PROP_FLOAT(_BlendingMaskSmoothnessWhite), maskColor.r);
maskColor = float3(maskBlackAndWhite, maskBlackAndWhite, maskBlackAndWhite);
#endif
#else
float3 maskColor = data.vertexColor.rgb;
float maskG = smoothstep(ACCESS_PROP_FLOAT(_BlendingMaskCutoffG), ACCESS_PROP_FLOAT(_BlendingMaskCutoffG) + ACCESS_PROP_FLOAT(_BlendingMaskSmoothnessG), maskColor.g);
float maskB = smoothstep(ACCESS_PROP_FLOAT(_BlendingMaskCutoffB), ACCESS_PROP_FLOAT(_BlendingMaskCutoffB) + ACCESS_PROP_FLOAT(_BlendingMaskSmoothnessB), maskColor.b);
maskColor.g = maskG;
maskColor.b = maskB;
#endif
#ifdef _STOCHASTIC_SAMPLING_ON
float2 dx = 0;
float2 dy = 0;
float stochasticScale = ACCESS_PROP_FLOAT(_StochasticScale);
float stochasticSkew = ACCESS_PROP_FLOAT(_StochasticSkew);
#endif
#ifdef _TEXTUREBLENDINGMODE_RGB
float2 texGUV = SIMPLE_CUSTOM_TRANSFORM_TEX(data.rawMainUV, _BlendingTextureG);
float2 texBUV = SIMPLE_CUSTOM_TRANSFORM_TEX(data.rawMainUV, _BlendingTextureB);
float4 texG = 0;
float4 texB = 0;
#ifdef _STOCHASTIC_SAMPLING_ON
float4x3 stochasticOffsets_G = getStochasticOffsets(texGUV, stochasticScale, stochasticSkew);
STOCHASTIC_SAMPLING_NO_DEF_DD(_BlendingTextureG, texGUV, stochasticOffsets_G, texG)
float4x3 stochasticOffsets_B = getStochasticOffsets(texBUV, stochasticScale, stochasticSkew);
STOCHASTIC_SAMPLING_NO_DEF_DD(_BlendingTextureB, texGUV, stochasticOffsets_B, texB)
#else
texG = SAMPLE_TEX2D(_BlendingTextureG, texGUV);
texB = SAMPLE_TEX2D(_BlendingTextureB, texBUV);
#endif
res = lerp(res, texG, maskColor.g);
res = lerp(res, texB, maskColor.b);
#else
float2 texWhiteUV = SIMPLE_CUSTOM_TRANSFORM_TEX(data.rawMainUV, _BlendingTextureWhite);
float4 texWhite = 0;
#ifdef _STOCHASTIC_SAMPLING_ON
float4x3 stochasticOffsets_W = getStochasticOffsets(texWhiteUV, stochasticScale, stochasticSkew);
STOCHASTIC_SAMPLING_NO_DEF_DD(_BlendingTextureWhite, texWhiteUV, stochasticOffsets_W, texWhite)
#else
texWhite = SAMPLE_TEX2D(_BlendingTextureWhite, texWhiteUV);
#endif
res = lerp(res, texWhite, maskColor.r);
#endif
return res;
}
#endif
#ifdef _HOLOGRAM_ON
float4 Hologram(float4 inputColor, EffectsData data)
{
float4 res = inputColor;
float3 dir = normalize(ACCESS_PROP_FLOAT3(_HologramLineDirection).xyz);
// Calculate primary hologram pattern using direction projection
float3 scrollPos1 = data.vertexWS * ACCESS_PROP_FLOAT(_HologramFrequency) + (data.shaderTime.y * ACCESS_PROP_FLOAT(_HologramScrollSpeed));
float3 scrollUV1 = frac(scrollPos1);
float projectedValue1 = dot(scrollUV1, normalize(dir));
float distance1 = abs(projectedValue1 - ACCESS_PROP_FLOAT(_HologramLineCenter)) * ACCESS_PROP_FLOAT(_HologramLineSpacing);
float gradientMask1 = 1 - distance1;
gradientMask1 = pow(saturate(gradientMask1), ACCESS_PROP_FLOAT(_HologramLineSmoothness));
gradientMask1 = max(gradientMask1, ACCESS_PROP_FLOAT(_HologramBaseAlpha));
// Calculate accent line pattern using direction projection
float3 scrollPos2 = data.vertexWS * ACCESS_PROP_FLOAT(_HologramAccentFrequency) + (data.shaderTime.y * ACCESS_PROP_FLOAT(_HologramAccentSpeed));
float3 scrollUV2 = frac(scrollPos2);
float projectedValue2 = dot(scrollUV2, normalize(dir));
float distance2 = abs(projectedValue2 - ACCESS_PROP_FLOAT(_HologramLineCenter)) * ACCESS_PROP_FLOAT(_HologramLineSpacing);
float gradientMask2 = 1 - distance2;
gradientMask2 = pow(saturate(gradientMask2), ACCESS_PROP_FLOAT(_HologramLineSmoothness));
// Combine both patterns
float combinedMask = saturate(gradientMask1 * ACCESS_PROP_FLOAT(_HologramAlpha) + gradientMask2 * ACCESS_PROP_FLOAT(_HologramAccentAlpha));
float4 finalColor = ACCESS_PROP_FLOAT4(_HologramColor);
finalColor.a = combinedMask * ACCESS_PROP_FLOAT4(_HologramColor).a;
res *= finalColor;
return res;
}
#endif
#ifdef _MATCAP_ON
float3 Matcap(EffectsData data)
{
#ifdef _NORMAL_MAP_ON
float3 normalMapOS = normalize(mul(UNITY_MATRIX_IT_MV, float4(data.normalWS, 0.0)).xyz);
float3 normalVS = normalize(mul(UNITY_MATRIX_MV, float4(normalMapOS, 0.0)).xyz);
#else
float3 normalVS = normalize(mul(UNITY_MATRIX_MV, float4(data.normalOS, 0.0)).xyz);
#endif
float3 positionVSDir = normalize(GetPositionVS(data.vertexOS));
float3 normalCrossPosition = cross(positionVSDir, normalVS);
float u = (-normalCrossPosition.y * 0.5) + 0.5;
float v = (normalCrossPosition.x * 0.5) + 0.5;
float2 matcapUV = float2(u, v);
float3 res = SAMPLE_TEX2D(_MatcapTex, matcapUV).rgb * ACCESS_PROP_FLOAT(_MatcapIntensity);
return res;
}
#endif
#ifdef _COLOR_RAMP_ON
float4 ColorRamp(float4 inputColor, EffectsData data)
{
float luminance = GetLuminance(inputColor);
luminance = saturate(luminance + ACCESS_PROP_FLOAT(_ColorRampLuminosity));
float2 rampUV = float2(luminance, 0);
rampUV.x *= ACCESS_PROP_FLOAT(_ColorRampTiling);
rampUV.x += frac(data.shaderTime.x * ACCESS_PROP_FLOAT(_ColorRampScrollSpeed));
float3 colorRamp = SAMPLE_TEX2D(_ColorRampTex, rampUV).rgb;
float3 resRGB = lerp(inputColor.rgb, colorRamp, ACCESS_PROP_FLOAT(_ColorRampBlend));
float4 res = float4(resRGB, inputColor.a);
return res;
}
#endif
#ifdef _HIT_ON
float4 Hit(float4 inputColor)
{
float3 resRGB = lerp(inputColor.rgb, ACCESS_PROP_FLOAT4(_HitColor).rgb * ACCESS_PROP_FLOAT(_HitGlow), ACCESS_PROP_FLOAT(_HitBlend));
float4 res = float4(resRGB, inputColor.a);
return res;
}
#endif
#ifdef _RIM_LIGHTING_ON
float3 Rim(float3 inputColorRGB, EffectsData data)
{
float3 rimOffset = ACCESS_PROP_FLOAT3(_RimOffset);
float rimIntensity = 0;
UNITY_BRANCH
if(dot(rimOffset, rimOffset) > 0.001f) //If we have an offset we calculate it
{
float3 viewSpaceOffset = mul((float3x3)UNITY_MATRIX_V, -rimOffset);
float3 normalizedViewDir = normalize(data.viewDirWS);
float3 biasedViewDir = normalize(normalizedViewDir + viewSpaceOffset);
float NdotV = saturate(dot(data.normalWS, biasedViewDir));
rimIntensity = smoothstep(ACCESS_PROP_FLOAT(_MinRim), ACCESS_PROP_FLOAT(_MaxRim), 1 - NdotV) * ACCESS_PROP_FLOAT(_RimAttenuation);
}
else //Otherwise we take quick path
{
float3 normalizedViewDir = normalize(data.viewDirWS);
float NdotV = saturate(dot(data.normalWS, normalizedViewDir));
rimIntensity = smoothstep(ACCESS_PROP_FLOAT(_MinRim), ACCESS_PROP_FLOAT(_MaxRim), 1 - NdotV) * ACCESS_PROP_FLOAT(_RimAttenuation);
}
return lerp(inputColorRGB, ACCESS_PROP_FLOAT4(_RimColor).rgb, rimIntensity);
}
#endif
#ifdef _GREYSCALE_ON
float3 Greyscale(float3 inputColorRGB)
{
float3 res = inputColorRGB;
float luminance = GetLuminance(res);
luminance = saturate(luminance + ACCESS_PROP_FLOAT(_GreyscaleLuminosity));
res = lerp(res, luminance * ACCESS_PROP_FLOAT4(_GreyscaleTintColor).rgb, ACCESS_PROP_FLOAT(_GreyscaleBlending));
return res;
}
#endif
#ifdef _POSTERIZE_ON
float3 Posterize(float3 inputColorRGB)
{
float3 res = inputColorRGB;
float gamma = ACCESS_PROP_FLOAT(_PosterizeGamma);
float numColors = ACCESS_PROP_FLOAT(_PosterizeNumColors);
res.rgb = pow(res.rgb, gamma) * numColors;
res.rgb = floor(res.rgb) / numColors;
res.rgb = pow(res.rgb, 1.0 / gamma);
return res;
}
#endif
#ifdef _HIGHLIGHTS_ON
float3 Highlights(float3 inputColorRGB, EffectsData data)
{
float3 normalizedLightDir = normalize(data.lightDir);
float3 offsetLightDir = normalize(normalizedLightDir + ACCESS_PROP_FLOAT3(_HighlightOffset));
float3 normalizedViewDir = normalize(data.viewDirWS);
float NdotL = saturate(dot(data.normalWS, offsetLightDir));
float NdotV = saturate(dot(data.normalWS, normalizedViewDir));
float rimFactor = 1.0 - NdotV;
float highlightCutoff = ACCESS_PROP_FLOAT(_HighlightCutoff);
float highlightSmoothness = ACCESS_PROP_FLOAT(_HighlightSmoothness);
float highlightsIntensity = smoothstep(highlightCutoff, highlightCutoff + highlightSmoothness, rimFactor);
float3 highlights = highlightsIntensity * NdotL * ACCESS_PROP_FLOAT4(_HighlightsColor).rgb * ACCESS_PROP_FLOAT(_HighlightsStrength);
return inputColorRGB * (highlights + 1);
}
#endif
#ifdef _CONTRAST_BRIGHTNESS_ON
float3 ContrastBrightness(float3 inputColorRGB)
{
float3 res = ContrastBrightness(inputColorRGB, ACCESS_PROP_FLOAT(_Contrast), ACCESS_PROP_FLOAT(_Brightness));
return res;
}
#endif
#ifdef _HEIGHT_GRADIENT_ON
float4 HeightGradient(float4 inputColor, EffectsData data)
{
float4 res = inputColor;
#ifdef _HEIGHTGRADIENTPOSITIONSPACE_WORLD
float3 selectedPos = data.vertexWS;
#else
float3 selectedPos = data.vertexOS;
#endif
float gradient = RemapFloat(selectedPos.y, ACCESS_PROP_FLOAT(_MinGradientHeight), ACCESS_PROP_FLOAT(_MaxGradientHeight), 0.0, 1.0);
gradient = saturate(gradient);
float4 gradientColor = lerp(ACCESS_PROP_FLOAT4(_GradientHeightColor01), ACCESS_PROP_FLOAT4(_GradientHeightColor02), gradient);
res *= gradientColor;
return res;
}
#endif
#ifdef _INTERSECTION_GLOW_ON
float4 IntersectionGlow(float4 inputColor, EffectsData data)
{
float4 res = inputColor;
float depthGlowMask = saturate(ACCESS_PROP_FLOAT(_DepthGlowDist) * pow(max(0, 1 - data.sceneDepthDiff), ACCESS_PROP_FLOAT(_DepthGlowPower)));
res.rgb = lerp(res.rgb, ACCESS_PROP_FLOAT(_DepthGlowGlobalIntensity) * res.rgb, depthGlowMask);
res.rgb += ACCESS_PROP_FLOAT4(_DepthGlowColor).rgb * ACCESS_PROP_FLOAT(_DepthGlowColorIntensity) * depthGlowMask * res.a;
return res;
}
#endif
#ifdef _DEPTH_COLORING_ON
float4 DepthColoring(float4 inputColor, EffectsData data)
{
float4 res = inputColor;
float eyeDepth = GetEyeDepth(data.vertexVS);
float eyeDepth01 = smoothstep(global_MinDepth, global_MinDepth + global_DepthZoneLength, eyeDepth);
eyeDepth01 = pow(eyeDepth01, global_DepthGradientFallOff);
#ifdef FORWARD_ADD_PASS
res *= (1 - eyeDepth01);
#else
float4 depthCol = SAMPLE_TEX2D(global_DepthGradient, float2(eyeDepth01, 0));
res = lerp(res, depthCol, depthCol.a);
#endif
return res;
}
#endif
#ifdef _SUBSURFACE_SCATTERING_ON
float4 SubsurfaceScattering(float4 inputColor, EffectsData data)
{
float4 res = inputColor;
float4 sssMapColor = SAMPLE_TEX2D(_SSSMap, data.mainUV);
//Why do we need to add 1000 for this to look good?
float3 lightColor = GetMainLightColorRGB() * 5;
float lightIntensity = GetMainLightIntensity();
float3 normalizedViewDir = normalize(data.viewDirWS);
float3 scatterNormal = (data.normalWS * ACCESS_PROP_FLOAT(_NormalInfluence)) + data.lightDir;
scatterNormal = -normalize(scatterNormal);
float VdotScatterNormal = saturate(dot(scatterNormal, normalizedViewDir));
float sssPower = max(1.0, ACCESS_PROP_FLOAT(_SSSPower));
float backScatterFactor = pow(VdotScatterNormal, sssPower);
float frontScatter = saturate(dot(data.normalWS, data.lightDir)); // How directly light hits surface
float frontVdotN = 1.0 - saturate(dot(normalizedViewDir, data.normalWS)); // Fresnel-like front falloff
frontVdotN = pow(frontVdotN, ACCESS_PROP_FLOAT(_SSSFrontPower));
float frontScatterFactor = frontScatter * frontVdotN * ACCESS_PROP_FLOAT(_SSSFrontAtten);
float scatterIntensity = max(backScatterFactor, frontScatterFactor) * ACCESS_PROP_FLOAT(_SSSAtten) * sssMapColor.r;
// Simulate wavelength-dependent scattering with original scatter calculation
float3 deepScatterColor = float3(1.0, 0.3, 0.2);
float3 scatterColor = scatterIntensity * lightColor.rgb * lightIntensity * ACCESS_PROP_FLOAT4(_SSSColor).rgb;
scatterColor *= lerp(float3(1,1,1), deepScatterColor, VdotScatterNormal);
res.rgb += scatterColor * inputColor.rgb;
return res;
}
#endif
#endif