Files
OpenSpace/modules/base/shaders/pointcloud/pointcloud_gs.glsl
Emma Broman 82ddbc57f8 Include orientation data in new point cloud and remove RenderablePlanesCloud (#3168)
* WIP start including rotation data

* Fix option to use orientation data or not

* Renames to reflect that points are no longer billboarded (at least not always)

* Increase max value for scale factor

* Fix correct scaling for tully and deep sky objects

* Remove the old RenderablePlanesCloud, we don't need it anymore

* Add unit handling for size scaling from data values

* Clarify some documentation about the points being rendered as planes

* Update datasets to the new ones on the server

* Use quaternions for orientation instead of vectors (simplifies interpolation and requires less data)

* Make interpolation of orientation work

* Fix size for deep sky objects being too small due to data being radius rather than diameter

* Add IsRadius flag for deepsky

* Update asset versions (major number update, due to breaking changes)

---------

Co-authored-by: Alexander Bock <alexander.bock@liu.se>
2024-04-18 14:06:55 +02:00

189 lines
6.9 KiB
GLSL

/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2024 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
#include "PowerScaling/powerScalingMath.hglsl"
layout(points) in;
flat in float textureLayer[];
flat in float colorParameter[];
flat in float scalingParameter[];
flat in vec4 orientation[]; // quaternion
layout(triangle_strip, max_vertices = 4) out;
flat out float gs_colorParameter;
out vec2 texCoord;
flat out int layer;
flat out float vs_screenSpaceDepth;
flat out vec4 vs_positionViewSpace;
// General settings
uniform float scaleExponent;
uniform float scaleFactor;
uniform int renderOption;
uniform dmat4 cameraViewMatrix;
uniform dmat4 projectionMatrix;
uniform dmat4 modelMatrix;
uniform bool enableMaxSizeControl;
uniform bool hasDvarScaling;
uniform float dvarScaleFactor;
uniform bool useOrientationData;
// RenderOption: CameraViewDirection
uniform vec3 up;
uniform vec3 right;
// RenderOption: CameraPositionNormal
uniform dvec3 cameraPosition;
uniform vec3 cameraLookUp;
// Max size control: true
// The max size is an angle, in degrees, for the diameter
uniform float maxAngularSize;
uniform vec2 aspectRatioScale;
const vec2 corners[4] = vec2[4](
vec2(0.0, 0.0),
vec2(1.0, 0.0),
vec2(1.0, 1.0),
vec2(0.0, 1.0)
);
const int RenderOptionCameraViewDirection = 0;
const int RenderOptionCameraPositionNormal = 1;
const int RenderOptionFixedRotation = 2;
// Quaternion math code from:
// https://gist.github.com/mattatz/40a91588d5fb38240403f198a938a593
vec4 quatMult(vec4 q1, vec4 q2) {
return vec4(
q2.xyz * q1.w + q1.xyz * q2.w + cross(q1.xyz, q2.xyz),
q1.w * q2.w - dot(q1.xyz, q2.xyz)
);
}
// Vector rotation with a quaternion
// http://mathworld.wolfram.com/Quaternion.html
vec3 rotate_vector(vec3 v, vec4 q) {
vec4 q_conjugate = q * vec4(-1.0, -1.0, -1.0, 1.0);
return quatMult(q, quatMult(vec4(v, 0.0), q_conjugate)).xyz;
}
void main() {
vec4 pos = gl_in[0].gl_Position;
layer = int(textureLayer[0]);
gs_colorParameter = colorParameter[0];
dvec4 dpos = modelMatrix * dvec4(dvec3(pos.xyz), 1.0);
float scaleMultiply = pow(10.0, scaleExponent);
if (hasDvarScaling) {
scaleMultiply *= scalingParameter[0] * dvarScaleFactor;
}
vec3 scaledRight = vec3(1.0, 0.0, 0.0);
vec3 scaledUp = vec3(0.0, 1.0, 0.0);
if (renderOption == RenderOptionCameraViewDirection) {
scaledRight = right;
scaledUp = up;
}
else if (renderOption == RenderOptionCameraPositionNormal) {
vec3 normal = vec3(normalize(cameraPosition - dpos.xyz));
vec3 newRight = normalize(cross(cameraLookUp, normal));
vec3 newUp = cross(normal, newRight);
scaledRight = newRight;
scaledUp = newUp;
}
else if (renderOption == RenderOptionFixedRotation) {
if (useOrientationData) {
vec4 quat = orientation[0];
scaledRight = normalize(rotate_vector(scaledRight, quat));
scaledUp = normalize(rotate_vector(scaledUp, quat));
}
// Else use default
}
scaledRight *= scaleMultiply * 0.5;
scaledUp *= scaleMultiply * 0.5;
if (enableMaxSizeControl) {
// Limit the max size of the points, as the angle in "FOV" that the point is allowed
// to take up. Note that the max size is for the diameter, and we need the radius
float desiredAngleRadians = radians(maxAngularSize * 0.5);
double distanceToCamera = length(dpos.xyz - cameraPosition);
double pointSize = length(dvec3(scaledRight));
// @TODO (2023-01-05, emmbr) Consider if this atan computation can be optimized using
// approximation
float angle = atan(float(pointSize / distanceToCamera));
if ((angle > desiredAngleRadians) && (distanceToCamera > 0.0)) {
float correctionScaleFactor = float(distanceToCamera) * tan(desiredAngleRadians) / float(pointSize);
scaledRight *= correctionScaleFactor;
scaledUp *= correctionScaleFactor;
}
}
dmat4 cameraViewProjectionMatrix = projectionMatrix * cameraViewMatrix;
vec4 dposClip = vec4(cameraViewProjectionMatrix * dpos);
vec4 scaledRightClip = scaleFactor * aspectRatioScale.x *
vec4(cameraViewProjectionMatrix * dvec4(scaledRight, 0.0));
vec4 scaledUpClip = scaleFactor * aspectRatioScale.y *
vec4(cameraViewProjectionMatrix * dvec4(scaledUp, 0.0));
vec4 dposViewSpace= vec4(cameraViewMatrix * dpos);
vs_positionViewSpace = dposViewSpace;
vec4 initialPosition = z_normalization(dposClip - scaledRightClip - scaledUpClip);
vs_screenSpaceDepth = initialPosition.w;
vec4 secondPosition = z_normalization(dposClip + scaledRightClip - scaledUpClip);
vec4 crossCorner = z_normalization(dposClip + scaledUpClip + scaledRightClip);
vec4 thirdPosition = z_normalization(dposClip + scaledUpClip - scaledRightClip);
// Build primitive
texCoord = corners[0];
gl_Position = initialPosition;
EmitVertex();
texCoord = corners[1];
gl_Position = secondPosition;
EmitVertex();
texCoord = corners[3];
gl_Position = thirdPosition;
EmitVertex();
texCoord = corners[2];
gl_Position = crossCorner;
EmitVertex();
EndPrimitive();
}