Pixscape is currently in public pre-release.

The runtime and documentation are already usable, but some APIs, workflows, and editor behavior may still evolve before a stable 1.0 release.

Shaders API

Apply Studio-authored shaders and float parameters to sprite entities.

Shaders are applied to sprite entities through their shader facade. Shader control is part of Pixscape’s sprite rendering model, but it has its own documentation because shaders are an important game-development feature.

There is no separate api.shaders() service in Runtime 0.2.1. Find an entity or spawn a sprite, then use its shader() facade:

EntityRef player = api.entities().requireTag("player");

player.shader()
        .use("damage-flash")
        .setFloat("u_strength", 1f);

Author and register shaders in the Studio Shader Manager. use(...) accepts a registered shader name; an unknown or blank name throws IllegalArgumentException without changing the previous shader.

Control a shader on a sprite entity

shader().exists() reports whether the entity has the render-material capability required for shader control. It does not mean that a custom shader is already selected.

Use shader() to select or clear the shader, and to manage the float values that the active shader interprets:

ShaderFacade shader = player.shader();

shader.use("water")
        .setFloat("u_time", elapsedSeconds)
        .setFloat("u_strength", 0.5f);

float strength = shader.getFloat("u_strength", 0f);
boolean hasStrength = shader.hasFloat("u_strength");

shader.removeFloat("u_strength");
shader.clearFloats();
shader.clear();

Runtime 0.2.1 supports float uniform values through this facade. It does not provide gameplay-time shader compilation, arbitrary file loading, or vector, matrix, texture, or generic uniform APIs.

Code examples

Flash a sprite when it takes damage

Convert application damage into a visual intensity for a shader authored in Studio.

void onPlayerDamaged(EntityRef player, int damage, int maxHealth) {
    if (!player.shader().exists()) {
        return;
    }

    // Application gameplay owns health and damage calculation.
    playerHealth.applyDamage(damage);

    // Convert gameplay damage into a normalized shader parameter.
    float strength = maxHealth > 0
            ? Math.min(1f, damage / (float) maxHealth)
            : 1f;

    // damage-flash and u_strength are authored shader data.
    player.shader()
            .use("damage-flash")
            .setFloat("u_strength", strength);
}

Animate a shader parameter over time

Use application time to drive a parameter interpreted by a Studio-authored water shader.

void updateWater(EntityRef water, float elapsedSeconds) {
    if (!water.shader().exists()) {
        return;
    }

    // The shader interprets this application-controlled float uniform.
    water.shader()
            .use("water")
            .setFloat("u_time", elapsedSeconds);
}