Despite working in the computer graphics industry for more than a few years, I could never motivate myself enough to write my own shaders on shadertoy! I would always look at others and only admire the work (or tweak a little bit). This is the first time I feel I should actually do something. You explained SO MANY tiny things merely in half an hour. You're a legend, sir! Thank you! Definitely need more of this... Btw, with those little achievements during the video, I'd have jumped on my chair and ran across the neighborhood yelling what I just did. You, on the other hand, were like "that's cool 😐"; found that a bit funny!
This video just popped up on my recommendations and I'm seriously impressed - you get straight down to business and explain everything as you go. Love it, dude.
I think there's a way to flip y for the uv coordinates without knowing neighbours. I'll express it by 2 bool values a = checker pattern, true for every other tile b = hash pattern, true for every tile that you flipped the orientation of then flip the uv y coordinate if a xor b
36:31 "More like 1700!!". According to Wolfram Alpha this is roughly 3.9365477946605944047872263433231095841463037044815290173387739901217075103664754606769104726079377942607302 × 10^2378.
Oh! man. You are a genius. Amazing stuff. I use illustrator and was wondering about this patter, but you actually program it and make it full of motion... wow!... I am so impressed by this stuff. Thank you.
That's so amazing to see what you can do with simple maths ! I managed to reproduce this shader in Blender using the node based material editor, aside from important glitches on 3D objects it looks the exact same on planes and UV unwrapped objects !
@@TheArtofCodeIsCool I'm sure you'll like it ! I heard the shader nodes are based off of GLSL, it shouldn't be too hard for you to do crazy stuff with them too ! I'm also trying to reproduce tiled Hexagons watching the video you made about them, but I am struggling to translate the two last steps into nodes as I don't know how to translate a "if".
Thanks! This effect I've seen on one particular dnb music channel. Always wondered how to actually do it. Tried to do it in Touchdesigner with its components, but I now realize the importance of resource control especially in larger projects. That's where shaders come into the picture. Kudos Martijn!
I just discovered your channel! It's so underrated. It's a wonder that I haven't heard of it prior to this. Keep up the good work and please upload more frequently.
This is fantastic! I've only really used shaders for rendering things with vertices but I love that you can do so much just with a fragment shader- and this is the most wonderful explanation of how that I've ever come across. Many, many props. Write a book already! I'll buy it!
If I haven't said it already, I love your videos. I would like to say thank you very much for fixing the mic issue; SO SO exciting to be able to follow your videos without the thumping. :D Also, thank you so much for explaining the randomness function you use a lot. I'd been wondering about it, but very satisfying to now know it doesn't necessarily rely on any specific mathematical trick, it's just a serious of math operations to create more digits, slice a few off, make more digits, slice, etc. Will definitely support when I can. Thank you!!!
Also, just a suggestion. Would be really cool to get small shader challenges from you. Not sure exactly what your goals are with the channel or Patreon, but something I struggle with when it comes to shaders is coming up with ideas that are actually within my grasp or that don't grow too much while I'm writing it. Would be nice to have someone experienced, like yourself, help guide my shader studies with challenges without spreading you too thin. Anyway, thank you yet again!
Thanks, Subscribed! Great explanation and step through style, so many programming videos make assumptions and completely gloss over fundamental blocks here you even take a moment to clarify absolute(5:15) and I'd never considered applying that for reflected gradients.
Wooooooooooooooooooooooooo. Sorry I just had to comment before actually watching the video. We are long overdue for a catchup dude. I've been swamped by illnesses, work and former clients from my freelancer days. Keen for another session soon?
Your "shift to the side" (13:51) where you have 2 lines inside each square is quite a surprise. Doesn't that change the maze algorithm by introducing all these parallel lines? Or does it not? Amazing. There should be a mathematical proof about this (whichever it is).
When I made the original one, with just the diagonal line, I didn't like the notches and played a bit to get rid of them. I haven't really thought about wether it actually changes the maze.
19:45 you could use a step function on zero, multiply by 2 and substract by 1 and you get negative and positive value. From: `sign(gv.x + gv.y)` to: `2.0 * step(0.0, gv.x + gv.y) - 1.0`. I'm not sure this is nicer fix because it's involve more computation and maybe harder to read than `sign` function.
@@cameronfoale8270 Condition is not really optimize in shaders cause your shader need to recompile if the condition change. It's kind of a micro optimization however I personally prefer to avoid condition when I can. But the point is, yes it works. ^^
@@rochbouchayer9120 Shaders do not need recompiled for conditionals. The actual issue is that shaders operate on many values at once (I.e. AMD's recent Navi cards operate on groups of 32 values), and conditional code on a vector can be very expensive.
@@bradennelson2436 Sorry for the mistake, I'm not an expert in shader at "hardware" level. A friend tried to explain to me GPU branching but I didn't understand all the subtleties. Thanks for the correction.
to remove the lines without adding random numbers in this case you could multiply color youre adding by the abs of sign. This would make it black in cases of 0 and do nothing for everything else. you could also replace one abs (somewhere) with the multiplication by the sign value (this would effectively just be abs, and 0 for when it's not needed anyway)
float s = sign(gv.x+gv.y); line 48: col += texture(iChannel0, tUv).rgb*mask * abs(s); ^ this would work
A possible better solution for that offset thing: You can wrap the y coordinate of the sign function into a max function like; sign(gv.x, max(gv.y, 0.001));
Yeah but that's just the neighbor. In order to get consistency each tile would have to follow the entire path and come to a consensus with all other tiles sharing the same path on how to flip its coordinate ;)
for the flow, instead of checker, I think you can use just the n variable (hash21) and substract 0.5 which will give you a value between -0.5 and +0.5, and only check wheather it's positive or negative without its magnitude, which would force all the boxes to spin in one direction (in this cas it's counterclockwise) this should work because only flipped boxed are spinning in the wrong direction, which are controlled by the n variable
30:44 _“Unfortunately, there's no easy way to remedy that and make it completely uniform, because you would have to know… one tile would have to know how all the other tiles are oriented in order to know which way to flip, and so that's not feasible.”_ But you _do_ know which way a tile's flipped- that's your hashed `n` variable (or rather, the `n
I think you can embed shaders, dunno about twitter though. If not, you could post it on the facebook group and perhaps it'll be picked up. Twitter integration would be awesome.
There's a minor problem with your solution at 19:33: You only shift the "bug" to another location. Using some hyperparameters you'll be able to get gv.x+gv.y = -0.001, adding 0.001 to this would give you the value 0. I think you could fix the problem by multiplying d by sign(abs(gv.x+gv.y)), which basically zeroes d if you're on the diagonal.
Yeah you are right. I was trying to find a solution without a conditional but the sign function is conditional anyways. So in this case a simple (gv.x+gv.y>0)?1:-1 would have sufficed.
@@TheArtofCodeIsCool I think (gv.x+gv.y>0)?1:-1 would've been worse (for the reason you mentioned -- avoiding conditionals). The GPU should have logic to handle _sign(abs(xx))_ better than _cond?true:false_ I also don't think my suggestion would be usable for most implementations, adding a minor shift to avoid zero behaves as expected in most of the cases, with no overhead. Great video all in all.
Instead of the sign function I would use something like this: #define stepsign(x) (step(0.,(x))*2.-1.) It shifts the step function result from [0,1] to [-1,1] range.
The concept 'uv coordinate' is widely used in computer graphics and probably comes from mathematics which generally uses letters at the end of the alphabet for varying variables (as opposed to letters at the start of the alphabet for constants). Common letters used are x,y, z,w, s, t, u and v. I just came up with 'gv' to stand for 'grid uv'. But I like your guess!
I think an easy way to fix the discontinuity at 30:35 would be to multiply y by checker and sign(n-.5) like: y=(d-(.5-width))/(2.*width)*checker*sign(n-.5) Or am I missing something there?
There's a good video here on youtube showing artistic uses of Truchet tiling for hidden messages by David Reimann's method. *Play Truchet: Using the Truchet Tiling to Engage the Public with Mathematics - Cindy Lawrence *
Best shader dev youtube channel ever! :D
By far!
Despite working in the computer graphics industry for more than a few years, I could never motivate myself enough to write my own shaders on shadertoy! I would always look at others and only admire the work (or tweak a little bit). This is the first time I feel I should actually do something. You explained SO MANY tiny things merely in half an hour. You're a legend, sir! Thank you! Definitely need more of this...
Btw, with those little achievements during the video, I'd have jumped on my chair and ran across the neighborhood yelling what I just did. You, on the other hand, were like "that's cool 😐"; found that a bit funny!
Haha, I'm glad you got something out of it!
This video just popped up on my recommendations and I'm seriously impressed - you get straight down to business and explain everything as you go. Love it, dude.
somewhere between Bob ross and Deadmau5 - jokes aside, best glsl teacher i've found.
Your videos are so good. I mainly do things in VEX but stuff like this in similar languages are awesome to watch.
I think there's a way to flip y for the uv coordinates without knowing neighbours.
I'll express it by 2 bool values
a = checker pattern, true for every other tile
b = hash pattern, true for every tile that you flipped the orientation of
then flip the uv y coordinate if a xor b
That might work! Good idea
Turns out you are right. :)
I was thinking just the same thing!
Turns out that i wasn't alone! :)
A lot of this is way over my head, and I thought that was a really obvious solution XD You get a like, fellow interwebber
Also don't forget to swap out smoothstep with a simple ceil and 1 - result. Basically: 1 - ceil((abs(d - 0.5) - width))).
36:31 "More like 1700!!". According to Wolfram Alpha this is roughly 3.9365477946605944047872263433231095841463037044815290173387739901217075103664754606769104726079377942607302 × 10^2378.
I am going to call you "SHADER MASTER" impressed!!
Dude, I love your videos. You don't explain the backing math in overly tangential ways. It's just right to the point. Awesome as always.
Thanks, I'm glad you like it :)
Oh! man. You are a genius. Amazing stuff. I use illustrator and was wondering about this patter, but you actually program it and make it full of motion... wow!... I am so impressed by this stuff. Thank you.
That's so amazing to see what you can do with simple maths !
I managed to reproduce this shader in Blender using the node based material editor, aside from important glitches on 3D objects it looks the exact same on planes and UV unwrapped objects !
Cool! I have to dive into blender 2.8 some day. A lot of people are doing cool stuff with it.
@@TheArtofCodeIsCool I'm sure you'll like it !
I heard the shader nodes are based off of GLSL, it shouldn't be too hard for you to do crazy stuff with them too !
I'm also trying to reproduce tiled Hexagons watching the video you made about them, but I am struggling to translate the two last steps into nodes as I don't know how to translate a "if".
Thanks! This effect I've seen on one particular dnb music channel. Always wondered how to actually do it. Tried to do it in Touchdesigner with its components, but I now realize the importance of resource control especially in larger projects. That's where shaders come into the picture. Kudos Martijn!
You are welcome. Thanks for watching!
I'm so happy finding this channel. There are so many tips and tricks hidden in this tutorial.Thanks a lot.
This is the first time I look into shader coding, seems super fun!
I just discovered your channel! It's so underrated. It's a wonder that I haven't heard of it prior to this. Keep up the good work and please upload more frequently.
This is fantastic! I've only really used shaders for rendering things with vertices but I love that you can do so much just with a fragment shader- and this is the most wonderful explanation of how that I've ever come across.
Many, many props. Write a book already! I'll buy it!
Aww thanks for the nice words!
Thanks a million for taking the effort of making these great videos.
It's channels like this that makes RUclips worth while !!
Best regards.
Aww thanks! And thanks for watching!
Every time I watch your videos I see a new optical illusion.
So glad to find this channel, always wanted to learn shaders!
This is good, there are very few people knowledgeable in graphic shaders.
Stumbled upon this video and I am totally amazed! I love this type of content. Keep up the good work!
There are soooooo many things I'd love to have as a screensaver here!
I love this channel! Impressive that it seems like you do this all spontaneous and in one take too!
You went to the Amazon? Nice! Cheers from Brazil and thank you for squeezing this video into your schedule :)
Thank you so much for this, things are slowly but surely clicking!
Awesome that's what I like to hear
the long wait is over, another shader tutorial from Martijn, I hope this channel keeps growing and you get the attention these videos deserve!
I think I've just randomly stumbled into a new "favorite channel" for me. Subscribed.
If I haven't said it already, I love your videos. I would like to say thank you very much for fixing the mic issue; SO SO exciting to be able to follow your videos without the thumping. :D
Also, thank you so much for explaining the randomness function you use a lot. I'd been wondering about it, but very satisfying to now know it doesn't necessarily rely on any specific mathematical trick, it's just a serious of math operations to create more digits, slice a few off, make more digits, slice, etc.
Will definitely support when I can. Thank you!!!
Also, just a suggestion. Would be really cool to get small shader challenges from you. Not sure exactly what your goals are with the channel or Patreon, but something I struggle with when it comes to shaders is coming up with ideas that are actually within my grasp or that don't grow too much while I'm writing it. Would be nice to have someone experienced, like yourself, help guide my shader studies with challenges without spreading you too thin.
Anyway, thank you yet again!
Erm, just realized that your Patreon is $1 per video at the lowest tier. I can definitely afford that...... and done!
@@DylanBurke I gotta think about how I would do this exactly but that sounds like a great idea!
this (and all of your videos) was soooo good - thank you.
Glad you enjoyed it!
Thanks, Subscribed! Great explanation and step through style, so many programming videos make assumptions and completely gloss over fundamental blocks here you even take a moment to clarify absolute(5:15) and I'd never considered applying that for reflected gradients.
I'm glad it worked for you. Thanks for watching!
Thank you bro, as usual "QUALITY CONTENT"
Спасибо за ваш труд
Nice explain, with visual samples per change, and detailed description! Thank You, please continue in the same vein )
11:07 beautiful 10 PRINT 😍
Great video, as always! Thanks a lot!
19:28 In order not to have those white lines and not to add the epsilon what you could do is something like :
mix(-0.5, 0.5, step(0., gv.x+gv.y));
Yes, or just step(0., gv.x+gv.y)-0.5
I waited a long time for the shadertoy content. Thanks
Me too
Amazing content and pedagogy, as usual ! Thanks !
I'd love to see a tutorial on metaballs, possibly taking what we've been learning from the Voronoi tutorial!
phenomenal. thank you.
Very cool and succinct, while still everything explained well! Thank you so much! I'll have fun with it soon! Also I subscribed ❤️
Wooooooooooooooooooooooooo. Sorry I just had to comment before actually watching the video. We are long overdue for a catchup dude. I've been swamped by illnesses, work and former clients from my freelancer days. Keen for another session soon?
Yes, hit me up on Patreon to schedule something.
You explain shaders so well. Thank you for your videos!
Yes ! finally ! a new video
I watched your mandlebrot video too. This is like Bob Ross 2.0
Спасибо за видео. Интересный эффект
Love your videos
Quality content as always
Incredible thank's !
That is fun
Great as always!
Awesome work! I love your channel!
Nice man ! ......Priceless Content imo....as usual
Thank for great guides!
Lovely video!
Awesome as always 👌
Wooooo thanks for the tutorial!
Great work! Thank you for sharing!
As always a very good video!
Your "shift to the side" (13:51) where you have 2 lines inside each square is quite a surprise. Doesn't that change the maze algorithm by introducing all these parallel lines? Or does it not? Amazing. There should be a mathematical proof about this (whichever it is).
When I made the original one, with just the diagonal line, I didn't like the notches and played a bit to get rid of them. I haven't really thought about wether it actually changes the maze.
Wow it looks like you do it live!
Great video, thanks
Nice!
19:45 you could use a step function on zero, multiply by 2 and substract by 1 and you get negative and positive value.
From: `sign(gv.x + gv.y)`
to: `2.0 * step(0.0, gv.x + gv.y) - 1.0`.
I'm not sure this is nicer fix because it's involve more computation and maybe harder to read than `sign` function.
Yeah that works too :)
How about float((gv.x + gv.y) > 0.0) * 2.0 - 1.0; ?
@@cameronfoale8270 Condition is not really optimize in shaders cause your shader need to recompile if the condition change. It's kind of a micro optimization however I personally prefer to avoid condition when I can.
But the point is, yes it works. ^^
@@rochbouchayer9120 Shaders do not need recompiled for conditionals. The actual issue is that shaders operate on many values at once (I.e. AMD's recent Navi cards operate on groups of 32 values), and conditional code on a vector can be very expensive.
@@bradennelson2436 Sorry for the mistake, I'm not an expert in shader at "hardware" level. A friend tried to explain to me GPU branching but I didn't understand all the subtleties. Thanks for the correction.
to remove the lines without adding random numbers in this case you could multiply color youre adding by the abs of sign. This would make it black in cases of 0 and do nothing for everything else. you could also replace one abs (somewhere) with the multiplication by the sign value (this would effectively just be abs, and 0 for when it's not needed anyway)
float s = sign(gv.x+gv.y);
line 48: col += texture(iChannel0, tUv).rgb*mask * abs(s);
^ this would work
Yeah that could work.
my man is baack
Quality content, very interesting.
A possible better solution for that offset thing:
You can wrap the y coordinate of the sign function into a max function like;
sign(gv.x, max(gv.y, 0.001));
30:18 you can know about the other tiles if you do for example Hash21(id-vec2(1,0)), this would be the tile above
Yeah but that's just the neighbor. In order to get consistency each tile would have to follow the entire path and come to a consensus with all other tiles sharing the same path on how to flip its coordinate ;)
This was awesome!
Very neat
This is awesome.
You are a godsend sir, thank you!
Is there a way to smooth out the result? Producing more straight lines where adjacent tiles are not flipped, and curve only where it's necessary.
This should be the way math should be reached in a computer science course.
for the flow, instead of checker, I think you can use just the n variable (hash21) and substract 0.5 which will give you a value between -0.5 and +0.5, and only check wheather it's positive or negative without its magnitude, which would force all the boxes to spin in one direction (in this cas it's counterclockwise)
this should work because only flipped boxed are spinning in the wrong direction, which are controlled by the n variable
flipped or not makes no difference on their spin direction, look again!
19:40 you can use 0.5 - step(0, gv.x+gv.y) instead of -sign(...)*0.5
Yeah!
30:44 _“Unfortunately, there's no easy way to remedy that and make it completely uniform, because you would have to know… one tile would have to know how all the other tiles are oriented in order to know which way to flip, and so that's not feasible.”_
But you _do_ know which way a tile's flipped- that's your hashed `n` variable (or rather, the `n
You are right. It IS possible. I stand corrected :)
www.shadertoy.com/view/td33D4
I like this
I really wish Shadertoy made shaders more easily embeddable outside the site, for example if they could just run as embeds on twitter.
I think you can embed shaders, dunno about twitter though. If not, you could post it on the facebook group and perhaps it'll be picked up. Twitter integration would be awesome.
I really enjoy your video😍
13:57 Towards the right of the render, you can see a spooked ghost.
Didn't know what you meant at first, but now I see it :)
Good job keep it up.
allways good~
please do a tutorial about importing geometry from other programs into glsl!!
Math is like real world magic : )
Yes!
There's a minor problem with your solution at 19:33: You only shift the "bug" to another location. Using some hyperparameters you'll be able to get gv.x+gv.y = -0.001, adding 0.001 to this would give you the value 0.
I think you could fix the problem by multiplying d by sign(abs(gv.x+gv.y)), which basically zeroes d if you're on the diagonal.
Yeah you are right. I was trying to find a solution without a conditional but the sign function is conditional anyways. So in this case a simple (gv.x+gv.y>0)?1:-1 would have sufficed.
@@TheArtofCodeIsCool I think (gv.x+gv.y>0)?1:-1 would've been worse (for the reason you mentioned -- avoiding conditionals). The GPU should have logic to handle _sign(abs(xx))_ better than _cond?true:false_
I also don't think my suggestion would be usable for most implementations, adding a minor shift to avoid zero behaves as expected in most of the cases, with no overhead.
Great video all in all.
Instead of the sign function I would use something like this:
#define stepsign(x) (step(0.,(x))*2.-1.)
It shifts the step function result from [0,1] to [-1,1] range.
Yes, that could work :)
Thumbs up! Subbed
I think you could fix the y continuity by flipping it if it is around the bottom corner.
You could try doing it and post the link if you succeed. I'd be very interested in this.
@@TheArtofCodeIsCool I tried doing it. I don't think that anymore.
@@erslippers3805 this tickled me. Hats off for trying!
awsome
Yeah ! Great tank's
I have a very pedantic question. How did you come up with the names uv and gv? Is it a shorthand for "uniform vector" and "grid vector"?
The concept 'uv coordinate' is widely used in computer graphics and probably comes from mathematics which generally uses letters at the end of the alphabet for varying variables (as opposed to letters at the start of the alphabet for constants). Common letters used are x,y, z,w, s, t, u and v.
I just came up with 'gv' to stand for 'grid uv'. But I like your guess!
nice vid, clearly explained.
do you use a blue screen? your eyes looks freaky sometimes : p
Yes :)
Do some cloud shaders or Water maybe...
Its on the ideas-for-videos list ;)
@@TheArtofCodeIsCool I vote clouds :p
At 30:41 could you use the checker board information and the Hash21 output to decide if you flip the texture?
Yes, there is a solution o this.Check the tea-time segment on my latest video (KIFS fractals).
I think an easy way to fix the discontinuity at 30:35 would be to multiply y by checker and sign(n-.5) like: y=(d-(.5-width))/(2.*width)*checker*sign(n-.5)
Or am I missing something there?
You are right. It IS possible. www.shadertoy.com/view/td33D4
what language is this?
GLSL
There's a good video here on youtube showing artistic uses of Truchet tiling for hidden messages by David Reimann's method.
*Play Truchet: Using the Truchet Tiling to Engage the Public with Mathematics - Cindy Lawrence
*
Very cool. Thanks for the tip. Perhaps I'll play with that some time.
Epic! Insta-subed :)
5:25 an optical illusion.
Yes, I noticed that myself as well.