diff --git a/modules/core/src/effects/lighting/camera-light.js b/modules/core/src/effects/lighting/camera-light.js new file mode 100644 index 00000000000..67d13cebb11 --- /dev/null +++ b/modules/core/src/effects/lighting/camera-light.js @@ -0,0 +1,17 @@ +import PointLight from './point-light'; +import {getUniformsFromViewport} from '../../shaderlib/project/viewport-uniforms'; + +export default class CameraLight extends PointLight { + getProjectedLight({layer}) { + const viewport = layer.context.viewport; + const {coordinateSystem, coordinateOrigin, modelMatrix} = layer.props; + const {project_uCameraPosition} = getUniformsFromViewport({ + viewport, + modelMatrix, + coordinateSystem, + coordinateOrigin + }); + this.projectedLight.position = project_uCameraPosition; + return this.projectedLight; + } +} diff --git a/modules/core/src/effects/lighting/directional-light.js b/modules/core/src/effects/lighting/directional-light.js new file mode 100644 index 00000000000..73bcc7674d6 --- /dev/null +++ b/modules/core/src/effects/lighting/directional-light.js @@ -0,0 +1,7 @@ +import {DirectionalLight as BaseDirectionalLight} from '@luma.gl/core'; + +export default class DirectionalLight extends BaseDirectionalLight { + getProjectedLight() { + return this; + } +} diff --git a/modules/core/src/effects/lighting-effect.js b/modules/core/src/effects/lighting/lighting-effect.js similarity index 67% rename from modules/core/src/effects/lighting-effect.js rename to modules/core/src/effects/lighting/lighting-effect.js index 6a741a6938b..432c2fd2d1b 100644 --- a/modules/core/src/effects/lighting-effect.js +++ b/modules/core/src/effects/lighting/lighting-effect.js @@ -1,7 +1,6 @@ -import {AmbientLight, PointLight, DirectionalLight} from '@luma.gl/core'; -import Effect from '../lib/effect'; -import {projectPosition} from '../shaderlib/project/project-functions'; -import {COORDINATE_SYSTEM} from '../lib'; +import {AmbientLight} from '@luma.gl/core'; +import DirectionalLight from './directional-light'; +import Effect from '../../lib/effect'; const DefaultAmbientLightProps = {color: [255, 255, 255], intensity: 1.0}; const DefaultDirectionalLightProps = [ @@ -47,8 +46,9 @@ export default class LightingEffect extends Effect { } getParameters(layer) { - const {ambientLight, directionalLights} = this; + const {ambientLight} = this; const pointLights = this.getProjectedPointLights(layer); + const directionalLights = this.getProjectedDirectionalLights(layer); return { lightSources: {ambientLight, directionalLights, pointLights} }; @@ -65,30 +65,22 @@ export default class LightingEffect extends Effect { } getProjectedPointLights(layer) { - const viewport = layer.context.viewport; - const {coordinateSystem, coordinateOrigin} = layer.props; const projectedPointLights = []; for (let i = 0; i < this.pointLights.length; i++) { const pointLight = this.pointLights[i]; - const position = projectPosition(pointLight.position, { - viewport, - coordinateSystem, - coordinateOrigin, - fromCoordinateSystem: viewport.isGeospatial - ? COORDINATE_SYSTEM.LNGLAT - : COORDINATE_SYSTEM.IDENTITY, - fromCoordinateOrigin: [0, 0, 0] - }); - projectedPointLights.push( - new PointLight({ - color: pointLight.color, - intensity: pointLight.intensity, - position - }) - ); + projectedPointLights.push(pointLight.getProjectedLight({layer})); } - return projectedPointLights; } + + getProjectedDirectionalLights(layer) { + const projectedDirectionalLights = []; + + for (let i = 0; i < this.directionalLights.length; i++) { + const directionalLight = this.directionalLights[i]; + projectedDirectionalLights.push(directionalLight.getProjectedLight({layer})); + } + return projectedDirectionalLights; + } } diff --git a/modules/core/src/effects/lighting/point-light.js b/modules/core/src/effects/lighting/point-light.js new file mode 100644 index 00000000000..8811d12e3c1 --- /dev/null +++ b/modules/core/src/effects/lighting/point-light.js @@ -0,0 +1,26 @@ +import {PointLight as BasePointLight} from '@luma.gl/core'; +import {projectPosition} from '../../shaderlib/project/project-functions'; +import {COORDINATE_SYSTEM} from '../../lib'; + +export default class PointLight extends BasePointLight { + constructor(props) { + super(props); + this.projectedLight = new BasePointLight(props); + } + + getProjectedLight({layer}) { + const viewport = layer.context.viewport; + const {coordinateSystem, coordinateOrigin} = layer.props; + const position = projectPosition(this.position, { + viewport, + coordinateSystem, + coordinateOrigin, + fromCoordinateSystem: viewport.isGeospatial + ? COORDINATE_SYSTEM.LNGLAT + : COORDINATE_SYSTEM.IDENTITY, + fromCoordinateOrigin: [0, 0, 0] + }); + this.projectedLight.position = position; + return this.projectedLight; + } +} diff --git a/modules/core/src/index.js b/modules/core/src/index.js index 6c0d95892d4..506da9631c7 100644 --- a/modules/core/src/index.js +++ b/modules/core/src/index.js @@ -29,7 +29,10 @@ import './shaderlib'; export {COORDINATE_SYSTEM} from './lib/constants'; // Effects -export {default as LightingEffect} from './effects/lighting-effect'; +export {default as LightingEffect} from './effects/lighting/lighting-effect'; +import {default as CameraLight} from './effects/lighting/camera-light'; +export {default as PointLight} from './effects/lighting/point-light'; +export {default as DirectionalLight} from './effects/lighting/directional-light'; // Experimental Pure JS (non-React) bindings export {default as Deck} from './lib/deck'; @@ -84,11 +87,12 @@ import {count} from './utils/count'; import memoize from './utils/memoize'; // lighting -export {AmbientLight, PointLight, DirectionalLight} from '@luma.gl/core'; +export {AmbientLight} from '@luma.gl/core'; // Exports for layers // Experimental Features may change in minor version bumps, use at your own risk) export const experimental = { + CameraLight, Tesselator, flattenVertices, fillArray, diff --git a/modules/core/src/lib/effect-manager.js b/modules/core/src/lib/effect-manager.js index b50bd28eefa..69831f8a1f1 100644 --- a/modules/core/src/lib/effect-manager.js +++ b/modules/core/src/lib/effect-manager.js @@ -1,5 +1,5 @@ import {deepEqual} from '../utils/deep-equal'; -import {default as LightingEffect} from '../effects/lighting-effect'; +import {default as LightingEffect} from '../effects/lighting/lighting-effect'; export default class EffectManager { constructor() { diff --git a/test/modules/core/effects/index.js b/test/modules/core/effects/index.js new file mode 100644 index 00000000000..2df78952599 --- /dev/null +++ b/test/modules/core/effects/index.js @@ -0,0 +1 @@ +import './lighting-effect.spec'; diff --git a/test/modules/core/effects/lighting-effect.spec.js b/test/modules/core/effects/lighting-effect.spec.js new file mode 100644 index 00000000000..c3c32049d71 --- /dev/null +++ b/test/modules/core/effects/lighting-effect.spec.js @@ -0,0 +1,39 @@ +import test from 'tape-catch'; +import LightingEffect from '@deck.gl/core/effects/lighting/lighting-effect'; +import {experimental} from '@deck.gl/core'; +const {CameraLight} = experimental; + +import {MapView, PolygonLayer} from 'deck.gl'; +import * as FIXTURES from 'deck.gl-test/data'; + +test('LightingEffect#constructor', t => { + const lightingEffect = new LightingEffect(); + t.ok(lightingEffect, 'Lighting effect created'); + t.ok(lightingEffect.ambientLight, 'Default ambient light created'); + t.equal(lightingEffect.directionalLights.length, 2, 'Default directional lights created'); + t.end(); +}); + +test('LightingEffect#CameraLight', t => { + const cameraLight = new CameraLight(); + const lightEffect = new LightingEffect({cameraLight}); + + const viewport = new MapView().makeViewport({ + width: 100, + height: 100, + viewState: {longitude: -122, latitude: 37, zoom: 13} + }); + + const layer = new PolygonLayer({ + data: FIXTURES.polygons.slice(0, 3), + getPolygon: f => f, + getFillColor: (f, {index}) => [index, 0, 0] + }); + + layer.context = {viewport}; + + const projectedLights = lightEffect.getProjectedPointLights(layer); + t.ok(projectedLights[0], 'Camera light is ok'); + t.deepEqual(projectedLights[0].position, [0, 0, 150], 'Camera light projection is ok'); + t.end(); +}); diff --git a/test/modules/core/index.js b/test/modules/core/index.js index d8d1fe4d9c2..b8543f91e69 100644 --- a/test/modules/core/index.js +++ b/test/modules/core/index.js @@ -27,3 +27,4 @@ import './shaderlib'; import './transitions'; import './experimental'; import './passes'; +import './effects';