Last active
September 28, 2024 05:19
-
-
Save ShaneBrumback/4b7df59d3129f56f03f84e4115d5fce4 to your computer and use it in GitHub Desktop.
Threejs Examples Water Shader Effects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!--//////////////////////////////////////////////////////////////////////////////////////// | |
/// /// | |
/// 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