A new Sky simulation Web demo (#9828)
* sky simulation sample Also added documentation on how to add another web sample --------- Co-authored-by: Powei Feng <powei@google.com>
@@ -49,7 +49,7 @@ def copy_assets():
|
||||
It preserves the relative directory structure per sample so that each sample's
|
||||
assets are isolated.
|
||||
"""
|
||||
exts = ['.filamat', '.filamesh', '.ktx', '.ktx2', '.png', '.jpg', '.bin', '.glb', '.gltf', '.hdr', '.css']
|
||||
exts = ['.filamat', '.filamesh', '.ktx', '.ktx2', '.png', '.jpg', '.bin', '.glb', '.gltf', '.hdr', '.css', '.js']
|
||||
for root, dirs, files in os.walk(OUT_DIR):
|
||||
for f in files:
|
||||
if any(f.endswith(ext) for ext in exts):
|
||||
@@ -66,9 +66,9 @@ def fix_paths():
|
||||
files (which assume assets are alongside them) need to be patched to point to the correct
|
||||
relative paths based on their nesting depth.
|
||||
"""
|
||||
files_to_fix = glob.glob(f"{BOOK_DIR}/samples/web/*.html") + glob.glob(f"{BOOK_DIR}/remote/*.html")
|
||||
files_to_fix = glob.glob(f"{BOOK_DIR}/samples/web/*.html") + glob.glob(f"{BOOK_DIR}/remote/*.html") + glob.glob(f"{BOOK_DIR}/web/*.html")
|
||||
|
||||
exts = "filamat|filamesh|ktx|ktx2|png|jpg|bin|glb|gltf|hdr|css"
|
||||
exts = "filamat|filamesh|ktx|ktx2|png|jpg|bin|glb|gltf|hdr|css|js"
|
||||
asset_pattern = r'([\'"`])((?:\.\.\/)?(?:[\w\-\/]+\.)(?:' + exts + r'))\1'
|
||||
|
||||
for f in files_to_fix:
|
||||
@@ -95,6 +95,8 @@ def fix_paths():
|
||||
def asset_repl(m):
|
||||
quote = m.group(1)
|
||||
path = m.group(2)
|
||||
if "lib/" in path:
|
||||
return m.group(0)
|
||||
if path.startswith("../"):
|
||||
return f"{quote}{depth_prefix}assets/{path[3:]}{quote}"
|
||||
else:
|
||||
@@ -116,6 +118,8 @@ def fix_paths():
|
||||
|
||||
text = re.sub(r'(\w+(?:\.\w+)*)\.loadResources\(([^)]*)\);', fix_load_resources, text)
|
||||
|
||||
text = text.replace('window.FILAMENT_ASSET_DIR = "";', f'window.FILAMENT_ASSET_DIR = "{depth_prefix}assets/{sample_name}/";')
|
||||
|
||||
with open(f, 'w') as file:
|
||||
file.write(text)
|
||||
|
||||
|
||||
@@ -130,6 +130,15 @@
|
||||
"out/cmake-webgl-release/web/examples/examples/skinning/skinning.html": {
|
||||
"dest": "samples/web/skinning.md"
|
||||
},
|
||||
"out/cmake-webgl-release/web/examples/examples/sky/sky.html": {
|
||||
"dest": "samples/web/sky.md",
|
||||
"replacements": {
|
||||
"<!-- mdbook: add fullscreen mode -->": "<a href=\"../../web/sky.html\">Full screen</a>"
|
||||
}
|
||||
},
|
||||
"./out/cmake-webgl-release/web/examples/examples/sky/sky.html": {
|
||||
"dest": "web/sky.html"
|
||||
},
|
||||
"out/cmake-webgl-release/web/examples/examples/remote/remote.html": {
|
||||
"dest": "remote/index.html"
|
||||
}
|
||||
|
||||
@@ -88,6 +88,10 @@ def pull_duplicates():
|
||||
if body_match:
|
||||
content = style_str + body_match.group(1)
|
||||
|
||||
replacements = config[fin].get('replacements', {})
|
||||
for old, new in replacements.items():
|
||||
content = content.replace(old, new)
|
||||
|
||||
with open(new_fpath, 'w') as out_file:
|
||||
for line in content.splitlines(True):
|
||||
out_file.write(transform_dup_file_link(line, link_transforms))
|
||||
|
||||
@@ -71,7 +71,7 @@ def snapshot_samples():
|
||||
|
||||
driver = webdriver.Chrome(options=chrome_options)
|
||||
|
||||
samples = ['animation', 'cube_fl0', 'helmet', 'morphing', 'parquet', 'skinning', 'triangle', 'redball', 'suzanne']
|
||||
samples = ['animation', 'cube_fl0', 'helmet', 'morphing', 'parquet', 'skinning', 'sky', 'triangle', 'redball', 'suzanne']
|
||||
|
||||
for sample in samples:
|
||||
print(f"Taking snapshot of {sample}...")
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
- [morphing](./samples/web/morphing.md)
|
||||
- [parquet](./samples/web/parquet.md)
|
||||
- [skinning](./samples/web/skinning.md)
|
||||
- [sky](./samples/web/sky.md)
|
||||
- [Technical Notes](./notes/README.md)
|
||||
- [Material Properties](./notes/material_properties.md)
|
||||
- [Release](./release/README.md)
|
||||
|
||||
BIN
docs_src/src_mdbook/src/images/web_sample_sky.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
@@ -62,4 +62,8 @@ Here are some additional standalone examples demonstrating Filament's capabiliti
|
||||
<img src="../../images/web_sample_skinning.png" alt="skinning" />
|
||||
<span>skinning</span>
|
||||
</a>
|
||||
<a href="sky.md" class="sample-card">
|
||||
<img src="../../images/web_sample_sky.png" alt="sky" />
|
||||
<span>sky</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
# Building Skybox Assets
|
||||
|
||||
This directory contains the source code for the Simulated Skybox sample. The assets (material and textures) are pre-built in the `assets/` directory.
|
||||
|
||||
If you need to modify the material or regenerate the moon textures, you can use the scripts provided in the `tools/` directory.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Filament**: You must have a built version of Filament. The scripts assume a standard CMake build output structure (e.g., `out/cmake-release`).
|
||||
- **Python 3**: Required for texture generation.
|
||||
- **Python Dependencies**: `numpy`, `Pillow` (automatically installed if missing, via pip).
|
||||
|
||||
## Rebuilding the Material
|
||||
|
||||
If you modify `simulated_skybox.mat`, you must recompile it into a `.filamat` file.
|
||||
|
||||
```bash
|
||||
# Run from the sample root or tools directory
|
||||
./tools/build_material.sh
|
||||
```
|
||||
|
||||
This will update `assets/simulated_skybox.filamat`.
|
||||
|
||||
## Regenerating Moon Textures
|
||||
|
||||
If you want to change the moon's resolution, bump scale, or blur, you can regenerate the textures.
|
||||
|
||||
```bash
|
||||
# Run from the sample root or tools directory
|
||||
./tools/generate_moon_assets.sh [size]
|
||||
```
|
||||
|
||||
Example:
|
||||
```bash
|
||||
./tools/generate_moon_assets.sh 512
|
||||
```
|
||||
|
||||
This will download raw NASA data (if not present) and generate:
|
||||
- `assets/moon_disk.png`
|
||||
- `assets/moon_normal.png`
|
||||
28
docs_src/src_raw/wip/sky/gl-matrix-min.js
vendored
@@ -1,9 +0,0 @@
|
||||
body {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
canvas {
|
||||
touch-action: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
@@ -61,3 +61,36 @@ The custom `serve.py` script in the `web/examples/` directory performs the follo
|
||||
- Automatically detects the built files in the `out/` directory.
|
||||
- Generates a main entry `index.html` listing all the available samples and tutorials.
|
||||
- Handles server-side rendering of `.md` tutorial files into HTML using an embedded template.
|
||||
|
||||
## Porting a Web Sample to Official Docs (`docs_src`)
|
||||
|
||||
If you want your web sample or tutorial to appear on the official Filament documentation website via
|
||||
`mdbook`, follow these steps:
|
||||
|
||||
1. **Map the Built HTML:**
|
||||
Add your generated `.html` or `.md` file to the mapping in `docs_src/build/duplicates.json`. This
|
||||
tells the documentation build script to copy your sample into the `mdbook` structure.
|
||||
```json
|
||||
"out/cmake-webgl-release/web/examples/examples/your_sample/your_sample.html": {
|
||||
"dest": "samples/web/your_sample.md"
|
||||
}
|
||||
```
|
||||
|
||||
2. **Add to the Navigation Menu:**
|
||||
Link your sample in the table of contents by adding it to `docs_src/src_mdbook/src/SUMMARY.md`
|
||||
under the "Web Tutorials" or "Web Samples" section.
|
||||
|
||||
3. **Generate a Thumbnail Image:**
|
||||
Add your sample's name to the `samples` array in `docs_src/build/snapshot_samples.py`. Then,
|
||||
manually run this script (`python3 snapshot_samples.py`). It will launch a headless browser,
|
||||
wait for your scene to render, and snap a 100x100 preview image.
|
||||
|
||||
4. **Dynamic Asset Loading (Optional):**
|
||||
When `mdbook` serves your sample, the assets (`.filamat`, textures) are segregated into a
|
||||
`web/assets/` directory.
|
||||
- For `<script src="...">` or `<img src="...">` tags embedded in the HTML, the paths will be
|
||||
automatically rewritten by `docs_src/build/copy_web_docs.py`.
|
||||
- However, if you load files dynamically within your JavaScript code (e.g., using `fetch()`), you
|
||||
**must** prepend `(window.FILAMENT_ASSET_DIR || '')` to the file URL.
|
||||
- If you need `window.FILAMENT_ASSET_DIR` to be properly populated, make sure to add logic to
|
||||
`docs_src/build/copy_web_docs.py` to inject the proper path prefix for your sample.
|
||||
|
||||
@@ -194,4 +194,15 @@ add_envmap("third_party/environments/lightroom_14b.hdr" "default_env" ${TARGET_D
|
||||
set(TARGET_DIR "remote")
|
||||
add_localfile("remote.html" "remote.html" ${TARGET_DIR} ALL_DEMO_ASSETS)
|
||||
|
||||
set(TARGET_DIR "sky")
|
||||
add_localfile("sky.html" "sky.html" ${TARGET_DIR} ALL_DEMO_ASSETS)
|
||||
build_material("materials/simulated_skybox.mat" ${TARGET_DIR} "simulated_skybox" ALL_DEMO_ASSETS)
|
||||
add_localfile("sky/lil-gui.js" "lil-gui.js" ${TARGET_DIR} ALL_DEMO_ASSETS)
|
||||
add_localfile("sky/suncalc_global.js" "suncalc_global.js" ${TARGET_DIR} ALL_DEMO_ASSETS)
|
||||
add_localfile("sky/main.js" "main.js" ${TARGET_DIR} ALL_DEMO_ASSETS)
|
||||
add_localfile("sky/SimulatedSkybox.js" "SimulatedSkybox.js" ${TARGET_DIR} ALL_DEMO_ASSETS)
|
||||
add_localfile("textures/sky/moon_disk.png" "moon_disk.png" ${TARGET_DIR} ALL_DEMO_ASSETS)
|
||||
add_localfile("textures/sky/moon_normal.png" "moon_normal.png" ${TARGET_DIR} ALL_DEMO_ASSETS)
|
||||
add_localfile("textures/sky/milkyway.png" "milkyway.png" ${TARGET_DIR} ALL_DEMO_ASSETS)
|
||||
|
||||
add_custom_target(${PROJECT_NAME} ALL DEPENDS ${ALL_DEMO_ASSETS})
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<title>Analytic Skybox</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1">
|
||||
<link href="styles.css" rel="stylesheet">
|
||||
<link href="../main.css" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
@@ -23,22 +23,24 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<canvas></canvas>
|
||||
|
||||
<div style="display:flex;flex-direction:column;align-items:center">
|
||||
<canvas></canvas>
|
||||
<!-- mdbook: add fullscreen mode -->
|
||||
</div>
|
||||
<!-- Filament -->
|
||||
<script src="filament.js"></script>
|
||||
<script src="gl-matrix-min.js"></script>
|
||||
<script src="../filament.js"></script>
|
||||
<script src="../gl-matrix-min.js"></script>
|
||||
|
||||
<!-- UI -->
|
||||
<script src="lil-gui.js"></script>
|
||||
|
||||
<!-- Utils -->
|
||||
<script src="assets/suncalc_global.js"></script>
|
||||
<script src="suncalc_global.js"></script>
|
||||
|
||||
<!-- App -->
|
||||
|
||||
<script src="SimulatedSkybox.js?v=9999"></script>
|
||||
<script src="main.js?v=9999"></script>
|
||||
<script>window.FILAMENT_ASSET_DIR = "";</script>
|
||||
<script src="SimulatedSkybox.js"></script>
|
||||
<script src="main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
@@ -66,7 +66,7 @@ class SimulatedSkybox {
|
||||
|
||||
// Load Moon Texture
|
||||
try {
|
||||
const texUrl = 'assets/moon_disk.png';
|
||||
const texUrl = (window.FILAMENT_ASSET_DIR || '') + 'moon_disk.png';
|
||||
const Texture = Filament.Texture;
|
||||
const TextureSampler = Filament.TextureSampler;
|
||||
const PixelDataFormat = Filament.PixelDataFormat;
|
||||
@@ -125,7 +125,7 @@ class SimulatedSkybox {
|
||||
|
||||
// Load Moon Normal
|
||||
try {
|
||||
const texUrl = 'assets/moon_normal.png';
|
||||
const texUrl = (window.FILAMENT_ASSET_DIR || '') + 'moon_normal.png';
|
||||
const Texture = Filament.Texture;
|
||||
const TextureSampler = Filament.TextureSampler;
|
||||
const PixelDataFormat = Filament.PixelDataFormat;
|
||||
@@ -182,7 +182,7 @@ class SimulatedSkybox {
|
||||
|
||||
// Load Milky Way Texture
|
||||
try {
|
||||
const texUrl = 'assets/milkyway.png';
|
||||
const texUrl = (window.FILAMENT_ASSET_DIR || '') + 'milkyway.png';
|
||||
const Texture = Filament.Texture;
|
||||
const TextureSampler = Filament.TextureSampler;
|
||||
const PixelDataFormat = Filament.PixelDataFormat;
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// main.js
|
||||
|
||||
Filament.init(['assets/simulated_skybox.filamat?v=' + Date.now()], () => {
|
||||
Filament.init([(window.FILAMENT_ASSET_DIR || '') + 'simulated_skybox.filamat?v=' + Date.now()], () => {
|
||||
window.app = new App(document.getElementsByTagName('canvas')[0]);
|
||||
});
|
||||
|
||||
@@ -130,7 +130,7 @@ class App {
|
||||
|
||||
// Load the material explicitly. SimulatedSkybox.loadMaterial fetches it.
|
||||
|
||||
const matUrl = 'assets/simulated_skybox.filamat?v=' + Date.now();
|
||||
const matUrl = (window.FILAMENT_ASSET_DIR || '') + 'simulated_skybox.filamat?v=' + Date.now();
|
||||
this.skybox.loadMaterial(matUrl).then(() => {
|
||||
this.initGUI();
|
||||
});
|
||||
@@ -3,8 +3,8 @@ set -e
|
||||
|
||||
# Default size
|
||||
SIZE=${1:-256}
|
||||
OUTPUT_COLOR="../assets/moon_disk.png"
|
||||
OUTPUT_NORMAL="../assets/moon_normal.png"
|
||||
OUTPUT_COLOR="../../textures/sky/moon_disk.png"
|
||||
OUTPUT_NORMAL="../../textures/sky/moon_normal.png"
|
||||
|
||||
# Navigate to script directory
|
||||
cd "$(dirname "$0")"
|
||||
|
Before Width: | Height: | Size: 447 KiB After Width: | Height: | Size: 447 KiB |
|
Before Width: | Height: | Size: 596 KiB After Width: | Height: | Size: 596 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 119 KiB |