Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ object PcIcons {
"Linear Burn" to ours("blend-linear-burn", 26f, "M14.35 6.44L14.27 6.49L12.12 10.46L12.03 10.64L11.91 11.02L11.85 11.41L11.84 11.61L11.87 12L11.96 12.39L12.03 12.57L12.21 12.93L12.32 13.09L12.58 13.4L12.88 13.65L13.22 13.86L13.4 13.94L13.78 14.07L14.17 14.13L14.37 14.14L14.57 14.13L14.96 14.07L15.34 13.94L15.52 13.86L15.86 13.65L16.16 13.4L16.42 13.09L16.62 12.76L16.71 12.57L16.83 12.2L16.89 11.81L16.9 11.61L16.89 11.41L16.83 11.02L16.78 10.82L16.62 10.46L14.47 6.49L14.42 6.45ZM14.39 10.4L14.47 10.45L15.25 12.04L15.33 12.26L15.36 12.49L15.35 12.64L15.28 12.87L15.17 13.07L15.07 13.19L14.95 13.29L14.75 13.4L14.6 13.45L14.37 13.48L14.22 13.46L13.99 13.4L13.79 13.29L13.67 13.19L13.57 13.07L13.46 12.87L13.41 12.72L13.38 12.49L13.41 12.26L13.49 12.04L14.27 10.45L14.32 10.41ZM18.69 16.23L18.84 16.13L18.95 16L19.01 15.89L19.04 15.78L19.04 15.6L18.99 15.43L18.93 15.33L18.85 15.24L18.71 15.13L18.54 15.08L18.42 15.07L18.3 15.09L14.37 15.99L10.44 15.09L10.32 15.07L10.2 15.08L10.09 15.11L9.93 15.2L9.81 15.33L9.73 15.48L9.7 15.6L9.7 15.78L9.76 15.95L9.86 16.09L9.95 16.17L10.11 16.25L11.67 16.61L10.16 16.96L10 17.02L9.86 17.13L9.76 17.28L9.7 17.45L9.7 17.62L9.73 17.74L9.78 17.85L9.84 17.94L9.93 18.03L10.03 18.09L10.14 18.13L10.26 18.15L10.38 18.15L14.37 17.23L18.3 18.14L18.42 18.15L18.54 18.14L18.71 18.09L18.85 17.99L18.93 17.9L19.01 17.74L19.04 17.62L19.04 17.45L18.98 17.28L18.88 17.13L18.79 17.05L18.63 16.97L17.07 16.61Z"),
"Darker Color" to ours("blend-darker-color", 26f, "M21.73 6.38L21.63 6.03L21.45 5.7L21.21 5.41L20.92 5.17L20.59 4.99L20.24 4.89L19.87 4.85L7.67 4.85L7.3 4.89L6.95 4.99L6.62 5.17L6.33 5.41L6.09 5.7L5.91 6.03L5.81 6.38L5.77 6.75L5.77 18.95L5.81 19.32L5.91 19.67L6.09 20L6.33 20.29L6.62 20.53L6.95 20.71L7.3 20.81L7.67 20.85L19.87 20.85L20.24 20.81L20.59 20.71L20.92 20.53L21.21 20.29L21.45 20L21.63 19.67L21.73 19.32L21.77 18.95L21.77 6.75ZM8.77 11.94L8.57 11.67L8.46 11.36L8.44 11.14L8.46 10.91L8.57 10.6L8.77 10.33L8.94 10.19L9.14 10.08L9.47 10L9.69 10L9.91 10.04L10.12 10.13L10.39 10.33L13.77 13.71L17.15 10.33L17.42 10.13L17.63 10.04L17.96 9.99L18.29 10.04L18.5 10.13L18.77 10.33L18.91 10.5L19.05 10.8L19.1 11.02L19.1 11.25L19.05 11.47L18.91 11.77L18.77 11.94L14.58 16.13L14.4 16.28L14.21 16.38L13.88 16.46L13.66 16.46L13.44 16.42L13.23 16.33L13.04 16.21Z"),
"Normal" to ours("blend-normal", 26f, "M21.92 12.8L21.88 12.01L21.76 11.22L21.57 10.45L21.3 9.7L20.96 8.98L20.55 8.3L20.08 7.66L19.55 7.07L18.96 6.54L18.32 6.07L17.64 5.66L16.92 5.32L16.17 5.05L15.4 4.86L14.61 4.74L13.82 4.7L13.03 4.74L12.24 4.86L11.47 5.05L10.72 5.32L10 5.66L9.32 6.07L8.68 6.54L8.09 7.07L7.56 7.66L7.09 8.3L6.68 8.98L6.34 9.7L6.07 10.45L5.88 11.22L5.76 12.01L5.72 12.8L5.76 13.59L5.88 14.38L6.07 15.15L6.34 15.9L6.68 16.62L7.09 17.3L7.56 17.94L8.09 18.53L8.68 19.06L9.32 19.53L10 19.94L10.72 20.28L11.47 20.55L12.24 20.74L13.03 20.86L13.82 20.9L14.61 20.86L15.4 20.74L16.17 20.55L16.92 20.28L17.64 19.94L18.32 19.53L18.96 19.06L19.55 18.53L20.08 17.94L20.55 17.3L20.96 16.62L21.3 15.9L21.57 15.15L21.76 14.38L21.88 13.59Z"),
"Greater" to ours("blend-greater", 26f, "M12.1 7.02L11.53 6.99L10.96 7.02L10.4 7.1L9.84 7.24L9.31 7.43L8.79 7.68L8.3 7.97L7.84 8.31L7.42 8.69L7.04 9.11L6.7 9.57L6.41 10.06L6.16 10.58L5.97 11.11L5.83 11.67L5.75 12.23L5.72 12.8L5.75 13.37L5.83 13.93L5.97 14.49L6.16 15.02L6.41 15.54L6.7 16.03L7.04 16.49L7.42 16.91L7.84 17.29L8.3 17.63L8.79 17.92L9.31 18.17L9.84 18.36L10.4 18.5L10.96 18.58L11.53 18.61L12.1 18.58L12.66 18.5L13.12 18.39L12.6 18.08L12.24 17.82L11.92 17.55L11.38 17.02L10.71 16.94L10.3 16.84L9.91 16.7L9.54 16.53L9.18 16.31L8.85 16.07L8.54 15.79L8.26 15.48L8.02 15.15L7.8 14.79L7.63 14.42L7.49 14.03L7.39 13.62L7.33 13.21L7.3 12.8L7.33 12.39L7.39 11.98L7.49 11.57L7.63 11.18L7.8 10.81L8.02 10.45L8.26 10.12L8.54 9.81L8.85 9.53L9.18 9.29L9.54 9.07L9.91 8.9L10.3 8.76L10.71 8.66L11.38 8.58L11.92 8.05L12.24 7.78L12.6 7.52L13.12 7.21L12.66 7.1ZM21.92 12.8L21.87 12.04L21.72 11.3L21.61 10.93L21.32 10.23L21.14 9.89L20.72 9.26L20.22 8.69L19.94 8.43L19.34 7.97L19.01 7.77L18.68 7.59L17.98 7.3L17.61 7.19L16.87 7.04L16.11 6.99L15.73 7L15.35 7.04L14.61 7.19L13.89 7.43L13.54 7.59L12.88 7.97L12.57 8.19L12 8.69L11.74 8.97L11.5 9.26L11.08 9.89L10.74 10.58L10.61 10.93L10.41 11.67L10.35 12.04L10.3 12.8L10.31 13.18L10.35 13.56L10.5 14.3L10.74 15.02L10.9 15.37L11.28 16.03L11.5 16.34L12 16.91L12.28 17.17L12.88 17.63L13.2 17.83L13.54 18.01L14.24 18.3L14.61 18.41L15.35 18.56L15.73 18.6L16.49 18.6L17.24 18.5L17.61 18.41L17.98 18.3L18.68 18.01L19.01 17.83L19.65 17.41L19.94 17.17L20.48 16.63L20.94 16.03L21.14 15.71L21.48 15.02L21.61 14.67L21.72 14.3L21.87 13.56Z"),
"Lighten" to ours("blend-lighten", 26f, "M14.89 3.81L14.76 3.53L14.55 3.3L14.28 3.13L13.97 3.06L13.66 3.07L13.37 3.18L13.11 3.37L12.98 3.53L12.88 3.71L12.82 3.91L12.8 4.12L12.8 6.44L12.82 6.65L12.88 6.85L13.04 7.12L13.19 7.27L13.46 7.43L13.66 7.49L13.87 7.51L14.08 7.49L14.28 7.43L14.46 7.33L14.63 7.2L14.76 7.03L14.86 6.85L14.92 6.65L14.94 6.44L14.94 4.12ZM20.99 7.18L21.1 6.89L21.11 6.58L21.04 6.27L20.94 6.09L20.8 5.92L20.55 5.74L20.26 5.63L19.94 5.62L19.64 5.69L19.45 5.79L19.29 5.92L17.65 7.56L17.52 7.73L17.42 7.91L17.34 8.21L17.34 8.42L17.42 8.73L17.52 8.91L17.65 9.08L17.81 9.21L18 9.31L18.2 9.37L18.41 9.39L18.62 9.37L18.82 9.31L19 9.21L19.16 9.08L20.8 7.44ZM8.2 5.74L7.9 5.63L7.59 5.62L7.28 5.69L7.01 5.85L6.87 6L6.75 6.18L6.64 6.47L6.63 6.79L6.7 7.09L6.8 7.27L6.94 7.44L8.58 9.08L8.74 9.21L8.92 9.31L9.23 9.38L9.44 9.38L9.74 9.31L9.93 9.21L10.09 9.08L10.22 8.91L10.32 8.73L10.38 8.53L10.4 8.32L10.38 8.11L10.32 7.91L10.22 7.73L10.09 7.56L8.45 5.92ZM4.82 11.83L4.54 11.97L4.31 12.18L4.15 12.45L4.07 12.75L4.09 13.07L4.19 13.36L4.38 13.61L4.54 13.75L4.73 13.85L4.93 13.91L5.13 13.93L7.45 13.93L7.66 13.91L7.86 13.85L8.13 13.68L8.34 13.45L8.44 13.27L8.5 13.07L8.52 12.86L8.5 12.65L8.44 12.45L8.34 12.26L8.21 12.1L8.05 11.97L7.86 11.87L7.66 11.81L7.45 11.79L5.13 11.79ZM17.79 11.67L17.66 11.29L17.49 10.92L17.28 10.58L17.04 10.26L16.77 9.96L16.47 9.69L16.15 9.45L15.8 9.24L15.44 9.07L15.06 8.93L14.67 8.84L14.27 8.78L13.87 8.76L13.47 8.78L13.07 8.84L12.68 8.93L12.3 9.07L11.94 9.24L11.59 9.45L11.27 9.69L10.97 9.96L10.7 10.26L10.46 10.58L10.25 10.92L10.08 11.29L9.95 11.67L9.85 12.06L9.79 12.46L9.77 12.86L9.79 13.26L9.85 13.66L9.95 14.05L10.08 14.43L10.25 14.79L10.46 15.14L10.7 15.46L10.97 15.76L11.27 16.03L11.59 16.27L11.94 16.47L12.3 16.65L12.68 16.78L13.07 16.88L13.47 16.94L13.87 16.96L14.27 16.94L14.67 16.88L15.06 16.78L15.44 16.65L15.8 16.47L16.15 16.27L16.47 16.03L16.77 15.76L17.04 15.46L17.28 15.14L17.49 14.79L17.66 14.43L17.79 14.05L17.89 13.66L17.95 13.26L17.97 12.86L17.95 12.46L17.89 12.06ZM22.92 13.88L23.2 13.75L23.43 13.54L23.59 13.27L23.67 12.96L23.67 12.75L23.63 12.55L23.49 12.26L23.28 12.03L23.01 11.87L22.81 11.81L22.61 11.79L20.29 11.79L20.08 11.81L19.88 11.87L19.61 12.03L19.4 12.26L19.3 12.45L19.24 12.65L19.22 12.86L19.24 13.07L19.3 13.27L19.4 13.45L19.53 13.61L19.69 13.75L19.88 13.85L20.08 13.91L20.29 13.93L22.61 13.93ZM6.75 18.53L6.64 18.83L6.63 19.14L6.7 19.44L6.87 19.71L7.1 19.92L7.38 20.06L7.59 20.1L7.8 20.1L8.1 20.02L8.29 19.92L8.45 19.79L10.09 18.15L10.22 17.99L10.32 17.8L10.4 17.5L10.4 17.29L10.32 16.99L10.22 16.8L10.09 16.64L9.93 16.51L9.74 16.41L9.54 16.35L9.33 16.33L9.12 16.35L8.92 16.41L8.74 16.51L8.58 16.64L6.94 18.28ZM19.64 20.02L19.94 20.1L20.26 20.08L20.55 19.98L20.8 19.79L20.99 19.54L21.1 19.24L21.11 18.93L21.04 18.63L20.94 18.44L20.8 18.28L19.16 16.64L19 16.51L18.72 16.37L18.51 16.33L18.3 16.33L18 16.41L17.81 16.51L17.65 16.64L17.52 16.8L17.42 16.99L17.36 17.19L17.34 17.4L17.36 17.6L17.42 17.8L17.52 17.99L17.65 18.15L19.29 19.79L19.45 19.92ZM12.88 22L13.04 22.27L13.28 22.48L13.56 22.62L13.87 22.66L14.18 22.62L14.46 22.48L14.7 22.27L14.86 22L14.92 21.8L14.94 21.59L14.94 19.28L14.92 19.07L14.86 18.87L14.7 18.6L14.46 18.39L14.28 18.29L14.08 18.23L13.87 18.21L13.66 18.23L13.46 18.29L13.28 18.39L13.11 18.52L12.98 18.68L12.88 18.87L12.82 19.07L12.8 19.28L12.8 21.59L12.82 21.8Z"),
"Screen" to ours("blend-screen", 26f, "M14.82 5.08L14.69 4.92L14.52 4.78L14.34 4.68L14.13 4.62L13.92 4.6L13.71 4.62L13.5 4.68L13.32 4.78L13.15 4.92L13.02 5.08L12.92 5.27L12.86 5.47L12.83 5.69L12.86 5.9L12.92 6.1L13.02 6.29L13.15 6.45L13.32 6.59L13.5 6.69L13.71 6.75L13.92 6.77L14.13 6.75L14.34 6.69L14.52 6.59L14.69 6.45L14.82 6.29L14.92 6.1L14.98 5.9L15.01 5.69L14.98 5.47L14.92 5.27ZM19.78 7.14L19.65 6.97L19.48 6.84L19.3 6.74L19.09 6.68L18.88 6.65L18.67 6.68L18.46 6.74L18.28 6.84L18.11 6.97L17.98 7.14L17.88 7.32L17.82 7.53L17.79 7.74L17.82 7.95L17.88 8.16L17.98 8.34L18.11 8.51L18.28 8.64L18.46 8.74L18.67 8.8L18.88 8.83L19.09 8.8L19.3 8.74L19.48 8.64L19.65 8.51L19.78 8.34L19.88 8.16L19.94 7.95L19.97 7.74L19.94 7.53L19.88 7.32ZM9.86 7.14L9.73 6.97L9.56 6.84L9.38 6.74L9.17 6.68L8.96 6.65L8.75 6.68L8.54 6.74L8.36 6.84L8.19 6.97L8.06 7.14L7.96 7.32L7.9 7.53L7.87 7.74L7.9 7.95L7.96 8.16L8.06 8.34L8.19 8.51L8.36 8.64L8.54 8.74L8.75 8.8L8.96 8.83L9.17 8.8L9.38 8.74L9.56 8.64L9.73 8.51L9.86 8.34L9.96 8.16L10.02 7.95L10.05 7.74L10.02 7.53L9.96 7.32ZM17.89 12.18L17.79 11.66L17.62 11.17L17.51 10.93L17.25 10.47L16.93 10.06L16.75 9.87L16.36 9.52L16.15 9.37L15.69 9.11L15.45 9L14.96 8.83L14.7 8.77L14.18 8.7L13.92 8.69L13.66 8.7L13.14 8.77L12.88 8.83L12.39 9L11.92 9.23L11.69 9.37L11.48 9.52L11.09 9.87L10.74 10.26L10.59 10.47L10.45 10.7L10.22 11.17L10.05 11.66L9.99 11.92L9.92 12.44L9.91 12.7L9.95 13.22L9.99 13.48L10.12 13.99L10.22 14.23L10.45 14.7L10.59 14.93L10.74 15.14L11.09 15.53L11.48 15.88L11.69 16.03L12.15 16.29L12.39 16.4L12.88 16.57L13.14 16.63L13.4 16.67L13.92 16.71L14.44 16.67L14.7 16.63L14.96 16.57L15.45 16.4L15.92 16.17L16.15 16.03L16.56 15.71L16.75 15.53L16.93 15.34L17.25 14.93L17.39 14.7L17.62 14.23L17.79 13.74L17.85 13.48L17.89 13.22L17.93 12.7ZM21.84 12.1L21.7 11.93L21.54 11.8L21.35 11.7L21.15 11.64L20.93 11.61L20.72 11.64L20.52 11.7L20.33 11.8L20.17 11.93L20.03 12.1L19.93 12.28L19.87 12.49L19.85 12.7L19.87 12.91L19.93 13.12L20.03 13.3L20.17 13.47L20.33 13.6L20.52 13.7L20.72 13.76L20.93 13.79L21.15 13.76L21.35 13.7L21.54 13.6L21.7 13.47L21.84 13.3L21.94 13.12L22 12.91L22.02 12.7L22 12.49L21.94 12.28ZM7.81 12.1L7.67 11.93L7.51 11.8L7.32 11.7L7.12 11.64L6.91 11.61L6.69 11.64L6.49 11.7L6.3 11.8L6.14 11.93L6 12.1L5.9 12.28L5.84 12.49L5.82 12.7L5.84 12.91L5.9 13.12L6 13.3L6.14 13.47L6.3 13.6L6.49 13.7L6.69 13.76L6.91 13.79L7.12 13.76L7.32 13.7L7.51 13.6L7.67 13.47L7.81 13.3L7.91 13.12L7.97 12.91L7.99 12.7L7.97 12.49L7.91 12.28ZM9.86 17.06L9.73 16.89L9.56 16.76L9.38 16.66L9.17 16.6L8.96 16.57L8.75 16.6L8.54 16.66L8.36 16.76L8.19 16.89L8.06 17.06L7.96 17.24L7.9 17.45L7.87 17.66L7.9 17.87L7.96 18.08L8.06 18.26L8.19 18.43L8.36 18.56L8.54 18.66L8.75 18.72L8.96 18.75L9.17 18.72L9.38 18.66L9.56 18.56L9.73 18.43L9.86 18.26L9.96 18.08L10.02 17.87L10.05 17.66L10.02 17.45L9.96 17.24ZM19.65 16.89L19.48 16.76L19.3 16.66L19.09 16.6L18.88 16.57L18.67 16.6L18.46 16.66L18.28 16.76L18.11 16.89L17.98 17.06L17.88 17.24L17.82 17.45L17.79 17.66L17.82 17.87L17.88 18.08L17.98 18.26L18.11 18.43L18.28 18.56L18.46 18.66L18.67 18.72L18.88 18.75L19.09 18.72L19.3 18.66L19.48 18.56L19.65 18.43L19.78 18.26L19.88 18.08L19.94 17.87L19.97 17.66L19.94 17.45L19.88 17.24L19.78 17.06ZM14.69 18.95L14.52 18.81L14.34 18.71L14.13 18.65L13.92 18.63L13.71 18.65L13.5 18.71L13.32 18.81L13.15 18.95L13.02 19.11L12.92 19.3L12.86 19.5L12.83 19.71L12.86 19.93L12.92 20.13L13.02 20.32L13.15 20.48L13.32 20.62L13.5 20.72L13.71 20.78L13.92 20.8L14.13 20.78L14.34 20.72L14.52 20.62L14.69 20.48L14.82 20.32L14.92 20.13L14.98 19.93L15.01 19.71L14.98 19.5L14.92 19.3L14.82 19.11Z"),
"Color Dodge" to ours("blend-color-dodge", 26f, "M13.72 4.98L12.07 11.04L6.07 12.66L6 12.71L5.98 12.77L6.01 12.85L6.07 12.88L12.07 14.5L13.69 20.5L13.72 20.56L13.8 20.59L13.88 20.56L13.91 20.5L15.53 14.5L21.53 12.88L21.59 12.85L21.62 12.77L21.59 12.69L21.53 12.66L15.53 11.04L13.91 5.04L13.88 4.98L13.8 4.95Z"),
Expand Down
4 changes: 4 additions & 0 deletions assets/icons/procraft/blend-greater.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/slots.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ blend-color-burn 26 26 7.56 4.8 21.47 20.5
blend-linear-burn 26 26 9.7 4.85 19.04 19.74
blend-darker-color 26 26 5.77 4.85 21.77 20.85
blend-normal 26 26 5.72 4.7 21.92 20.9
blend-greater 26 26 5.72 4.7 21.92 20.9
blend-lighten 26 26 4.07 2.81 23.67 22.91
blend-screen 26 26 5.82 4.6 22.02 20.8
blend-color-dodge 26 26 5.96 4.95 21.64 20.59
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,7 @@ fn merge_duplicate_blend_and_locks() {
assert_eq!(s.layers().len(), 2);
assert!(s.set_layer_blend(copy, procraft_engine::document::BlendMode::Multiply.id()));
assert!(!s.set_layer_blend(copy, 999));
assert_eq!(crate::layers::blend_modes().len(), 27);
assert_eq!(crate::layers::blend_modes().len(), 28);
assert!(s.merge_down(copy));
assert_eq!(s.layers().len(), 1);
// red multiplied by red is still red
Expand Down
8 changes: 6 additions & 2 deletions crates/engine/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ pub enum BlendMode {
Saturation,
Color,
Luminosity,
Greater,
}

impl BlendMode {
/// Every mode, in the order the layer panel lists them (grouped: darken, normal, lighten,
/// contrast, difference, colour).
pub const ALL: [BlendMode; 27] = [
pub const ALL: [BlendMode; 28] = [
BlendMode::Multiply,
BlendMode::Darken,
BlendMode::Shade,
Expand Down Expand Up @@ -71,10 +72,11 @@ impl BlendMode {
BlendMode::Saturation,
BlendMode::Color,
BlendMode::Luminosity,
BlendMode::Greater,
];

/// The highest of the modes' numbers.
pub const MAX_ID: u32 = 26;
pub const MAX_ID: u32 = 30;

/// The renderer's number for the mode (stable: shaders switch on it).
pub fn id(self) -> u32 {
Expand Down Expand Up @@ -106,6 +108,7 @@ impl BlendMode {
BlendMode::Color => 24,
BlendMode::Luminosity => 25,
BlendMode::Shade => 26,
BlendMode::Greater => 30,
}
}

Expand Down Expand Up @@ -142,6 +145,7 @@ impl BlendMode {
BlendMode::Saturation => "Saturation",
BlendMode::Color => "Color",
BlendMode::Luminosity => "Luminosity",
BlendMode::Greater => "Greater",
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/engine/src/formats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,8 @@ fn blend_key(mode: BlendMode) -> &'static [u8; 4] {
BlendMode::Saturation => b"sat ",
BlendMode::Color => b"colr",
BlendMode::Luminosity => b"lum ",
// procreate has not "greater", "normal" is the nearest
BlendMode::Greater => b"norm",
}
}

Expand Down
5 changes: 5 additions & 0 deletions crates/engine/src/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1629,6 +1629,11 @@ mod tests {
#[test]
fn every_blend_mode_has_its_number() {
for m in BlendMode::ALL {
// Procreate has no Greater mode: it saves as Normal
if m == BlendMode::Greater {
assert_eq!(blend_from(blend_to(m)), BlendMode::Normal);
continue;
}
assert_eq!(blend_from(blend_to(m)), m, "{m:?}");
}
assert_eq!(
Expand Down
4 changes: 2 additions & 2 deletions crates/engine/src/studio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,8 @@ impl Brush {
// blend modes are kept by number (as the layers' are numbered; a grain's own and behind
// past them)
"blend_mode" | "burnt_blend" => {
let id = value.round().clamp(0.0, BRUSH_BEHIND as f32);
let known = id <= BlendMode::MAX_ID as f32 || id == BRUSH_BEHIND as f32;
let id = value.round().clamp(0.0, BlendMode::MAX_ID as f32);
let known = BlendMode::from_id(id as u32).is_some() || id == BRUSH_BEHIND as f32;
self.extra.insert(key.to_owned(), if known { id } else { 0.0 });
}
// the grain's and a dual brush's second's: a layer mode or the grain's own heights
Expand Down
9 changes: 7 additions & 2 deletions crates/gpu/src/canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,11 @@ impl StrokeStyle {
}
}

fn brush_blend(value: f32) -> u32 {
let id = value.round().clamp(0.0, BlendMode::MAX_ID as f32) as u32;
if BlendMode::from_id(id).is_some() || id == BRUSH_BEHIND { id } else { 0 }
}

/// A stroke drawn with `brush`'s shape, grain and rendering.
pub fn for_brush(
brush: &Brush,
Expand Down Expand Up @@ -329,10 +334,10 @@ impl StrokeStyle {
grade: if wet { brush.setting("wet_grade").clamp(-1.0, 1.0) } else { 0.0 },
blur: if wet { brush.setting("wet_blur").clamp(0.0, 1.0) } else { 0.0 },
wet_jitter: if wet { brush.setting("wet_jitter").clamp(0.0, 1.0) } else { 0.0 },
blend: brush.setting("blend_mode").round().clamp(0.0, BRUSH_BEHIND as f32) as u32,
blend: Self::brush_blend(brush.setting("blend_mode")),
blur_jitter: if wet { brush.setting("wet_blur_jitter").clamp(0.0, 1.0) } else { 0.0 },
grain_blend: brush.setting("grain_blend").round().clamp(0.0, GRAIN_LINEAR_HEIGHT as f32) as u32,
burnt_blend: brush.setting("burnt_blend").round().clamp(0.0, BRUSH_BEHIND as f32) as u32,
burnt_blend: Self::brush_blend(brush.setting("burnt_blend")),
// a brush's rotation turns its grain the other way to the shaders' angle
// the editors' turn of the image, the whole grain with it (the rotation control is
// each stamp's own: `Stamp::grain_turn`)
Expand Down
31 changes: 31 additions & 0 deletions crates/gpu/src/shaders/blend.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,40 @@ fn blend(b: vec4<f32>, s: vec4<f32>, mode: u32) -> vec4<f32> {
if (mode == 29u) {
return b + s * (1.0 - b.a);
}
if (mode == 30u) {
return blend_greater(b, s);
}
let cb = unpremultiply(b);
let cs = unpremultiply(s);
let mixed = clamp(blend_rgb(cb, cs, mode), vec3<f32>(0.0), vec3<f32>(1.0));
let rgb = s.a * (1.0 - b.a) * cs + s.a * b.a * mixed + (1.0 - s.a) * b.rgb;
return vec4<f32>(rgb, s.a + b.a * (1.0 - s.a));
}

// Standard Greater/Max Alpha Blend for premultiplied targets
fn blend_greater(b: vec4<f32>, s: vec4<f32>) -> vec4<f32> {
let dA = b.a;
let sa = s.a;

// Early exit if background is fully opaque or source is completely transparent
if (dA >= 1.0 || sa <= 0.0) {
return b;
}

// Target alpha is determined by the greater of the two layers
let target_a = max(dA, sa);

// Unpremultiply both inputs to operate in straight (unassociated) color space
let color_b = select(vec3<f32>(0.0), b.rgb / dA, dA > 0.0);
let color_s = select(vec3<f32>(0.0), s.rgb / sa, sa > 0.0);

// Calculate normalized weight based on relative alpha contribution
let total_a = dA + sa;
let weight = select(0.5, sa / total_a, total_a > 0.0);

// Blend in straight RGB space
let blended_rgb = mix(color_b, color_s, weight);

// Re-premultiply by the target alpha for output consistency
return vec4<f32>(blended_rgb * target_a, target_a);
}
Loading
Loading