/** * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ export default ` precision highp float; precision highp int; #include common #include read_from_texture #include common_vert_params #include color_vert_params #include size_vert_params uniform mat4 uModelView; uniform mat4 uInvProjection; attribute vec3 aPosition; attribute vec2 aMapping; attribute mat4 aTransform; attribute float aInstance; attribute float aGroup; varying float vRadius; varying float vRadiusSq; varying vec3 vPoint; varying vec3 vPointViewPosition; #include matrix_scale const mat4 D = mat4( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0 ); /** * Compute point size and center using the technique described in: * "GPU-Based Ray-Casting of Quadratic Surfaces" http://dl.acm.org/citation.cfm?id=2386396 * by Christian Sigg, Tim Weyrich, Mario Botsch, Markus Gross. */ void quadraticProjection(const in float radius, const in vec3 position){ vec2 xbc, ybc; mat4 T = mat4( radius, 0.0, 0.0, 0.0, 0.0, radius, 0.0, 0.0, 0.0, 0.0, radius, 0.0, position.x, position.y, position.z, 1.0 ); mat4 R = transpose4(uProjection * uModelView * aTransform * T); float A = dot(R[3], D * R[3]); float B = -2.0 * dot(R[0], D * R[3]); float C = dot(R[0], D * R[0]); xbc[0] = (-B - sqrt(B * B - 4.0 * A * C)) / (2.0 * A); xbc[1] = (-B + sqrt(B * B - 4.0 * A * C)) / (2.0 * A); float sx = abs(xbc[0] - xbc[1]) * 0.5; A = dot(R[3], D * R[3]); B = -2.0 * dot(R[1], D * R[3]); C = dot(R[1], D * R[1]); ybc[0] = (-B - sqrt(B * B - 4.0 * A * C)) / (2.0 * A); ybc[1] = (-B + sqrt(B * B - 4.0 * A * C)) / (2.0 * A); float sy = abs(ybc[0] - ybc[1]) * 0.5; gl_Position.xy = vec2(0.5 * (xbc.x + xbc.y), 0.5 * (ybc.x + ybc.y)); gl_Position.xy -= aMapping * vec2(sx, sy); gl_Position.xy *= gl_Position.w; } void main(void){ #include assign_group #include assign_color_varying #include assign_marker_varying #include assign_size vRadius = size * matrixScale(uModelView); vec4 mvPosition = uModelView * aTransform * vec4(aPosition, 1.0); mvPosition.z -= vRadius; // avoid clipping, added again in fragment shader gl_Position = uProjection * vec4(mvPosition.xyz, 1.0); quadraticProjection(size, aPosition); vRadiusSq = vRadius * vRadius; vec4 vPoint4 = uInvProjection * gl_Position; vPoint = vPoint4.xyz / vPoint4.w; vPointViewPosition = -mvPosition.xyz / mvPosition.w; } `