1
0
mirror of https://github.com/troisjs/trois.git synced 2024-11-24 04:12:02 +08:00

wip: lights

This commit is contained in:
Kevin Levron 2021-04-18 22:58:28 +02:00
parent ca2ef58436
commit a7a4f15734
16 changed files with 181 additions and 174 deletions

View File

@ -1,12 +0,0 @@
import { defineComponent } from 'vue';
import { AmbientLight } from 'three';
import Light from './Light.js';
export default defineComponent({
extends: Light,
created() {
this.light = new AmbientLight(this.color, this.intensity);
this.initLight();
},
__hmrId: 'AmbientLight',
});

View File

@ -0,0 +1,11 @@
import { defineComponent } from 'vue'
import { AmbientLight } from 'three'
import Light from './Light'
export default defineComponent({
extends: Light,
created() {
this.initLight(new AmbientLight(this.color, this.intensity))
},
__hmrId: 'AmbientLight',
})

View File

@ -1,15 +0,0 @@
import { defineComponent } from 'vue';
import { DirectionalLight } from 'three';
import Light from './Light.js';
export default defineComponent({
extends: Light,
props: {
target: Object,
},
created() {
this.light = new DirectionalLight(this.color, this.intensity);
this.initLight();
},
__hmrId: 'DirectionalLight',
});

View File

@ -0,0 +1,14 @@
import { defineComponent } from 'vue'
import { DirectionalLight } from 'three'
import Light from './Light'
export default defineComponent({
extends: Light,
props: {
target: { type: Object, default: () => ({ x: 0, y: 0, z: 0 }) },
},
created() {
this.initLight(new DirectionalLight(this.color, this.intensity))
},
__hmrId: 'DirectionalLight',
})

View File

@ -1,16 +0,0 @@
import { defineComponent, watch } from 'vue';
import { HemisphereLight } from 'three';
import Light from './Light.js';
export default defineComponent({
extends: Light,
props: {
groundColor: { type: String, default: '#444444' },
},
created() {
this.light = new HemisphereLight(this.color, this.groundColor, this.intensity);
watch(() => this.groundColor, (value) => { this.light.groundColor.set(value); });
this.initLight();
},
__hmrId: 'HemisphereLight',
});

View File

@ -0,0 +1,16 @@
import { defineComponent, watch } from 'vue'
import { HemisphereLight } from 'three'
import Light from './Light'
export default defineComponent({
extends: Light,
props: {
groundColor: { type: String, default: '#444444' },
},
created() {
const light = new HemisphereLight(this.color, this.groundColor, this.intensity)
watch(() => this.groundColor, (value) => { light.groundColor.set(value) })
this.initLight(light)
},
__hmrId: 'HemisphereLight',
})

View File

@ -1,47 +0,0 @@
import { defineComponent, watch } from 'vue';
import Object3D from '../core/Object3D';
import { bindProp, setFromProp } from '../tools';
export default defineComponent({
extends: Object3D,
name: 'Light',
props: {
color: { type: String, default: '#ffffff' },
intensity: { type: Number, default: 1 },
castShadow: { type: Boolean, default: false },
shadowMapSize: { type: Object, default: { x: 512, y: 512 } },
shadowCamera: { type: Object, default: {} },
},
// can't use setup because it will not be used in sub components
// setup() {},
unmounted() {
if (this.light.target) this.removeFromParent(this.light.target);
},
methods: {
initLight() {
if (this.light.target) {
bindProp(this, 'target', this.light.target, 'position');
}
if (this.light.shadow) {
this.light.castShadow = this.castShadow;
setFromProp(this.light.shadow.mapSize, this.shadowMapSize);
setFromProp(this.light.shadow.camera, this.shadowCamera);
}
['color', 'intensity', 'castShadow'].forEach(p => {
watch(() => this[p], () => {
if (p === 'color') {
this.light.color.set(this.color);
} else {
this.light[p] = this[p];
}
});
});
this.initObject3D(this.light);
if (this.light.target) this.addToParent(this.light.target);
},
},
__hmrId: 'Light',
});

59
src/lights/Light.ts Normal file
View File

@ -0,0 +1,59 @@
import { DirectionalLight, Light, SpotLight } from 'three'
import { defineComponent, watch } from 'vue'
import Object3D from '../core/Object3D'
import { bindProp, setFromProp } from '../tools'
interface LightInterface {
light?: Light
}
type LightWithTarget = SpotLight | DirectionalLight
export default defineComponent({
extends: Object3D,
name: 'Light',
props: {
color: { type: String, default: '#ffffff' },
intensity: { type: Number, default: 1 },
castShadow: { type: Boolean, default: false },
shadowMapSize: { type: Object, default: () => ({ x: 512, y: 512 }) },
shadowCamera: { type: Object, default: () => ({}) },
},
setup(): LightInterface {
return {}
},
unmounted() {
const light = this.light as LightWithTarget
if (light && light.target) this.removeFromParent(light.target)
},
methods: {
initLight(light: Light) {
this.light = light
const lightWithTarget = light as LightWithTarget
if (lightWithTarget.target) {
bindProp(this, 'target', lightWithTarget.target, 'position')
}
if (this.light?.shadow) {
this.light.castShadow = this.castShadow
setFromProp(this.light.shadow.mapSize, this.shadowMapSize)
setFromProp(this.light.shadow.camera, this.shadowCamera)
}
['color', 'intensity', 'castShadow'].forEach(p => {
watch(() => this[p], () => {
if (p === 'color') {
light.color.set(this.color)
} else {
light[p] = this[p]
}
})
})
this.initObject3D(this.light)
if (lightWithTarget.target) this.addToParent(lightWithTarget.target)
},
},
__hmrId: 'Light',
})

View File

@ -1,22 +0,0 @@
import { defineComponent } from 'vue';
import { PointLight } from 'three';
import Light from './Light.js';
export default defineComponent({
extends: Light,
props: {
distance: {
type: Number,
default: 0,
},
decay: {
type: Number,
default: 1,
},
},
created() {
this.light = new PointLight(this.color, this.intensity, this.distance, this.decay);
this.initLight();
},
__hmrId: 'PointLight',
});

15
src/lights/PointLight.ts Normal file
View File

@ -0,0 +1,15 @@
import { defineComponent } from 'vue'
import { PointLight } from 'three'
import Light from './Light'
export default defineComponent({
extends: Light,
props: {
distance: { type: Number, default: 0 },
decay: { type: Number, default: 1 },
},
created() {
this.initLight(new PointLight(this.color, this.intensity, this.distance, this.decay))
},
__hmrId: 'PointLight',
})

View File

@ -1,32 +0,0 @@
import { defineComponent, watch } from 'vue';
import { RectAreaLight } from 'three';
import { RectAreaLightUniformsLib } from 'three/examples/jsm/lights/RectAreaLightUniformsLib.js';
import { RectAreaLightHelper } from 'three/examples/jsm/helpers/RectAreaLightHelper.js';
import Light from './Light.js';
export default defineComponent({
extends: Light,
props: {
width: { type: Number, default: 10 },
height: { type: Number, default: 10 },
helper: Boolean,
},
created() {
RectAreaLightUniformsLib.init();
this.light = new RectAreaLight(this.color, this.intensity, this.width, this.height);
['width', 'height'].forEach(p => {
watch(() => this[p], () => {
this.light[p] = this[p];
});
});
if (this.helper) {
this.lightHelper = new RectAreaLightHelper(this.light);
this.light.add(this.lightHelper);
}
this.initLight();
},
__hmrId: 'RectAreaLight',
});

View File

@ -0,0 +1,33 @@
import { defineComponent, watch } from 'vue'
import { RectAreaLight } from 'three'
import { RectAreaLightUniformsLib } from 'three/examples/jsm/lights/RectAreaLightUniformsLib.js'
import { RectAreaLightHelper } from 'three/examples/jsm/helpers/RectAreaLightHelper.js'
import Light from './Light'
export default defineComponent({
extends: Light,
props: {
width: { type: Number, default: 10 },
height: { type: Number, default: 10 },
helper: Boolean,
},
created() {
RectAreaLightUniformsLib.init()
const light = new RectAreaLight(this.color, this.intensity, this.width, this.height)
const watchProps = ['width', 'height']
watchProps.forEach(p => {
watch(() => this[p], () => {
light[p] = this[p]
})
})
if (this.helper) {
const lightHelper = new RectAreaLightHelper(light)
light.add(lightHelper)
}
this.initLight(light)
},
__hmrId: 'RectAreaLight',
})

View File

@ -1,24 +0,0 @@
import { defineComponent, watch } from 'vue';
import { SpotLight } from 'three';
import Light from './Light.js';
export default defineComponent({
extends: Light,
props: {
angle: { type: Number, default: Math.PI / 3 },
decay: { type: Number, default: 1 },
distance: { type: Number, default: 0 },
penumbra: { type: Number, default: 0 },
target: Object,
},
created() {
this.light = new SpotLight(this.color, this.intensity, this.distance, this.angle, this.penumbra, this.decay);
['angle', 'decay', 'distance', 'penumbra'].forEach(p => {
watch(() => this[p], () => {
this.light[p] = this[p];
});
});
this.initLight();
},
__hmrId: 'SpotLight',
});

27
src/lights/SpotLight.ts Normal file
View File

@ -0,0 +1,27 @@
import { defineComponent, watch } from 'vue'
import { SpotLight } from 'three'
import Light from './Light'
export default defineComponent({
extends: Light,
props: {
angle: { type: Number, default: Math.PI / 3 },
decay: { type: Number, default: 1 },
distance: { type: Number, default: 0 },
penumbra: { type: Number, default: 0 },
target: Object,
},
created() {
const light = new SpotLight(this.color, this.intensity, this.distance, this.angle, this.penumbra, this.decay)
const watchProps = ['angle', 'decay', 'distance', 'penumbra']
watchProps.forEach(p => {
watch(() => this[p], () => {
light[p] = this[p]
})
})
this.initLight(light)
},
__hmrId: 'SpotLight',
})

View File

@ -1,6 +0,0 @@
export { default as AmbientLight } from './AmbientLight.js';
export { default as DirectionalLight } from './DirectionalLight.js';
export { default as HemisphereLight } from './HemisphereLight.js';
export { default as PointLight } from './PointLight.js';
export { default as RectAreaLight } from './RectAreaLight.js';
export { default as SpotLight } from './SpotLight.js';

6
src/lights/index.ts Normal file
View File

@ -0,0 +1,6 @@
export { default as AmbientLight } from './AmbientLight'
export { default as DirectionalLight } from './DirectionalLight'
export { default as HemisphereLight } from './HemisphereLight'
export { default as PointLight } from './PointLight'
export { default as RectAreaLight } from './RectAreaLight'
export { default as SpotLight } from './SpotLight'