ArcGIS JSAPI 高级教程 - ArcGIS Maps SDK for JavaScript - 添加自定义(GLSL)数据
ArcGIS Maps SDK for JavaScript 从 4.29
开始增加 RenderNode
类,可以添加数据以及操作 FBO(ManagedFBO)
;
通过操作 FBO,可以通过后处理实现很多效果,官方提供了几个示例,感兴趣可以看看。
本文介绍一下通过 FBO,添加自定义数据。
本文包括核心代码、完整代码以及在线示例。
核心代码
原理就是将坐标数据转为 WebGL 内部数据,即世界坐标;
在通过相机对象属性,传入投影矩阵与视图矩阵;
通过相机矩阵转换世界坐标,显示在地图上。
// 初始化shader
var VSHADER = `#version 300 es
layout (location=0) in vec3 a_Position;
layout (location=1) in vec4 a_color;
out vec4 v_color;
uniform mat4 u_projectionMatrix;
uniform mat4 u_viewMatrix;
void main(){
gl_Position = u_projectionMatrix*u_viewMatrix*vec4(a_Position,1.0);
// 传递颜色
v_color = a_color;
}
`;
var FSHADER = `#version 300 es
precision mediump float;
in vec4 v_color;
out vec4 fragColor;
void main(){
fragColor = vec4(v_color.rgb*2.0,0.5);
}
`;
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"/>
<title>自定义三角形 | Sample | ArcGIS Maps SDK for JavaScript 4.29</title>
<link rel="stylesheet" href="./4.29/esri/themes/light/main.css"/>
<script src="./4.29/init.js"></script>
<script src="./renderCommon.js"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<script>
require([
"esri/core/Accessor",
"esri/Map",
"esri/views/SceneView",
"esri/views/3d/externalRenderers",
"esri/geometry/Extent",
"esri/rest/query",
"esri/rest/support/Query",
"esri/widgets/Home",
"esri/core/promiseUtils",
"esri/views/3d/webgl/RenderNode",
"esri/views/3d/webgl",
"esri/geometry/SpatialReference",
], (Accessor, Map, SceneView, externalRenderers,
Extent, query, Query, Home,
promiseUtils,
RenderNode, webgl, SpatialReference,
) => {
const {map, view} = initMap({Map, SceneView, Home});
// 创建三角形数据
// 经纬度
let projectionCoordinates = [
// lon lat elevation
115.12, 32, 0,
120, 31, 0,
124, 33, 0
];
// 创建三角形颜色
let colors = new Float32Array(
[
1.0, 1.0, 0.0,
1.0, 1.0, 0.0,
1.0, 1.0, 0.0
]
)
// Derive a new subclass from RenderNode called LuminanceRenderNode
const TriAngleRenderNode = RenderNode.createSubclass({
constructor: function () {
// consumes and produces define the location of the the render node in the render pipeline
this.consumes = {required: ["composite-color"]};
this.produces = "composite-color";
},
// Ensure resources are cleaned up when render node is removed
destroy() {
this.shaderProgram && this.gl?.deleteProgram(this.shaderProgram);
this.vbo && this.gl?.deleteBuffer(this.vbo);
this.colorBuffer && this.gl?.deleteBuffer(this.colorBuffer);
},
properties: {},
initialize: function () {
let gl = this.gl;
// 初始化shader
var VSHADER = `#version 300 es
layout (location=0) in vec3 a_Position;
layout (location=1) in vec4 a_color;
out vec4 v_color;
uniform mat4 u_projectionMatrix;
uniform mat4 u_viewMatrix;
void main(){
gl_Position = u_projectionMatrix*u_viewMatrix*vec4(a_Position,1.0);
// 传递颜色
v_color = a_color;
}
`;
var FSHADER = `#version 300 es
precision mediump float;
in vec4 v_color;
out vec4 fragColor;
void main(){
fragColor = vec4(v_color.rgb*2.0,0.5);
}
`;
// 初始化 shader 程序
this.shaderProgram = initWebgl2Shaders(gl, VSHADER, FSHADER);
if (!this.shaderProgram) {
console.assert("初始化shader错误")
}
// 获取顶点位置
this.a_Position = gl.getAttribLocation(this.shaderProgram, 'a_Position')
// 获取顶点颜色
this.a_color = gl.getAttribLocation(this.shaderProgram, 'a_color')
// 初始化顶点的 bufferdata
this.vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo);
// 转换坐标为渲染坐标
let renderCoordinates = webgl.toRenderCoordinates(
view,
// 经纬度坐标
projectionCoordinates,
// 开始索引
0,
// 坐标系
SpatialReference.WGS84,
// 顶点容器
new Float32Array(9),
// 目标开始索引
0,
// 顶点数量
3
);
gl.bufferData(gl.ARRAY_BUFFER, renderCoordinates, gl.STATIC_DRAW);
// 给顶点的各个点赋予颜色
this.colorBuffer = gl.createBuffer() //创建缓冲区对象
gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer) //将缓冲区对象绑定到目标
gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW) //向缓冲区对象写入数据
},
// 渲染
render: function (inputs) {
// The field input contains all available framebuffer objects
// We need color texture from the composite render target
this.resetWebGLState();
// 获取输出 FBO
const output = this.bindRenderTarget();
let gl = this.gl;
// 开启透明
activeOpacity(gl);
gl.useProgram(this.shaderProgram); // 使用 shader 程序
gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo);
gl.vertexAttribPointer(this.a_Position, 3, gl.FLOAT, false, 0, 0) //将缓冲区对象分配给a_Posiotion
gl.enableVertexAttribArray(this.a_Position); // 启用 a_Position
gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer) //将缓冲区对象绑定到目标
gl.vertexAttribPointer(this.a_color, 3, gl.FLOAT, false, 0, 0) //将缓冲区对象分配给a_color
gl.enableVertexAttribArray(this.a_color);
// 开启相机投影
activeMatrix(this)
gl.drawArrays(gl.TRIANGLES, 0, 3); // 绘制图形
return output;
},
a_Position: undefined, // 顶点位置
a_color: undefined, // 顶点颜色
vbo: undefined, // 顶点缓冲区对象
colorBuffer: undefined, // 颜色缓冲区对象
shaderProgram: null, // shader 程序
});
promiseUtils
.eachAlways([view.when()])
.then((results) => {
// Initializes the new custom render node and connects to SceneView
const triAngleRenderNode = new TriAngleRenderNode({view});
})
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
在线示例
ArcGIS Maps SDK for JavaScript 在线示例:添加自定义(GLSL)数据
标签:GLSL,自定义,color,shaderProgram,ArcGIS,vec4,Position,gl,esri From: https://blog.csdn.net/linzi19900517/article/details/139636138