Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GREASED_LINE_USE_OFFSETS - WebGPU fix for Safari/Firefox #16053

Merged
merged 8 commits into from
Jan 10, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { GreasedLineMaterialDefaults } from "./greasedLineMaterialDefaults";
import { GreasedLineTools } from "../../Misc/greasedLineTools";
import { GetCustomCode as getCustomCodeGLSL } from "./greasedLinePluginMaterialShadersGLSL";
import { GetCustomCode as getCustomCodeWGSL } from "./greasedLinePluginMaterialShadersWGSL";
import type { GreasedLineBaseMesh } from "../../Meshes";

/**
* @internal
Expand Down Expand Up @@ -50,6 +51,12 @@ export class MaterialGreasedLineDefines extends MaterialDefines {
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
GREASED_LINE_CAMERA_FACING = true;

/**
* True if the line uses offsets
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
GREASED_LINE_USE_OFFSETS = false;
}

/**
Expand Down Expand Up @@ -327,14 +334,15 @@ export class GreasedLinePluginMaterial extends MaterialPluginBase implements IGr
* Prepare the defines
* @param defines
* @param _scene
* @param _mesh
* @param mesh
*/
override prepareDefines(defines: MaterialGreasedLineDefines, _scene: Scene, _mesh: AbstractMesh) {
override prepareDefines(defines: MaterialGreasedLineDefines, _scene: Scene, mesh: AbstractMesh) {
defines.GREASED_LINE_HAS_COLOR = !!this.color && !this.useColors;
defines.GREASED_LINE_SIZE_ATTENUATION = this._sizeAttenuation;
defines.GREASED_LINE_COLOR_DISTRIBUTION_TYPE_LINE = this._colorsDistributionType === GreasedLineMeshColorDistributionType.COLOR_DISTRIBUTION_TYPE_LINE;
defines.GREASED_LINE_RIGHT_HANDED_COORDINATE_SYSTEM = _scene.useRightHandedSystem;
defines.GREASED_LINE_CAMERA_FACING = this._cameraFacing;
defines.GREASED_LINE_USE_OFFSETS = !!(mesh as GreasedLineBaseMesh).offsets;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ export function GetCustomCode(shaderType: string, cameraFacing: boolean): Nullab
const obj: any = {
CUSTOM_VERTEX_DEFINITIONS: `
attribute grl_widths: f32;
attribute grl_offsets: vec3f;
attribute grl_colorPointers: f32;
varying grlCounters: f32;
varying grlColorPointer: f32;

#ifdef GREASED_LINE_USE_OFFSETS
attribute grl_offsets: vec3f;
#endif

#ifdef GREASED_LINE_CAMERA_FACING
attribute grl_previousAndSide : vec4f;
attribute grl_nextAndCounters : vec4f;
Expand All @@ -35,11 +38,16 @@ export function GetCustomCode(shaderType: string, cameraFacing: boolean): Nullab

`,
CUSTOM_VERTEX_UPDATE_POSITION: `
#ifdef GREASED_LINE_CAMERA_FACING
#ifdef GREASED_LINE_USE_OFFSETS
var grlPositionOffset: vec3f = input.grl_offsets;
#else
var grlPositionOffset = vec3f(0.);
#endif

#ifdef GREASED_LINE_CAMERA_FACING
positionUpdated += grlPositionOffset;
#else
positionUpdated = (positionUpdated + input.grl_offsets) + (input.grl_slopes * input.grl_widths);
positionUpdated = (positionUpdated + grlPositionOffset) + (input.grl_slopes * input.grl_widths);
#endif
`,
CUSTOM_VERTEX_MAIN_END: `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { GreasedLineMeshColorDistributionType, GreasedLineMeshColorMode } from "
import { GreasedLineTools } from "../../Misc/greasedLineTools";
import { GreasedLineMaterialDefaults } from "./greasedLineMaterialDefaults";

export const GreasedLineUseOffsetsSimpleMaterialDefine = "GREASED_LINE_USE_OFFSETS";

/**
* GreasedLineSimpleMaterial
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Buffer } from "../../Buffers/buffer";
import type { Vector3 } from "../../Maths/math.vector";
import { VertexData } from "../mesh.vertexData";
import { DeepCopier } from "../../Misc/deepCopier";
import { GreasedLineSimpleMaterial } from "../../Materials/GreasedLine/greasedLineSimpleMaterial";
import { GreasedLineSimpleMaterial, GreasedLineUseOffsetsSimpleMaterialDefine } from "../../Materials/GreasedLine/greasedLineSimpleMaterial";
import type { AbstractEngine } from "../../Engines/abstractEngine";
import type { FloatArray, IndicesArray } from "../../types";
import { GreasedLineTools } from "../../Misc/greasedLineTools";
Expand Down Expand Up @@ -221,7 +221,6 @@ export abstract class GreasedLineBaseMesh extends Mesh {
this._updateColorPointers();
}
this._createVertexBuffers(this._options.ribbonOptions?.smoothShading);
this._createOffsetsBuffer(this._offsets || []);
!this.doNotSyncBoundingInfo && this.refreshBoundingInfo();

this.greasedLineMaterial?.updateLazy();
Expand Down Expand Up @@ -287,6 +286,9 @@ export abstract class GreasedLineBaseMesh extends Mesh {
* @param offsets offset table [x,y,z, x,y,z, ....]
*/
set offsets(offsets: number[]) {
if (this.material instanceof GreasedLineSimpleMaterial) {
this.material.setDefine(GreasedLineUseOffsetsSimpleMaterialDefine, offsets?.length > 0);
}
this._offsets = offsets;
if (!this._offsetsBuffer) {
this._createOffsetsBuffer(offsets);
Expand Down
28 changes: 20 additions & 8 deletions packages/dev/core/src/ShadersWGSL/greasedLine.fragment.fx
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,18 @@ fn main(input: FragmentInputs) -> FragmentOutputs {
let grlColorMode: f32 = uniforms.grl_colorModeAndColorDistributionType.x;
let grlColorDistributionType: f32 = uniforms.grl_colorModeAndColorDistributionType.y;

fragmentOutputs.color = vec4(uniforms.grlColor, 1.);
var outColor = vec4(uniforms.grlColor, 1.);

fragmentOutputs.color.a = step(fragmentInputs.grlCounters, uniforms.grlVisibility);
if (fragmentOutputs.color.a == 0.0) {
outColor.a = step(fragmentInputs.grlCounters, uniforms.grlVisibility);
if (outColor.a == 0.0) {
discard;
}

if (uniforms.grlUseDash == 1.0) {
let dashPosition = (fragmentInputs.grlCounters + uniforms.grlDashOffset) % uniforms.grlDashArray;
fragmentOutputs.color.a *= ceil(dashPosition - (uniforms.grlDashArray * uniforms.grlDashRatio));
outColor.a *= ceil(dashPosition - (uniforms.grlDashArray * uniforms.grlDashRatio));

if (fragmentOutputs.color.a == 0.0) {
if (outColor.a == 0.0) {
discard;
}
}
Expand All @@ -49,13 +49,25 @@ fn main(input: FragmentInputs) -> FragmentOutputs {
#endif

if (grlColorMode == COLOR_MODE_SET) {
fragmentOutputs.color = grlColor;
outColor = grlColor;
} else if (grlColorMode == COLOR_MODE_ADD) {
fragmentOutputs.color += grlColor;
outColor += grlColor;
} else if (grlColorMode == COLOR_MODE_MULTIPLY) {
fragmentOutputs.color *= grlColor;
outColor *= grlColor;
}
}

#if !defined(PREPASS) && !defined(ORDER_INDEPENDENT_TRANSPARENCY)
fragmentOutputs.color = outColor;
#endif

#if ORDER_INDEPENDENT_TRANSPARENCY
if (fragDepth == nearestDepth) {
fragmentOutputs.frontColor = vec4f(fragmentOutputs.frontColor.rgb + outColor.rgb * outColor.a * alphaMultiplier, 1.0 - alphaMultiplier * (1.0 - outColor.a));
} else {
fragmentOutputs.backColor += outColor;
}
#endif

#define CUSTOM_FRAGMENT_MAIN_END
}
10 changes: 8 additions & 2 deletions packages/dev/core/src/ShadersWGSL/greasedLine.vertex.fx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
#include<meshUboDeclaration>

attribute grl_widths: f32;
attribute grl_offsets: vec3f;
#ifdef GREASED_LINE_USE_OFFSETS
attribute grl_offsets: vec3f;
#endif
attribute grl_colorPointers: f32;
attribute position: vec3f;

Expand Down Expand Up @@ -48,7 +50,11 @@ fn main(input : VertexInputs) -> FragmentInputs {
let grlNext: vec3f = input.grl_nextAndCounters.xyz;
vertexOutputs.grlCounters = input.grl_nextAndCounters.w;

let grlPositionOffset: vec3f = input.grl_offsets;
#ifdef GREASED_LINE_USE_OFFSETS
var grlPositionOffset: vec3f = input.grl_offsets;
#else
var grlPositionOffset = vec3f(0.);
#endif
let grlFinalPosition: vec4f = grlMatrix * vec4f(vertexInputs.position + grlPositionOffset , 1.0);
let grlPrevPos: vec4f = grlMatrix * vec4f(grlPrevious + grlPositionOffset, 1.0);
let grlNextPos: vec4f = grlMatrix * vec4f(grlNext + grlPositionOffset, 1.0);
Expand Down