diff --git a/__tests__/plots/api/chart-render-3d-line-plot-perspective.ts b/__tests__/plots/api/chart-render-3d-line-plot-perspective.ts
new file mode 100644
index 0000000000..b40564adfc
--- /dev/null
+++ b/__tests__/plots/api/chart-render-3d-line-plot-perspective.ts
@@ -0,0 +1,66 @@
+import { CameraType } from '@antv/g';
+import { Renderer as WebGLRenderer } from '@antv/g-webgl';
+import { Plugin as ThreeDPlugin } from '@antv/g-plugin-3d';
+import { Plugin as ControlPlugin } from '@antv/g-plugin-control';
+import { Runtime, extend } from '../../../src/api';
+import { corelib, threedlib } from '../../../src/lib';
+
+export function chartRender3dLinePlotPerspective(context) {
+ const { container } = context;
+
+ // Create a WebGL renderer.
+ const renderer = new WebGLRenderer();
+ renderer.registerPlugin(new ThreeDPlugin());
+ renderer.registerPlugin(new ControlPlugin());
+
+ const Chart = extend(Runtime, { ...corelib(), ...threedlib() });
+ const chart = new Chart({
+ container,
+ renderer,
+ depth: 400,
+ });
+
+ /**
+ * 3D Spiral
+ * @see https://plotly.com/javascript/3d-line-plots/
+ */
+ const pointCount = 500;
+ let r: number;
+ const data: { x: number; y: number; z: number }[] = [];
+
+ for (let i = 0; i < pointCount; i++) {
+ r = i * (pointCount - i);
+ data.push({
+ x: r * Math.cos(i / 30),
+ y: r * Math.sin(i / 30),
+ z: i,
+ });
+ }
+
+ chart
+ .line3D()
+ .data(data)
+ .encode('x', 'x')
+ .encode('y', 'y')
+ .encode('z', 'z')
+ .encode('size', 4)
+ .coordinate({ type: 'cartesian3D' })
+ .scale('x', { nice: true })
+ .scale('y', { nice: true })
+ .scale('z', { nice: true })
+ .legend(false)
+ .axis('x', { gridLineWidth: 2 })
+ .axis('y', { gridLineWidth: 2, titleBillboardRotation: -Math.PI / 2 })
+ .axis('z', { gridLineWidth: 2 });
+
+ const finished = chart.render().then(() => {
+ const { canvas } = chart.getContext();
+ const camera = canvas!.getCamera();
+ camera.setPerspective(0.1, 5000, 45, 500 / 500);
+ camera.setType(CameraType.ORBITING);
+ });
+
+ return { finished };
+}
+
+chartRender3dLinePlotPerspective.skip = true;
diff --git a/__tests__/plots/api/chart-render-3d-line-plot.ts b/__tests__/plots/api/chart-render-3d-line-plot.ts
new file mode 100644
index 0000000000..442d27fe44
--- /dev/null
+++ b/__tests__/plots/api/chart-render-3d-line-plot.ts
@@ -0,0 +1,66 @@
+import { CameraType } from '@antv/g';
+import { Renderer as WebGLRenderer } from '@antv/g-webgl';
+import { Plugin as ThreeDPlugin } from '@antv/g-plugin-3d';
+import { Plugin as ControlPlugin } from '@antv/g-plugin-control';
+import { Runtime, extend } from '../../../src/api';
+import { corelib, threedlib } from '../../../src/lib';
+
+export function chartRender3dLinePlot(context) {
+ const { container } = context;
+
+ // Create a WebGL renderer.
+ const renderer = new WebGLRenderer();
+ renderer.registerPlugin(new ThreeDPlugin());
+ renderer.registerPlugin(new ControlPlugin());
+
+ const Chart = extend(Runtime, { ...corelib(), ...threedlib() });
+ const chart = new Chart({
+ container,
+ renderer,
+ depth: 400,
+ });
+
+ /**
+ * 3D Line
+ * @see https://plotly.com/javascript/3d-line-plots/
+ */
+ const pointCount = 31;
+ let r: number;
+ const data: { x: number; y: number; z: number }[] = [];
+
+ for (let i = 0; i < pointCount; i++) {
+ r = 10 * Math.cos(i / 10);
+ data.push({
+ x: r * Math.cos(i),
+ y: r * Math.sin(i),
+ z: i,
+ });
+ }
+
+ chart
+ .line3D()
+ .data(data)
+ .encode('x', 'x')
+ .encode('y', 'y')
+ .encode('z', 'z')
+ .encode('size', 4)
+ .coordinate({ type: 'cartesian3D' })
+ .scale('x', { nice: true })
+ .scale('y', { nice: true })
+ .scale('z', { nice: true })
+ .legend(false)
+ .axis('x', { gridLineWidth: 2 })
+ .axis('y', { gridLineWidth: 2, titleBillboardRotation: -Math.PI / 2 })
+ .axis('z', { gridLineWidth: 2 });
+
+ const finished = chart.render().then(() => {
+ const { canvas } = chart.getContext();
+ const camera = canvas!.getCamera();
+ camera.setType(CameraType.ORBITING);
+ camera.rotate(-20, -20, 0);
+ });
+
+ return { finished };
+}
+
+chartRender3dLinePlot.skip = true;
diff --git a/__tests__/plots/api/chart-render-3d-scatter-plot-legend.ts b/__tests__/plots/api/chart-render-3d-scatter-plot-legend.ts
index f0b6aad456..49ccfbb7b6 100644
--- a/__tests__/plots/api/chart-render-3d-scatter-plot-legend.ts
+++ b/__tests__/plots/api/chart-render-3d-scatter-plot-legend.ts
@@ -77,7 +77,6 @@ export function chartRender3dScatterPlotLegend(context) {
const Chart = extend(Runtime, { ...corelib(), ...threedlib() });
const chart = new Chart({
container,
-
renderer,
depth: 400,
});
diff --git a/__tests__/plots/api/chart-render-3d-scatter-plot-perspective.ts b/__tests__/plots/api/chart-render-3d-scatter-plot-perspective.ts
index ed6a2cbfce..17f2cc925e 100644
--- a/__tests__/plots/api/chart-render-3d-scatter-plot-perspective.ts
+++ b/__tests__/plots/api/chart-render-3d-scatter-plot-perspective.ts
@@ -16,7 +16,6 @@ export function chartRender3dScatterPlotPerspective(context) {
const Chart = extend(Runtime, { ...corelib(), ...threedlib() });
const chart = new Chart({
container,
-
renderer,
depth: 400,
});
diff --git a/__tests__/plots/api/chart-render-3d-scatter-plot.ts b/__tests__/plots/api/chart-render-3d-scatter-plot.ts
index 21251492d8..ca590c1bbb 100644
--- a/__tests__/plots/api/chart-render-3d-scatter-plot.ts
+++ b/__tests__/plots/api/chart-render-3d-scatter-plot.ts
@@ -16,7 +16,6 @@ export function chartRender3dScatterPlot(context) {
const Chart = extend(Runtime, { ...corelib(), ...threedlib() });
const chart = new Chart({
container,
-
renderer,
depth: 400,
});
diff --git a/__tests__/plots/api/index.ts b/__tests__/plots/api/index.ts
index 42f1be5096..b34773393f 100644
--- a/__tests__/plots/api/index.ts
+++ b/__tests__/plots/api/index.ts
@@ -45,3 +45,5 @@ export { chartRenderEvent } from './chart-render-event';
export { chartRender3dScatterPlot } from './chart-render-3d-scatter-plot';
export { chartRender3dScatterPlotPerspective } from './chart-render-3d-scatter-plot-perspective';
export { chartRender3dScatterPlotLegend } from './chart-render-3d-scatter-plot-legend';
+export { chartRender3dLinePlot } from './chart-render-3d-line-plot';
+export { chartRender3dLinePlotPerspective } from './chart-render-3d-line-plot-perspective';
diff --git a/__tests__/unit/lib/threed.spec.ts b/__tests__/unit/lib/threed.spec.ts
index f111745a2a..b616c286d9 100644
--- a/__tests__/unit/lib/threed.spec.ts
+++ b/__tests__/unit/lib/threed.spec.ts
@@ -1,7 +1,7 @@
import { threedlib } from '../../../src/lib';
import { Cartesian3D } from '../../../src/coordinate';
import { AxisZ } from '../../../src/component';
-import { Point3D } from '../../../src/mark';
+import { Point3D, Line3D } from '../../../src/mark';
describe('threedlib', () => {
it('threedlib() should returns expected threed components.', () => {
@@ -9,6 +9,7 @@ describe('threedlib', () => {
'coordinate.cartesian3D': Cartesian3D,
'component.axisZ': AxisZ,
'mark.point3D': Point3D,
+ 'mark.line3D': Line3D,
});
});
});
diff --git a/site/docs/api/chart.zh.md b/site/docs/api/chart.zh.md
index 0603a12dea..3c4fcca131 100644
--- a/site/docs/api/chart.zh.md
+++ b/site/docs/api/chart.zh.md
@@ -199,6 +199,10 @@ chart.render();
添加 point3D 图形,具体见 [3d](/spec/threed/point-threed)。
+### `chart.line3D`
+
+添加 line3D 图形,具体见 [3d](/spec/threed/line-threed)。
+
## 设置属性
### `chart.width`
diff --git a/site/docs/spec/threed/lineThreed.en.md b/site/docs/spec/threed/lineThreed.en.md
new file mode 100644
index 0000000000..afdeefc766
--- /dev/null
+++ b/site/docs/spec/threed/lineThreed.en.md
@@ -0,0 +1,6 @@
+---
+title: line3D
+order: 2
+---
+
+
diff --git a/site/docs/spec/threed/lineThreed.zh.md b/site/docs/spec/threed/lineThreed.zh.md
new file mode 100644
index 0000000000..cd5aac57b4
--- /dev/null
+++ b/site/docs/spec/threed/lineThreed.zh.md
@@ -0,0 +1,74 @@
+---
+title: line3D
+order: 2
+---
+
+主要用于绘制 3D 折线图。
+
+## 开始使用
+
+首先需要使用 [@antv/g-webgl](https://g.antv.antgroup.com/api/renderer/webgl) 作为渲染器并注册以下两个插件:
+
+- [g-plugin-3d](https://g.antv.antgroup.com/plugins/3d) 提供 3D 场景下的几何、材质和光照
+- [g-plugin-control](https://g.antv.antgroup.com/plugins/control) 提供 3D 场景下的相机交互
+
+然后设置 z 通道、scale 和 z 坐标轴。无需在场景中添加光源。
+
+```js | ob
+(() => {
+ const renderer = new gWebgl.Renderer();
+ renderer.registerPlugin(new gPluginControl.Plugin());
+ renderer.registerPlugin(new gPlugin3d.Plugin());
+
+ const Chart = G2.extend(G2.Runtime, { ...G2.corelib(), ...G2.threedlib() });
+
+ // 初始化图表实例
+ const chart = new Chart({
+ theme: 'classic',
+ renderer,
+ width: 500,
+ height: 500,
+ depth: 400,
+ });
+
+ const pointCount = 31;
+ let r;
+ const data = [];
+
+ for (let i = 0; i < pointCount; i++) {
+ r = 10 * Math.cos(i / 10);
+ data.push({
+ x: r * Math.cos(i),
+ y: r * Math.sin(i),
+ z: i,
+ });
+ }
+
+ chart
+ .line3D()
+ .data(data)
+ .encode('x', 'x')
+ .encode('y', 'y')
+ .encode('z', 'z')
+ .encode('size', 4)
+ .coordinate({ type: 'cartesian3D' })
+ .scale('x', { nice: true })
+ .scale('y', { nice: true })
+ .scale('z', { nice: true })
+ .legend(false)
+ .axis('x', { gridLineWidth: 2 })
+ .axis('y', { gridLineWidth: 2, titleBillboardRotation: -Math.PI / 2 })
+ .axis('z', { gridLineWidth: 2 });
+
+ chart.render().then(() => {
+ const { canvas } = chart.getContext();
+ const camera = canvas.getCamera();
+ camera.setPerspective(0.1, 5000, 45, 500 / 500);
+ camera.setType(g.CameraType.ORBITING);
+ });
+
+ return chart.getContainer();
+})();
+```
+
+更多的案例,可以查看[图表示例](/examples)页面。
diff --git a/site/examples/threed/line/demo/meta.json b/site/examples/threed/line/demo/meta.json
new file mode 100644
index 0000000000..b3429d1739
--- /dev/null
+++ b/site/examples/threed/line/demo/meta.json
@@ -0,0 +1,24 @@
+{
+ "title": {
+ "zh": "中文分类",
+ "en": "Category"
+ },
+ "demos": [
+ {
+ "filename": "polyline.ts",
+ "title": {
+ "zh": "折线",
+ "en": "Polyline"
+ },
+ "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*0MEPQrNRlvoAAAAAAAAAAAAADmJ7AQ/original"
+ },
+ {
+ "filename": "spiral.ts",
+ "title": {
+ "zh": "螺旋线",
+ "en": "Spiral"
+ },
+ "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*Ak1iTZ1dpI0AAAAAAAAAAAAADmJ7AQ/original"
+ }
+ ]
+}
diff --git a/site/examples/threed/line/demo/polyline.ts b/site/examples/threed/line/demo/polyline.ts
new file mode 100644
index 0000000000..b9dcec8c6e
--- /dev/null
+++ b/site/examples/threed/line/demo/polyline.ts
@@ -0,0 +1,60 @@
+import { CameraType } from '@antv/g';
+import { Renderer as WebGLRenderer } from '@antv/g-webgl';
+import { Plugin as ThreeDPlugin } from '@antv/g-plugin-3d';
+import { Plugin as ControlPlugin } from '@antv/g-plugin-control';
+import { Runtime, corelib, threedlib, extend } from '@antv/g2';
+
+// Create a WebGL renderer.
+const renderer = new WebGLRenderer();
+renderer.registerPlugin(new ThreeDPlugin());
+renderer.registerPlugin(new ControlPlugin());
+
+// Customize our own Chart with threedlib.
+const Chart = extend(Runtime, { ...corelib(), ...threedlib() });
+const chart = new Chart({
+ container: 'container',
+ theme: 'classic',
+ renderer,
+ depth: 400, // Define the depth of chart.
+});
+
+/**
+ * 3D Line
+ * @see https://plotly.com/javascript/3d-line-plots/
+ */
+const pointCount = 31;
+let r;
+const data = [];
+
+for (let i = 0; i < pointCount; i++) {
+ r = 10 * Math.cos(i / 10);
+ data.push({
+ x: r * Math.cos(i),
+ y: r * Math.sin(i),
+ z: i,
+ });
+}
+
+chart
+ .line3D()
+ .data(data)
+ .encode('x', 'x')
+ .encode('y', 'y')
+ .encode('z', 'z')
+ .encode('size', 4)
+ .coordinate({ type: 'cartesian3D' })
+ .scale('x', { nice: true })
+ .scale('y', { nice: true })
+ .scale('z', { nice: true })
+ .legend(false)
+ .axis('x', { gridLineWidth: 2 })
+ .axis('y', { gridLineWidth: 2, titleBillboardRotation: -Math.PI / 2 })
+ .axis('z', { gridLineWidth: 2 });
+
+chart.render().then(() => {
+ const { canvas } = chart.getContext();
+ const camera = canvas.getCamera();
+ // Use perspective projection mode.
+ camera.setPerspective(0.1, 5000, 45, 640 / 480);
+ camera.setType(CameraType.ORBITING);
+});
diff --git a/site/examples/threed/line/demo/spiral.ts b/site/examples/threed/line/demo/spiral.ts
new file mode 100644
index 0000000000..5c4de4b7ed
--- /dev/null
+++ b/site/examples/threed/line/demo/spiral.ts
@@ -0,0 +1,62 @@
+import { CameraType } from '@antv/g';
+import { Renderer as WebGLRenderer } from '@antv/g-webgl';
+import { Plugin as ThreeDPlugin } from '@antv/g-plugin-3d';
+import { Plugin as ControlPlugin } from '@antv/g-plugin-control';
+import { Runtime, corelib, threedlib, extend } from '@antv/g2';
+
+// Create a WebGL renderer.
+const renderer = new WebGLRenderer();
+renderer.registerPlugin(new ThreeDPlugin());
+renderer.registerPlugin(new ControlPlugin());
+
+// Customize our own Chart with threedlib.
+const Chart = extend(Runtime, { ...corelib(), ...threedlib() });
+const chart = new Chart({
+ container: 'container',
+ theme: 'classic',
+ renderer,
+ depth: 400, // Define the depth of chart.
+});
+
+/**
+ * 3D Spiral
+ * @see https://plotly.com/javascript/3d-line-plots/
+ */
+const pointCount = 500;
+let r;
+const data = [];
+
+for (let i = 0; i < pointCount; i++) {
+ r = i * (pointCount - i);
+ data.push({
+ x: r * Math.cos(i / 30),
+ y: r * Math.sin(i / 30),
+ z: i,
+ });
+}
+
+chart
+ .line3D()
+ .data(data)
+ .encode('x', 'x')
+ .encode('y', 'y')
+ .encode('z', 'z')
+ .encode('size', 4)
+ .coordinate({ type: 'cartesian3D' })
+ .scale('x', { nice: true })
+ .scale('y', { nice: true })
+ .scale('z', { nice: true })
+ .legend(false)
+ .axis('x', { gridLineWidth: 2 })
+ .axis('y', { gridLineWidth: 2, titleBillboardRotation: -Math.PI / 2 })
+ .axis('z', { gridLineWidth: 2 });
+
+chart.render().then(() => {
+ const { canvas } = chart.getContext();
+ const camera = canvas.getCamera();
+ // Use perspective projection mode.
+ camera.setPerspective(0.1, 5000, 45, 640 / 480);
+ camera.rotate(30, 30, 0);
+ camera.dolly(30);
+ camera.setType(CameraType.ORBITING);
+});
diff --git a/site/examples/threed/line/index.en.md b/site/examples/threed/line/index.en.md
new file mode 100644
index 0000000000..dfbad93091
--- /dev/null
+++ b/site/examples/threed/line/index.en.md
@@ -0,0 +1,4 @@
+---
+title: 3D Line Chart
+order: 2
+---
diff --git a/site/examples/threed/line/index.zh.md b/site/examples/threed/line/index.zh.md
new file mode 100644
index 0000000000..c448b7aed1
--- /dev/null
+++ b/site/examples/threed/line/index.zh.md
@@ -0,0 +1,4 @@
+---
+title: 3D 折线图
+order: 2
+---
diff --git a/src/lib/threed.ts b/src/lib/threed.ts
index af29661450..4c55355361 100644
--- a/src/lib/threed.ts
+++ b/src/lib/threed.ts
@@ -1,11 +1,12 @@
import { Cartesian3D } from '../coordinate';
import { AxisZ } from '../component';
-import { Point3D } from '../mark';
+import { Point3D, Line3D } from '../mark';
export function threedlib() {
return {
'coordinate.cartesian3D': Cartesian3D,
'component.axisZ': AxisZ,
'mark.point3D': Point3D,
+ 'mark.line3D': Line3D,
} as const;
}
diff --git a/src/mark/index.ts b/src/mark/index.ts
index ee029a3e60..3d3d9d70bb 100644
--- a/src/mark/index.ts
+++ b/src/mark/index.ts
@@ -1,6 +1,7 @@
export { Interval } from './interval';
export { Rect } from './rect';
export { Line } from './line';
+export { Line3D } from './line3D';
export { Point } from './point';
export { Point3D } from './point3D';
export { Text } from './text';
diff --git a/src/mark/line3D.ts b/src/mark/line3D.ts
new file mode 100644
index 0000000000..b1f7cdb2d6
--- /dev/null
+++ b/src/mark/line3D.ts
@@ -0,0 +1,81 @@
+import { group } from 'd3-array';
+import { Mark, MarkComponent as MC, SingleMark, Vector3 } from '../runtime';
+import { LineMark } from '../spec';
+import { Line3DShape } from '../shape';
+import { MaybeSeries } from '../transform';
+import {
+ baseGeometryChannels,
+ basePostInference,
+ basePreInference,
+ tooltip3d,
+} from './utils';
+
+const shape = {
+ line: Line3DShape,
+};
+
+export type LineOptions = Omit;
+
+const line: Mark = (index, scale, value, coordinate) => {
+ const { series: S, x: X, y: Y, z: Z } = value;
+ const { x, y, z } = scale;
+
+ // Because x and y channel is not strictly required in Line.props,
+ // it should throw error with empty x, y or z channels.
+ if (X === undefined || Y === undefined || Z === undefined) {
+ throw new Error('Missing encode for x, y or z channel.');
+ }
+
+ // Group data into series.
+ // There is only one series without specified series encode.
+ const series = S ? Array.from(group(index, (i) => S[i]).values()) : [index];
+ const I = series.map((group) => group[0]).filter((i) => i !== undefined);
+
+ // A group of data corresponds to one line.
+ const xoffset = (x?.getBandWidth?.() || 0) / 2;
+ const yoffset = (y?.getBandWidth?.() || 0) / 2;
+ const zoffset = (z?.getBandWidth?.() || 0) / 2;
+ const P = Array.from(series, (I) => {
+ return I.map((i) =>
+ coordinate.map([
+ (+X[i] || 0) + xoffset,
+ (+Y[i] || 0) + yoffset,
+ (+Z[i] || 0) + zoffset,
+ ]),
+ ) as Vector3[];
+ });
+ return [I, P, series];
+};
+
+/**
+ * Convert value for each channel to line shapes.
+ */
+export const Line3D: MC = () => {
+ return (index, scale, value, coordinate) => {
+ const mark = line;
+ return (mark as SingleMark)(index, scale, value, coordinate);
+ };
+};
+
+Line3D.props = {
+ defaultShape: 'line',
+ defaultLabelShape: 'label',
+ composite: false,
+ shape,
+ channels: [
+ ...baseGeometryChannels({ shapes: Object.keys(shape) }),
+ { name: 'x' },
+ { name: 'y' },
+ { name: 'z' },
+ { name: 'position', independent: true },
+ { name: 'size' },
+ { name: 'series', scale: 'identity' },
+ ],
+ preInference: [...basePreInference(), { type: MaybeSeries }],
+ postInference: [...basePostInference(), ...tooltip3d()],
+ interaction: {
+ shareTooltip: false,
+ seriesTooltip: false,
+ crosshairs: false,
+ },
+};
diff --git a/src/shape/index.ts b/src/shape/index.ts
index 986e365d7f..bc9bd4c555 100644
--- a/src/shape/index.ts
+++ b/src/shape/index.ts
@@ -10,6 +10,7 @@ export { HV as LineHV } from './line/hv';
export { VH as LineVH } from './line/vh';
export { HVH as LineHVH } from './line/hvh';
export { Trail as LineTrail } from './line/trail';
+export { Line as Line3DShape } from './line3D/line';
export { HollowBowtie as PointHollowBowtie } from './point/hollowBowtie';
export { HollowDiamond as PointHollowDiamond } from './point/hollowDiamond';
export { HollowHexagon as PointHollowHexagon } from './point/hollowHexagon';
diff --git a/src/shape/line3D/line.ts b/src/shape/line3D/line.ts
new file mode 100644
index 0000000000..70341e44fe
--- /dev/null
+++ b/src/shape/line3D/line.ts
@@ -0,0 +1,29 @@
+import { Polyline } from '@antv/g';
+import { applyStyle } from '../utils';
+import { ShapeComponent as SC } from '../../runtime';
+import { select } from '../../utils/selection';
+
+export type LineOptions = Record;
+
+export const Line: SC = (options, context) => {
+ return (P, value, defaults) => {
+ const { color: defaultColor, lineWidth: defaultSize, ...rest } = defaults;
+ const { color = defaultColor, size = defaultSize } = value;
+ const stroke = color;
+ const finalStyle = {
+ isBillboard: true,
+ ...rest,
+ ...(stroke && { stroke }),
+ ...(size && { lineWidth: size }),
+ };
+
+ return select(new Polyline())
+ .style('points', P)
+ .call(applyStyle, finalStyle)
+ .node();
+ };
+};
+
+Line.props = {
+ defaultMarker: 'line',
+};
diff --git a/src/shape/point3D/cube.ts b/src/shape/point3D/cube.ts
index ebd4ee2fb6..f1d460408c 100644
--- a/src/shape/point3D/cube.ts
+++ b/src/shape/point3D/cube.ts
@@ -1,4 +1,4 @@
-import { MeshPhongMaterial, CubeGeometry, Mesh } from '@antv/g-plugin-3d';
+import { MeshLambertMaterial, CubeGeometry, Mesh } from '@antv/g-plugin-3d';
import { applyStyle, getOrigin, toOpacityKey } from '../utils';
import { ShapeComponent as SC } from '../../runtime';
import { select } from '../../utils/selection';
@@ -28,7 +28,7 @@ export const Cube: SC = (options, context) => {
});
// create a material with Phong lighting model
// @ts-ignore
- context.cubeMaterial = new MeshPhongMaterial(device);
+ context.cubeMaterial = new MeshLambertMaterial(device);
}
return (points, value, defaults) => {
diff --git a/src/shape/point3D/sphere.ts b/src/shape/point3D/sphere.ts
index 07a061b31c..1e27367b56 100644
--- a/src/shape/point3D/sphere.ts
+++ b/src/shape/point3D/sphere.ts
@@ -1,4 +1,4 @@
-import { MeshPhongMaterial, SphereGeometry, Mesh } from '@antv/g-plugin-3d';
+import { MeshLambertMaterial, SphereGeometry, Mesh } from '@antv/g-plugin-3d';
import { applyStyle, getOrigin, toOpacityKey } from '../utils';
import { ShapeComponent as SC } from '../../runtime';
import { select } from '../../utils/selection';
@@ -28,7 +28,7 @@ export const Sphere: SC = (options, context) => {
});
// create a material with Phong lighting model
// @ts-ignore
- context.sphereMaterial = new MeshPhongMaterial(device);
+ context.sphereMaterial = new MeshLambertMaterial(device);
}
return (points, value, defaults) => {