2021-03-07 18:46:35 +08:00
|
|
|
import { ClampToEdgeWrapping, LinearFilter, LinearMipmapLinearFilter, TextureLoader, UVMapping } from 'three';
|
2020-10-04 06:20:27 +08:00
|
|
|
import { watch } from 'vue';
|
2021-03-07 18:46:35 +08:00
|
|
|
import { bindProp } from '../tools.js';
|
2020-10-04 06:07:10 +08:00
|
|
|
|
|
|
|
export default {
|
2020-10-04 20:00:07 +08:00
|
|
|
inject: ['material'],
|
2020-10-04 06:07:10 +08:00
|
|
|
emits: ['loaded'],
|
|
|
|
props: {
|
2021-03-15 23:45:08 +08:00
|
|
|
name: { type: String, default: 'map' },
|
|
|
|
uniform: { type: String, default: null },
|
2020-10-04 06:07:10 +08:00
|
|
|
src: String,
|
|
|
|
onLoad: Function,
|
|
|
|
onProgress: Function,
|
|
|
|
onError: Function,
|
2021-03-07 18:46:35 +08:00
|
|
|
mapping: { type: Number, default: UVMapping },
|
|
|
|
wrapS: { type: Number, default: ClampToEdgeWrapping },
|
|
|
|
wrapT: { type: Number, default: ClampToEdgeWrapping },
|
|
|
|
magFilter: { type: Number, default: LinearFilter },
|
|
|
|
minFilter: { type: Number, default: LinearMipmapLinearFilter },
|
|
|
|
repeat: { type: Object, default: { x: 1, y: 1 } },
|
|
|
|
rotation: { type: Number, default: 0 },
|
|
|
|
center: { type: Object, default: { x: 0, y: 0 } },
|
2020-10-04 06:07:10 +08:00
|
|
|
},
|
|
|
|
created() {
|
2020-10-04 20:00:07 +08:00
|
|
|
this.refreshTexture();
|
2020-10-04 06:20:27 +08:00
|
|
|
watch(() => this.src, this.refreshTexture);
|
2020-10-04 06:07:10 +08:00
|
|
|
},
|
|
|
|
unmounted() {
|
2021-03-15 23:45:08 +08:00
|
|
|
if (this.material && this.material.setTexture) this.material.setTexture(null, this.name);
|
2020-10-04 06:07:10 +08:00
|
|
|
this.texture.dispose();
|
|
|
|
},
|
|
|
|
methods: {
|
2020-10-04 06:20:27 +08:00
|
|
|
createTexture() {
|
|
|
|
this.texture = new TextureLoader().load(this.src, this.onLoaded, this.onProgress, this.onError);
|
2021-03-07 18:46:35 +08:00
|
|
|
const wathProps = ['mapping', 'wrapS', 'wrapT', 'magFilter', 'minFilter', 'repeat', 'rotation', 'rotation', 'center'];
|
|
|
|
wathProps.forEach(prop => {
|
|
|
|
bindProp(this, prop, this.texture);
|
|
|
|
});
|
2020-10-04 06:20:27 +08:00
|
|
|
},
|
|
|
|
refreshTexture() {
|
|
|
|
this.createTexture();
|
2021-03-15 23:45:08 +08:00
|
|
|
// handle standard material
|
|
|
|
if (this.material && this.material.setTexture) { this.material.setTexture(this.texture, this.name); }
|
|
|
|
// handle shader material
|
2021-03-15 12:33:27 +08:00
|
|
|
else if (this.material && this.material.material.type === "ShaderMaterial") {
|
2021-03-15 23:45:08 +08:00
|
|
|
// require a `uniform` prop so we know what to call the uniform
|
|
|
|
if (!this.uniform) {
|
|
|
|
console.warn('"uniform" prop required to use texture in a shader.')
|
|
|
|
return
|
|
|
|
}
|
|
|
|
this.material.uniforms[this.uniform] = { value: this.texture };
|
2021-03-15 12:33:27 +08:00
|
|
|
}
|
2020-10-04 06:20:27 +08:00
|
|
|
},
|
2020-10-04 06:07:10 +08:00
|
|
|
onLoaded() {
|
|
|
|
if (this.onLoad) this.onLoad();
|
|
|
|
this.$emit('loaded');
|
|
|
|
},
|
|
|
|
},
|
2021-03-07 06:14:22 +08:00
|
|
|
render() { return []; },
|
2020-10-04 06:07:10 +08:00
|
|
|
};
|