NodeMaterial Smooth Blur

@sebavan

Hi

I found this on the forum:

I’m also now standing in front of the same problem. I’m generating a texture that I want to be blurred and then used as input for the rest of my Node Material.

I need this:

To look like this:

And to be done inside NodeMaterials and not with postprocessing.

I prepared a starter NodeMaterial:

Regards
Peter

And I just tested blur with adding noise to UVs and It’s actually not working cause it adds even more problems at the end.

It makes it super grainy which I want to get rid of that mora effect.

I think you will need to do the multiple lookups in the texture yourself. For eg, something like:

https://nme.babylonjs.com/#M189YK#1

It is averaging the pixels on the left/right/top/bottom of the current pixel, with a weight of 0.5 for those pixels (and 1 for the current pixel). If you want gaussian blur, I think you will need to perform more lookups and use different weights.

I would advise against doing the blur like this, you will get bad performances because of all the additional texture fetching you will do compared to having a separate post process pass that will apply two passes to the picture, one for the X and one for the Y dimension.

@Evgeni_Popov

OK, but what to do if my result is in the middle of the Node Material pipeline?

I’m actually making Normal maps out of height maps but the result is so grainy it’s not working at all after. Results with additional texture are not doing this. But the ones generated are terrible and are not working with the rest of the shader. I actually need this in NodeMaterial blocks but I cant work it out.

|

Then you will need to do as how I did it with multiple texture lookups and averaging the results.

Hi @Evgeni_Popov

So I put the texture that I was interested in and it looks almost the same:

https://nme.babylonjs.com/#M189YK#2

So there is no blur amount that I added to control it. And I also put it on purpose to be behind the texture cause I would need to use it there. I need to prepare it in a way, that will be input for the next step for something else. And the Normal map is again the middle point. I’m not interested in it.

https://nme.babylonjs.com/#M189YK#3

So. What I really need to do is to blur this output. Even with your solution. How do I make it work? For now, you got this terrible morra effect while moving the camera. And again I’m not interested in the normal map. It must be strong like that just blurred at the end.

Regards
Peter

My mistake, the sum of the weights is 3 in my example:

https://nme.babylonjs.com/#M189YK#4

You will see that if you link directly the texture output to the fragmentOutput block and compare with the output of the divide block the texture is a little blurred in the latter case. If you want more blur you need to add additional texture lookups to take into account more neighbours of the current pixels. It’s a bit tedious to do that in the NME but I don’t see another way…

You can’t blur the output of the Remap block in the same way because you only get a rgb value here, not a texture. What you can do is blurring the input texture and apply your derivation on it instead. Something like:

https://nme.babylonjs.com/#M189YK#5

Hi @Evgeni_Popov

I see you hit my problem then.

And I do not have a texture that goes in. I told you this is in the middle of the Material. This is just an example that simulates the scenario.

So maybe differently. How can I make Derivatives smooth? Cause this is always very pixelated. Even more, than the texture suggests. It got more steps than pixels in texture. How can I smooth the derivative? Cause my math is not on that level TBH and I do not really get why it comes out like that.

https://nme.babylonjs.com/#M189YK#6

But I see a lot of people are searching for exactly this solution. Not smoothing the texture but smoothing some RBG shader output. That’s why I put my “Do stuff” frame after the texture output. It’s a tricky thing but would make so much more good after that. I’m really stuck only on this for 4 days now :confused:

Regards
Peter

Not sure if it helps, but if you are not limited in nodeMaterial, you can try to use shaderMaterial and use textureGrad function instead of texture function to get the color, with that you can pass the dx/dy yourself to reduce morra effect.

In your shader, if you plug the ColorSplitter.r output to the input of the Derivative block instead of the current Texture.r output you will see it’s better, it’s a bit smoothed out.

Original shader:
image

With smoothing (https://nme.babylonjs.com/#M189YK#7):
image

If you want more smoothing, you will need to add additional lookups.

Hello @peterimg just checking in, was your question answered?

@carolhmj

Not really but this is apparently how the shaders are working so I decided to do it differently cause this solution was clearly not for me. So no problems.

Or do you have a solution for it?

Regards
Peter

@peterimg, This is a simple and hacky way to get small amounts of fake blur
in the shader. This is basically the same as sampling the texture multiple times. Granted if you want a high-quality blur this isn’t the way to go as you would need to do this operation several more times which will get costly. But if you are looking for quick and dirty small blur amounts in the middle of the shader, this may work but it will need to be customized for the size of the image you are using and the amount of blur you need.

2 Likes

Hi @PatrickRyan

Yes, that will work for someone that has a texture and I do not have one. I need to blur shader output. That’s my problem :expressionless:

But thank you anyway for sharing this. This will be useful for someone :slight_smile:

Regards
Peter

Can you write your shader output to a Render Target Texture and blur that?

1 Like