Is there a way to make a gradient move along the same path as an inset would?

So I know I can use nodes to specify a gradient that moves along an axis, or away from a specific point in space. But what I want is a little more complex.

I want the gradient to move along the same direction as an inset. So the object is blue, but gradually fades to gray around the edges, sort of like an outline color. I want a gradual transition, not just making an inset and coloring it differently.

Something like this - if you zoom in on the bottom pic you can see that the inset is colored blue nearer the middle, and fades to gray near the outermost edges.


in this case. as the path is a bit complex to be defined by simple mathematical formulas, you’d be better using other ways.

For example, with insets, vertex paint can be easier to work with and easier to control.

You could use pointiness attribute in Geometry node to drive the gradient.

I was able to figure it out ^^

Due to the 3 image limit on the forum, I’m also posting this on imgur with more screenshots, if it helps make it clearer - https://imgur.com/a/Kg55w?

So there’s no way (as far as I can find) to make a blender node that lets you specify a gradient direction like “away from the object’s inner rim” or “away from the object’s edge” or anything like that.

But what you CAN do is specify a direction determined by a face’s position the UV/Image Editor. Then you can position the faces in the editor to make the gradient move in the direction you want.

It sounds like a lot of manual work but it’s not actually, here’s what I did.

  1. Originally my number 5 was a text object, so first I converted it to a mesh. I cleaned it up by using “remove doubles” to get rid of a lot of unnecessary points. You could probably also use decimate or something. I got the mesh looking tidy, basically, and made everything into quads. Like so: https://i.imgur.com/u9elJIn.jpg

  2. I wanted something like an inset, but outside the original 5’s boundaries. So I guess like an outset, but when I tried using the inset modifier with the outset option, it didn’t work as I wanted. So I found a workaround. I extrude the 5 downward along the Z axis. Then I selected all those edges I just extruded, but not the 5’s front or back face. Then I separated those edges with P to make them into their own object, so I had this 5 shaped “cookie cutter”, an outline of the 5 with zero thickness in the X or Y direction. I then gave it thickness by using the solidify modifier, and applied the modifer. That gave me the shape below (and I’m hiding the original “5” to just show the rim). If you don’t want your gradient to expand outside the original object’s boundaries, you could just use the inset modifier to make a rim.
    Note that when viewed from above, the entire rim is made of nicely angled quads, sort of like a winding sidewalk path, the curves and corners all seem to move along a direction, which is important to make the rest of this work.

[ATTACH=CONFIG]500303[/ATTACH]

  1. Once I had my rim, I set up the nodes like this. The busy-looking principled shaders make it look overly complex, but it’s not really. I am going from a shiny black solid surface, to a shiny white transparent surface. The first node on the left is the white. The second one is the black. These plug into a mix shader.

Then to specify exactly how smooth the transition is from one shader to the other, I use the color ramp node. By dragging the black and white arrow thingies inward a bit, I made a sharper transition from black to white.
I plug the color output of this ramp into the factor of the mix shader.

So we have color A, color B, and a ramp to control the transition from one to the other. Now I just need the tricky part, a vector that tells blender where to position the texture so that color A and color B appear where I want. So that’s a “texture coordinate” input. And we’re using the UV output of the texture coordinates (because basically it’s the only way I could find to specify this). Then we add a mapping node to control the coordinates, because the UV node by itself doesn’t position them the way I want by default.

The only part of this setup that might be a little confusing here is the seemingly arbitrary -10" on the mapping node, under the Y location… and the 45 degree rotation on the Z axis, under the rotation column.

The Y tweak is there because, for some reason, Once I got the gradient working and visible, it was off-center a bit, so that there was more black than white even though they’re supposed to be exactly the same amount. When I played with the Y location to move it -10", it seemed to center perfectly.

The rotation tweak is there because the blender UV map editor works in 2D space, with X being left & right, and Y being up + down. The coordinates of this space are 0,0 (bottom left) to 1,1 (upper right). If I just plug the texture coordinates as “UV” it’s not specific enough, I’m not giving exact X or Y directions, just “UV coordinates”.

So blender assumes equal X and Y directions. That puts black in our gradient at 0,0, and white is at 1,1. This makes the gradient move diagonally from the bottom left corner of the UV editor, to the top right corner. I don’t want that, I want the gradient to move vertically. Not on the object itself, just within the UV editor. So I rotate the gradient 45 degrees with that mapping node.

[ATTACH=CONFIG]500304[/ATTACH]

Finally, I just need to unwrap this 5’s rim so that for every individual face, when I’m looking at the UV Editor, the inner edge of the 5 is at the bottom, and the outer edge is at the top.

It would be super handy and easy if I could just have each face scaled to fit the entire UV editor plane, as a perfect square, and just make sure all the squares are rotated correctly.

To achieve that, all you have to do is click one random face of the rim, as in the pic below, press U, and do “smart UV project”. You don’t need to specify any seams or change any of the settings shown below. Just click OK. This does exactly what I wanted… makes a zillion perfect squares in the UV editor, all of them filling up the entire UV plane, and all of them overlapping. Once that’s done, you should immediately see the gradient on every face in the 3D view. But by default it was just rotating the wrong way, like so: https://i.imgur.com/nYS274c.jpg

So all I had to do is go into the UV editor, A to select all, R, X, -90 to rotate them all 90 degrees counterclockwise, putting the black edges along the inner rim and the white edges along the outer rim.

This got me 95% of the way there, You may end up with a few weird faces that end up backwards or whatever, like this one shown below. To fix that easily, I first enabled the option to synchronize the selection between my mesh and my UV mapping. In the imgur screenshot above, that’s the little button at the bottom that looks like an arrow clicking on a cube. Then when I clicked on the misbehaving face, it highlighted that same face in the UV editor. Then I just hovered my mouse over the UV editor (so I don’t accidentally rotate the mesh instead of the UV) and did R, X, 180 to flip it around 180 degrees.

[ATTACH=CONFIG]500301[/ATTACH]

Final result of the rim can be seen here. So now my object’s edges are semi transparent, sort of like subsurface scattering but controlled the way I want (and possibly less resource-intensive). https://i.imgur.com/h2ZBtKu.jpg

So there’s no way (as far as I can find) to make a blender node that lets you specify a gradient direction like “away from the object’s inner rim” or “away from the object’s edge” or anything like that.

This is what pointiness does, within its limitations. The problem with such constructs as “inner rim” or “object’s edge” is that while it is quite clear for a human, what it means, it is not so easy to decribe it as a general property of geometry. For example, if you have a letter S, which edges are inner and which are outer? Ask 10 people and you will get 10 different answers.

The linear gradient node is very simple. It outputs the X coordinate of the coordinate system that you’ve plugged in. It’s basically the same as separateXYZ and clamp the X coordinate between [0,1].

With this in mind, you can use whatever coordinate system you want. UVmaps, as custom coordinate systems, are very easy to edit, and can help on lots of small tricks, not only with materials as also with particles.
They are quite valueable whenever the globals (world pos, object pos, generated pos, normal, etc) are not enought for achieving the wished result.
And similar to UVmaps, you have also the vertex paint… While UVmaps are basically 2D, vertex paint can hold 3D values (which in some cases is also usefull).

The problem with such constructs as “inner rim” or “object’s edge” is that while it is quite clear for a human, what it means, it is not so easy to decribe it as a general property of geometry. For example, if you have a letter S, which edges are inner and which are outer? Ask 10 people and you will get 10 different answers.

As far as inner and outer rim, I’m talking about after I extrude outwards and create a rim / stroke / outline around the object. The outline has thickness, so it forms a continuous loop with a clear inner edge and outer edge, like so - https://i.imgur.com/nJetfDB.jpg

This could be detected by the program pretty easily, and there may even be a way to do it already, but I haven’t found it.

On my 5’s rim, the pointiness of the faces doesn’t change much, they’re all roughly cubes, with a few sharp triangles where the round part and flat part meet. There’s also the sharp 90 degree angle where the 5 extrudes downward along the Z axis, is that what you were thinking of as far as using pointiness to achieve the effect? Like it’s more pointy near the edge and less near the center? That might have potential as a solution though so far I can’t get anything except solid white or solid black.

edit: nevermind, you’re a genius, that solution DOES work. I was pulling my hair out because it never seemed to show the pointiness effect, it just seemed to blend my two input colors evenly across the whole surface. Then I tried rendered view, and there it was. For whatever reason it doesn’t show in material preview.

if an edge is not “pointy” enough to make the outer texture show, I figured out I can just add an edge loop that splits the outermost faces, then drag the loop all the way to the outermost edge, to create overlapping edges. Not great topology, but it does create a sort of “infinitely pointy” edge that makes the 2nd texture show up clearly.