Frosted Glass

This is a frosted glass shader using a bi-cubic function for the blur effect + an optional frosted texture that you can provide to add a bit of a frosty effect.

Shader code
shader_type spatial;

uniform sampler2D screen_texture : hint_screen_texture, filter_linear_mipmap; // Captures the screen texture
uniform sampler2D frosted_texture : source_color, repeat_enable; // Your frosted glass texture for distortion

uniform int lod_level : hint_range(0, 10) = 4; // Base blur level
uniform float brightness : hint_range(0.0, 100.0) = 1.0; // Brightness adjustment
uniform float distortion_intensity : hint_range(0.0, 0.1) = 0.02; // Strength of distortion

// w0, w1, w2, and w3 are the four cubic B-spline basis functions
float w0(float a) {
	return (1.0f / 6.0f) * (a * (a * (-a + 3.0f) - 3.0f) + 1.0f);
}

float w1(float a) {
	return (1.0f / 6.0f) * (a * a * (3.0f * a - 6.0f) + 4.0f);
}

float w2(float a) {
	return (1.0f / 6.0f) * (a * (a * (-3.0f * a + 3.0f) + 3.0f) + 1.0f);
}

float w3(float a) {
	return (1.0f / 6.0f) * (a * a * a);
}

// g0 and g1 are the two amplitude functions
float g0(float a) {
	return w0(a) + w1(a);
}

float g1(float a) {
	return w2(a) + w3(a);
}

// h0 and h1 are the two offset functions
float h0(float a) {
	return -1.0f + w1(a) / (w0(a) + w1(a));
}

float h1(float a) {
	return 1.0f + w3(a) / (w2(a) + w3(a));
}

vec4 texture2D_bicubic(sampler2D tex, vec2 uv, int p_lod, ivec2 tex_size) {
	vec2 tex_size_lod = vec2(tex_size >> p_lod);
	vec2 pixel_size = vec2(1.0f) / tex_size_lod;
	uv = uv * tex_size_lod + vec2(0.5f);
	vec2 iuv = floor(uv);
	vec2 fuv = fract(uv);
	float g0x = g0(fuv.x);
	float g1x = g1(fuv.x);
	float h0x = h0(fuv.x);
	float h1x = h1(fuv.x);
	float h0y = h0(fuv.y);
	float h1y = h1(fuv.y);
	vec2 p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - vec2(0.5f)) * pixel_size;
	vec2 p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - vec2(0.5f)) * pixel_size;
	vec2 p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - vec2(0.5f)) * pixel_size;
	vec2 p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - vec2(0.5f)) * pixel_size;
	return (g0(fuv.y) * (g0x * textureLod(tex, p0, float(p_lod)) + g1x * textureLod(tex, p1, float(p_lod)))) +
		   (g1(fuv.y) * (g0x * textureLod(tex, p2, float(p_lod)) + g1x * textureLod(tex, p3, float(p_lod))));
}

void fragment() {
    // Get the original UV coordinates
    vec2 screen_uv = SCREEN_UV;

    // Use the frosted texture for distortion
    vec2 distortion = texture(frosted_texture, UV).rg - 0.5; // Center distortion values around 0
    distortion = normalize(distortion) * distortion_intensity; // Normalize to prevent stretching

    // Apply the distortion to the UV coordinates
    vec2 distorted_uv = screen_uv + distortion;

    // Sample the screen texture with the distorted UV and specified LOD level
	vec4 blurred_color = texture2D_bicubic(screen_texture, distorted_uv, lod_level, textureSize(screen_texture, 0));

    // Adjust the brightness of the blurred color
    vec3 adjusted_color = blurred_color.rgb * brightness;

    // Apply the adjusted color to the fragment
    ALBEDO *= adjusted_color;

    // Optional: Preserve the original alpha of the blurred screen texture
    ALPHA = blurred_color.a;
}
Tags
3d, blur, blurry, frosted, frosty, glass, Transparent
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

Related shaders

Frosted Glass

Frosted glass

Improved frosted glass

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments