diff --git a/packages/g-camera-api/CHANGELOG.md b/packages/g-camera-api/CHANGELOG.md index 08ce58e08..a91a91679 100644 --- a/packages/g-camera-api/CHANGELOG.md +++ b/packages/g-camera-api/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-camera-api +## 1.2.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.2.12 ### Patch Changes diff --git a/packages/g-camera-api/package.json b/packages/g-camera-api/package.json index 077d8bea5..5a74c5b46 100644 --- a/packages/g-camera-api/package.json +++ b/packages/g-camera-api/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-camera-api", - "version": "1.2.12", + "version": "1.2.13", "description": "A simple implementation of Camera API.", "keywords": [ "antv", diff --git a/packages/g-canvas/CHANGELOG.md b/packages/g-canvas/CHANGELOG.md index 2c9a385d1..c09b44afb 100644 --- a/packages/g-canvas/CHANGELOG.md +++ b/packages/g-canvas/CHANGELOG.md @@ -1,5 +1,18 @@ # @antv/g-canvas +## 1.11.16 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + - @antv/g-plugin-canvas-path-generator@1.3.13 + - @antv/g-plugin-canvas-picker@1.10.13 + - @antv/g-plugin-canvas-renderer@1.9.13 + - @antv/g-plugin-dom-interaction@1.9.13 + - @antv/g-plugin-html-renderer@1.9.16 + - @antv/g-plugin-image-loader@1.3.13 + ## 1.11.15 ### Patch Changes diff --git a/packages/g-canvas/package.json b/packages/g-canvas/package.json index 249404722..77193a3f8 100644 --- a/packages/g-canvas/package.json +++ b/packages/g-canvas/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-canvas", - "version": "1.11.15", + "version": "1.11.16", "description": "A renderer implemented by Canvas 2D API", "keywords": [ "antv", diff --git a/packages/g-canvaskit/CHANGELOG.md b/packages/g-canvaskit/CHANGELOG.md index 65d0964f7..46f449f4c 100644 --- a/packages/g-canvaskit/CHANGELOG.md +++ b/packages/g-canvaskit/CHANGELOG.md @@ -1,5 +1,18 @@ # @antv/g-canvaskit +## 0.10.16 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + - @antv/g-plugin-canvas-path-generator@1.3.13 + - @antv/g-plugin-canvas-picker@1.10.13 + - @antv/g-plugin-canvaskit-renderer@1.3.13 + - @antv/g-plugin-dom-interaction@1.9.13 + - @antv/g-plugin-html-renderer@1.9.16 + - @antv/g-plugin-image-loader@1.3.13 + ## 0.10.15 ### Patch Changes diff --git a/packages/g-canvaskit/package.json b/packages/g-canvaskit/package.json index 617579803..adb44a272 100644 --- a/packages/g-canvaskit/package.json +++ b/packages/g-canvaskit/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-canvaskit", - "version": "0.10.15", + "version": "0.10.16", "description": "A renderer implemented by CanvasKit", "keywords": [ "antv", diff --git a/packages/g-components/CHANGELOG.md b/packages/g-components/CHANGELOG.md index d8f761e70..b736f609a 100644 --- a/packages/g-components/CHANGELOG.md +++ b/packages/g-components/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-components +## 1.9.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.9.12 ### Patch Changes diff --git a/packages/g-components/package.json b/packages/g-components/package.json index 5276c3fbf..f2e026558 100644 --- a/packages/g-components/package.json +++ b/packages/g-components/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-components", - "version": "1.9.12", + "version": "1.9.13", "description": "Components for g", "keywords": [ "antv", diff --git a/packages/g-dom-mutation-observer-api/CHANGELOG.md b/packages/g-dom-mutation-observer-api/CHANGELOG.md index 656c44131..87f617f4e 100644 --- a/packages/g-dom-mutation-observer-api/CHANGELOG.md +++ b/packages/g-dom-mutation-observer-api/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-dom-mutation-observer-api +## 1.2.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.2.12 ### Patch Changes diff --git a/packages/g-dom-mutation-observer-api/package.json b/packages/g-dom-mutation-observer-api/package.json index e931c8459..8fb354177 100644 --- a/packages/g-dom-mutation-observer-api/package.json +++ b/packages/g-dom-mutation-observer-api/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-dom-mutation-observer-api", - "version": "1.2.12", + "version": "1.2.13", "description": "A simple implementation of DOM MutationObserver API.", "keywords": [ "antv", diff --git a/packages/g-gesture/CHANGELOG.md b/packages/g-gesture/CHANGELOG.md index 771c99a83..832e251f1 100644 --- a/packages/g-gesture/CHANGELOG.md +++ b/packages/g-gesture/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-gesture +## 2.2.16 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 2.2.15 ### Patch Changes diff --git a/packages/g-gesture/package.json b/packages/g-gesture/package.json index 1328a6321..ea2ab6ee7 100644 --- a/packages/g-gesture/package.json +++ b/packages/g-gesture/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-gesture", - "version": "2.2.15", + "version": "2.2.16", "description": "G Gesture", "keywords": [ "antv", diff --git a/packages/g-image-exporter/CHANGELOG.md b/packages/g-image-exporter/CHANGELOG.md index 31ae6e497..5ced4b965 100644 --- a/packages/g-image-exporter/CHANGELOG.md +++ b/packages/g-image-exporter/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-image-exporter +## 0.7.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 0.7.12 ### Patch Changes diff --git a/packages/g-image-exporter/package.json b/packages/g-image-exporter/package.json index b7fd3169e..c9658b001 100644 --- a/packages/g-image-exporter/package.json +++ b/packages/g-image-exporter/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-image-exporter", - "version": "0.7.12", + "version": "0.7.13", "description": "A image exporter for G using DOM API", "keywords": [ "antv", diff --git a/packages/g-lite/CHANGELOG.md b/packages/g-lite/CHANGELOG.md index a783c8595..ffebc139b 100644 --- a/packages/g-lite/CHANGELOG.md +++ b/packages/g-lite/CHANGELOG.md @@ -1,5 +1,11 @@ # @antv/g-lite +## 1.2.13 + +### Patch Changes + +- e5d69c70: Fix gradient path & add more geometry. + ## 1.2.12 ### Patch Changes diff --git a/packages/g-lite/package.json b/packages/g-lite/package.json index 2c8fe8b8e..663b99acf 100644 --- a/packages/g-lite/package.json +++ b/packages/g-lite/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-lite", - "version": "1.2.12", + "version": "1.2.13", "description": "A core module for rendering engine implements DOM API.", "keywords": [ "antv", diff --git a/packages/g-lite/src/components/hierarchy/Hierarchy.ts b/packages/g-lite/src/components/hierarchy/Hierarchy.ts deleted file mode 100644 index 77793d3db..000000000 --- a/packages/g-lite/src/components/hierarchy/Hierarchy.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { Types, defineComponent } from 'bitecs'; - -export const HIERARCHY = { - /** - * The ID of the World entity the owner of this component belongs to - */ - WORLD: 0, - /** - * The ID of the Parent entity. If it has no parent, will match the world ID - */ - PARENT: 1, - /** - * The ID of the next entity in the display list (horizontally, the next sibling) - */ - NEXT: 2, - /** - * The ID of the previous entity in the display list (horizontally, the previous sibling) - */ - PREV: 3, - /** - * The ID of the left-most (first) child entity of this parent - */ - FIRST: 4, - /** - * The ID of the right-most (last) child entity of this parent - */ - LAST: 5, - /** - * The number of direct descendants this entity has - */ - NUM_CHILDREN: 6, - /** - * Reserved to allow for per-child depth sorting outside of the display list index - */ - DEPTH: 7, -}; - -export const HierarchyComponent = defineComponent({ - data: [Types.ui32, 8], -}); - -export function getParentID(id: number): number { - return HierarchyComponent.data[id][HIERARCHY.PARENT]; -} - -export function getFirstChildID(parentID: number): number { - return HierarchyComponent.data[parentID][HIERARCHY.FIRST]; -} - -export function getLastChildID(parentID: number): number { - return HierarchyComponent.data[parentID][HIERARCHY.LAST]; -} - -export function getPreviousSiblingID(id: number): number { - return HierarchyComponent.data[id][HIERARCHY.PREV]; -} - -export function getNextSiblingID(id: number): number { - return HierarchyComponent.data[id][HIERARCHY.NEXT]; -} - -export function clearHierarchyComponent(id: number): void { - HierarchyComponent.data[id].fill(0); -} - -export function setFirstChildID(parentID: number, childID: number): void { - HierarchyComponent.data[parentID][HIERARCHY.FIRST] = childID; -} - -export function setLastChildID(parentID: number, childID: number): void { - HierarchyComponent.data[parentID][HIERARCHY.LAST] = childID; -} - -export function setNextSiblingID(parentID: number, childID: number): void { - HierarchyComponent.data[parentID][HIERARCHY.NEXT] = childID; -} - -export function setPreviousSiblingID(parentID: number, childID: number): void { - HierarchyComponent.data[parentID][HIERARCHY.PREV] = childID; -} - -export function getParents(id: number): number[] { - const results = []; - - let currentParent = getParentID(id); - - while (currentParent) { - results.push(currentParent); - currentParent = getParentID(currentParent); - } - - return results; -} - -export function clearSiblings(id: number): void { - setNextSiblingID(id, 0); - setPreviousSiblingID(id, 0); -} - -export function linkSiblings(childA: number, childB: number): void { - setNextSiblingID(childA, childB); - setPreviousSiblingID(childB, childA); -} - -export function addChildIDAfter(afterID: number, childID: number): void { - const nextID = getNextSiblingID(afterID); - - if (nextID) { - linkSiblings(childID, nextID); - } else { - // childID is going to the end of the list - setNextSiblingID(childID, 0); - - const parentID = getParentID(childID); - - setLastChildID(parentID, childID); - } - - linkSiblings(afterID, childID); -} - -export function addChildIDBefore(beforeID: number, childID: number): void { - const prevID = getPreviousSiblingID(beforeID); - - if (prevID) { - linkSiblings(prevID, childID); - } else { - // childID is going to the start of the list - setPreviousSiblingID(childID, 0); - - const parentID = getParentID(childID); - - setFirstChildID(parentID, childID); - } - - linkSiblings(childID, beforeID); -} - -export function removeChildID(childID: number): void { - const parentID = getParentID(childID); - - const first = getFirstChildID(parentID); - const last = getLastChildID(parentID); - - const prevID = getPreviousSiblingID(childID); - const nextID = getNextSiblingID(childID); - - linkSiblings(prevID, nextID); - - if (first === childID) { - setFirstChildID(parentID, nextID); - } - - if (last === childID) { - setLastChildID(parentID, prevID); - } - - clearSiblings(childID); -} diff --git a/packages/g-lottie-player/CHANGELOG.md b/packages/g-lottie-player/CHANGELOG.md index 6e86a29fa..fe4c4c8f9 100644 --- a/packages/g-lottie-player/CHANGELOG.md +++ b/packages/g-lottie-player/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-lottie-player +## 0.2.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 0.2.12 ### Patch Changes diff --git a/packages/g-lottie-player/package.json b/packages/g-lottie-player/package.json index b680eb147..43047b8cf 100644 --- a/packages/g-lottie-player/package.json +++ b/packages/g-lottie-player/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-lottie-player", - "version": "0.2.12", + "version": "0.2.13", "description": "A lottie player for G", "keywords": [ "antv", diff --git a/packages/g-mobile-canvas-element/CHANGELOG.md b/packages/g-mobile-canvas-element/CHANGELOG.md index 16c35271f..5b07d0451 100644 --- a/packages/g-mobile-canvas-element/CHANGELOG.md +++ b/packages/g-mobile-canvas-element/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-mobile-canvas-element +## 0.8.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 0.8.12 ### Patch Changes diff --git a/packages/g-mobile-canvas-element/package.json b/packages/g-mobile-canvas-element/package.json index cedad085a..c9559e597 100644 --- a/packages/g-mobile-canvas-element/package.json +++ b/packages/g-mobile-canvas-element/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-mobile-canvas-element", - "version": "0.8.12", + "version": "0.8.13", "description": "Create a CanvasLike element from existed context in mobile environment", "keywords": [ "antv", diff --git a/packages/g-mobile-canvas/CHANGELOG.md b/packages/g-mobile-canvas/CHANGELOG.md index 64abc52b3..223b979b6 100644 --- a/packages/g-mobile-canvas/CHANGELOG.md +++ b/packages/g-mobile-canvas/CHANGELOG.md @@ -1,5 +1,19 @@ # @antv/g-mobile-canvas +## 0.11.2 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + - @antv/g-plugin-canvas-path-generator@1.3.13 + - @antv/g-plugin-canvas-picker@1.10.13 + - @antv/g-plugin-canvas-renderer@1.9.13 + - @antv/g-plugin-dragndrop@1.8.13 + - @antv/g-plugin-gesture@1.1.2 + - @antv/g-plugin-image-loader@1.3.13 + - @antv/g-plugin-mobile-interaction@0.9.13 + ## 0.11.1 ### Patch Changes diff --git a/packages/g-mobile-canvas/package.json b/packages/g-mobile-canvas/package.json index 74e6cb211..8dc0b92d9 100644 --- a/packages/g-mobile-canvas/package.json +++ b/packages/g-mobile-canvas/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-mobile-canvas", - "version": "0.11.1", + "version": "0.11.2", "description": "A renderer implemented with Canvas2D API in mobile environment", "keywords": [ "antv", diff --git a/packages/g-mobile-svg/CHANGELOG.md b/packages/g-mobile-svg/CHANGELOG.md index 7f96fea72..c2521c664 100644 --- a/packages/g-mobile-svg/CHANGELOG.md +++ b/packages/g-mobile-svg/CHANGELOG.md @@ -1,5 +1,16 @@ # @antv/g-mobile-svg +## 0.10.15 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + - @antv/g-plugin-dragndrop@1.8.13 + - @antv/g-plugin-mobile-interaction@0.9.13 + - @antv/g-plugin-svg-picker@1.9.15 + - @antv/g-plugin-svg-renderer@1.10.15 + ## 0.10.14 ### Patch Changes diff --git a/packages/g-mobile-svg/package.json b/packages/g-mobile-svg/package.json index 5540e3e83..c5bd3d68b 100644 --- a/packages/g-mobile-svg/package.json +++ b/packages/g-mobile-svg/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-mobile-svg", - "version": "0.10.14", + "version": "0.10.15", "description": "A renderer implemented by SVG in mobile environment", "keywords": [ "antv", diff --git a/packages/g-mobile-webgl/CHANGELOG.md b/packages/g-mobile-webgl/CHANGELOG.md index 51d49121a..445b443fa 100644 --- a/packages/g-mobile-webgl/CHANGELOG.md +++ b/packages/g-mobile-webgl/CHANGELOG.md @@ -1,5 +1,18 @@ # @antv/g-mobile-webgl +## 0.9.18 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-plugin-device-renderer@1.9.15 + - @antv/g-lite@1.2.13 + - @antv/g-plugin-webgl-device@1.9.15 + - @antv/g-plugin-dragndrop@1.8.13 + - @antv/g-plugin-html-renderer@1.9.16 + - @antv/g-plugin-image-loader@1.3.13 + - @antv/g-plugin-mobile-interaction@0.9.13 + ## 0.9.17 ### Patch Changes diff --git a/packages/g-mobile-webgl/package.json b/packages/g-mobile-webgl/package.json index 275fae518..5668163eb 100644 --- a/packages/g-mobile-webgl/package.json +++ b/packages/g-mobile-webgl/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-mobile-webgl", - "version": "0.9.17", + "version": "0.9.18", "description": "A renderer implemented by WebGL1/2 in mobile environment", "keywords": [ "antv", diff --git a/packages/g-pattern/CHANGELOG.md b/packages/g-pattern/CHANGELOG.md index 3eb16a2e9..fa4611054 100644 --- a/packages/g-pattern/CHANGELOG.md +++ b/packages/g-pattern/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-pattern +## 1.2.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.2.12 ### Patch Changes diff --git a/packages/g-pattern/package.json b/packages/g-pattern/package.json index e7d2f9fa6..fafc7a175 100644 --- a/packages/g-pattern/package.json +++ b/packages/g-pattern/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-pattern", - "version": "1.2.12", + "version": "1.2.13", "description": "A pattern libs for G", "keywords": [ "antv", diff --git a/packages/g-plugin-3d/CHANGELOG.md b/packages/g-plugin-3d/CHANGELOG.md index e04fba721..495be52af 100644 --- a/packages/g-plugin-3d/CHANGELOG.md +++ b/packages/g-plugin-3d/CHANGELOG.md @@ -1,5 +1,15 @@ # @antv/g-plugin-3d +## 1.9.15 + +### Patch Changes + +- e5d69c70: Fix gradient path & add more geometry. +- Updated dependencies [e5d69c70] + - @antv/g-plugin-device-renderer@1.9.15 + - @antv/g-shader-components@1.8.5 + - @antv/g-lite@1.2.13 + ## 1.9.14 ### Patch Changes diff --git a/packages/g-plugin-3d/package.json b/packages/g-plugin-3d/package.json index bed8ae109..2c7963ba0 100644 --- a/packages/g-plugin-3d/package.json +++ b/packages/g-plugin-3d/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-3d", - "version": "1.9.14", + "version": "1.9.15", "description": "Provide 3D extension for G", "keywords": [ "antv", diff --git a/packages/g-plugin-3d/src/geometries/CapsuleGeometry.ts b/packages/g-plugin-3d/src/geometries/CapsuleGeometry.ts new file mode 100644 index 000000000..3b1f3f8ee --- /dev/null +++ b/packages/g-plugin-3d/src/geometries/CapsuleGeometry.ts @@ -0,0 +1,95 @@ +import type { Device } from '@antv/g-plugin-device-renderer'; +import { ProceduralGeometry } from './ProceduralGeometry'; +import { createConeData } from './util'; + +export interface CapsuleGeometryProps { + /** + * The radius of the tube forming the body of the capsule + */ + radius: number; + /** + * The length of the body of the capsule from tip to tip + */ + height: number; + /** + * The number of divisions along the tubular length of the capsule + */ + heightSegments: number; + /** + * The number of divisions around the tubular body of the capsule + */ + sides: number; +} + +export class CapsuleGeometry extends ProceduralGeometry { + constructor(device: Device, props: Partial = {}) { + super(device, { + radius: 0.5, + height: 1, + heightSegments: 1, + sides: 20, + ...props, + }); + } + + get radius() { + return this.props.radius; + } + set radius(v) { + if (this.props.radius !== v) { + this.props.radius = v; + this.rebuildPosition(); + } + } + + get height() { + return this.props.height; + } + set height(v) { + if (this.props.height !== v) { + this.props.height = v; + this.rebuildPosition(); + } + } + + get heightSegments() { + return this.props.heightSegments; + } + set heightSegments(v) { + if (this.props.heightSegments !== v) { + this.props.heightSegments = v; + this.build(); + } + } + + get sides() { + return this.props.sides; + } + set sides(v) { + if (this.props.sides !== v) { + this.props.sides = v; + this.build(); + } + } + + createTopology() { + const { radius, height, heightSegments, sides } = this.props; + + const { indices, positions, normals, uvs, uvs1 } = createConeData( + radius, + radius, + height - 2 * radius, + heightSegments, + sides, + true, + ); + + return { + indices, + positions, + normals, + uvs, + uv1s: uvs1, + }; + } +} diff --git a/packages/g-plugin-3d/src/geometries/ConeGeometry.ts b/packages/g-plugin-3d/src/geometries/ConeGeometry.ts new file mode 100644 index 000000000..939d87954 --- /dev/null +++ b/packages/g-plugin-3d/src/geometries/ConeGeometry.ts @@ -0,0 +1,111 @@ +import type { Device } from '@antv/g-plugin-device-renderer'; +import { ProceduralGeometry } from './ProceduralGeometry'; +import { createConeData } from './util'; + +export interface ConeGeometryProps { + /** + * The base radius of the cone + */ + baseRadius: number; + /** + * The peak radius of the cone + */ + peakRadius: number; + /** + * The length of the body of the cylinder + */ + height: number; + /** + * The number of divisions along the length of the cylinder + */ + heightSegments: number; + /** + * The number of divisions around the tubular body of the cylinder + */ + capSegments: number; +} + +export class ConeGeometry extends ProceduralGeometry { + constructor(device: Device, props: Partial = {}) { + super(device, { + baseRadius: 0.5, + peakRadius: 0, + height: 1, + heightSegments: 5, + capSegments: 18, + ...props, + }); + } + + get baseRadius() { + return this.props.baseRadius; + } + set baseRadius(v) { + if (this.props.baseRadius !== v) { + this.props.baseRadius = v; + this.rebuildPosition(); + } + } + + get peakRadius() { + return this.props.peakRadius; + } + set peakRadius(v) { + if (this.props.peakRadius !== v) { + this.props.peakRadius = v; + this.rebuildPosition(); + } + } + + get height() { + return this.props.height; + } + set height(v) { + if (this.props.height !== v) { + this.props.height = v; + this.rebuildPosition(); + } + } + + get heightSegments() { + return this.props.heightSegments; + } + set heightSegments(v) { + if (this.props.heightSegments !== v) { + this.props.heightSegments = v; + this.build(); + } + } + + get capSegments() { + return this.props.capSegments; + } + set capSegments(v) { + if (this.props.capSegments !== v) { + this.props.capSegments = v; + this.build(); + } + } + + createTopology() { + const { baseRadius, peakRadius, height, heightSegments, capSegments } = + this.props; + + const { indices, positions, normals, uvs, uvs1 } = createConeData( + baseRadius, + peakRadius, + height, + heightSegments, + capSegments, + false, + ); + + return { + indices, + positions, + normals, + uvs, + uv1s: uvs1, + }; + } +} diff --git a/packages/g-plugin-3d/src/geometries/CubeGeometry.ts b/packages/g-plugin-3d/src/geometries/CubeGeometry.ts index db61d7864..b6831fdc5 100644 --- a/packages/g-plugin-3d/src/geometries/CubeGeometry.ts +++ b/packages/g-plugin-3d/src/geometries/CubeGeometry.ts @@ -1,17 +1,15 @@ import type { Device } from '@antv/g-plugin-device-renderer'; import { vec3 } from 'gl-matrix'; import { ProceduralGeometry } from './ProceduralGeometry'; - -const primitiveUv1Padding = 4.0 / 64; -const primitiveUv1PaddingScale = 1.0 - primitiveUv1Padding * 2; +import { primitiveUv1Padding, primitiveUv1PaddingScale } from './util'; export interface CubeGeometryProps { height: number; width: number; depth: number; - widthSegments?: number; - heightSegments?: number; - depthSegments?: number; + widthSegments: number; + heightSegments: number; + depthSegments: number; } export class CubeGeometry extends ProceduralGeometry { diff --git a/packages/g-plugin-3d/src/geometries/CylinderGeometry.ts b/packages/g-plugin-3d/src/geometries/CylinderGeometry.ts new file mode 100644 index 000000000..27ce83a68 --- /dev/null +++ b/packages/g-plugin-3d/src/geometries/CylinderGeometry.ts @@ -0,0 +1,95 @@ +import type { Device } from '@antv/g-plugin-device-renderer'; +import { ProceduralGeometry } from './ProceduralGeometry'; +import { createConeData } from './util'; + +export interface CylinderGeometryProps { + /** + * The radius of the tube forming the body of the cylinder + */ + radius: number; + /** + * The length of the body of the cylinder + */ + height: number; + /** + * The number of divisions along the length of the cylinder + */ + heightSegments: number; + /** + * The number of divisions around the tubular body of the cylinder + */ + capSegments: number; +} + +export class CylinderGeometry extends ProceduralGeometry { + constructor(device: Device, props: Partial = {}) { + super(device, { + radius: 0.5, + height: 1, + heightSegments: 5, + capSegments: 20, + ...props, + }); + } + + get radius() { + return this.props.radius; + } + set radius(v) { + if (this.props.radius !== v) { + this.props.radius = v; + this.rebuildPosition(); + } + } + + get height() { + return this.props.height; + } + set height(v) { + if (this.props.height !== v) { + this.props.height = v; + this.rebuildPosition(); + } + } + + get heightSegments() { + return this.props.heightSegments; + } + set heightSegments(v) { + if (this.props.heightSegments !== v) { + this.props.heightSegments = v; + this.build(); + } + } + + get capSegments() { + return this.props.capSegments; + } + set capSegments(v) { + if (this.props.capSegments !== v) { + this.props.capSegments = v; + this.build(); + } + } + + createTopology() { + const { radius, height, heightSegments, capSegments } = this.props; + + const { indices, positions, normals, uvs, uvs1 } = createConeData( + radius, + radius, + height, + heightSegments, + capSegments, + false, + ); + + return { + indices, + positions, + normals, + uvs, + uv1s: uvs1, + }; + } +} diff --git a/packages/g-plugin-3d/src/geometries/PlaneGeometry.ts b/packages/g-plugin-3d/src/geometries/PlaneGeometry.ts index 25f820b60..f5fb55637 100644 --- a/packages/g-plugin-3d/src/geometries/PlaneGeometry.ts +++ b/packages/g-plugin-3d/src/geometries/PlaneGeometry.ts @@ -4,8 +4,8 @@ import { ProceduralGeometry } from './ProceduralGeometry'; export interface PlaneGeometryProps { width: number; depth: number; - widthSegments?: number; - depthSegments?: number; + widthSegments: number; + depthSegments: number; } export class PlaneGeometry extends ProceduralGeometry { @@ -65,7 +65,12 @@ export class PlaneGeometry extends ProceduralGeometry { const uvs: number[] = []; const indices: number[] = []; - const { widthSegments = 5, depthSegments = 5, width = 1, depth = 1 } = this.props; + const { + widthSegments = 5, + depthSegments = 5, + width = 1, + depth = 1, + } = this.props; const he = { x: width / 2, y: depth / 2 }; const ws = widthSegments; diff --git a/packages/g-plugin-3d/src/geometries/SphereGeometry.ts b/packages/g-plugin-3d/src/geometries/SphereGeometry.ts index 2d94a2162..91d634d93 100644 --- a/packages/g-plugin-3d/src/geometries/SphereGeometry.ts +++ b/packages/g-plugin-3d/src/geometries/SphereGeometry.ts @@ -3,8 +3,8 @@ import { ProceduralGeometry } from './ProceduralGeometry'; export interface SphereGeometryProps { radius: number; - latitudeBands?: number; - longitudeBands?: number; + latitudeBands: number; + longitudeBands: number; } export class SphereGeometry extends ProceduralGeometry { diff --git a/packages/g-plugin-3d/src/geometries/TorusGeometry.ts b/packages/g-plugin-3d/src/geometries/TorusGeometry.ts index 34d05c99f..eff55e0c3 100644 --- a/packages/g-plugin-3d/src/geometries/TorusGeometry.ts +++ b/packages/g-plugin-3d/src/geometries/TorusGeometry.ts @@ -2,10 +2,10 @@ import type { Device } from '@antv/g-plugin-device-renderer'; import { ProceduralGeometry } from './ProceduralGeometry'; export interface TorusGeometryProps { - tubeRadius?: number; - ringRadius?: number; - segments?: number; - sides?: number; + tubeRadius: number; + ringRadius: number; + segments: number; + sides: number; } export class TorusGeometry extends ProceduralGeometry { @@ -71,7 +71,12 @@ export class TorusGeometry extends ProceduralGeometry { let i: number; let j: number; - const { tubeRadius = 0.2, ringRadius = 0.3, segments = 30, sides = 20 } = this.props; + const { + tubeRadius = 0.2, + ringRadius = 0.3, + segments = 30, + sides = 20, + } = this.props; const rc = tubeRadius; const rt = ringRadius; @@ -91,9 +96,13 @@ export class TorusGeometry extends ProceduralGeometry { Math.sin((2.0 * Math.PI * j) / segments) * (rt + rc * Math.cos((2.0 * Math.PI * i) / sides)); - nx = Math.cos((2.0 * Math.PI * j) / segments) * Math.cos((2.0 * Math.PI * i) / sides); + nx = + Math.cos((2.0 * Math.PI * j) / segments) * + Math.cos((2.0 * Math.PI * i) / sides); ny = Math.sin((2.0 * Math.PI * i) / sides); - nz = Math.sin((2.0 * Math.PI * j) / segments) * Math.cos((2.0 * Math.PI * i) / sides); + nz = + Math.sin((2.0 * Math.PI * j) / segments) * + Math.cos((2.0 * Math.PI * i) / sides); u = i / sides; v = 1.0 - j / segments; diff --git a/packages/g-plugin-3d/src/geometries/index.ts b/packages/g-plugin-3d/src/geometries/index.ts index 0f3eaf7d5..2b53095a1 100644 --- a/packages/g-plugin-3d/src/geometries/index.ts +++ b/packages/g-plugin-3d/src/geometries/index.ts @@ -3,3 +3,6 @@ export * from './CubeGeometry'; export * from './SphereGeometry'; export * from './TorusGeometry'; export * from './PlaneGeometry'; +export * from './CylinderGeometry'; +export * from './ConeGeometry'; +export * from './CapsuleGeometry'; diff --git a/packages/g-plugin-3d/src/geometries/util.ts b/packages/g-plugin-3d/src/geometries/util.ts new file mode 100644 index 000000000..5a569d8a3 --- /dev/null +++ b/packages/g-plugin-3d/src/geometries/util.ts @@ -0,0 +1,259 @@ +import { vec3 } from 'gl-matrix'; + +export const primitiveUv1Padding = 4.0 / 64; +export const primitiveUv1PaddingScale = 1.0 - primitiveUv1Padding * 2; + +export function createConeData( + baseRadius: number, + peakRadius: number, + height: number, + heightSegments: number, + capSegments: number, + roundedCaps: boolean, +) { + // Variable declarations + let i: number, + j: number, + x: number, + y: number, + z: number, + u: number, + v: number; + const pos = vec3.create(); + const bottomToTop = vec3.create(); + const norm = vec3.create(); + let top: vec3, bottom: vec3, tangent: vec3; + + const positions: number[] = []; + const normals: number[] = []; + const uvs: number[] = []; + const uvs1: number[] = []; + const indices: number[] = []; + + let theta: number, cosTheta: number, sinTheta: number; + let phi: number, sinPhi: number, cosPhi: number; + let first: number, second: number, third: number, fourth: number; + let offset: number; + + // Define the body of the cone/cylinder + if (height > 0) { + for (i = 0; i <= heightSegments; i++) { + for (j = 0; j <= capSegments; j++) { + // Sweep the cone body from the positive Y axis to match a 3DS Max cone/cylinder + theta = (j / capSegments) * 2.0 * Math.PI - Math.PI; + sinTheta = Math.sin(theta); + cosTheta = Math.cos(theta); + bottom = vec3.fromValues( + sinTheta * baseRadius, + -height / 2.0, + cosTheta * baseRadius, + ); + top = vec3.fromValues( + sinTheta * peakRadius, + height / 2.0, + cosTheta * peakRadius, + ); + vec3.lerp(pos, bottom, top, i / heightSegments); + vec3.normalize(bottomToTop, vec3.sub(bottomToTop, top, bottom)); + // bottomToTop.sub2(top, bottom).normalize(); + tangent = vec3.fromValues(cosTheta, 0.0, -sinTheta); + vec3.normalize(norm, vec3.cross(norm, tangent, bottomToTop)); + // norm.cross(tangent, bottomToTop).normalize(); + + positions.push(pos[0], pos[1], pos[2]); + normals.push(norm[0], norm[1], norm[2]); + u = j / capSegments; + v = i / heightSegments; + uvs.push(u, 1.0 - v); + + // Pack UV1 to 1st third + const _v = v; + v = u; + u = _v; + u /= 3; + u = u * primitiveUv1PaddingScale + primitiveUv1Padding; + v = v * primitiveUv1PaddingScale + primitiveUv1Padding; + uvs1.push(u, 1.0 - v); + + if (i < heightSegments && j < capSegments) { + first = i * (capSegments + 1) + j; + second = i * (capSegments + 1) + (j + 1); + third = (i + 1) * (capSegments + 1) + j; + fourth = (i + 1) * (capSegments + 1) + (j + 1); + + indices.push(first, second, third); + indices.push(second, fourth, third); + } + } + } + } + + if (roundedCaps) { + let lat: number, lon: number; + const latitudeBands = Math.floor(capSegments / 2); + const longitudeBands = capSegments; + const capOffset = height / 2; + + // Generate top cap + for (lat = 0; lat <= latitudeBands; lat++) { + theta = (lat * Math.PI * 0.5) / latitudeBands; + sinTheta = Math.sin(theta); + cosTheta = Math.cos(theta); + + for (lon = 0; lon <= longitudeBands; lon++) { + // Sweep the sphere from the positive Z axis to match a 3DS Max sphere + phi = (lon * 2 * Math.PI) / longitudeBands - Math.PI / 2.0; + sinPhi = Math.sin(phi); + cosPhi = Math.cos(phi); + + x = cosPhi * sinTheta; + y = cosTheta; + z = sinPhi * sinTheta; + u = 1.0 - lon / longitudeBands; + v = 1.0 - lat / latitudeBands; + + positions.push( + x * peakRadius, + y * peakRadius + capOffset, + z * peakRadius, + ); + normals.push(x, y, z); + uvs.push(u, 1.0 - v); + + // Pack UV1 to 2nd third + u /= 3; + v /= 3; + u = u * primitiveUv1PaddingScale + primitiveUv1Padding; + v = v * primitiveUv1PaddingScale + primitiveUv1Padding; + u += 1.0 / 3; + uvs1.push(u, 1.0 - v); + } + } + + offset = (heightSegments + 1) * (capSegments + 1); + for (lat = 0; lat < latitudeBands; ++lat) { + for (lon = 0; lon < longitudeBands; ++lon) { + first = lat * (longitudeBands + 1) + lon; + second = first + longitudeBands + 1; + + indices.push(offset + first + 1, offset + second, offset + first); + indices.push(offset + first + 1, offset + second + 1, offset + second); + } + } + + // Generate bottom cap + for (lat = 0; lat <= latitudeBands; lat++) { + theta = Math.PI * 0.5 + (lat * Math.PI * 0.5) / latitudeBands; + sinTheta = Math.sin(theta); + cosTheta = Math.cos(theta); + + for (lon = 0; lon <= longitudeBands; lon++) { + // Sweep the sphere from the positive Z axis to match a 3DS Max sphere + phi = (lon * 2 * Math.PI) / longitudeBands - Math.PI / 2.0; + sinPhi = Math.sin(phi); + cosPhi = Math.cos(phi); + + x = cosPhi * sinTheta; + y = cosTheta; + z = sinPhi * sinTheta; + u = 1.0 - lon / longitudeBands; + v = 1.0 - lat / latitudeBands; + + positions.push( + x * peakRadius, + y * peakRadius - capOffset, + z * peakRadius, + ); + normals.push(x, y, z); + uvs.push(u, 1.0 - v); + + // Pack UV1 to 3rd third + u /= 3; + v /= 3; + u = u * primitiveUv1PaddingScale + primitiveUv1Padding; + v = v * primitiveUv1PaddingScale + primitiveUv1Padding; + u += 2.0 / 3; + uvs1.push(u, 1.0 - v); + } + } + + offset = + (heightSegments + 1) * (capSegments + 1) + + (longitudeBands + 1) * (latitudeBands + 1); + for (lat = 0; lat < latitudeBands; ++lat) { + for (lon = 0; lon < longitudeBands; ++lon) { + first = lat * (longitudeBands + 1) + lon; + second = first + longitudeBands + 1; + + indices.push(offset + first + 1, offset + second, offset + first); + indices.push(offset + first + 1, offset + second + 1, offset + second); + } + } + } else { + // Generate bottom cap + offset = (heightSegments + 1) * (capSegments + 1); + if (baseRadius > 0.0) { + for (i = 0; i < capSegments; i++) { + theta = (i / capSegments) * 2.0 * Math.PI; + x = Math.sin(theta); + y = -height / 2.0; + z = Math.cos(theta); + u = 1.0 - (x + 1.0) / 2.0; + v = (z + 1.0) / 2.0; + + positions.push(x * baseRadius, y, z * baseRadius); + normals.push(0.0, -1.0, 0.0); + uvs.push(u, 1.0 - v); + + // Pack UV1 to 2nd third + u /= 3; + v /= 3; + u = u * primitiveUv1PaddingScale + primitiveUv1Padding; + v = v * primitiveUv1PaddingScale + primitiveUv1Padding; + u += 1.0 / 3; + uvs1.push(u, 1.0 - v); + + if (i > 1) { + indices.push(offset, offset + i, offset + i - 1); + } + } + } + + // Generate top cap + offset += capSegments; + if (peakRadius > 0.0) { + for (i = 0; i < capSegments; i++) { + theta = (i / capSegments) * 2.0 * Math.PI; + x = Math.sin(theta); + y = height / 2.0; + z = Math.cos(theta); + u = 1.0 - (x + 1.0) / 2.0; + v = (z + 1.0) / 2.0; + + positions.push(x * peakRadius, y, z * peakRadius); + normals.push(0.0, 1.0, 0.0); + uvs.push(u, 1.0 - v); + + // Pack UV1 to 3rd third + u /= 3; + v /= 3; + u = u * primitiveUv1PaddingScale + primitiveUv1Padding; + v = v * primitiveUv1PaddingScale + primitiveUv1Padding; + u += 2.0 / 3; + uvs1.push(u, 1.0 - v); + + if (i > 1) { + indices.push(offset, offset + i - 1, offset + i); + } + } + } + } + + return { + positions: positions, + normals: normals, + uvs: uvs, + uvs1: uvs1, + indices: indices, + }; +} diff --git a/packages/g-plugin-3d/src/materials/MeshLambertMaterial.ts b/packages/g-plugin-3d/src/materials/MeshLambertMaterial.ts new file mode 100644 index 000000000..18bef478d --- /dev/null +++ b/packages/g-plugin-3d/src/materials/MeshLambertMaterial.ts @@ -0,0 +1,104 @@ +import type { CSSRGB } from '@antv/g-lite'; +import { parseColor } from '@antv/g-lite'; +import type { Device, Texture } from '@antv/g-plugin-device-renderer'; +import frag from '../shaders/material.lambert.frag'; +import vert from '../shaders/material.lambert.vert'; +import type { IMeshBasicMaterial } from './MeshBasicMaterial'; +import { MeshBasicMaterial } from './MeshBasicMaterial'; + +export interface IMeshLambertMaterial extends IMeshBasicMaterial { + emissive: string; + bumpMap: Texture; + bumpScale: number; + doubleSide: boolean; +} + +enum Uniform { + EMISSIVE = 'u_Emissive', + BUMP_SCALE = 'u_BumpScale', + BUMP_MAP = 'u_BumpMap', +} + +export class MeshLambertMaterial extends MeshBasicMaterial { + get emissive() { + return this.props.emissive; + } + set emissive(v) { + this.props.emissive = v; + const emissiveColor = parseColor(v) as CSSRGB; + this.setUniforms({ + [Uniform.EMISSIVE]: [ + Number(emissiveColor.r) / 255, + Number(emissiveColor.g) / 255, + Number(emissiveColor.b) / 255, + ], + }); + } + + get bumpMap() { + return this.props.bumpMap; + } + set bumpMap(v) { + if (this.props.map !== v) { + this.props.bumpMap = v; + this.programDirty = true; + } + + this.defines.USE_BUMPMAP = !!v; + this.setUniforms({ + [Uniform.BUMP_MAP]: v, + [Uniform.BUMP_SCALE]: this.bumpScale, + }); + } + get bumpScale() { + return this.props.bumpScale; + } + set bumpScale(v) { + this.props.bumpScale = v; + this.setUniforms({ + [Uniform.BUMP_SCALE]: v, + }); + } + + get doubleSide() { + return this.props.doubleSide; + } + set doubleSide(v) { + this.props.doubleSide = v; + this.defines.USE_DOUBLESIDE = v; + } + + constructor(device: Device, props?: Partial) { + super(device, { + vertexShader: vert, + fragmentShader: frag, + emissive: 'black', + bumpScale: 1, + doubleSide: false, + ...props, + }); + + const { bumpMap, doubleSide, emissive } = this; + + const emissiveColor = parseColor(emissive) as CSSRGB; + this.setUniforms({ + u_Placeholder: null, + [Uniform.EMISSIVE]: [ + Number(emissiveColor.r) / 255, + Number(emissiveColor.g) / 255, + Number(emissiveColor.b) / 255, + ], + }); + + if (bumpMap) { + this.bumpMap = bumpMap; + } + + this.doubleSide = doubleSide; + + this.defines = { + ...this.defines, + USE_LIGHT: true, + }; + } +} diff --git a/packages/g-plugin-3d/src/materials/MeshPhongMaterial.ts b/packages/g-plugin-3d/src/materials/MeshPhongMaterial.ts index fc2faeeb7..9ab7ba021 100644 --- a/packages/g-plugin-3d/src/materials/MeshPhongMaterial.ts +++ b/packages/g-plugin-3d/src/materials/MeshPhongMaterial.ts @@ -126,7 +126,8 @@ export class MeshPhongMaterial extends MeshBasicMaterial { ...props, }); - const { specularMap, bumpMap, doubleSide, emissive, shininess, specular } = this; + const { specularMap, bumpMap, doubleSide, emissive, shininess, specular } = + this; const emissiveColor = parseColor(emissive) as CSSRGB; const specularColor = parseColor(specular) as CSSRGB; @@ -157,6 +158,7 @@ export class MeshPhongMaterial extends MeshBasicMaterial { this.defines = { ...this.defines, + USE_LIGHT: true, }; } } diff --git a/packages/g-plugin-3d/src/materials/index.ts b/packages/g-plugin-3d/src/materials/index.ts index 652fddd10..bb582609b 100644 --- a/packages/g-plugin-3d/src/materials/index.ts +++ b/packages/g-plugin-3d/src/materials/index.ts @@ -1,3 +1,4 @@ export * from './MeshBasicMaterial'; export * from './MeshPhongMaterial'; +export * from './MeshLambertMaterial'; export * from './PointMaterial'; diff --git a/packages/g-plugin-3d/src/shaders/material.lambert.frag b/packages/g-plugin-3d/src/shaders/material.lambert.frag new file mode 100644 index 000000000..642918490 --- /dev/null +++ b/packages/g-plugin-3d/src/shaders/material.lambert.frag @@ -0,0 +1,58 @@ +#pragma glslify: import('@antv/g-shader-components/common.glsl') +#pragma glslify: import('@antv/g-shader-components/scene.both.glsl') +#pragma glslify: import('@antv/g-shader-components/material.lambert.glsl') + +#pragma glslify: import('@antv/g-shader-components/batch.declaration.frag') +#pragma glslify: import('@antv/g-shader-components/uv.declaration.frag') +#pragma glslify: import('@antv/g-shader-components/map.declaration.frag') +#pragma glslify: import('@antv/g-shader-components/bumpmap.declaration.frag') +#pragma glslify: import('@antv/g-shader-components/specularmap.declaration.frag') +#pragma glslify: import('@antv/g-shader-components/bsdf.declaration.frag') +#pragma glslify: import('@antv/g-shader-components/wireframe.declaration.frag') +#pragma glslify: import('@antv/g-shader-components/fog.declaration.frag') +#pragma glslify: import('@antv/g-shader-components/light.begin.declaration.frag') +#pragma glslify: import('@antv/g-shader-components/light.lambert.declaration.frag') + +in vec3 v_ViewPosition; +in vec3 v_Normal; + +out vec4 outputColor; + +void main() { + #pragma glslify: import('@antv/g-shader-components/batch.frag') + + // diffusemap + #pragma glslify: import('@antv/g-shader-components/map.frag') + // specularmap + #pragma glslify: import('@antv/g-shader-components/specularmap.frag') + // bumpmap & normalmap + #pragma glslify: import('@antv/g-shader-components/normal.frag') + #pragma glslify: import('@antv/g-shader-components/normalmap.frag') + + if (u_IsPicking > 0.5) { + if (u_PickingColor.x == 0.0 && u_PickingColor.y == 0.0 && u_PickingColor.z == 0.0) { + discard; + } + outputColor = vec4(u_PickingColor, 1.0); + } else { + outputColor = u_Color; + outputColor.a = outputColor.a * u_Opacity; + + vec4 diffuseColor = outputColor; + ReflectedLight reflectedLight = ReflectedLight(vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 )); + vec3 totalEmissiveRadiance = u_Emissive; + + // calculate lighting accumulation + #pragma glslify: import('@antv/g-shader-components/light.lambert.frag') + #pragma glslify: import('@antv/g-shader-components/light.begin.frag') + #pragma glslify: import('@antv/g-shader-components/light.end.frag') + + vec3 outgoingLight = reflectedLight.directDiffuse + + reflectedLight.indirectDiffuse + + totalEmissiveRadiance; + + #pragma glslify: import('@antv/g-shader-components/output.frag') + #pragma glslify: import('@antv/g-shader-components/wireframe.frag') + #pragma glslify: import('@antv/g-shader-components/fog.frag') + } +} \ No newline at end of file diff --git a/packages/g-plugin-3d/src/shaders/material.lambert.vert b/packages/g-plugin-3d/src/shaders/material.lambert.vert new file mode 100644 index 000000000..2eb42937a --- /dev/null +++ b/packages/g-plugin-3d/src/shaders/material.lambert.vert @@ -0,0 +1,41 @@ +#pragma glslify: import('@antv/g-shader-components/common.glsl') +#pragma glslify: import('@antv/g-shader-components/scene.both.glsl') +#pragma glslify: import('@antv/g-shader-components/material.lambert.glsl') + +#pragma glslify: import('@antv/g-shader-components/batch.declaration.vert') +#pragma glslify: project = require('@antv/g-shader-components/project.vert') + +layout(location = POSITION) in vec3 a_Position; +layout(location = NORMAL) in vec3 a_Normal; + +#ifdef USE_UV + layout(location = UV) in vec2 a_Uv; + out vec2 v_Uv; +#endif + +#ifdef USE_WIREFRAME + layout(location = BARYCENTRIC) in vec3 a_Barycentric; + out vec3 v_Barycentric; +#endif + +out vec3 v_ViewPosition; +out vec3 v_Normal; + +void main() { + #pragma glslify: import('@antv/g-shader-components/batch.vert') + + vec4 position = vec4(a_Position, 1.0); + + gl_Position = project(position, u_ProjectionMatrix, u_ViewMatrix, u_ModelMatrix); + + vec4 mvPosition = u_ViewMatrix * u_ModelMatrix * position; + v_ViewPosition = - mvPosition.xyz; + + // v_ViewPosition = vec3(mvPosition) / mvPosition.w; + + mat3 normalWorld = mat3(transposeMat3(inverseMat3(mat3(u_ViewMatrix * u_ModelMatrix)))); + v_Normal = normalize(normalWorld * a_Normal); + + #pragma glslify: import('@antv/g-shader-components/uv.vert') + #pragma glslify: import('@antv/g-shader-components/wireframe.vert') +} \ No newline at end of file diff --git a/packages/g-plugin-3d/src/shaders/material.phong.frag b/packages/g-plugin-3d/src/shaders/material.phong.frag index 214a4b6c0..dfe260c9a 100644 --- a/packages/g-plugin-3d/src/shaders/material.phong.frag +++ b/packages/g-plugin-3d/src/shaders/material.phong.frag @@ -1,7 +1,6 @@ #pragma glslify: import('@antv/g-shader-components/common.glsl') #pragma glslify: import('@antv/g-shader-components/scene.both.glsl') #pragma glslify: import('@antv/g-shader-components/material.phong.glsl') -#pragma glslify: import('@antv/g-shader-components/light.both.glsl') #pragma glslify: import('@antv/g-shader-components/batch.declaration.frag') #pragma glslify: import('@antv/g-shader-components/uv.declaration.frag') @@ -11,6 +10,7 @@ #pragma glslify: import('@antv/g-shader-components/bsdf.declaration.frag') #pragma glslify: import('@antv/g-shader-components/wireframe.declaration.frag') #pragma glslify: import('@antv/g-shader-components/fog.declaration.frag') +#pragma glslify: import('@antv/g-shader-components/light.begin.declaration.frag') #pragma glslify: import('@antv/g-shader-components/light.phong.declaration.frag') in vec3 v_ViewPosition; diff --git a/packages/g-plugin-3d/src/shaders/material.phong.vert b/packages/g-plugin-3d/src/shaders/material.phong.vert index 0a0c5e081..0aaecb417 100644 --- a/packages/g-plugin-3d/src/shaders/material.phong.vert +++ b/packages/g-plugin-3d/src/shaders/material.phong.vert @@ -1,7 +1,6 @@ #pragma glslify: import('@antv/g-shader-components/common.glsl') #pragma glslify: import('@antv/g-shader-components/scene.both.glsl') #pragma glslify: import('@antv/g-shader-components/material.phong.glsl') -#pragma glslify: import('@antv/g-shader-components/light.both.glsl') #pragma glslify: import('@antv/g-shader-components/batch.declaration.vert') #pragma glslify: project = require('@antv/g-shader-components/project.vert') diff --git a/packages/g-plugin-a11y/CHANGELOG.md b/packages/g-plugin-a11y/CHANGELOG.md index f996a1eae..b34698744 100644 --- a/packages/g-plugin-a11y/CHANGELOG.md +++ b/packages/g-plugin-a11y/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-plugin-a11y +## 0.6.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 0.6.12 ### Patch Changes diff --git a/packages/g-plugin-a11y/package.json b/packages/g-plugin-a11y/package.json index d7cf4289a..004390061 100644 --- a/packages/g-plugin-a11y/package.json +++ b/packages/g-plugin-a11y/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-a11y", - "version": "0.6.12", + "version": "0.6.13", "description": "A G plugin for accessibility", "keywords": [ "antv", diff --git a/packages/g-plugin-annotation/CHANGELOG.md b/packages/g-plugin-annotation/CHANGELOG.md index 1985d5bbe..c1fcf5a4a 100644 --- a/packages/g-plugin-annotation/CHANGELOG.md +++ b/packages/g-plugin-annotation/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-plugin-annotation +## 0.4.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 0.4.12 ### Patch Changes diff --git a/packages/g-plugin-annotation/package.json b/packages/g-plugin-annotation/package.json index 1e23f0d18..3d733e087 100644 --- a/packages/g-plugin-annotation/package.json +++ b/packages/g-plugin-annotation/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-annotation", - "version": "0.4.12", + "version": "0.4.13", "description": "A G plugin for annotation", "keywords": [ "antv", diff --git a/packages/g-plugin-box2d/CHANGELOG.md b/packages/g-plugin-box2d/CHANGELOG.md index 479950208..f6ffbbb78 100644 --- a/packages/g-plugin-box2d/CHANGELOG.md +++ b/packages/g-plugin-box2d/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-plugin-box2d +## 1.9.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.9.12 ### Patch Changes diff --git a/packages/g-plugin-box2d/package.json b/packages/g-plugin-box2d/package.json index 5253aa7a2..3546fc325 100644 --- a/packages/g-plugin-box2d/package.json +++ b/packages/g-plugin-box2d/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-box2d", - "version": "1.9.12", + "version": "1.9.13", "description": "A G plugin for Box2D", "keywords": [ "antv", diff --git a/packages/g-plugin-canvas-path-generator/CHANGELOG.md b/packages/g-plugin-canvas-path-generator/CHANGELOG.md index b3928a5c7..3a8950594 100644 --- a/packages/g-plugin-canvas-path-generator/CHANGELOG.md +++ b/packages/g-plugin-canvas-path-generator/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-plugin-canvas-path-generator +## 1.3.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.3.12 ### Patch Changes diff --git a/packages/g-plugin-canvas-path-generator/package.json b/packages/g-plugin-canvas-path-generator/package.json index 0f05b0bdf..a69d33a16 100644 --- a/packages/g-plugin-canvas-path-generator/package.json +++ b/packages/g-plugin-canvas-path-generator/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-canvas-path-generator", - "version": "1.3.12", + "version": "1.3.13", "description": "A G plugin of path generator with Canvas2D API", "keywords": [ "antv", diff --git a/packages/g-plugin-canvas-picker/CHANGELOG.md b/packages/g-plugin-canvas-picker/CHANGELOG.md index c2cf95146..07f765553 100644 --- a/packages/g-plugin-canvas-picker/CHANGELOG.md +++ b/packages/g-plugin-canvas-picker/CHANGELOG.md @@ -1,5 +1,14 @@ # @antv/g-plugin-canvas-picker +## 1.10.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + - @antv/g-plugin-canvas-path-generator@1.3.13 + - @antv/g-plugin-canvas-renderer@1.9.13 + ## 1.10.12 ### Patch Changes diff --git a/packages/g-plugin-canvas-picker/package.json b/packages/g-plugin-canvas-picker/package.json index 49ecdaa7b..bf45df721 100644 --- a/packages/g-plugin-canvas-picker/package.json +++ b/packages/g-plugin-canvas-picker/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-canvas-picker", - "version": "1.10.12", + "version": "1.10.13", "description": "A G plugin for picking in canvas", "keywords": [ "antv", diff --git a/packages/g-plugin-canvas-renderer/CHANGELOG.md b/packages/g-plugin-canvas-renderer/CHANGELOG.md index 355f2d0a6..c6754d4a0 100644 --- a/packages/g-plugin-canvas-renderer/CHANGELOG.md +++ b/packages/g-plugin-canvas-renderer/CHANGELOG.md @@ -1,5 +1,14 @@ # @antv/g-plugin-canvas-renderer +## 1.9.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + - @antv/g-plugin-canvas-path-generator@1.3.13 + - @antv/g-plugin-image-loader@1.3.13 + ## 1.9.12 ### Patch Changes diff --git a/packages/g-plugin-canvas-renderer/package.json b/packages/g-plugin-canvas-renderer/package.json index 815ce6e49..21eab8c32 100644 --- a/packages/g-plugin-canvas-renderer/package.json +++ b/packages/g-plugin-canvas-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-canvas-renderer", - "version": "1.9.12", + "version": "1.9.13", "description": "A G plugin of renderer implementation with Canvas2D API", "keywords": [ "antv", diff --git a/packages/g-plugin-canvaskit-renderer/CHANGELOG.md b/packages/g-plugin-canvaskit-renderer/CHANGELOG.md index 01ccf7d76..e90aba112 100644 --- a/packages/g-plugin-canvaskit-renderer/CHANGELOG.md +++ b/packages/g-plugin-canvaskit-renderer/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-canvaskit-renderer +## 1.3.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + - @antv/g-plugin-image-loader@1.3.13 + ## 1.3.12 ### Patch Changes diff --git a/packages/g-plugin-canvaskit-renderer/package.json b/packages/g-plugin-canvaskit-renderer/package.json index 43f2aa1d1..bb80cfd96 100644 --- a/packages/g-plugin-canvaskit-renderer/package.json +++ b/packages/g-plugin-canvaskit-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-canvaskit-renderer", - "version": "1.3.12", + "version": "1.3.13", "description": "A G plugin of renderer implementation with CanvasKit", "keywords": [ "antv", diff --git a/packages/g-plugin-control/CHANGELOG.md b/packages/g-plugin-control/CHANGELOG.md index b28b3f96e..549736bb5 100644 --- a/packages/g-plugin-control/CHANGELOG.md +++ b/packages/g-plugin-control/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-plugin-control +## 1.9.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.9.12 ### Patch Changes diff --git a/packages/g-plugin-control/package.json b/packages/g-plugin-control/package.json index e3e8922c1..8eacfe6ef 100644 --- a/packages/g-plugin-control/package.json +++ b/packages/g-plugin-control/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-control", - "version": "1.9.12", + "version": "1.9.13", "description": "A G plugin for orbit control", "keywords": [ "antv", diff --git a/packages/g-plugin-css-select/CHANGELOG.md b/packages/g-plugin-css-select/CHANGELOG.md index 8602e5377..7176a94dd 100644 --- a/packages/g-plugin-css-select/CHANGELOG.md +++ b/packages/g-plugin-css-select/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-plugin-css-select +## 1.9.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.9.12 ### Patch Changes diff --git a/packages/g-plugin-css-select/package.json b/packages/g-plugin-css-select/package.json index c8a447c05..62b958ef4 100644 --- a/packages/g-plugin-css-select/package.json +++ b/packages/g-plugin-css-select/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-css-select", - "version": "1.9.12", + "version": "1.9.13", "description": "A G plugin for using CSS select syntax in query selector", "keywords": [ "antv", diff --git a/packages/g-plugin-device-renderer/CHANGELOG.md b/packages/g-plugin-device-renderer/CHANGELOG.md index 3ba03fde1..de3596d2c 100644 --- a/packages/g-plugin-device-renderer/CHANGELOG.md +++ b/packages/g-plugin-device-renderer/CHANGELOG.md @@ -1,5 +1,15 @@ # @antv/g-plugin-device-renderer +## 1.9.15 + +### Patch Changes + +- e5d69c70: Fix gradient path & add more geometry. +- Updated dependencies [e5d69c70] + - @antv/g-shader-components@1.8.5 + - @antv/g-lite@1.2.13 + - @antv/g-plugin-image-loader@1.3.13 + ## 1.9.14 ### Patch Changes diff --git a/packages/g-plugin-device-renderer/package.json b/packages/g-plugin-device-renderer/package.json index 2fd65b8a4..85266833e 100644 --- a/packages/g-plugin-device-renderer/package.json +++ b/packages/g-plugin-device-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-device-renderer", - "version": "1.9.14", + "version": "1.9.15", "description": "A G plugin of renderer implementation with GPUDevice", "keywords": [ "antv", diff --git a/packages/g-plugin-device-renderer/src/PickingIdGenerator.ts b/packages/g-plugin-device-renderer/src/PickingIdGenerator.ts index a0cae2ded..d6ac7064d 100644 --- a/packages/g-plugin-device-renderer/src/PickingIdGenerator.ts +++ b/packages/g-plugin-device-renderer/src/PickingIdGenerator.ts @@ -14,6 +14,10 @@ export class PickingIdGenerator { return this.id2DisplayObjectMap[id]; } + deleteById(id: number) { + delete this.id2DisplayObjectMap[id]; + } + reset() { this.counter = 0; this.id2DisplayObjectMap = {}; diff --git a/packages/g-plugin-device-renderer/src/PickingPlugin.ts b/packages/g-plugin-device-renderer/src/PickingPlugin.ts index 975d53493..6afe7657c 100644 --- a/packages/g-plugin-device-renderer/src/PickingPlugin.ts +++ b/packages/g-plugin-device-renderer/src/PickingPlugin.ts @@ -70,12 +70,24 @@ export class PickingPlugin implements RenderingPlugin { this.pickingIdGenerator.encodePickingColor(pickingId); }; + const handleUnmounted = (e: FederatedEvent) => { + const object = e.target as DisplayObject; + + // @ts-ignore + const renderable3D = object.renderable3D; + if (renderable3D) { + this.pickingIdGenerator.deleteById(renderable3D.pickingId); + } + }; + renderingService.hooks.init.tap(PickingPlugin.tag, () => { canvas.addEventListener(ElementEvent.MOUNTED, handleMounted); + canvas.addEventListener(ElementEvent.UNMOUNTED, handleUnmounted); }); renderingService.hooks.destroy.tap(PickingPlugin.tag, () => { canvas.removeEventListener(ElementEvent.MOUNTED, handleMounted); + canvas.removeEventListener(ElementEvent.UNMOUNTED, handleUnmounted); this.pickingIdGenerator.reset(); }); diff --git a/packages/g-plugin-device-renderer/src/RenderGraphPlugin.ts b/packages/g-plugin-device-renderer/src/RenderGraphPlugin.ts index effe0770d..1da6ae365 100644 --- a/packages/g-plugin-device-renderer/src/RenderGraphPlugin.ts +++ b/packages/g-plugin-device-renderer/src/RenderGraphPlugin.ts @@ -7,7 +7,7 @@ import type { RenderingPlugin, RenderingPluginContext, } from '@antv/g-lite'; -import { CanvasEvent, ElementEvent, parseColor } from '@antv/g-lite'; +import { CanvasEvent, ElementEvent, Shape, parseColor } from '@antv/g-lite'; import { Renderable3D } from './components/Renderable3D'; import type { LightPool } from './LightPool'; import { Fog, Light } from './lights'; @@ -138,6 +138,19 @@ export class RenderGraphPlugin implements RenderingPlugin { } else if (object.nodeName === Fog.tag) { this.lightPool.removeFog(object as Fog); return; + } else if (object.nodeName === Shape.MESH) { + if (object.style.geometry?.meshes) { + const index = object.style.geometry.meshes.indexOf(object); + if (index > -1) { + object.style.geometry.meshes.splice(index, 1); + } + } + if (object.style.material?.meshes) { + const index = object.style.material.meshes.indexOf(object); + if (index > -1) { + object.style.material.meshes.splice(index, 1); + } + } } if (this.swapChain) { diff --git a/packages/g-plugin-device-renderer/src/drawcalls/Instanced.ts b/packages/g-plugin-device-renderer/src/drawcalls/Instanced.ts index e857ab1e3..3ee956f58 100644 --- a/packages/g-plugin-device-renderer/src/drawcalls/Instanced.ts +++ b/packages/g-plugin-device-renderer/src/drawcalls/Instanced.ts @@ -5,7 +5,7 @@ import type { Pattern, Tuple4Number, } from '@antv/g-lite'; -import { CSSRGB, isPattern, isCSSRGB, parseColor, Shape } from '@antv/g-lite'; +import { CSSRGB, isPattern, isCSSRGB, parseColor } from '@antv/g-lite'; import { mat4, vec3 } from 'gl-matrix'; import { BufferGeometry, GeometryEvent } from '../geometries'; import type { LightPool } from '../LightPool'; @@ -95,6 +95,11 @@ export abstract class Instanced { */ key: string; + /** + * attribute name used for gradient or pattern + */ + gradientAttributeName: 'stroke' | 'fill' = 'fill'; + constructor( protected renderHelper: RenderHelper, protected texturePool: TexturePool, @@ -138,11 +143,6 @@ export abstract class Instanced { protected textureMappings: TextureMapping[] = []; protected samplerEntries: BindingLayoutSamplerDescriptor[]; - /** - * Receiving light e.g. Mesh. - */ - protected lightReceived = false; - /** * Divisor of instanced array. */ @@ -515,10 +515,8 @@ export abstract class Instanced { applyRenderInst(renderInst: RenderInst, objects: DisplayObject[]) { // detect if scene changed, eg. lights & fog - const lights = this.lightPool.getAllLights(); const fog = this.lightPool.getFog(); const useFog = !!fog; - const useLight = !!lights.length; if (this.clipPathTarget || this.clipPath) { if (this.clipPathTarget) { @@ -544,10 +542,9 @@ export abstract class Instanced { const oldDefines = { ...this.material.defines }; this.material.defines.USE_FOG = useFog; - this.material.defines.USE_LIGHT = useLight; this.material.defines = { - ...this.material.defines, ...this.lightPool.getDefines(), + ...this.material.defines, ...this.renderHelper.getDefines(), }; @@ -1033,7 +1030,8 @@ export abstract class Instanced { const lights = this.lightPool.getAllLights(); const fog = this.lightPool.getFog(); const useFog = !!fog; - const useLight = this.lightReceived && !!lights.length; + const useLight = material.defines.USE_LIGHT ?? !!lights.length; + const useWireframe = material.defines.USE_WIREFRAME; // collect uniforms @@ -1192,11 +1190,11 @@ export abstract class Instanced { ): TextureMapping | null { const instance = objects[0]; - const fill = ( - instance.nodeName === Shape.LINE - ? instance.parsedStyle.stroke - : instance.parsedStyle.fill - ) as CSSRGB | CSSGradientValue[] | Pattern; + // should account for Line, Path, Polyline and Polyline + const fill = instance.parsedStyle[this.gradientAttributeName] as + | CSSRGB + | CSSGradientValue[] + | Pattern; let texImageSource: string | TexImageSource; @@ -1244,8 +1242,8 @@ export abstract class Instanced { 'Fill Texture' + this.id, ); fillMapping.sampler = this.renderHelper.getCache().createSampler({ - wrapS: WrapMode.Repeat, - wrapT: WrapMode.Repeat, + wrapS: WrapMode.Clamp, + wrapT: WrapMode.Clamp, minFilter: TexFilterMode.Point, magFilter: TexFilterMode.Bilinear, mipFilter: MipFilterMode.Linear, diff --git a/packages/g-plugin-device-renderer/src/drawcalls/InstancedFill.ts b/packages/g-plugin-device-renderer/src/drawcalls/InstancedFill.ts index 18c3194a5..2f642d51b 100644 --- a/packages/g-plugin-device-renderer/src/drawcalls/InstancedFill.ts +++ b/packages/g-plugin-device-renderer/src/drawcalls/InstancedFill.ts @@ -89,12 +89,10 @@ export class InstancedFillDrawcall extends Instanced { } createGeometry(objects: DisplayObject[]): void { - // use default common attributes - super.createGeometry(objects); - const indices: number[] = []; const pointsBuffer: number[] = []; const uvsBuffer: number[] = []; + let offset = 0; objects.forEach((object, i) => { // use triangles for Polygon const { triangles, pointsBuffer: pBuffer } = updateBuffer( @@ -104,43 +102,58 @@ export class InstancedFillDrawcall extends Instanced { this.calcSubpathIndex(object), ); - const { halfExtents } = object.getGeometryBounds(); - const uvBuffer = pBuffer.map((x, i) => x / halfExtents[i % 2] / 2); - - pointsBuffer.push(...pBuffer); - uvsBuffer.push(...uvBuffer); - indices.push(...triangles.map((n) => n + (i * pBuffer.length) / 2)); - }); - - this.geometry.setVertexBuffer({ - bufferIndex: VertexAttributeBufferIndex.POSITION, - byteStride: 4 * 3, - frequency: VertexBufferFrequency.PerVertex, - attributes: [ - { - format: Format.F32_RGB, - bufferByteOffset: 4 * 0, - location: VertexAttributeLocation.POSITION, - }, - ], - data: new Float32Array(pointsBuffer), + if (triangles.length) { + const { halfExtents } = object.getGeometryBounds(); + // pointsBuffer use 3D + const uvBuffer = []; + pBuffer.forEach((x, i) => { + if (i % 3 !== 2) { + uvBuffer.push(x / halfExtents[i % 3] / 2); + } + }); + + offset += pointsBuffer.length / 3; + + pointsBuffer.push(...pBuffer); + uvsBuffer.push(...uvBuffer); + indices.push(...triangles.map((n) => n + offset)); + } }); - this.geometry.setVertexBuffer({ - bufferIndex: VertexAttributeBufferIndex.UV, - byteStride: 4 * 2, - frequency: VertexBufferFrequency.PerVertex, - attributes: [ - { - format: Format.F32_RG, - bufferByteOffset: 4 * 0, - location: VertexAttributeLocation.UV, - }, - ], - data: new Float32Array(uvsBuffer), - }); - this.geometry.vertexCount = indices.length / objects.length; - this.geometry.setIndexBuffer(new Uint32Array(indices)); + if (pointsBuffer.length) { + // use default common attributes + super.createGeometry(objects); + + this.geometry.setVertexBuffer({ + bufferIndex: VertexAttributeBufferIndex.POSITION, + byteStride: 4 * 3, + frequency: VertexBufferFrequency.PerVertex, + attributes: [ + { + format: Format.F32_RGB, + bufferByteOffset: 4 * 0, + location: VertexAttributeLocation.POSITION, + }, + ], + data: new Float32Array(pointsBuffer), + }); + + this.geometry.setVertexBuffer({ + bufferIndex: VertexAttributeBufferIndex.UV, + byteStride: 4 * 2, + frequency: VertexBufferFrequency.PerVertex, + attributes: [ + { + format: Format.F32_RG, + bufferByteOffset: 4 * 0, + location: VertexAttributeLocation.UV, + }, + ], + data: new Float32Array(uvsBuffer), + }); + this.geometry.vertexCount = indices.length / objects.length; + this.geometry.setIndexBuffer(new Uint32Array(indices)); + } } createMaterial(objects: DisplayObject[]): void { diff --git a/packages/g-plugin-device-renderer/src/drawcalls/InstancedLine.ts b/packages/g-plugin-device-renderer/src/drawcalls/InstancedLine.ts index 19cfc9d88..cfa88f1ab 100644 --- a/packages/g-plugin-device-renderer/src/drawcalls/InstancedLine.ts +++ b/packages/g-plugin-device-renderer/src/drawcalls/InstancedLine.ts @@ -20,6 +20,11 @@ import { VertexAttributeBufferIndex, VertexAttributeLocation, } from './Instanced'; +import { InstancedFillDrawcall } from './InstancedFill'; +import { RenderHelper } from '../render'; +import { TexturePool } from '../TexturePool'; +import { LightPool } from '../LightPool'; +import { BatchContext } from '../renderer'; export const segmentInstanceGeometry = [ 0, -0.5, 0, 0, 0, 1, -0.5, 1, 1, 0, 1, 0.5, 1, 1, 1, 0, 0.5, 0, 0, 1, @@ -97,6 +102,27 @@ export class InstancedLineDrawcall extends Instanced { return false; } + constructor( + protected renderHelper: RenderHelper, + protected texturePool: TexturePool, + protected lightPool: LightPool, + object: DisplayObject, + drawcallCtors: (new (..._: any) => Instanced)[], + index: number, + context: BatchContext, + ) { + super( + renderHelper, + texturePool, + lightPool, + object, + drawcallCtors, + index, + context, + ); + this.gradientAttributeName = 'stroke'; + } + shouldMerge(object: DisplayObject, index: number) { const shouldMerge = super.shouldMerge(object, index); if (!shouldMerge) { @@ -115,6 +141,16 @@ export class InstancedLineDrawcall extends Instanced { }; } + private calcSubpathIndex(object: DisplayObject) { + if (object.nodeName === Shape.PATH) { + const fillDrawcallCount = this.drawcallCtors.filter( + (ctor) => ctor === InstancedFillDrawcall, + ).length; + return this.index - fillDrawcallCount; + } + return 0; + } + createGeometry(objects: DisplayObject[]): void { // use default common attributes super.createGeometry(objects); @@ -179,10 +215,11 @@ export class InstancedLineDrawcall extends Instanced { } = (object as Path).parsedStyle; let mSegmentCount = 0; let mCommandIndex = 0; + const index = this.calcSubpathIndex(object); for (let i = 0; i < absolutePath.length; i++) { const segment = absolutePath[i]; if (segment[0] === 'M') { - if (mSegmentCount === this.index) { + if (mSegmentCount === index) { mCommandIndex = i; break; } diff --git a/packages/g-plugin-device-renderer/src/drawcalls/InstancedPath.ts b/packages/g-plugin-device-renderer/src/drawcalls/InstancedPath.ts index f03477774..019b78f54 100644 --- a/packages/g-plugin-device-renderer/src/drawcalls/InstancedPath.ts +++ b/packages/g-plugin-device-renderer/src/drawcalls/InstancedPath.ts @@ -87,6 +87,7 @@ export class InstancedPathDrawcall extends Instanced { context, ); this.segmentNum = this.calcSegmentNum(object); + this.gradientAttributeName = 'stroke'; } protected mergeAnchorIntoModelMatrix = true; diff --git a/packages/g-plugin-device-renderer/src/drawcalls/Mesh.ts b/packages/g-plugin-device-renderer/src/drawcalls/Mesh.ts index 8a74945b6..4d62b0594 100644 --- a/packages/g-plugin-device-renderer/src/drawcalls/Mesh.ts +++ b/packages/g-plugin-device-renderer/src/drawcalls/Mesh.ts @@ -3,8 +3,6 @@ import { Shape } from '@antv/g-lite'; import type { Mesh } from '../Mesh'; import { Instanced } from './Instanced'; export class MeshDrawcall extends Instanced { - protected lightReceived = true; - shouldMerge(object: DisplayObject, index: number) { const shouldMerge = super.shouldMerge(object, index); diff --git a/packages/g-plugin-device-renderer/src/shader/instanced-line.frag b/packages/g-plugin-device-renderer/src/shader/instanced-line.frag index cd8aa70de..36a1fd495 100644 --- a/packages/g-plugin-device-renderer/src/shader/instanced-line.frag +++ b/packages/g-plugin-device-renderer/src/shader/instanced-line.frag @@ -21,7 +21,7 @@ void main() { } else { outputColor = u_StrokeColor; #ifdef USE_MAP - outputColor = u_Color; + outputColor = u_Color; #endif float blur; diff --git a/packages/g-plugin-device-renderer/src/shader/line.frag b/packages/g-plugin-device-renderer/src/shader/line.frag index e36d6d9f6..b4f41cd3d 100644 --- a/packages/g-plugin-device-renderer/src/shader/line.frag +++ b/packages/g-plugin-device-renderer/src/shader/line.frag @@ -1,6 +1,9 @@ #pragma glslify: import('@antv/g-shader-components/scene.both.glsl') #pragma glslify: import('@antv/g-shader-components/batch.declaration.frag') +#pragma glslify: import('@antv/g-shader-components/uv.declaration.frag') +#pragma glslify: import('@antv/g-shader-components/map.declaration.frag') + in vec4 v_Dash; in vec4 v_Distance; @@ -13,6 +16,7 @@ out vec4 outputColor; void main(){ #pragma glslify: import('@antv/g-shader-components/batch.frag') + #pragma glslify: import('@antv/g-shader-components/map.frag') float alpha = 1.0; float lineWidth = v_Distance.w; @@ -73,6 +77,10 @@ void main(){ outputColor = vec4(pickingColor, 1.0); } else { outputColor = u_StrokeColor; + #ifdef USE_MAP + outputColor = u_Color; + #endif + outputColor.a *= alpha * u_Opacity * u_StrokeOpacity; } } \ No newline at end of file diff --git a/packages/g-plugin-device-renderer/src/shader/line.vert b/packages/g-plugin-device-renderer/src/shader/line.vert index 836ddca5e..5ae1be21c 100644 --- a/packages/g-plugin-device-renderer/src/shader/line.vert +++ b/packages/g-plugin-device-renderer/src/shader/line.vert @@ -10,7 +10,10 @@ layout(location = NEXT) in vec3 a_Next; layout(location = VERTEX_JOINT) in float a_VertexJoint; layout(location = VERTEX_NUM) in float a_VertexNum; layout(location = TRAVEL) in float a_Travel; - +#ifdef USE_UV + layout(location = UV) in vec2 a_Uv; + out vec2 v_Uv; +#endif layout(location = DASH) in vec4 a_Dash; out vec4 v_Dash; @@ -65,6 +68,8 @@ vec2 project2ScreenSpace(vec3 pos, mat4 u_ModelMatrix) { void main() { #pragma glslify: import('@antv/g-shader-components/batch.vert') + #pragma glslify: import('@antv/g-shader-components/uv.vert') + v_Dash = a_Dash; vec2 pointA; diff --git a/packages/g-plugin-dom-interaction/CHANGELOG.md b/packages/g-plugin-dom-interaction/CHANGELOG.md index 7dc4573c7..9b9a58e65 100644 --- a/packages/g-plugin-dom-interaction/CHANGELOG.md +++ b/packages/g-plugin-dom-interaction/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-plugin-dom-interaction +## 1.9.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.9.12 ### Patch Changes diff --git a/packages/g-plugin-dom-interaction/package.json b/packages/g-plugin-dom-interaction/package.json index 7b3a6e76a..d9e1421e8 100644 --- a/packages/g-plugin-dom-interaction/package.json +++ b/packages/g-plugin-dom-interaction/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-dom-interaction", - "version": "1.9.12", + "version": "1.9.13", "description": "A G plugin", "keywords": [ "antv", diff --git a/packages/g-plugin-dragndrop/CHANGELOG.md b/packages/g-plugin-dragndrop/CHANGELOG.md index 0c72d8f08..dc8f08f66 100644 --- a/packages/g-plugin-dragndrop/CHANGELOG.md +++ b/packages/g-plugin-dragndrop/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-plugin-dragndrop +## 1.8.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.8.12 ### Patch Changes diff --git a/packages/g-plugin-dragndrop/package.json b/packages/g-plugin-dragndrop/package.json index bb1ad2f4a..36d35e29c 100644 --- a/packages/g-plugin-dragndrop/package.json +++ b/packages/g-plugin-dragndrop/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-dragndrop", - "version": "1.8.12", + "version": "1.8.13", "description": "A G plugin for Drag n Drop implemented with PointerEvents", "keywords": [ "antv", diff --git a/packages/g-plugin-gesture/CHANGELOG.md b/packages/g-plugin-gesture/CHANGELOG.md index 696318fe2..1319b3cc4 100644 --- a/packages/g-plugin-gesture/CHANGELOG.md +++ b/packages/g-plugin-gesture/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-plugin-gesture +## 1.1.2 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.1.1 ### Patch Changes diff --git a/packages/g-plugin-gesture/package.json b/packages/g-plugin-gesture/package.json index 8de9c96f6..6ae80c48f 100644 --- a/packages/g-plugin-gesture/package.json +++ b/packages/g-plugin-gesture/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-gesture", - "version": "1.1.1", + "version": "1.1.2", "description": "A G plugin for Gesture implemented with PointerEvents", "keywords": [ "antv", diff --git a/packages/g-plugin-gpgpu/CHANGELOG.md b/packages/g-plugin-gpgpu/CHANGELOG.md index a9f449e50..4f7b649e5 100644 --- a/packages/g-plugin-gpgpu/CHANGELOG.md +++ b/packages/g-plugin-gpgpu/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-gpgpu +## 1.9.18 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + - @antv/g-webgpu@1.9.18 + ## 1.9.17 ### Patch Changes diff --git a/packages/g-plugin-gpgpu/package.json b/packages/g-plugin-gpgpu/package.json index a43559914..5bf2b0e73 100644 --- a/packages/g-plugin-gpgpu/package.json +++ b/packages/g-plugin-gpgpu/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-gpgpu", - "version": "1.9.17", + "version": "1.9.18", "description": "A G plugin for GPGPU based on WebGPU", "keywords": [ "webgpu", diff --git a/packages/g-plugin-html-renderer/CHANGELOG.md b/packages/g-plugin-html-renderer/CHANGELOG.md index c0f50da1f..71961445c 100644 --- a/packages/g-plugin-html-renderer/CHANGELOG.md +++ b/packages/g-plugin-html-renderer/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-plugin-html-renderer +## 1.9.16 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.9.15 ### Patch Changes diff --git a/packages/g-plugin-html-renderer/package.json b/packages/g-plugin-html-renderer/package.json index 7b313f8ec..54178d6ea 100644 --- a/packages/g-plugin-html-renderer/package.json +++ b/packages/g-plugin-html-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-html-renderer", - "version": "1.9.15", + "version": "1.9.16", "description": "A G plugin for rendering HTML", "keywords": [ "antv", diff --git a/packages/g-plugin-image-loader/CHANGELOG.md b/packages/g-plugin-image-loader/CHANGELOG.md index 97e5972a5..0cab01c5a 100644 --- a/packages/g-plugin-image-loader/CHANGELOG.md +++ b/packages/g-plugin-image-loader/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-plugin-image-loader +## 1.3.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.3.12 ### Patch Changes diff --git a/packages/g-plugin-image-loader/package.json b/packages/g-plugin-image-loader/package.json index 13b2dd220..5a3214691 100644 --- a/packages/g-plugin-image-loader/package.json +++ b/packages/g-plugin-image-loader/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-image-loader", - "version": "1.3.12", + "version": "1.3.13", "description": "A G plugin for loading image", "keywords": [ "antv", diff --git a/packages/g-plugin-matterjs/CHANGELOG.md b/packages/g-plugin-matterjs/CHANGELOG.md index a112f944b..cbeadc0b1 100644 --- a/packages/g-plugin-matterjs/CHANGELOG.md +++ b/packages/g-plugin-matterjs/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-plugin-matterjs +## 1.9.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.9.12 ### Patch Changes diff --git a/packages/g-plugin-matterjs/package.json b/packages/g-plugin-matterjs/package.json index f3e9c3a4e..903cb5a37 100644 --- a/packages/g-plugin-matterjs/package.json +++ b/packages/g-plugin-matterjs/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-matterjs", - "version": "1.9.12", + "version": "1.9.13", "description": "A G plugin for matter.js physics engine", "keywords": [ "antv", diff --git a/packages/g-plugin-mobile-interaction/CHANGELOG.md b/packages/g-plugin-mobile-interaction/CHANGELOG.md index 36960f6eb..239b904b0 100644 --- a/packages/g-plugin-mobile-interaction/CHANGELOG.md +++ b/packages/g-plugin-mobile-interaction/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-plugin-mobile-interaction +## 0.9.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 0.9.12 ### Patch Changes diff --git a/packages/g-plugin-mobile-interaction/package.json b/packages/g-plugin-mobile-interaction/package.json index 0178f1c79..e8b707bf4 100644 --- a/packages/g-plugin-mobile-interaction/package.json +++ b/packages/g-plugin-mobile-interaction/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-mobile-interaction", - "version": "0.9.12", + "version": "0.9.13", "description": "A G plugin listening events in mobile environment", "keywords": [ "antv", diff --git a/packages/g-plugin-physx/CHANGELOG.md b/packages/g-plugin-physx/CHANGELOG.md index b6055de66..28ac96f02 100644 --- a/packages/g-plugin-physx/CHANGELOG.md +++ b/packages/g-plugin-physx/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-plugin-physx +## 1.9.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.9.12 ### Patch Changes diff --git a/packages/g-plugin-physx/package.json b/packages/g-plugin-physx/package.json index 47d09831e..d0d58d9b5 100644 --- a/packages/g-plugin-physx/package.json +++ b/packages/g-plugin-physx/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-physx", - "version": "1.9.12", + "version": "1.9.13", "description": "A G plugin for PhysX", "keywords": [ "antv", diff --git a/packages/g-plugin-rough-canvas-renderer/CHANGELOG.md b/packages/g-plugin-rough-canvas-renderer/CHANGELOG.md index 1cae42f18..6f4c31c9b 100644 --- a/packages/g-plugin-rough-canvas-renderer/CHANGELOG.md +++ b/packages/g-plugin-rough-canvas-renderer/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-rough-canvas-renderer +## 1.9.16 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + - @antv/g-canvas@1.11.16 + ## 1.9.15 ### Patch Changes diff --git a/packages/g-plugin-rough-canvas-renderer/package.json b/packages/g-plugin-rough-canvas-renderer/package.json index c8387041d..6343ecbc1 100644 --- a/packages/g-plugin-rough-canvas-renderer/package.json +++ b/packages/g-plugin-rough-canvas-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-rough-canvas-renderer", - "version": "1.9.15", + "version": "1.9.16", "description": "A G plugin of renderer implementation with rough.js", "keywords": [ "antv", diff --git a/packages/g-plugin-rough-svg-renderer/CHANGELOG.md b/packages/g-plugin-rough-svg-renderer/CHANGELOG.md index df2ef7968..718d33bfb 100644 --- a/packages/g-plugin-rough-svg-renderer/CHANGELOG.md +++ b/packages/g-plugin-rough-svg-renderer/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-rough-svg-renderer +## 1.9.16 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + - @antv/g-svg@1.10.15 + ## 1.9.15 ### Patch Changes diff --git a/packages/g-plugin-rough-svg-renderer/package.json b/packages/g-plugin-rough-svg-renderer/package.json index 8ff6fdc57..5b891e5d5 100644 --- a/packages/g-plugin-rough-svg-renderer/package.json +++ b/packages/g-plugin-rough-svg-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-rough-svg-renderer", - "version": "1.9.15", + "version": "1.9.16", "description": "A G plugin of renderer implementation with rough.js", "keywords": [ "antv", diff --git a/packages/g-plugin-svg-picker/CHANGELOG.md b/packages/g-plugin-svg-picker/CHANGELOG.md index 83a91a2ef..f3381f82f 100644 --- a/packages/g-plugin-svg-picker/CHANGELOG.md +++ b/packages/g-plugin-svg-picker/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-svg-picker +## 1.9.15 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + - @antv/g-plugin-svg-renderer@1.10.15 + ## 1.9.14 ### Patch Changes diff --git a/packages/g-plugin-svg-picker/package.json b/packages/g-plugin-svg-picker/package.json index de26adbc3..04aec2afc 100644 --- a/packages/g-plugin-svg-picker/package.json +++ b/packages/g-plugin-svg-picker/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-svg-picker", - "version": "1.9.14", + "version": "1.9.15", "description": "A G plugin for picking in SVG", "keywords": [ "antv", diff --git a/packages/g-plugin-svg-renderer/CHANGELOG.md b/packages/g-plugin-svg-renderer/CHANGELOG.md index e8eb52a3d..7ebc2e40a 100644 --- a/packages/g-plugin-svg-renderer/CHANGELOG.md +++ b/packages/g-plugin-svg-renderer/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-plugin-svg-renderer +## 1.10.15 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.10.14 ### Patch Changes diff --git a/packages/g-plugin-svg-renderer/package.json b/packages/g-plugin-svg-renderer/package.json index 1d48d9932..3f0a1f3fc 100644 --- a/packages/g-plugin-svg-renderer/package.json +++ b/packages/g-plugin-svg-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-svg-renderer", - "version": "1.10.14", + "version": "1.10.15", "description": "A G plugin of renderer implementation with SVG", "keywords": [ "antv", diff --git a/packages/g-plugin-webgl-device/CHANGELOG.md b/packages/g-plugin-webgl-device/CHANGELOG.md index 9cd5c9563..c73f8079e 100644 --- a/packages/g-plugin-webgl-device/CHANGELOG.md +++ b/packages/g-plugin-webgl-device/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-webgl-device +## 1.9.15 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-plugin-device-renderer@1.9.15 + - @antv/g-lite@1.2.13 + ## 1.9.14 ### Patch Changes diff --git a/packages/g-plugin-webgl-device/package.json b/packages/g-plugin-webgl-device/package.json index 92ac5fb85..3f2fa2d50 100644 --- a/packages/g-plugin-webgl-device/package.json +++ b/packages/g-plugin-webgl-device/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-webgl-device", - "version": "1.9.14", + "version": "1.9.15", "description": "A G plugin implements GPUDevice interface with WebGL API", "keywords": [ "antv", diff --git a/packages/g-plugin-webgpu-device/CHANGELOG.md b/packages/g-plugin-webgpu-device/CHANGELOG.md index e273cba85..8a6742a12 100644 --- a/packages/g-plugin-webgpu-device/CHANGELOG.md +++ b/packages/g-plugin-webgpu-device/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-webgpu-device +## 1.9.15 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-plugin-device-renderer@1.9.15 + - @antv/g-lite@1.2.13 + ## 1.9.14 ### Patch Changes diff --git a/packages/g-plugin-webgpu-device/package.json b/packages/g-plugin-webgpu-device/package.json index 3956d3a55..797d92480 100644 --- a/packages/g-plugin-webgpu-device/package.json +++ b/packages/g-plugin-webgpu-device/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-webgpu-device", - "version": "1.9.14", + "version": "1.9.15", "description": "A G plugin implements GPUDevice interface with WebGPU API", "keywords": [ "antv", diff --git a/packages/g-plugin-yoga/CHANGELOG.md b/packages/g-plugin-yoga/CHANGELOG.md index 5feccf679..32ad1363c 100644 --- a/packages/g-plugin-yoga/CHANGELOG.md +++ b/packages/g-plugin-yoga/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-plugin-yoga +## 1.9.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.9.12 ### Patch Changes diff --git a/packages/g-plugin-yoga/package.json b/packages/g-plugin-yoga/package.json index 57f94621f..26bd9f4e9 100644 --- a/packages/g-plugin-yoga/package.json +++ b/packages/g-plugin-yoga/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-yoga", - "version": "1.9.12", + "version": "1.9.13", "description": "A G plugin for Yoga layout engine", "keywords": [ "antv", diff --git a/packages/g-plugin-zdog-canvas-renderer/CHANGELOG.md b/packages/g-plugin-zdog-canvas-renderer/CHANGELOG.md index 03eab7d83..b5d942dc0 100644 --- a/packages/g-plugin-zdog-canvas-renderer/CHANGELOG.md +++ b/packages/g-plugin-zdog-canvas-renderer/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-zdog-canvas-renderer +## 1.2.16 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + - @antv/g-canvas@1.11.16 + ## 1.2.15 ### Patch Changes diff --git a/packages/g-plugin-zdog-canvas-renderer/package.json b/packages/g-plugin-zdog-canvas-renderer/package.json index 8b7738ef6..67199cbc9 100644 --- a/packages/g-plugin-zdog-canvas-renderer/package.json +++ b/packages/g-plugin-zdog-canvas-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-zdog-canvas-renderer", - "version": "1.2.15", + "version": "1.2.16", "description": "A G plugin of renderer implementation with Zdog", "keywords": [ "antv", diff --git a/packages/g-plugin-zdog-svg-renderer/CHANGELOG.md b/packages/g-plugin-zdog-svg-renderer/CHANGELOG.md index cf75a2d1c..c1e35933c 100644 --- a/packages/g-plugin-zdog-svg-renderer/CHANGELOG.md +++ b/packages/g-plugin-zdog-svg-renderer/CHANGELOG.md @@ -1,5 +1,14 @@ # @antv/g-plugin-zdog-svg-renderer +## 1.2.16 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + - @antv/g-plugin-svg-renderer@1.10.15 + - @antv/g-svg@1.10.15 + ## 1.2.15 ### Patch Changes diff --git a/packages/g-plugin-zdog-svg-renderer/package.json b/packages/g-plugin-zdog-svg-renderer/package.json index 8621cfe88..b303739a7 100644 --- a/packages/g-plugin-zdog-svg-renderer/package.json +++ b/packages/g-plugin-zdog-svg-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-zdog-svg-renderer", - "version": "1.2.15", + "version": "1.2.16", "description": "A G plugin of renderer implementation with Zdog", "keywords": [ "antv", diff --git a/packages/g-shader-components/CHANGELOG.md b/packages/g-shader-components/CHANGELOG.md index 3dc6e6f11..dd922da0b 100644 --- a/packages/g-shader-components/CHANGELOG.md +++ b/packages/g-shader-components/CHANGELOG.md @@ -1,5 +1,11 @@ # @antv/g-shader-components +## 1.8.5 + +### Patch Changes + +- e5d69c70: Fix gradient path & add more geometry. + ## 1.8.4 ### Patch Changes diff --git a/packages/g-shader-components/light.both.glsl b/packages/g-shader-components/light.begin.declaration.frag similarity index 70% rename from packages/g-shader-components/light.both.glsl rename to packages/g-shader-components/light.begin.declaration.frag index 6c26aca32..c1b7cb65c 100644 --- a/packages/g-shader-components/light.both.glsl +++ b/packages/g-shader-components/light.begin.declaration.frag @@ -8,4 +8,9 @@ light.direction = normalize(directionalLight.direction); light.visible = true; } + + vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) { + vec3 irradiance = ambientLightColor; + return irradiance; + } #endif \ No newline at end of file diff --git a/packages/g-shader-components/light.lambert.declaration.frag b/packages/g-shader-components/light.lambert.declaration.frag new file mode 100644 index 000000000..b55044b71 --- /dev/null +++ b/packages/g-shader-components/light.lambert.declaration.frag @@ -0,0 +1,28 @@ +struct LambertMaterial { + vec3 diffuseColor; + float specularStrength; +}; + +void RE_Direct_Lambert( + const in IncidentLight directLight, + const in GeometricContext geometry, + const in LambertMaterial material, + inout ReflectedLight reflectedLight +) { + float dotNL = saturate(dot(geometry.normal, directLight.direction)); + vec3 irradiance = dotNL * directLight.color; + + reflectedLight.directDiffuse += irradiance * BRDF_Lambert(material.diffuseColor); +} + +void RE_IndirectDiffuse_Lambert( + const in vec3 irradiance, + const in GeometricContext geometry, + const in LambertMaterial material, + inout ReflectedLight reflectedLight +) { + reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert(material.diffuseColor); +} + +#define RE_Direct RE_Direct_Lambert +#define RE_IndirectDiffuse RE_IndirectDiffuse_Lambert \ No newline at end of file diff --git a/packages/g-shader-components/light.lambert.frag b/packages/g-shader-components/light.lambert.frag new file mode 100644 index 000000000..a4c3ea098 --- /dev/null +++ b/packages/g-shader-components/light.lambert.frag @@ -0,0 +1,3 @@ +LambertMaterial material; +material.diffuseColor = diffuseColor.rgb; +material.specularStrength = specularStrength; \ No newline at end of file diff --git a/packages/g-shader-components/light.phong.declaration.frag b/packages/g-shader-components/light.phong.declaration.frag index 5ab2faaa0..99055b975 100644 --- a/packages/g-shader-components/light.phong.declaration.frag +++ b/packages/g-shader-components/light.phong.declaration.frag @@ -28,10 +28,5 @@ void RE_IndirectDiffuse_BlinnPhong( reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); } -vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) { - vec3 irradiance = ambientLightColor; - return irradiance; -} - #define RE_Direct RE_Direct_BlinnPhong #define RE_IndirectDiffuse RE_IndirectDiffuse_BlinnPhong \ No newline at end of file diff --git a/packages/g-shader-components/material.lambert.glsl b/packages/g-shader-components/material.lambert.glsl new file mode 100644 index 000000000..d5678fa0c --- /dev/null +++ b/packages/g-shader-components/material.lambert.glsl @@ -0,0 +1,27 @@ +layout(std140) uniform ub_MaterialParams { + #ifdef USE_WIREFRAME + vec3 u_WireframeLineColor; + float u_WireframeLineWidth; + #endif + + #ifdef USE_FOG + vec4 u_FogInfos; + vec3 u_FogColor; + #endif + + vec3 u_Emissive; + + #ifdef USE_LIGHT + #ifdef USE_BUMPMAP + float u_BumpScale; + #endif + + #ifdef NUM_AMBIENT_LIGHTS + vec3 u_AmbientLightColor; + #endif + + #ifdef NUM_DIR_LIGHTS + DirectionalLight directionalLights[ NUM_DIR_LIGHTS ]; + #endif + #endif +}; \ No newline at end of file diff --git a/packages/g-shader-components/package.json b/packages/g-shader-components/package.json index 812820cef..8f2cd3308 100644 --- a/packages/g-shader-components/package.json +++ b/packages/g-shader-components/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-shader-components", - "version": "1.8.4", + "version": "1.8.5", "description": "Shader components based on glslify", "keywords": [ "antv", diff --git a/packages/g-svg/CHANGELOG.md b/packages/g-svg/CHANGELOG.md index a622230af..1cd761e50 100644 --- a/packages/g-svg/CHANGELOG.md +++ b/packages/g-svg/CHANGELOG.md @@ -1,5 +1,15 @@ # @antv/g-svg +## 1.10.15 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + - @antv/g-plugin-dom-interaction@1.9.13 + - @antv/g-plugin-svg-picker@1.9.15 + - @antv/g-plugin-svg-renderer@1.10.15 + ## 1.10.14 ### Patch Changes diff --git a/packages/g-svg/package.json b/packages/g-svg/package.json index c66c60ab0..20074eaad 100644 --- a/packages/g-svg/package.json +++ b/packages/g-svg/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-svg", - "version": "1.10.14", + "version": "1.10.15", "description": "A renderer implemented by SVG", "keywords": [ "antv", diff --git a/packages/g-web-animations-api/CHANGELOG.md b/packages/g-web-animations-api/CHANGELOG.md index 2f2ba9097..61779f684 100644 --- a/packages/g-web-animations-api/CHANGELOG.md +++ b/packages/g-web-animations-api/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-web-animations-api +## 1.2.13 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + ## 1.2.12 ### Patch Changes diff --git a/packages/g-web-animations-api/package.json b/packages/g-web-animations-api/package.json index fd8e8b653..e5e76aa6c 100644 --- a/packages/g-web-animations-api/package.json +++ b/packages/g-web-animations-api/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-web-animations-api", - "version": "1.2.12", + "version": "1.2.13", "description": "A simple implementation of Web Animations API.", "keywords": [ "antv", diff --git a/packages/g-web-components/CHANGELOG.md b/packages/g-web-components/CHANGELOG.md index a9074f637..9b93ae33b 100644 --- a/packages/g-web-components/CHANGELOG.md +++ b/packages/g-web-components/CHANGELOG.md @@ -1,5 +1,14 @@ # @antv/g-web-components +## 1.9.18 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + - @antv/g-webgl@1.9.18 + - @antv/g-canvas@1.11.16 + ## 1.9.17 ### Patch Changes diff --git a/packages/g-web-components/package.json b/packages/g-web-components/package.json index ad08cabb2..cb6ccd1ee 100644 --- a/packages/g-web-components/package.json +++ b/packages/g-web-components/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-web-components", - "version": "1.9.17", + "version": "1.9.18", "description": "A declarative usage for G implemented with WebComponents", "keywords": [ "antv", diff --git a/packages/g-webgl/CHANGELOG.md b/packages/g-webgl/CHANGELOG.md index f02e52f28..6ca52a0f9 100644 --- a/packages/g-webgl/CHANGELOG.md +++ b/packages/g-webgl/CHANGELOG.md @@ -1,5 +1,17 @@ # @antv/g-webgl +## 1.9.18 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-plugin-device-renderer@1.9.15 + - @antv/g-lite@1.2.13 + - @antv/g-plugin-webgl-device@1.9.15 + - @antv/g-plugin-dom-interaction@1.9.13 + - @antv/g-plugin-html-renderer@1.9.16 + - @antv/g-plugin-image-loader@1.3.13 + ## 1.9.17 ### Patch Changes diff --git a/packages/g-webgl/package.json b/packages/g-webgl/package.json index 84304a3f7..fa978de8c 100644 --- a/packages/g-webgl/package.json +++ b/packages/g-webgl/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-webgl", - "version": "1.9.17", + "version": "1.9.18", "description": "A renderer implemented by WebGL1/2", "keywords": [ "antv", diff --git a/packages/g-webgpu/CHANGELOG.md b/packages/g-webgpu/CHANGELOG.md index 3d9846252..5cded09ba 100644 --- a/packages/g-webgpu/CHANGELOG.md +++ b/packages/g-webgpu/CHANGELOG.md @@ -1,5 +1,17 @@ # @antv/g-webgpu +## 1.9.18 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-plugin-device-renderer@1.9.15 + - @antv/g-lite@1.2.13 + - @antv/g-plugin-webgpu-device@1.9.15 + - @antv/g-plugin-dom-interaction@1.9.13 + - @antv/g-plugin-html-renderer@1.9.16 + - @antv/g-plugin-image-loader@1.3.13 + ## 1.9.17 ### Patch Changes diff --git a/packages/g-webgpu/package.json b/packages/g-webgpu/package.json index ac07256d1..7888660e9 100644 --- a/packages/g-webgpu/package.json +++ b/packages/g-webgpu/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-webgpu", - "version": "1.9.17", + "version": "1.9.18", "description": "A renderer implemented by WebGPU", "keywords": [ "antv", diff --git a/packages/g/CHANGELOG.md b/packages/g/CHANGELOG.md index e64056c41..ccc2673a1 100644 --- a/packages/g/CHANGELOG.md +++ b/packages/g/CHANGELOG.md @@ -1,5 +1,15 @@ # @antv/g +## 5.18.14 + +### Patch Changes + +- Updated dependencies [e5d69c70] + - @antv/g-lite@1.2.13 + - @antv/g-camera-api@1.2.13 + - @antv/g-dom-mutation-observer-api@1.2.13 + - @antv/g-web-animations-api@1.2.13 + ## 5.18.13 ### Patch Changes diff --git a/packages/g/package.json b/packages/g/package.json index 7c18c2863..1904a1384 100644 --- a/packages/g/package.json +++ b/packages/g/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g", - "version": "5.18.13", + "version": "5.18.14", "description": "A core module for rendering engine implements DOM API.", "keywords": [ "antv", diff --git a/packages/react-g/CHANGELOG.md b/packages/react-g/CHANGELOG.md index 8a3575822..5dec67283 100644 --- a/packages/react-g/CHANGELOG.md +++ b/packages/react-g/CHANGELOG.md @@ -1,5 +1,11 @@ # @antv/react-g +## 1.10.14 + +### Patch Changes + +- @antv/g@5.18.14 + ## 1.10.13 ### Patch Changes diff --git a/packages/react-g/package.json b/packages/react-g/package.json index 886c224ba..3e1559b97 100644 --- a/packages/react-g/package.json +++ b/packages/react-g/package.json @@ -1,6 +1,6 @@ { "name": "@antv/react-g", - "version": "1.10.13", + "version": "1.10.14", "description": "react render for @antv/g", "keywords": [ "react", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5768c1902..6f95bef0a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1173,6 +1173,9 @@ importers: '@antv/g-components': specifier: ^1.9.1 version: link:../packages/g-components + '@antv/g-lite': + specifier: ^1.2.12 + version: link:../packages/g-lite '@antv/g-mobile-webgl': specifier: ^0.9.1 version: link:../packages/g-mobile-webgl @@ -1180,7 +1183,7 @@ importers: specifier: ^0.6.7 version: link:../packages/g-plugin-a11y '@antv/g-plugin-image-loader': - specifier: ^1.3.7 + specifier: ^1.3.12 version: link:../packages/g-plugin-image-loader '@antv/g6': specifier: ^4.5.2 diff --git a/site/docs/api/3d/geometry.en.md b/site/docs/api/3d/geometry.en.md index 1dca90136..0035bffd7 100644 --- a/site/docs/api/3d/geometry.en.md +++ b/site/docs/api/3d/geometry.en.md @@ -60,93 +60,94 @@ cube.style.width = 300; 立方体,[示例](/zh/examples/3d#cube) - +cube -#### width - -宽度,必填。 - -#### height - -高度,必填。 - -#### depth - -深度,必填。 - -#### widthSegments - -影响程序化生成,默认值为 1 - -#### heightSegments - -影响程序化生成,默认值为 1 - -#### depthSegments - -影响程序化生成,默认值为 1 +| 属性名 | 说明 | +| -------------- | -------------------------- | +| width | 宽度,必填 | +| height | 高度,必填 | +| depth | 深度,必填 | +| widthSegments | 影响程序化生成,默认值为 1 | +| heightSegments | 影响程序化生成,默认值为 1 | +| depthSegments | 影响程序化生成,默认值为 1 | ### SphereGeometry 球体,[示例](/zh/examples/3d#sphere) - +sphere -#### radius - -球半径,必填,默认值为 0.5 - -#### latitudeBands - -默认值为 16 - -#### longitudeBands - -默认值为 16 +| 属性名 | 说明 | +| -------------- | -------------------------- | +| radius | 球半径,必填,默认值为 0.5 | +| latitudeBands | 默认值为 16 | +| longitudeBands | 默认值为 16 | ### PlaneGeometry 平面,默认躺在 XZ 平面上,[示例](/zh/examples/3d#plane) - - -#### width +plane -必填,宽度 +| 属性名 | 说明 | +| ------------- | ---------- | +| width | 宽度 | +| depth | 深度 | +| widthSegments | 默认值为 5 | +| depthSegments | 默认值为 5 | -#### depth +### TorusGeometry -必填,深度 +圆环,[示例](/zh/examples/3d#torus) -#### widthSegments +torus -选填,默认值为 5 +| 属性名 | 说明 | +| ---------- | ------------------ | +| tubeRadius | 选填,默认值为 0.2 | +| ringRadius | 选填,默认值为 0.3 | +| segments | 选填,默认值为 30 | +| sides | 选填,默认值为 20 | -#### depthSegments +### CylinderGeometry -选填,默认值为 5 +圆柱,[示例](/zh/examples/3d#cylinder) -### TorusGeometry - -圆环,[示例](/zh/examples/3d#torus) +cylinder - +| 属性名 | 说明 | +| -------------- | ---------------------------------- | +| radius | 圆柱体顶面半径,默认值为 0.5 | +| height | 圆柱体高度,默认值为 1 | +| heightSegments | 圆柱体身体曲面划分数目,默认值为 5 | +| capSegments | 圆柱体顶面划分数目,默认值为 20 | -#### tubeRadius +### ConeGeometry -选填,默认值为 0.2 +圆锥,[示例](/zh/examples/3d#cone) -#### ringRadius +cone -选填,默认值为 0.3 +| 属性名 | 说明 | +| -------------- | ---------------------------------- | +| baseRadius | 圆锥体底面半径,默认值为 0.5 | +| peakRadius | 圆锥体顶面半径,默认值为 0 | +| height | 圆锥体高度,默认值为 1 | +| heightSegments | 圆锥体身体曲面划分数目,默认值为 5 | +| capSegments | 圆锥体顶面划分数目,默认值为 20 | -#### segments +### CapsuleGeometry -选填,默认值为 30 +胶囊,[示例](/zh/examples/3d#capsule) -#### sides +capsule -选填,默认值为 20 +| 属性名 | 说明 | +| -------------- | -------------------------------- | +| radius | 胶囊半径,默认值为 0.5 | +| height | 胶囊高度,默认值为 1 | +| heightSegments | 胶囊身体曲面划分数目,默认值为 1 | +| sides | 胶囊顶面划分数目,默认值为 20 | ## BufferGeometry diff --git a/site/docs/api/3d/geometry.zh.md b/site/docs/api/3d/geometry.zh.md index 1dca90136..0035bffd7 100644 --- a/site/docs/api/3d/geometry.zh.md +++ b/site/docs/api/3d/geometry.zh.md @@ -60,93 +60,94 @@ cube.style.width = 300; 立方体,[示例](/zh/examples/3d#cube) - +cube -#### width - -宽度,必填。 - -#### height - -高度,必填。 - -#### depth - -深度,必填。 - -#### widthSegments - -影响程序化生成,默认值为 1 - -#### heightSegments - -影响程序化生成,默认值为 1 - -#### depthSegments - -影响程序化生成,默认值为 1 +| 属性名 | 说明 | +| -------------- | -------------------------- | +| width | 宽度,必填 | +| height | 高度,必填 | +| depth | 深度,必填 | +| widthSegments | 影响程序化生成,默认值为 1 | +| heightSegments | 影响程序化生成,默认值为 1 | +| depthSegments | 影响程序化生成,默认值为 1 | ### SphereGeometry 球体,[示例](/zh/examples/3d#sphere) - +sphere -#### radius - -球半径,必填,默认值为 0.5 - -#### latitudeBands - -默认值为 16 - -#### longitudeBands - -默认值为 16 +| 属性名 | 说明 | +| -------------- | -------------------------- | +| radius | 球半径,必填,默认值为 0.5 | +| latitudeBands | 默认值为 16 | +| longitudeBands | 默认值为 16 | ### PlaneGeometry 平面,默认躺在 XZ 平面上,[示例](/zh/examples/3d#plane) - - -#### width +plane -必填,宽度 +| 属性名 | 说明 | +| ------------- | ---------- | +| width | 宽度 | +| depth | 深度 | +| widthSegments | 默认值为 5 | +| depthSegments | 默认值为 5 | -#### depth +### TorusGeometry -必填,深度 +圆环,[示例](/zh/examples/3d#torus) -#### widthSegments +torus -选填,默认值为 5 +| 属性名 | 说明 | +| ---------- | ------------------ | +| tubeRadius | 选填,默认值为 0.2 | +| ringRadius | 选填,默认值为 0.3 | +| segments | 选填,默认值为 30 | +| sides | 选填,默认值为 20 | -#### depthSegments +### CylinderGeometry -选填,默认值为 5 +圆柱,[示例](/zh/examples/3d#cylinder) -### TorusGeometry - -圆环,[示例](/zh/examples/3d#torus) +cylinder - +| 属性名 | 说明 | +| -------------- | ---------------------------------- | +| radius | 圆柱体顶面半径,默认值为 0.5 | +| height | 圆柱体高度,默认值为 1 | +| heightSegments | 圆柱体身体曲面划分数目,默认值为 5 | +| capSegments | 圆柱体顶面划分数目,默认值为 20 | -#### tubeRadius +### ConeGeometry -选填,默认值为 0.2 +圆锥,[示例](/zh/examples/3d#cone) -#### ringRadius +cone -选填,默认值为 0.3 +| 属性名 | 说明 | +| -------------- | ---------------------------------- | +| baseRadius | 圆锥体底面半径,默认值为 0.5 | +| peakRadius | 圆锥体顶面半径,默认值为 0 | +| height | 圆锥体高度,默认值为 1 | +| heightSegments | 圆锥体身体曲面划分数目,默认值为 5 | +| capSegments | 圆锥体顶面划分数目,默认值为 20 | -#### segments +### CapsuleGeometry -选填,默认值为 30 +胶囊,[示例](/zh/examples/3d#capsule) -#### sides +capsule -选填,默认值为 20 +| 属性名 | 说明 | +| -------------- | -------------------------------- | +| radius | 胶囊半径,默认值为 0.5 | +| height | 胶囊高度,默认值为 1 | +| heightSegments | 胶囊身体曲面划分数目,默认值为 1 | +| sides | 胶囊顶面划分数目,默认值为 20 | ## BufferGeometry diff --git a/site/docs/api/3d/material.en.md b/site/docs/api/3d/material.en.md index 6bb2e3914..ed9e7f8b7 100644 --- a/site/docs/api/3d/material.en.md +++ b/site/docs/api/3d/material.en.md @@ -71,7 +71,7 @@ material.cullMode = CullMode.BACK; ### wireframe -是否绘制 wireframe,常用于直观展示三角面。开启后将额外生成重心坐标,原理详见 https://zhuanlan.zhihu.com/p/48499247。 +是否绘制 wireframe,常用于直观展示三角面。开启后将额外生成重心坐标,原理详见 @@ -292,7 +292,7 @@ material.setUniform({ ### MeshBasicMaterial -和 Three.js 保持一致:https://threejs.org/docs/#api/en/materials/MeshBasicMaterial +和 Three.js 保持一致: 该材质不受光照影响,从 FragmentShader 可以看出直接使用 fill 定义的颜色或者 map 定义的贴图: @@ -338,11 +338,15 @@ const basicMaterial = new MeshBasicMaterial({ }); ``` +### MeshLambertMaterial + +继承自 MeshBasicMaterial,使用 Lambertian 模型,无高光。 + ### MeshPhongMaterial 继承自 MeshBasicMaterial,使用 Blinn-Phong 光照模型。 -在多伦多大学的某教学页面上可以看到 Phong 模型的一个基础实现: http://www.cs.toronto.edu/~jacobson/phong-demo/ +在多伦多大学的某教学页面上可以看到 Phong 模型的一个基础实现: 该模型将直接光照部分“漫反射”、高光与间接光照部分“环境光”累加,得出最终的贡献值。从下图中我们能看到物体表面的法线、光源到物体表面的入射方向,以及人眼(相机)的观察方向都需要考虑。 @@ -455,12 +459,12 @@ struct ub_SceneParams { // https://github.com/mrdoob/three.js/blob/e1ead8c5c2/src/renderers/shaders/ShaderChunk/alphamap_fragment.glsl.js export default /* glsl */ ` #ifdef USE_ALPHAMAP - diffuseColor.a *= texture2D( alphaMap, vUv ).g; + diffuseColor.a *= texture2D( alphaMap, vUv ).g; #endif `; ``` -好处是无需额外的构建工具 loader/插件,坏处就是丧失了语法高亮,在 Shader 开发时容易犯错。我们希望使用编辑器的高亮以及 Lint,例如配合 VSCode GLSL Lint 插件。因此 shader 需要以 \*.glsl/vert/frag 形式存在,使用时以文本形式引入: +好处是无需额外的构建工具 loader/插件,坏处就是丧失了语法高亮,在 Shader 开发时容易犯错。我们希望使用编辑器的高亮以及 Lint,例如配合 VS Code GLSL Lint 插件。因此 shader 需要以 \*.glsl/vert/frag 形式存在,使用时以文本形式引入: ```js // 引入文本字符串 @@ -488,14 +492,14 @@ uniform vec4 color; void main(void) { #include - gbuf_color = color; + gbuf_color = color; } ``` 在构建时完成替换可以省掉 compiler 代码,现成的方案是 glslify,但需要配合构建工具,例如: -- webpack https://github.com/glslify/glslify-loader -- babel https://github.com/onnovisser/babel-plugin-glsl +- webpack +- babel - rollup rollup-plugin-glslify 我们选择它 ```glsl @@ -509,7 +513,7 @@ void main() { 但问题是会增大包体积,毕竟共用的 chunk 都内联在每个内置 Shader 字符串中了。 -参考 stack.gl 建立的一系列 shader components:https://github.com/glslify/glsl-easings 我们也提供一个 `@antv/g-shader-components` 包提供内置的所有 chunks。 +参考 stack.gl 建立的一系列 shader components: 我们也提供一个 `@antv/g-shader-components` 包提供内置的所有 chunks。 ### Shader 压缩 diff --git a/site/docs/api/3d/material.zh.md b/site/docs/api/3d/material.zh.md index 6bb2e3914..173fb2f29 100644 --- a/site/docs/api/3d/material.zh.md +++ b/site/docs/api/3d/material.zh.md @@ -71,7 +71,7 @@ material.cullMode = CullMode.BACK; ### wireframe -是否绘制 wireframe,常用于直观展示三角面。开启后将额外生成重心坐标,原理详见 https://zhuanlan.zhihu.com/p/48499247。 +是否绘制 wireframe,常用于直观展示三角面。开启后将额外生成重心坐标,原理详见 @@ -292,7 +292,7 @@ material.setUniform({ ### MeshBasicMaterial -和 Three.js 保持一致:https://threejs.org/docs/#api/en/materials/MeshBasicMaterial +和 Three.js 保持一致: 该材质不受光照影响,从 FragmentShader 可以看出直接使用 fill 定义的颜色或者 map 定义的贴图: @@ -338,11 +338,19 @@ const basicMaterial = new MeshBasicMaterial({ }); ``` +### MeshLambertMaterial + +继承自 MeshBasicMaterial,使用 Lambertian 模型,无高光。 + +#### emissive + +自发光颜色。 + ### MeshPhongMaterial 继承自 MeshBasicMaterial,使用 Blinn-Phong 光照模型。 -在多伦多大学的某教学页面上可以看到 Phong 模型的一个基础实现: http://www.cs.toronto.edu/~jacobson/phong-demo/ +在多伦多大学的某教学页面上可以看到 Phong 模型的一个基础实现: 该模型将直接光照部分“漫反射”、高光与间接光照部分“环境光”累加,得出最终的贡献值。从下图中我们能看到物体表面的法线、光源到物体表面的入射方向,以及人眼(相机)的观察方向都需要考虑。 @@ -455,12 +463,12 @@ struct ub_SceneParams { // https://github.com/mrdoob/three.js/blob/e1ead8c5c2/src/renderers/shaders/ShaderChunk/alphamap_fragment.glsl.js export default /* glsl */ ` #ifdef USE_ALPHAMAP - diffuseColor.a *= texture2D( alphaMap, vUv ).g; + diffuseColor.a *= texture2D( alphaMap, vUv ).g; #endif `; ``` -好处是无需额外的构建工具 loader/插件,坏处就是丧失了语法高亮,在 Shader 开发时容易犯错。我们希望使用编辑器的高亮以及 Lint,例如配合 VSCode GLSL Lint 插件。因此 shader 需要以 \*.glsl/vert/frag 形式存在,使用时以文本形式引入: +好处是无需额外的构建工具 loader/插件,坏处就是丧失了语法高亮,在 Shader 开发时容易犯错。我们希望使用编辑器的高亮以及 Lint,例如配合 VS Code GLSL Lint 插件。因此 shader 需要以 \*.glsl/vert/frag 形式存在,使用时以文本形式引入: ```js // 引入文本字符串 @@ -488,14 +496,14 @@ uniform vec4 color; void main(void) { #include - gbuf_color = color; + gbuf_color = color; } ``` 在构建时完成替换可以省掉 compiler 代码,现成的方案是 glslify,但需要配合构建工具,例如: -- webpack https://github.com/glslify/glslify-loader -- babel https://github.com/onnovisser/babel-plugin-glsl +- webpack +- babel - rollup rollup-plugin-glslify 我们选择它 ```glsl @@ -509,7 +517,7 @@ void main() { 但问题是会增大包体积,毕竟共用的 chunk 都内联在每个内置 Shader 字符串中了。 -参考 stack.gl 建立的一系列 shader components:https://github.com/glslify/glsl-easings 我们也提供一个 `@antv/g-shader-components` 包提供内置的所有 chunks。 +参考 stack.gl 建立的一系列 shader components: 我们也提供一个 `@antv/g-shader-components` 包提供内置的所有 chunks。 ### Shader 压缩 diff --git a/site/examples/3d/geometry/demo/capsule.js b/site/examples/3d/geometry/demo/capsule.js new file mode 100644 index 000000000..29e025283 --- /dev/null +++ b/site/examples/3d/geometry/demo/capsule.js @@ -0,0 +1,176 @@ +import { Canvas, CanvasEvent } from '@antv/g'; +import { Renderer } from '@antv/g-webgl'; +import { + MeshPhongMaterial, + CapsuleGeometry, + DirectionalLight, + Mesh, + FogType, + Plugin as Plugin3D, +} from '@antv/g-plugin-3d'; +import { Plugin as PluginControl } from '@antv/g-plugin-control'; +import * as lil from 'lil-gui'; +import Stats from 'stats.js'; + +// create a renderer +const renderer = new Renderer(); +renderer.registerPlugin(new Plugin3D()); +renderer.registerPlugin(new PluginControl()); + +// create a canvas +const canvas = new Canvas({ + container: 'container', + width: 600, + height: 500, + renderer, +}); + +(async () => { + // wait for canvas' initialization complete + await canvas.ready; + // use GPU device + const plugin = renderer.getPlugin('device-renderer'); + const device = plugin.getDevice(); + + const capsuleGeometry = new CapsuleGeometry(device, { + radius: 50, + height: 200, + }); + const basicMaterial = new MeshPhongMaterial(device); + + const capsule = new Mesh({ + style: { + x: 300, + y: 250, + fill: 'white', + opacity: 1, + geometry: capsuleGeometry, + material: basicMaterial, + }, + }); + + canvas.appendChild(capsule); + + // add a directional light into scene + const light = new DirectionalLight({ + style: { + fill: 'white', + direction: [-1, 0, 1], + }, + }); + canvas.appendChild(light); + + const camera = canvas.getCamera(); + camera.setPosition(300, 0, 500); + + // stats + const stats = new Stats(); + stats.showPanel(0); + const $stats = stats.dom; + $stats.style.position = 'absolute'; + $stats.style.left = '0px'; + $stats.style.top = '0px'; + const $wrapper = document.getElementById('container'); + $wrapper.appendChild($stats); + canvas.addEventListener(CanvasEvent.AFTER_RENDER, () => { + if (stats) { + stats.update(); + } + capsule.setOrigin(0, 0, 0); + capsule.rotate(0, 0.2, 0); + }); + + // GUI + const gui = new lil.GUI({ autoPlace: false }); + $wrapper.appendChild(gui.domElement); + + const capsuleFolder = gui.addFolder('capsule'); + const capsuleConfig = { + opacity: 1, + fill: '#fff', + }; + capsuleFolder.add(capsuleConfig, 'opacity', 0, 1, 0.1).onChange((opacity) => { + capsule.style.opacity = opacity; + }); + capsuleFolder.addColor(capsuleConfig, 'fill').onChange((color) => { + capsule.style.fill = color; + }); + capsuleFolder.open(); + + const geometryFolder = gui.addFolder('geometry'); + const geometryConfig = { + radius: 100, + height: 200, + heightSegments: 5, + capSegments: 20, + }; + geometryFolder.add(geometryConfig, 'radius', 10, 300).onChange((radius) => { + capsuleGeometry.radius = radius; + }); + geometryFolder.add(geometryConfig, 'height', 10, 300).onChange((height) => { + capsuleGeometry.height = height; + }); + geometryFolder + .add(geometryConfig, 'heightSegments', 2, 30, 1) + .onChange((heightSegments) => { + capsuleGeometry.heightSegments = heightSegments; + }); + geometryFolder + .add(geometryConfig, 'capSegments', 2, 30, 1) + .onChange((capSegments) => { + capsuleGeometry.capSegments = capSegments; + }); + geometryFolder.open(); + + const materialFolder = gui.addFolder('material'); + const materialConfig = { + wireframe: false, + map: 'none', + fogType: FogType.NONE, + fogColor: '#000000', + fogDensity: 0.5, + fogStart: 1, + fogEnd: 1000, + }; + materialFolder.add(materialConfig, 'wireframe').onChange((enable) => { + capsule.style.material.wireframe = !!enable; + }); + materialFolder + .add(materialConfig, 'map', [ + 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*npAsSLPX4A4AAAAAAAAAAAAAARQnAQ', + 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*N4ZMS7gHsUIAAAAAAAAAAABkARQnAQ', + 'none', + ]) + .onChange((mapURL) => { + if (mapURL === 'none') { + capsule.style.material.map = null; + } else { + const map = plugin.loadTexture(mapURL); + capsule.style.material.map = map; + } + }); + const fogTypes = [FogType.NONE, FogType.EXP, FogType.EXP2, FogType.LINEAR]; + materialFolder + .add(materialConfig, 'fogType', fogTypes) + .onChange((fogType) => { + // FogType.NONE + capsule.style.material.fogType = fogType; + }); + materialFolder.addColor(materialConfig, 'fogColor').onChange((fogColor) => { + capsule.style.material.fogColor = fogColor; + }); + materialFolder + .add(materialConfig, 'fogDensity', 0, 10) + .onChange((fogDensity) => { + capsule.style.material.fogDensity = fogDensity; + }); + materialFolder + .add(materialConfig, 'fogStart', 0, 1000) + .onChange((fogStart) => { + capsule.style.material.fogStart = fogStart; + }); + materialFolder.add(materialConfig, 'fogEnd', 0, 1000).onChange((fogEnd) => { + capsule.style.material.fogEnd = fogEnd; + }); + materialFolder.open(); +})(); diff --git a/site/examples/3d/geometry/demo/cone.js b/site/examples/3d/geometry/demo/cone.js new file mode 100644 index 000000000..f3dcbb94a --- /dev/null +++ b/site/examples/3d/geometry/demo/cone.js @@ -0,0 +1,184 @@ +import { Canvas, CanvasEvent } from '@antv/g'; +import { Renderer } from '@antv/g-webgl'; +import { + MeshPhongMaterial, + ConeGeometry, + DirectionalLight, + Mesh, + FogType, + Plugin as Plugin3D, +} from '@antv/g-plugin-3d'; +import { Plugin as PluginControl } from '@antv/g-plugin-control'; +import * as lil from 'lil-gui'; +import Stats from 'stats.js'; + +// create a renderer +const renderer = new Renderer(); +renderer.registerPlugin(new Plugin3D()); +renderer.registerPlugin(new PluginControl()); + +// create a canvas +const canvas = new Canvas({ + container: 'container', + width: 600, + height: 500, + renderer, +}); + +(async () => { + // wait for canvas' initialization complete + await canvas.ready; + // use GPU device + const plugin = renderer.getPlugin('device-renderer'); + const device = plugin.getDevice(); + + const coneGeometry = new ConeGeometry(device, { + baseRadius: 100, + height: 200, + }); + const basicMaterial = new MeshPhongMaterial(device); + + const cone = new Mesh({ + style: { + x: 300, + y: 250, + fill: 'white', + opacity: 1, + geometry: coneGeometry, + material: basicMaterial, + }, + }); + + canvas.appendChild(cone); + + // add a directional light into scene + const light = new DirectionalLight({ + style: { + fill: 'white', + direction: [-1, 0, 1], + }, + }); + canvas.appendChild(light); + + const camera = canvas.getCamera(); + camera.setPosition(300, 0, 500); + + // stats + const stats = new Stats(); + stats.showPanel(0); + const $stats = stats.dom; + $stats.style.position = 'absolute'; + $stats.style.left = '0px'; + $stats.style.top = '0px'; + const $wrapper = document.getElementById('container'); + $wrapper.appendChild($stats); + canvas.addEventListener(CanvasEvent.AFTER_RENDER, () => { + if (stats) { + stats.update(); + } + cone.setOrigin(0, 0, 0); + cone.rotate(0, 0.2, 0); + }); + + // GUI + const gui = new lil.GUI({ autoPlace: false }); + $wrapper.appendChild(gui.domElement); + + const coneFolder = gui.addFolder('cone'); + const coneConfig = { + opacity: 1, + fill: '#fff', + }; + coneFolder.add(coneConfig, 'opacity', 0, 1, 0.1).onChange((opacity) => { + cone.style.opacity = opacity; + }); + coneFolder.addColor(coneConfig, 'fill').onChange((color) => { + cone.style.fill = color; + }); + coneFolder.open(); + + const geometryFolder = gui.addFolder('geometry'); + const geometryConfig = { + baseRadius: 100, + peakRadius: 0, + height: 200, + heightSegments: 5, + capSegments: 20, + }; + geometryFolder + .add(geometryConfig, 'baseRadius', 10, 300) + .onChange((baseRadius) => { + coneGeometry.baseRadius = baseRadius; + }); + geometryFolder + .add(geometryConfig, 'peakRadius', 0, 100) + .onChange((peakRadius) => { + coneGeometry.peakRadius = peakRadius; + }); + geometryFolder.add(geometryConfig, 'height', 10, 300).onChange((height) => { + coneGeometry.height = height; + }); + geometryFolder + .add(geometryConfig, 'heightSegments', 2, 30, 1) + .onChange((heightSegments) => { + coneGeometry.heightSegments = heightSegments; + }); + geometryFolder + .add(geometryConfig, 'capSegments', 2, 30, 1) + .onChange((capSegments) => { + coneGeometry.capSegments = capSegments; + }); + geometryFolder.open(); + + const materialFolder = gui.addFolder('material'); + const materialConfig = { + wireframe: false, + map: 'none', + fogType: FogType.NONE, + fogColor: '#000000', + fogDensity: 0.5, + fogStart: 1, + fogEnd: 1000, + }; + materialFolder.add(materialConfig, 'wireframe').onChange((enable) => { + cone.style.material.wireframe = !!enable; + }); + materialFolder + .add(materialConfig, 'map', [ + 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*npAsSLPX4A4AAAAAAAAAAAAAARQnAQ', + 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*N4ZMS7gHsUIAAAAAAAAAAABkARQnAQ', + 'none', + ]) + .onChange((mapURL) => { + if (mapURL === 'none') { + cone.style.material.map = null; + } else { + const map = plugin.loadTexture(mapURL); + cone.style.material.map = map; + } + }); + const fogTypes = [FogType.NONE, FogType.EXP, FogType.EXP2, FogType.LINEAR]; + materialFolder + .add(materialConfig, 'fogType', fogTypes) + .onChange((fogType) => { + // FogType.NONE + cone.style.material.fogType = fogType; + }); + materialFolder.addColor(materialConfig, 'fogColor').onChange((fogColor) => { + cone.style.material.fogColor = fogColor; + }); + materialFolder + .add(materialConfig, 'fogDensity', 0, 10) + .onChange((fogDensity) => { + cone.style.material.fogDensity = fogDensity; + }); + materialFolder + .add(materialConfig, 'fogStart', 0, 1000) + .onChange((fogStart) => { + cone.style.material.fogStart = fogStart; + }); + materialFolder.add(materialConfig, 'fogEnd', 0, 1000).onChange((fogEnd) => { + cone.style.material.fogEnd = fogEnd; + }); + materialFolder.open(); +})(); diff --git a/site/examples/3d/geometry/demo/cylinder.js b/site/examples/3d/geometry/demo/cylinder.js new file mode 100644 index 000000000..601fc19bb --- /dev/null +++ b/site/examples/3d/geometry/demo/cylinder.js @@ -0,0 +1,178 @@ +import { Canvas, CanvasEvent } from '@antv/g'; +import { Renderer } from '@antv/g-webgl'; +import { + MeshPhongMaterial, + CylinderGeometry, + DirectionalLight, + Mesh, + FogType, + Plugin as Plugin3D, +} from '@antv/g-plugin-3d'; +import { Plugin as PluginControl } from '@antv/g-plugin-control'; +import * as lil from 'lil-gui'; +import Stats from 'stats.js'; + +// create a renderer +const renderer = new Renderer(); +renderer.registerPlugin(new Plugin3D()); +renderer.registerPlugin(new PluginControl()); + +// create a canvas +const canvas = new Canvas({ + container: 'container', + width: 600, + height: 500, + renderer, +}); + +(async () => { + // wait for canvas' initialization complete + await canvas.ready; + // use GPU device + const plugin = renderer.getPlugin('device-renderer'); + const device = plugin.getDevice(); + + const cylinderGeometry = new CylinderGeometry(device, { + radius: 100, + height: 200, + }); + const basicMaterial = new MeshPhongMaterial(device); + + const cylinder = new Mesh({ + style: { + x: 300, + y: 250, + fill: 'white', + opacity: 1, + geometry: cylinderGeometry, + material: basicMaterial, + }, + }); + + canvas.appendChild(cylinder); + + // add a directional light into scene + const light = new DirectionalLight({ + style: { + fill: 'white', + direction: [-1, 0, 1], + }, + }); + canvas.appendChild(light); + + const camera = canvas.getCamera(); + camera.setPosition(300, 0, 500); + + // stats + const stats = new Stats(); + stats.showPanel(0); + const $stats = stats.dom; + $stats.style.position = 'absolute'; + $stats.style.left = '0px'; + $stats.style.top = '0px'; + const $wrapper = document.getElementById('container'); + $wrapper.appendChild($stats); + canvas.addEventListener(CanvasEvent.AFTER_RENDER, () => { + if (stats) { + stats.update(); + } + cylinder.setOrigin(0, 0, 0); + cylinder.rotate(0, 0.2, 0); + }); + + // GUI + const gui = new lil.GUI({ autoPlace: false }); + $wrapper.appendChild(gui.domElement); + + const cylinderFolder = gui.addFolder('cylinder'); + const cylinderConfig = { + opacity: 1, + fill: '#fff', + }; + cylinderFolder + .add(cylinderConfig, 'opacity', 0, 1, 0.1) + .onChange((opacity) => { + cylinder.style.opacity = opacity; + }); + cylinderFolder.addColor(cylinderConfig, 'fill').onChange((color) => { + cylinder.style.fill = color; + }); + cylinderFolder.open(); + + const geometryFolder = gui.addFolder('geometry'); + const geometryConfig = { + radius: 100, + height: 200, + heightSegments: 5, + capSegments: 20, + }; + geometryFolder.add(geometryConfig, 'radius', 10, 300).onChange((radius) => { + cylinderGeometry.radius = radius; + }); + geometryFolder.add(geometryConfig, 'height', 10, 300).onChange((height) => { + cylinderGeometry.height = height; + }); + geometryFolder + .add(geometryConfig, 'heightSegments', 2, 30, 1) + .onChange((heightSegments) => { + cylinderGeometry.heightSegments = heightSegments; + }); + geometryFolder + .add(geometryConfig, 'capSegments', 2, 30, 1) + .onChange((capSegments) => { + cylinderGeometry.capSegments = capSegments; + }); + geometryFolder.open(); + + const materialFolder = gui.addFolder('material'); + const materialConfig = { + wireframe: false, + map: 'none', + fogType: FogType.NONE, + fogColor: '#000000', + fogDensity: 0.5, + fogStart: 1, + fogEnd: 1000, + }; + materialFolder.add(materialConfig, 'wireframe').onChange((enable) => { + cylinder.style.material.wireframe = !!enable; + }); + materialFolder + .add(materialConfig, 'map', [ + 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*npAsSLPX4A4AAAAAAAAAAAAAARQnAQ', + 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*N4ZMS7gHsUIAAAAAAAAAAABkARQnAQ', + 'none', + ]) + .onChange((mapURL) => { + if (mapURL === 'none') { + cylinder.style.material.map = null; + } else { + const map = plugin.loadTexture(mapURL); + cylinder.style.material.map = map; + } + }); + const fogTypes = [FogType.NONE, FogType.EXP, FogType.EXP2, FogType.LINEAR]; + materialFolder + .add(materialConfig, 'fogType', fogTypes) + .onChange((fogType) => { + // FogType.NONE + cylinder.style.material.fogType = fogType; + }); + materialFolder.addColor(materialConfig, 'fogColor').onChange((fogColor) => { + cylinder.style.material.fogColor = fogColor; + }); + materialFolder + .add(materialConfig, 'fogDensity', 0, 10) + .onChange((fogDensity) => { + cylinder.style.material.fogDensity = fogDensity; + }); + materialFolder + .add(materialConfig, 'fogStart', 0, 1000) + .onChange((fogStart) => { + cylinder.style.material.fogStart = fogStart; + }); + materialFolder.add(materialConfig, 'fogEnd', 0, 1000).onChange((fogEnd) => { + cylinder.style.material.fogEnd = fogEnd; + }); + materialFolder.open(); +})(); diff --git a/site/examples/3d/geometry/demo/meta.json b/site/examples/3d/geometry/demo/meta.json index fb1281c46..e93c349de 100644 --- a/site/examples/3d/geometry/demo/meta.json +++ b/site/examples/3d/geometry/demo/meta.json @@ -44,6 +44,30 @@ }, "screenshot": "https://mdn.alipayobjects.com/mdn/huamei_qa8qxu/afts/img/A*C5ZXT7TaG9cAAAAAAAAAAAAADmJ7AQ" }, + { + "filename": "cylinder.js", + "title": { + "zh": "圆柱", + "en": "Cylinder" + }, + "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*Vx-bSZTGKrIAAAAAAAAAAAAADmJ7AQ/original" + }, + { + "filename": "cone.js", + "title": { + "zh": "圆锥", + "en": "Cone" + }, + "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*4v4GQrGXA_UAAAAAAAAAAAAADmJ7AQ/original" + }, + { + "filename": "capsule.js", + "title": { + "zh": "胶囊", + "en": "Capsule" + }, + "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*5czISLOqEeUAAAAAAAAAAAAADmJ7AQ/original" + }, { "filename": "buffer-geometry.js", "title": { diff --git a/site/examples/3d/geometry/demo/torus.js b/site/examples/3d/geometry/demo/torus.js index 67bb09113..d6c0aea3f 100644 --- a/site/examples/3d/geometry/demo/torus.js +++ b/site/examples/3d/geometry/demo/torus.js @@ -87,7 +87,7 @@ const canvas = new Canvas({ const torusFolder = gui.addFolder('torus'); const torusConfig = { opacity: 1, - fill: '#1890FF', + fill: '#fff', }; torusFolder.add(torusConfig, 'opacity', 0, 1, 0.1).onChange((opacity) => { torus.style.opacity = opacity; diff --git a/site/examples/3d/material/demo/basic.js b/site/examples/3d/material/demo/basic.js new file mode 100644 index 000000000..b8bbc7d25 --- /dev/null +++ b/site/examples/3d/material/demo/basic.js @@ -0,0 +1,178 @@ +import { Canvas, CanvasEvent } from '@antv/g'; +import { Renderer } from '@antv/g-webgl'; +import { + MeshBasicMaterial, + TorusGeometry, + DirectionalLight, + Mesh, + FogType, + Plugin as Plugin3D, +} from '@antv/g-plugin-3d'; +import { Plugin as PluginControl } from '@antv/g-plugin-control'; +import * as lil from 'lil-gui'; +import Stats from 'stats.js'; + +// create a renderer +const renderer = new Renderer(); +renderer.registerPlugin(new Plugin3D()); +renderer.registerPlugin(new PluginControl()); + +// create a canvas +const canvas = new Canvas({ + container: 'container', + width: 600, + height: 500, + renderer, +}); + +(async () => { + // wait for canvas' initialization complete + await canvas.ready; + // use GPU device + const plugin = renderer.getPlugin('device-renderer'); + const device = plugin.getDevice(); + + const torusGeometry = new TorusGeometry(device, { + tubeRadius: 30, + ringRadius: 200, + }); + const basicMaterial = new MeshBasicMaterial(device); + + const torus = new Mesh({ + style: { + x: 300, + y: 250, + fill: '#b0b0b0', + opacity: 1, + geometry: torusGeometry, + material: basicMaterial, + }, + }); + + canvas.appendChild(torus); + + // add a directional light into scene + const light = new DirectionalLight({ + style: { + fill: 'white', + direction: [-1, 0, 1], + }, + }); + canvas.appendChild(light); + + const camera = canvas.getCamera(); + camera.setPosition(300, 0, 500); + + // stats + const stats = new Stats(); + stats.showPanel(0); + const $stats = stats.dom; + $stats.style.position = 'absolute'; + $stats.style.left = '0px'; + $stats.style.top = '0px'; + const $wrapper = document.getElementById('container'); + $wrapper.appendChild($stats); + canvas.addEventListener(CanvasEvent.AFTER_RENDER, () => { + if (stats) { + stats.update(); + } + torus.setOrigin(0, 0, 0); + torus.rotate(0, 0.2, 0); + }); + + // GUI + const gui = new lil.GUI({ autoPlace: false }); + $wrapper.appendChild(gui.domElement); + + const torusFolder = gui.addFolder('torus'); + const torusConfig = { + opacity: 1, + fill: '#b0b0b0', + }; + torusFolder.add(torusConfig, 'opacity', 0, 1, 0.1).onChange((opacity) => { + torus.style.opacity = opacity; + }); + torusFolder.addColor(torusConfig, 'fill').onChange((color) => { + torus.style.fill = color; + }); + torusFolder.open(); + + const geometryFolder = gui.addFolder('geometry'); + const geometryConfig = { + tubeRadius: 30, + ringRadius: 200, + segments: 30, + sides: 20, + }; + geometryFolder + .add(geometryConfig, 'tubeRadius', 10, 300) + .onChange((tubeRadius) => { + torusGeometry.tubeRadius = tubeRadius; + }); + geometryFolder + .add(geometryConfig, 'ringRadius', 10, 300) + .onChange((ringRadius) => { + torusGeometry.ringRadius = ringRadius; + }); + geometryFolder + .add(geometryConfig, 'segments', 2, 30, 1) + .onChange((segments) => { + torusGeometry.segments = segments; + }); + geometryFolder.add(geometryConfig, 'sides', 2, 30, 1).onChange((sides) => { + torusGeometry.sides = sides; + }); + geometryFolder.open(); + + const materialFolder = gui.addFolder('material'); + const materialConfig = { + wireframe: false, + map: 'none', + fogType: FogType.NONE, + fogColor: '#000000', + fogDensity: 0.5, + fogStart: 1, + fogEnd: 1000, + }; + materialFolder.add(materialConfig, 'wireframe').onChange((enable) => { + torus.style.material.wireframe = !!enable; + }); + materialFolder + .add(materialConfig, 'map', [ + 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*npAsSLPX4A4AAAAAAAAAAAAAARQnAQ', + 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*N4ZMS7gHsUIAAAAAAAAAAABkARQnAQ', + 'none', + ]) + .onChange((mapURL) => { + if (mapURL === 'none') { + torus.style.material.map = null; + } else { + const map = plugin.loadTexture(mapURL); + torus.style.material.map = map; + } + }); + const fogTypes = [FogType.NONE, FogType.EXP, FogType.EXP2, FogType.LINEAR]; + materialFolder + .add(materialConfig, 'fogType', fogTypes) + .onChange((fogType) => { + // FogType.NONE + torus.style.material.fogType = fogType; + }); + materialFolder.addColor(materialConfig, 'fogColor').onChange((fogColor) => { + torus.style.material.fogColor = fogColor; + }); + materialFolder + .add(materialConfig, 'fogDensity', 0, 10) + .onChange((fogDensity) => { + torus.style.material.fogDensity = fogDensity; + }); + materialFolder + .add(materialConfig, 'fogStart', 0, 1000) + .onChange((fogStart) => { + torus.style.material.fogStart = fogStart; + }); + materialFolder.add(materialConfig, 'fogEnd', 0, 1000).onChange((fogEnd) => { + torus.style.material.fogEnd = fogEnd; + }); + materialFolder.open(); +})(); diff --git a/site/examples/3d/material/demo/lambert.js b/site/examples/3d/material/demo/lambert.js new file mode 100644 index 000000000..ff857d0f1 --- /dev/null +++ b/site/examples/3d/material/demo/lambert.js @@ -0,0 +1,178 @@ +import { Canvas, CanvasEvent } from '@antv/g'; +import { Renderer } from '@antv/g-webgl'; +import { + MeshLambertMaterial, + TorusGeometry, + DirectionalLight, + Mesh, + FogType, + Plugin as Plugin3D, +} from '@antv/g-plugin-3d'; +import { Plugin as PluginControl } from '@antv/g-plugin-control'; +import * as lil from 'lil-gui'; +import Stats from 'stats.js'; + +// create a renderer +const renderer = new Renderer(); +renderer.registerPlugin(new Plugin3D()); +renderer.registerPlugin(new PluginControl()); + +// create a canvas +const canvas = new Canvas({ + container: 'container', + width: 600, + height: 500, + renderer, +}); + +(async () => { + // wait for canvas' initialization complete + await canvas.ready; + // use GPU device + const plugin = renderer.getPlugin('device-renderer'); + const device = plugin.getDevice(); + + const torusGeometry = new TorusGeometry(device, { + tubeRadius: 30, + ringRadius: 200, + }); + const basicMaterial = new MeshLambertMaterial(device); + + const torus = new Mesh({ + style: { + x: 300, + y: 250, + fill: 'white', + opacity: 1, + geometry: torusGeometry, + material: basicMaterial, + }, + }); + + canvas.appendChild(torus); + + // add a directional light into scene + const light = new DirectionalLight({ + style: { + fill: 'white', + direction: [-1, 0, 1], + }, + }); + canvas.appendChild(light); + + const camera = canvas.getCamera(); + camera.setPosition(300, 0, 500); + + // stats + const stats = new Stats(); + stats.showPanel(0); + const $stats = stats.dom; + $stats.style.position = 'absolute'; + $stats.style.left = '0px'; + $stats.style.top = '0px'; + const $wrapper = document.getElementById('container'); + $wrapper.appendChild($stats); + canvas.addEventListener(CanvasEvent.AFTER_RENDER, () => { + if (stats) { + stats.update(); + } + torus.setOrigin(0, 0, 0); + torus.rotate(0, 0.2, 0); + }); + + // GUI + const gui = new lil.GUI({ autoPlace: false }); + $wrapper.appendChild(gui.domElement); + + const torusFolder = gui.addFolder('torus'); + const torusConfig = { + opacity: 1, + fill: '#fff', + }; + torusFolder.add(torusConfig, 'opacity', 0, 1, 0.1).onChange((opacity) => { + torus.style.opacity = opacity; + }); + torusFolder.addColor(torusConfig, 'fill').onChange((color) => { + torus.style.fill = color; + }); + torusFolder.open(); + + const geometryFolder = gui.addFolder('geometry'); + const geometryConfig = { + tubeRadius: 30, + ringRadius: 200, + segments: 30, + sides: 20, + }; + geometryFolder + .add(geometryConfig, 'tubeRadius', 10, 300) + .onChange((tubeRadius) => { + torusGeometry.tubeRadius = tubeRadius; + }); + geometryFolder + .add(geometryConfig, 'ringRadius', 10, 300) + .onChange((ringRadius) => { + torusGeometry.ringRadius = ringRadius; + }); + geometryFolder + .add(geometryConfig, 'segments', 2, 30, 1) + .onChange((segments) => { + torusGeometry.segments = segments; + }); + geometryFolder.add(geometryConfig, 'sides', 2, 30, 1).onChange((sides) => { + torusGeometry.sides = sides; + }); + geometryFolder.open(); + + const materialFolder = gui.addFolder('material'); + const materialConfig = { + wireframe: false, + map: 'none', + fogType: FogType.NONE, + fogColor: '#000000', + fogDensity: 0.5, + fogStart: 1, + fogEnd: 1000, + }; + materialFolder.add(materialConfig, 'wireframe').onChange((enable) => { + torus.style.material.wireframe = !!enable; + }); + materialFolder + .add(materialConfig, 'map', [ + 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*npAsSLPX4A4AAAAAAAAAAAAAARQnAQ', + 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*N4ZMS7gHsUIAAAAAAAAAAABkARQnAQ', + 'none', + ]) + .onChange((mapURL) => { + if (mapURL === 'none') { + torus.style.material.map = null; + } else { + const map = plugin.loadTexture(mapURL); + torus.style.material.map = map; + } + }); + const fogTypes = [FogType.NONE, FogType.EXP, FogType.EXP2, FogType.LINEAR]; + materialFolder + .add(materialConfig, 'fogType', fogTypes) + .onChange((fogType) => { + // FogType.NONE + torus.style.material.fogType = fogType; + }); + materialFolder.addColor(materialConfig, 'fogColor').onChange((fogColor) => { + torus.style.material.fogColor = fogColor; + }); + materialFolder + .add(materialConfig, 'fogDensity', 0, 10) + .onChange((fogDensity) => { + torus.style.material.fogDensity = fogDensity; + }); + materialFolder + .add(materialConfig, 'fogStart', 0, 1000) + .onChange((fogStart) => { + torus.style.material.fogStart = fogStart; + }); + materialFolder.add(materialConfig, 'fogEnd', 0, 1000).onChange((fogEnd) => { + torus.style.material.fogEnd = fogEnd; + }); + materialFolder.open(); +})(); diff --git a/site/examples/3d/material/demo/meta.json b/site/examples/3d/material/demo/meta.json index b0834a484..afcd0f58c 100644 --- a/site/examples/3d/material/demo/meta.json +++ b/site/examples/3d/material/demo/meta.json @@ -4,6 +4,30 @@ "en": "Material" }, "demos": [ + { + "filename": "basic.js", + "title": { + "zh": "Basic", + "en": "Basic" + }, + "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*hMqFTYoGSnIAAAAAAAAAAAAADmJ7AQ/original" + }, + { + "filename": "lambert.js", + "title": { + "zh": "Lambert", + "en": "Lambert" + }, + "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*90sCSavLTiMAAAAAAAAAAAAADmJ7AQ/original" + }, + { + "filename": "phong.js", + "title": { + "zh": "Phong", + "en": "Phong" + }, + "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*m7RvSIZ45uwAAAAAAAAAAAAADmJ7AQ/original" + }, { "filename": "shader-material.js", "title": { diff --git a/site/examples/3d/material/demo/phong.js b/site/examples/3d/material/demo/phong.js new file mode 100644 index 000000000..d6c0aea3f --- /dev/null +++ b/site/examples/3d/material/demo/phong.js @@ -0,0 +1,178 @@ +import { Canvas, CanvasEvent } from '@antv/g'; +import { Renderer } from '@antv/g-webgl'; +import { + MeshPhongMaterial, + TorusGeometry, + DirectionalLight, + Mesh, + FogType, + Plugin as Plugin3D, +} from '@antv/g-plugin-3d'; +import { Plugin as PluginControl } from '@antv/g-plugin-control'; +import * as lil from 'lil-gui'; +import Stats from 'stats.js'; + +// create a renderer +const renderer = new Renderer(); +renderer.registerPlugin(new Plugin3D()); +renderer.registerPlugin(new PluginControl()); + +// create a canvas +const canvas = new Canvas({ + container: 'container', + width: 600, + height: 500, + renderer, +}); + +(async () => { + // wait for canvas' initialization complete + await canvas.ready; + // use GPU device + const plugin = renderer.getPlugin('device-renderer'); + const device = plugin.getDevice(); + + const torusGeometry = new TorusGeometry(device, { + tubeRadius: 30, + ringRadius: 200, + }); + const basicMaterial = new MeshPhongMaterial(device); + + const torus = new Mesh({ + style: { + x: 300, + y: 250, + fill: 'white', + opacity: 1, + geometry: torusGeometry, + material: basicMaterial, + }, + }); + + canvas.appendChild(torus); + + // add a directional light into scene + const light = new DirectionalLight({ + style: { + fill: 'white', + direction: [-1, 0, 1], + }, + }); + canvas.appendChild(light); + + const camera = canvas.getCamera(); + camera.setPosition(300, 0, 500); + + // stats + const stats = new Stats(); + stats.showPanel(0); + const $stats = stats.dom; + $stats.style.position = 'absolute'; + $stats.style.left = '0px'; + $stats.style.top = '0px'; + const $wrapper = document.getElementById('container'); + $wrapper.appendChild($stats); + canvas.addEventListener(CanvasEvent.AFTER_RENDER, () => { + if (stats) { + stats.update(); + } + torus.setOrigin(0, 0, 0); + torus.rotate(0, 0.2, 0); + }); + + // GUI + const gui = new lil.GUI({ autoPlace: false }); + $wrapper.appendChild(gui.domElement); + + const torusFolder = gui.addFolder('torus'); + const torusConfig = { + opacity: 1, + fill: '#fff', + }; + torusFolder.add(torusConfig, 'opacity', 0, 1, 0.1).onChange((opacity) => { + torus.style.opacity = opacity; + }); + torusFolder.addColor(torusConfig, 'fill').onChange((color) => { + torus.style.fill = color; + }); + torusFolder.open(); + + const geometryFolder = gui.addFolder('geometry'); + const geometryConfig = { + tubeRadius: 30, + ringRadius: 200, + segments: 30, + sides: 20, + }; + geometryFolder + .add(geometryConfig, 'tubeRadius', 10, 300) + .onChange((tubeRadius) => { + torusGeometry.tubeRadius = tubeRadius; + }); + geometryFolder + .add(geometryConfig, 'ringRadius', 10, 300) + .onChange((ringRadius) => { + torusGeometry.ringRadius = ringRadius; + }); + geometryFolder + .add(geometryConfig, 'segments', 2, 30, 1) + .onChange((segments) => { + torusGeometry.segments = segments; + }); + geometryFolder.add(geometryConfig, 'sides', 2, 30, 1).onChange((sides) => { + torusGeometry.sides = sides; + }); + geometryFolder.open(); + + const materialFolder = gui.addFolder('material'); + const materialConfig = { + wireframe: false, + map: 'none', + fogType: FogType.NONE, + fogColor: '#000000', + fogDensity: 0.5, + fogStart: 1, + fogEnd: 1000, + }; + materialFolder.add(materialConfig, 'wireframe').onChange((enable) => { + torus.style.material.wireframe = !!enable; + }); + materialFolder + .add(materialConfig, 'map', [ + 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*npAsSLPX4A4AAAAAAAAAAAAAARQnAQ', + 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*N4ZMS7gHsUIAAAAAAAAAAABkARQnAQ', + 'none', + ]) + .onChange((mapURL) => { + if (mapURL === 'none') { + torus.style.material.map = null; + } else { + const map = plugin.loadTexture(mapURL); + torus.style.material.map = map; + } + }); + const fogTypes = [FogType.NONE, FogType.EXP, FogType.EXP2, FogType.LINEAR]; + materialFolder + .add(materialConfig, 'fogType', fogTypes) + .onChange((fogType) => { + // FogType.NONE + torus.style.material.fogType = fogType; + }); + materialFolder.addColor(materialConfig, 'fogColor').onChange((fogColor) => { + torus.style.material.fogColor = fogColor; + }); + materialFolder + .add(materialConfig, 'fogDensity', 0, 10) + .onChange((fogDensity) => { + torus.style.material.fogDensity = fogDensity; + }); + materialFolder + .add(materialConfig, 'fogStart', 0, 1000) + .onChange((fogStart) => { + torus.style.material.fogStart = fogStart; + }); + materialFolder.add(materialConfig, 'fogEnd', 0, 1000).onChange((fogEnd) => { + torus.style.material.fogEnd = fogEnd; + }); + materialFolder.open(); +})(); diff --git a/site/examples/shape/path/demo/meta.json b/site/examples/shape/path/demo/meta.json index a8b6a70ab..ebbb3e871 100644 --- a/site/examples/shape/path/demo/meta.json +++ b/site/examples/shape/path/demo/meta.json @@ -34,7 +34,7 @@ "zh": "路径定义中包含多段", "en": "Multi segments in a path definition" }, - "screenshot": "https://mdn.alipayobjects.com/mdn/huamei_qa8qxu/afts/img/A*9Q4iQaoxsS0AAAAAAAAAAAAADmJ7AQ" + "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*AO0jT40V6S0AAAAAAAAAAAAADmJ7AQ/original" }, { "filename": "group.js", diff --git a/site/examples/style/gradient/demo/gradient-path.js b/site/examples/style/gradient/demo/gradient-path.js deleted file mode 100644 index 94d536fa9..000000000 --- a/site/examples/style/gradient/demo/gradient-path.js +++ /dev/null @@ -1,313 +0,0 @@ -import { - Canvas, - CanvasEvent, - HTML, - Line, - Rect, - Path, - convertToPath, -} from '@antv/g'; -import { Renderer as CanvasRenderer } from '@antv/g-canvas'; -import { Renderer as CanvaskitRenderer } from '@antv/g-canvaskit'; -import { Renderer as SVGRenderer } from '@antv/g-svg'; -import { Renderer as WebGLRenderer } from '@antv/g-webgl'; -import { Renderer as WebGPURenderer } from '@antv/g-webgpu'; -import * as lil from 'lil-gui'; -import Stats from 'stats.js'; - -/** - * - * e.g. linear-gradient(0deg, blue, green 40%, red) - * radial-gradient(circle at center, red 0, blue, green 100%) - * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/gradient/linear-gradient - * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/gradient/radial-gradient - * - * interactive demo: - * @see https://observablehq.com/@danburzo/css-gradient-line - */ - -// create a renderer -const canvasRenderer = new CanvasRenderer(); -const svgRenderer = new SVGRenderer(); -const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer({ - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', -}); -const canvaskitRenderer = new CanvaskitRenderer({ - wasmDir: '/', -}); - -// create a canvas -const canvas = new Canvas({ - container: 'container', - width: 600, - height: 500, - renderer: canvasRenderer, -}); - -// single linear gradient -const rect1 = new Rect({ - style: { - x: 50, - y: 50, - width: 200, - height: 100, - fill: 'linear-gradient(0deg, blue, green 40%, red)', - }, -}); -const rectPath = convertToPath(rect1); -const path1 = new Path({ - style: { - d: rectPath, - fill: 'linear-gradient(0deg, blue, green 40%, red)', - }, -}); - -// multi linear gradients -const rect2 = new Rect({ - style: { - x: 50, - y: 250, - width: 200, - height: 100, - fill: `linear-gradient(217deg, rgba(255,0,0,.8), rgba(255,0,0,0) 70.71%), - linear-gradient(127deg, rgba(0,255,0,.8), rgba(0,255,0,0) 70.71%), - linear-gradient(336deg, rgba(0,0,255,.8), rgba(0,0,255,0) 70.71%)`, - }, -}); - -// single radial gradient -const rect3 = new Rect({ - style: { - x: 350, - y: 50, - width: 200, - height: 100, - fill: 'radial-gradient(circle at center, red, blue, green 100%)', - }, -}); - -// hard stop -const rect4 = new Rect({ - style: { - x: 350, - y: 250, - width: 200, - height: 100, - fill: 'radial-gradient(red 50%, blue 50%)', - }, -}); - -const line1 = new Line({ - style: { - x1: 50, - y1: 180, - x2: 250, - y2: 180, - strokeWidth: 10, - stroke: 'linear-gradient(0deg, blue, green 40%, red)', - }, -}); -const line2 = new Line({ - style: { - x1: 350, - y1: 180, - x2: 550, - y2: 180, - strokeWidth: 10, - stroke: 'radial-gradient(circle at center, red, blue, green 100%)', - }, -}); - -canvas.addEventListener(CanvasEvent.READY, () => { - canvas.appendChild(line1); - canvas.appendChild(line2); - - canvas.appendChild(rect1); - canvas.appendChild(rect2); - canvas.appendChild(rect3); - canvas.appendChild(rect4); - - canvas.appendChild(path1); - - canvas.appendChild( - new HTML({ - style: { - x: 100, - y: 20, - height: 30, - width: 200, - innerHTML: 'linear gradient', - }, - }), - ); - canvas.appendChild( - new HTML({ - style: { - x: 60, - y: 220, - height: 30, - width: 200, - innerHTML: 'multiple linear gradients', - }, - }), - ); - canvas.appendChild( - new HTML({ - style: { - x: 350, - y: 20, - height: 30, - width: 200, - innerHTML: 'radial gradient', - }, - }), - ); - canvas.appendChild( - new HTML({ - style: { - x: 350, - y: 220, - height: 30, - width: 200, - innerHTML: 'hard color stop', - }, - }), - ); -}); - -// stats -const stats = new Stats(); -stats.showPanel(0); -const $stats = stats.dom; -$stats.style.position = 'absolute'; -$stats.style.left = '0px'; -$stats.style.top = '0px'; -const $wrapper = document.getElementById('container'); -$wrapper.appendChild($stats); -canvas.addEventListener(CanvasEvent.AFTER_RENDER, () => { - if (stats) { - stats.update(); - } -}); - -// GUI -const gui = new lil.GUI({ autoPlace: false }); -$wrapper.appendChild(gui.domElement); -const rendererFolder = gui.addFolder('renderer'); -const rendererConfig = { - renderer: 'canvas', -}; -rendererFolder - .add(rendererConfig, 'renderer', [ - 'canvas', - 'svg', - 'webgl', - 'webgpu', - 'canvaskit', - ]) - .onChange((rendererName) => { - let renderer; - if (rendererName === 'canvas') { - renderer = canvasRenderer; - } else if (rendererName === 'svg') { - renderer = svgRenderer; - } else if (rendererName === 'webgl') { - renderer = webglRenderer; - } else if (rendererName === 'webgpu') { - renderer = webgpuRenderer; - } else if (rendererName === 'canvaskit') { - renderer = canvaskitRenderer; - } - canvas.setRenderer(renderer); - }); -rendererFolder.open(); - -const linearGradientFolder = gui.addFolder('linear gradient'); -const linearGradientConfig = { - angle: 0, - width: 200, - height: 100, - 'side or corner': 'to right', - 'green color stop(%)': 40, -}; -linearGradientFolder - .add(linearGradientConfig, 'angle', 0, 360) - .onChange((angle) => { - rect1.style.fill = `linear-gradient(${angle}deg, blue, green 40%, red)`; - }); -linearGradientFolder - .add(linearGradientConfig, 'side or corner', [ - 'to left', - 'to top', - 'to bottom', - 'to right', - 'to left top', - 'to top left', - 'to left bottom', - 'to bottom left', - 'to right top', - 'to top right', - 'to right bottom', - 'to bottom right', - ]) - .onChange((direction) => { - rect1.style.fill = `linear-gradient(${direction}, blue, green 40%, red)`; - }); -linearGradientFolder - .add(linearGradientConfig, 'green color stop(%)', 0, 100) - .onChange((percentage) => { - rect1.style.fill = `linear-gradient(0deg, blue, green ${percentage}%, red)`; - }); -linearGradientFolder - .add(linearGradientConfig, 'width', 50, 400) - .onChange((width) => { - rect1.style.width = width; - }); -linearGradientFolder - .add(linearGradientConfig, 'height', 50, 400) - .onChange((height) => { - rect1.style.height = height; - }); - -const radialGradientFolder = gui.addFolder('radial gradient'); -const radialGradientConfig = { - position: 'center', - size: 'farthest-corner', - 'green color stop(%)': 100, -}; -radialGradientFolder - .add(radialGradientConfig, 'position', [ - 'top', - 'left', - 'bottom', - 'right', - 'center', - 'top left', - 'left top', - 'top right', - 'bottom left', - 'bottom right', - '25% 25%', - '50% 50%', - '50px 50px', - ]) - .onChange((position) => { - rect3.style.fill = `radial-gradient(circle ${radialGradientConfig.size} at ${position}, red, blue, green ${radialGradientConfig['green color stop(%)']}%)`; - }); -radialGradientFolder - .add(radialGradientConfig, 'size', [ - 'closest-side', - 'closest-corner', - 'farthest-side', - 'farthest-corner', - '100px', - ]) - .onChange((size) => { - rect3.style.fill = `radial-gradient(circle ${size} at ${radialGradientConfig.position}, red, blue, green ${radialGradientConfig['green color stop(%)']}%)`; - }); -radialGradientFolder - .add(radialGradientConfig, 'green color stop(%)', 0, 100) - .onChange((percentage) => { - rect3.style.fill = `radial-gradient(circle ${radialGradientConfig.size} at ${radialGradientConfig.position}, red, blue, green ${percentage}%)`; - }); diff --git a/site/examples/style/gradient/demo/meta.json b/site/examples/style/gradient/demo/meta.json index 3fe1a417d..a4144da34 100644 --- a/site/examples/style/gradient/demo/meta.json +++ b/site/examples/style/gradient/demo/meta.json @@ -9,10 +9,10 @@ "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*rWIvR729TqwAAAAAAAAAAAAADmJ7AQ/original" }, { - "filename": "gradient-path.js", + "filename": "path.js", "title": { - "zh": "Gradient", - "en": "Gradient" + "zh": "带渐变的 Path", + "en": "Path with gradient" } }, { @@ -20,7 +20,8 @@ "title": { "zh": "Radial Gradient", "en": "Radial Gradient" - } + }, + "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*8v8eQ77nS2EAAAAAAAAAAAAADmJ7AQ/original" }, { "filename": "inner-shadow.js", diff --git a/site/examples/style/gradient/demo/path.js b/site/examples/style/gradient/demo/path.js new file mode 100644 index 000000000..c964b8d61 --- /dev/null +++ b/site/examples/style/gradient/demo/path.js @@ -0,0 +1,87 @@ +import { Canvas, CanvasEvent, Path } from '@antv/g'; +import { Renderer as CanvasRenderer } from '@antv/g-canvas'; +import { Renderer as CanvaskitRenderer } from '@antv/g-canvaskit'; +import { Renderer as SVGRenderer } from '@antv/g-svg'; +import { Renderer as WebGLRenderer } from '@antv/g-webgl'; +import { Renderer as WebGPURenderer } from '@antv/g-webgpu'; +import * as lil from 'lil-gui'; +import Stats from 'stats.js'; + +// create a renderer +const canvasRenderer = new CanvasRenderer(); +const svgRenderer = new SVGRenderer(); +const webglRenderer = new WebGLRenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); +const canvaskitRenderer = new CanvaskitRenderer({ + wasmDir: '/', +}); + +// create a canvas +const canvas = new Canvas({ + container: 'container', + width: 600, + height: 500, + renderer: webglRenderer, +}); + +const path = new Path({ + style: { + d: 'M 100 100 L 200 200 L 300 400', + lineWidth: 10, + stroke: + 'linear-gradient(-90deg, rgba(178, 230, 181, 0), rgba(178, 230, 181, 0.6) 14%, rgba(166, 221, 179, 0.82) 23%, rgba(101, 171, 170, 0.9) 67%, rgb(23, 80, 157))', + }, +}); + +canvas.addEventListener(CanvasEvent.READY, () => { + canvas.appendChild(path); +}); + +// stats +const stats = new Stats(); +stats.showPanel(0); +const $stats = stats.dom; +$stats.style.position = 'absolute'; +$stats.style.left = '0px'; +$stats.style.top = '0px'; +const $wrapper = document.getElementById('container'); +$wrapper.appendChild($stats); +canvas.addEventListener(CanvasEvent.AFTER_RENDER, () => { + if (stats) { + stats.update(); + } +}); + +// GUI +const gui = new lil.GUI({ autoPlace: false }); +$wrapper.appendChild(gui.domElement); +const rendererFolder = gui.addFolder('renderer'); +const rendererConfig = { + renderer: 'canvas', +}; +rendererFolder + .add(rendererConfig, 'renderer', [ + 'canvas', + 'svg', + 'webgl', + 'webgpu', + 'canvaskit', + ]) + .onChange((rendererName) => { + let renderer; + if (rendererName === 'canvas') { + renderer = canvasRenderer; + } else if (rendererName === 'svg') { + renderer = svgRenderer; + } else if (rendererName === 'webgl') { + renderer = webglRenderer; + } else if (rendererName === 'webgpu') { + renderer = webgpuRenderer; + } else if (rendererName === 'canvaskit') { + renderer = canvaskitRenderer; + } + canvas.setRenderer(renderer); + }); +rendererFolder.open(); diff --git a/site/package.json b/site/package.json index 777cbd711..10e573534 100644 --- a/site/package.json +++ b/site/package.json @@ -25,9 +25,10 @@ }, "dependencies": { "@antv/g-components": "^1.9.1", + "@antv/g-lite": "^1.2.12", "@antv/g-mobile-webgl": "^0.9.1", "@antv/g-plugin-a11y": "^0.6.7", - "@antv/g-plugin-image-loader": "^1.3.7", + "@antv/g-plugin-image-loader": "^1.3.12", "@antv/g6": "^4.5.2", "@antv/react-g": "^1.8.79", "@antv/util": "^3.3.4",