diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml
new file mode 100644
index 0000000..8e25d9e
--- /dev/null
+++ b/.github/workflows/build-and-deploy.yml
@@ -0,0 +1,34 @@
+name: Build and Deploy web
+
+on: [push]
+
+jobs:
+ build:
+ runs-on: macos-14
+ name: MacOS -> Emscripten, Release
+
+ steps:
+ - name: Clone DiligentGraphics.github.io repository
+ uses: actions/checkout@v3
+ with:
+ submodules: recursive
+
+ - name: Set up build environment
+ if: success()
+ uses: DiligentGraphics/github-action/setup-build-env@v1
+ with:
+ platform: Emscripten
+
+ - name: Build artifacts
+ if: success()
+ working-directory: ${{github.workspace}}
+ run: |
+ python ./build_artifacts.py
+
+ - name: Upload artifacts
+ if: success()
+ uses: actions/upload-artifact@v3
+ with:
+ path: |
+ ${{github.workspace}}/BuildArtefacts
+ retention-days: 90
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5327163
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+CMakeFiles
+*.cmake
+https_server.py
diff --git a/build_artifacts.py b/build_artifacts.py
new file mode 100644
index 0000000..74ad4dc
--- /dev/null
+++ b/build_artifacts.py
@@ -0,0 +1,71 @@
+import os
+import subprocess
+import shutil
+
+DILIGENT_ENGINE_URL = 'https://github.com/DiligentGraphics/DiligentEngine.git'
+SOURCE_IMAGES = 'images'
+SOURCE_TEMPLATE = 'template'
+SOURCE_BUILD = 'DiligentEngine/build/Emscripten/DiligentSamples'
+DESTINATION_DIR = 'BuildArtefacts'
+BUILD_TARGETS = [
+ "Tutorial01_HelloTriangle"
+]
+
+def clone_repository(repository_url):
+ try:
+ command = ["git", "clone", "--recursive", "--depth", "1", repository_url]
+ subprocess.run(command, check=True)
+ except subprocess.CalledProcessError as e:
+ print(f"An error occurred while cloning the repository: {e}")
+ except Exception as e:
+ print(f"An unexpected error occurred: {e}")
+
+def configure_project():
+ try:
+ command = ["emcmake", "cmake", "-S", "./DiligentEngine", "-B", "./DiligentEngine/build/Emscripten", "-DCMAKE_BUILD_TYPE=Release", "-DDILIGENT_NO_WEBGPU=ON"]
+ subprocess.run(command, check=True)
+ except subprocess.CalledProcessError as e:
+ print(f"An error occurred while configuring the project: {e}")
+ except Exception as e:
+ print(f"An unexpected error occurred: {e}")
+
+def build_project():
+ try:
+ command = ["cmake", "--build", "./DiligentEngine/build/Emscripten", "--target", "Tutorial01_HelloTriangle"]
+ subprocess.run(command, check=True)
+ except subprocess.CalledProcessError as e:
+ print(f"An error occurred while building the project: {e}")
+ except Exception as e:
+ print(f"An unexpected error occurred: {e}")
+
+def upload_artefacts():
+ if not os.path.exists(DESTINATION_DIR):
+ os.makedirs(DESTINATION_DIR)
+
+ shutil.copytree(SOURCE_IMAGES, os.path.join(DESTINATION_DIR, 'images'), dirs_exist_ok=True)
+ for item in os.listdir(SOURCE_TEMPLATE):
+ source_item = os.path.join(SOURCE_TEMPLATE, item)
+ destination_item = os.path.join(DESTINATION_DIR, item) # Corrected the destination path
+
+ if os.path.isdir(source_item):
+ shutil.copytree(source_item, destination_item, dirs_exist_ok=True)
+ else:
+ shutil.copy2(source_item, destination_item)
+
+ for folder in BUILD_TARGETS:
+ source_folder_path_tutorials = os.path.join(SOURCE_BUILD, "Tutorials", folder)
+ source_folder_path_samples = os.path.join(SOURCE_BUILD, "Samples", folder)
+ destination_folder_path = os.path.join(DESTINATION_DIR, "wasm-modules", folder)
+
+ if os.path.exists(source_folder_path_tutorials):
+ shutil.copytree(source_folder_path_tutorials, destination_folder_path, dirs_exist_ok=True)
+ elif os.path.exists(source_folder_path_samples):
+ shutil.copytree(source_folder_path_samples, destination_folder_path, dirs_exist_ok=True)
+ else:
+ print(f"Folder '{folder}' not found.")
+
+if __name__ == '__main__':
+ clone_repository(DILIGENT_ENGINE_URL)
+ configure_project()
+ build_project()
+ upload_artefacts()
diff --git a/images/content/samples/Atmosphere.gif b/images/content/samples/Atmosphere.gif
new file mode 100644
index 0000000..32521ae
Binary files /dev/null and b/images/content/samples/Atmosphere.gif differ
diff --git a/images/content/samples/GLTFViewer.jpg b/images/content/samples/GLTFViewer.jpg
new file mode 100644
index 0000000..e394b36
Binary files /dev/null and b/images/content/samples/GLTFViewer.jpg differ
diff --git a/images/content/samples/ImguiDemo.png b/images/content/samples/ImguiDemo.png
new file mode 100644
index 0000000..af2d937
Binary files /dev/null and b/images/content/samples/ImguiDemo.png differ
diff --git a/images/content/samples/Shadows.jpg b/images/content/samples/Shadows.jpg
new file mode 100644
index 0000000..6ffbbb1
Binary files /dev/null and b/images/content/samples/Shadows.jpg differ
diff --git a/images/content/search-bar/search-icon.png b/images/content/search-bar/search-icon.png
new file mode 100644
index 0000000..a4ec6c3
Binary files /dev/null and b/images/content/search-bar/search-icon.png differ
diff --git a/images/content/tutorials/Tutorial01_HelloTriangle.png b/images/content/tutorials/Tutorial01_HelloTriangle.png
new file mode 100644
index 0000000..d6233fc
Binary files /dev/null and b/images/content/tutorials/Tutorial01_HelloTriangle.png differ
diff --git a/images/content/tutorials/Tutorial02_Cube.gif b/images/content/tutorials/Tutorial02_Cube.gif
new file mode 100644
index 0000000..6421028
Binary files /dev/null and b/images/content/tutorials/Tutorial02_Cube.gif differ
diff --git a/images/content/tutorials/Tutorial03_Texturing.gif b/images/content/tutorials/Tutorial03_Texturing.gif
new file mode 100644
index 0000000..392cd76
Binary files /dev/null and b/images/content/tutorials/Tutorial03_Texturing.gif differ
diff --git a/images/content/tutorials/Tutorial04_Instancing.gif b/images/content/tutorials/Tutorial04_Instancing.gif
new file mode 100644
index 0000000..e31f344
Binary files /dev/null and b/images/content/tutorials/Tutorial04_Instancing.gif differ
diff --git a/images/content/tutorials/Tutorial05_TextureArray.gif b/images/content/tutorials/Tutorial05_TextureArray.gif
new file mode 100644
index 0000000..ed53054
Binary files /dev/null and b/images/content/tutorials/Tutorial05_TextureArray.gif differ
diff --git a/images/content/tutorials/Tutorial06_Multithreading.gif b/images/content/tutorials/Tutorial06_Multithreading.gif
new file mode 100644
index 0000000..f9238c1
Binary files /dev/null and b/images/content/tutorials/Tutorial06_Multithreading.gif differ
diff --git a/images/content/tutorials/Tutorial09_Quads.gif b/images/content/tutorials/Tutorial09_Quads.gif
new file mode 100644
index 0000000..594796b
Binary files /dev/null and b/images/content/tutorials/Tutorial09_Quads.gif differ
diff --git a/images/content/tutorials/Tutorial10_DataStreaming.gif b/images/content/tutorials/Tutorial10_DataStreaming.gif
new file mode 100644
index 0000000..2ad01f2
Binary files /dev/null and b/images/content/tutorials/Tutorial10_DataStreaming.gif differ
diff --git a/images/content/tutorials/Tutorial11_ResourceUpdates.gif b/images/content/tutorials/Tutorial11_ResourceUpdates.gif
new file mode 100644
index 0000000..b61f11d
Binary files /dev/null and b/images/content/tutorials/Tutorial11_ResourceUpdates.gif differ
diff --git a/images/content/tutorials/Tutorial12_RenderTarget.gif b/images/content/tutorials/Tutorial12_RenderTarget.gif
new file mode 100644
index 0000000..dba0f13
Binary files /dev/null and b/images/content/tutorials/Tutorial12_RenderTarget.gif differ
diff --git a/images/content/tutorials/Tutorial13_ShadowMap.gif b/images/content/tutorials/Tutorial13_ShadowMap.gif
new file mode 100644
index 0000000..258634a
Binary files /dev/null and b/images/content/tutorials/Tutorial13_ShadowMap.gif differ
diff --git a/images/content/tutorials/Tutorial14_ComputeShader.gif b/images/content/tutorials/Tutorial14_ComputeShader.gif
new file mode 100644
index 0000000..c0967ca
Binary files /dev/null and b/images/content/tutorials/Tutorial14_ComputeShader.gif differ
diff --git a/images/content/tutorials/Tutorial16_BindlessResources.gif b/images/content/tutorials/Tutorial16_BindlessResources.gif
new file mode 100644
index 0000000..1818ec8
Binary files /dev/null and b/images/content/tutorials/Tutorial16_BindlessResources.gif differ
diff --git a/images/content/tutorials/Tutorial17_MSAA.gif b/images/content/tutorials/Tutorial17_MSAA.gif
new file mode 100644
index 0000000..40d6053
Binary files /dev/null and b/images/content/tutorials/Tutorial17_MSAA.gif differ
diff --git a/images/content/tutorials/Tutorial18_Queries.gif b/images/content/tutorials/Tutorial18_Queries.gif
new file mode 100644
index 0000000..708854b
Binary files /dev/null and b/images/content/tutorials/Tutorial18_Queries.gif differ
diff --git a/images/content/tutorials/Tutorial19_RenderPasses.gif b/images/content/tutorials/Tutorial19_RenderPasses.gif
new file mode 100644
index 0000000..4e9d1d2
Binary files /dev/null and b/images/content/tutorials/Tutorial19_RenderPasses.gif differ
diff --git a/images/content/tutorials/Tutorial25_StatePackager.jpg b/images/content/tutorials/Tutorial25_StatePackager.jpg
new file mode 100644
index 0000000..fee79ec
Binary files /dev/null and b/images/content/tutorials/Tutorial25_StatePackager.jpg differ
diff --git a/images/content/tutorials/Tutorial26_StateCache.jpg b/images/content/tutorials/Tutorial26_StateCache.jpg
new file mode 100644
index 0000000..6480359
Binary files /dev/null and b/images/content/tutorials/Tutorial26_StateCache.jpg differ
diff --git a/images/content/tutorials/Tutorial27_PostProcessing.jpg b/images/content/tutorials/Tutorial27_PostProcessing.jpg
new file mode 100644
index 0000000..940dee9
Binary files /dev/null and b/images/content/tutorials/Tutorial27_PostProcessing.jpg differ
diff --git a/images/header/diligentgraphics-icon.ico b/images/header/diligentgraphics-icon.ico
new file mode 100644
index 0000000..beb2e09
Binary files /dev/null and b/images/header/diligentgraphics-icon.ico differ
diff --git a/images/header/diligentgraphics-logo.png b/images/header/diligentgraphics-logo.png
new file mode 100644
index 0000000..e2cb9f7
Binary files /dev/null and b/images/header/diligentgraphics-logo.png differ
diff --git a/images/header/github-mark-white.png b/images/header/github-mark-white.png
new file mode 100644
index 0000000..50b8175
Binary files /dev/null and b/images/header/github-mark-white.png differ
diff --git a/index.html b/index.html
deleted file mode 100644
index e902295..0000000
--- a/index.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
- Under Development
-
-
-
- Under Development
-
-
diff --git a/template/enable-threads.js b/template/enable-threads.js
new file mode 100644
index 0000000..70daaca
--- /dev/null
+++ b/template/enable-threads.js
@@ -0,0 +1,76 @@
+// NOTE: This file creates a service worker that cross-origin-isolates the page (read more here: https://web.dev/coop-coep/) which allows us to use wasm threads.
+// Normally you would set the COOP and COEP headers on the server to do this, but Github Pages doesn't allow this, so this is a hack to do that.
+
+/* Edited version of: coi-serviceworker v0.1.6 - Guido Zuidhof, licensed under MIT */
+// From here: https://github.com/gzuidhof/coi-serviceworker
+if(typeof window === 'undefined') {
+ self.addEventListener("install", () => self.skipWaiting());
+ self.addEventListener("activate", e => e.waitUntil(self.clients.claim()));
+
+ async function handleFetch(request) {
+ if(request.cache === "only-if-cached" && request.mode !== "same-origin") {
+ return;
+ }
+
+ if(request.mode === "no-cors") { // We need to set `credentials` to "omit" for no-cors requests, per this comment: https://bugs.chromium.org/p/chromium/issues/detail?id=1309901#c7
+ request = new Request(request.url, {
+ cache: request.cache,
+ credentials: "omit",
+ headers: request.headers,
+ integrity: request.integrity,
+ destination: request.destination,
+ keepalive: request.keepalive,
+ method: request.method,
+ mode: request.mode,
+ redirect: request.redirect,
+ referrer: request.referrer,
+ referrerPolicy: request.referrerPolicy,
+ signal: request.signal,
+ });
+ }
+
+ let r = await fetch(request).catch(e => console.error(e));
+
+ if(r.status === 0) {
+ return r;
+ }
+
+ const headers = new Headers(r.headers);
+ headers.set("Cross-Origin-Embedder-Policy", "credentialless"); // or: require-corp
+ headers.set("Cross-Origin-Opener-Policy", "same-origin");
+
+ return new Response(r.body, { status: r.status, statusText: r.statusText, headers });
+ }
+
+ self.addEventListener("fetch", function(e) {
+ e.respondWith(handleFetch(e.request)); // respondWith must be executed synchonously (but can be passed a Promise)
+ });
+
+ } else {
+ (async function() {
+ if(window.crossOriginIsolated !== false) return;
+
+ let registration = await navigator.serviceWorker.register(window.document.currentScript.src).catch(e => console.error("COOP/COEP Service Worker failed to register:", e));
+ if(registration) {
+ console.log("COOP/COEP Service Worker registered", registration.scope);
+
+ registration.addEventListener("updatefound", () => {
+ console.log("Reloading page to make use of updated COOP/COEP Service Worker.");
+ window.location.reload();
+ });
+
+ // If the registration is active, but it's not controlling the page
+ if(registration.active && !navigator.serviceWorker.controller) {
+ console.log("Reloading page to make use of COOP/COEP Service Worker.");
+ window.location.reload();
+ }
+ }
+ })();
+ }
+
+ // Code to deregister:
+ // let registrations = await navigator.serviceWorker.getRegistrations();
+ // for(let registration of registrations) {
+ // await registration.unregister();
+ // }
+
\ No newline at end of file
diff --git a/template/index.html b/template/index.html
new file mode 100644
index 0000000..85fc7c2
--- /dev/null
+++ b/template/index.html
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+ Diligent Graphics
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Known issues
+
+ - 14 - Compute Shader tutorial doesn't work on WebGL.
+ - 18 - Queries tutorial doesn't work on WebGPU.
+ - 19 - Render Passes tutorial doesn't work on WebGL.
+ - Atmosphere sample doesn't work on WebGL.
+ - Shadows sample has artifacts on WebGL.
+
+
+
+
+
+
+
+
+
+
diff --git a/template/script.js b/template/script.js
new file mode 100644
index 0000000..b3322b2
--- /dev/null
+++ b/template/script.js
@@ -0,0 +1,206 @@
+const tutorials = [
+ {
+ id: "Tutorial01_HelloTriangle",
+ title: "01 - Hello Triangle",
+ description: "This tutorial demonstrates the basics of Diligent Engine API. It shows how to create shaders, pipeline state object and how to render a simple triangle.",
+ image: "images/content/tutorials/Tutorial01_HelloTriangle.png",
+ tutorialLink: "wasm-modules/Tutorial01_HelloTriangle/Tutorial01_HelloTriangle.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial01_HelloTriangle"
+ },
+ {
+ id: "Tutorial02_Cube",
+ title: "02 - Cube",
+ description: "This tutorial demonstrates how to render an actual 3D object, a cube. It shows how to load shaders from files, create and use vertex, index and uniform buffers.",
+ image: "images/content/tutorials/Tutorial02_Cube.gif",
+ tutorialLink: "wasm-modules/Tutorial02_Cube/Tutorial02_Cube.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial02_Cube"
+ },
+ {
+ id: "Tutorial03_Texturing",
+ title: "03 - Texturing",
+ description: "This tutorial demonstrates how to apply a texture to a 3D object. It shows how to load a texture from file, create shader resource binding object and how to sample a texture in the shader.",
+ image: "images/content/tutorials/Tutorial03_Texturing.gif",
+ tutorialLink: "wasm-modules/Tutorial03_Texturing/Tutorial03_Texturing.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial03_Texturing"
+ },
+ {
+ id: "Tutorial04_Instancing",
+ title: "04 - Instancing",
+ description: "This tutorial demonstrates how to use instancing to render multiple copies of one object using unique transformation matrix for every copy.",
+ image: "images/content/tutorials/Tutorial04_Instancing.gif",
+ tutorialLink: "wasm-modules/Tutorial04_Instancing/Tutorial04_Instancing.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial04_Instancing"
+ },
+ {
+ id: "Tutorial05_TextureArray",
+ title: "05 - Texture Array",
+ description: "This tutorial demonstrates how to combine instancing with texture arrays to use unique texture for every instance.",
+ image: "images/content/tutorials/Tutorial05_TextureArray.gif",
+ tutorialLink: "wasm-modules/Tutorial05_TextureArray/Tutorial05_TextureArray.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial05_TextureArray"
+ },
+ {
+ id: "Tutorial06_Multithreading",
+ title: "06 - Multithreading",
+ description: "This tutorial shows how to generate command lists in parallel from multiple threads.",
+ image: "images/content/tutorials/Tutorial06_Multithreading.gif",
+ tutorialLink: "wasm-modules/Tutorial06_Multithreading/Tutorial06_Multithreading.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial06_Multithreading"
+ },
+ {
+ id: "Tutorial09_Quads",
+ title: "09 - Quads",
+ description: "This tutorial shows how to render multiple 2D quads, frequently switching textures and blend modes.",
+ image: "images/content/tutorials/Tutorial09_Quads.gif",
+ tutorialLink: "wasm-modules/Tutorial09_Quads/Tutorial09_Quads.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial09_Quads"
+ },
+ {
+ id: "Tutorial10_DataStreaming",
+ title: "10 - Data Streaming",
+ description: "This tutorial shows dynamic buffer mapping strategy using MAP_FLAG_DISCARD and MAP_FLAG_DO_NOT_SYNCHRONIZE flags to efficiently stream varying amounts of data to GPU.",
+ image: "images/content/tutorials/Tutorial10_DataStreaming.gif",
+ tutorialLink: "wasm-modules/Tutorial10_DataStreaming/Tutorial10_DataStreaming.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial10_DataStreaming"
+ },
+ {
+ id: "Tutorial11_ResourceUpdates",
+ title: "11 - Resource Updates",
+ description: "This tutorial demonstrates different ways to update buffers and textures in Diligent Engine and explains important internal details and performance implications related to each method.",
+ image: "images/content/tutorials/Tutorial11_ResourceUpdates.gif",
+ tutorialLink: "wasm-modules/Tutorial11_ResourceUpdates/Tutorial11_ResourceUpdates.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial11_ResourceUpdates"
+ },
+ {
+ id: "Tutorial12_RenderTarget",
+ title: "12 - Render Target",
+ description: "This tutorial demonstrates how to render a 3d cube into an offscreen render target and do a simple post-processing effect.",
+ image: "images/content/tutorials/Tutorial12_RenderTarget.gif",
+ tutorialLink: "wasm-modules/Tutorial12_RenderTarget/Tutorial12_RenderTarget.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial12_RenderTarget"
+ },
+ {
+ id: "Tutorial13_ShadowMap",
+ title: "13 - Shadow Map",
+ description: "This tutorial demonstrates how to render basic shadows using a shadow map.",
+ image: "images/content/tutorials/Tutorial13_ShadowMap.gif",
+ tutorialLink: "wasm-modules/Tutorial13_ShadowMap/Tutorial13_ShadowMap.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial13_ShadowMap"
+ },
+ {
+ id: "Tutorial14_ComputeShader",
+ title: "14 - Compute Shader",
+ description: "This tutorial shows how to implement a simple particle simulation system using compute shaders.",
+ image: "images/content/tutorials/Tutorial14_ComputeShader.gif",
+ tutorialLink: "wasm-modules/Tutorial14_ComputeShader/Tutorial14_ComputeShader.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial14_ComputeShader"
+ },
+ {
+ id: "Tutorial16_BindlessResources",
+ title: "16 - Bindless Resources",
+ description: "This tutorial shows how to implement bindless resources, a technique that leverages dynamic shader resource indexing feature enabled by the next-gen APIs to significantly improve rendering performance.",
+ image: "images/content/tutorials/Tutorial16_BindlessResources.gif",
+ tutorialLink: "wasm-modules/Tutorial16_BindlessResources/Tutorial16_BindlessResources.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial16_BindlessResources"
+ },
+ {
+ id: "Tutorial17_MSAA",
+ title: "17 - MSAA",
+ description: "This tutorial demonstrates how to use multisample anti-aliasing (MSAA) to make geometrical edges look smoother and more temporarily stable.",
+ image: "images/content/tutorials/Tutorial17_MSAA.gif",
+ tutorialLink: "wasm-modules/Tutorial17_MSAA/Tutorial17_MSAA.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial17_MSAA"
+ },
+ {
+ id: "Tutorial18_Queries",
+ title: "18 - Queries",
+ description: "This tutorial demonstrates how to use queries to retrieve various information about the GPU operation, such as the number of primitives rendered, command processing duration, etc.",
+ image: "images/content/tutorials/Tutorial18_Queries.gif",
+ tutorialLink: "wasm-modules/Tutorial18_Queries/Tutorial18_Queries.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial18_Queries"
+ },
+ {
+ id: "Tutorial19_RenderPasses",
+ title: "19 - Render Passes",
+ description: "This tutorial demonstrates how to use the render passes API to implement simple deferred shading.",
+ image: "images/content/tutorials/Tutorial19_RenderPasses.gif",
+ tutorialLink: "wasm-modules/Tutorial19_RenderPasses/Tutorial19_RenderPasses.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial19_RenderPasses"
+ },
+ {
+ id: "Tutorial27_PostProcessing",
+ title: "27 - Post Processing",
+ description: "This tutorial demonstrates how to use post-processing effects from the DiligentFX module.",
+ image: "images/content/tutorials/Tutorial27_PostProcessing.jpg",
+ tutorialLink: "wasm-modules/Tutorial27_PostProcessing/Tutorial27_PostProcessing.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Tutorials/Tutorial27_PostProcessing"
+ }
+];
+
+const samples = [
+ {
+ id: "Sample_Atmosphere",
+ title: "Atmosphere",
+ description: "This sample demonstrates how to integrate Epipolar Light Scattering post-processing effect into an application to render physically-based atmosphere.",
+ image: "images/content/samples/Atmosphere.gif",
+ tutorialLink: "wasm-modules/Atmosphere/Atmosphere.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Samples/Atmosphere"
+ },
+ {
+ id: "Sample_GLTFViewer",
+ title: "GLTF Viewer",
+ description: "This sample demonstrates how to use the Asset Loader and PBR Renderer to load and render GLTF models.",
+ image: "images/content/samples/GLTFViewer.jpg",
+ tutorialLink: "wasm-modules/GLTFViewer/GLTFViewer.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Samples/GLTFViewer"
+ },
+ {
+ id: "Sample_ImguiDemo",
+ title: "Dear ImGui Demo",
+ description: "This sample demonstrates the integration of the engine with dear imgui UI library.",
+ image: "images/content/samples/ImguiDemo.png",
+ tutorialLink: "wasm-modules/ImguiDemo/ImguiDemo.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Samples/ImguiDemo"
+ },
+ {
+ id: "Sample_Shadows",
+ title: "Shadows",
+ description: "This sample demonstrates how to use the Shadowing component to render high-quality shadows.",
+ image: "images/content/samples/Shadows.jpg",
+ tutorialLink: "wasm-modules/Shadows/Shadows.html",
+ githubLink: "https://github.com/DiligentGraphics/DiligentSamples/tree/master/Samples/Shadows"
+ }
+];
+
+function createCard(item) {
+ return `
+
+
+
${item.title}
+
${item.description}
+
+
+ `;
+}
+
+const tutorialGrid = document.getElementById('tutorialGrid');
+const samplesGrid = document.getElementById('samplesGrid');
+
+tutorials.forEach(tutorial => {
+ tutorialGrid.innerHTML += createCard(tutorial);
+});
+
+samples.forEach(sample => {
+ samplesGrid.innerHTML += createCard(sample);
+});
+
+document.querySelector('.search-bar input').addEventListener('input', function(e) {
+ const query = e.target.value.toLowerCase();
+ document.querySelectorAll('.card').forEach(function(card) {
+ const title = card.querySelector('h3').innerText.toLowerCase();
+ card.style.display = title.includes(query) ? '' : 'none';
+ });
+});
diff --git a/template/styles.css b/template/styles.css
new file mode 100644
index 0000000..47404a4
--- /dev/null
+++ b/template/styles.css
@@ -0,0 +1,275 @@
+body {
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+ margin: 0;
+ background: linear-gradient(177deg, #22223a, #303e3d, #3a3a3a);
+ background-size: 180% 180%;
+ animation: gradient-animation 15s ease infinite;
+ color: #ffffff;
+ padding-top: 80px;
+ padding-right: 20px;
+ background-attachment: fixed;
+}
+
+@keyframes gradient-animation {
+ 0% { background-position: 0% 50%; }
+ 50% { background-position: 100% 50%; }
+ 100% { background-position: 0% 50%; }
+}
+
+header {
+ background-color: rgba(0, 0, 0, 0.5);
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
+ backdrop-filter: blur(10px);
+ -webkit-backdrop-filter: blur(10px);
+ position: fixed;
+ top: 0;
+ width: 100%;
+ z-index: 1000;
+}
+
+.logo {
+ height: 60px;
+ padding-left: 40px;
+ padding-top: 10px;
+ padding-bottom: 10px;
+ transition: transform 0.3s ease, filter 0.3s ease;
+}
+
+.logo:hover {
+ transform: scale(1.1);
+ filter: brightness(1.2);
+}
+
+.github-link img {
+ height: 40px;
+ padding-right: 40px;
+ padding-top: 10px;
+ padding-bottom: 10px;
+ transition: transform 0.3s ease, filter 0.3s ease;
+}
+
+.github-link img:hover {
+ transform: scale(1.1);
+ filter: brightness(1.2);
+}
+
+nav {
+ width: 250px;
+ background-color: rgba(0, 0, 0, 0.4);
+ padding: 10px 20px;
+ border-radius: 8px;
+ margin-right: 20px;
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
+ position: sticky;
+ top: 100px;
+ height: fit-content;
+ max-height: calc(100vh - 40px);
+ overflow-y: auto;
+}
+
+nav h2 {
+ font-size: 18px;
+ margin-bottom: 10px;
+ color: #ffffff;
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
+}
+
+nav ul {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+nav ul li {
+ margin: 2.5px 0;
+}
+
+nav ul li a {
+ color: #ddd;
+ text-decoration: none;
+ font-size: 16px;
+ padding: 6px 10px;
+ display: block;
+ border-radius: 6px;
+ transition: background-color 0.3s ease, color 0.3s ease;
+}
+
+nav ul li a:hover {
+ background-color: #444;
+ color: #ffffff;
+}
+
+.container {
+ display: flex;
+ padding: 20px;
+ padding-bottom: 200px;
+}
+
+.content {
+ flex-grow: 1;
+ margin-left: 20px;
+}
+
+.search-bar {
+ position: relative;
+ margin-bottom: 20px;
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
+ border-radius: 8px;
+ overflow: hidden;
+}
+
+.search-bar input {
+ width: 100%;
+ padding: 12px;
+ padding-left: 40px;
+ font-size: 16px;
+ border: none;
+ background-color: rgba(0, 0, 0, 0.4);
+ color: #ddd;
+ outline: none;
+ transition: background-color 0.3s ease;
+}
+
+.search-bar input:focus {
+ background-color: rgba(0, 0, 0, 0.3);
+ box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
+ color: #fff;
+}
+
+.search-icon {
+ position: absolute;
+ left: 10px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 20px;
+ height: 20px;
+ background-image: url('images/content/search-bar/search-icon.png');
+ background-size: cover;
+ pointer-events: none;
+ opacity: 0.5;
+ transition: opacity 0.3s ease;
+}
+
+.search-bar input:focus + .search-icon {
+ opacity: 1;
+}
+
+.grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
+ gap: 18px;
+}
+
+.card {
+ background-color: rgba(255, 255, 255, 0.15);
+ padding: 15px;
+ border-radius: 10px;
+ text-align: center;
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
+ transition: transform 0.3s, box-shadow 0.3s;
+ backdrop-filter: blur(10px);
+ -webkit-backdrop-filter: blur(10px);
+ position: relative;
+ overflow: hidden;
+ height: 100%;
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+}
+
+.card:hover {
+ transform: scale(1.05);
+ box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
+}
+
+.card img {
+ width: 100%;
+ height: auto;
+ border-radius: 8px;
+ margin-bottom: 10px;
+}
+
+.card h3 {
+ margin: 10px 0;
+ font-size: 18px;
+}
+
+.card p {
+ font-size: 14px;
+ color: #bbb;
+ margin-bottom: auto;
+}
+
+.buttons-container {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ width: 100%;
+ box-sizing: border-box;
+ padding-top: 15px;
+}
+
+.github-button, .view-link {
+ display: inline-block;
+ padding: 8px 12px;
+ border-radius: 5px;
+ background-color: #2c3e50;
+ color: #ecf0f1;
+ text-decoration: none;
+ font-size: 14px;
+ transition: background-color 0.3s ease;
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
+ width: 100%;
+ box-sizing: border-box;
+ text-align: center;
+}
+
+.github-button:hover, .view-link:hover {
+ background-color: #1abc9c;
+ color: #ffffff;
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
+}
+
+#known-issues {
+ margin-top: 40px;
+ padding: 30px;
+ background-color: rgba(0, 0, 0, 0.4);
+ border-radius: 8px;
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
+}
+
+#known-issues h2 {
+ margin-bottom: 15px;
+ color: #ffffff;
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
+}
+
+#known-issues ul {
+ list-style-type: disc;
+ padding-left: 35px;
+ color: #ddd;
+}
+
+#known-issues ul li {
+ margin-bottom: 10px;
+}
+
+@media (max-width: 768px) {
+ .container {
+ flex-direction: column;
+ }
+
+ nav {
+ width: 100%;
+ margin-right: 0;
+ margin-bottom: 20px;
+ }
+
+ .grid {
+ grid-template-columns: 1fr;
+ }
+}