diff --git a/src/components/meshes/Gem.js b/src/components/meshes/Gem.js index d1c1322..c6098a3 100644 --- a/src/components/meshes/Gem.js +++ b/src/components/meshes/Gem.js @@ -8,7 +8,7 @@ import { RGBFormat, WebGLCubeRenderTarget, } from 'three'; -import Mesh from '../../meshes/Mesh.js'; +import Mesh from '../../meshes/Mesh'; import { bindProp } from '../../tools'; export default defineComponent({ diff --git a/src/components/meshes/MirrorMesh.js b/src/components/meshes/MirrorMesh.js index e62b862..ac72a17 100644 --- a/src/components/meshes/MirrorMesh.js +++ b/src/components/meshes/MirrorMesh.js @@ -5,7 +5,7 @@ import { RGBFormat, WebGLCubeRenderTarget, } from 'three'; -import Mesh from '../../meshes/Mesh.js'; +import Mesh from '../../meshes/Mesh'; export default defineComponent({ extends: Mesh, diff --git a/src/components/meshes/RefractionMesh.js b/src/components/meshes/RefractionMesh.js index 3e942a9..81232fe 100644 --- a/src/components/meshes/RefractionMesh.js +++ b/src/components/meshes/RefractionMesh.js @@ -6,7 +6,7 @@ import { RGBFormat, WebGLCubeRenderTarget, } from 'three'; -import Mesh from '../../meshes/Mesh.js'; +import Mesh from '../../meshes/Mesh'; import { bindProp } from '../../tools'; export default defineComponent({ diff --git a/src/components/noisy/NoisyImage.js b/src/components/noisy/NoisyImage.js index 3bd2f53..dad2151 100644 --- a/src/components/noisy/NoisyImage.js +++ b/src/components/noisy/NoisyImage.js @@ -1,7 +1,7 @@ -import { defineComponent, watch } from 'vue'; -import { DoubleSide, MeshBasicMaterial, PlaneGeometry } from 'three'; -import Image from '../../meshes/Image.js'; -import snoise2 from '../../glsl/snoise2.glsl.js'; +import { defineComponent, watch } from 'vue' +import { DoubleSide, MeshBasicMaterial, PlaneGeometry } from 'three' +import Image from '../../meshes/Image' +import snoise2 from '../../glsl/snoise2.glsl.js' export default defineComponent({ extends: Image, @@ -15,43 +15,41 @@ export default defineComponent({ }, setup(props) { // uniforms - const uTime = { value: 0 }; - const uNoiseCoef = { value: props.noiseCoef }; - watch(() => props.noiseCoef, (value) => { uNoiseCoef.value = value; }); - const uZCoef = { value: props.zCoef }; - watch(() => props.zCoef, (value) => { uZCoef.value = value; }); - const uDispCoef = { value: props.dispCoef }; - watch(() => props.dispCoef, (value) => { uDispCoef.value = value; }); + const uTime = { value: 0 } + const uNoiseCoef = { value: props.noiseCoef } + watch(() => props.noiseCoef, (value) => { uNoiseCoef.value = value }) + const uZCoef = { value: props.zCoef } + watch(() => props.zCoef, (value) => { uZCoef.value = value }) + const uDispCoef = { value: props.dispCoef } + watch(() => props.dispCoef, (value) => { uDispCoef.value = value }) return { uTime, uNoiseCoef, uZCoef, uDispCoef, - }; + } }, - mounted() { - this.startTime = Date.now(); - this.renderer.onBeforeRender(this.updateTime); + created() { + this.tweakMaterial() + + this.startTime = Date.now() + this.renderer.onBeforeRender(this.updateTime) }, unmounted() { - this.renderer.offBeforeRender(this.updateTime); + this.renderer.offBeforeRender(this.updateTime) }, methods: { - createGeometry() { - this.geometry = new PlaneGeometry(1, 1, this.widthSegments, this.heightSegments); - }, - createMaterial() { - this.material = new MeshBasicMaterial({ side: DoubleSide, map: this.loadTexture() }); + tweakMaterial() { this.material.onBeforeCompile = (shader) => { - shader.uniforms.uTime = this.uTime; - shader.uniforms.uNoiseCoef = this.uNoiseCoef; - shader.uniforms.uZCoef = this.uZCoef; - shader.uniforms.uDispCoef = this.uDispCoef; + shader.uniforms.uTime = this.uTime + shader.uniforms.uNoiseCoef = this.uNoiseCoef + shader.uniforms.uZCoef = this.uZCoef + shader.uniforms.uDispCoef = this.uDispCoef shader.vertexShader = ` uniform float uTime; uniform float uNoiseCoef; uniform float uZCoef; varying float vNoise; ${snoise2} - ` + shader.vertexShader; + ` + shader.vertexShader shader.vertexShader = shader.vertexShader.replace( '#include ', @@ -62,12 +60,12 @@ export default defineComponent({ vec3 transformed = vec3(position); transformed.z += vNoise * uZCoef; ` - ); + ) shader.fragmentShader = ` uniform float uDispCoef; varying float vNoise; - ` + shader.fragmentShader; + ` + shader.fragmentShader shader.fragmentShader = shader.fragmentShader.replace( '#include ', @@ -77,13 +75,13 @@ export default defineComponent({ texelColor.r = dispTexel.r; diffuseColor = texelColor; ` - ); - this.materialShader = shader; - }; + ) + this.materialShader = shader + } }, updateTime() { - this.uTime.value = (Date.now() - this.startTime) * this.timeCoef; + this.uTime.value = (Date.now() - this.startTime) * this.timeCoef }, }, __hmrId: 'NoisyImage', -}); +}) diff --git a/src/components/noisy/NoisyPlane.js b/src/components/noisy/NoisyPlane.js index 6b8010a..719e748 100644 --- a/src/components/noisy/NoisyPlane.js +++ b/src/components/noisy/NoisyPlane.js @@ -1,7 +1,7 @@ import { defineComponent, watch } from 'vue'; import { ObjectSpaceNormalMap, ShaderMaterial, Vector2, WebGLRenderTarget } from 'three'; import { Pass } from 'three/examples/jsm/postprocessing/Pass.js'; -import Plane from '../../meshes/Plane.js'; +import Plane from '../../meshes/Plane'; import snoise3 from '../../glsl/snoise3.glsl.js'; export default defineComponent({ diff --git a/src/components/noisy/NoisySphere.js b/src/components/noisy/NoisySphere.js index 23e2e4c..5bb47dd 100644 --- a/src/components/noisy/NoisySphere.js +++ b/src/components/noisy/NoisySphere.js @@ -1,5 +1,5 @@ import { defineComponent, watch } from 'vue'; -import Sphere from '../../meshes/Sphere.js'; +import Sphere from '../../meshes/Sphere'; import snoise4 from '../../glsl/snoise4.glsl.js'; export default defineComponent({ diff --git a/src/components/noisy/NoisyText.js b/src/components/noisy/NoisyText.js index 3909c52..c8966fa 100644 --- a/src/components/noisy/NoisyText.js +++ b/src/components/noisy/NoisyText.js @@ -1,5 +1,5 @@ import { defineComponent, watch } from 'vue'; -import Text from '../../meshes/Text.js'; +import Text from '../../meshes/Text'; import snoise2 from '../../glsl/snoise2.glsl.js'; export default defineComponent({ diff --git a/src/components/sliders/Slider1.vue b/src/components/sliders/Slider1.vue index f9be477..c998c40 100644 --- a/src/components/sliders/Slider1.vue +++ b/src/components/sliders/Slider1.vue @@ -12,8 +12,8 @@ import { Object3D } from 'three'; import { gsap, Power4 } from 'gsap'; import Camera from '../../core/PerspectiveCamera'; -import Renderer from '../../core/Renderer.js'; -import Scene from '../../core/Scene.js'; +import Renderer from '../../core/Renderer'; +import Scene from '../../core/Scene'; import { lerp } from '../../tools'; import AnimatedPlane from './AnimatedPlane.js'; diff --git a/src/components/sliders/Slider2.vue b/src/components/sliders/Slider2.vue index 44d3936..1838d5b 100644 --- a/src/components/sliders/Slider2.vue +++ b/src/components/sliders/Slider2.vue @@ -11,12 +11,12 @@ import { Vector2 } from 'three'; import { gsap, Power4 } from 'gsap'; import OrthographicCamera from '../../core/OrthographicCamera'; -import Renderer from '../../core/Renderer.js'; -import Scene from '../../core/Scene.js'; +import Renderer from '../../core/Renderer'; +import Scene from '../../core/Scene'; import { lerp, lerpv2 } from '../../tools'; import ZoomBlurImage from './ZoomBlurImage.js'; -import useTextures from '../../use/useTextures.js'; +import useTextures from '../../use/useTextures'; export default defineComponent({ components: { OrthographicCamera, Renderer, Scene }, @@ -86,7 +86,7 @@ export default defineComponent({ scene.add(this.image2.mesh); }, animate() { - const { positionN } = this.renderer.pointer; + const { positionN } = this.renderer.three.pointer; this.center.copy(positionN).divideScalar(2).addScalar(0.5); lerpv2(this.image1.uCenter.value, this.center, 0.1); lerpv2(this.image2.uCenter.value, this.center, 0.1); diff --git a/src/core/OrthographicCamera.ts b/src/core/OrthographicCamera.ts index d9d4044..3c6bc83 100644 --- a/src/core/OrthographicCamera.ts +++ b/src/core/OrthographicCamera.ts @@ -19,7 +19,7 @@ export default defineComponent({ setup(props) { const camera = new OrthographicCamera(props.left, props.right, props.top, props.bottom, props.near, props.far) - bindProp(this, 'position', camera) + bindProp(props, 'position', camera) const watchProps = ['left', 'right', 'top', 'bottom', 'near', 'far', 'zoom'] watchProps.forEach(p => { diff --git a/src/effects/TiltShiftPass.ts b/src/effects/TiltShiftPass.ts index 38fe6cf..e2fd033 100644 --- a/src/effects/TiltShiftPass.ts +++ b/src/effects/TiltShiftPass.ts @@ -1,6 +1,5 @@ import { defineComponent, watch } from 'vue' -import { ShaderMaterial, Vector2 } from 'three' -import { Pass } from 'three/examples/jsm/postprocessing/Pass' +import { Vector2 } from 'three' import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js' import EffectPass from './EffectPass' import TiltShift from '../shaders/TiltShift' @@ -14,27 +13,35 @@ const props = { } interface TiltShiftPassSetupInterface { - uniforms: {[name: string]: { value: any }} - pass1?: Pass - pass2?: Pass + uniforms1: {[name: string]: { value: any }} + uniforms2: {[name: string]: { value: any }} + pass1?: ShaderPass + pass2?: ShaderPass } export default defineComponent({ extends: EffectPass, props, setup(): TiltShiftPassSetupInterface { - const uniforms = {} - return { uniforms } + return { uniforms1: {}, uniforms2: {} } }, created() { - const shaderMat = new ShaderMaterial(TiltShift) - this.uniforms = shaderMat.uniforms + this.pass1 = new ShaderPass(TiltShift) + this.pass2 = new ShaderPass(TiltShift) - this.pass1 = new ShaderPass(shaderMat) - this.pass2 = new ShaderPass(shaderMat) + const uniforms1 = this.uniforms1 = this.pass1.uniforms + const uniforms2 = this.uniforms2 = this.pass2.uniforms + + // shared uniforms + uniforms2.blurRadius = uniforms1.blurRadius + uniforms2.gradientRadius = uniforms1.gradientRadius + uniforms2.start = uniforms1.start + uniforms2.end = uniforms1.end + uniforms2.texSize = uniforms1.texSize + + bindProp(this, 'blurRadius', uniforms1.blurRadius, 'value') + bindProp(this, 'gradientRadius', uniforms1.gradientRadius, 'value') - bindProp(this, 'blurRadius', this.uniforms.blurRadius, 'value') - bindProp(this, 'gradientRadius', this.uniforms.gradientRadius, 'value') this.updateFocusLine(); ['start', 'end'].forEach(p => { @@ -43,7 +50,7 @@ export default defineComponent({ }) this.pass1.setSize = (width: number, height: number) => { - this.uniforms.texSize.value.set(width, height) + uniforms1.texSize.value.set(width, height) } this.initEffectPass(this.pass1) @@ -54,10 +61,11 @@ export default defineComponent({ }, methods: { updateFocusLine() { - this.uniforms.start.value.copy(this.start) - this.uniforms.end.value.copy(this.end) + this.uniforms1.start.value.copy(this.start) + this.uniforms1.end.value.copy(this.end) const dv = new Vector2().copy(this.end as Vector2).sub(this.start as Vector2).normalize() - this.uniforms.delta.value.copy(dv) + this.uniforms1.delta.value.copy(dv) + this.uniforms2.delta.value.set(-dv.y, dv.x) }, }, __hmrId: 'TiltShiftPass', diff --git a/src/geometries/TubeGeometry.ts b/src/geometries/TubeGeometry.ts index 5dada15..237d5f6 100644 --- a/src/geometries/TubeGeometry.ts +++ b/src/geometries/TubeGeometry.ts @@ -50,7 +50,7 @@ export function updateTubeGeometryPoints(tube: TubeGeometry, points: Vector3[]): const nAttribute = tube.getAttribute('normal') const normal = new Vector3() - let P = new Vector3() + const P = new Vector3() for (let i = 0; i < tubularSegments; i++) { updateSegment(i) @@ -61,7 +61,7 @@ export function updateTubeGeometryPoints(tube: TubeGeometry, points: Vector3[]): tube.attributes.normal.needsUpdate = true function updateSegment(i: number) { - P = curve.getPointAt(i / tubularSegments, P) + curve.getPointAt(i / tubularSegments, P) const N = frames.normals[i] const B = frames.binormals[i] for (let j = 0; j <= radialSegments; j++) { @@ -72,7 +72,7 @@ export function updateTubeGeometryPoints(tube: TubeGeometry, points: Vector3[]): normal.y = (cos * N.y + sin * B.y) normal.z = (cos * N.z + sin * B.z) normal.normalize() - const index = (i * (radialSegments + 1) + j) * 3 + const index = (i * (radialSegments + 1) + j) nAttribute.setXYZ(index, normal.x, normal.y, normal.z) pAttribute.setXYZ(index, P.x + radius * normal.x, P.y + radius * normal.y, P.z + radius * normal.z) } diff --git a/src/meshes/Image.ts b/src/meshes/Image.ts index ca920ca..f1a04eb 100644 --- a/src/meshes/Image.ts +++ b/src/meshes/Image.ts @@ -15,13 +15,15 @@ export default defineComponent({ src: { type: String, required: true }, width: Number, height: Number, + widthSegments: { type: Number, default: 1 }, + heightSegments: { type: Number, default: 1 }, keepSize: Boolean, }, setup(): ImageSetupInterface { return object3DSetup() }, created() { - this.geometry = new PlaneGeometry(1, 1, 1, 1) + this.geometry = new PlaneGeometry(1, 1, this.widthSegments, this.heightSegments) this.material = new MeshBasicMaterial({ side: DoubleSide, map: this.loadTexture() }) watch(() => this.src, this.refreshTexture); @@ -34,6 +36,9 @@ export default defineComponent({ this.resize() if (this.keepSize) this.renderer.onResize(this.resize) }, + unmounted() { + this.renderer.offResize(this.resize) + }, methods: { loadTexture() { return new TextureLoader().load(this.src, this.onLoaded) diff --git a/src/meshes/Mesh.ts b/src/meshes/Mesh.ts index 6472475..44b441e 100644 --- a/src/meshes/Mesh.ts +++ b/src/meshes/Mesh.ts @@ -93,8 +93,9 @@ const Mesh = defineComponent({ if (this.mesh) { this.renderer.three?.removeIntersectObject(this.mesh) } - // for predefined mesh (geometry is not unmounted) + // for predefined mesh (geometry/material are not unmounted) if (this.geometry) this.geometry.dispose() + if (this.material) this.material.dispose() }, __hmrId: 'Mesh', })