3D Refraction Shader

3d refraction shader on ocean

After you have created vertex part of ocean shader using gerstner waves, you can make your ocean look more better by adding refraction effect for objects under the surface.

Bird Eye’s View

We need to sample screen texture with distorted UVs based on normals of object. Then we mix the screen texture color with object’s color based on a float alpha value. So if alpha is 1.0, only albedo color is shown, otherwise mix of albedo & screen texture is drawn. If alpha is 0.0, only screen texture is drawn which makes the water plane appear fully transparent.

Complete Code

shader_type spatial;

uniform samler2D normalmap;
uniform sampler2D screen_texture : hint_screen_texture;
uniform sampler2D albedo;
uniform float refraction_strength = 0.5;
uniform float alpha = 0.5;

vec2 refract_uv(vec2 uv, float strength, vec3 normal){
	uv += strength * (normal.x * normal.y * normal.z);
	return uv;

void fragment() {
	NORMAL_MAP = texture(normalmap, UV).rgb;
	ALBEDO = mix(albedo, texture(screen_texture, refract_uv(SCREEN_UV, refraction_strength, NORMAL_MAP)).rgb, 1.0 - alpha);

Continue reading

To make water even more better, you may want to add foam shader to your water to make it look realistic & part of the scene.

Table of Contents