Remote OpenClaw
Menu
SkillsMCPPluginsFree guideDigestSubmit MCPSkillPluginMCPMCP, plugin, or skillAdvertise
Remote OpenClaw
SkillsMCPPluginsFree guideDigestSubmit MCPSkillPluginMCPMCP, plugin, or skillAdvertise

Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger →
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger →
Turn any website into LLM-ready data with Firecrawl logoTurn any website into LLM-ready data with Firecrawl

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits plus 10% off through our link.

Try Firecrawl free →
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now →
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free →
Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger →
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger →
Turn any website into LLM-ready data with Firecrawl logoTurn any website into LLM-ready data with Firecrawl

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits plus 10% off through our link.

Try Firecrawl free →
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now →
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free →
Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger →
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger →
Turn any website into LLM-ready data with Firecrawl logoTurn any website into LLM-ready data with Firecrawl

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits plus 10% off through our link.

Try Firecrawl free →
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now →
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free →
Skills/enzed/r3f-skills/r3f-shaders
r3f-shaders logo

r3f-shaders

enzed/r3f-skills
739 installs93 stars
Run it on Hostinger →up to 70% off + an extra 10% with code ZACAARON10Free API →

Installation

npx skills add https://github.com/enzed/r3f-skills --skill r3f-shaders

Summary

React Three Fiber shaders - GLSL, shaderMaterial, uniforms, custom effects. Use when creating custom visual effects, modifying vertices, writing fragment shaders, or extending built-in materials.

SKILL.md

React Three Fiber Shaders

Quick Start

import { Canvas, useFrame, extend } from '@react-three/fiber'
import { shaderMaterial } from '@react-three/drei'
import { useRef } from 'react'
import * as THREE from 'three'

// Create custom shader material
const ColorShiftMaterial = shaderMaterial(
  // Uniforms
  { time: 0, color: new THREE.Color(0.2, 0.0, 0.1) },
  // Vertex shader
  `
    varying vec2 vUv;
    void main() {
      vUv = uv;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  // Fragment shader
  `
    uniform float time;
    uniform vec3 color;
    varying vec2 vUv;
    void main() {
      gl_FragColor = vec4(vUv.x + sin(time), vUv.y + cos(time), color.b, 1.0);
    }
  `
)

// Extend so it can be used as JSX
extend({ ColorShiftMaterial })

function ShaderMesh() {
  const materialRef = useRef()

  useFrame(({ clock }) => {
    materialRef.current.time = clock.elapsedTime
  })

  return (
    <mesh>
      <planeGeometry args={[2, 2]} />
      {/* key={Material.key} enables HMR for shader development */}
      <colorShiftMaterial ref={materialRef} key={ColorShiftMaterial.key} />
    </mesh>
  )
}

export default function App() {
  return (
    <Canvas>
      <ShaderMesh />
    </Canvas>
  )
}

shaderMaterial (Drei)

The recommended way to create shader materials in R3F.

Basic Pattern

import { shaderMaterial } from '@react-three/drei'
import { extend } from '@react-three/fiber'
import * as THREE from 'three'

// 1. Define the material
const MyShaderMaterial = shaderMaterial(
  // Uniforms object
  {
    time: 0,
    color: new THREE.Color(1, 0, 0),
    opacity: 1,
    map: null,
  },
  // Vertex shader (GLSL)
  `
    varying vec2 vUv;
    varying vec3 vPosition;

    void main() {
      vUv = uv;
      vPosition = position;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  // Fragment shader (GLSL)
  `
    uniform float time;
    uniform vec3 color;
    uniform float opacity;
    uniform sampler2D map;
    varying vec2 vUv;

    void main() {
      vec4 texColor = texture2D(map, vUv);
      gl_FragColor = vec4(color * texColor.rgb, opacity);
    }
  `
)

// 2. Extend R3F
extend({ MyShaderMaterial })

// 3. Use in component
function MyMesh() {
  const materialRef = useRef()

  useFrame(({ clock }) => {
    materialRef.current.time = clock.elapsedTime
  })

  return (
    <mesh>
      <boxGeometry />
      {/* key prop enables Hot Module Replacement during development */}
      <myShaderMaterial
        ref={materialRef}
        key={MyShaderMaterial.key}
        color="hotpink"
        transparent
        opacity={0.8}
      />
    </mesh>
  )
}

Hot Module Replacement (HMR)

The key prop on shaderMaterial enables live shader editing without page refresh:

const MyMaterial = shaderMaterial(
  { time: 0 },
  vertexShader,
  fragmentShader
)

extend({ MyMaterial })

// MyMaterial.key changes when shader code changes
<myMaterial key={MyMaterial.key} />

When you edit shader code, the material automatically updates. Without key, you'd need to refresh the page to see changes.

TypeScript Support

import { shaderMaterial } from '@react-three/drei'
import { extend, Object3DNode } from '@react-three/fiber'
import * as THREE from 'three'

// Define uniform types
type WaveMaterialUniforms = {
  time: number
  amplitude: number
  color: THREE.Color
}

const WaveMaterial = shaderMaterial(
  {
    time: 0,
    amplitude: 0.5,
    color: new THREE.Color('hotpink'),
  } as WaveMaterialUniforms,
  // vertex shader
  `...`,
  // fragment shader
  `...`
)

// Extend with proper types
extend({ WaveMaterial })

// Declare for TypeScript
declare module '@react-three/fiber' {
  interface ThreeElements {
    waveMaterial: Object3DNode<
      typeof WaveMaterial & THREE.ShaderMaterial,
      typeof WaveMaterial
    >
  }
}

Raw THREE.ShaderMaterial

For full control without Drei helper.

import { useFrame } from '@react-three/fiber'
import { useMemo, useRef } from 'react'
import * as THREE from 'three'

function CustomShaderMesh() {
  const materialRef = useRef()

  const shaderMaterial = useMemo(() => {
    return new THREE.ShaderMaterial({
      uniforms: {
        time: { value: 0 },
        color: { value: new THREE.Color('cyan') },
        resolution: { value: new THREE.Vector2(window.innerWidth, window.innerHeight) },
      },
      vertexShader: `
        varying vec2 vUv;
        void main() {
          vUv = uv;
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }
      `,
      fragmentShader: `
        uniform float time;
        uniform vec3 color;
        uniform vec2 resolution;
        varying vec2 vUv;

        void main() {
          vec2 st = gl_FragCoord.xy / resolution;
          float pattern = sin(st.x * 20.0 + time) * sin(st.y * 20.0 + time);
          gl_FragColor = vec4(color * pattern, 1.0);
        }
      `,
      side: THREE.DoubleSide,
      transparent: true,
    })
  }, [])

  useFrame(({ clock }) => {
    shaderMaterial.uniforms.time.value = clock.elapsedTime
  })

  return (
    <mesh material={shaderMaterial}>
      <planeGeometry args={[4, 4, 32, 32]} />
    </mesh>
  )
}

Uniforms

Common Uniform Types

const MyMaterial = shaderMaterial(
  {
    // Numbers
    time: 0,
    intensity: 1.5,

    // Vectors
    resolution: new THREE.Vector2(1920, 1080),
    lightPosition: new THREE.Vector3(5, 10, 5),
    bounds: new THREE.Vector4(0, 0, 1, 1),

    // Color (becomes vec3)
    color: new THREE.Color('#ff0000'),

    // Matrices
    customMatrix: new THREE.Matrix4(),

    // Textures
    map: null,        // sampler2D
    cubeMap: null,    // samplerCube

    // Arrays
    positions: [new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()],
  },
  vertexShader,
  fragmentShader
)

GLSL Declarations

// In shader code
uniform float time;
uniform float intensity;
uniform vec2 resolution;
uniform vec3 lightPosition;
uniform vec3 color;  // THREE.Color becomes vec3
uniform vec4 bounds;
uniform mat4 customMatrix;
uniform sampler2D map;
uniform samplerCube cubeMap;
uniform vec3 positions[3];

Updating Uniforms

function AnimatedShader() {
  const materialRef = useRef()

  useFrame(({ clock, mouse, viewport }) => {
    // Direct value update
    materialRef.current.time = clock.elapsedTime

    // Vector update
    materialRef.current.resolution.set(viewport.width, viewport.height)

    // Color update
    materialRef.current.color.setHSL((clock.elapsedTime * 0.1) % 1, 1, 0.5)

    // Or via uniforms object (for THREE.ShaderMaterial)
    // materialRef.current.uniforms.time.value = clock.elapsedTime
  })

  return (
    <mesh>
      <boxGeometry />
      <myShaderMaterial ref={materialRef} />
    </mesh>
  )
}

Varyings

Pass data from vertex to fragment shader.

// Vertex shader
varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vPosition;
varying vec3 vWorldPosition;

void main() {
  vUv = uv;
  vNormal = normalize(normalMatrix * normal);
  vPosition = position;
  vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;

  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

// Fragment shader
varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vPosition;
varying vec3 vWorldPosition;

void main() {
  // Use interpolated values
  gl_FragColor = vec4(vNormal * 0.5 + 0.5, 1.0);
}

Common Shader Patterns

Texture Sampling

import { useTexture } from '@react-three/drei'

function TexturedShaderMesh() {
  const texture = useTexture('/textures/color.jpg')
  const materialRef = useRef()

  return (
    <mesh>
      <planeGeometry args={[2, 2]} />
      <myShaderMaterial ref={materialRef} map={texture} />
    </mesh>
  )
}

// Shader
const TextureMaterial = shaderMaterial(
  { map: null },
  `
    varying vec2 vUv;
    void main() {
      vUv = uv;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  `
    uniform sampler2D map;
    varying vec2 vUv;

    void main() {
      vec4 texColor = texture2D(map, vUv);
      gl_FragColor = texColor;
    }
  `
)

Vertex Displacement

const WaveMaterial = shaderMaterial(
  { time: 0, amplitude: 0.5, frequency: 2.0 },
  `
    uniform float time;
    uniform float amplitude;
    uniform float frequency;
    varying vec2 vUv;

    void main() {
      vUv = uv;
      vec3 pos = position;

      // Wave displacement
      pos.z += sin(pos.x * frequency + time) * amplitude;
      pos.z += sin(pos.y * frequency + time) * amplitude;

      gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
    }
  `,
  `
    varying vec2 vUv;
    void main() {
      gl_FragColor = vec4(vUv, 1.0, 1.0);
    }
  `
)

extend({ WaveMaterial })

function WavePlane() {
  const ref = useRef()

  useFrame(({ clock }) => {
    ref.current.time = clock.elapsedTime
  })

  return (
    <mesh rotation={[-Math.PI / 2, 0, 0]}>
      <planeGeometry args={[10, 10, 64, 64]} />
      <waveMaterial ref={ref} />
    </mesh>
  )
}

Fresnel Effect

const FresnelMaterial = shaderMaterial(
  { fresnelColor: new THREE.Color('cyan'), baseColor: new THREE.Color('navy') },
  `
    varying vec3 vNormal;
    varying vec3 vWorldPosition;

    void main() {
      vNormal = normalize(normalMatrix * normal);
      vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  `
    uniform vec3 fresnelColor;
    uniform vec3 baseColor;
    varying vec3 vNormal;
    varying vec3 vWorldPosition;

    void main() {
      vec3 viewDirection = normalize(cameraPosition - vWorldPosition);
      float fresnel = pow(1.0 - dot(viewDirection, vNormal), 3.0);

      gl_FragColor = vec4(mix(baseColor, fresnelColor, fresnel), 1.0);
    }
  `
)

Noise Functions

// Simple random
float random(vec2 st) {
  return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453);
}

// Value noise
float noise(vec2 st) {
  vec2 i = floor(st);
  vec2 f = fract(st);

  float a = random(i);
  float b = random(i + vec2(1.0, 0.0));
  float c = random(i + vec2(0.0, 1.0));
  float d = random(i + vec2(1.0, 1.0));

  vec2 u = f * f * (3.0 - 2.0 * f);

  return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
}

// FBM (Fractal Brownian Motion)
float fbm(vec2 st) {
  float value = 0.0;
  float amplitude = 0.5;

  for (int i = 0; i < 5; i++) {
    value += amplitude * noise(st);
    st *= 2.0;
    amplitude *= 0.5;
  }

  return value;
}

Gradient

// Linear gradient
vec3 gradient = mix(colorA, colorB, vUv.y);

// Radial gradient
float dist = distance(vUv, vec2(0.5));
vec3 radial = mix(centerColor, edgeColor, dist * 2.0);

// Smooth gradient
float t = smoothstep(0.0, 1.0, vUv.y);
vec3 smooth = mix(colorA, colorB, t);

Dissolve Effect

const DissolveMaterial = shaderMaterial(
  { progress: 0, noiseScale: 10.0, edgeColor: new THREE.Color('orange') },
  `
    varying vec2 vUv;
    void main() {
      vUv = uv;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  `
    uniform float progress;
    uniform float noiseScale;
    uniform vec3 edgeColor;
    varying vec2 vUv;

    float random(vec2 st) {
      return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453);
    }

    float noise(vec2 st) {
      vec2 i = floor(st);
      vec2 f = fract(st);
      float a = random(i);
      float b = random(i + vec2(1.0, 0.0));
      float c = random(i + vec2(0.0, 1.0));
      float d = random(i + vec2(1.0, 1.0));
      vec2 u = f * f * (3.0 - 2.0 * f);
      return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
    }

    void main() {
      float n = noise(vUv * noiseScale);

      if (n < progress) {
        discard;
      }

      float edge = smoothstep(progress, progress + 0.1, n);
      vec3 baseColor = vec3(0.5);

      gl_FragColor = vec4(mix(edgeColor, baseColor, edge), 1.0);
    }
  `
)

Extending Built-in Materials

onBeforeCompile

Modify existing material shaders.

import { useRef, useEffect } from 'react'
import { useFrame } from '@react-three/fiber'
import * as THREE from 'three'

function ModifiedStandardMaterial() {
  const materialRef = useRef()
  const shaderRef = useRef()

  useEffect(() => {
    if (materialRef.current) {
      materialRef.current.onBeforeCompile = (shader) => {
        // Add custom uniform
        shader.uniforms.time = { value: 0 }
        shaderRef.current = shader

        // Add uniform declaration
        shader.vertexShader = 'uniform float time;\n' + shader.vertexShader

        // Modify vertex shader
        shader.vertexShader = shader.vertexShader.replace(
          '#include <begin_vertex>',
          `
            #include <begin_vertex>
            transformed.y += sin(position.x * 10.0 + time) * 0.1;
          `
        )
      }
    }
  }, [])

  useFrame(({ clock }) => {
    if (shaderRef.current) {
      shaderRef.current.uniforms.time.value = clock.elapsedTime
    }
  })

  return (
    <mesh>
      <planeGeometry args={[5, 5, 32, 32]} />
      <meshStandardMaterial ref={materialRef} color="green" />
    </mesh>
  )
}

Common Injection Points

// Vertex shader chunks
'#include <begin_vertex>'       // After position is calculated
'#include <project_vertex>'     // After gl_Position
'#include <beginnormal_vertex>' // Normal calculation start

// Fragment shader chunks
'#include <color_fragment>'     // After diffuse color
'#include <output_fragment>'    // Final output
'#include <fog_fragment>'       // After fog applied

GLSL Built-in Functions

Math Functions

// Basic
abs(x), sign(x), floor(x), ceil(x), fract(x)
mod(x, y), min(x, y), max(x, y), clamp(x, min, max)
mix(a, b, t), step(edge, x), smoothstep(edge0, edge1, x)

// Trigonometry
sin(x), cos(x), tan(x)
asin(x), acos(x), atan(y, x), atan(x)

// Exponential
pow(x, y), exp(x), log(x), sqrt(x)

Vector Functions

length(v), distance(p0, p1), dot(x, y), cross(x, y)
normalize(v), reflect(I, N), refract(I, N, eta)

Instanced Shaders

import { useRef, useMemo } from 'react'
import { useFrame } from '@react-three/fiber'
import * as THREE from 'three'

function InstancedShaderMesh({ count = 1000 }) {
  const meshRef = useRef()

  // Create instance attributes
  const { offsets, colors } = useMemo(() => {
    const offsets = new Float32Array(count * 3)
    const colors = new Float32Array(count * 3)

    for (let i = 0; i < count; i++) {
      offsets[i * 3] = (Math.random() - 0.5) * 20
      offsets[i * 3 + 1] = (Math.random() - 0.5) * 20
      offsets[i * 3 + 2] = (Math.random() - 0.5) * 20

      colors[i * 3] = Math.random()
      colors[i * 3 + 1] = Math.random()
      colors[i * 3 + 2] = Math.random()
    }

    return { offsets, colors }
  }, [count])

  const shaderMaterial = useMemo(() => {
    return new THREE.ShaderMaterial({
      uniforms: {
        time: { value: 0 }
      },
      vertexShader: `
        attribute vec3 offset;
        attribute vec3 instanceColor;
        varying vec3 vColor;

        void main() {
          vColor = instanceColor;
          vec3 pos = position + offset;
          gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
        }
      `,
      fragmentShader: `
        varying vec3 vColor;

        void main() {
          gl_FragColor = vec4(vColor, 1.0);
        }
      `
    })
  }, [])

  useFrame(({ clock }) => {
    shaderMaterial.uniforms.time.value = clock.elapsedTime
  })

  return (
    <instancedMesh ref={meshRef} args={[null, null, count]} material={shaderMaterial}>
      <boxGeometry args={[0.5, 0.5, 0.5]}>
        <instancedBufferAttribute attach="attributes-offset" args={[offsets, 3]} />
        <instancedBufferAttribute attach="attributes-instanceColor" args={[colors, 3]} />
      </boxGeometry>
    </instancedMesh>
  )
}

External Shader Files

With Vite/Webpack

// shaders/vertex.glsl
varying vec2 vUv;
void main() {
  vUv = uv;
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

// shaders/fragment.glsl
uniform float time;
varying vec2 vUv;
void main() {
  gl_FragColor = vec4(vUv, sin(time), 1.0);
}

// Component.tsx
import vertexShader from './shaders/vertex.glsl?raw'
import fragmentShader from './shaders/fragment.glsl?raw'

const MyMaterial = shaderMaterial(
  { time: 0 },
  vertexShader,
  fragmentShader
)

Vite Config for GLSL

// vite.config.js
import glsl from 'vite-plugin-glsl'

export default {
  plugins: [glsl()]
}

Material Properties

<myShaderMaterial
  // Rendering
  transparent={true}
  opacity={1.0}
  side={THREE.DoubleSide}
  depthTest={true}
  depthWrite={true}

  // Blending
  blending={THREE.NormalBlending}
  // NormalBlending, AdditiveBlending, SubtractiveBlending, MultiplyBlending

  // Wireframe
  wireframe={false}

  // Custom uniforms
  time={0}
  color="hotpink"
/>

Debugging Shaders

function DebugShaderMesh() {
  const materialRef = useRef()

  useEffect(() => {
    // Log compiled shaders
    if (materialRef.current) {
      console.log('Vertex:', materialRef.current.vertexShader)
      console.log('Fragment:', materialRef.current.fragmentShader)
    }
  }, [])

  return (
    <mesh>
      <boxGeometry />
      {/* Debug with visual output */}
      <shaderMaterial
        ref={materialRef}
        fragmentShader={`
          varying vec2 vUv;
          void main() {
            // Debug UV
            gl_FragColor = vec4(vUv, 0.0, 1.0);

            // Debug normals (in vertex: vNormal = normal)
            // gl_FragColor = vec4(vNormal * 0.5 + 0.5, 1.0);
          }
        `}
        vertexShader={`
          varying vec2 vUv;
          void main() {
            vUv = uv;
            gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
          }
        `}
      />
    </mesh>
  )
}

Performance Tips

  1. Minimize uniforms: Group related values into vectors
  2. Avoid conditionals: Use mix/step instead of if/else
  3. Precalculate in JS: Move static calculations out of shaders
  4. Use textures for lookup: Complex functions as texture lookups
  5. Limit overdraw: Avoid unnecessary transparent objects
// Instead of:
if (value > 0.5) {
  color = colorA;
} else {
  color = colorB;
}

// Use:
color = mix(colorB, colorA, step(0.5, value));

See Also

  • r3f-materials - Built-in material types
  • r3f-postprocessing - Full-screen shader effects
  • r3f-textures - Texture sampling in shaders

Score

0–100
63/ 100

Grade

C

Popularity15/30

739 installs — growing adoption.

Completeness27/30

Documented: full SKILL.md body, description, one-line install. Missing: category/license metadata.

Trust15/25

Community skill with a public GitHub source repository you can review.

Freshness6/15

No update timestamp is tracked for this skill in our catalog.

Scored automatically from popularity, completeness, trust, and freshness — computed only from data in our catalog, never fabricated.

Proud of your score? Add this badge to your README.

Paste a snippet into your GitHub README. The badge updates automatically and links back to this page.

R3f Shaders skill score badge previewScore badge

Markdown

[![R3f Shaders skill](https://www.remoteopenclaw.com/skills/enzed/r3f-skills/r3f-shaders/badges/score.svg)](https://www.remoteopenclaw.com/skills/enzed/r3f-skills/r3f-shaders)

HTML

<a href="https://www.remoteopenclaw.com/skills/enzed/r3f-skills/r3f-shaders"><img src="https://www.remoteopenclaw.com/skills/enzed/r3f-skills/r3f-shaders/badges/score.svg" alt="R3f Shaders skill"/></a>

R3f Shaders FAQ

How do I install the R3f Shaders skill?

Run “npx skills add https://github.com/enzed/r3f-skills --skill r3f-shaders” in your terminal. The skill is added to your agent's skills directory and picked up automatically on the next run — no restart or extra configuration needed.

What does the R3f Shaders skill do?

React Three Fiber shaders - GLSL, shaderMaterial, uniforms, custom effects. Use when creating custom visual effects, modifying vertices, writing fragment shaders, or extending built-in materials. The full SKILL.md on this page shows the exact instructions the skill gives your agent.

Is the R3f Shaders skill free?

Yes. R3f Shaders is a free, open-source skill published from enzed/r3f-skills. As with any third-party skill, review the source repository before installing it into an agent with sensitive access.

Does R3f Shaders work with Claude Code and OpenClaw?

Yes. Skills use the portable SKILL.md format, so R3f Shaders works with Claude Code, OpenClaw, Codex, Hermes, and any other agent that reads SKILL.md skills.

Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger →
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger →
Turn any website into LLM-ready data with Firecrawl logoTurn any website into LLM-ready data with Firecrawl

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits plus 10% off through our link.

Try Firecrawl free →
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now →
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free →
Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger →
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger →
Turn any website into LLM-ready data with Firecrawl logoTurn any website into LLM-ready data with Firecrawl

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits plus 10% off through our link.

Try Firecrawl free →
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now →
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free →
Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger →
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger →
Turn any website into LLM-ready data with Firecrawl logoTurn any website into LLM-ready data with Firecrawl

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits plus 10% off through our link.

Try Firecrawl free →
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now →
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free →

Categories

No Code
View on GitHub

Recommended skills

Browse all →
find-skills logo

find-skills

vercel-labs/skills

2.7M installsInstall
frontend-design logo

frontend-design

anthropics/skills

721K installsInstall
grill-me logo

grill-me

mattpocock/skills

702K installsInstall
agent-browser logo

agent-browser

vercel-labs/agent-browser

597K installsInstall
grill-with-docs logo

grill-with-docs

mattpocock/skills

595K installsInstall
vercel-react-best-practices logo

vercel-react-best-practices

vercel-labs/agent-skills

591K installsInstall

Browse

Skills by category

Frontend250Git198Data154Testing120Design105Docs103Security96Automation87Backend76Devops37Productivity29Mcp23

Related guides

Hand-picked reading to help you choose, install, and use agent skills.

GuideBest Documentation Skills For AI AgentsGuide10 Openclaw Skills Every Nextjs Developer NeedsGuideBest Openclaw Skills 2026

Remote OpenClaw

AI agent skills directory, marketplace, and workflow hub for OpenClaw, Hermes Agent, Claude Code, Codex, and MCP-powered operator stacks.

The Agent Stack: weekly agent tooling digest, free.

Explore

  • Home
  • Skills Directory
  • Claude Code Skills
  • Codex Skills
  • MCP Clients
  • Marketplace
  • Hermes Ecosystem
  • Free guide
  • Learn
  • OpenClaw for Creators
  • OpenClaw for Founders
  • Blog
  • The Agent Stack (Digest)

More

  • Submit a Tool
  • Advertise
  • Playbook
  • Free Tools
  • API
  • Shipping
  • Contact
  • Terms
  • Privacy

Know a company that should advertise here? Refer them and earn 10% — up to $300 per referral.

© 2026 Remote OpenClaw
Fazier badgeFeatured on Twelve ToolsFeatured on Wired BusinessRemote OpenClaw - Featured on AI Agents DirectoryListed on Turbo0Featured on Uneed