Skip to content

Commit 5fd5060

Browse files
committed
Use a matrix for !transform window nodes
1 parent 0854a96 commit 5fd5060

File tree

3 files changed

+19
-14
lines changed

3 files changed

+19
-14
lines changed

docs/shaders.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,8 @@ if not specified.
155155
`downsample_passes=` *PASS_NUMBERS*
156156
: This specifies which (if any) passes to render with a smaller frame-buffer.
157157
It is specified as a vector of pass numbers, with the first pass being `0`.
158-
For example `1;2` would specify that the second and third pass. Default is
159-
`null`, i.e., all passes will be rendered with a `size` frame-buffer.
158+
For example `1;2` would specify the second and third pass. Default is `null`,
159+
i.e., all passes will be rendered with a `size` frame-buffer.
160160

161161
`downsample=` *DIVISOR*
162162
: This specifies how much to reduce the size of the output frame-buffer for
@@ -254,13 +254,12 @@ which is implemented as a shader program. Each of these nodes, in common
254254
with the default [`!shader` program](#shader), accepts one or more child nodes
255255
which will be composited together with the blend function controlled with
256256
the `composite` attribute (default `:over`). All of the filters also support
257-
the standard shader `gamma` and `alpha` attributes.
257+
the standard shader `alpha` attribute.
258258

259259
### `!transform`
260260

261261
Composites its input nodes and then scales, rotates and translates its output.
262-
This is similar to the `!translate` node in `!canvas` and `!canvas3d` with the
263-
exception that the order of operations is fixed: scale, rotate, translate. The
262+
This is similar to the `!translate` node in `!canvas` and `!canvas3d`. The
264263
origin for all of these operations is the *centre* of the image.
265264

266265
`scale=` *SX*`;`*SY*
@@ -278,6 +277,9 @@ Areas "outside" the transformed image will be transparent by default. This can
278277
be controlled with the `border` and `repeat` attributes described above for
279278
[`!shader`](#shader).
280279

280+
The order that the attributes are specified is important. Transforms are
281+
applied from the rightmost attribute (last) to the leftmost (first).
282+
281283
### `!vignette`
282284

283285
A *very* simple vignette filter that (alpha-) fades out the edges of its output.

src/flitter/render/window/glsl/transform.frag

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ const float Tau = 6.283185307179586231995926937088370323181152343750;
44

55
in vec2 coord;
66
out vec4 color;
7-
uniform vec2 scale;
8-
uniform vec2 translate;
9-
uniform float rotate;
7+
uniform mat3 transform_matrix;
108
uniform vec2 size;
119
uniform float alpha;
1210
uniform bool flip_x;
@@ -19,10 +17,7 @@ uniform sampler2D ${name};
1917

2018
void main() {
2119
% if child_textures:
22-
float th = -rotate * Tau;
23-
float cth = cos(th);
24-
float sth = sin(th);
25-
vec2 point = ((coord - 0.5) * size - translate) * mat2(cth, sth, -sth, cth) / scale / size + 0.5;
20+
vec2 point = (transform_matrix * vec3((coord - 0.5) * size, 1.0)).xy / size + 0.5;
2621
% for name in child_textures:
2722
% if loop.index == 0:
2823
vec4 merged = texture(${name}, point);

src/flitter/render/window/shaders.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,22 @@
44

55
from . import ProgramNode
66
from .glsl import TemplateLoader
7-
from ...model import null
7+
from ...model import null, Matrix33
88

99

1010
class Transform(ProgramNode):
1111
DEFAULT_FRAGMENT_SOURCE = TemplateLoader.get_template('transform.frag')
1212

1313
def render(self, node, references, **kwargs):
14-
super().render(node, references, scale=1, translate=0, rotate=0, **kwargs)
14+
transform_matrix = Matrix33.identity()
15+
for name, value in node.items():
16+
if name == 'scale' and (matrix := Matrix33.scale(value)) is not None:
17+
transform_matrix @= matrix
18+
elif name == 'translate' and (matrix := Matrix33.translate(value)) is not None:
19+
transform_matrix @= matrix
20+
elif name == 'rotate' and (matrix := Matrix33.rotate(value)) is not None:
21+
transform_matrix @= matrix
22+
super().render(node, references, transform_matrix=transform_matrix.inverse(), **kwargs)
1523

1624

1725
class Vignette(ProgramNode):

0 commit comments

Comments
 (0)