184 lines
5.1 KiB
HLSL
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 |