Add a toggle for picking foreign albedo from screen or material
The hybrid foreign-object pipette previously always overwrote albedo with the lit on-screen pixel. Gate that behind a new serialized pipetteAlbedoFromScreen flag (default off): off reads albedo texel-exact from the material like the other channels, on takes it from the rendered, fully-lit pixel. The data channels still always come from the material. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
4da2e3a70c
commit
67e3696339
1 file changed
+26
-17
@@ -10,20 +10,27 @@ public partial class MeshPainter
|
||||
// the hit point (albedo, metallic, smoothness, occlusion, emission) into the brush properties -
|
||||
// with every opacity/alpha forced to 1 so re-painting reproduces the picked look at full strength.
|
||||
//
|
||||
// On a FOREIGN object the pick is a HYBRID: the data channels (metallic/smoothness/occlusion/
|
||||
// emission) come texel-exact from the material (raw, UNLIT), while albedo is taken from the
|
||||
// rendered, fully-lit on-screen pixel ("what you see" - honours baked lightmaps/ambient/SSAO).
|
||||
// This combines the PBR fidelity of the material read with the lit look of the screen. When no
|
||||
// texel-exact material read is possible (no readable UV / headless) it falls back to a pure screen
|
||||
// pick (lit albedo, data channels at defaults). Our own paint mesh and terrain are read texel-exact.
|
||||
// On a FOREIGN object the data channels (metallic/smoothness/occlusion/emission) come texel-exact
|
||||
// from the material (raw, UNLIT). Albedo follows the 'pipetteAlbedoFromScreen' toggle: OFF (default)
|
||||
// reads it texel-exact from the material too; ON takes it from the rendered, fully-lit on-screen
|
||||
// pixel ("what you see" - honours baked lightmaps/ambient/SSAO), combining material PBR fidelity
|
||||
// with the lit look. When no texel-exact material read is possible (no readable UV / headless) it
|
||||
// falls back to a pure screen pick (lit albedo, data channels at defaults). Our own paint mesh and
|
||||
// terrain are read texel-exact.
|
||||
|
||||
[Header("Brush - pipette (eyedropper)")]
|
||||
[Tooltip("Pipette mode: a click samples ALL channel values at the hit point on ANY surface " +
|
||||
"(albedo, metallic, smoothness, occlusion, emission) and adopts them into the brush " +
|
||||
"(all alphas set to 1) instead of painting. On a foreign object the data channels are read " +
|
||||
"texel-exact from the material while albedo comes from the lit on-screen pixel. Held button picks once.")]
|
||||
"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 " +
|
||||
"texel-exact from the material like the other channels (raw, unlit). ON: albedo is taken " +
|
||||
"from the lit on-screen pixel ('what you see' - honours baked lightmaps/ambient/SSAO). " +
|
||||
"The data channels (metallic/smoothness/occlusion/emission) always come from the material.")]
|
||||
[SerializeField] private bool pipetteAlbedoFromScreen = false;
|
||||
|
||||
/// <summary>
|
||||
/// Raised after a successful pick, once the brush has adopted the sampled values and all four
|
||||
/// paint-channel flags have been enabled. The in-game HUD listens to re-sync its widgets.
|
||||
@@ -44,8 +51,8 @@ public partial class MeshPainter
|
||||
/// - our paint mesh -> texel-exact from the painted maps (full PBR);
|
||||
/// - terrain ground -> blend of the terrain layers by their splat weights (full PBR);
|
||||
/// - terrain tree / detail -> the rendered on-screen colour (no per-instance renderer/UV);
|
||||
/// - any foreign object -> hybrid: data channels texel-exact from the material, albedo from
|
||||
/// the rendered, fully-lit on-screen pixel (baked lightmaps/ambient/SSAO);
|
||||
/// - any foreign object -> data channels texel-exact from the material; albedo from the
|
||||
/// material or the lit on-screen pixel per pipetteAlbedoFromScreen;
|
||||
/// - anything else / sky -> the rendered on-screen colour.
|
||||
/// </summary>
|
||||
private void PickAtScreen(Vector2 screenPos)
|
||||
@@ -138,19 +145,21 @@ public partial class MeshPainter
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hybrid foreign-object pick: the data channels (metallic/smoothness/occlusion/emission) come
|
||||
/// texel-exact from the material via <see cref="PickFromForeignMaterial"/> (raw, unlit), while
|
||||
/// albedo is overwritten with the rendered, fully-lit on-screen pixel ("what you see" - honours
|
||||
/// baked lightmaps/ambient/SSAO). When no texel-exact material read is possible (no readable UV /
|
||||
/// headless) it falls back to a pure screen pick (lit albedo, data channels at defaults).
|
||||
/// Foreign-object pick: the data channels (metallic/smoothness/occlusion/emission) always come
|
||||
/// texel-exact from the material via <see cref="PickFromForeignMaterial"/> (raw, unlit). Albedo
|
||||
/// follows <see cref="pipetteAlbedoFromScreen"/>: when set, it is overwritten with the rendered,
|
||||
/// fully-lit on-screen pixel ("what you see" - honours baked lightmaps/ambient/SSAO); otherwise
|
||||
/// (default) it stays the material's texel-exact value. When no texel-exact material read is
|
||||
/// possible (no readable UV / headless) it falls back to a pure screen pick (lit albedo, data
|
||||
/// channels at defaults).
|
||||
/// </summary>
|
||||
private bool PickFromForeignHybrid(RaycastHit hit, Vector2 screenPos)
|
||||
{
|
||||
if (PickFromForeignMaterial(hit))
|
||||
{
|
||||
// Keep the material's texel-exact PBR; replace only albedo with the lit on-screen colour.
|
||||
// No camera (headless) -> keep the material's raw albedo rather than failing the pick.
|
||||
if (TrySampleScreenColor(screenPos, out Color lit))
|
||||
// Keep the material's texel-exact PBR; optionally replace albedo with the lit on-screen
|
||||
// colour. No camera (headless) -> keep the material's raw albedo rather than failing.
|
||||
if (pipetteAlbedoFromScreen && TrySampleScreenColor(screenPos, out Color lit))
|
||||
brushColor = new Color(Mathf.Clamp01(lit.r), Mathf.Clamp01(lit.g), Mathf.Clamp01(lit.b), 1f);
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user