Frontend Lab
← 回到所有效果
T073D007three

Noise Background

噪聲背景

難度 ★★★★標籤 shader · noise · glsl3 min read

效果簡述

shader 內手寫 hash + value noise,產生有機流動感的背景。比一般動態漸層 有層次。是進入 shader 世界的第二站。

預設|細顆粒灰

Claude Code Prompt

💬 Claude Code Prompt
參考:3D007 noise background
技術:fragment shader 內寫 hash-based noise

具體行為:
- float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); }
- float noise(vec2 p) { 雙線性內插 4 個 hash 點 }
- 主程式 noise(uv*4 + uTime*0.15) 混兩色

限制:
- noise 函式效能 ok,但 fBM (多層疊加) 開始重,2~3 層上限
- 中文字 / 內文壓在上面要確保對比度
- 沒必要時不用 Perlin,hash-noise 已夠用

完整程式碼

NoiseBackground.tsx
'use client'

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

const vert = `varying vec2 vUv; void main(){ vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0); }`
const frag = `uniform float uTime; varying vec2 vUv;
float hash(vec2 p){ return fract(sin(dot(p, vec2(127.1,311.7))) * 43758.5453); }
float noise(vec2 p){
  vec2 i = floor(p); vec2 f = fract(p);
  f = f*f*(3.0-2.0*f);
  return mix(
    mix(hash(i), hash(i+vec2(1,0)), f.x),
    mix(hash(i+vec2(0,1)), hash(i+vec2(1,1)), f.x), f.y
  );
}
void main(){
  float n = noise(vUv * 4.0 + uTime * 0.15);
  vec3 col = mix(vec3(0.05,0.05,0.08), vec3(0.76,0.25,0.05), n);
  gl_FragColor = vec4(col, 1.0);
}`

function NoisePlane() {
const ref = useRef<THREE.ShaderMaterial>(null)
const uniforms = useMemo(() => ({ uTime: { value: 0 } }), [])
useFrame((s) => { if (ref.current) ref.current.uniforms.uTime.value = s.clock.getElapsedTime() })
return (
  <mesh>
    <planeGeometry args={[6,4]} />
    <shaderMaterial ref={ref} vertexShader={vert} fragmentShader={frag} uniforms={uniforms} />
  </mesh>
)
}

export function NoiseBackground() {
return (
  <Canvas camera={{ position: [0,0,3], fov: 55 }} dpr={[1,2]}>
    <NoisePlane />
  </Canvas>
)
}

何時用

  • ✅ 高級感 Hero 背景
  • ✅ 跟漸層搭配做「有機光感」
  • ✅ Art / 設計工作室站

何時別用

  • ❌ 內文背景(讀者眼睛累)
  • ❌ 對比度沒處理(前景文字看不清)
  • ❌ 一頁多塊 noise

我踩過的坑

  1. hash 系數對結果影響大:127.1 / 311.7 / 43758.5453 是社群驗證 過的「亂得剛好」的數字。別亂改。

  2. 多層 fBM 行動裝置卡:1~2 層 noise 就好。

  3. 混色太接近看不出來:兩端色差要夠大才有層次。

相關效果

搜尋

按 ⌘K 隨時開啟