WEBVTT 00:00.000 --> 00:14.400 Graphite is a 2D open source image editing software, like graphics creation software. 00:14.400 --> 00:27.680 And the idea, the end graphite is to be able to parametically design art, so what we do 00:27.680 --> 00:35.880 is that we have like everything is based on a note graph, and in this case we have an arc node, 00:35.880 --> 00:42.240 which then goes and the arc node has a few parameters, we then feed the arc node into 00:42.240 --> 00:47.960 a stroke node, which actually makes it visible, that's the white lines we see there, 00:47.960 --> 00:53.920 and then we can really repeat these to get fancy shapes. 00:53.920 --> 01:02.960 And the idea is that we can change the parameters after the fact to influence how the 01:02.960 --> 01:15.440 artwork looks, but maybe to give you a bit of like rounding what graphite is, this is like 01:15.440 --> 01:24.080 this is from my talk last year, but it's basically a fairly standard editor, you have 01:24.080 --> 01:28.960 a tool shelf on the left, and we have a layer panel on the right, so that's what you would 01:28.960 --> 01:37.240 be familiar with from other software, and we also have a properties panel, which is used to edit 01:37.280 --> 01:45.640 the parameters for the nodes, and we do have a note graph, which you can see here, this 01:45.640 --> 01:51.320 note graph is essentially the same information you have in the layer panel at the bottom 01:51.320 --> 01:59.320 right, but in the note graph you have the ability to use a note more than once, and in the 01:59.400 --> 02:11.160 layer panel that would just be displayed as two copies of the same node, yeah, and you might, 02:11.160 --> 02:18.280 well you see that, well this was the talk for first and last year, this is a new year, and 02:18.280 --> 02:27.800 a lot has changed since then, so like we did a couple of things, we had a major focus on improving 02:27.880 --> 02:37.880 the editor performance, and polishing the editor UX and UI, but another big thing we've been working 02:37.880 --> 02:47.800 on is our desktop app, so graphite has from the ground up being developed as sort of with 02:47.800 --> 02:54.840 the native and desktop philosophy, so currently graphite is only available as a web app, but 02:55.800 --> 03:02.600 all the logic is written in Rust and executed wire back to assembly, using a message passing 03:02.600 --> 03:10.760 interface, not MPI, but like a message protocol for the interaction, and basically the only thing 03:10.760 --> 03:17.160 we had to do to the native is that we run all the note graph and a rendering code natively, 03:18.120 --> 03:28.440 and we only render the UI in the browser, and we do that since like for one graphite in Rust, 03:29.960 --> 03:36.760 the iTunes are not as mature yet, and this allows us to build a cohesive user experience that 03:36.760 --> 03:45.160 works the same across web and native, and some might reject and say, wow, so you just 03:45.160 --> 03:53.800 bundled an electron app or just bundled the web app, but that's actually not the case, so in graphite, 03:53.800 --> 04:03.320 we only render the UI using the browser, so that's the green part you can see here, that is usually 04:03.320 --> 04:10.600 not latency sensitive, and the browser is just a pretty good tool to render your eyes, but everything 04:10.600 --> 04:21.000 that matters is like we render ourselves, and we use a off screen like CF instance to render 04:21.000 --> 04:29.560 the browser UI to a texture, then composite this together in our native app, and I mentioned 04:29.560 --> 04:37.320 that graphite is only available as a desktop as a web app currently, so you might be wondering, 04:37.320 --> 04:44.920 well what's the state of the desktop app, and I can tell you that this whole time, 04:45.800 --> 04:54.200 we've actually been in graphite, we made a small hack to allow it to go full screen and present 04:54.200 --> 05:03.880 slides, so this is our graphite desktop app, and now we will go through a bit like a few more features 05:03.880 --> 05:13.480 that we've worked on in the last year, so one of the things that graphite allows you to do 05:13.480 --> 05:25.240 is to build like parametric designs and procedural designs, so you can see that like as a, this is 05:25.240 --> 05:36.280 sort of grid, and if we look at the no graph representation, we can see that in the bottom here, 05:37.240 --> 05:50.280 this is essentially a grid, so right on the right hand side we, well every node is a function, 05:50.280 --> 05:58.920 so to speak, and a function can be evaluated with parameters, we have these sort of static parameters, 05:58.920 --> 06:06.760 which we can set in the properties panel, so here you can see that we can set some static parameters, 06:06.760 --> 06:14.920 which we can also change parameters at runtime, and in this case we have the instance on points 06:14.920 --> 06:23.000 node on the right, and this instance on points node evaluates everything going into the instance input, 06:24.520 --> 06:32.520 multiple times, so we have a grid at the bottom, that's the grid structure you can see, and we then 06:33.080 --> 06:41.480 evaluate this node chain, this function chain, with the position input, we can then use the 06:42.280 --> 06:50.600 instance position to build the shape, and this is a fairly powerful paradigm because it allows you to 06:51.320 --> 07:02.280 procedurally generate out, and we also take that step further, in the next example, we have 07:03.080 --> 07:13.320 like a snowflake kind of thing, and the graphite consists of two things, it's the editor UI, 07:14.200 --> 07:22.440 and it's the note graph engine, and he can use the note graph engine as a standalone, using for 07:22.440 --> 07:26.920 example the CLI, and in the future we want to build embedded applications where you can just 07:27.080 --> 07:32.280 export a graphite document basically as a shared library and embedded in other applications, 07:33.320 --> 07:39.720 but another part of the experience is our editor tools which allow you to modify the word graph, 07:40.840 --> 07:51.400 so here we have the, we have this star shape, and it looks sort of like a fractal, 07:52.360 --> 08:00.040 and this is just two instances of the same shape copy paste it into each other, so for every end 08:00.040 --> 08:08.920 point of the star we instance a new star, and this gives us this fractal nature, and we can use the editor 08:08.920 --> 08:19.080 tools to manipulate our representation, and we can like you saw the number of points have changed, 08:19.160 --> 08:27.320 we can change the radius, and this allows us to build these powerful procedural effects to get 08:27.320 --> 08:31.560 you nice looking pictures without having to do a bunch of manual effort. 08:37.160 --> 08:46.680 All right, next we'll talk about clipping masks, so let's another new feature we've added, 08:46.760 --> 08:54.520 and with all these features like most of these features, they are just notes, so developing a 08:54.520 --> 09:00.120 feature and adding a feature in graphite is as simple as basically writing a single function, which is 09:00.120 --> 09:07.560 then like which is then turned into a note that you can use in the editor, and clipping is 09:07.560 --> 09:16.120 a feature of the SVG spec, and we try to support most of what SVG supports, and if we 09:17.640 --> 09:29.320 get rid of this text and run simple shape, we can enable clipping, which takes basically the 09:29.320 --> 09:35.240 color information from one shape, and the structure information from the other, and it allows us to 09:35.240 --> 09:43.080 get these fancy effects, and this is compositing only effect, so we don't need to do Boolean operations 09:44.040 --> 09:54.600 so it's also very high performance and easy to do, we can also expand the stroke radius, 09:55.800 --> 10:04.520 and now you can see we have this target we can move around, and again like what you see in the background, 10:04.520 --> 10:18.920 that's just we, and that's all procedurally generated, yeah, now to our next slide, so you can 10:18.920 --> 10:28.040 see this cute little custom item, and this is another example of what you do with graphite, 10:28.920 --> 10:34.840 so this is another note we added, it's the point of position note, and the point of position note 10:34.840 --> 10:43.480 just gives access to the point of position in our document space, and we can then use the point of 10:43.480 --> 10:51.080 position to like offset the location of the eyes, to look at the direction you're pointing 10:51.080 --> 10:58.840 to, and what happens at a more like, this is a very simple note graph, so you can take 10:58.840 --> 11:06.920 a bit of a closer look, what happens here is that we have this left-to-right data flow, which is 11:06.920 --> 11:11.560 very obvious if you look at the slides and look at the note graph, if data going from left 11:11.560 --> 11:18.840 to right, but what is a bit less obvious is the data going from right to left, because every note 11:18.920 --> 11:26.360 is an essence of function, so we have, for example, the transform note, which takes a shape as 11:26.360 --> 11:34.280 input, and outputs a shape, and what we do in graphite actually is that we link these functions 11:34.280 --> 11:40.040 together, so the normalize note is a function, which calls the point of position function, 11:40.280 --> 11:49.960 you can then call the, like, the combined function as one, and the essentially here entire artwork 11:49.960 --> 11:56.840 becomes one, huge function, which you can evaluate with the current viewport position, and in this 11:56.840 --> 12:03.640 case, the current point of position, and the current time, and this is another thing we've added 12:03.640 --> 12:09.480 over the last year, animation, and all of our animation is fairly simple, we just have an animation 12:09.720 --> 12:16.280 time note, which we can connect to, for example, the rotation input, for the transform note, 12:17.320 --> 12:25.720 and this allows us to add animation to lots of artworks without having to build a huge animation 12:25.720 --> 12:32.760 system, so this was very easy to implement, and we have another demo for you, like we can take 12:32.840 --> 12:40.040 this step further, and build something essentially fully interactive, as you can see here, 12:42.680 --> 12:50.760 so the note graph is a purely functional program language, and we don't really have a way of 12:50.760 --> 12:55.640 representing state in the note graph, so you might have seen that even if he doesn't, 12:56.520 --> 13:04.760 and doesn't try to catch the wall, we still don't lose, but I mean, maybe that's just a feature. 13:10.200 --> 13:17.480 All right, another note that was added was the blend shape note, and you can see here on the 13:17.480 --> 13:25.720 left-hand side we have two serve paths, and what we do in the note is we have one note, 13:25.720 --> 13:30.840 which takes two paths as input, or like any collection of paths, and we can then 13:30.840 --> 13:39.720 interpolate between them, and here we can increase the number of interpolations and get this 13:39.800 --> 13:47.400 sort of 3D-looking effect, and you might have seen throughout the presentation, and also 13:47.400 --> 13:54.040 like on the right side, this allows you to do some pretty cool procedure-looking effects, 13:55.080 --> 14:00.040 and if we now, like this does not just work for regular strokes, and for four lines, 14:00.760 --> 14:14.200 we can also use a dashed line, and we can use a dashed line to give you these sort of 14:14.200 --> 14:20.760 interesting looking patterns, which look a bit like aliasing and artifacts, but that cannot be 14:21.880 --> 14:29.160 useful, and one thing you might wonder is, isn't that a very inefficient way of doing 3D rendering, 14:29.240 --> 14:35.960 and the answer to that is yes, but we've spent a lot of time and effort on making 14:35.960 --> 14:41.480 graphite fast enough, so you can do silly things like this, and it still just works perfectly fine. 14:48.360 --> 14:55.240 Another thing we added is the data panel, it's basically a way of 14:55.960 --> 15:02.520 introspecting the data that flows through the note graph, so you can enable this panel, and you 15:02.520 --> 15:08.760 can then look at the vector data that has actually returned from the individual notes, 15:09.480 --> 15:17.320 you can also enter a gate further, look at the nested structure, and this allows you to 15:17.960 --> 15:25.480 take a look at what goes wrong in graphite, because we thought, well, it would be unfair if 15:25.480 --> 15:34.760 artists wouldn't have the joy of debugging code, but it is a legitimately useful tool, especially 15:34.760 --> 15:46.280 if you work on more complex nested artworks. All right, and that essentially, 15:47.160 --> 15:59.800 brings us to our slide, and this is, again, procedurally generated, and if you have, I would 15:59.800 --> 16:08.360 ask you to please scan the QR code and try to give us a star on GitHub, because graphite can do 16:08.440 --> 16:17.000 a lot of things, and potentially, we have in the note graph a note that hypothetically, potentially, 16:17.800 --> 16:25.800 does a web request to the GitHub API, and as you can see, at least one person has already 16:26.920 --> 16:34.040 given us a star, we can take a quick look at the note graph, for that example, so 16:34.040 --> 16:47.880 another one. Yeah, it's essentially just, we do a get request to the GitHub API, and from the 16:47.880 --> 16:55.800 get request, we can then extract the JSON star gases count as, like, from the JSON object that 16:55.880 --> 17:06.360 is returned, and feed that into our text node, and we are, yeah, we're not forming GitHub's API, 17:06.360 --> 17:14.120 it's a throttle to five requests per second, but yeah, this allows us to have a live count of the 17:14.120 --> 17:19.640 GitHub stars, and this is actually a nice motivating factor, and can everyone, I can recommend everyone 17:19.640 --> 17:24.120 to implement something like this, because it's just cool, whenever you open the app, there are a few 17:24.200 --> 17:31.080 more stars, it's just, yeah, a nice motivating. It can also see the QR code, for example, 17:31.720 --> 17:40.600 is, of course, generated in graphite, it's just a note that we use, and we can also use a different 17:40.600 --> 17:59.160 QR code, so this would be the QR code for the graphite website, and, well, that's the joy 17:59.160 --> 18:06.600 of doing live demos. Yeah, but you can theoretically, like, if you would, where to change the text, 18:07.560 --> 18:17.000 you could change this to go to graphite.ard, as you can see on the slide there, and this is also 18:17.000 --> 18:24.520 where you can reach us. We do most of our development coordination on our Discord, but you can also 18:24.520 --> 18:29.640 reach us via GitHub, create issues, and one thing we're looking for in particular is help with 18:29.640 --> 18:36.280 packaging or desktop app, so we're working on, like, we do have a functioning mix bundle, but 18:37.000 --> 18:44.520 other packages would be very welcome. But, yeah, I think we'll end a bit early, so we have more 18:44.520 --> 18:51.000 time for questions, which they are hopefully many. So, thank you very much. Thank you. 18:51.880 --> 19:00.440 So, questions? Okay, can we? 19:00.440 --> 19:27.400 Thank you. Thanks for the presentation. The interactive features are the animation features. 19:27.400 --> 19:35.400 When you export the document, the project, what formats does that export to? 19:36.760 --> 19:43.640 Yes, that is actually a question we get a lot. So, currently, we don't have a native export 19:43.640 --> 19:49.640 for animated pictures yet, so something that would be fairly easy to add is something like give 19:49.800 --> 19:59.400 export. But, yeah, it's not been a focus yet, but this also illuminates another potential 20:00.200 --> 20:06.200 like strength of graphite, because what you can do, and we will work on making that a dedicated 20:06.200 --> 20:13.240 feature is to export the no-graph as a graphite executable within a better render engine essentially. 20:13.560 --> 20:21.320 So, you could, for example, build a game UI in graphite with values driven by a node, 20:22.440 --> 20:27.480 just input into the app, and then you could re-render, like you could render your game UI and 20:27.480 --> 20:34.200 embed graphite into your game engine. That answers the question. Right? 20:34.280 --> 20:43.000 Okay. So, just one of the back. So, they write just the use of I should find in the people what 20:49.000 --> 20:54.920 Hello. I didn't even know about this tool very, very cool. I'm wondering if you are 20:54.920 --> 21:00.840 planning to have some kind of library, so that other applications can render graphite projects. 21:01.080 --> 21:07.720 So, are you asking about whether we have a library so other projects can render graphite documents? 21:07.720 --> 21:13.400 Yes, yes. Yes. Absolutely. For the animation, this seems very cool to be able to embed these things into 21:13.400 --> 21:22.040 other things. So, we do have a, like, we do have a CLI, like basically the no-graph execution engine 21:22.040 --> 21:28.040 is already a library, and you can use, we have two consumers of that library, it's the editor 21:28.120 --> 21:35.080 UI, and the CLI application, but you could use the library on its own to render graphite documents, 21:36.040 --> 21:40.920 and also use the node system to build it, like you could particularly generate, 21:41.960 --> 21:48.280 or programmatically generate nodes, and documents, which you could then render. Does that 21:48.280 --> 21:51.960 answer the question? Yes. So, it seems like it's already possible today. 21:52.120 --> 22:01.160 So, you, like you could, you could today already just use the in-graph execution engine as a 22:01.160 --> 22:07.960 library, and use that in any rust project, and you get a, like a WGPU texture out, which you can then 22:07.960 --> 22:15.240 use in your compositing. Like that is possible, but the user experience is not optimized for that use case yet. 22:21.960 --> 22:29.480 We've got time for more questions in the chat there. Another question is, is our next speaker 22:29.480 --> 22:39.800 already in room? Yeah. Thank you for the talk. I want to ask what, what has been so far 22:39.800 --> 22:44.440 the experience of using WebGPU for, well, both rendering, and also, I guess you could use it for 22:44.520 --> 22:54.760 compute as well. Generally, the experience has been pretty good. So, we took, like on the browser, 22:54.760 --> 23:01.320 we started out by basically just on every frame returning an SVG to the browser, 23:01.320 --> 23:05.960 and using the browser rendering engine to render this, and we also still have that as a default, 23:05.960 --> 23:09.960 and it's like on the browser that's still the default, and we slap that as a fallback. 23:10.920 --> 23:17.960 So, we had, like, gave the WGPU ecosystem more time to mature, but by now, our experience has been 23:17.960 --> 23:27.000 pretty good, and most things just work. Cool. Thank you. Do we have the next speaker in the room? 23:27.000 --> 23:34.200 Thank you. I wasn't sure you understood. Okay. Wonderful. Can we have the big round of applause for 23:34.200 --> 23:40.280 the graph I created? Very nice, specialisation.