Ocean Test_1

re

Shader code
shader_type spatial;
render_mode blend_mix, depth_draw_opaque, cull_disabled, diffuse_burley, specular_schlick_ggx;

// Core Color Uniforms
uniform vec4 primary_colour : source_color; 
uniform vec4 secondary_color: source_color;
uniform float roughness : hint_range(0.0, 1.0) = 0.2;
uniform bool fernalEnabled = true;

// Texture Uniforms
uniform sampler2D normalmapA : hint_normal, filter_linear_mipmap_anisotropic;
uniform sampler2D normalmapB : hint_normal, filter_linear_mipmap_anisotropic;
uniform bool enable_second_normalmap = true;

uniform sampler2D screeen_texture : hint_screen_texture, repeat_disable, filter_nearest;
uniform sampler2D depth_texture : hint_depth_texture, repeat_disable, filter_nearest;

// Global Control Toggles
uniform bool enable_depth_effects = true;
uniform bool use_compatibility_mode = false; // Turn ON if running on Mobile/WebGL/Compatibility backend

// Depth & Beer's Law Variables
uniform float depth_distance : hint_range(0.0, 20.0, 0.1) = 4.0;
uniform float beers_law : hint_range(0.0, 20.0, 0.1) = 12.0;
uniform float water_transpareny : hint_range(0.0, 1.0, 0.01) = 0.05;

// Refraction Uniforms
uniform float refraction_strength : hint_range(0.0, 1.0, 0.01) = 0.02;

// Ripples Tuning
uniform float normalmapAstrength : hint_range(0.0, 1.0) = 0.3;
uniform float model_normal_b_strength : hint_range(0.0, 1.0) = 0.4;
uniform vec2 movementdirection = vec2(0.2, 0.1);
uniform float movementstrength = 0.1; 
uniform float UV_Scale = 25.0; 

// Contrast Sharpening
uniform float smooth_edge_low : hint_range(-1.0, 1.0) = -0.5;
uniform float smooth_edge_high : hint_range(-1.0, 1.0) = 0.5;

void fragment() {
	// --- 1. CORE MOVING NORMAL MAPS GENERATION ---
	vec2 scaled_uv = UV * UV_Scale;
	float time_scaled = TIME * movementstrength;
	
	// Sample primary moving map
	vec3 texA = texture(normalmapA, scaled_uv + (movementdirection * time_scaled)).rgb;
	vec3 blended_normal = texA * vec3(normalmapAstrength, normalmapAstrength, 1.0);

	// Dynamically blend secondary rotated moving map to hide repetition
	if (enable_second_normalmap) {
		vec2 dirB = vec2(movementdirection.x * 0.5 - movementdirection.y * 0.866, movementdirection.x * 0.866 + movementdirection.y * 0.5);
		vec2 uvB = scaled_uv - (dirB * (time_scaled * 1.15)) + vec2(0.32, 0.71);
		vec3 texB = texture(normalmapB, uvB).rgb;
		
		vec3 n2 = texB * vec3(model_normal_b_strength, model_normal_b_strength, 1.0);
		blended_normal = vec3(blended_normal.xy + n2.xy, blended_normal.z * n2.z);
	}
	
	// Apply visual sharpening pass to normal values
	blended_normal.x = smoothstep(smooth_edge_low, smooth_edge_high, blended_normal.x) * 2.0 - 1.0;
	blended_normal.y = smoothstep(smooth_edge_low, smooth_edge_high, blended_normal.y) * 2.0 - 1.0;
	
	// Set baseline outputs
	vec3 final_albedo = primary_colour.rgb;
	float depth_blend_factor = 0.0;
	float basic_frenel = pow(1.0 - clamp(dot(normalize(NORMAL), normalize(VIEW)), 0.0, 1.0), 3.0);
	
	// --- 2. DEPTH EFFECTS, BEER'S LAW, AND REFRACTION ---
	if (enable_depth_effects) {
		// Distort screen space coordinate using normal vectors
		vec2 refracted_uv = SCREEN_UV + (blended_normal.xy * refraction_strength);
		float depth_raw = textureLod(depth_texture, refracted_uv, 0.0).r;
		float water_depth = 0.0;
		
		if (use_compatibility_mode) {
			// Compatibility (OpenGL) depth-reconstruction pass
			vec4 upos = INV_PROJECTION_MATRIX * vec4(refracted_uv * 2.0 - 1.0, depth_raw, 1.0);
			water_depth = (-upos.z / upos.w) + VERTEX.z;
			
			// Shoreline bleeding cleanup safety catch
			if (water_depth < 0.0) {
				refracted_uv = SCREEN_UV;
				depth_raw = textureLod(depth_texture, SCREEN_UV, 0.0).r;
				upos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, depth_raw, 1.0);
				water_depth = (-upos.z / upos.w) + VERTEX.z;
			}
		} else {
			// Forward++ (Vulkan) world-space depth-reconstruction pass
			vec3 ndc = vec3(refracted_uv * 2.0 - 1.0, depth_raw);
			vec4 world = INV_VIEW_MATRIX * INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
			float vertex_y = (INV_VIEW_MATRIX * vec4(VERTEX, 1.0)).y;
			water_depth = vertex_y - (world.y / world.w);
			
			// Shoreline bleeding cleanup safety catch
			if (water_depth < 0.0) {
				refracted_uv = SCREEN_UV;
				depth_raw = textureLod(depth_texture, SCREEN_UV, 0.0).r;
				ndc = vec3(SCREEN_UV * 2.0 - 1.0, depth_raw);
				world = INV_VIEW_MATRIX * INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
				vertex_y = (INV_VIEW_MATRIX * vec4(VERTEX, 1.0)).y;
				water_depth = vertex_y - (world.y / world.w);
			}
		}
		
		// Map linear depth to exponential Beer's law curve
		float linear_depth_blend = clamp(water_depth / depth_distance, 0.0, 1.0);
		depth_blend_factor = exp(-linear_depth_blend * beers_law);
		
		// Grab background screen buffer and compile final color stack
		vec3 screen = texture(screeen_texture, refracted_uv).rgb;
		vec3 depth_color = mix(secondary_color, primary_colour, depth_blend_factor).rgb;
		vec3 background_mix = mix(depth_color, screen, water_transpareny);
		
		if (fernalEnabled) {
			final_albedo = mix(background_mix, screen, depth_blend_factor * (1.0 - basic_frenel));
		} else {
			final_albedo = mix(background_mix, screen, depth_blend_factor);
		}
	} else {
		// Baseline color mode fallback when depth logic is checked off completely
		if (fernalEnabled) {
			final_albedo = primary_colour.rgb + (0.2 * basic_frenel);
		}
	}
	
	// --- 3. FINAL PIPELINE ASSIGNMENTS ---
	ALBEDO = final_albedo;
	NORMAL_MAP = normalize(blended_normal);
	ROUGHNESS = (fernalEnabled) ? roughness * (1.0 - basic_frenel) : roughness;
	ALPHA = (enable_depth_effects) ? 1.0 : water_transpareny;
}
Live Preview
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.
guest

0 Comments
Oldest
Newest Most Voted