diff --git a/app/components/cube-boy-dancefloor/CubeBoy.vue b/app/components/cube-boy-dancefloor/CubeBoy.vue new file mode 100644 index 00000000..2a2e5b93 --- /dev/null +++ b/app/components/cube-boy-dancefloor/CubeBoy.vue @@ -0,0 +1,33 @@ + + + diff --git a/app/components/cube-boy-dancefloor/DanceFloor.vue b/app/components/cube-boy-dancefloor/DanceFloor.vue new file mode 100644 index 00000000..3d2a6eef --- /dev/null +++ b/app/components/cube-boy-dancefloor/DanceFloor.vue @@ -0,0 +1,36 @@ + + + \ No newline at end of file diff --git a/app/components/cube-boy-dancefloor/Grid.vue b/app/components/cube-boy-dancefloor/Grid.vue new file mode 100644 index 00000000..33a06bd4 --- /dev/null +++ b/app/components/cube-boy-dancefloor/Grid.vue @@ -0,0 +1,183 @@ + + + diff --git a/app/components/cube-boy-dancefloor/Lighting.vue b/app/components/cube-boy-dancefloor/Lighting.vue new file mode 100644 index 00000000..0a2edf13 --- /dev/null +++ b/app/components/cube-boy-dancefloor/Lighting.vue @@ -0,0 +1,18 @@ + + \ No newline at end of file diff --git a/app/components/cube-boy-dancefloor/MusicPlayer.vue b/app/components/cube-boy-dancefloor/MusicPlayer.vue new file mode 100644 index 00000000..a66bd809 --- /dev/null +++ b/app/components/cube-boy-dancefloor/MusicPlayer.vue @@ -0,0 +1,71 @@ + + + + diff --git a/app/components/cube-boy-dancefloor/index.global.vue b/app/components/cube-boy-dancefloor/index.global.vue new file mode 100644 index 00000000..afa7c1c7 --- /dev/null +++ b/app/components/cube-boy-dancefloor/index.global.vue @@ -0,0 +1,16 @@ + + + \ No newline at end of file diff --git a/app/components/cube-boy-dancefloor/shaderMaterial.ts b/app/components/cube-boy-dancefloor/shaderMaterial.ts new file mode 100644 index 00000000..ec9eff80 --- /dev/null +++ b/app/components/cube-boy-dancefloor/shaderMaterial.ts @@ -0,0 +1,83 @@ +/* +MIT License + +Copyright (c) 2020 react-spring + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import type { Color, CubeTexture, Matrix3, Matrix4, Quaternion, Texture, Vector2, Vector3, Vector4 } from 'three' +import { MathUtils, ShaderMaterial, UniformsUtils } from 'three' + +export function shaderMaterial( + uniforms: { + [name: string]: + | CubeTexture + | Texture + | Int32Array + | Float32Array + | Matrix4 + | Matrix3 + | Quaternion + | Vector4 + | Vector3 + | Vector2 + | Color + | number + | boolean + | Array + | null + }, + vertexShader: string, + fragmentShader: string, + onInit?: (material?: ShaderMaterial) => void, +) { + const material = class extends ShaderMaterial { + public key: string = '' + constructor(parameters = {}) { + const entries = Object.entries(uniforms) + // Create unforms and shaders + super({ + uniforms: entries.reduce((acc, [name, value]) => { + const uniform = UniformsUtils.clone({ [name]: { value } }) + return { + ...acc, + ...uniform, + } + }, {}), + vertexShader, + fragmentShader, + }) + // Create getter/setters + entries.forEach(([name]) => + Object.defineProperty(this, name, { + get: () => this.uniforms[name].value, + set: v => (this.uniforms[name].value = v), + }), + ) + + // Assign parameters, this might include uniforms + Object.assign(this, parameters) + // Call onInit + if (onInit) { onInit(this) } + } + } as unknown as typeof ShaderMaterial & { key: string } + material.key = MathUtils.generateUUID() + return material +} diff --git a/content/experiments/cube-boy-dancefloor.md b/content/experiments/cube-boy-dancefloor.md new file mode 100644 index 00000000..e48c7701 --- /dev/null +++ b/content/experiments/cube-boy-dancefloor.md @@ -0,0 +1,16 @@ +--- +title: Cube Boy Dancefloor +description: A dancing cube character on an animated dancefloor +author: alvarosabu +thumbnail: /experiments/cube-boy-dancefloor.png +date: 2025-09-11 +tags: + - animation + - character + - dancefloor + - cube +--- + +# Cube Boy Dancefloor + +A dancing cube character on an animated dancefloor experiment showcasing character animation and dynamic environments in TresJS. \ No newline at end of file diff --git a/public/experiments/cube-boy-dancefloor.png b/public/experiments/cube-boy-dancefloor.png new file mode 100644 index 00000000..31af47e4 Binary files /dev/null and b/public/experiments/cube-boy-dancefloor.png differ diff --git a/public/models/cube-boy/cube-boy-dance.glb b/public/models/cube-boy/cube-boy-dance.glb new file mode 100644 index 00000000..70a27085 Binary files /dev/null and b/public/models/cube-boy/cube-boy-dance.glb differ diff --git a/public/music/yarin-primak-just-enough.mp3 b/public/music/yarin-primak-just-enough.mp3 new file mode 100644 index 00000000..eb7e5d0e Binary files /dev/null and b/public/music/yarin-primak-just-enough.mp3 differ