赞
踩
为了方便调试渲染效果,可以借助一些工具,这里介绍一下 dat.gui。
官网:
本文包括核心代码、完整代码以及在线示例。
简单介绍一下使用方式:
<script type="text/javascript" src="https://openlayers.vip/examples/resources/dat_gui/dat.gui.js"></script>
<link rel="stylesheet" type="text/css" href="https://openlayers.vip/examples/resources/dat_gui/dat.gui.css"/>
// 创建对象
var gui = new dat.GUI();
// 添加动态属性
// 监听属性值变化,更新帧
gui.add(luminanceRenderNode, 'test_float', 0, 3.0).name("夜视仪亮度").onChange(function (value) {
luminanceRenderNode.requestRender();
});
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"/> <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/> <title>Custom RenderNode - dat_gui 使用示例 | Sample | ArcGIS Maps SDK for JavaScript 4.29</title> <!-- <link rel="stylesheet" href="https://js.arcgis.com/4.29/esri/themes/light/main.css"/>--> <link rel="stylesheet" href="./4.29/esri/themes/light/main.css"/> <script type="text/javascript" src="./dat_gui/dat.gui.js"></script> <link rel="stylesheet" type="text/css" href="./dat_gui/dat.gui.css"/> <!-- <script src="https://js.arcgis.com/4.29/"></script>--> <script src="./4.29/init.js"></script> <script src="./renderCommon.js"></script> <script type="module" src="https://js.arcgis.com/calcite-components/2.5.1/calcite.esm.js"></script> <link rel="stylesheet" type="text/css" href="https://js.arcgis.com/calcite-components/2.5.1/calcite.css"/> <style> html, body, #viewDiv { padding: 0; margin: 0; height: 100%; width: 100%; } </style> </head> <body> <script> require(["esri/Map", "esri/views/SceneView", "esri/views/3d/webgl/RenderNode", "esri/Graphic", "esri/views/3d/webgl", "esri/geometry/SpatialReference", "esri/widgets/Home", ], function ( Map, SceneView, RenderNode, Graphic, webgl, SpatialReference, Home, ) { const {map, view} = initMap({Map, SceneView, Home}); view.when(() => { // Derive a new subclass from RenderNode called LuminanceRenderNode const LuminanceRenderNode = 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"; // 定义属性 this.test_float = 1.0; }, // Ensure resources are cleaned up when render node is removed destroy() { this.shaderProgram && this.gl?.deleteProgram(this.shaderProgram); this.positionBuffer && this.gl?.deleteBuffer(this.positionBuffer); this.vao && this.gl?.deleteVertexArray(this.vao); }, properties: { // Define getter and setter for class member enabled enabled: { get: function () { return this.produces != null; }, set: function (value) { // Setting produces to null disables the render node this.produces = value ? "composite-color" : null; this.requestRender(); } } }, render(inputs) { // The field input contains all available framebuffer objects // We need color texture from the composite render target const input = inputs.find(({name}) => name === "composite-color"); const color = input.getTexture(); // this.resetWebGLState(); // const output = this.bindRenderTarget(); // Acquire the composite framebuffer object, and bind framebuffer as current target const output = this.acquireOutputFramebuffer(); const gl = this.gl; // Clear newly acquired framebuffer gl.clearColor(0, 0, 0, 0); gl.colorMask(true, true, true, true); gl.clear(gl.COLOR_BUFFER_BIT); // gl.disable(gl.CULL_FACE); // 禁用面剔除 // Prepare custom shaders and geometry for screenspace rendering this.ensureShader(gl); this.ensureScreenSpacePass(gl); // Bind custom program gl.useProgram(this.shaderProgram); // Use composite-color render target to be modified in the shader gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, color.glName); gl.uniform1i(this.textureUniformLocation, 0); // 传递测试数据 gl.uniform1f(this.textureUniformTestFloat, this.test_float); // Issue the render call for a screen space render pass gl.bindVertexArray(this.vao); gl.drawArrays(gl.TRIANGLES, 0, 3); return output; }, shaderProgram: null, textureUniformLocation: null, positionLocation: null, vao: null, positionBuffer: null, // used to avoid allocating objects in each frame. // Setup screen space filling triangle ensureScreenSpacePass(gl) { if (this.vao) { return; } this.vao = gl.createVertexArray(); gl.bindVertexArray(this.vao); this.positionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer); const vertices = new Float32Array([-1.0, -1.0, 3.0, -1.0, -1.0, 3.0]); gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); gl.vertexAttribPointer(this.positionLocation, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(this.positionLocation); gl.bindVertexArray(null); }, // Setup custom shader programs ensureShader(gl) { if (this.shaderProgram != null) { return; } // The vertex shader program // Sets position from 0..1 for fragment shader // Forwards texture coordinates to fragment shader const vshader = `#version 300 es in vec2 position; out vec2 uv; void main() { gl_Position = vec4(position, 0.0, 1.0); uv = position * 0.5 + vec2(0.5); }`; // The fragment shader program applying a greyscsale conversion const fshader = `#version 300 es precision mediump float; out mediump vec4 fragColor; // 测试属性 uniform float test_float; in vec2 uv; uniform sampler2D colorTex; void main() { vec4 color = texture(colorTex, uv); // 使用测试数据 fragColor = vec4(color.r, color.g * test_float, color.b, 0.9); fragColor.rgb = fragColor.rgb/2.0; } `; this.shaderProgram = initWebgl2Shaders(gl, vshader, fshader); this.textureUniformLocation = gl.getUniformLocation(this.shaderProgram, "colorTex"); // 测试数据位置 this.textureUniformTestFloat = gl.getUniformLocation(this.shaderProgram, "test_float"); this.positionLocation = gl.getAttribLocation(this.shaderProgram, "position"); } }); // Initializes the new custom render node and connects to SceneView const luminanceRenderNode = new LuminanceRenderNode({view}); var gui = new dat.GUI(); // 激活 ui gui.add(luminanceRenderNode, 'test_float', 0, 3.0).name("夜视仪亮度").onChange(function (value) { luminanceRenderNode.requestRender(); }); // Toggle button to enable/disable the custom render node const renderNodeToggle = document.getElementById("renderNodeToggle"); renderNodeToggle.addEventListener("calciteSwitchChange", () => { luminanceRenderNode.enabled = !luminanceRenderNode.enabled; }); }); }); </script> <calcite-block open heading="Toggle Render Node" id="renderNodeUI"> <calcite-label layout="inline"> Color <calcite-switch id="renderNodeToggle" checked></calcite-switch> Grayscale </calcite-label> </calcite-block> <div id="viewDiv"></div> </body> </html>
ArcGIS Maps SDK for JavaScript 在线示例: dat.gui 使用示例
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。