Files
Ipseity-Demo/Assets/_Content/Shaders/EnkiBilal/Include/EnkiBiIal.hlsl
T
2026-07-07 19:49:54 +02:00

184 lines
5.1 KiB
HLSL

#ifndef ENKI_BILAL_INCLUDED
#define ENKI_BILAL_INCLUDED
/*
ENKI BILLAL - MEDIUM VERSION WITH SECOND DETAIL LAYER
Goal:
Keep the optimized stylized render while allowing DetailTexB to be tested again.
Changes from the original version:
- Removed custom shadow sampling.
In the original shader, shadowAtten was calculated but never used.
This was pure GPU overhead.
- Removed Lighting.hlsl include.
GetMainLight / GetAdditionalLight are no longer used here.
- Uses the optimized SampleProjectedDetailLOD from Details.hlsl.
- DetailTexA is active when DetailIntensityA > 0.
- DetailTexB is active when DetailIntensityB > 0.
- Both details are limited by camera distance.
- World/Object conversions are computed only once if at least one detail layer is used.
- Simple fog is preserved.
Cost with the new Details.hlsl:
- DetailTexA only: 6 texture samples.
- DetailTexA + DetailTexB: 12 texture samples.
This is still much cheaper than the original setup.
*/
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Assets/_Content/Shaders/Include/Noises.hlsl"
#include "Assets/_Content/Shaders/Include/Details.hlsl"
#include "Assets/_Content/Shaders/Include/Utilities.hlsl"
/*
Maximum distance for projected details.
Lower value = better GPU performance.
Higher value = details visible farther from the camera.
Recommended range:
- 12 to 18 for dense scenes.
- 25 to 30 if details disappear too aggressively in depth.
*/
#define ENKI_DETAIL_MAX_DISTANCE 18.0
/*
Fade range used to avoid a hard cutoff.
Detail starts fading at:
ENKI_DETAIL_MAX_DISTANCE - ENKI_DETAIL_FADE_DISTANCE.
*/
#define ENKI_DETAIL_FADE_DISTANCE 4.0
/*
Safety stub.
If another include or older graph version still calls GetShadow,
the shader will compile and return "no custom shadow".
In this Medium version, custom shadow sampling is intentionally disabled.
*/
float GetShadow(float3 PositionWS)
{
return 0.0;
}
void EnkiBillal_float
(
float4 Color,
UnityTexture2D DetailTexA,
UnityTexture2D DetailTexB,
float2 ScreenUV,
float3 PositionWS,
float3 NormalWS,
float ProjectionsBlend,
float DetailIntensityA,
float DetailIntensityB,
float DetailSizeA,
float DetailSizeB,
uint FogUse,
float4 FogColor,
float FogMin,
float FogMax,
out float3 Output,
out float Alpha
)
{
/*
Base output.
If no extra effect is applied, this function remains very cheap.
*/
Output = Color.rgb;
Alpha = Color.a;
/*
Camera-to-fragment distance.
Used for projected detail distance limiting and optional fog.
*/
float depth = length(PositionWS - _WorldSpaceCameraPos.xyz);
/*
Distance fade for projected details.
detailFade is:
- 1 near the camera.
- 0 beyond ENKI_DETAIL_MAX_DISTANCE.
*/
float detailFadeStart = ENKI_DETAIL_MAX_DISTANCE - ENKI_DETAIL_FADE_DISTANCE;
float detailFade = 1.0 - smoothstep(detailFadeStart, ENKI_DETAIL_MAX_DISTANCE, depth);
float detailWeightA = DetailIntensityA * detailFade;
float detailWeightB = DetailIntensityB * detailFade;
/*
Only compute object-space data if at least one detail layer is actually used.
*/
if (detailWeightA > 0.001 || detailWeightB > 0.001)
{
float3 pivotWS = TransformObjectToWorld(float3(0.0, 0.0, 0.0));
float3 scale = GetScale(pivotWS);
float3 positionOS = TransformWorldToObject(PositionWS) * scale;
float3 normalOS = normalize(TransformWorldToObjectDir(NormalWS));
/*
Detail layer A.
*/
if (detailWeightA > 0.001)
{
float4 detailA = SampleProjectedDetailLOD
(
DetailTexA,
positionOS,
normalOS,
ProjectionsBlend,
DetailSizeA,
depth
);
float detailMaskA = smoothstep(0.0, 0.8, detailA.a);
Output = lerp(Output, detailA.rgb, detailMaskA * detailWeightA);
}
/*
Detail layer B.
This is intentionally restored for testing.
If performance drops too much, set DetailIntensityB to 0
or remove this block again.
*/
if (detailWeightB > 0.001)
{
float4 detailB = SampleProjectedDetailLOD
(
DetailTexB,
positionOS,
normalOS,
ProjectionsBlend,
DetailSizeB,
depth
);
float detailMaskB = smoothstep(0.0, 0.8, detailB.a);
Output = lerp(Output, detailB.rgb, detailMaskB * detailWeightB);
}
}
/*
Simple fog is preserved.
If fog becomes a measurable cost later, it can be moved to a cheaper global pass
or replaced with a simpler approximation.
*/
if (FogUse)
{
float fogFactor = smoothstep(FogMin, FogMax, depth) * FogColor.a;
Output = lerp(Output, FogColor.rgb, fogFactor);
}
}
#endif