概述
这是一个很常见需求,游戏场景中往往需要展现炫酷的霓虹灯,各种led灯,或需要光照渲染氛围的朦胧光效。
材质发光
three中的材质可分为自发光材质和不发光材质,发光材质即使在没有光的场景中依然清晰可见(需要设置发光的颜色如果是黑色依然不可见),而不发光材质在无光时是一片黑色。
react-three中常见的发光材质是MeshBasicMaterial和MeshStandardMaterial
<mesh>
<boxGeometry args={[2, 2, 2]} />
<meshBasicMaterial color="white" emissive="orange" emissiveIntensity={1} />
</mesh>
上面的代码实现了一个发出黄色光的白球,黄光强度是1。
你也可以加载模型直接修改模型的发光效果和材质。
const { scene, nodes } = useGLTF(path);
useLayoutEffect(() => {
scene.traverse((obj) => {
if (obj instanceof Mesh) {
obj.material.emissive = 'white'
obj.material.emissiveIntensity=10
}
});
}, [scene, map]);
光晕效果
<Billboard>组件:
Billboard是@react-three/drei的组件 ,它可以将物体始终面向相机。这对实现发光效果很重要,我们不需要构建一个三维的发光体,只需要构建一个二维的发光体,让它一直朝着镜头。这样确保用户总能看到发光效果。
<LayerMaterial> 材质体:
LayerMaterial是一种多层材质,通过叠加不同的Depth层来实现发光效果。这个材质设置了:transparent: true:使材质具有透明效果。depthWrite: false:禁止深度写入,这样材质不会影响深度缓冲,可以避免深度遮挡,确保发光效果在其他物体之前渲染。- 自定义
blending(混合模式):使用THREE.CustomBlending和blendEquation、blendSrc、blendDst设置来控制如何将每个层的颜色叠加在一起。这些设置确保不同层的颜色和透明度能混合在一起,产生柔和的发光效果。
<Depth> 层:
Depth是一种可以实现深度渐变的材质,通常用于模拟光的散射效果。这里每个Depth层代表一种发光的深度效果,通过colorA和colorB控制颜色的渐变,alpha控制透明度。- 每个
Depth层的属性设置有所不同,组合起来可以产生分散的发光效果。 - 参数解读:
colorA和colorB:用于控制发光颜色的渐变,例如从colorA到colorB的渐变,其中colorB被设置为黑色以营造出从明亮到暗淡的效果。alpha:控制透明度,让光晕效果更柔和。mode:混合模式,如normal和add。near和far:控制每一层的深度范围。不同层的near和far设置产生不同的层次效果,使光晕看起来更自然
const Glow = ({ color, scale = 0.5, near = -2, far = 1.4 }) => (
<Billboard>
<mesh>
<circleGeometry args={[2 * scale, 16]} />
<LayerMaterial
transparent
depthWrite={false}
blending={THREE.CustomBlending}
blendEquation={THREE.AddEquation}
blendSrc={THREE.SrcAlphaFactor}
blendDst={THREE.DstAlphaFactor}>
<Depth colorA={color} colorB="black" alpha={1} mode="normal" near={near * scale} far={far * scale} origin={[0, 0, 0]} />
<Depth colorA={color} colorB="black" alpha={0.5} mode="add" near={-40 * scale} far={far * 1.2 * scale} origin={[0, 0, 0]} />
<Depth colorA={color} colorB="black" alpha={1} mode="add" near={-15 * scale} far={far * 0.7 * scale} origin={[0, 0, 0]} />
<Depth colorA={color} colorB="black" alpha={1} mode="add" near={-10 * scale} far={far * 0.68 * scale} origin={[0, 0, 0]} />
</LayerMaterial>
</mesh>
</Billboard>
)
点光源
在场景中添加一个点光源,它会照亮周围,它是不可见的但可以看到周围被照亮的物体。当它与后处理的光晕效果结合时表现力更强。
<pointLight ref={light} intensity={1} color={[10, 2, 5]} distance={2.5} />
后处理
光晕效果
这应该是最简单的实现了,只需要添加上后处理效果的绽光组件Bloom就可以实现。
它会极大的加强光线的表现力,让光照更有层次,有晕染开的效果。
<EffectComposer>
<Bloom luminanceThreshold={2} mipmapBlur />
<ToneMapping />
</EffectComposer>
比起前面Billboard组件实现的Glow,它更加简单自然。但是性能消耗也大。
关于Bloom效果具体参数参见官方文档
上帝射线
顾名思义,上帝登场时一定从天际投射出一道光线照在他身上,以此来表现祂宗教上的神性。
GodRays组件从某个物体上投射出一道光线,可以设置其曝光程度,和衰减速率。
核心代码如下:
import { EffectComposer, GodRays } from '@react-three/postprocessing'
function Screen() {
const [material, set] = useState()
return (
<>
<Emitter ref={set} />
{material && (
<EffectComposer disableNormalPass multisampling={8}>
<GodRays sun={material} exposure={0.34} decay={0.8} blur />
<Bloom luminanceThreshold={0} mipmapBlur luminanceSmoothing={0.0} intensity={1} />
</EffectComposer>
)}
</>
)
}