Skip to content

Commit 943a37e

Browse files
authored
Merge pull request #3738 from pmndrs:chore/simplify-shadermaterial-demo
chore: Simplify ShaderMaterial demo v2
2 parents 877c839 + 1be9504 commit 943a37e

2 files changed

Lines changed: 32 additions & 6 deletions

File tree

example/src/demos/ShaderMaterial.tsx

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Canvas, useFrame } from '@react-three/fiber'
2-
import { useMemo, useRef } from 'react'
2+
import { useMemo, useRef, useState } from 'react'
33
import * as THREE from 'three'
44

55
const vertexShader = `
@@ -18,26 +18,38 @@ void main() {
1818

1919
const fragmentShader = `
2020
uniform float uTime;
21+
uniform vec3 uColor;
2122
varying vec2 vUv;
2223
2324
void main() {
24-
vec3 color = 0.5 + 0.5 * cos(uTime + vUv.xyx + vec3(0.0, 2.0, 4.0));
25-
gl_FragColor = vec4(color, 1.0);
25+
vec3 rainbow = 0.5 + 0.5 * cos(uTime + vUv.xyx + vec3(0.0, 2.0, 4.0));
26+
gl_FragColor = vec4(mix(rainbow, uColor, 0.6), 1.0);
2627
}
2728
`
2829

2930
function Plane() {
3031
const material = useRef<THREE.ShaderMaterial>(null!)
31-
const uniforms = useMemo(() => ({ uTime: { value: 0 } }), [])
32+
const [hovered, setHovered] = useState(false)
3233

3334
useFrame(({ clock }) => {
3435
material.current.uniforms.uTime.value = clock.elapsedTime
3536
})
3637

3738
return (
38-
<mesh>
39+
<mesh onPointerOver={() => setHovered(true)} onPointerOut={() => setHovered(false)}>
3940
<planeGeometry args={[2, 2, 64, 64]} />
40-
<shaderMaterial ref={material} uniforms={uniforms} vertexShader={vertexShader} fragmentShader={fragmentShader} />
41+
<shaderMaterial
42+
ref={material}
43+
// The uniforms object has a stable reference so objects can be safely merged in
44+
uniforms={{
45+
uTime: { value: 0 },
46+
uColor: { value: new THREE.Color('hotpink') },
47+
}}
48+
// Individual uniforms can also be safely updated with pierce notation
49+
uniforms-uColor-value={hovered ? 'royalblue' : 'hotpink'}
50+
vertexShader={vertexShader}
51+
fragmentShader={fragmentShader}
52+
/>
4153
</mesh>
4254
)
4355
}

packages/fiber/tests/utils.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,20 @@ describe('applyProps', () => {
430430
expect(material.uniforms.resolution.value.toArray()).toStrictEqual([4, 8])
431431
})
432432

433+
it('should merge pierced uniform props into stable shader uniforms', () => {
434+
const material = new THREE.ShaderMaterial({
435+
uniforms: { uColor: { value: new THREE.Color('hotpink') } },
436+
})
437+
const uniforms = material.uniforms
438+
const uColor = material.uniforms.uColor
439+
440+
applyProps(material, { 'uniforms-uColor-value': 'royalblue' })
441+
442+
expect(material.uniforms).toBe(uniforms)
443+
expect(material.uniforms.uColor).toBe(uColor)
444+
expect((material.uniforms.uColor.value as THREE.Color).getHex()).toBe(new THREE.Color('royalblue').getHex())
445+
})
446+
433447
it('should prefer to copy potentially read-only math classes', () => {
434448
const one = new THREE.Vector3(1, 1, 1)
435449
const two = new THREE.Vector3(2, 2, 2)

0 commit comments

Comments
 (0)