diff --git a/Source/Editor/Tools/Terrain/Paint/Mode.cs b/Source/Editor/Tools/Terrain/Paint/Mode.cs index bf9857bea..03e4a4690 100644 --- a/Source/Editor/Tools/Terrain/Paint/Mode.cs +++ b/Source/Editor/Tools/Terrain/Paint/Mode.cs @@ -209,8 +209,7 @@ namespace FlaxEditor.Tools.Terrain.Paint public int SplatmapIndex; /// - /// The splatmap texture index. If is 0, this will be 1. - /// If is 1, this will be 0. + /// The splatmap texture index. If is 0, this will be 1. If is 1, this will be 0. /// public int SplatmapIndexOther; @@ -220,8 +219,7 @@ namespace FlaxEditor.Tools.Terrain.Paint public Color32* TempBuffer; /// - /// The 'other" temporary data buffer (for modified data). If refers - /// to the splatmap with index 0, this one will refer to the one with index 1. + /// The 'other' temporary data buffer (for modified data). If refersto the splatmap with index 0, this one will refer to the one with index 1. /// public Color32* TempBufferOther; diff --git a/Source/Editor/Tools/Terrain/Paint/SingleLayerMode.cs b/Source/Editor/Tools/Terrain/Paint/SingleLayerMode.cs index d0c76a830..5921f7d10 100644 --- a/Source/Editor/Tools/Terrain/Paint/SingleLayerMode.cs +++ b/Source/Editor/Tools/Terrain/Paint/SingleLayerMode.cs @@ -76,6 +76,7 @@ namespace FlaxEditor.Tools.Terrain.Paint // Apply brush modification Profiler.BeginEvent("Apply Brush"); + bool otherModified = false; for (int z = 0; z < p.ModifiedSize.Y; z++) { var zz = z + p.ModifiedOffset.Y; @@ -86,34 +87,38 @@ namespace FlaxEditor.Tools.Terrain.Paint var samplePositionLocal = p.PatchPositionLocal + new Vector3(xx * FlaxEngine.Terrain.UnitsPerVertex, 0, zz * FlaxEngine.Terrain.UnitsPerVertex); Vector3.Transform(ref samplePositionLocal, ref p.TerrainWorld, out Vector3 samplePositionWorld); + var sample = Mathf.Saturate(p.Brush.Sample(ref brushPosition, ref samplePositionWorld)); + + var paintAmount = sample * strength; + if (paintAmount < 0.0f) + continue; // Skip when pixel won't be affected - var sample = Mathf.Clamp(p.Brush.Sample(ref brushPosition, ref samplePositionWorld), 0f, 1f); - var paintAmount = sample * strength * (1f - src[c]); - // Paint on the active splatmap texture - src[c] = Mathf.Clamp(src[c] + paintAmount, 0, 1f); - src[(c + 1) % 4] = Mathf.Clamp(src[(c + 1) % 4] - paintAmount, 0, 1f); - src[(c + 2) % 4] = Mathf.Clamp(src[(c + 2) % 4] - paintAmount, 0, 1f); - src[(c + 3) % 4] = Mathf.Clamp(src[(c + 3) % 4] - paintAmount, 0, 1f); - + src[c] = Mathf.Saturate(src[c] + paintAmount); + src[(c + 1) % 4] = Mathf.Saturate(src[(c + 1) % 4] - paintAmount); + src[(c + 2) % 4] = Mathf.Saturate(src[(c + 2) % 4] - paintAmount); + src[(c + 3) % 4] = Mathf.Saturate(src[(c + 3) % 4] - paintAmount); p.TempBuffer[z * p.ModifiedSize.X + x] = src; - // Remove 'paint' from the other splatmap texture var other = (Color)p.SourceDataOther[zz * p.HeightmapSize + xx]; - - other[c] = Mathf.Clamp(other[c] - paintAmount, 0, 1f); - other[(c + 1) % 4] = Mathf.Clamp(other[(c + 1) % 4] - paintAmount, 0, 1f); - other[(c + 2) % 4] = Mathf.Clamp(other[(c + 2) % 4] - paintAmount, 0, 1f); - other[(c + 3) % 4] = Mathf.Clamp(other[(c + 3) % 4] - paintAmount, 0, 1f); - - p.TempBufferOther[z * p.ModifiedSize.X + x] = other; + //if (other.ValuesSum > 0.0f) // Skip editing the other splatmap if it's empty + { + // Remove 'paint' from the other splatmap texture + other[c] = Mathf.Saturate(other[c] - paintAmount); + other[(c + 1) % 4] = Mathf.Saturate(other[(c + 1) % 4] - paintAmount); + other[(c + 2) % 4] = Mathf.Saturate(other[(c + 2) % 4] - paintAmount); + other[(c + 3) % 4] = Mathf.Saturate(other[(c + 3) % 4] - paintAmount); + p.TempBufferOther[z * p.ModifiedSize.X + x] = other; + otherModified = true; + } } } Profiler.EndEvent(); // Update terrain patch TerrainTools.ModifySplatMap(p.Terrain, ref p.PatchCoord, p.SplatmapIndex, p.TempBuffer, ref p.ModifiedOffset, ref p.ModifiedSize); - TerrainTools.ModifySplatMap(p.Terrain, ref p.PatchCoord, p.SplatmapIndexOther, p.TempBufferOther, ref p.ModifiedOffset, ref p.ModifiedSize); + if (otherModified) + TerrainTools.ModifySplatMap(p.Terrain, ref p.PatchCoord, p.SplatmapIndexOther, p.TempBufferOther, ref p.ModifiedOffset, ref p.ModifiedSize); } } } diff --git a/Source/Engine/Core/Math/Color.cs b/Source/Engine/Core/Math/Color.cs index d585177a0..7474b913d 100644 --- a/Source/Engine/Core/Math/Color.cs +++ b/Source/Engine/Core/Math/Color.cs @@ -92,6 +92,21 @@ namespace FlaxEngine /// public float MaxColorComponent => Mathf.Max(Mathf.Max(R, G), B); + /// + /// Gets a minimum component value (max of r,g,b,a). + /// + public float MinValue => Math.Min(R, Math.Min(G, Math.Min(B, A))); + + /// + /// Gets a maximum component value (min of r,g,b,a). + /// + public float MaxValue => Math.Max(R, Math.Max(G, Math.Max(B, A))); + + /// + /// Gets a sum of the component values. + /// + public float ValuesSum => R + G + B + A; + /// /// Constructs a new Color with given r,g,b,a component. ///