• geoscene/views

externalRenderers

AMD: require(["geoscene/views/3d/externalRenderers"], (externalRenderers) => { /* code goes here */ });
ESM: import * as externalRenderers from "@geoscene/core/views/3d/externalRenderers";
类: geoscene/views/3d/externalRenderers
起始版本:GeoScene Maps SDK for JavaScript 4.0

SceneView 使用 WebGL 在屏幕上呈现地图/场景。GeoScene Maps SDK for JavaScript 提供了访问 SceneView 的 WebGL 上下文的低级接口,因此可以创建与场景交互的自定义可视化,其方式与内置图层相同。开发者既可以直接编写 WebGL 代码,也可以与第三方 WebGL 库集成。

重要提示

这个接口是实验性的。在产品中使用之前,请仔细阅读以下信息:

  • 无法从 SceneView 内部实现细节中屏蔽此接口的用户。因此,此接口应被视为不稳定的,并且会在即将发布的 GeoScene Maps SDK for JavaScript 次要版本中发生变化。
  • 由于 WebGL 和硬件加速 3D 渲染的复杂性,此接口只能由具有 WebGL 或 OpenGL 经验的专家开发人员使用。
    • WebGL 使用不当不仅会破坏自定义渲染,还会破坏 SceneView 本身的渲染。
    • GeoScene 不会为自定义渲染代码中与 WebGL 渲染相关的问题提供任何支持,也不为使用自定义渲染代码时在 SceneView 渲染中出现的问题提供任何支持。
  • 只有在特定条件下才能与第三方库集成。具体来说,第三方库必须能够在与 SceneView 相同的 WebGL 上下文中工作,并且能够在每一帧中设置 WebGL 状态的相关部分。
  • 我们不鼓励同时使用多个自定义渲染器,尤其是当由多方开发时。

用法

外部渲染器必须注册到 SceneView 实例:

require(["geoscene/Map",
         "geoscene/views/SceneView",
         "geoscene/views/3d/externalRenderers"],
  function(Map, SceneView, externalRenderers) {
    let view = new SceneView({
      map: new Map({
        basemap: "tianditu-vector",
        ground: "world-elevation"
      }),
      container: "viewDiv"
    });

    externalRenderers.add(view, myExternalRenderer);
  }
);

externalRenderers.add() 的第二个参数是一个对象,它必须至少包含两个方法 setuprender

let myExternalRenderer = {
  setup: function(context) {
    // Executed once after the external renderer is added to a view. You can use this function to allocate all static
    // WebGL resources (shaders, buffers, etc.)
  },
  render: function(context) {
    // Executed in every frame to draw geometry to the canvas. Tasks done in this function:
    // * Update the state of dynamic resources
    // * Set the WebGL state as needed for rendering
    // * Issue WebGL draw calls
  }
}

传递给外部渲染器对象的所有方法的 context 变量包含对 WebGL
上下文的引用,以及渲染所需的其他信息:RenderContext。您可以直接在 WebGL 上下文中执行 WebGL 命令:

let myExternalRenderer = {
  vbo: null,
  setup: function(context) {
    this.vbo = context.gl.createBuffer();
    context.gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo);
    let positions = new Float32Array([0, 0, 0,   1, 0, 0,   0, 1, 0]);
    context.gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW)
  },
  render: function(context) {
    // bind a shader program etc.
    context.gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo);
    context.gl.drawArrays(gl.TRIANGLES, 0, 3);
  }
}

请求重绘

SceneView 仅在视图发生更改时渲染帧,例如当相机移动或有新数据可供显示时。帧总是从头开始重新绘制,这意味着在绘制的每一帧中都会调用外部渲染器。

如果外部渲染器需要重新绘制视图,例如因为数据已更改,它必须调用 externalRenderers.requestRender(view)。这将触发要渲染的单个帧。对于连续渲染,例如在动画期间,必须在 render 内的每一帧中调用 externalRenderers.requestRender(view)

let myExternalRenderer = {
  render: function(context) {
    // update WebGL resources and execute draw calls
    externalRenderers.requestRender(view);
  }
}

管理 WebGL 状态

GeoScene Maps SDK for JavaScript 在调用 setuprender 时保证所有 WebGL 状态变量都根据 WebGL 规范设置为各自的默认值。唯一例外是 gl.FRAMEBUFFER_BINDING,其设置为内部使用的帧缓冲区。有关更多详细信息,请参阅绑定正确渲染目标部分。作为回报,接口用户需要在将控制权返回给 API 之前将 WebGL 上下文恢复到相同的状态。否则,可能会导致未定义的行为。为方便起见,在传递给 setuprendercontext 参数上提供了一个 resetWebGLState() 函数。可调用此函数来完全重置所有 WebGL 状态。由于此函数保守地设置了所有 WebGL 状态,它可能会产生性能开销;因此,建议用户跟踪被修改的特定 WebGL 状态,并手动重置该部分状态。

绑定正确渲染目标

在内部,SceneView 渲染到一个中间渲染目标,而不是 WebGL 上下文提供的默认帧缓冲区。在调用 setuprender 时,此渲染目标已绑定,并且将对正确的缓冲区进行绘图调用。但是,如果您通过调用 gl.bindFramebuffer() 来绑定另一个帧缓冲区,请注意随后对 gl.bindFramebuffer(null) 的调用将不会绑定 GeoScene Maps SDK for JavaScript 预期的正确渲染目标。因此,之后发出的 WebGL 绘制调用不会显示在屏幕上。相反,函数 bindRenderTarget() 在传递给 setuprenderRenderContext 参数上提供,它将绑定正确的颜色和深度缓冲区。

坐标系

在使用外部渲染器接口时,尤其是在 WebGL 的上下文中,必须在 SceneView 的内部渲染坐标系中指定坐标。此坐标系取决于视图的 viewingMode

  • local 查看模式下,它等于视图的空间参考所定义的坐标系。
  • global 查看模式下,它是 ECEF 坐标系,其中 X 轴指向 0°N 0°E,Y 轴指向 0°N 90°E,Z 轴指向北极。虚拟地球被绘制为一个半径为 6378137 的完美球体,所以坐标系的单位应该是米。

externalRenderers-global-coordinate-system

您可使用 toRenderCoordinates()fromRenderCoordinates() 在渲染坐标系之间进行转换,而不必担心 viewingMode 和确切的坐标系定义。

精度问题

在全球场景中,32 位浮点算法的精度对于超越全球尺度 (即国家尺度到城市尺度) 的可视化来说是不够的。当将视图缩放到超过一定比例时,几何会出现摆动或抖动,并且通常会出现移位。这同样适用于几何远离坐标系原点的局部场景。

通常,您应确保在 JavaScript 中执行所有算术都是以双精度完成的。这是一般 JavaScript 算术的情况,但您应特别避免使用 Float32Array,除非您可以排除精度问题。

但是,WebGL 不支持 64 位浮点运算。解决此限制的一种简单方法是渲染具有局部原点的场景:

  • 选择一个局部原点位置,大约在数据的中心。
  • 在将其传递到 WebGL 之前,从所有位置数据 (顶点数据、uniforms 等) 中删减掉局部原点位置。
  • 根据原点转换视图变换矩阵 (将视图变换矩阵预乘以原点平移矩阵)

这种技术将导致数据在局部坐标系中呈现,从而避免使用较大的数字,否则需要将数据放置在正确位置。如果数据覆盖范围较大且细节丰富,则需要多个局部原点。请注意,局部原点必须以 32 位浮点数精确表示,最好通过将局部原点本身存储为 Float32Array 来实现。

方法概述

名称 返回值类值 描述 对象

将外部渲染器添加到视图。

更多详情
externalRenderers

请求 SceneView 使用特定的 WebGL 版本进行渲染。

更多详情
externalRenderers
Number[]|Float32Array

将位置从内部渲染坐标系转换为输出空间参考。

更多详情
externalRenderers
RenderCamera

获取视图的当前相机的渲染表示。

更多详情
externalRenderers

从视图中移除一个外部渲染器。

更多详情
externalRenderers
Number[]|Float32Array

计算一个 4x4 仿射变换矩阵,该矩阵构成从局部笛卡尔坐标系到虚拟世界坐标系的线性坐标变换。

更多详情
externalRenderers

请求重绘的视图。

更多详情
externalRenderers
Number[]|Float32Array

将位置从给定的空间参考转换到内部渲染坐标系。

更多详情
externalRenderers

方法详细说明

add(view, renderer)static

将外部渲染器添加到视图。外部渲染器是由包含一些方法和属性的对象定义的,如 ExternalRenderer 所定义的那样。

参数

附加外部渲染器的视图。

外部渲染器。

forceWebGLContext(version)static

请求 SceneView 使用特定的 WebGL 版本进行渲染。在创建视图之前调用此函数。默认情况下,SceneView 在支持它的平台上使用 WebGL 2。我们建议在未来的实现中使用 WebGL 2。

参数
version Number

所需的上下文版本。

fromRenderCoordinates(view, srcCoordinates, srcStart, destCoordinates, destStart, destSpatialReference, count){Number[]|Float32Array}static

将位置从内部渲染坐标系转换为输出空间参考。允许的输出空间参考是有限的,取决于 viewingMode

  • global 模式下,它可以是 Web Mercator 或 WGS84。
  • local 模式下,它必须匹配 view.spatialReference;对该函数的调用只是将坐标从 srcCoordinates 复制到 destCoordinates

如果不满足这些条件,则不会向 destCoordinates 写入任何内容,并且该函数返回 null

参数

与输入坐标相关的视图。

srcCoordinates Number[]|Float32Array

一个或多个矢量的线性数组,被解释为 XYZ 坐标。例如,两个位置矢量将表示为 [x1, y1, z1, x2, y2, z2]。这必须至少包含 srcStart + 3 * count 个元素。

srcStart Number

srcCoordinates 中的索引,坐标将从其开始进行读取。

destCoordinates Number[]|Float32Array

对数组的引用,将在其中写入结果。

destStart Number

destCoordinates 中的索引,坐标将从其开始进行写入。

destSpatialReference SpatialReference

输出坐标的空间参考。当为 null 时,改为使用 view.spatialReference

count Number

要转换的顶点的数量。

返回
类型 描述
Number[] | Float32Array 如果操作成功,则返回对 destCoordinates 的引用,否则返回 null
示例
let cameraPositionGeographic = new Array(3);
externalRenderers.fromRenderCoordinates(view,
  context.camera.eye, 0,
  cameraPositionGeographic, 0, SpatialReference.WGS84,
1);
getRenderCamera(view){RenderCamera}static

获取视图的当前相机的渲染表示。这与在渲染上下文中为外部渲染器传递的相机相同。

参数

从中获取渲染相机的视图。

返回
类型 描述
RenderCamera 返回一个渲染相机实例。
remove(view, renderer)static

从视图中移除一个外部渲染器。

参数

要从中移除外部渲染器的视图。

外部渲染器。

renderCoordinateTransformAt(view, origin, srcSpatialReference, dest){Number[]|Float32Array}static

计算一个 4x4 仿射变换矩阵,该矩阵构成从局部笛卡尔坐标系到虚拟世界坐标系的线性坐标变换。例如,此矩阵可用于将 3D 模型的顶点转换为渲染坐标系。

局部笛卡尔系统由其原点和以下轴定义进行定义:

  • X:东
  • Y:北
  • Z:Elevation

externalRenderers-renderCoordinateTransformAt

view.viewingModeglobal 时,线性变换不考虑地球曲率或其他非线性投影方面。因此,生成的坐标只会在围绕局部笛卡尔坐标系原点的一个小区域内正确显示。

origin 允许的空间参考,取决于 viewingMode

  • global 模式下,它可以是 Web Mercator 或 WGS84。
  • local 模式下,它必须匹配 view.spatialReference

如果不满足这些条件,则不会向 dest 写入任何内容,并且该函数将返回 null

参数

将使用转换的视图。

局部笛卡尔坐标系中原点的全局坐标。

srcSpatialReference SpatialReference
optional

原点坐标的空间参考。如果未定义,则改为使用 view.spatialReference

optional

对存储 16 个矩阵元素的数组的引用。生成的矩阵遵循 OpenGL 约定,其中平移分量占据第 13、14 和 15 个元素。如果未定义,则返回一个新创建的矩阵。

返回
类型 描述
Number[] | Float32Array 如果操作成功,则返回对 dest 的引用,否则返回 null
示例
// places a tetrahedron in New York
let verticesLocal = [[10, 10, 10], [10, −10, −10], [−10, 10, −10], [−10, −10, 10]],
  transformation = new Array(16),
  geographicCoordinates = [
  //  lon     lat   elevation
      -74,   40.71,    10]

externalRenderers.renderCoordinateTransformAt(view, geographicCoordinates, SpatialReference.WGS84, transformation);

let verticesGlobal = verticesLocal.map(function(vertexLocal) {
  // transform the coordinates with the computed transformation (using the synthax of glMatrix, see http://glmatrix.net)
  return vec3.transformMat4(new Array(3), vertexLocal, transformation);
});
requestRender(view)static

请求重绘的视图。

参数

外部渲染器附加到的视图。

toRenderCoordinates(view, srcCoordinates, srcStart, srcSpatialReference, destCoordinates, destStart, count){Number[]|Float32Array}static

将位置从给定的空间参考转换到内部渲染坐标系。允许的输入空间参考是有限的,取决于 viewingMode

  • global 模式下,它可以是 Web Mercator 或 WGS84。
  • local 模式下,它必须匹配 view.spatialReference;对该函数的调用只是将坐标从 srcCoordinates 复制到 destCoordinates

如果不满足这些条件,则不会向 destCoordinates 写入任何内容,并且该函数返回 null

参数

将在其中使用坐标的视图。

srcCoordinates Number[]|Float32Array

一个或多个矢量的线性数组,被解释为 XYZ 坐标。例如,两个位置矢量将表示为 [x1, y1, z1, x2, y2, z2]。这必须至少包含 srcStart + 3 * count 个元素。

srcStart Number

srcCoordinates 中的索引,坐标将从其开始进行读取。

srcSpatialReference SpatialReference

输入坐标的空间参考。当为 null 时,改为使用 view.spatialReference

destCoordinates Number[]|Float32Array

对数组的引用,将在其中写入结果。

destStart Number

destCoordinates 中的索引,坐标将从其开始进行写入。

count Number

要转换的顶点的数量。

返回
类型 描述
Number[] | Float32Array 如果操作成功,则返回对 destCoordinates 的引用,否则返回 null
示例
// A linear list of coordinate triples
let geographicCoordinates = [
  //  lon     lat   elevation
    -117.19, 34.05,   414,
     47.39,   8.51,   408];

// Allocate storage for the result
let renderCoordinates = new Array(6);

externalRenderers.toRenderCoordinates(view,
  geographicCoordinates, 0, SpatialReference.WGS84,
  renderCoordinates, 0,
2);

类型定义

ColorAndIntensity Object

RGB 颜色值和强度值的元组。

属性
color Vec3

值介于 0 和 1 之间的 RGB 颜色。

intensity Number

标量强度值,应根据该值缩放颜色以进行合成。

ExternalRenderer Object

使用回调和属性定义外部渲染器。

属性
optional

通常在将外部渲染器添加到视图后或 SceneView 准备就绪时调用一次。如果就绪状态循环,则可能会再次调用它,例如当将不同的 Map 分配给视图时。接收 RenderContext 类型的单个参数。

optional

在每一帧中调用以执行状态更新和绘制调用。接收 RenderContext 类型的单个参数。

optional

当从视图中移除外部渲染器时调用,或当视图的就绪状态变为 false 时调用。接收 RenderContext 类型的单个参数。

RenderCamera Object

RenderContext 中传递给渲染器回调的相机对象。这与 Camera 不同。所有属性都是只读的,并根据内部渲染坐标系定义 (请参阅本页顶部的坐标系部分)。

向量 (Vec3 and Vec4) 以数组的形式呈现。矩阵 (Mat4) 呈现为具有 16 个元素的线性数组,遵循 OpenGL 约定,其中平移分量占据第 13、14 和 15 个元素。

属性
viewMatrix Mat4

将坐标从世界空间转换到相机空间的 4x4 矩阵。

viewInverseTransposeMatrix Mat4

viewMatrix 的逆转置,用于将法线从世界空间转换到相机空间。

projectionMatrix Mat4

4x4 的矩阵,用于定义透视投影变换。

eye Vec3

内部笛卡尔渲染坐标系中的摄像机位置。

center Vec3

内部笛卡尔渲染坐标系中的摄像机目标 (“看”) 位置。

up Vec3

摄像机向上矢量。

near Number

到近裁剪面的距离。

far Number

到远裁剪面的距离。

fovX Number

视图的水平字段。

fovY Number

视图的垂直字段。

pixelRatio Number

渲染像素比率。这可用于调整屏幕尺寸,以便在以 HiDPI 呈现时正确匹配 CSS 像素尺寸。

viewport Vec4

视区 (x、y、宽度、高度)。

RenderContext Object

该对象作为参数传递给每次调用以 setuprender 外部渲染器。

属性

WebGL 渲染上下文。

用于渲染当前帧的相机。

sunLight SunLight

SceneView 用于渲染当前帧的光照。

resetWebGLState Function

提供了一个方便的函数,用于在使用后完全重置 WebGL 状态。

bindRenderTarget Function

绑定外部渲染器应该渲染到的颜色和深度缓冲区。

RenderContextCallback(context)

使用渲染上下文调用的回调(用于外部渲染器的设置和渲染阶段)。

参数
optional

渲染上下文。

SunLight Object

描述 SceneView 使用的光照,派生自其太阳光照模型。它由一个定向 Lambertian (diffuse) 和一个常数 (ambient) 项组成,应在 Phong 反射模型的意义上进行处理。

属性
direction Vec3

渲染坐标中的入射光方向。

漫射光的颜色和强度。

环境光的颜色和强度。

您的浏览器不再受支持。请升级您的浏览器以获得最佳体验。请参阅浏览器弃用帖子以获取更多信息