diff --git a/packages/dev/core/src/Rendering/boundingBoxRenderer.ts b/packages/dev/core/src/Rendering/boundingBoxRenderer.ts index 00b2da12c19..a093a6d5fce 100644 --- a/packages/dev/core/src/Rendering/boundingBoxRenderer.ts +++ b/packages/dev/core/src/Rendering/boundingBoxRenderer.ts @@ -138,11 +138,11 @@ export class BoundingBoxRenderer implements ISceneComponent { */ public enabled = true; - /** Shader language used by the material */ + /** Shader language used by the renderer */ protected _shaderLanguage = ShaderLanguage.GLSL; /** - * Gets the shader language used in this material. + * Gets the shader language used in this renderer. */ public get shaderLanguage(): ShaderLanguage { return this._shaderLanguage; diff --git a/packages/dev/core/src/Rendering/edgesRenderer.ts b/packages/dev/core/src/Rendering/edgesRenderer.ts index 92772fda608..40ecac2f3bb 100644 --- a/packages/dev/core/src/Rendering/edgesRenderer.ts +++ b/packages/dev/core/src/Rendering/edgesRenderer.ts @@ -14,11 +14,10 @@ import { Camera } from "../Cameras/camera"; import { Constants } from "../Engines/constants"; import type { Node } from "../node"; -import "../Shaders/line.fragment"; -import "../Shaders/line.vertex"; import type { DataBuffer } from "../Buffers/dataBuffer"; import { SmartArray } from "../Misc/smartArray"; import { DrawWrapper } from "../Materials/drawWrapper"; +import { ShaderLanguage } from "core/Materials/shaderLanguage"; declare module "../scene" { export interface Scene { @@ -245,7 +244,7 @@ export class EdgesRenderer implements IEdgesRenderer { */ public customInstances = new SmartArray(32); - private static _GetShader(scene: Scene): ShaderMaterial { + private static _GetShader(scene: Scene, shaderLanguage: ShaderLanguage): ShaderMaterial { if (!scene._edgeRenderLineShader) { const shader = new ShaderMaterial( "lineShader", @@ -255,6 +254,14 @@ export class EdgesRenderer implements IEdgesRenderer { attributes: ["position", "normal"], uniforms: ["world", "viewProjection", "color", "width", "aspectRatio"], uniformBuffers: ["Scene", "Mesh"], + shaderLanguage: shaderLanguage, + extraInitializationsAsync: async () => { + if (shaderLanguage === ShaderLanguage.WGSL) { + await Promise.all([import("../ShadersWGSL/line.vertex"), import("../ShadersWGSL/line.fragment")]); + } else { + await Promise.all([import("../Shaders/line.vertex"), import("../Shaders/line.fragment")]); + } + }, }, false ); @@ -269,6 +276,16 @@ export class EdgesRenderer implements IEdgesRenderer { return scene._edgeRenderLineShader; } + /** Shader language used*/ + protected _shaderLanguage = ShaderLanguage.GLSL; + + /** + * Gets the shader language used. + */ + public get shaderLanguage(): ShaderLanguage { + return this._shaderLanguage; + } + /** * Creates an instance of the EdgesRenderer. It is primarily use to display edges of a mesh. * Beware when you use this class with complex objects as the adjacencies computation can be really long @@ -284,8 +301,10 @@ export class EdgesRenderer implements IEdgesRenderer { this._options = options ?? null; this._epsilon = epsilon; - if (this._source.getScene().getEngine().isWebGPU) { - this._drawWrapper = new DrawWrapper(source.getEngine()); + const engine = this._source.getScene().getEngine(); + if (engine.isWebGPU) { + this._drawWrapper = new DrawWrapper(engine); + this._shaderLanguage = ShaderLanguage.WGSL; } this._prepareRessources(); @@ -311,7 +330,7 @@ export class EdgesRenderer implements IEdgesRenderer { return; } - this._lineShader = EdgesRenderer._GetShader(this._source.getScene()); + this._lineShader = EdgesRenderer._GetShader(this._source.getScene(), this._shaderLanguage); } /** @internal */ diff --git a/packages/dev/core/src/Rendering/index.ts b/packages/dev/core/src/Rendering/index.ts index 55bc6d74a21..5d650b6f876 100644 --- a/packages/dev/core/src/Rendering/index.ts +++ b/packages/dev/core/src/Rendering/index.ts @@ -31,7 +31,13 @@ export * from "../ShadersWGSL/geometry.fragment"; export * from "../ShadersWGSL/geometry.vertex"; // Bounding Box Renderer -import "../Shaders/boundingBoxRenderer.fragment"; -import "../Shaders/boundingBoxRenderer.vertex"; -import "../ShadersWGSL/boundingBoxRenderer.fragment"; -import "../ShadersWGSL/boundingBoxRenderer.vertex"; +export * from "../Shaders/boundingBoxRenderer.fragment"; +export * from "../Shaders/boundingBoxRenderer.vertex"; +export * from "../ShadersWGSL/boundingBoxRenderer.fragment"; +export * from "../ShadersWGSL/boundingBoxRenderer.vertex"; + +// Edges Renderer +export * from "../Shaders/line.fragment"; +export * from "../Shaders/line.vertex"; +export * from "../ShadersWGSL/line.fragment"; +export * from "../ShadersWGSL/line.vertex"; diff --git a/packages/dev/core/src/ShadersWGSL/line.fragment.fx b/packages/dev/core/src/ShadersWGSL/line.fragment.fx new file mode 100644 index 00000000000..511738bb326 --- /dev/null +++ b/packages/dev/core/src/ShadersWGSL/line.fragment.fx @@ -0,0 +1,20 @@ +#include + +uniform color: vec4f; + +#include + +#define CUSTOM_FRAGMENT_DEFINITIONS + +@fragment +fn main(input: FragmentInputs) -> FragmentOutputs { + +#define CUSTOM_FRAGMENT_MAIN_BEGIN + + #include + + #include + fragmentOutputs.color = uniforms.color; + +#define CUSTOM_FRAGMENT_MAIN_END +} \ No newline at end of file diff --git a/packages/dev/core/src/ShadersWGSL/line.vertex.fx b/packages/dev/core/src/ShadersWGSL/line.vertex.fx new file mode 100644 index 00000000000..f3a3d08e719 --- /dev/null +++ b/packages/dev/core/src/ShadersWGSL/line.vertex.fx @@ -0,0 +1,58 @@ +// Uniforms +#define ADDITIONAL_VERTEX_DECLARATION + +#include + +#include + +#include +#include + +// Attributes +attribute position: vec3f; +attribute normal: vec4f; + +uniform width: f32; +uniform aspectRatio: f32; + +#include + +#define CUSTOM_VERTEX_DEFINITIONS + +@vertex +fn main(input : VertexInputs) -> FragmentInputs { + +#define CUSTOM_VERTEX_MAIN_BEGIN + + #include + + var worldViewProjection: mat4x4f = scene.viewProjection * finalWorld; + + var viewPosition: vec4f = worldViewProjection * vec4f(input.position, 1.0); + var viewPositionNext: vec4f = worldViewProjection * vec4f(input.normal.xyz, 1.0); + + var currentScreen: vec2f = viewPosition.xy / viewPosition.w; + var nextScreen: vec2f = viewPositionNext.xy / viewPositionNext.w; + + currentScreen = vec2f(currentScreen.x * uniforms.aspectRatio, currentScreen.y); + nextScreen = vec2f(nextScreen.x * uniforms.aspectRatio, nextScreen.y); + + var dir: vec2f = normalize(nextScreen - currentScreen); + var normalDir: vec2f = vec2f(-dir.y, dir.x); + + normalDir *= uniforms.width / 2.0; + normalDir = vec2f(normalDir.x / uniforms.aspectRatio, normalDir.y); + + var offset: vec4f = vec4f(normalDir * input.normal.w, 0.0, 0.0); + vertexOutputs.position = viewPosition + offset; + +#if defined(CLIPPLANE) || defined(CLIPPLANE2) || defined(CLIPPLANE3) || defined(CLIPPLANE4) || defined(CLIPPLANE5) || defined(CLIPPLANE6) + var worldPos: vec4f = finalWorld * vec4f(input.position, 1.0); + #include +#endif + + #include + +#define CUSTOM_VERTEX_MAIN_END + +} \ No newline at end of file