135 lines
3.6 KiB
HTML
135 lines
3.6 KiB
HTML
|
|
<!doctype html>
|
||
|
|
<html lang="en">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
|
<title>WebGPU FFT Ocean Demo</title>
|
||
|
|
<style>
|
||
|
|
body {
|
||
|
|
margin: 0;
|
||
|
|
background: radial-gradient(circle at 20% 20%, #0f172a, #020617 60%);
|
||
|
|
color: #e2e8f0;
|
||
|
|
font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
|
||
|
|
height: 100vh;
|
||
|
|
width: 100vw;
|
||
|
|
overflow: hidden;
|
||
|
|
}
|
||
|
|
#container {
|
||
|
|
position: fixed;
|
||
|
|
inset: 0;
|
||
|
|
border: none;
|
||
|
|
box-shadow: none;
|
||
|
|
overflow: hidden;
|
||
|
|
}
|
||
|
|
#status {
|
||
|
|
position: absolute;
|
||
|
|
left: 12px;
|
||
|
|
bottom: 12px;
|
||
|
|
padding: 6px 10px;
|
||
|
|
background: rgba(15, 23, 42, 0.65);
|
||
|
|
border: 1px solid #1f2937;
|
||
|
|
border-radius: 6px;
|
||
|
|
font-size: 12px;
|
||
|
|
letter-spacing: 0.4px;
|
||
|
|
backdrop-filter: blur(4px);
|
||
|
|
}
|
||
|
|
canvas {
|
||
|
|
width: 100vw;
|
||
|
|
height: 100vh;
|
||
|
|
display: block;
|
||
|
|
}
|
||
|
|
#controls {
|
||
|
|
position: absolute;
|
||
|
|
right: 12px;
|
||
|
|
top: 12px;
|
||
|
|
padding: 6px 10px;
|
||
|
|
background: rgba(15, 23, 42, 0.75);
|
||
|
|
border: 1px solid #1f2937;
|
||
|
|
border-radius: 6px;
|
||
|
|
font-size: 12px;
|
||
|
|
display: flex;
|
||
|
|
align-items: flex-start;
|
||
|
|
gap: 10px;
|
||
|
|
backdrop-filter: blur(4px);
|
||
|
|
}
|
||
|
|
#controls label {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 6px;
|
||
|
|
white-space: nowrap;
|
||
|
|
}
|
||
|
|
#controls input[type="range"] {
|
||
|
|
width: 140px;
|
||
|
|
}
|
||
|
|
#controls .column {
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
gap: 6px;
|
||
|
|
}
|
||
|
|
#controls .row {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 6px;
|
||
|
|
}
|
||
|
|
#controls select {
|
||
|
|
font-size: 12px;
|
||
|
|
padding: 2px 4px;
|
||
|
|
background: #020617;
|
||
|
|
color: #e2e8f0;
|
||
|
|
border-radius: 4px;
|
||
|
|
border: 1px solid #1f2937;
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<div id="container">
|
||
|
|
<canvas id="gfx"></canvas>
|
||
|
|
<div id="controls">
|
||
|
|
<div class="column">
|
||
|
|
<label class="row">
|
||
|
|
Wave height
|
||
|
|
<input id="waveHeight" type="range" min="0" max="60" step="1" value="33">
|
||
|
|
<span id="waveHeightValue">33</span>
|
||
|
|
</label>
|
||
|
|
<label class="row">
|
||
|
|
Wave length
|
||
|
|
<input id="wavelengthSlider" type="range" min="0.25" max="4" step="0.05" value="1">
|
||
|
|
<span id="wavelengthValue">1.00</span>
|
||
|
|
</label>
|
||
|
|
<label class="row">
|
||
|
|
Resolution
|
||
|
|
<input id="resolutionSlider" type="range" min="32" max="2048" step="32" value="1024">
|
||
|
|
<span id="resolutionValue">1024</span>
|
||
|
|
</label>
|
||
|
|
<label class="row">
|
||
|
|
<input id="wireframeToggle" type="checkbox">
|
||
|
|
Wireframe mode
|
||
|
|
</label>
|
||
|
|
<label class="row">
|
||
|
|
<input id="pauseToggle" type="checkbox">
|
||
|
|
Pause waves
|
||
|
|
</label>
|
||
|
|
<label class="row">
|
||
|
|
<button id="stepButton" type="button">Next frame</button>
|
||
|
|
</label>
|
||
|
|
<label class="row">
|
||
|
|
Shading
|
||
|
|
<select id="shadingMode">
|
||
|
|
<option value="realistic">Realistic</option>
|
||
|
|
<option value="lighting">Lighting</option>
|
||
|
|
<option value="normals">Normals</option>
|
||
|
|
<option value="solid">Solid color</option>
|
||
|
|
<option value="height">Height (debug)</option>
|
||
|
|
</select>
|
||
|
|
</label>
|
||
|
|
<label class="row">
|
||
|
|
<button id="dumpHeightButton" type="button">Dump height (debug)</button>
|
||
|
|
</label>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div id="status">Initializing WebGPU ocean…</div>
|
||
|
|
</div>
|
||
|
|
<script type="module" src="./main.js"></script>
|
||
|
|
</body>
|
||
|
|
</html>
|