1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

音声ビジュアライザーを作るとき、パーティクルだけでなく、ワイヤーフレームメッシュもかなり相性がよいです。

音量に合わせてメッシュが膨らみ、低域で強く反応し、中域や高域でゆっくり回転すると、それだけで音に反応している感じが出ます。

今回は React Three Fiber を使って、音に反応するワイヤーフレームメッシュを作ります。

作るもの

音声解析で取得した以下の値を使います。

type AudioFeatures = {
  volume: number
  bass: number
  mids: number
  highs: number
  waveform: Float32Array
}

この値を使って、メッシュの以下を変化させます。

volume: 全体のスケール
bass: 低域による強い膨張
mids: ゆっくりした回転
highs: 細かい回転や発光

基本のメッシュ

まずは React Three Fiber でメッシュを表示します。

import { useRef } from 'react'
import { useFrame } from '@react-three/fiber'
import * as THREE from 'three'

type AudioFeatures = {
  volume: number
  bass: number
  mids: number
  highs: number
  waveform: Float32Array
}

type ReactiveMeshProps = {
  featuresRef: React.MutableRefObject<AudioFeatures>
}

export function ReactiveMesh({ featuresRef }: ReactiveMeshProps) {
  const meshRef = useRef<THREE.Mesh>(null)

  return (
    <mesh ref={meshRef}>
      <icosahedronGeometry args={[1.6, 3]} />
      <meshStandardMaterial wireframe />
    </mesh>
  )
}

ここでは icosahedronGeometry を使っています。

wireframe を true にすると、立体の線だけが表示されます。

useFrameで毎フレーム更新する

音に反応させるには、useFrame の中でメッシュを更新します。

useFrame(() => {
  const mesh = meshRef.current

  if (!mesh) {
    return
  }

  const { volume, bass, mids, highs } = featuresRef.current

  const scale = 1 + volume * 0.3 + bass * 0.45

  mesh.scale.lerp(
    new THREE.Vector3(scale, scale, scale),
    0.12
  )

  mesh.rotation.x += 0.003 + mids * 0.01
  mesh.rotation.y += 0.004 + highs * 0.008
})

volumebass でスケールを変えています。

midshighs は回転に使っています。

lerpで急な変化をなめらかにする

音声解析値は急に変化することがあります。

その値をそのままスケールに使うと、見た目がガタガタする場合があります。

そこで lerp を使っています。

mesh.scale.lerp(
  new THREE.Vector3(scale, scale, scale),
  0.12
)

lerp を使うと、現在の値から目標値に少しずつ近づきます。

音声ビジュアライザーでは、急激すぎる反応を少し抑えると見やすくなります。

色や発光も音に合わせる

マテリアルの色や発光も音に合わせられます。

const material = mesh.material as THREE.MeshStandardMaterial

material.emissiveIntensity = 0.2 + highs * 1.5

highs は細かい音に反応しやすいので、発光感に使うと分かりやすいです。

ただし、強くしすぎると画面がうるさくなるので、少し控えめにするのが扱いやすいです。

完成形

まとめると、以下のようなコンポーネントになります。

import { useRef } from 'react'
import { useFrame } from '@react-three/fiber'
import * as THREE from 'three'

type AudioFeatures = {
  volume: number
  bass: number
  mids: number
  highs: number
  waveform: Float32Array
}

type ReactiveMeshProps = {
  featuresRef: React.MutableRefObject<AudioFeatures>
}

export function ReactiveMesh({ featuresRef }: ReactiveMeshProps) {
  const meshRef = useRef<THREE.Mesh>(null)
  const targetScale = new THREE.Vector3()

  useFrame(() => {
    const mesh = meshRef.current

    if (!mesh) {
      return
    }

    const { volume, bass, mids, highs } = featuresRef.current

    const scale = 1 + volume * 0.3 + bass * 0.45

    targetScale.set(scale, scale, scale)
    mesh.scale.lerp(targetScale, 0.12)

    mesh.rotation.x += 0.003 + mids * 0.01
    mesh.rotation.y += 0.004 + highs * 0.008

    const material = mesh.material as THREE.MeshStandardMaterial
    material.emissiveIntensity = 0.15 + highs * 1.2
  })

  return (
    <mesh ref={meshRef}>
      <icosahedronGeometry args={[1.6, 3]} />
      <meshStandardMaterial
        wireframe
        emissive="#ffffff"
        emissiveIntensity={0.2}
      />
    </mesh>
  )
}

音の役割を見た目に割り当てる

ビジュアライザーでは、音の特徴量ごとに見た目の役割を分けると調整しやすいです。

volume:
  全体の大きさ

bass:
  低域の衝撃、膨張

mids:
  流れ、回転、うねり

highs:
  細かい揺れ、発光、ちらつき

全部の値を全部の表現に使うと、何が何に反応しているのか分かりづらくなります。

役割を分けることで、音楽的に見えやすくなります。

派手にしすぎない

音声ビジュアライザーは、係数を上げればすぐ派手になります。

const scale = 1 + bass * 2

ただ、派手にしすぎると、常に大きく動いてしまい、逆に音楽の変化が見えづらくなります。

最初は小さめの値から調整した方がよいです。

const scale = 1 + volume * 0.3 + bass * 0.45

音のピークで少し大きく動くくらいの方が、見ていて疲れにくいです。

まとめ

React Three Fiberを使うと、音声解析値を使って3Dメッシュを簡単に動かせます。

今回作ったワイヤーフレームメッシュでは、

  • volumeで全体のスケール
  • bassで低域の膨張
  • midsで回転
  • highsで細かい動きや発光

を制御しました。

音に反応する3D表現を作るときは、まずシンプルなメッシュから始めると調整しやすいです。

パーティクルやシェーダーに進む前の最初のビジュアライザーとして、ワイヤーフレームメッシュはかなり扱いやすいと思いました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?