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

Provide aliases for patchES300 #10

Open
vorg opened this issue Jan 24, 2024 · 4 comments
Open

Provide aliases for patchES300 #10

vorg opened this issue Jan 24, 2024 · 4 comments

Comments

@vorg
Copy link
Member

vorg commented Jan 24, 2024

Current approach is verbose and error prone

ctx.pipeline({
   vert: parser.patchES300("..."),
   frag: parser.patchES300("...", "fragment")
})

The alternative approach is much more readable

ctx.pipeline({
   vert: parser.patchVert("..."),
   frag: parser.patchFrag("...")
})

Downsides:

  • assumes glsl (could be wglsl one day)
  • function name doesn't imply that it is for webgl2/ES300

But for comparision i don't think this is better

ctx.pipeline({
   vert: parser.patchVertES300("..."),
   frag: parser.patchFragES300("...")
})

Maybe it should be the parser that is typed?

import { parser } from "pex-shaders";

to

import { es3000Parser as parser } from "pex-shaders";

then you could switch language by switching import (in my dreams..)

@vorg
Copy link
Member Author

vorg commented Jan 24, 2024

One could as why do we even have to bother and why pex-context is not auto-upgrading it for us?

@vorg
Copy link
Member Author

vorg commented Jan 24, 2024

Another option build a online tool when we can upgrade our code by copy paste and stop using parser.

What do you think @dmnsgn

@dmnsgn
Copy link
Member

dmnsgn commented Jan 29, 2024

I think parser.patchES300 is purposely verbose as it should be a relic from the past by now and we are willing to remove it entirely.

The current solution (as of Jan 2024) is:

  • provide a shader written in GLSL 1.00 (WebGL 1 only) with output.vert/frag chunks that allows the shader to be used seamlessly with GLSL version 3 (WebGL2)
    const vert = /* glsl */ `
    #if (__VERSION__ >= 300)
    #define attribute in
    #define varying out
    ${texture}
    #endif
    `;
  • use parser.build(ctx, src, defines = [], extensions = {}) to add #version, defines and extension

That works beautifully in pex-renderer v4 alpha and has the following pros:

  • one source of truth, write shader once
  • familiarity of attribute/varying
  • no string replace except adding defines/extension in parser.build (which means greater performance improvement when diffing shader code): what you write is what you get
  • MRT (WebGL2 multiple color attachments) made easy with define (again perf improvement by reducing GPU memory pressure)
    #if LOCATION_NORMAL >= 0
    outNormal = FragData[LOCATION_NORMAL];
    #endif
  • easy to see what code is there for #if (VERSION >= 300) and check new
    // EXT_frag_depth
    #define gl_FragDepthEXT gl_FragDepth
    // EXT_shader_texture_lod
    #define texture2DLodEXT textureLod
    #define texture2DProjLodEXT textureProjLod
    #define textureCubeLodEXT textureLod
    #define texture2DGradEXT textureGrad
    #define texture2DProjGradEXT textureProjGrad
    #define textureCubeGradEXT textureGrad

And cons:

  • written in "old school" language (although so many more snippets out there are written in 1 and not 3), not all features (3d textures, transform feedback etc.)
  • shaders code slightly bigger (although we use template strings so not a biggy)
  • WGSL doesn't support #define (at least last time I checked)

That's for current status.

We reached the conclusion that –now that Safari caught up– WebGL 2 has enough worldwide support so we should entirely drop WebGL1. In a soonish future that means:

  • ditching all the tricks above (parser output chunks, VERSION checks...)
  • rewrite shaders to use in/out instead of attribute/varying and only use that syntax
  • rely on non WebGL fallback if any device still doesn't support WebGL2
  • enjoy

PS: I still don't see any obvious GLSL -> WGSL bridge without DSL extracting shader variables and providing different body like I did in dgel:

https://github.com/dmnsgn/dgel/blob/b3a213d636a3327eb80a89a93344a4f852c25db2/examples/cube.js#L159-L194

@vorg
Copy link
Member Author

vorg commented Jan 29, 2024

Ok. I missed that defines SOTA. It kind of brings back the question of Shift from framework to library #9 as those defines are in final shaders that could be in pex-renderer instead of here.

Re. glsl/wgsl we could got further into thi.ng/umbrella and copy ThreeJS approach with DSL in JS/TS. https://github.com/thi-ng/umbrella/tree/develop/packages/shader-ast. There is no WGSL front end yet, only glsl.

const sinc = (x: FloatTerm, k: FloatTerm) =>
    div(sin(mul(x,k)), mul(x, k));

Not sure how does it feel to write whole PBR shader in this though... Seems like 6 months project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants