Newer
Older
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
#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;
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;