mtx*_*mtx 6 three.js reactjs react-spring react-three-fiber
我有带有自定义着色器和缓冲区几何形状的简单点网格。
几何图形具有位置、大小和颜色属性。指针悬停时,悬停的顶点会变成红色。
到目前为止,一切都很好。
现在我想为悬停顶点的颜色变化设置动画。
以下是点网格的代码片段:
const Points = (
props = { hoveredIndex: null, initialCameraZ: 0, array: [], sizes: [] }
) => {
const [_, setHover] = useState(false);
const vertices = new Float32Array(props.array);
const sizes = new Float32Array(props.sizes);
const _colors = genColors(props.sizes.length); // returns [] of numbers.
const uniforms = useMemo(() => {
return {
time: { type: "f", value: 0.0 },
cameraZ: { type: "f", value: props.initialCameraZ }
};
}, [props.initialCameraZ]);
// trying to use react-spring here
const [animProps, setAnimProps] = useSpring(() => ({
colors: _colors
}));
const geometry = useUpdate(
(geo) => {
if (props.hoveredIndex !== null) {
const i = props.hoveredIndex * 3;
const cols = [..._colors];
cols[i] = 1.0;
cols[i + 1] = 0.0;
cols[i + 2] = 0.0;
geo.setAttribute(
"color",
new THREE.BufferAttribute(new Float32Array(cols), 3)
);
setAnimProps({ colors: cols });
} else {
geo.setAttribute(
"color",
new THREE.BufferAttribute(new Float32Array(_colors), 3)
);
setAnimProps({ colors: _colors });
}
},
[props.hoveredIndex]
);
return (
<a.points
onPointerOver={(e) => setHover(true)}
onPointerOut={(e) => setHover(false)}
>
<a.bufferGeometry attach="geometry" ref={geometry}>
<bufferAttribute
attachObject={["attributes", "position"]}
count={vertices.length / 3}
array={vertices}
itemSize={3}
/>
<bufferAttribute
attachObject={["attributes", "size"]}
count={sizes.length}
array={sizes}
itemSize={1}
/>
<a.bufferAttribute
attachObject={["attributes", "color"]}
count={_colors.length}
array={new Float32Array(_colors)}
// array={animProps.colors} // this does not work
itemSize={3}
/>
</a.bufferGeometry>
<shaderMaterial
attach="material"
uniforms={uniforms}
vertexShader={PointsShader.vertexShader}
fragmentShader={PointsShader.fragmentShader}
vertexColors={true}
/>
</a.points>
);
};
Run Code Online (Sandbox Code Playgroud)
当我尝试animProps.colors在 bufferAttribute 中使用颜色时,它无法更改颜色。
我究竟做错了什么?怎样做才对呢?
我知道我可以创建开始和目标颜色属性,将它们传递给着色器并在那里进行插值,但这会超出使用反应三纤维的目的。
有没有办法在反应三纤维中动画缓冲区属性?
这可能无法按预期工作,因为需要显式标记对缓冲区属性所做的更改才能发送到 GPU。我想这react-spring并不是开箱即用的。
这是一个普通示例,请注意 的用法needsUpdate:
import { useFrame } from '@react-three/fiber'
import React, { useRef } from 'react'
import { BufferAttribute, DoubleSide } from 'three'
const positions = new Float32Array([
1, 0, 0,
0, 1, 0,
-1, 0, 0,
0, -1, 0
])
const indices = new Uint16Array([
0, 1, 3,
2, 3, 1,
])
const Comp = () => {
const positionsRef = useRef<BufferAttribute>(null)
useFrame(() => {
const x = 1 + Math.sin(performance.now() * 0.01) * 0.5
positionsRef.current.array[0] = x
positionsRef.current.needsUpdate = true
})
return <mesh>
<bufferGeometry>
<bufferAttribute
ref={positionsRef}
attach='attributes-position'
array={positions}
count={positions.length / 3}
itemSize={3}
/>
<bufferAttribute
attach="index"
array={indices}
count={indices.length}
itemSize={1}
/>
</bufferGeometry>
<meshBasicMaterial
color={[0, 1, 1]}
side={DoubleSide}
/>
</mesh>
}
Run Code Online (Sandbox Code Playgroud)
如需进一步阅读,请查看本教程。
| 归档时间: |
|
| 查看次数: |
2008 次 |
| 最近记录: |