Skip to content

@carrot/engine-shaders ​

ts

Shader data model and XML parser - describes GLSL shaders as pure data objects without any WebGL compilation.

Installation ​

bash
npm install @carrot/engine-shaders

Architecture / How It Works ​

This package is the data layer for shaders. It describes what a shader is (source code, uniforms, includes) but never touches WebGL. The renderer compiles ShaderSource objects into GPU programs separately.

ShaderSource ​

The core data class. Holds:

  • id - unique key (e.g. core.sprite.default)
  • version - GLSL version string (e.g. 300 es)
  • precision - precision qualifier (e.g. mediump float)
  • vertexRaw / fragmentRaw - raw GLSL source for vertex and fragment stages
  • includes - list of other shader IDs to include (resolved by the registry)
  • uniforms - array of ShaderUniform metadata

renderVertex() and renderFragment() prepend the #version and precision headers to produce final compilable source.

ShaderFile ​

Parses the Carrot .shader XML format into a ShaderSource. The XML format defines shader ID, version, precision, includes, uniforms, and vertex/fragment blocks in one file.

ShaderUniform ​

Metadata for a single uniform - name, GLSL type, and optional default value string. The fromXml() factory constructs from parsed XML attributes. toString() produces a valid GLSL uniform declaration.

ShaderUniformType ​

Covers the standard GLSL uniform types: float, int, bool, vec2/3/4, mat3/4, sampler2D, samplerCube.

Dependencies ​

PackageUsed For
@carrot/ioparseXml() for parsing .shader XML files

Build ​

bash
npm run build   # runs tsc

Usage Guide ​

Shader data model and XML parser - describe and load GLSL shaders as pure data objects.

Import ​

ts
import { ShaderSource, ShaderFile, ShaderUniform, ShaderUniformType } from '@carrot/engine-shaders';

Common Patterns ​

1. Loading a shader from XML ​

ts
const xml = await fetch('/shaders/sprite.shader').then(r => r.text());
const file = new ShaderFile(xml);

console.log(file.id);        // 'core.sprite.default'
console.log(file.uniforms);  // [ShaderUniform, ...]

2. Getting compilable GLSL source ​

ts
const vertSrc = file.renderVertex();
// Produces:
// #version 300 es
// precision mediump float;
//
// ... vertex GLSL ...

const fragSrc = file.renderFragment();

3. Building a ShaderSource programmatically ​

ts
const source = new ShaderSource(
  'game.water.surface',
  '300 es',
  'mediump float',
  vertexGlsl,
  fragmentGlsl,
  ['core.common', 'core.lighting'],
  [
    new ShaderUniform('u_Time', ShaderUniformType.Float),
    new ShaderUniform('u_WaveScale', ShaderUniformType.Float, '1.0'),
    new ShaderUniform('u_MainTexture', ShaderUniformType.Sampler2D),
  ],
);

4. Inspecting uniforms ​

ts
for (const u of source.uniforms) {
  console.log(u.name, u.type, u.defaultValue);
}

// Quick lookup
const timeUniform = source.getUniform('u_Time');

// Name set for fast checks
if (source.uniformNames.has('u_MainTexture')) {
  // bind texture...
}

5. Shader XML format ​

xml
<Shader id="core.sprite.default" version="300 es" precision="mediump float">
  <Include link="core.common" />
  <Uniform name="u_MainTexture" type="sampler2D" />
  <Uniform name="u_TintColor" type="vec4" default="1.0 1.0 1.0 1.0" />
  <Vertex>
    in vec3 a_Position;
    in vec2 a_TexCoord;
    out vec2 v_TexCoord;
    uniform mat4 u_MVP;

    void main() {
      v_TexCoord = a_TexCoord;
      gl_Position = u_MVP * vec4(a_Position, 1.0);
    }
  </Vertex>
  <Fragment>
    in vec2 v_TexCoord;
    out vec4 fragColor;
    uniform sampler2D u_MainTexture;
    uniform vec4 u_TintColor;

    void main() {
      fragColor = texture(u_MainTexture, v_TexCoord) * u_TintColor;
    }
  </Fragment>
</Shader>

6. Generating GLSL uniform declarations ​

ts
const u = new ShaderUniform('u_Color', ShaderUniformType.Vec4, '1.0 0.0 0.0 1.0');
console.log(u.toString());
// "uniform vec4 u_Color = 1.0 0.0 0.0 1.0;"

Carrot