Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
openaec-foundation avatar

Threejs Syntax Shaders

  • 18 installs
  • 11 repo stars
  • Updated July 8, 2026
  • openaec-foundation/three.js-claude-skill-package

Helps with ai & agent building tasks.

About

threejs-syntax-shaders is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.

  • threejs-syntax-shaders
  • AI & Agent Building
  • AI-coding skill

Threejs Syntax Shaders by the numbers

  • 18 all-time installs (skills.sh)
  • +2 installs in the week ending Aug 4, 2026 (Skillselion tracking)
  • Ranked #10,710 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/openaec-foundation/three.js-claude-skill-package --skill threejs-syntax-shaders

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs18
repo stars11
Last updatedJuly 8, 2026
Repositoryopenaec-foundation/three.js-claude-skill-package

What it does

Helps with ai & agent building tasks.

Files

SKILL.mdMarkdownGitHub ↗

threejs-syntax-shaders

Quick Reference

ShaderMaterial vs RawShaderMaterial

AspectShaderMaterialRawShaderMaterial
Built-in uniformsAutomatically injectedNONE -- you MUST declare everything
Built-in attributesAutomatically declaredNONE -- you MUST declare everything
#include <chunk>SupportedNOT supported
Precision declarationAutomaticYou MUST add precision mediump float;
Use caseExtend Three.js renderingFull shader control, porting external shaders
PerformanceSlight overhead from unused built-insMinimal shader overhead

Uniform Type Map

GLSL TypeJavaScript Value
float{ value: 1.0 }
int{ value: 1 }
bool{ value: true }
vec2{ value: new THREE.Vector2() }
vec3{ value: new THREE.Vector3() } or { value: new THREE.Color() }
vec4{ value: new THREE.Vector4() }
mat3{ value: new THREE.Matrix3() }
mat4{ value: new THREE.Matrix4() }
sampler2D{ value: texture } (a THREE.Texture instance)
samplerCube{ value: cubeTexture }
float[]{ value: [1.0, 2.0, 3.0] }
vec3[]{ value: [new THREE.Vector3(), ...] }

Critical Warnings

NEVER pass a bare value as a uniform -- ALWAYS wrap it in { value: ... }. Writing uniforms: { uTime: 0.0 } silently fails; ALWAYS write uniforms: { uTime: { value: 0.0 } }.

NEVER declare built-in uniforms or attributes in a ShaderMaterial shader -- Three.js injects them automatically. Redeclaring causes a GLSL compilation error.

ALWAYS declare ALL uniforms, attributes, and precision in RawShaderMaterial shaders -- nothing is injected for you.

NEVER use gl_FragColor or texture2D() when glslVersion is THREE.GLSL3 -- use a declared out vec4 variable and texture() instead.

ALWAYS call material.needsUpdate = true after changing defines -- defines are compiled into the shader, so changes require recompilation.

---

ShaderMaterial

Constructor

import * as THREE from 'three';

const material = new THREE.ShaderMaterial({
  uniforms: {
    uTime: { value: 0.0 },
    uColor: { value: new THREE.Color(0x00ff00) },
    uTexture: { value: someTexture },
  },
  vertexShader: `
    varying vec2 vUv;
    void main() {
      vUv = uv;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  fragmentShader: `
    uniform float uTime;
    uniform vec3 uColor;
    varying vec2 vUv;
    void main() {
      gl_FragColor = vec4(uColor * vUv.x, 1.0);
    }
  `,
  transparent: false,
  wireframe: false,
  side: THREE.FrontSide,
});

Properties

PropertyTypeDefaultDescription
uniformsObject{}{ name: { value: ... } } format
uniformsGroupsArray[]Uniform buffer objects (UBO)
vertexShaderstring--GLSL vertex shader source
fragmentShaderstring--GLSL fragment shader source
definesObject{}Preprocessor #define directives
extensionsObject{}GLSL extensions to enable
wireframebooleanfalseWireframe rendering
lightsbooleanfalsePass light uniforms to shader
fogbooleanfalsePass fog uniforms to shader
clippingbooleanfalseEnable clipping planes
glslVersion`string \null`null
defaultAttributeValuesObject--Fallback values for missing attributes

---

Built-in Uniforms (ShaderMaterial Only)

These are injected automatically. NEVER declare them yourself.

// Transform matrices
uniform mat4 modelMatrix;           // Object -> World
uniform mat4 modelViewMatrix;       // Object -> Camera
uniform mat4 projectionMatrix;      // Camera -> Clip
uniform mat4 viewMatrix;            // World -> Camera
uniform mat3 normalMatrix;          // Transpose inverse of modelViewMatrix

// Camera
uniform vec3 cameraPosition;        // Camera world position

// When lights: true
uniform vec3 ambientLightColor;
// Plus structured arrays for directional, point, spot, hemisphere lights

Built-in Attributes (ShaderMaterial Only)

These are injected automatically. NEVER declare them yourself.

attribute vec3 position;    // Vertex position
attribute vec3 normal;      // Vertex normal
attribute vec2 uv;          // Primary UV coordinates
attribute vec2 uv2;         // Secondary UV (for aoMap, lightMap)
attribute vec4 tangent;     // Tangent vector (if computeTangents was called)
attribute vec3 color;       // Vertex color (if geometry has color attribute)

---

RawShaderMaterial

Use when you need full control over the shader source. NOTHING is injected.

const material = new THREE.RawShaderMaterial({
  uniforms: {
    uModelViewMatrix: { value: new THREE.Matrix4() },
    uProjectionMatrix: { value: new THREE.Matrix4() },
  },
  vertexShader: `
    precision highp float;
    attribute vec3 position;
    uniform mat4 uModelViewMatrix;
    uniform mat4 uProjectionMatrix;
    void main() {
      gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(position, 1.0);
    }
  `,
  fragmentShader: `
    precision highp float;
    void main() {
      gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
  `,
});

ALWAYS add precision highp float; (or mediump) at the top of both shaders in RawShaderMaterial. Omitting precision causes a GLSL compilation error on mobile and some desktop drivers.

---

ShaderChunk -- Reusing Three.js Shader Code

THREE.ShaderChunk contains all internal shader fragments. Use #include <chunk_name> in ShaderMaterial (NOT RawShaderMaterial).

Common Chunks

ChunkPurpose
<common>Shared constants and functions (PI, saturate, etc.)
<fog_pars_vertex> / <fog_vertex>Fog support (vertex)
<fog_pars_fragment> / <fog_fragment>Fog support (fragment)
<shadowmap_pars_vertex> / <shadowmap_vertex>Shadow support (vertex)
<shadowmap_pars_fragment> / <shadowmap_fragment>Shadow support (fragment)
<lights_pars_begin>Light structure declarations
<begin_vertex>Initializes transformed variable from position
<project_vertex>Applies modelViewMatrix and projectionMatrix
<normal_fragment_begin>Normal mapping setup
<color_pars_vertex> / <color_vertex>Vertex color support

Accessing Chunks Programmatically

// Read the source of any chunk
console.log(THREE.ShaderChunk.common);
console.log(THREE.ShaderChunk.fog_pars_vertex);

---

onBeforeCompile -- Patching Built-in Materials

Modify an existing material's shader at compile time. This preserves PBR lighting, shadows, and all built-in features.

const material = new THREE.MeshStandardMaterial({ color: 0xff0000 });

material.onBeforeCompile = (shader) => {
  shader.uniforms.uTime = { value: 0.0 };

  shader.vertexShader = shader.vertexShader.replace(
    '#include <begin_vertex>',
    `
    #include <begin_vertex>
    transformed.y += sin(transformed.x * 5.0 + uTime) * 0.5;
    `
  );

  // Store reference for uniform updates
  material.userData.shader = shader;
};

// ALWAYS override customProgramCacheKey when using onBeforeCompile
material.customProgramCacheKey = () => 'my-wavy-material';

// In animation loop
if (material.userData.shader) {
  material.userData.shader.uniforms.uTime.value = clock.getElapsedTime();
}

ALWAYS override customProgramCacheKey() when using onBeforeCompile -- without it, Three.js may reuse a cached unpatched shader program, causing your modifications to silently disappear.

ALWAYS check material.userData.shader exists before accessing uniforms -- the shader object is created lazily on first render and can be recreated when material.needsUpdate = true.

---

Defines -- Preprocessor Directives

const material = new THREE.ShaderMaterial({
  defines: {
    USE_FOG: '',           // #define USE_FOG
    MAX_LIGHTS: 4,         // #define MAX_LIGHTS 4
    EPSILON: '0.001',      // #define EPSILON 0.001
  },
  // ...shaders
});

Changing defines at runtime:

material.defines.MAX_LIGHTS = 8;
material.needsUpdate = true;  // REQUIRED -- triggers recompilation

---

GLSL3 Mode

const material = new THREE.ShaderMaterial({
  glslVersion: THREE.GLSL3,
  vertexShader: `
    in vec3 position;           // 'attribute' becomes 'in'
    uniform mat4 modelViewMatrix;
    uniform mat4 projectionMatrix;
    out vec3 vPosition;         // 'varying' becomes 'out'

    void main() {
      vPosition = position;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  fragmentShader: `
    precision highp float;
    in vec3 vPosition;          // 'varying' becomes 'in'
    out vec4 fragColor;         // replaces gl_FragColor

    void main() {
      fragColor = vec4(vPosition * 0.5 + 0.5, 1.0);
    }
  `,
});

GLSL1 vs GLSL3 Syntax

GLSL1GLSL3Context
attributeinVertex shader inputs
varying (vertex)outVertex shader outputs
varying (fragment)inFragment shader inputs
gl_FragColorDeclared out vec4Fragment shader output
texture2D()texture()Texture sampling
textureCube()texture()Cube texture sampling

---

Uniform Update Pattern

// At creation
const material = new THREE.ShaderMaterial({
  uniforms: {
    uTime: { value: 0.0 },
    uResolution: { value: new THREE.Vector2(window.innerWidth, window.innerHeight) },
    uMouse: { value: new THREE.Vector2() },
  },
  vertexShader: '...',
  fragmentShader: '...',
});

// In animation loop -- update the .value property directly
function animate() {
  material.uniforms.uTime.value = performance.now() / 1000;
  material.uniforms.uMouse.value.set(mouseX, mouseY);
  renderer.render(scene, camera);
  requestAnimationFrame(animate);
}

NEVER replace the uniform object itself (e.g., material.uniforms.uTime = { value: 5 }). ALWAYS mutate the existing .value property. Replacing the object breaks the internal reference.

---

Reference Links

  • references/methods.md -- Complete API signatures
  • references/examples.md -- Working code examples
  • references/anti-patterns.md -- What NOT to do

Official Sources

  • https://threejs.org/docs/#api/en/materials/ShaderMaterial
  • https://threejs.org/docs/#api/en/materials/RawShaderMaterial
  • https://threejs.org/docs/#api/en/renderers/shaders/ShaderChunk
  • https://threejs.org/docs/#api/en/renderers/shaders/UniformsLib

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.