_❯Film Grain Shader
Procedural multi-octave value-noise film grain in WebGL, supersampled to stay fine on high-DPI screens.
WebGLGLSLfilm grainnoise
1import { useState } from "react";2import { GrainCanvas } from "@/components/misc/grain-canvas/grain-canvas.component";3import { LabsDemoLayout } from "../../components/labs-experiment-frame/labs-experiment-frame.component";4import {5 ControlGroup,6 ControlPanel,7 ResetButton,8 SliderControl,9} from "../../components/labs-control/labs-control.component";10import * as styles from "./grain-shader.demo.css";1112const DEFAULT_GRAIN = 0.18;13const DEFAULT_BASE = 0.04;1415export function GrainShaderDemo() {16 const [grainAlpha, setGrainAlpha] = useState(DEFAULT_GRAIN);17 const [baseAlpha, setBaseAlpha] = useState(DEFAULT_BASE);1819 const reset = () => {20 setGrainAlpha(DEFAULT_GRAIN);21 setBaseAlpha(DEFAULT_BASE);22 };2324 return (25 <LabsDemoLayout26 stage={27 <div className={styles.stageInner}>28 <div className={styles.grainBox}>29 <GrainCanvas grainAlpha={grainAlpha} baseAlpha={baseAlpha} />30 </div>31 </div>32 }33 controls={34 <ControlPanel>35 <ControlGroup title="Grain">36 <SliderControl37 label="Grain"38 value={grainAlpha}39 min={0}40 max={0.4}41 step={0.005}42 onChange={setGrainAlpha}43 format={(value) => value.toFixed(3)}44 />45 <SliderControl46 label="Base"47 value={baseAlpha}48 min={0}49 max={0.15}50 step={0.005}51 onChange={setBaseAlpha}52 format={(value) => value.toFixed(3)}53 />54 </ControlGroup>5556 <ResetButton onReset={reset} />57 </ControlPanel>58 }59 />60 );61}