这是indexloc提供的服务,不要输入任何密码
Skip to content

Compiling/validating shaders asynchronously #6

@frzi

Description

@frzi

Many developers will agree that freezing the interface the user interacts with results in a bad user experience. It is for this reason that developers may choose to perform some tasks asynchronously. Currently with WebGL compiling a shader / linking a program can freeze the browser for a short while; depending on the complexity of the shader and the user's hardware. On mobile this is usually way more noticeable.

Some would argue it's up to the developer to perform all shader generating, compiling and program linking at the very start of their web app or game. But there are valid reasons to generate and compile shaders at a later moment. E.g. loading in a new model at a later time (streaming?), or the user changing the game's quality settings during runtime. Or perhaps the app performs computations based on the user's input.

This is why I propose that, whatever function will compile the shader, should be either done forcefully asynchronously, or at least provide the option to do so, to prevent the browser from temporarily freezing. Said function would return a Promise, passing the compiled and validated shader to the resolve function and passing any error messages to the reject function.

Promises are The Future of Async Javascript™ and it only seemed logical to choose Promises over callback functions. With the introduction of async functions (already implemented in some browsers!) I believe Promises have become a more strong and important feature of the Javascript language.

Continuing Apple's example of using the Metal API, a common path to compile a shader (library) may look something like this (ignoring any error handling):

async function createRenderPipelineState() {
    const source = await fetch(/* url */).then(response => response.text())
    const library = await gpu.createLibrary(source)
    const vertexF = library.functionWithName('vertex_main')
    const fragmentF = library.functionWithName('fragment_main')
    /** etc **/
    return gpu.createRenderPipelineState(pipelineDescriptor);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions