So Blurred glass material is impossible in Unreal Engine 4?

EDIT:

From this thread, I started to work on various glass and mirror materials.
If you’re interested in what’s going on, you can check these 2 posts:
https://forums.unrealengine.com/showthread.php?82037-Experiments-on-glasses-materials-Coloured-refracting-reflecting-etc
https://forums.unrealengine.com/showthread.php?98407-Mirror-shader

Cheers


Hi,
I searched a way to make a blurred glass material with UE4, I mean a glass material which is blurring all that’s behind it.
So I DON’T MEAN FROSTED GLASS, which can be more or less be done, as shown in this thread: Frosted Glass ? - Rendering - Epic Developer Community Forums
I mean regular, smooth blurring, like with a gaussian blur filter in Photoshop and changing in real time.

I didn’t find any tutorial about this on the web.
I searched in Epic documentation but found nothing really useful for this.
So, is it something the engine can’t do for the moment or did I (certainly) miss something? When I see all the incredible materials and visual effects you can achieve with UE4,
I have no reason to think that this particular effect couldn’t be done.

1 Like

It can be done but requires looking up several copies of the SceneColor node and offsetting them and then averaging them. This technique is a bit slow though. It is probably possible to do something better in code like use one of the downresed buffers for bloom. I asked BrianK about this and the reason it isn’t done already is that the bloom buffers are from the previous frame and have to be reprojected with camera movement. This means when there is a camera cut there will be no information for one frame. And when rotating the camera quickly you would see weird behavior on the edge of the screen that revealed new parts of the blurred image. I wouldn’t expect an epic solution to this anytime soon as a result of these issues but maybe one day.

OK. Thanks for these explanations.
Searching through the post process effects documentation, i wondered if you could find a way to make something like a “limited” gaussian DOF post process effect.
I mean: not applying the effect all over the screen but only on the part of the screen where the glass is visible, using an opacity mask recalculated every frame.
Is it currently undoable or could it be implemented?****

You could achieve such an optimized result by using a sprite that is of the same size as the bounding box of the mesh you want to use the blur. Jon Lindquist used a technique like this on fortnite to layer specific effects on various characters using the post process system. Using that method, only the pixels in the sprite are processed.

Great, thanks again ! I’ll experiment in this way.

Coincidentally last “Epic Friday” I messed around with doing a radial style blur custom node. It only took 2 line changes to make it work with SceneColor like you want.

I added a distance mask as well so you can have the blur get slightly less as objects get closer to the glass.

This is probably not very optimized, I just barely got TempAA dithering working on it but the settings are very fiddly to fix the specular artifacts.

It requires that you hook up the SceneColor node somewhere in opacity otherwise the compiler won’t recognize the texture.

The material graph:

The hlsl code for the custom material node:

float3 CurColor;
float2 BaseUV = MaterialFloat2(ScreenAlignedPosition(Parameters.ScreenPosition).xy);
float2 NewUV = BaseUV;
int i;
float StepSize = Distance / (int) DistanceSteps;
float CurDistance;
float2 CurOffset;
float TwoPi = 6.283185;
float Substep;
float2 ScenePixels = View.RenderTargetSizeBaseUV;
float2 RandomSamp = View.TemporalAAParams.r+ScenePixels;
RandomSamp = ((uint)(RandomSamp.x) + 2 * (uint)(RandomSamp.y)) % 5;
RandomSamp
=TempAARandom;
if (DistanceSteps<1)
{
return DecodeSceneColorForMaterialNode(NewUV);
}
else
{
while ( i < (int) DistanceSteps)
{

CurDistance += StepSize;
for (int j = 0; j < (int) RadialSteps; j++)
{
Substep++;
CurOffset.x = cos(TwoPi*((RandomSamp+Substep) / RadialSteps));
CurOffset.y = (TwoPi*((RandomSamp+Substep) / RadialSteps));
CurOffset =DistanceMask;
NewUV.x = BaseUV.x + (CurOffset.x * (CurDistance+RandomSamp
StepSize));
NewUV.y = BaseUV.y + (CurOffset.y * (CurDistance+RandomSampStepSize));
CurColor += DecodeSceneColorForMaterialNode(NewUV);
}
Substep+=0;
i++;
}
CurColor = CurColor / ((int)DistanceSteps
(int)RadialSteps);
return CurColor;
}

1 Like

With the TempAARandom set to 0 you can see some cool artifacts in specular highlights using various values of “Radial Steps”

3 radial steps:

3.1 Radial steps causes a spiral instead:

3.3 Radial steps causes a sort of fibonacci spiral:

The tempAA random fixes some of this up but not all of it without using tons of samples.

I think there is way better way of using TempAA here this was just an experiment.

That’s so cool! Blows my mind what can be done in realtime these days.

turns out the tempAA dither thing really needs the dither texture in addition to the math pattern offset. Makes the spec patterns much smoother except at very far distances.

I would have just used the DitherTemporalAA material node but for some reason plugging it in consistently caused a crash so I basically had to put all the code from that function into here.

b7e47b532ad397500877494729f00d5910e04e6a.jpeg

Hi there - i didn’t understand which file (and file format) i must edit or create to put these HLSL code to it? And in which directory it must be stored?

You have to add a “Custom” node, and paste the HLSL code there (and add the appropriate inputs).

I reproduced your material graph and pasted the second code in the custom node.
I checked it multiples times but I can’t get it to work.
Can’t figure out what the problem is.
Do you apply this material to a plane, a cube or a sprite? Does it matter?
Are there important settings you didn’t indicate?

Othewise: no doubt using a shader is the way to achieve this blurring effect but I have no skills to do it.
So I tried to achieve my limited gaussian blur DOF effect in a post process material as a first step.
Quite simple, in fact. Here is the graph, if it can be useful to someone:

And the texture I used as a mask in the material:

And here is what i get in game:

Nice setup :slight_smile:

You could try using CustomDepth to create masks for the objects in your scene to use.

In terms of why the other approach didnt work, did you have scenecolor hooked up to opacity somewhere? You also need to make sure that the values for Distance, Distance Steps and Radial Steps are all above 1 or nothing happens. Also just set DistanceMask to 1 to rule that out.

Even with these tweaks, it doesn’t work for me.
Wondering what I’m missing here.
What was the map you tested it on?
Does it work for someone else?

I tried your setup as well and for some reason the DOF blur shows up even when I just plug in the straight “SceneTexture:SceneColor” sample or PostProcessInput0. Were you just defining DOF in a post process volume or was there something else going on?

In terms of why the custom node didn’t work, is what ue4 version are you in? What did the output of the node give? Any errors? A pic of the material graph would be useful.

Nevermind figured it out. You need to set the material to “Before Tonemapping” down in the “post process material” settings.

This is a really nice basically free way to get controllable blur. The only problem with this technique is you will give up DOF elsewhere in the scene since this isn’t doing a separate pass its simply blending to a scene without the post process for outside the window.

In this example, I used a simple plane instead of a cube, I unchecked “Receive Decals” on the skeletal mesh and used SceneTexture:decalmask to better define where the blur is applied.
And it works but the problem is that I can’t get rid of the “blurry halo” around the character:

Such a shame I can’t exclude the character from beeing affected by depth of field, as meshes with translucent materials can be.
Or is there an option here?

The above halo problem is a pretty standard problem. Even the approach I did has that same problem.

The custom node version can fix this problem though by comparing depths and rejecting a sample if it came from a depth that is greater than the window. But then you have to do something like use an old color or use no color, which means you still have a halo of some kind, like a halo of no blur at all. Clever use of temporalAA may help solve it. I haven’t tried that yet but it might be fun to mess around with.

Ok, I found a way to get rid of the halo.

So now I have 2 problems to fix:

1 - The skySphere is not affected by DOF. I don’t think it’s the most difficult part - but I didn’t find out how to tweak it’s material the proper way).

31a314387361d112abb9e6e54ae77c18dba80618.jpeg

2 - With my actual setup, actors are always or never blurred.

67eba0a98d295628c5f030c9fe5027c655f1f480.jpeg

So, in the pic above, my character which is behind the window, should be blurred, but he is not.

How did you accomplish masking the actors from the DOF? you didn’t have the sky masking problem before. That default engine sky is opaque which means there should be no issues picking it up in DOF.