Skip to content

Commit b269b16

Browse files
committed
Fix UI clipToBounds bug
1 parent 0078cb2 commit b269b16

File tree

3 files changed

+62
-6
lines changed

3 files changed

+62
-6
lines changed

Sources/GateEngine/System/Rendering/SystemShaders.swift

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,53 @@ internal extension VertexShader {
234234
}()
235235
}
236236

237+
@MainActor
237238
internal extension FragmentShader {
238-
239+
static let userInterfaceClipRectTextureSample: FragmentShader = {
240+
let fsh = FragmentShader()
241+
let viewOrigin: Vec2 = fsh.uniforms["ViewOrigin"]
242+
let viewSize: Vec2 = fsh.uniforms["ViewSize"]
243+
let minX: Scalar = viewOrigin.x
244+
let maxX: Scalar = minX + viewSize.width
245+
let minY: Scalar = viewOrigin.y
246+
let maxY: Scalar = minY + viewSize.height
247+
let inBounds: Scalar = (fsh.input.position.x >= minX && fsh.input.position.x < maxX && fsh.input.position.y >= minY && fsh.input.position.y < maxY)
248+
let opacity: Scalar = fsh.uniforms["opacity"]
249+
let sample = fsh.channel(0).texture.sample(
250+
at: fsh.input["texCoord0"]
251+
)
252+
fsh.output.color = Vec4(sample.rgb, sample.a * opacity).discard(if: inBounds == false)
253+
return fsh
254+
}()
255+
static let userInterfaceClipRectTintColor: FragmentShader = {
256+
let fsh = FragmentShader()
257+
let viewOrigin: Vec2 = fsh.uniforms["ViewOrigin"]
258+
let viewSize: Vec2 = fsh.uniforms["ViewSize"]
259+
let minX: Scalar = viewOrigin.x
260+
let maxX: Scalar = minX + viewSize.width
261+
let minY: Scalar = viewOrigin.y
262+
let maxY: Scalar = minY + viewSize.height
263+
let inBounds: Scalar = (fsh.input.position.x >= minX && fsh.input.position.x < maxX && fsh.input.position.y >= minY && fsh.input.position.y < maxY)
264+
let opacity: Scalar = fsh.uniforms["opacity"]
265+
let tintColor: Vec4 = fsh.channel(0).color
266+
fsh.output.color = Vec4(tintColor.rgb, tintColor.a * opacity).discard(if: inBounds == false)
267+
return fsh
268+
}()
269+
static let userInterfaceClipRectTextureTemplateTintColor: FragmentShader = {
270+
let fsh = FragmentShader()
271+
let viewOrigin: Vec2 = fsh.uniforms["ViewOrigin"]
272+
let viewSize: Vec2 = fsh.uniforms["ViewSize"]
273+
let minX: Scalar = viewOrigin.x
274+
let maxX: Scalar = minX + viewSize.width
275+
let minY: Scalar = viewOrigin.y
276+
let maxY: Scalar = minY + viewSize.height
277+
let inBounds: Scalar = (fsh.input.position.x >= minX && fsh.input.position.x < maxX && fsh.input.position.y >= minY && fsh.input.position.y < maxY)
278+
let opacity: Scalar = fsh.uniforms["opacity"]
279+
let tintColor: Vec4 = fsh.channel(0).color
280+
let sample = fsh.channel(0).texture.sample(
281+
at: fsh.input["texCoord0"]
282+
)
283+
fsh.output.color = Vec4(tintColor.rgb, opacity * tintColor.a * sample.a).discard(if: inBounds == false)
284+
return fsh
285+
}()
239286
}

Sources/GateEngine/UI/ImageView.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ open class ImageView: View {
5353
override func draw(_ rect: Rect, into canvas: inout UICanvas) {
5454
super.draw(rect, into: &canvas)
5555

56+
material.setCustomUniformValue(rect.position, forUniform: "ViewOrigin")
57+
material.setCustomUniformValue(rect.size, forUniform: "ViewSize")
58+
material.setCustomUniformValue(self.opacity, forUniform: "opacity")
59+
5660
canvas.insert(
5761
DrawCommand(
5862
resource: .geometry(.rectOriginTopLeft),
@@ -63,8 +67,8 @@ open class ImageView: View {
6367
)
6468
],
6569
material: material,
66-
vsh: .standard,
67-
fsh: .textureSample,
70+
vsh: .userInterface,
71+
fsh: .userInterfaceClipRectTextureSample,
6872
flags: .userInterface
6973
)
7074
)

Sources/GateEngine/UI/Label.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,18 @@ public final class Label: View {
169169
}
170170
yOffset = (rect.height / 2) - ((size.height / 2) * self.interfaceScale)
171171

172+
var material = Material(texture: texture, sampleFilter: sampleFilter, tintColor: textColor)
173+
material.setCustomUniformValue(rect.position, forUniform: "ViewOrigin")
174+
material.setCustomUniformValue(rect.size, forUniform: "ViewSize")
175+
material.setCustomUniformValue(self.opacity, forUniform: "opacity")
176+
172177
canvas.insert(
173178
DrawCommand(
174179
resource: .geometry(geometry),
175180
transforms: [Transform3(position: Position3(rect.x + xOffset, rect.y + yOffset, 0))],
176-
material: Material(texture: texture, sampleFilter: sampleFilter, tintColor: textColor),
177-
vsh: .standard,
178-
fsh: .textureSampleTintColor,
181+
material: material,
182+
vsh: .userInterface,
183+
fsh: .userInterfaceClipRectTextureTemplateTintColor,
179184
flags: .userInterface
180185
)
181186
)

0 commit comments

Comments
 (0)