Skip to content

Instantly share code, notes, and snippets.

@ShaneBrumback
Last active September 28, 2024 05:19
Show Gist options
  • Save ShaneBrumback/4b7df59d3129f56f03f84e4115d5fce4 to your computer and use it in GitHub Desktop.
Save ShaneBrumback/4b7df59d3129f56f03f84e4115d5fce4 to your computer and use it in GitHub Desktop.
Threejs Examples Water Shader Effects
<!--////////////////////////////////////////////////////////////////////////////////////////
/// ///
/// Example Using Three.js Library, HTML, CSS & JavaScript ///
// 3D Interactive Web Apps & Games 2021-2024 ///
/// Contact Shane Brumback https://www.shanebrumback.com ///
/// Send a message if you have questions about this code ///
/// I am a freelance developer. I develop any and all web. ///
/// Apps Websites 3D 2D CMS Systems etc. Contact me anytime :) ///
/// ///
////////////////////////////////////////////////////////////////////////////////////////////-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js Examples - Water Shader Effects Updated</title>
<style>
body {
color: white;
text-align: center;
margin: 0;
background-color: black
}
a {
text-decoration: none;
color: white;
}
h1 {
padding: 10px;
}
</style>
</head>
<body>
<a href="http://www.shanebrumback.com/threejs-examples/water-shader-effects.html">
<h1>Three.js Examples - Water Shader Effects</h1>
</a>
<script type="importmap">
{
"imports": {
"three": "../build/three.module.js"
}
}
</script>
<script type="module">
// Import necessary modules from Three.js library
import * as THREE from 'three';
import Stats from '../jsm/libs/stats.module.js';
import { GUI } from '../jsm/libs/lil-gui.module.min.js';
import { OrbitControls } from '../jsm/controls/OrbitControls.js';
import { Water } from '../jsm/objects/Water.js';
import { Sky } from '../jsm/objects/Sky.js';
let stats;
let camera, scene, renderer;
let controls, water, sun, mesh;
// Initialize the application
init();
function init() {
// Create the WebGL renderer
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.toneMapping = THREE.ReinhardToneMapping;
renderer.setClearColor(0x000000);
renderer.domElement.style.position = 'fixed';
renderer.domElement.style.zIndex = '-1';
renderer.domElement.style.left = '0';
renderer.domElement.style.top = '0';
document.body.appendChild(renderer.domElement);
// Create the scene
scene = new THREE.Scene();
// Create the camera
camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 1, 20000);
camera.position.set(30, 30, 100);
// Create the sun vector
sun = new THREE.Vector3();
// Create the water geometry
const waterGeometry = new THREE.PlaneGeometry(10000, 10000);
// Create the water object
water = new Water(
waterGeometry,
{
textureWidth: 512,
textureHeight: 512,
waterNormals: new THREE.TextureLoader().load('../textures/water/waternormals.jpg', function (texture) {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
}),
sunDirection: new THREE.Vector3(),
sunColor: 0xffffff,
waterColor: 0x001e0f,
distortionScale: 3.7,
fog: scene.fog !== undefined
}
);
// Set the rotation of the water
water.rotation.x = - Math.PI / 2;
// Add the water to the scene
scene.add(water);
// Create the sky object
const sky = new Sky();
sky.scale.setScalar(10000);
scene.add(sky);
// Set the parameters for the sky
const skyUniforms = sky.material.uniforms;
skyUniforms['turbidity'].value = 10;
skyUniforms['rayleigh'].value = 2;
skyUniforms['mieCoefficient'].value = 0.005;
skyUniforms['mieDirectionalG'].value = 0.8;
// Set the parameters for the sun
const parameters = {
elevation: 2,
azimuth: 180
};
// Create the PMREM generator
const pmremGenerator = new THREE.PMREMGenerator(renderer);
// Update the position of the sun and sky
function updateSun() {
const phi = THREE.MathUtils.degToRad(90 - parameters.elevation);
const theta = THREE.MathUtils.degToRad(parameters.azimuth);
sun.setFromSphericalCoords(1, phi, theta);
sky.material.uniforms['sunPosition'].value.copy(sun);
water.material.uniforms['sunDirection'].value.copy(sun).normalize();
scene.environment = pmremGenerator.fromScene(sky).texture;
}
// Call the updateSun function
updateSun();
// Create a cube mesh
const geometry = new THREE.BoxGeometry(30, 30, 30);
const material = new THREE.MeshStandardMaterial({ roughness: 0 });
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
// Create orbit controls
controls = new OrbitControls(camera, renderer.domElement);
controls.maxPolarAngle = Math.PI * 0.495;
controls.target.set(0, 10, 0);
controls.minDistance = 40.0;
controls.maxDistance = 200.0;
controls.update();
// Get the water uniforms
const waterUniforms = water.material.uniforms;
// Add event listener for window resize
window.addEventListener('resize', onWindowResize);
// Start the animation loop
animate();
}
// Function to handle window resize
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
// Animation loop
function animate() {
requestAnimationFrame(animate);
render();
stats.update();
controls.update();
}
// Render function
function render() {
const time = performance.now() * 0.001;
mesh.position.y = Math.sin(time) * 20 + 5;
mesh.rotation.x = time * 0.5;
mesh.rotation.z = time * 0.51;
water.material.uniforms['time'].value += 1.0 / 60.0;
renderer.render(scene, camera);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment