Meta Description" name="description" />

Share this result

Previews are deleted daily. Get a permanent share link sent to your inbox:
Script
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Ocean Wave Simulation</title> <style> body { margin: 0; background-color: #000; color: #fff; font-family: sans-serif; } canvas { display: block; } #info { position: absolute; top: 10px; width: 100%; text-align: center; z-index: 100; display:block; } .controls { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); background: rgba(0, 0, 0, 0.5); padding: 15px; border-radius: 10px; display: flex; gap: 20px; align-items: center; } .slider-container { display: flex; flex-direction: column; align-items: center; } label { margin-bottom: 5px; } input[type="range"] { width: 150px; } </style> </head> <body> <div id="info"> <h1>Ocean Wave Simulation</h1> </div> <div class="controls"> <div class="slider-container"> <label for="windSpeed">Wind Speed</label> <input type="range" id="windSpeed" min="0.1" max="10" value="4" step="0.1"> </div> <div class="slider-container"> <label for="waveHeight">Wave Height</label> <input type="range" id="waveHeight" min="0.1" max="5" value="1" step="0.1"> </div> <div class="slider-container"> <label for="lighting">Lighting</label> <input type="range" id="lighting" min="-1" max="1" value="0.5" step="0.01"> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script> let scene, camera, renderer, water, light; let windSpeed = 4, waveHeight = 1, lighting = 0.5; init(); animate(); function init() { scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000); camera.position.set(0, 5, 10); camera.lookAt(scene.position); renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); const waterGeometry = new THREE.PlaneGeometry(100, 100, 100, 100); const waterMaterial = new THREE.ShaderMaterial({ uniforms: { time: { value: 1.0 }, windSpeed: { value: windSpeed }, waveHeight: { value: waveHeight }, lightDirection: { value: new THREE.Vector3(lighting, 1.0, 0.5) }, waterColor: { value: new THREE.Color(0x001e0f) }, skyColor: { value: new THREE.Color(0x87CEEB) } }, vertexShader: ` uniform float time; uniform float windSpeed; uniform float waveHeight; varying vec3 vNormal; varying vec3 vPosition; void main() { vNormal = normal; vec3 pos = position; float k = 2.0 * 3.14159 / 20.0; float c = sqrt(9.8 / k); float f1 = k * (pos.x - c * time * windSpeed); float f2 = k * (pos.y - c * time * windSpeed * 0.5); pos.z += waveHeight * sin(f1); pos.z += waveHeight * cos(f2) * 0.5; vPosition = pos; gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); } `, fragmentShader: ` uniform vec3 lightDirection; uniform vec3 waterColor; uniform vec3 skyColor; varying vec3 vNormal; varying vec3 vPosition; void main() { vec3 normal = normalize(vNormal); vec3 lightDir = normalize(lightDirection); float fresnel = dot(cameraPosition - vPosition, normal); fresnel = pow(1.0 - fresnel, 3.0); fresnel = clamp(fresnel, 0.0, 1.0); float diffuse = max(0.0, dot(normal, lightDir)); vec3 color = mix(waterColor, skyColor, fresnel); gl_FragColor = vec4(color * diffuse, 1.0); } ` }); waterMaterial.side = THREE.DoubleSide; water = new THREE.Mesh(waterGeometry, waterMaterial); water.rotation.x = -Math.PI / 2; scene.add(water); light = new THREE.DirectionalLight(0xffffff, 1); scene.add(light); window.addEventListener('resize', onWindowResize, false); document.getElementById('windSpeed').addEventListener('input', (event) => { windSpeed = parseFloat(event.target.value); water.material.uniforms.windSpeed.value = windSpeed; }); document.getElementById('waveHeight').addEventListener('input', (event) => { waveHeight = parseFloat(event.target.value); water.material.uniforms.waveHeight.value = waveHeight; }); document.getElementById('lighting').addEventListener('input', (event) => { lighting = parseFloat(event.target.value); water.material.uniforms.lightDirection.value.x = lighting; }); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } function animate() { requestAnimationFrame(animate); water.material.uniforms.time.value += 1.0 / 60.0; renderer.render(scene, camera); } </script> </body> </html>
Landing Page
This ad does not have a landing page available
Network Timeline
Performance Summary

2

Requests

2

Domains

125KB

Transfer Size

596KB

Content Size

1,225.0ms

Dom Content Loaded

124.0ms

First Paint

1,225.0ms

Load Time
Domain Breakdown
Transfer Size (bytes)
Loading...
Content Size (bytes)
Loading...
Header Size (bytes)
Loading...
Requests
Loading...
Timings (ms)
Loading...
Total Time
Loading...
Content Breakdown
Transfer Size (bytes)
Loading...
Content Size (bytes)
Loading...
Header Size (bytes)
Loading...
Requests
Loading...