{
  "id": "water",
  "course": "creative",
  "version": 1,
  "title": { "en": "Build a water surface from three waves", "ja": "3 つの波から水面を作る" },
  "summary": {
    "en": "Change wave height and speed, inspect the mesh, then download a record of what your browser actually submitted. This free local demo uses native WebGL and no AI model.",
    "ja": "波の高さと速さを変え、メッシュを確認し、ブラウザーが実際に描画要求した内容を記録として保存します。無料のローカルデモで、ネイティブ WebGL を使います。AI モデルは使いません。"
  },
  "execution": { "kind": "local-procedural", "model": "none", "networkRequired": false, "paidApiRequired": false, "recordSchema": "demoWaterVersion1" },
  "intro": {
    "en": "A shader is a small GPU program. Here the vertex shader moves a grid up and down by summing three sine waves. The fragment shader shades the surface using interpolated analytic normals, a fictional depth tint and simple lighting. These are chosen visual approximations: a convincing image does not establish a physically correct ocean.",
    "ja": "シェーダーは GPU で実行する小さなプログラムです。ここでは頂点シェーダーが 3 つの正弦波を足し合わせて格子を上下に動かします。フラグメントシェーダーは解析的に計算した法線を補間し、仮の水深による色と簡単な照明で水面を描きます。見た目のために選んだ近似であり、きれいに見えても物理的に正しい海とは限りません。"
  },
  "inputs": [
    { "id": "wave-amplitude", "type": "range", "min": 0, "max": 0.5, "step": 0.01, "default": 0.18, "label": { "en": "Wave height", "ja": "波の高さ" }, "description": { "en": "Maximum combined height scale in arbitrary scene units. Zero flattens the grid.", "ja": "シーン内の任意単位で表す波高の倍率です。0 では格子が平らになります。" } },
    { "id": "wave-speed", "type": "range", "min": 0, "max": 2, "step": 0.05, "default": 0.6, "label": { "en": "Wave speed", "ja": "波の速さ" }, "description": { "en": "Multiplies the simulated phase progression. Zero keeps the current wave shape still.", "ja": "波の位相が進む速度の倍率です。0 では現在の波形が止まります。" } },
    { "id": "water-wireframe", "type": "checkbox", "default": false, "label": { "en": "Show grid", "ja": "格子を表示" }, "description": { "en": "Shows horizontal and vertical mesh edges so you can connect the surface to its geometry.", "ja": "メッシュの縦横の辺を表示し、水面と形状データの関係を確認できます。" } }
  ],
  "outputs": [
    { "en": "An interactive water-like height field drawn in a local canvas.", "ja": "ローカルの canvas に描かれる、水面風の高さ場。" },
    { "en": "A JSON execution record with settings, settings history, submitted frames, drawing-buffer size, browser version and JavaScript submission timing.", "ja": "設定・変更履歴・描画要求フレーム数・描画バッファー寸法・ブラウザーバージョン・JavaScript の描画要求時間を含む JSON 実行記録。" }
  ],
  "procedure": [
    { "en": "Start with height 0.18 and speed 0.6. Observe one full cycle, then pause.", "ja": "高さ 0.18、速さ 0.6 で開始し、波の動きを観察してから停止します。" },
    { "en": "Set height to zero. The grid becomes flat; any remaining color variation comes from the lighting and view terms.", "ja": "高さを 0 にします。格子が平らになり、残った色の違いは照明や視点によるものだと確認できます。" },
    { "en": "Restore the height and turn on the grid. Compare the displaced geometry with the shaded surface.", "ja": "高さを戻して格子を表示し、変形した形状と陰影の付いた水面を比べます。" },
    { "en": "Set speed to zero, then change height. A still frame separates the geometry setting from the animation setting.", "ja": "速さを 0 にして高さを変えます。静止画なら形状の設定とアニメーションの設定を分けて確認できます。" },
    { "en": "Download the record after at least one submitted frame. Save an observation of visual quality alongside it; the record itself cannot judge appearance.", "ja": "少なくとも 1 フレームの描画要求が成功したら記録を保存します。見た目の観察メモも別に残してください。記録だけでは外観の品質は判断できません。" }
  ],
  "review": [
    { "en": "Does zero height produce a flat surface? Does zero speed stop the phase? Does pause keep the shape steady?", "ja": "高さ 0 で平面になるか、速さ 0 で位相が止まるか、停止で形が固定されるかを確認します。" },
    { "en": "Compare shaded and grid modes. Check for missing triangles, clipping or flashing at several canvas sizes.", "ja": "陰影表示と格子表示を比べ、複数の画面寸法で三角形の欠落・切れ・点滅がないか確認します。" },
    { "en": "Hide the tab or scroll the canvas away. Animation pauses automatically. Reduced-motion preference starts with a still frame; Play can explicitly enable animation.", "ja": "タブを非表示にするか canvas を画面外へ移動すると自動停止します。動きを減らす設定では静止画から始まり、再生を押すと動きを有効にできます。" },
    { "en": "A failed WebGL context or shader reports an error. A record requires an actual successful command submission; it is never prefilled as an executed experiment.", "ja": "WebGL の初期化やシェーダーに失敗した場合はエラーを表示します。記録には実際に成功した描画要求が必要で、実行済みの実験として事前入力しません。" }
  ],
  "limitations": [
    { "en": "This is a height-field illustration, not a fluid simulation. There is no reflection, refraction, foam, shoreline, collision or texture.", "ja": "高さ場の説明用デモで、流体シミュレーションではありません。反射・屈折・泡・岸辺・衝突・テクスチャは実装していません。" },
    { "en": "The depth tint uses an invented flat bottom. It does not measure real water depth or solve light transport through water.", "ja": "水深による色は仮の平らな底を使います。実際の水深を計測したり、水中の光の伝わり方を計算したりはしません。" },
    { "en": "Normals come from analytic wave derivatives at vertices, then are interpolated and normalized per fragment. A finite grid limits geometric detail.", "ja": "法線は頂点で波の微分から解析的に計算し、各フラグメントで補間・正規化します。格子の細かさによって形状の細部には限界があります。" },
    { "en": "The timer measures JavaScript work submitting WebGL commands. It excludes GPU completion and model inference. Animation cadence also depends on browser scheduling and the display.", "ja": "タイマーは WebGL コマンドを要求する JavaScript の処理を計測します。GPU の完了時間やモデルの推論時間は含みません。アニメーション周期はブラウザーのスケジュールや表示環境にも左右されます。" },
    { "en": "The record aggregates this page session, including control changes, and retains up to 100 setting snapshots. It is an execution trace, not a hardware benchmark or independent visual verification.", "ja": "記録は入力変更を含むこのページのセッションを集計し、設定履歴を最大 100 件残します。実行の記録であり、ハードウェアのベンチマークや独立した画質検証ではありません。" },
    { "en": "Simulation steps are capped at 0.1 seconds after stalls. Pixel ratio is capped at 2. Browser implementations can produce different images and timings.", "ja": "処理が遅れた後のシミュレーション刻みは 0.1 秒を上限とし、ピクセル比は 2 を上限とします。ブラウザーの実装によって画像や時間は変わります。" }
  ],
  "sourceFiles": ["apps/academy/src/water.js", "apps/academy/content/creative/demos/water.json"],
  "related": { "chapters": ["ocean", "materials"], "themes": ["three-shaders"] },
  "sources": [
    { "id": "webgl-tutorial", "title": "WebGL tutorial", "author": "MDN contributors / Mozilla", "url": "https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial", "verifiedOn": "2026-10-03", "supports": "JavaScript control code, GPU shader code and the canvas rendering context." },
    { "id": "webgl-spec", "title": "WebGL 1.0 specification (editor's draft)", "author": "Khronos Group", "url": "https://registry.khronos.org/webgl/specs/latest/1.0/", "verifiedOn": "2026-10-03", "supports": "Context creation failure and actual drawing-buffer dimensions; draft status retained." },
    { "id": "webgl-practices", "title": "WebGL best practices", "author": "MDN contributors / Mozilla", "url": "https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices", "verifiedOn": "2026-10-03", "supports": "Resource cleanup, back-buffer sizing and avoiding blocking queries during rendering." },
    { "id": "context-loss", "title": "HTMLCanvasElement: webglcontextlost event", "author": "MDN contributors / Mozilla", "url": "https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/webglcontextlost_event", "verifiedOn": "2026-10-03", "supports": "Handling WebGL context loss and browser restoration." }
  ]
}
