Add spray brush, paint interval, and per-channel paint opacity
Spray brush mode: bakes a procedural scattered-dot mask per stamp (random position, size, alpha within the brush disc) and paints it through the existing single-stamp pipeline; dot centers clamped to (0.5 - dotR) so the spray footprint matches the solid brush radius. Paint interval: float on MeshPainter; 0 keeps the continuous interpolated stroke, >0 emits a single timed dab every x.xx seconds. Color picker alpha: horizontal alpha bar on both HSV pickers, runtime-built in Rebind (no prefab re-bake), passed through to brushColor.a / emissionColor.a. Metallic/smoothness + occlusion paint opacity: new opacity fields applied in both CPU and GPU backends (GPU MSO draw split into MS and occlusion sub-stamps for independent opacity), with cloned alpha sliders wired into the HUD. Also includes the prefab layout tweaks and scene adjustments. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
af3aa34d66
commit
b07d9a22d2
9 files changed
+1227
-86
No files matched your search
@@ -112,6 +112,8 @@ public partial class MeshPainter
|
||||
float msoR = Mathf.Clamp01(metallic) * 255f; // metallic
|
||||
float msoG = Mathf.Clamp01(occlusion) * 255f; // occlusion
|
||||
float msoA = Mathf.Clamp01(smoothness) * 255f; // smoothness
|
||||
float msOpMul = Mathf.Clamp01(metallicSmoothnessOpacity); // metallic+smoothness paint opacity
|
||||
float aoOpMul = Mathf.Clamp01(occlusionOpacity); // occlusion paint opacity
|
||||
CpuMap mso = _cpu[MAP_MSO];
|
||||
bool aMSO = aMS || aAO;
|
||||
|
||||
@@ -210,14 +212,16 @@ public partial class MeshPainter
|
||||
|
||||
if (aMSO)
|
||||
{
|
||||
// Mask map blend (op = mask, no extra alpha multiplier). Metallic(R) +
|
||||
// smoothness(A) only when painting MS; occlusion(G) only when painting AO.
|
||||
// Untouched channels keep their previous value; B stays 0.
|
||||
// Mask map blend. Metallic(R) + smoothness(A) blend with the MS opacity,
|
||||
// occlusion(G) with its own opacity - each = mask * the channel's opacity
|
||||
// multiplier (the albedo brushColor.a equivalent). Untouched channels keep
|
||||
// their previous value; B stays 0.
|
||||
Color32 dst = mso.pixels[idx];
|
||||
float it = 1f - maskOp;
|
||||
byte mr = aMS ? (byte)(dst.r * it + msoR * maskOp) : dst.r;
|
||||
byte mg = aAO ? (byte)(dst.g * it + msoG * maskOp) : dst.g;
|
||||
byte ma = aMS ? (byte)(dst.a * it + msoA * maskOp) : dst.a;
|
||||
float msOp = maskOp * msOpMul;
|
||||
float aoOp = maskOp * aoOpMul;
|
||||
byte mr = aMS ? (byte)(dst.r * (1f - msOp) + msoR * msOp) : dst.r;
|
||||
byte mg = aAO ? (byte)(dst.g * (1f - aoOp) + msoG * aoOp) : dst.g;
|
||||
byte ma = aMS ? (byte)(dst.a * (1f - msOp) + msoA * msOp) : dst.a;
|
||||
mso.pixels[idx] = new Color32(mr, mg, 0, ma);
|
||||
mso.painted[idx] = true;
|
||||
ExpandDirty(mso, x, y);
|
||||
|
||||
Reference in new issue
Block a user