Pick height/occlusion channel when sampling own player
The pipette now reads the height (occlusion) value from the own paint mesh and enables the height toggle; picking anything else disables the toggle while leaving value and alpha untouched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
68ee58a167
commit
5149544afe
1 file changed
+26
-13
@@ -9,8 +9,9 @@ public partial class MeshPainter
|
||||
// left-click raycasts onto ANY surface (not just the paint mesh) and reads the channel values at
|
||||
// the hit point (albedo, metallic, smoothness, emission) into the brush properties. The brush
|
||||
// opacities/alphas (albedo alpha, metallic/smoothness opacity, emission alpha) are left UNTOUCHED,
|
||||
// so a pick changes only WHAT is painted, not how strongly. Occlusion is excluded: it drives painted
|
||||
// height now, so the pipette neither samples it nor enables its toggle.
|
||||
// so a pick changes only WHAT is painted, not how strongly. Height (the occlusion channel) is picked
|
||||
// and its toggle enabled ONLY when our own paint mesh is hit; any other surface leaves the height
|
||||
// value untouched and disables its toggle. The height opacity (occlusionOpacity) is untouched either way.
|
||||
//
|
||||
// On a FOREIGN object the data channels (metallic/smoothness/emission) come texel-exact
|
||||
// from the material (raw, UNLIT). Albedo follows the 'pipetteAlbedoFromScreen' toggle: OFF (default)
|
||||
@@ -22,9 +23,11 @@ public partial class MeshPainter
|
||||
|
||||
[Header("Brush - pipette (eyedropper)")]
|
||||
[Tooltip("Pipette mode: a click samples the channel values at the hit point on ANY surface " +
|
||||
"(albedo, metallic, smoothness, emission - NOT occlusion/height) and adopts them into the " +
|
||||
"brush (opacities/alphas left untouched) instead of painting. On a foreign object the data " +
|
||||
"channels are read texel-exact from the material; albedo follows 'Pipette Albedo From Screen'. Held button picks once.")]
|
||||
"(albedo, metallic, smoothness, emission) and adopts them into the brush (opacities/alphas " +
|
||||
"left untouched) instead of painting. Height (occlusion) is adopted and its toggle enabled " +
|
||||
"only when our own paint mesh is picked; any other surface disables the height toggle. On a " +
|
||||
"foreign object the data channels are read texel-exact from the material; albedo follows " +
|
||||
"'Pipette Albedo From Screen'. Held button picks once.")]
|
||||
public bool pipette = false;
|
||||
|
||||
[Tooltip("On a foreign-object pick, where albedo comes from. OFF (default): albedo is read " +
|
||||
@@ -48,7 +51,8 @@ public partial class MeshPainter
|
||||
/// <summary>
|
||||
/// Raycasts at a screen position against ANY collider, samples the channel values at the hit
|
||||
/// (texel-exact where possible) and copies them into the brush, leaving the brush opacities/alphas
|
||||
/// untouched and enabling those paint channels. Occlusion/height is excluded (see FinalizePick). Reads
|
||||
/// untouched and enabling those paint channels. Height (occlusion) is adopted and its toggle enabled
|
||||
/// only when our own paint mesh is hit; any other surface disables it (see FinalizePick). Reads
|
||||
/// regardless of which channels are currently toggled.
|
||||
/// Pick paths, by what was hit:
|
||||
/// - our paint mesh -> texel-exact from the painted maps (full PBR);
|
||||
@@ -61,10 +65,16 @@ public partial class MeshPainter
|
||||
private void PickAtScreen(Vector2 screenPos)
|
||||
{
|
||||
bool ok;
|
||||
// Height (occlusion) is only meaningful off our OWN painted maps, so a hit on our paint mesh is
|
||||
// the sole pick that enables the height channel - every other surface leaves it off (FinalizePick).
|
||||
bool pickedHeight = false;
|
||||
if (TryRaycastAny(screenPos, out RaycastHit hit))
|
||||
{
|
||||
if (hit.collider == _collider)
|
||||
{
|
||||
ok = PickFromPaintTextures(hit);
|
||||
pickedHeight = ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
Terrain terrain = hit.collider is TerrainCollider ? hit.collider.GetComponent<Terrain>() : null;
|
||||
@@ -82,22 +92,23 @@ public partial class MeshPainter
|
||||
}
|
||||
if (!ok) return;
|
||||
|
||||
FinalizePick();
|
||||
FinalizePick(pickedHeight);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Common tail of every successful pick: enables the sampled paint channels, leaves pipette mode
|
||||
/// (one-shot) and notifies listeners (the in-game HUD) to re-sync their widgets. The brush
|
||||
/// opacities/alphas (albedo alpha, metallic/smoothness opacity, emission alpha) are left UNTOUCHED,
|
||||
/// so a pick changes only WHAT is painted, not how strongly. Occlusion is deliberately EXCLUDED:
|
||||
/// that channel now drives painted height, not a surface property to sample, so the pipette neither
|
||||
/// reads it (see the pick paths) nor enables its toggle - the deliberate height brush value is left untouched.
|
||||
/// so a pick changes only WHAT is painted, not how strongly. Height (the occlusion channel) is a
|
||||
/// special case: <paramref name="pickedHeight"/> is true only when our own paint mesh was picked -
|
||||
/// then the height toggle is enabled with the adopted value; any other surface disables the toggle
|
||||
/// and keeps the deliberate height value. The height opacity (occlusionOpacity) is untouched either way.
|
||||
/// </summary>
|
||||
private void FinalizePick()
|
||||
private void FinalizePick(bool pickedHeight)
|
||||
{
|
||||
paintAlbedo = true;
|
||||
paintMetallicSmoothness = true;
|
||||
paintOcclusion = false;
|
||||
paintOcclusion = pickedHeight;
|
||||
paintEmission = true;
|
||||
|
||||
pipette = false;
|
||||
@@ -140,10 +151,12 @@ public partial class MeshPainter
|
||||
|
||||
// sRGB bytes map straight back into the gamma-space brush colours (round-trips exactly). The
|
||||
// alpha (paint opacity) is deliberately preserved, not overwritten - a pick changes only the colour.
|
||||
// Occlusion (m.g) is NOT picked: it now drives painted height, kept as the deliberate brush value.
|
||||
brushColor = new Color(a.r / 255f, a.g / 255f, a.b / 255f, brushColor.a);
|
||||
metallic = m.r / 255f;
|
||||
smoothness = m.a / 255f;
|
||||
// Occlusion (m.g) is the painted HEIGHT: adopted only off our own paint mesh, which is the sole
|
||||
// pick that enables the height toggle (FinalizePick). Its opacity (occlusionOpacity) is left as-is.
|
||||
occlusion = m.g / 255f;
|
||||
emissionColor = new Color(e.r / 255f, e.g / 255f, e.b / 255f, emissionColor.a);
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user