Skip to content

Commit

Permalink
Merged PR 85179: Small improvements to shader code for both WebGL1 & …
Browse files Browse the repository at this point in the history
…WebGL2

Modified a couple of uniforms to come in as boolean instead of float and reworked their usage in the shaders for a small reduction in instruction count of the compiled shaders.

Also fixed a bug in output of hlsl fragment shaders for WebGL2.
  • Loading branch information
MarcNeely committed May 6, 2020
1 parent 7ffea27 commit df12496
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@bentley/imodeljs-frontend",
"comment": "small improvements to WebGL1 & WebGL2 performance & fix for output of hlsl shaders for debug",
"type": "none"
}
],
"packageName": "@bentley/imodeljs-frontend",
"email": "[email protected]"
}
2 changes: 1 addition & 1 deletion core/frontend/src/render/webgl/ShaderProgram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ export class ShaderProgram implements WebGLDisposable {

if (haveGLFragColorOnly) {
++ndx;
lines.splice(ndx, 0, " float out_FragColor : SV_TARGET;");
lines.splice(ndx, 0, " float4 out_FragColor : SV_TARGET;");
} else {
for (cNdx = 0; cNdx < haveGLFragColor.length; ++cNdx) {
if (haveGLFragColor[cNdx]) {
Expand Down
8 changes: 4 additions & 4 deletions core/frontend/src/render/webgl/glsl/Fragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ export function addWindowToTexCoords(frag: FragmentShaderBuilder) {

/** @internal */
export function addWhiteOnWhiteReversal(frag: FragmentShaderBuilder) {
frag.addUniform("u_reverseWhiteOnWhite", VariableType.Float, (prog) => {
frag.addUniform("u_reverseWhiteOnWhite", VariableType.Boolean, (prog) => {
prog.addGraphicUniform("u_reverseWhiteOnWhite", (uniform, params) => {
const isWhite = params.target.uniforms.style.isWhiteBackground;
const doReversal = (isWhite && params.geometry.wantWoWReversal(params.programParams)) ? 1.0 : 0.0;
uniform.setUniform1f(doReversal);
const doReversal = (isWhite && params.geometry.wantWoWReversal(params.programParams)) ? 1 : 0;
uniform.setUniform1i(doReversal);
});
});
frag.set(FragmentShaderComponent.ReverseWhiteOnWhite, reverseWhiteOnWhite);
Expand All @@ -54,7 +54,7 @@ const reverseWhiteOnWhite = `
vec3 color = baseColor.rgb;
vec3 delta = (color + epsilon) - white;
vec4 wowColor = vec4(baseColor.rgb * vec3(float(delta.x <= 0.0 || delta.y <= 0.0 || delta.z <= 0.0)), baseColor.a); // set to black if almost white
return mix(baseColor, wowColor, floor(u_reverseWhiteOnWhite + 0.5));
return u_reverseWhiteOnWhite ? wowColor : baseColor;
`;

const multiplyAlpha = `
Expand Down
22 changes: 6 additions & 16 deletions core/frontend/src/render/webgl/glsl/Surface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const applyMaterialColor = `
// Replace with diffuse alpha if alpha overridden.
// Multiply texel alpha with diffuse alpha if specified.
const applyTextureWeight = `
float textureWeight = mat_texture_weight * extractSurfaceBit(kSurfaceBit_HasTexture) * (1.0 - u_applyGlyphTex);
float textureWeight = isSurfaceBitSet(kSurfaceBit_HasTexture) && !u_applyGlyphTex ? mat_texture_weight : 0.0;
vec4 rgba = mix(baseColor, g_surfaceTexel, textureWeight);
rgba.rgb = chooseVec3WithBitFlag(rgba.rgb, v_color.rgb, surfaceFlags, kSurfaceBit_OverrideRgb);
rgba.a = chooseFloatWithBitFlag(rgba.a, v_color.a, surfaceFlags, kSurfaceBit_OverrideAlpha);
Expand Down Expand Up @@ -236,14 +236,6 @@ export function createSurfaceHiliter(instanced: IsInstanced, classified: IsClass
return builder;
}

// nvidia hardware incorrectly interpolates varying floats when we send the same exact value for every vertex...
const extractSurfaceBit = `
float extractSurfaceBit(float flag) { return extractNthBit(surfaceFlags, flag); }
`;
const extractSurfaceBit2 = `
float extractSurfaceBit(uint flag) { return mix(0.0, 1.0, 0u != (surfaceFlags & flag)); }
`;

const isSurfaceBitSet = `
bool isSurfaceBitSet(float flag) { return nthBitSet(surfaceFlags, flag); }
`;
Expand Down Expand Up @@ -286,11 +278,9 @@ function addSurfaceFlagsLookup(builder: ShaderBuilder) {

addExtractNthBit(builder);
if (System.instance.capabilities.isWebGL2) {
builder.addFunction(extractSurfaceBit2);
builder.addFunction(isSurfaceBitSet2);
builder.addGlobal("surfaceFlags", VariableType.Uint);
} else {
builder.addFunction(extractSurfaceBit);
builder.addFunction(isSurfaceBitSet);
builder.addGlobal("surfaceFlags", VariableType.Float);
}
Expand Down Expand Up @@ -419,14 +409,14 @@ const computeBaseColor = `
vec3 delta = (color + epsilon) - white;
// set to black if almost white
glyphColor.rgb *= float(u_reverseWhiteOnWhite <= 0.5 || delta.x <= 0.0 || delta.y <= 0.0 || delta.z <= 0.0);
glyphColor.rgb *= float(!u_reverseWhiteOnWhite || delta.x <= 0.0 || delta.y <= 0.0 || delta.z <= 0.0);
glyphColor = vec4(glyphColor.rgb * g_surfaceTexel.rgb, g_surfaceTexel.a);
// Choose glyph color or unmodified texture sample
vec4 texColor = mix(g_surfaceTexel, glyphColor, u_applyGlyphTex);
vec4 texColor = u_applyGlyphTex ? glyphColor : g_surfaceTexel;
// If untextured, or textureWeight < 1.0, choose surface color.
return mix(surfaceColor, texColor, extractSurfaceBit(kSurfaceBit_HasTexture) * floor(mat_texture_weight));
return isSurfaceBitSet(kSurfaceBit_HasTexture) && mat_texture_weight >= 1.0 ? texColor : surfaceColor;
`;

const surfaceFlagArray = new Int32Array(SurfaceBitIndex.Count);
Expand Down Expand Up @@ -551,10 +541,10 @@ export function createSurfaceBuilder(flags: TechniqueFlags): ProgramBuilder {

addTexture(builder, flags.isAnimated, flags.isThematic);

builder.frag.addUniform("u_applyGlyphTex", VariableType.Float, (prog) => {
builder.frag.addUniform("u_applyGlyphTex", VariableType.Boolean, (prog) => {
prog.addGraphicUniform("u_applyGlyphTex", (uniform, params) => {
const surfGeom = params.geometry.asSurface!;
uniform.setUniform1f(surfGeom.useTexture(params.programParams) && surfGeom.isGlyph ? 1 : 0);
uniform.setUniform1i(surfGeom.useTexture(params.programParams) && surfGeom.isGlyph ? 1 : 0);
});
});

Expand Down

0 comments on commit df12496

Please sign in to comment.