Add painted-height HUD sliders for AO shift and relief intensity
Wire three material-backed look sliders (occlusion AO shift, relief normal intensity, parallax intensity) through the paint HUD, its layout/state persistence, the .paint slot format (bumped to v4), owner-authoritative network sync and the runtime reset, mirroring the existing camo-knob path so they save, restore, replicate and reset alongside the brush values. Change the occlusion AO mapping from a division threshold to a linear shift: AO fades from 1 down to (1 - shift) at the deepest painted hole, so a 0 shift no longer leaves black spots. Enable _NORMALMAP alongside _PARALLAXMAP so URP transforms the painted relief normal into world space (otherwise it discards normalTS and the relief is invisible), and pin the added keyword in the build keep-alive material. Stop the pipette from picking the occlusion/height value and turn its toggle off after a pick. Default the knobs to 0.2 shift / 1.4 normal / 1.0 parallax across the shader, painter, network and HUD fallbacks. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
fdcb4f8d8a
commit
59939b3496
11 files changed
+216
-49
No files matched your search
@@ -40,10 +40,15 @@ half _SpecularDampen;
|
||||
// The UV displacement is URP's stock single-step parallax (ParallaxOffset1Step already does
|
||||
// height*amp - amp/2, i.e. the 0.5 centring) under the _PARALLAXMAP keyword. Here we add the
|
||||
// matching per-pixel relief NORMAL from the height gradient (the dominant cue) and remap the ambient
|
||||
// occlusion so only the LOWER half darkens: AO = saturate(occ*2) (occ>=0.5 -> no darkening, occ in
|
||||
// [0,0.5] -> AO 1..0). Declared outside UnityPerMaterial like the camo knobs above (the player is a
|
||||
// occlusion so only the LOWER half darkens, with the darkening DEPTH driven by _OcclusionThreshold
|
||||
// (a shift, see below). Declared outside UnityPerMaterial like the camo knobs above (the player is a
|
||||
// handful of instances, so the SRP-batcher break is irrelevant).
|
||||
half _HeightNormalStrength;
|
||||
// Runtime intensities tuned from the paint HUD. _HeightNormalIntensity scales the relief normal
|
||||
// (default 1). _OcclusionThreshold is a SHIFT (0..1, default 0.5): the AO darkening depth at the
|
||||
// deepest painted hole - 0 = no darkening at all, 1 = AO reaches full black at occ=0.
|
||||
half _HeightNormalIntensity;
|
||||
half _OcclusionThreshold;
|
||||
float4 _OcclusionMap_TexelSize;
|
||||
|
||||
// Remaps the painted occlusion/height value into surface AO + a relief normal. Runs after URP's
|
||||
@@ -52,9 +57,14 @@ float4 _OcclusionMap_TexelSize;
|
||||
void ApplyPaintedHeightSurface(float2 uv, inout SurfaceData surfaceData)
|
||||
{
|
||||
#if defined(_OCCLUSIONMAP)
|
||||
// Lower-half AO remap: occ>=0.5 stays fully lit, occ in [0,0.5] darkens toward 0.
|
||||
// Only the lower (recessed) half of the painted height darkens. _OcclusionThreshold is a SHIFT =
|
||||
// how DEEP the darkening reaches at the deepest hole: AO fades from 1 (occ>=0.5, neutral/hill)
|
||||
// down to (1 - shift) at occ=0. shift=0 -> AO stays 1 everywhere (no darkening, no black spots),
|
||||
// shift=0.5 -> AO in [0.5,1], shift=1 -> AO in [0,1] (full darkening). Linear over occ in [0,0.5].
|
||||
half occ = SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv).g;
|
||||
surfaceData.occlusion = LerpWhiteTo(saturate(occ * 2.0h), _OcclusionStrength);
|
||||
half depth = saturate(1.0h - occ * 2.0h); // 0 at occ>=0.5 (neutral/hill), 1 at occ=0 (deepest)
|
||||
half ao = 1.0h - depth * _OcclusionThreshold; // darken toward (1 - shift) as the hole deepens
|
||||
surfaceData.occlusion = LerpWhiteTo(ao, _OcclusionStrength);
|
||||
#endif
|
||||
|
||||
#if defined(_PARALLAXMAP)
|
||||
@@ -65,8 +75,9 @@ void ApplyPaintedHeightSurface(float2 uv, inout SurfaceData surfaceData)
|
||||
half hR = SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv + float2(texel.x, 0.0)).g;
|
||||
half hD = SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv - float2(0.0, texel.y)).g;
|
||||
half hU = SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv + float2(0.0, texel.y)).g;
|
||||
half3 reliefTS = normalize(half3((hL - hR) * _HeightNormalStrength,
|
||||
(hD - hU) * _HeightNormalStrength, 1.0h));
|
||||
half strength = _HeightNormalStrength * _HeightNormalIntensity;
|
||||
half3 reliefTS = normalize(half3((hL - hR) * strength,
|
||||
(hD - hU) * strength, 1.0h));
|
||||
surfaceData.normalTS = BlendNormalRNM(surfaceData.normalTS, reliefTS);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -44,6 +44,11 @@ Shader "Custom/PlayerCamoLit"
|
||||
_Parallax("Scale", Range(0.005, 0.08)) = 0.005
|
||||
_ParallaxMap("Height Map", 2D) = "black" {}
|
||||
_HeightNormalStrength("Painted Height Normal Strength", Range(0.0, 50.0)) = 8.0
|
||||
// Runtime knobs for the painted-height look (1 = base, tuned live in the paint HUD):
|
||||
_HeightNormalIntensity("Painted Height Normal Intensity", Range(0.0, 2.0)) = 1.4
|
||||
// AO darkening DEPTH (shift): AO fades from 1 down to (1 - this) at the deepest painted hole.
|
||||
// 0 = no darkening (no black spots), 1 = full black at occ=0.
|
||||
_OcclusionThreshold("Painted Occlusion AO Shift", Range(0.0, 1.0)) = 0.2
|
||||
|
||||
_OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0
|
||||
_OcclusionMap("Occlusion", 2D) = "white" {}
|
||||
|
||||
Reference in new issue
Block a user