Skip to content

Commit

Permalink
Fix uniforms not updating
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminpreiss committed Jul 28, 2022
1 parent 7fa94e8 commit 321942f
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 30 deletions.
49 changes: 23 additions & 26 deletions components/Particles/Particles.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@

import { useMemo, useRef, useState, useEffect } from 'react'
import { FloatType, RGBAFormat, DataTexture, NearestFilter, Vector3, ShaderMaterial, MathUtils, Scene, OrthographicCamera, NormalBlending } from 'three'
import { useFrame, extend } from '@react-three/fiber'
import { useMemo, useRef, useState } from 'react'
import { FloatType, RGBAFormat, DataTexture, NearestFilter, Vector4, ShaderMaterial, MathUtils, Scene, OrthographicCamera, NormalBlending } from 'three'
import { useFrame, extend, createPortal } from '@react-three/fiber'
import { useFBO } from '@react-three/drei'
import dofVertex from '../../shaders/sim-dot/vertex.glsl'
import dofFragment from '../../shaders/sim-dot/fragment.glsl'
import simVertex from '../../shaders/dof-dot/vertex.glsl'
import simFragment from '../../shaders/dof-dot/fragment.glsl'
import simVertex from '../../shaders/sim-dot/vertex.glsl'
import simFragment from '../../shaders/sim-dot/fragment.glsl'
import dofVertex from '../../shaders/dof-dot/vertex.glsl'
import dofFragment from '../../shaders/dof-dot/fragment.glsl'
import '../../materials/dofPointsMaterial'
import '../../materials/simulationMaterial'

function getPoint(v:Vector3, size:number, data: Float32Array, offset: number): ArrayLike<number> {
v.set(Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1)
extend({ShaderMaterial})

function getPoint(v:Vector4, size:number, data: Float32Array, offset: number): ArrayLike<number> {
v.set(Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1, 0)
if (v.length() > 1) return getPoint(v, size, data, offset)
return v.normalize().multiplyScalar(size).toArray(data, offset)
}

function getSphere(count: number, size: number, p = new Vector3()) {
const data = new Float32Array(count * 3)
for (let i = 0; i < count * 3; i += 3) getPoint(p, size, data, i)
return data
function getSphere(count:number, size:number, p = new Vector4()) {
const data = new Float32Array(count * 4)
for (let i = 0; i < count * 4; i += 4) getPoint(p, size, data, i)
return data
}

export default function Particles({ speed, fov, aperture, focus, curl, size = 512, ...props}: {speed: number, fov: number, aperture: number, focus: number, curl:number, size:number}) {
Expand Down Expand Up @@ -69,27 +73,20 @@ export default function Particles({ speed, fov, aperture, focus, curl, size = 51
return (
<>
{/* Simulation goes into a FBO/Off-buffer */}
{createPortal(
<mesh>
<shaderMaterial ref={simRef} vertexShader={dofVertex} fragmentShader={dofFragment} uniforms={{
positions: { value: texture },
uTime: { value: 0 },
uCurlFreq: { value: 0.25 }
}} />
<simulationMaterial ref={simRef} />
<bufferGeometry>
<bufferAttribute attach="attributes-position" count={positions.length / 3} array={positions} itemSize={3} />
<bufferAttribute attach="attributes-uv" count={uvs.length / 2} array={uvs} itemSize={2} />
</bufferGeometry>
</mesh>
</mesh>,
scene
)}
{/* The result of which is forwarded into a pointcloud via data-texture */}
<points {...props}>

<shaderMaterial ref={renderRef} vertexShader={simVertex} fragmentShader={simFragment} transparent={true} blending={NormalBlending} depthWrite={false} uniforms={{
positions: { value: null },
uTime: { value: 0 },
uFocus: { value: 5.1 },
uFov: { value: 50 },
uBlur: { value: 30 }
}} />
<dofPointsMaterial ref={renderRef} />
<bufferGeometry>
<bufferAttribute attach="attributes-position" count={particles.length / 3} array={particles} itemSize={3} />
</bufferGeometry>
Expand Down
25 changes: 25 additions & 0 deletions materials/dofPointsMaterial.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { extend } from '@react-three/fiber'
import { ShaderMaterial, NormalBlending } from 'three'
import dofVertex from '../shaders/dof-dot/vertex.glsl'
import dofFragment from '../shaders/dof-dot/fragment.glsl'

class DofPointsMaterial extends ShaderMaterial {
constructor() {
super({
vertexShader: dofVertex,
fragmentShader: dofFragment,
uniforms: {
positions: { value: null },
uTime: { value: 0 },
uFocus: { value: 5.1 },
uFov: { value: 50 },
uBlur: { value: 30 }
},
transparent: true,
blending: NormalBlending,
depthWrite: false
})
}
}

extend({ DofPointsMaterial })
35 changes: 35 additions & 0 deletions materials/simulationMaterial.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { extend } from '@react-three/fiber'
import { Vector4, ShaderMaterial, DataTexture, RGBAFormat, FloatType } from 'three'
import simVertex from '../shaders/sim-dot/vertex.glsl'
import simFragment from '../shaders/sim-dot/fragment.glsl'

function getPoint(v:Vector4, size:number, data: Float32Array, offset: number): ArrayLike<number> {
v.set(Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1, 0)
if (v.length() > 1) return getPoint(v, size, data, offset)
return v.normalize().multiplyScalar(size).toArray(data, offset)
}

function getSphere(count:number, size:number, p = new Vector4()) {
const data = new Float32Array(count * 4)
for (let i = 0; i < count * 4; i += 4) getPoint(p, size, data, i)
return data
}

class SimulationMaterial extends ShaderMaterial {
constructor() {
const positionsTexture = new DataTexture(getSphere(512 * 512, 128), 512, 512, RGBAFormat, FloatType)
positionsTexture.needsUpdate = true

super({
vertexShader: simVertex,
fragmentShader: simFragment,
uniforms: {
positions: { value: positionsTexture },
uTime: { value: 0 },
uCurlFreq: { value: 0.25 }
}
})
}
}

extend({ SimulationMaterial })
2 changes: 1 addition & 1 deletion pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const Home: NextPage = () => {
size: 512
})
return (
<div className='fixed inset-0 z-10'>
<div className='fixed inset-0 z-10 bg-black'>
<Canvas linear={true} camera={{position: [0,0,6], fov:25}}>
<OrbitControls makeDefault autoRotate autoRotateSpeed={0.5} zoomSpeed={0.1} />
<CameraShake yawFrequency={1} maxYaw={0.05} pitchFrequency={1} maxPitch={0.05} rollFrequency={0.5} maxRoll={0.5} intensity={0.2} />
Expand Down
2 changes: 1 addition & 1 deletion shaders/dof-dot/vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ uniform float uFov;
uniform float uBlur;
varying float vDistance;
void main() {
vec3 pos = texture2D(positions, position.xy).xyz;
vec3 pos = texture(positions, position.xy).xyz;
vec4 mvPosition = modelViewMatrix * vec4(pos, 1.0);
gl_Position = projectionMatrix * mvPosition;
vDistance = abs(uFocus - -mvPosition.z);
Expand Down
4 changes: 2 additions & 2 deletions shaders/sim-dot/fragment.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ varying vec2 vUv;
#pragma glslify: noise = require(glsl-noise/classic/3d.glsl)
void main() {
float t = uTime * 0.015;
vec3 pos = texture2D(positions, vUv).rgb; // basic simulation: displays the particles in place.
vec3 curlPos = texture2D(positions, vUv).rgb;
vec3 pos = texture(positions, vUv).rgb; // basic simulation: displays the particles in place.
vec3 curlPos = texture(positions, vUv).rgb;
pos = curl(pos * uCurlFreq + t);
curlPos = curl(curlPos * uCurlFreq + t);
curlPos += curl(curlPos * uCurlFreq * 2.0) * 0.5;
Expand Down

0 comments on commit 321942f

Please sign in to comment.