Skip to content

Commit 3823ad8

Browse files
authored
feat: introduce MeshWobbleMaterial (#63)
This PR introduces `MeshWobbleMaterial` - Add `MeshWobbleMaterial` and its story - Adjust `MeshDistortMaterial` to expose a parameters interface
1 parent 1b08c0c commit 3823ad8

File tree

6 files changed

+160
-8
lines changed

6 files changed

+160
-8
lines changed

.storybook/stories/MeshDistortMaterial.stories.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,7 @@ export const MDMStory = async () => {
4444

4545
async function setupMeshDistortMaterial() {
4646
const geometry = new THREE.SphereGeometry(1, 32, 32)
47-
meshDistortMaterial = new MeshDistortMaterial({ color: '#f25042' })
48-
49-
meshDistortMaterial._radius.value = 0.2
47+
meshDistortMaterial = new MeshDistortMaterial({ color: '#f25042', radius: 0.2 })
5048

5149
const mesh = new THREE.Mesh(geometry, meshDistortMaterial)
5250
mesh.scale.set(2, 4, 1)
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import * as THREE from 'three'
2+
import { Setup } from '../Setup'
3+
import GUI from 'lil-gui'
4+
import { Meta } from '@storybook/html'
5+
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
6+
import { MeshWobbleMaterial } from '../../src/materials/MeshWobbleMaterial'
7+
8+
export default {
9+
title: 'Shaders/MeshWobbleMaterial',
10+
} as Meta // TODO: this should be `satisfies Meta` but commit hooks lag behind TS
11+
12+
let gui: GUI, materialGuiFolder: GUI
13+
let scene: THREE.Scene,
14+
camera: THREE.PerspectiveCamera,
15+
renderer: THREE.WebGLRenderer,
16+
animateLoop: (arg0: (time: number) => void) => void,
17+
meshWobbleMaterial: MeshWobbleMaterial
18+
19+
export const MWMStory = async () => {
20+
const setupResult = Setup()
21+
scene = setupResult.scene
22+
camera = setupResult.camera
23+
renderer = setupResult.renderer
24+
animateLoop = setupResult.render
25+
26+
gui = new GUI({ title: MWMStory.storyName })
27+
camera.position.set(0, 0, 5)
28+
29+
const controls = new OrbitControls(camera, renderer.domElement)
30+
controls.update()
31+
32+
const ambientLight = new THREE.AmbientLight()
33+
scene.add(ambientLight)
34+
35+
const dirLight = new THREE.DirectionalLight(0xabcdef, 10)
36+
dirLight.position.set(1, 20, 1)
37+
dirLight.castShadow = true
38+
dirLight.shadow.mapSize.width = 1024
39+
dirLight.shadow.mapSize.height = 1024
40+
scene.add(dirLight)
41+
42+
setupMeshWobbleMaterial()
43+
}
44+
45+
async function setupMeshWobbleMaterial() {
46+
const geometry = new THREE.TorusGeometry(1, 0.25, 16, 100)
47+
meshWobbleMaterial = new MeshWobbleMaterial({ color: '#f25042', factor: 0.75 })
48+
49+
const mesh = new THREE.Mesh(geometry, meshWobbleMaterial)
50+
51+
scene.add(mesh)
52+
53+
createMeshWobbleGUI()
54+
55+
animateLoop((time) => {
56+
meshWobbleMaterial.time = time * 0.0025
57+
})
58+
}
59+
60+
/**
61+
* Create gui for material properties
62+
*/
63+
function createMeshWobbleGUI() {
64+
if (materialGuiFolder) {
65+
materialGuiFolder.destroy()
66+
}
67+
68+
const matProps = gui.addFolder('MeshWobbleMaterial id: ' + meshWobbleMaterial.id)
69+
70+
matProps.addColor(meshWobbleMaterial, 'color')
71+
matProps.add(meshWobbleMaterial._factor, 'value').min(0.5).max(4).step(0.1).name('factor')
72+
73+
materialGuiFolder = matProps
74+
}
75+
76+
MWMStory.storyName = 'Torus'

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import { pcss, ... } from '@pmndrs/vanilla'
4343
<li><a href="#shadermaterial">shaderMaterial</a></li>
4444
<li><a href="#discardmaterial">MeshDiscardMaterial</a></li>
4545
<li><a href="#meshdistortmaterial">MeshDistortMaterial</a></li>
46+
<li><a href="#meshwobblematerial">MeshWobbleMaterial</a></li>
4647
<li><a href="#meshtransmissionmaterial">MeshTransmissionMaterial</a></li>
4748
<li><a href="#spotlight">SpotLight</a></li>
4849
</ul>
@@ -185,14 +186,20 @@ const mesh = new THREE.Mesh(geometry, new MeshDiscardMaterial())
185186

186187
#### MeshDistortMaterial
187188

188-
[![storybook](https://img.shields.io/badge/-storybook-%23ff69b4)](https://pmndrs.github.io/drei-vanilla/?path=/story/shaders-meshtransmissionmaterial--mdm-story)
189+
[![storybook](https://img.shields.io/badge/-storybook-%23ff69b4)](https://pmndrs.github.io/drei-vanilla/?path=/story/shaders-meshdistortmaterial--mdm-story)
189190

190191
<p>
191192
<a href="https://codesandbox.io/s/l03yb"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/l03yb/screenshot.png" alt="Demo"/></a>
192193
</p>
193194

194195
This material makes your geometry distort following simplex noise.
195196

197+
#### MeshWobbleMaterial
198+
199+
[![storybook](https://img.shields.io/badge/-storybook-%23ff69b4)](https://pmndrs.github.io/drei-vanilla/?path=/story/shaders-meshwobblematerial--mwm-story)
200+
201+
This material makes your geometry wobble and wave around. It was taken from the [threejs-examples](https://threejs.org/examples/#webgl_materials_modified) and adapted into a self-contained material.
202+
196203
#### MeshTransmissionMaterial
197204

198205
[![storybook](https://img.shields.io/badge/-storybook-%23ff69b4)](https://pmndrs.github.io/drei-vanilla/?path=/story/shaders-meshtransmissionmaterial--mtm-story)

src/materials/MeshDistortMaterial.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,28 @@ import { IUniform, MeshPhysicalMaterial, MeshPhysicalMaterialParameters } from '
22
// @ts-ignore
33
import distort from '../helpers/glsl/distort.vert.glsl'
44

5+
export interface MeshDistortMaterialParameters {
6+
time?: number
7+
distort?: number
8+
radius?: number
9+
}
10+
511
export class MeshDistortMaterial extends MeshPhysicalMaterial {
612
_time: IUniform<number>
713
_distort: IUniform<number>
814
_radius: IUniform<number>
915

10-
constructor(parameters: MeshPhysicalMaterialParameters = {}) {
16+
constructor({
17+
time = 0,
18+
distort = 0.4,
19+
radius = 1,
20+
...parameters
21+
}: MeshDistortMaterialParameters & MeshPhysicalMaterialParameters = {}) {
1122
super(parameters)
1223
this.setValues(parameters)
13-
this._time = { value: 0 }
14-
this._distort = { value: 0.4 }
15-
this._radius = { value: 1 }
24+
this._time = { value: time }
25+
this._distort = { value: distort }
26+
this._radius = { value: radius }
1627
}
1728

1829
// FIXME Use `THREE.WebGLProgramParametersWithUniforms` type when able to target @types/[email protected]

src/materials/MeshWobbleMaterial.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { IUniform, MeshStandardMaterial, MeshStandardMaterialParameters } from 'three'
2+
3+
export interface MeshWobbleMaterialParameters {
4+
time?: number
5+
factor?: number
6+
}
7+
8+
export class MeshWobbleMaterial extends MeshStandardMaterial {
9+
_time: IUniform<number>
10+
_factor: IUniform<number>
11+
12+
constructor({
13+
time = 0,
14+
factor = 1,
15+
...parameters
16+
}: MeshStandardMaterialParameters & MeshWobbleMaterialParameters = {}) {
17+
super(parameters)
18+
this.setValues(parameters)
19+
this._time = { value: time }
20+
this._factor = { value: factor }
21+
}
22+
23+
// FIXME Use `THREE.WebGLProgramParametersWithUniforms` type when able to target @types/[email protected]
24+
override onBeforeCompile(shader: { vertexShader: string; uniforms: { [uniform: string]: IUniform } }) {
25+
shader.uniforms['time'] = this._time
26+
shader.uniforms['factor'] = this._factor
27+
28+
shader.vertexShader = `
29+
uniform float time;
30+
uniform float factor;
31+
${shader.vertexShader}
32+
`
33+
shader.vertexShader = shader.vertexShader.replace(
34+
'#include <begin_vertex>',
35+
`float theta = sin( time + position.y ) / 2.0 * factor;
36+
float c = cos( theta );
37+
float s = sin( theta );
38+
mat3 m = mat3( c, 0, s, 0, 1, 0, -s, 0, c );
39+
vec3 transformed = vec3( position ) * m;
40+
vNormal = vNormal * m;`
41+
)
42+
}
43+
44+
get time() {
45+
return this._time.value
46+
}
47+
48+
set time(v) {
49+
this._time.value = v
50+
}
51+
52+
get factor() {
53+
return this._factor.value
54+
}
55+
56+
set factor(v) {
57+
this._factor.value = v
58+
}
59+
}

src/materials/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ export * from './BlurPass'
55
export * from './ConvolutionMaterial'
66
export * from './MeshReflectorMaterial'
77
export * from './MeshDistortMaterial'
8+
export * from './MeshWobbleMaterial'

0 commit comments

Comments
 (0)