assemblyscript icon indicating copy to clipboard operation
assemblyscript copied to clipboard

Proposal: Ability to compile to WebGL / WebGPU Shader

Open Awendel opened this issue 1 year ago • 5 comments

One of the most popular libraries for GPGPU in the javascript eco-system is:

https://github.com/gpujs/gpu.js/

It works by taking a javascript function and compiles it to a WGSL shader at runtime.

It does so quite well, despite javascript not having any types.

Typescript of course would be a better foundation for compiling into shader format, but AssemblyScript would be even better, since it is even more refined in terms of types and constraints.

Hence one could leverage the existing infrastructure to offer compile targets into WebGL shader and WebGPU shader formats.

Compiling could be done statically via cli utilities etc.

One would just have to include type definitions that match the types available in the respective shader environments. For Math library stuff, I believe gpu.js should serve as a great foundation for translating calls etc.

I believe this proposal would increase the target group for this library substantially, since it targets web developers who are familiar with typescript etc, but don't want to use static languages directly, hence it seems like an organic extension of its founding principles.

Awendel avatar Sep 02 '22 12:09 Awendel

Automatic compilation to GPU or even automatic multi-threading is a very complex thing. GPU.js uses classic GPGPU tricks. But if we're talking about Compute Shaders for WebGPU for example, you need to execute scatter/gather commands intelligently, use non-blocking or atomic ops, properly dispatch thread groups etc. There are quite a few languages and DSLs that do this. For example Halide. This is a rather vast and complex area. Given that we have a very small team, I wouldn't go into that just yet. The best we can do now is to translate AS into WGSL source code for functions with @wgsl decorators. Something like this:

@wgsl.fragment("main")
function simpleShader(): @wgsl.loc(0, "res") f32x4 {
   return f32x4(0.0, 1.0, 0.0, 1.0);
}

which will transpile to:

[[location(0)]] var<out> res : vec4<f32>;
      
[[stage(fragment)]]
fn main() -> void {
  res = vec4<f32>(0.0, 1.0, 0.0, 1.0);
  return;
}

MaxGraey avatar Sep 02 '22 12:09 MaxGraey

I agree that it's a very complicated task if one was to aim for supporting all the different ways a shader could be used.

The example with the decorator is a great way to start though.

One could begin just doing it very modular, so really just translations of simple functions or structs etc and then to see how far one can take it. Kind of a "hybrid" development approach, where some straightforward function could be written in assemblyScript and then one "stitches together" the outputs together for the final shader.

Another thing that wouldn't be too hard, would be to take care of all the "boiler plate" code needed for basic shaders.

E.g. how vertex / fragment shader always have a main function that returns vec4 etc.

Awendel avatar Sep 02 '22 13:09 Awendel

One could begin just doing it very modular

AssemblyScript already supports transforms which allows adding hooks between different compiler's stage. For example, get access to AST. It's already using a lot for DSL like approaches. So you can already start to experiment.

The only thing missing so far are specific v128 types such as f32x4, i64x2 and so on. At this moment there is only generalized v128 type which requires explicit operation call like:

const a: v128 = f32x4(0, 0, 0, 1);
const b: v128 = f32x4(1, 0, 0, 0);
const c = f32x4.add(a, b);

instead:

const a: f32x4 = f32x4(0, 0, 0, 1);
const b: f32x4 = f32x4(1, 0, 0, 0);
const c = a + b;

MaxGraey avatar Sep 02 '22 15:09 MaxGraey

Thanks for the nudge, seems like a great way to get started and run some experiments.

I guess it's up to you as the maintainers to decide whether additional output targets would make sense at some point as part of the AssemblyScript core library, or whether it's best if someone else starts a seperate project, explicitly targetting web shaders and perhaps using AssemblyScript as a dependency / backend for the translation logic.

If the latter is the case, feel free to close the issue.

Awendel avatar Sep 03 '22 08:09 Awendel

I think having built-in tools for translation in WGSL from some DSL (or limited set of AS language) is consistent with our main goal of being Web-cetric. Tighter integration with WebGPU definitely makes sense. It's just not a priority right now.

MaxGraey avatar Sep 03 '22 09:09 MaxGraey

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in one week if no further activity occurs. Thank you for your contributions!

github-actions[bot] avatar Oct 03 '22 23:10 github-actions[bot]