视觉音乐从贝拉吉奥斯喷泉中学到什么

音乐与视觉 (Music and Visuals)

The fountains at Bellagio is one of the most famous signature scenes. On a hot summer night, you must be impressed by the massive water beams dancing in the sky, tiny drops from the flying mist may land on your face with a pleasant chill.

贝拉吉奥的喷泉是最著名的标志性场景之一。 在炎热的夏日夜晚,天空中翩翩起舞的光束会给您留下深刻的印象,飞扬的雾气中的细小水滴可能会落在您的脸上,令人不寒而栗。

When Steven Soderbergh remade Ocean’s Eleven, he shot the final scene under this iconic setting. The music happened to be Debussy as well.

当史蒂芬·索德伯格(Steven Soderbergh)重制《海洋十一》时,他在这一标志性场景下拍摄了最后一幕。 音乐碰巧也是德彪西。

Fountains of Bellagio, Ocean’s Eleven final scenes (Steven Soderbergh 2001)
贝拉吉奥的喷泉,海洋的十一个最后场面(Steven Soderbergh 2001)

According to an interview by the Las Vegas Review Journal, there are over 5000 nozzles to shoot water straight up, each with precise timing control. The patterns formed in the air are pre-programmed according to the music. Technically, the music and the water patterns are synchronized and the system is not sound responsive.

根据《 拉斯维加斯评论杂志》的采访有5000多个喷嘴可以直接向上喷射水,每个喷嘴都具有精确的定时控制。 空中形成的模式根据音乐进行预编程。 从技术上讲,音乐和水流模式是同步的,并且系统没有声音响应。

Babylon.js中的粒子系统 (Particle System in Babylon.js)

Babylon.js has a powerful particle system, and it is quite easy to use. Previously, we made a sound responsive structure and particles in space.

Babylon.js具有强大的粒子系统,并且非常易于使用。 以前,我们制作了声音响应结构和空间中的粒子。

Let’s see how we improve by learning from Bellagio’s fountains.

让我们看看如何通过向贝拉吉奥的喷泉学习来改进自己。

We are using a line of spheres as a particle source, this is quite similar to the arrangement of the water nozzles. The water nozzles cannot move, our particle sources can easily move in space.

我们使用球体线作为粒子源,这与水喷嘴的布置非常相似。 水喷嘴不能移动,我们的粒子源可以很容易地在太空中移动。

色彩和谐 (Harmony in Color)

Water blends in the environment well by reflecting, refracting, and bleeds with ambiance. Let’s rewrite the random color for the background clearColor, and also adjust the colors of the particles.

水通过反射,折射和渗出而在环境中很好地融合在一起。 让我们为背景clearColor重写随机颜色,并调整粒子的颜色。

Colors in the particle system are mixed from 2 colors now. We can use the background color for one of the colors, which means that we are mixing colors with the background.

现在,粒子系统中的颜色是从2种颜色混合而成的。 我们可以将背景色用于其中一种颜色,这意味着我们正在将颜色与背景混合。

音乐运动 (Motion with Music)

Bellagio’s performances are tuned according to the rhythms and development of the music. Right now, our center curve shapes are only determined by some oscillators. Let’s introduce some influence from the sound, and we do this by passing the FFT result into curve_points in the Dense2 class.

贝拉吉奥的演奏根据音乐的节奏和发展进行调整。 目前,我们的中心曲线形状仅由某些振荡器确定。 让我们从介绍的声音有一定的影响,我们通过将FFT结果到在Dense2curve_points做到这一点。

颗粒物排放 (Emissions of Particles)

The amount of water going through the nozzles is programmed according to the changes in the music. We can dynamically adjust particles emitRate using the FFT’s results.

根据音乐的变化对通过喷嘴的水量进行编程。 我们可以使用FFT的结果动态调整粒子的erateRate

With these changes, the Dense2 class looks like this.

通过这些更改,Dense2类看起来像这样。

import * as BABYLON from 'babylonjs'


export default class Danse2 {
    private _scene: BABYLON.Scene


    // _t: timer for the accumulated time
    private _t: number


    private _tubes: BABYLON.Mesh[]
    private _balls: BABYLON.Mesh[]
    private _partis: BABYLON.ParticleSystem[]


    private _current: number = 0
    private _n: number = 20
    private _c: BABYLON.Color3 = new BABYLON.Color3(0.3+Math.random()*0.5,0.3+Math.random()*0.5,0.3+Math.random()*0.5)


    constructor(scene: BABYLON.Scene) {
        this._scene = scene
        this._t = 0


        this._tubes = []
        for(let i=0;i<this._n;i++) {
            this.make_tube(this._t, false)
        }
        this._balls = []
        this._partis = []
    }


    curve_points(t: number, fft: number[]): BABYLON.Vector3[] {
        // create 5 points for Catmull Rom curve
        // each point rotate at different speed
        // the shape of the curve is determined by t


        // use fft as the radii
        // divide fft array into 6 sections, throw the highest away, as there is hardly sound there
        let rs = []
        for(let i=0;i<6;i++) {
            rs[i] = 0
            if(fft) {
                for(let j=0;j<fft.length/6;j++) {
                    rs[i] += fft[j]
                }
                rs[i] *= 0.05
            }
        }
        const r1 = rs[0] * Math.cos(t)
        const r2 = rs[1]
        const r3 = rs[2] * Math.sin(t) - rs[2]*0.6
        const r4 = rs[3]
        const r5 = rs[4] * Math.cos(t) - rs[4]*0.4


        let a1 = t * 0.5
        let a2 = t * 2.0
        let a3 = t * 1.5
        let a4 = t * 2.5
        let a5 = t * 0.5


        let p1 = new BABYLON.Vector3(r1*Math.cos(a1),0.5+0.85*Math.cos(t*2)-0.25,r1*Math.sin(a1))
        let p2 = new BABYLON.Vector3(r2*Math.cos(a2),1.0,r2*Math.sin(a2))
        let p3 = new BABYLON.Vector3(r3*Math.cos(a3),1.8,r3*Math.sin(a3))
        let p4 = new BABYLON.Vector3(r4*Math.cos(a4),2.5,r4*Math.sin(a4))
        let p5 = new BABYLON.Vector3(r5*Math.cos(a5),2.8+0.85*Math.cos(t*1.5)-0.25,r5*Math.sin(a5))


        let pts: BABYLON.Vector3[] = [p1,p2,p3,p4,p5]
        return pts
    }


    update(dt: number, fft: number[]) {
        // update according to dt: time delta, i.e., the time has passed
        this._t += dt * 0.00052 
        if(fft) {
            this._t += fft[10] * 0.01
        }


        this.make_tube(this._t, true, fft)


    }


    make_tube(t: number, update: boolean, fft?: number[] ) {
        let cat = BABYLON.Curve3.CreateCatmullRomSpline(
            this.curve_points(t, fft),10,true)
        if(update) {
            this._tubes[this._current] = BABYLON.MeshBuilder.CreateTube("mesh",
            {path:cat.getPoints(),radius:0.01,
            instance:this._tubes[this._current % this._n]})
        } else {
            this._tubes[this._current] = BABYLON.MeshBuilder.CreateTube("mesh",
            {path:cat.getPoints(), radius:0.01, updatable:true}, this._scene)




            let m = new BABYLON.StandardMaterial("mat", this._scene)
            m.diffuseColor = this._c
            this._tubes[this._current].material = m
        }


        if(fft) {
            if(this._balls.length==0) {
                for(let i=0; i<fft.length; i++) {
                    // create balls
                    this._balls.push(
                        BABYLON.MeshBuilder.CreateSphere("ball",{diameter:0.01,segments:4,updatable:true},this._scene)
                    )
                    let parti = new BABYLON.ParticleSystem("parti", 1000, this._scene)
                    parti.emitter = this._balls[i]
                    parti.particleTexture = new BABYLON.Texture("textures/Flare.png", this._scene)
                    parti.minSize = 0.02
                    //parti.maxSize = 0.1


                    //parti.color1 = new BABYLON.Color4(0.7, 0.8, 1.0, 1.0);
                    parti.color1 = BABYLON.Color4.FromColor3(this._c, 0.5)
                    parti.color2 = new BABYLON.Color4(0.2, 0.5, 1.0, 1.0);
                    parti.colorDead = new BABYLON.Color4(0, 0, 0.2, 0.0);




                    // Noise
                    var noiseTexture = new BABYLON.NoiseProceduralTexture("perlin", 256, this._scene);
                    noiseTexture.animationSpeedFactor = 2;
                    noiseTexture.persistence = 0.1;//2
                    noiseTexture.brightness = 0.5;
                    noiseTexture.octaves = 1;


                    parti.noiseTexture = noiseTexture;
                    parti.noiseStrength = new BABYLON.Vector3(10, 10, 10);


                    parti.minEmitPower = 1;
                    parti.maxEmitPower = 3;
                    parti.updateSpeed = 0.003;


                    parti.start()


                    this._partis.push(parti)
                }
            }


            let cat = BABYLON.Curve3.CreateCatmullRomSpline(
                this.curve_points(t, fft),10,false)
            let path3d = new BABYLON.Path3D(cat.getPoints())


            for(let i=0; i<fft.length; i++) {
                let p = path3d.getPointAt( i/fft.length )
                this._balls[i].position = p


                // make higher frequencies more visuable
                this._partis[i].emitRate = fft[i] * 5 * i
                this._partis[i].maxSize = fft[i] * 0.1 


            }


        }


        this._current += 1
    }


}

A recorded clip from the program.

程序中录制的剪辑。

The Github project can be downloaded. Give it a try and see the whole piece in real-time. I encourage you to move the camera to find the best angles.

Github项目可以下载。 试试看,实时查看整个作品。 我建议您移动相机以找到最佳角度。

As you can see, the nuances in the music are not yet there in our result. We’ll need to do more towards a real visual music work. Stay tuned.

如您所见,音乐的细微差别尚未出现。 我们需要为真正的视觉音乐作品做更多的工作。 敬请关注。

This story is part of Making Visual Music in Real-Time. You can read more about it below. Hope you enjoy it.

该故事是“实时制作视觉音乐”的一部分。 您可以在下面阅读有关此内容的更多信息。 希望你喜欢它。

Cheers.

干杯。

普通英语JavaScript (JavaScript In Plain English)

Did you know that we have three publications and a YouTube channel? Find links to everything at plainenglish.io!

您知道我们有三个出版物和一个YouTube频道吗? 在plainenglish.io上找到所有内容的链接!

翻译自: https://medium.com/javascript-in-plain-english/visual-music-what-to-learn-from-bellagios-fountains-8ec4f41a2017

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值