ShaderMate: First Fragment Shader

A fast, practical way to start writing GLSL fragment shaders with ShaderMate using the Codevre browser IDE. You’ll be coding online in a clean browser code editor: write your first mainImage, understand UVs, wire up essential uniforms (with explicit GLSL declarations), and build a clean procedural pattern you can iterate on. Great for creative coding, generative art, and WebGL shader prototyping.

ShaderMate 16 min Codevre browser IDE

What you’ll build

You’ll build a ShaderMate “sketch” that renders a crisp, remixable procedural pattern. You’ll learn: UV coordinates, core ShaderMate uniforms, and a clean layering approach (base + pattern + accent) that you can iterate on quickly.

This guide is optimized for the Codevre browser IDE: prototype shaders in a browser code editor, iterate instantly, and share a link so others can run/remix your ShaderMate sketch while coding online.

Project structure

A ShaderMate sketch is intentionally small and readable. In the Codevre browser IDE, open:

  • /index.html — canvas + loads ShaderMate + your sketch script
  • /style.css — fullscreen canvas styling
  • /sketch.js — defines passes and typed uniforms
  • /frag.glsl (or /sketch.glsl) — your fragment shader code

Important ShaderMate detail: declare the uniforms you use in GLSL (for example uniform vec3 iResolution;, uniform float iTime;, etc.). And when you add custom uniforms in sketch.js, ShaderMate expects a typed uniform object like { type: '1f', value: 0.35 }.

Step 1 — Load ShaderMate (CDN) in index.html

Your HTML needs a canvas (ShaderMate defaults to glcanvas) and the ShaderMate script must load before your sketch script.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>ShaderMate Sketch</title>
  <link rel="stylesheet" href="style.css" />
</head>
<body>
  <canvas id="glcanvas"></canvas>

  <script src="https://cdn.jsdelivr.net/gh/Tezumie/ShaderMate@main/src/shaderMate.js"></script>
  <script src="sketch.js"></script>
</body>
</html>

Step 2 — Fullscreen canvas in style.css

html,
body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: #000;
}

canvas {
  display: block;
  width: 100%;
  height: 100%;
}

Step 3 — Start ShaderMate with a pass + typed uniforms

ShaderMate can start from a single shader path, but most templates use an explicit pass object. This is also how you attach channels and typed uniforms.

// sketch.js
document.addEventListener('DOMContentLoaded', () => {
  const passes = [
    {
      name: 'Sketch',
      src: 'frag.glsl',
      screen: true,
      size: 'screen',
      channels: [null, null, null, null],
      uniforms: {
        // typed uniforms: { type, value }
        uDebug: { type: '1i', value: 0 },

        uZoom: { type: '1f', value: 1.6 },
        uInk:  { type: '3f', value: [0.55, 0.65, 1.0] },

        // pattern knobs (easy iteration)
        uGridDensity: { type: '1f', value: 10.0 },
        uStripeAmp:   { type: '1f', value: 0.55 }
      }
    }
  ];

  ShaderMate.startShaderMate(passes);
});

ShaderMate updates built-in uniforms like iResolution, iTime, and iMouse automatically. For your own uniforms, use the typed format (type + value) in sketch.js and declare them in GLSL with matching names and types.

Step 4 — First fragment shader with explicit uniforms

Start simple: UV gradient + time pulse. The key point is declaring the uniforms you use.

// frag.glsl

// ===== Built-in uniforms (declare what you use)
uniform vec3  iResolution;
uniform float iTime;

// ===== Custom uniforms (from sketch.js)
uniform float uZoom;
uniform vec3  uInk;

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
  vec2 uv = fragCoord.xy / iResolution.xy;

  float pulse = 0.5 + 0.5 * sin(iTime);
  vec3 col = vec3(uv, pulse);

  col = mix(col, uInk, 0.25);
  fragColor = vec4(col, 1.0);
}

Understand UVs: normalize, center, and aspect-correct

Normalize pixels into UVs (0..1), then convert to a centered coordinate system (-1..1) and correct aspect ratio. This makes procedural patterns scale cleanly across screen sizes.

vec2 uv = fragCoord.xy / iResolution.xy; // 0..1
vec2 p  = uv * 2.0 - 1.0;                // -1..1 centered
p.x *= iResolution.x / iResolution.y;    // aspect correction

p *= uZoom;                               // custom zoom knob

Uniforms: built-ins vs your custom controls

ShaderMate gives you ShaderToy-style built-ins automatically (you just declare what you use):

  • uniform vec3 iResolution; — canvas size (width, height, 0)
  • uniform float iTime; — seconds since start
  • uniform vec4 iMouse; — mouse data (position/click)
  • uniform int iFrame; — current frame index

And you can add custom uniforms per pass in sketch.js, using typed uniforms: uZoom: { type: '1f', value: 1.6 }. Then declare uniform float uZoom; in GLSL.

Build a clean procedural pattern you can iterate on

This pattern is intentionally layered and tweakable: a soft base, animated stripes, and a subtle grid overlay. It also uses iMouse for an interactive control and custom uniforms for easy iteration.

// frag.glsl

// ===== Built-in uniforms (declare what you use)
uniform vec3  iResolution;
uniform float iTime;
uniform vec4  iMouse;

// ===== Custom uniforms (from sketch.js typed uniforms)
uniform int   uDebug;
uniform float uZoom;
uniform vec3  uInk;
uniform float uGridDensity;
uniform float uStripeAmp;

// small stable hash for grain
float hash21(vec2 p) {
  p = fract(p * vec2(123.34, 345.45));
  p += dot(p, p + 34.345);
  return fract(p.x * p.y);
}

float smoothStripe(float x, float freq, float w) {
  float s = sin(x * freq);
  return smoothstep(-w, w, s);
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
  vec2 uv = fragCoord.xy / iResolution.xy;
  vec2 p  = uv * 2.0 - 1.0;
  p.x *= iResolution.x / iResolution.y;
  p *= uZoom;

  // Mouse X -> stripe frequency
  float mx = iMouse.x / max(iResolution.x, 1.0);
  float freq = mix(6.0, 24.0, clamp(mx, 0.0, 1.0));

  // 1) base: smooth radial falloff
  float r = length(p);
  float base = exp(-2.0 * r * r);

  // 2) stripes: animated + directional
  float t = iTime * 0.85;
  float stripe = smoothStripe(p.x + p.y * 0.35 + t, freq, 0.18) * uStripeAmp;

  // 3) grid overlay (UV stable)
  vec2 g = abs(fract(uv * uGridDensity) - 0.5);
  float grid = smoothstep(0.48, 0.50, max(g.x, g.y));

  // 4) subtle grain
  float grain = (hash21(fragCoord.xy) - 0.5) * 0.035;

  // palette
  vec3 colA = vec3(0.06, 0.09, 0.18);
  vec3 colB = uInk;
  vec3 colC = vec3(1.00, 0.55, 0.25);

  vec3 col = mix(colA, colB, base);
  col = mix(col, colC, stripe);
  col += grid * 0.08;
  col += grain;

  // debug view: show UVs
  if (uDebug == 1) {
    col = vec3(uv, 0.0);
  }

  fragColor = vec4(col, 1.0);
}

Iteration strategy: keep “knobs” as uniforms. When you like a direction, duplicate the project and tweak the uniform defaults. This is perfect for building a personal shader study library in a browser IDE.

Quick edits (make it yours)

Toggle debug mode (show UVs)

Flip uDebug to 1 in sketch.js:

uDebug: { type: '1i', value: 1 }

Change the main ink color

uInk: { type: '3f', value: [0.95, 0.45, 0.85] }

Share your ShaderMate sketch

  • Share the Codevre project link so others can run/remix the shader in a browser editor
  • Screenshot / screen-record for sharing visuals
  • Duplicate the project for variations (change uniforms + palette)

FAQ: ShaderMate uniforms and setup

Do I need to declare ShaderMate uniforms in GLSL?

Yes—declare the uniforms you use (for example uniform vec3 iResolution;, uniform float iTime;, uniform vec4 iMouse;). ShaderMate supplies their values automatically each frame.

How do custom uniforms work in ShaderMate?

Add them per pass in sketch.js using typed uniforms like { type: '1f', value: 0.35 }, then declare matching GLSL uniforms (example: uniform float uZoom;).

Why use mainImage instead of main()?

ShaderMate supports a ShaderToy-like workflow by wrapping mainImage into the WebGL fragment entry point, so you can focus on shader logic with fragCoord and familiar uniforms.

Next steps

Next, try multi-pass rendering (buffer → screen), add feedback with a ping-pong pass, or sample textures using iChannel0. ShaderMate stays fast in a Codevre browser IDE when your shaders stay modular, readable, and easy to remix.

ShaderMate fragment shader GLSL typed uniforms iResolution iTime iMouse UV coordinates procedural patterns WebGL browser IDE browser code editor coding online Codevre

Ready to write your first shader?

Open the ShaderMate template in the Codevre browser IDE and start remixing your fragment shader sketch.