Hey everybody, im learning to write shaders because i want to make a brushstroke shader.
As a first step i manage to make a fragment shader that makes a super simple cellshading look.
So my next step would be to get the alpha of my brush-texture on the different areas/colors. in this case for now just on the yellow maybe.
But it should not wrap around the form or be applied onto the 3d Mesh like i could do it with the regular UVs.
It needs to be 2D screenspace so to say. But also it should move with the mesh if the mesh/cam moves.
Later on i want to try if its possible to make some kind of brush-movement… but for now i just want to apply the texture as 2D on the right place…
What you’re looking to do is really, really hard. It’s easy enough to have the texture projected onto the surface in 2D screen space, but much harder to have it move with the object nicely. The simplest solution is to use 2D screen space offset by the object’s pivot position in screen space.
There’s a conversation on doing this kind of thing here, with a couple of different examples:
@bgolus thank you! i will play around with this.
maybe there is other approaches …what i definetly want to avoid is that the brushtexture is repeated like in the image below → i.e. on the cube on every face… the yellow areas should melt together, but the edges should be manipulated in a way. (just using the regular uvs in this image)
move each duplicate 2 pixel on each cardinal direction
apply on the duplicate the blending mode lighter color or darker color
that’s will show you a prototype of the effect. with a cross pattern.
How to generalize?
Well you need to sample at each pixel, every pixel of the brush, for the one that define the brush shape, you compare it to the color, you keep it if it’s lighter, darker or whatever test you devise. It will give you a brush look. You can probably also blend the final color if your brush is not binary. You can also just threshold based on parameter to avoid it applied everywhere.
It’s a post process
You can render extra data per pixel to control the brush (like sampling radius). TO have brush only affect edge, you simply sample a sobel rendering of the scene and only keep color that detect a edge, that is only pixel around the edge will “brush”.
How it work?
It’s basically a filter, it’s like a DOF but the circle of confusion is of the brush shape. The effect work in the same way sobel filter work, it emphasize difference.
It’s been used to make watercolor effect by Princess on tigsource, with a small radius brush (no duplicated mesh)
@bgolus i tried it with the link you mentioned → the magic hat thingy. It does work it moves with the mesh, not 100% but very good to start with.
@neoshaman thanks for this. im currently trying to make it work.
another idea i had about this is… since i have the cellshading derrived from the light i exactly know where the edge is, because i set it. can i not apply the brushtexture along the edge somehow ?
a sobel filter will take anything into account but so far it might be enough to just deal with the light.
It depend, do you want it to “bleed” outside the mesh?
If no,
you can try to just use a texture sample as usual but using the screen UV instead of the mesh UV, combine it with the ndotl, then threshold as usual for cel shading.
If yes,
You can use the same technique, but also with an inverted shell, where instead of mixing down color, you discard like with alpha, since it’s screen space it will be continuous with the mesh screen space texture
But in order to have internal bleed on teh mesh, just use a fresnel with the screen space texture masked at the edges, and discard pixel like alpha, it will simulate bleed of the ink inside the mesh.
Now I tend to avoid screen space texture due to swimming effect, I haven’t investigate way to bypass it (object position and rotation offsetting of the screen UV, triplanar test, etc …).