From 78028893e25d7572bcff46563bdddd907026ecbf Mon Sep 17 00:00:00 2001 From: jahow Date: Sat, 1 Dec 2018 00:01:52 +0100 Subject: [PATCH 1/3] Added missing attributes in PointsLayer Attributes were used in the shader but not bound to a buffer, which made the rendering failed in some implementations. --- src/ol/layer/Heatmap.js | 6 +++++- src/ol/renderer/webgl/PointsLayer.js | 24 +++++++++++++++--------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/ol/layer/Heatmap.js b/src/ol/layer/Heatmap.js index 3e179ea03b..15dfa21ecd 100644 --- a/src/ol/layer/Heatmap.js +++ b/src/ol/layer/Heatmap.js @@ -205,6 +205,7 @@ class Heatmap extends VectorLayer { attribute vec2 a_texCoord; attribute float a_rotateWithView; attribute vec2 a_offsets; + attribute float a_opacity; uniform mat4 u_projectionMatrix; uniform mat4 u_offsetScaleMatrix; @@ -212,6 +213,7 @@ class Heatmap extends VectorLayer { uniform float u_size; varying vec2 v_texCoord; + varying float v_opacity; void main(void) { mat4 offsetMatrix = u_offsetScaleMatrix; @@ -221,6 +223,7 @@ class Heatmap extends VectorLayer { vec4 offsets = offsetMatrix * vec4(a_offsets, 0.0, 0.0); gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets * u_size; v_texCoord = a_texCoord; + v_opacity = a_opacity; }`, fragmentShader: ` precision mediump float; @@ -229,12 +232,13 @@ class Heatmap extends VectorLayer { uniform float u_blur; varying vec2 v_texCoord; + varying float v_opacity; void main(void) { gl_FragColor.rgb = vec3(1.0, 1.0, 1.0); vec2 texCoord = v_texCoord * 2.0 - vec2(1.0, 1.0); float sqRadius = texCoord.x * texCoord.x + texCoord.y * texCoord.y; - float alpha = 1.0 - sqRadius * sqRadius; + float alpha = 1.0 - sqRadius * sqRadius * v_opacity; if (alpha <= 0.0) { discard; } diff --git a/src/ol/renderer/webgl/PointsLayer.js b/src/ol/renderer/webgl/PointsLayer.js index 4469307ba9..70c716d6cd 100644 --- a/src/ol/renderer/webgl/PointsLayer.js +++ b/src/ol/renderer/webgl/PointsLayer.js @@ -13,12 +13,14 @@ const VERTEX_SHADER = ` attribute vec2 a_texCoord; attribute float a_rotateWithView; attribute vec2 a_offsets; + attribute float a_opacity; uniform mat4 u_projectionMatrix; uniform mat4 u_offsetScaleMatrix; uniform mat4 u_offsetRotateMatrix; varying vec2 v_texCoord; + varying float v_opacity; void main(void) { mat4 offsetMatrix = u_offsetScaleMatrix; @@ -28,6 +30,7 @@ const VERTEX_SHADER = ` vec4 offsets = offsetMatrix * vec4(a_offsets, 0.0, 0.0); gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets; v_texCoord = a_texCoord; + v_opacity = a_opacity; }`; const FRAGMENT_SHADER = ` @@ -35,10 +38,11 @@ const FRAGMENT_SHADER = ` uniform float u_opacity; varying vec2 v_texCoord; + varying float v_opacity; void main(void) { gl_FragColor.rgb = vec3(1.0, 1.0, 1.0); - float alpha = u_opacity; + float alpha = u_opacity * v_opacity; if (alpha == 0.0) { discard; } @@ -202,14 +206,14 @@ class WebGLPointsLayerRenderer extends LayerRenderer { const x = this.coordCallback_(feature, 0); const y = this.coordCallback_(feature, 1); const size = this.sizeCallback_(feature); - const stride = 6; + const stride = 8; const baseIndex = this.verticesBuffer_.getArray().length / stride; this.verticesBuffer_.getArray().push( - x, y, -size / 2, -size / 2, 0, 0, - x, y, +size / 2, -size / 2, 1, 0, - x, y, +size / 2, +size / 2, 1, 1, - x, y, -size / 2, +size / 2, 0, 1 + x, y, -size / 2, -size / 2, 0, 0, 1, 1, + x, y, +size / 2, -size / 2, 1, 0, 1, 1, + x, y, +size / 2, +size / 2, 1, 1, 1, 1, + x, y, -size / 2, +size / 2, 0, 1, 1, 1 ); this.indicesBuffer_.getArray().push( baseIndex, baseIndex + 1, baseIndex + 3, @@ -223,9 +227,11 @@ class WebGLPointsLayerRenderer extends LayerRenderer { this.helper_.bindBuffer(ELEMENT_ARRAY_BUFFER, this.indicesBuffer_); const bytesPerFloat = Float32Array.BYTES_PER_ELEMENT; - this.helper_.enableAttributeArray(DefaultAttrib.POSITION, 2, FLOAT, bytesPerFloat * 6, 0); - this.helper_.enableAttributeArray(DefaultAttrib.OFFSETS, 2, FLOAT, bytesPerFloat * 6, bytesPerFloat * 2); - this.helper_.enableAttributeArray(DefaultAttrib.TEX_COORD, 2, FLOAT, bytesPerFloat * 6, bytesPerFloat * 4); + this.helper_.enableAttributeArray(DefaultAttrib.POSITION, 2, FLOAT, bytesPerFloat * 8, 0); + this.helper_.enableAttributeArray(DefaultAttrib.OFFSETS, 2, FLOAT, bytesPerFloat * 8, bytesPerFloat * 2); + this.helper_.enableAttributeArray(DefaultAttrib.TEX_COORD, 2, FLOAT, bytesPerFloat * 8, bytesPerFloat * 4); + this.helper_.enableAttributeArray(DefaultAttrib.OPACITY, 1, FLOAT, bytesPerFloat * 8, bytesPerFloat * 6); + this.helper_.enableAttributeArray(DefaultAttrib.ROTATE_WITH_VIEW, 1, FLOAT, bytesPerFloat * 8, bytesPerFloat * 7); return true; } From 55c36b5aabae62c3191b3f16898051c158347d43 Mon Sep 17 00:00:00 2001 From: jahow Date: Sat, 1 Dec 2018 00:03:05 +0100 Subject: [PATCH 2/3] Shader compilation errors are now logged even when the compilation succeeded --- src/ol/webgl/Helper.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ol/webgl/Helper.js b/src/ol/webgl/Helper.js index 05acb07e57..b0c8039e87 100644 --- a/src/ol/webgl/Helper.js +++ b/src/ol/webgl/Helper.js @@ -619,11 +619,11 @@ class WebGLHelper extends Disposable { const vertexShader = this.compileShader(vertexShaderSource, gl.VERTEX_SHADER); this.shaderCompileErrors_ = null; - if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { + if (gl.getShaderInfoLog(fragmentShader)) { this.shaderCompileErrors_ = `Fragment shader compilation failed:\n${gl.getShaderInfoLog(fragmentShader)}`; } - if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) { + if (gl.getShaderInfoLog(vertexShader)) { this.shaderCompileErrors_ = (this.shaderCompileErrors_ || '') + `Vertex shader compilation failed:\n${gl.getShaderInfoLog(vertexShader)}`; } From 8bb7d77f68913f673eb43d4ec696a0070f7d70a1 Mon Sep 17 00:00:00 2001 From: jahow Date: Sat, 1 Dec 2018 00:11:27 +0100 Subject: [PATCH 3/3] Update PointsLayer documentation --- src/ol/renderer/webgl/PointsLayer.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ol/renderer/webgl/PointsLayer.js b/src/ol/renderer/webgl/PointsLayer.js index 70c716d6cd..a64f36f74b 100644 --- a/src/ol/renderer/webgl/PointsLayer.js +++ b/src/ol/renderer/webgl/PointsLayer.js @@ -77,7 +77,12 @@ const FRAGMENT_SHADER = ` * All features will be rendered as quads (two triangles forming a square). New data will be flushed to the GPU * every time the vector source changes. * - * Use shaders to customize the final output. + * Use shaders to customize the final output. The following attributes are available: + * * `vec2 a_position` + * * `vec2 a_texCoord` + * * `vec2 a_offsets` + * * `float a_rotateWithView` + * * `float a_opacity` * * This uses {@link module:ol/webgl/Helper~WebGLHelper} internally. * @@ -90,12 +95,14 @@ const FRAGMENT_SHADER = ` * attribute vec2 a_texCoord; * attribute float a_rotateWithView; * attribute vec2 a_offsets; + * attribute float a_opacity; * * uniform mat4 u_projectionMatrix; * uniform mat4 u_offsetScaleMatrix; * uniform mat4 u_offsetRotateMatrix; * * varying vec2 v_texCoord; + * varying float v_opacity; * * void main(void) { * mat4 offsetMatrix = u_offsetScaleMatrix; @@ -105,6 +112,7 @@ const FRAGMENT_SHADER = ` * vec4 offsets = offsetMatrix * vec4(a_offsets, 0.0, 0.0); * gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets; * v_texCoord = a_texCoord; + * v_opacity = a_opacity; * } * ``` * @@ -114,10 +122,11 @@ const FRAGMENT_SHADER = ` * uniform float u_opacity; * * varying vec2 v_texCoord; + * varying float v_opacity; * * void main(void) { * gl_FragColor.rgb = vec3(1.0, 1.0, 1.0); - * float alpha = u_opacity; + * float alpha = u_opacity * v_opacity; * if (alpha == 0.0) { * discard; * }