postfx-bloom
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePost-Processing Bloom
后处理光晕(Bloom)效果
Bloom effects using UnrealBloomPass for luminance-based glow and selective object bloom.
使用UnrealBloomPass实现基于亮度的发光和对象选择性光晕效果。
Quick Start
快速开始
bash
npm install three @react-three/fiber @react-three/postprocessingtsx
import { Canvas } from '@react-three/fiber';
import { EffectComposer, Bloom } from '@react-three/postprocessing';
function Scene() {
return (
<Canvas>
<mesh>
<sphereGeometry args={[1, 32, 32]} />
<meshStandardMaterial emissive="#00F5FF" emissiveIntensity={2} />
</mesh>
<EffectComposer>
<Bloom
luminanceThreshold={0.2}
luminanceSmoothing={0.9}
intensity={1.5}
/>
</EffectComposer>
</Canvas>
);
}bash
npm install three @react-three/fiber @react-three/postprocessingtsx
import { Canvas } from '@react-three/fiber';
import { EffectComposer, Bloom } from '@react-three/postprocessing';
function Scene() {
return (
<Canvas>
<mesh>
<sphereGeometry args={[1, 32, 32]} />
<meshStandardMaterial emissive="#00F5FF" emissiveIntensity={2} />
</mesh>
<EffectComposer>
<Bloom
luminanceThreshold={0.2}
luminanceSmoothing={0.9}
intensity={1.5}
/>
</EffectComposer>
</Canvas>
);
}Core Concepts
核心概念
How Bloom Works
光晕效果的工作原理
- Threshold — Pixels brighter than threshold are extracted
- Blur — Extracted pixels are blurred in multiple passes
- Composite — Blurred result is added back to original image
- 阈值 — 提取亮度超过阈值的像素
- 模糊 — 对提取的像素进行多轮模糊处理
- 合成 — 将模糊后的结果叠加回原始图像
Key Parameters
关键参数
| Parameter | Range | Description |
|---|---|---|
| 0-1 | Brightness cutoff for bloom (lower = more glow) |
| 0-1 | Softness of threshold transition |
| 0-10 | Bloom brightness multiplier |
| 0-1 | Blur spread/size |
| 1-9 | Blur quality/iterations |
| 参数 | 范围 | 说明 |
|---|---|---|
| 0-1 | 光晕的亮度 cutoff 值(值越低,发光范围越大) |
| 0-1 | 阈值过渡的柔和度 |
| 0-10 | 光晕亮度的乘数 |
| 0-1 | 模糊扩散范围/大小 |
| 1-9 | 模糊质量/迭代次数 |
Patterns
实现模式
Cosmic Glow Effect
宇宙发光效果
tsx
import { EffectComposer, Bloom } from '@react-three/postprocessing';
import { KernelSize } from 'postprocessing';
function CosmicBloom() {
return (
<EffectComposer>
<Bloom
luminanceThreshold={0.1}
luminanceSmoothing={0.9}
intensity={2.5}
radius={0.8}
kernelSize={KernelSize.LARGE}
mipmapBlur
/>
</EffectComposer>
);
}tsx
import { EffectComposer, Bloom } from '@react-three/postprocessing';
import { KernelSize } from 'postprocessing';
function CosmicBloom() {
return (
<EffectComposer>
<Bloom
luminanceThreshold={0.1}
luminanceSmoothing={0.9}
intensity={2.5}
radius={0.8}
kernelSize={KernelSize.LARGE}
mipmapBlur
/>
</EffectComposer>
);
}Neon Cyberpunk Bloom
霓虹赛博朋克光晕
tsx
// High-contrast neon with sharp falloff
function NeonBloom() {
return (
<EffectComposer>
<Bloom
luminanceThreshold={0.4}
luminanceSmoothing={0.2}
intensity={3.0}
radius={0.4}
mipmapBlur
/>
</EffectComposer>
);
}
// Emissive material for neon objects
function NeonTube({ color = '#FF00FF' }) {
return (
<mesh>
<cylinderGeometry args={[0.05, 0.05, 2]} />
<meshStandardMaterial
emissive={color}
emissiveIntensity={4}
toneMapped={false}
/>
</mesh>
);
}tsx
// 高对比度霓虹,边缘锐利衰减
function NeonBloom() {
return (
<EffectComposer>
<Bloom
luminanceThreshold={0.4}
luminanceSmoothing={0.2}
intensity={3.0}
radius={0.4}
mipmapBlur
/>
</EffectComposer>
);
}
// 霓虹物体的自发光材质
function NeonTube({ color = '#FF00FF' }) {
return (
<mesh>
<cylinderGeometry args={[0.05, 0.05, 2]} />
<meshStandardMaterial
emissive={color}
emissiveIntensity={4}
toneMapped={false}
/>
</mesh>
);
}Selective Bloom with Layers
使用图层实现选择性光晕
tsx
import { useRef } from 'react';
import { useThree } from '@react-three/fiber';
import { EffectComposer, SelectiveBloom } from '@react-three/postprocessing';
function SelectiveGlow() {
const glowRef = useRef();
return (
<>
{/* Non-blooming object */}
<mesh position={[-2, 0, 0]}>
<boxGeometry />
<meshStandardMaterial color="#333" />
</mesh>
{/* Blooming object */}
<mesh ref={glowRef} position={[2, 0, 0]}>
<sphereGeometry args={[0.5, 32, 32]} />
<meshStandardMaterial
emissive="#00F5FF"
emissiveIntensity={3}
/>
</mesh>
<EffectComposer>
<SelectiveBloom
selection={glowRef}
luminanceThreshold={0.1}
intensity={2}
mipmapBlur
/>
</EffectComposer>
</>
);
}tsx
import { useRef } from 'react';
import { useThree } from '@react-three/fiber';
import { EffectComposer, SelectiveBloom } from '@react-three/postprocessing';
function SelectiveGlow() {
const glowRef = useRef();
return (
<>
{/* 不发光的物体 */}
<mesh position={[-2, 0, 0]}>
<boxGeometry />
<meshStandardMaterial color="#333" />
</mesh>
{/* 发光的物体 */}
<mesh ref={glowRef} position={[2, 0, 0]}>
<sphereGeometry args={[0.5, 32, 32]} />
<meshStandardMaterial
emissive="#00F5FF"
emissiveIntensity={3}
/>
</mesh>
<EffectComposer>
<SelectiveBloom
selection={glowRef}
luminanceThreshold={0.1}
intensity={2}
mipmapBlur
/>
</EffectComposer>
</>
);
}Multi-Selection Bloom
多物体选择光晕
tsx
import { Selection, Select, EffectComposer } from '@react-three/postprocessing';
import { SelectiveBloom } from '@react-three/postprocessing';
function MultiSelectBloom() {
return (
<Selection>
{/* Non-blooming */}
<mesh position={[-2, 0, 0]}>
<boxGeometry />
<meshStandardMaterial color="#333" />
</mesh>
{/* Blooming objects wrapped in Select */}
<Select enabled>
<mesh position={[0, 0, 0]}>
<sphereGeometry args={[0.5]} />
<meshStandardMaterial emissive="#00F5FF" emissiveIntensity={2} />
</mesh>
</Select>
<Select enabled>
<mesh position={[2, 0, 0]}>
<octahedronGeometry args={[0.5]} />
<meshStandardMaterial emissive="#FF00FF" emissiveIntensity={2} />
</mesh>
</Select>
<EffectComposer>
<SelectiveBloom
luminanceThreshold={0.1}
intensity={1.5}
mipmapBlur
/>
</EffectComposer>
</Selection>
);
}tsx
import { Selection, Select, EffectComposer } from '@react-three/postprocessing';
import { SelectiveBloom } from '@react-three/postprocessing';
function MultiSelectBloom() {
return (
<Selection>
{/* 不发光的物体 */}
<mesh position={[-2, 0, 0]}>
<boxGeometry />
<meshStandardMaterial color="#333" />
</mesh>
{/* 包裹在Select组件中的发光物体 */}
<Select enabled>
<mesh position={[0, 0, 0]}>
<sphereGeometry args={[0.5]} />
<meshStandardMaterial emissive="#00F5FF" emissiveIntensity={2} />
</mesh>
</Select>
<Select enabled>
<mesh position={[2, 0, 0]}>
<octahedronGeometry args={[0.5]} />
<meshStandardMaterial emissive="#FF00FF" emissiveIntensity={2} />
</mesh>
</Select>
<EffectComposer>
<SelectiveBloom
luminanceThreshold={0.1}
intensity={1.5}
mipmapBlur
/>
</EffectComposer>
</Selection>
);
}Animated Bloom Intensity
光晕强度动画
tsx
import { useRef } from 'react';
import { useFrame } from '@react-three/fiber';
import { EffectComposer, Bloom } from '@react-three/postprocessing';
function PulsingBloom() {
const bloomRef = useRef();
useFrame(({ clock }) => {
if (bloomRef.current) {
const pulse = Math.sin(clock.elapsedTime * 2) * 0.5 + 1.5;
bloomRef.current.intensity = pulse;
}
});
return (
<EffectComposer>
<Bloom
ref={bloomRef}
luminanceThreshold={0.2}
intensity={1.5}
mipmapBlur
/>
</EffectComposer>
);
}tsx
import { useRef } from 'react';
import { useFrame } from '@react-three/fiber';
import { EffectComposer, Bloom } from '@react-three/postprocessing';
function PulsingBloom() {
const bloomRef = useRef();
useFrame(({ clock }) => {
if (bloomRef.current) {
const pulse = Math.sin(clock.elapsedTime * 2) * 0.5 + 1.5;
bloomRef.current.intensity = pulse;
}
});
return (
<EffectComposer>
<Bloom
ref={bloomRef}
luminanceThreshold={0.2}
intensity={1.5}
mipmapBlur
/>
</EffectComposer>
);
}Audio-Reactive Bloom
音频响应式光晕
tsx
function AudioReactiveBloom({ audioData }) {
const bloomRef = useRef();
useFrame(() => {
if (bloomRef.current && audioData) {
// Map bass frequency (0-255) to bloom intensity (1-4)
const bassLevel = audioData[0] / 255;
bloomRef.current.intensity = 1 + bassLevel * 3;
// Map mid frequencies to threshold
const midLevel = audioData[4] / 255;
bloomRef.current.luminanceThreshold = 0.1 + (1 - midLevel) * 0.3;
}
});
return (
<EffectComposer>
<Bloom
ref={bloomRef}
luminanceThreshold={0.2}
intensity={1.5}
mipmapBlur
/>
</EffectComposer>
);
}tsx
function AudioReactiveBloom({ audioData }) {
const bloomRef = useRef();
useFrame(() => {
if (bloomRef.current && audioData) {
// 将低音频率(0-255)映射到光晕强度(1-4)
const bassLevel = audioData[0] / 255;
bloomRef.current.intensity = 1 + bassLevel * 3;
// 将中音频率映射到阈值
const midLevel = audioData[4] / 255;
bloomRef.current.luminanceThreshold = 0.1 + (1 - midLevel) * 0.3;
}
});
return (
<EffectComposer>
<Bloom
ref={bloomRef}
luminanceThreshold={0.2}
intensity={1.5}
mipmapBlur
/>
</EffectComposer>
);
}Emissive Materials
自发光材质
Standard Emissive Setup
标准自发光设置
tsx
// For bloom to work, objects need emissive materials
function GlowingSphere({ color = '#00F5FF', intensity = 2 }) {
return (
<mesh>
<sphereGeometry args={[1, 32, 32]} />
<meshStandardMaterial
color="#000"
emissive={color}
emissiveIntensity={intensity}
toneMapped={false} // Important: prevents HDR clamping
/>
</mesh>
);
}tsx
// 要使光晕生效,物体需要使用自发光材质
function GlowingSphere({ color = '#00F5FF', intensity = 2 }) {
return (
<mesh>
<sphereGeometry args={[1, 32, 32]} />
<meshStandardMaterial
color="#000"
emissive={color}
emissiveIntensity={intensity}
toneMapped={false} // 重要:避免HDR颜色被钳制
/>
</mesh>
);
}Emissive with Texture
带纹理的自发光材质
tsx
import { useTexture } from '@react-three/drei';
function EmissiveTextured() {
const emissiveMap = useTexture('/glow-pattern.png');
return (
<mesh>
<planeGeometry args={[2, 2]} />
<meshStandardMaterial
emissiveMap={emissiveMap}
emissive="#FFFFFF"
emissiveIntensity={3}
toneMapped={false}
/>
</mesh>
);
}tsx
import { useTexture } from '@react-three/drei';
function EmissiveTextured() {
const emissiveMap = useTexture('/glow-pattern.png');
return (
<mesh>
<planeGeometry args={[2, 2]} />
<meshStandardMaterial
emissiveMap={emissiveMap}
emissive="#FFFFFF"
emissiveIntensity={3}
toneMapped={false}
/>
</mesh>
);
}Shader Material with Emissive
自定义着色器自发光材质
tsx
import { shaderMaterial } from '@react-three/drei';
import { extend } from '@react-three/fiber';
const GlowMaterial = shaderMaterial(
{ uTime: 0, uColor: [0, 0.96, 1], uIntensity: 2.0 },
// Vertex shader
`
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
// Fragment shader - outputs HDR values for bloom
`
uniform float uTime;
uniform vec3 uColor;
uniform float uIntensity;
varying vec2 vUv;
void main() {
float pulse = sin(uTime * 2.0) * 0.3 + 0.7;
vec3 glow = uColor * uIntensity * pulse;
gl_FragColor = vec4(glow, 1.0);
}
`
);
extend({ GlowMaterial });
function PulsingGlowMesh() {
const materialRef = useRef();
useFrame(({ clock }) => {
materialRef.current.uTime = clock.elapsedTime;
});
return (
<mesh>
<sphereGeometry args={[1, 32, 32]} />
<glowMaterial ref={materialRef} toneMapped={false} />
</mesh>
);
}tsx
import { shaderMaterial } from '@react-three/drei';
import { extend } from '@react-three/fiber';
const GlowMaterial = shaderMaterial(
{ uTime: 0, uColor: [0, 0.96, 1], uIntensity: 2.0 },
// 顶点着色器
`
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
// 片元着色器 - 输出HDR值以支持光晕效果
`
uniform float uTime;
uniform vec3 uColor;
uniform float uIntensity;
varying vec2 vUv;
void main() {
float pulse = sin(uTime * 2.0) * 0.3 + 0.7;
vec3 glow = uColor * uIntensity * pulse;
gl_FragColor = vec4(glow, 1.0);
}
`
);
extend({ GlowMaterial });
function PulsingGlowMesh() {
const materialRef = useRef();
useFrame(({ clock }) => {
materialRef.current.uTime = clock.elapsedTime;
});
return (
<mesh>
<sphereGeometry args={[1, 32, 32]} />
<glowMaterial ref={materialRef} toneMapped={false} />
</mesh>
);
}Performance Optimization
性能优化
Resolution Scaling
分辨率缩放
tsx
<EffectComposer
multisampling={0} // Disable MSAA for performance
>
<Bloom
luminanceThreshold={0.2}
intensity={1.5}
mipmapBlur // More efficient blur method
radius={0.8}
levels={5} // Reduce for performance (default: 8)
/>
</EffectComposer>tsx
<EffectComposer
multisampling={0} // 关闭MSAA以提升性能
>
<Bloom
luminanceThreshold={0.2}
intensity={1.5}
mipmapBlur // 更高效的模糊方式
radius={0.8}
levels={5} // 减少迭代次数以提升性能(默认值:8)
/>
</EffectComposer>Mobile-Optimized Bloom
移动端优化光晕
tsx
import { useDetectGPU } from '@react-three/drei';
function AdaptiveBloom() {
const { tier } = useDetectGPU();
const config = tier < 2
? { levels: 3, radius: 0.5, intensity: 1.0 }
: { levels: 5, radius: 0.8, intensity: 1.5 };
return (
<EffectComposer multisampling={tier < 2 ? 0 : 4}>
<Bloom
luminanceThreshold={0.2}
luminanceSmoothing={0.9}
mipmapBlur
{...config}
/>
</EffectComposer>
);
}tsx
import { useDetectGPU } from '@react-three/drei';
function AdaptiveBloom() {
const { tier } = useDetectGPU();
const config = tier < 2
? { levels: 3, radius: 0.5, intensity: 1.0 }
: { levels: 5, radius: 0.8, intensity: 1.5 };
return (
<EffectComposer multisampling={tier < 2 ? 0 : 4}>
<Bloom
luminanceThreshold={0.2}
luminanceSmoothing={0.9}
mipmapBlur
{...config}
/>
</EffectComposer>
);
}Temporal Collapse Theme
时空坍缩主题效果
Bloom configuration for the New Year countdown cosmic aesthetic:
tsx
// Cosmic void with cyan/magenta glow
function TemporalCollapseBloom() {
return (
<EffectComposer>
<Bloom
luminanceThreshold={0.15}
luminanceSmoothing={0.9}
intensity={2.0}
radius={0.85}
mipmapBlur
/>
</EffectComposer>
);
}
// Color palette for emissive materials
const TEMPORAL_COLORS = {
cyan: '#00F5FF',
magenta: '#FF00FF',
gold: '#FFD700',
void: '#050508'
};
// Time digit with glow
function GlowingDigit({ digit, color = TEMPORAL_COLORS.cyan }) {
return (
<Text3D font="/fonts/cosmic.json" size={2} height={0.2}>
{digit}
<meshStandardMaterial
color="#111"
emissive={color}
emissiveIntensity={3}
toneMapped={false}
/>
</Text3D>
);
}适用于新年倒计时宇宙美学风格的光晕配置:
tsx
// 带有青/品红发光的宇宙虚空效果
function TemporalCollapseBloom() {
return (
<EffectComposer>
<Bloom
luminanceThreshold={0.15}
luminanceSmoothing={0.9}
intensity={2.0}
radius={0.85}
mipmapBlur
/>
</EffectComposer>
);
}
// 自发光材质的调色板
const TEMPORAL_COLORS = {
cyan: '#00F5FF',
magenta: '#FF00FF',
gold: '#FFD700',
void: '#050508'
};
// 带发光效果的时间数字
function GlowingDigit({ digit, color = TEMPORAL_COLORS.cyan }) {
return (
<Text3D font="/fonts/cosmic.json" size={2} height={0.2}>
{digit}
<meshStandardMaterial
color="#111"
emissive={color}
emissiveIntensity={3}
toneMapped={false}
/>
</Text3D>
);
}Troubleshooting
常见问题排查
| Issue | Solution |
|---|---|
| No bloom visible | Ensure |
| Bloom too subtle | Lower |
| Performance issues | Reduce |
| Selective bloom not working | Verify |
| Bloom bleeding everywhere | Raise |
| 问题 | 解决方案 |
|---|---|
| 看不到光晕效果 | 确保 |
| 光晕效果太淡 | 降低 |
| 性能问题 | 减少 |
| 选择性光晕不生效 | 确认已正确传递 |
| 光晕效果扩散到整个画面 | 提高 |
Reference
参考资料
- See for EffectComposer setup patterns
postfx-composer - See for combining bloom with other effects
postfx-effects - See for custom emissive shader techniques
shaders-glsl
- 查看了解EffectComposer的配置模式
postfx-composer - 查看了解光晕与其他特效的组合方式
postfx-effects - 查看了解自定义自发光着色器的实现技巧
shaders-glsl