Frost effect in three.js

Hi community!

I am looking for the solutions to achieve this effect.
Is there anyway to make the freezing or frost effect like this? :cold_face:

Thank you!

1 Like

Transmission / TransmissionMap on MeshPhysicalMaterial, together with a fancy normal map, may be precisely what you’re looking for :blush: (docs.)


Thank so much @mjurczyk !
Yeah, that’s one same as what I am looking for, but Im kinda wanna add animation for the freezing ice, same as this one on ShaderToy Spreading Frost
But this shader toy needs to work with texture as channel what I dont want to.
Can I use NormalMap on MeshPhysicalMaterial and make animation same as shader toy above?

1 Like

You could do something like the shader toy example easily with Polygonjs, as this gives you tools to inject code in threejs materials.

See this example, where in a few nodes, you can use a noise to have area with a low or high roughness, which gives a nice frost effect.


If you are allergic to shader,s you can try an old-school approach. With sufficient attention to details, it might be possible to make a nice effect. Here is a proof-of-concept demo – it uses static image as a seed, but it would be much better with some real-time fractal:


1 Like

wow! Thanks so much very much @PavelBoytchev
By the way I found similar example of yours but it was made by shaders and a lot of cool stuffs there :smiling_face_with_tear:
I tried to understand it but still…
Anyway, thank you and I’ll give it a try with the “old-school approach” above (hope it’s less complicated :smiling_face_with_tear: )

1 Like

Yes, that example uses three textures and a shader. Two textures are images for the two end cases - completely frozen and completely not frozen; the third texture is temporal and the shader uses it to control the process of transition between the two textures.

1 Like

Hi @PavelBoytchev !
I’ve tried your solution, it works well :stuck_out_tongue_winking_eye:
But what if I want to draw snowflake image into a PlaneGeometry (not a Box) only left and right side?
I was playing with the number:

const x = (700*Math.sin(this.count*1.7-1)+700)%712 - 100
const y = (700*Math.sin(this.count*1.1+2)+700)%712 - 100

but don’t know how to re-calculate it :frowning:

Here is what I got so far…


If you want to apply the frost to a plane geometry, you can use PlaneGeometry instead of BoxGeometry. The geometry is unrelated to the material.

If you want to have a box, but apply the material to only some of the 6 sides, you can use multi materials – i.e. an array of 6 materials instead of one material:

var box = new THREE.Mesh(
			new THREE.BoxGeometry( 3, 3, 3 ),
  			[ mat0, mat1, mat2, mat3, mat4, mat5 ]

Material mat0 will be applied to side 0, mat1 to side 1 and so on. For your case, you will have to apply the frost material to two of the sides, and another non-frost material to the rest 4 sides.

Do not forget that if you use array of materials and update the bumpScale of two of them, let’s say the 2nd and the 3rd, it is done by:

object.material[2].bumpScale = ...;
object.material[3].bumpScale = ...;

The two expressions with 700 in them – they just control how the snowflake drawing is distributed over the texture. The same texture is applied to all 6 sides of the box (unless you use multi materials).

Yes, you’re right,
and I am working with the PlaneGeometry instead of the Box.
What I want is to draw the texture in both left and right side of plane only (except the middle).
Because later, what I wanna achieve is draw the snow (per frame) only in the red region as the image below (the Snowy Plane will be attached into PerspectiveCamera):

So Im trying to play with the numbers cuz I think x and y will change the position of the texture while drawing:

const x = (1000*Math.sin(this.count*1.7-1)+1000)%1000 - 50
const y = (1000*Math.sin(this.count*1.1+2)+1000)%1000 - 50

So here is what I got so far:


The texture is drawn randomly for the whole plane which I don’t want to.
Do I really need to set multiple materials for Plane and update its bumScale? Since I don’t use Box.


Absolutely not! Do not use multiple material for PlaneGeometry.

Have you considered to use two plane geometries (to the left and right side of the screen), thus you can easily control their size and position.

If you insist on having a single plane, then you have to change how x is calculated. One possible way is this:


1 Like

Thanks so much for your reply! @PavelBoytchev

Yeah, I did the same thing by using two planes on the left and right side. Assign them with the same material and re-calculated the position of the texture and it works.

But I am facing another issue ( I consider to make another post or not, but I think same thread is better…anw) to attach (or lock) the planes into the camera so that the camera always looks at the planes in any angle.

My current approach is:


but it seems not right.

Do you know another solution for this case?
Thanks so much,

If you want to have the frost cover the camera, I’d look at a postprocessing effect to get the job done - much like the shadertoy posted earlier in the thread. Frost could be achieved by color-ramped fbm noise, probably.

Here’s a shadertoy I made w/ an ice effect that works in any postpro pipeline, no external textures (other than the scene diffuse) necessary.


I’m not sure I understand the question.

A blind shot → this demo shows how to place objects at the left and right edges of the window. Resize the window to see the effect:

1 Like

Thanks @N8Three for your reply!
And it’s really a nice effect!
Can I use it as references? ^^

Of course - feel free to use it however you want.

1 Like