This commit is contained in:
Brad Hefta-Gaub 2016-10-18 21:33:37 -07:00
parent 0b6e041d45
commit 6bd193cdd8
8 changed files with 118 additions and 109 deletions

View file

@ -13,6 +13,9 @@ struct OverlayData {
vec4 glowPoints;
vec4 glowColors[2];
vec4 resolutionRadiusAlpha;
vec4 extraGlowColor;
vec2 extraGlowPoint;
};
layout(std140) uniform overlayBuffer {
@ -25,6 +28,9 @@ float alpha = overlay.resolutionRadiusAlpha.w;
vec4 glowPoints = overlay.glowPoints;
vec4 glowColors[2] = overlay.glowColors;
vec2 extraGlowPoint = overlay.extraGlowPoint;
vec4 extraGlowColor = overlay.extraGlowColor;
in vec3 vPosition;
in vec2 vTexCoord;
@ -48,11 +54,16 @@ void main() {
float glowIntensity = 0.0;
float dist1 = distance(vTexCoord * aspect, glowPoints.xy * aspect);
float dist2 = distance(vTexCoord * aspect, glowPoints.zw * aspect);
float dist = min(dist1, dist2);
float dist3 = distance(vTexCoord * aspect, extraGlowPoint * aspect);
float distX = min(dist1, dist2);
float dist = min(distX, dist3);
vec3 glowColor = glowColors[0].rgb;
if (dist2 < dist1) {
glowColor = glowColors[1].rgb;
}
if (dist3 < dist2) {
glowColor = extraGlowColor.rgb;
}
if (dist <= radius) {
glowIntensity = 1.0 - (dist / radius);

View file

@ -11,6 +11,9 @@ struct OverlayData {
vec4 glowPoints;
vec4 glowColors[2];
vec4 resolutionRadiusAlpha;
vec4 extraGlowColor;
vec2 extraGlowPoint;
};
layout(std140) uniform overlayBuffer {

View file

@ -341,6 +341,11 @@ void HmdDisplayPlugin::updateFrameData() {
if (_currentFrame) {
auto batchPose = _currentFrame->pose;
// HACK o RAMA
//_handPoses[0] = _currentFrame->pose;
//_handPoses[1] = _currentFrame->pose;
auto currentPose = _currentPresentFrameInfo.presentPose;
auto correction = glm::inverse(batchPose) * currentPose;
getGLBackend()->setCameraCorrection(correction);
@ -350,11 +355,16 @@ void HmdDisplayPlugin::updateFrameData() {
_presentHandLasers = _handLasers;
_presentHandPoses = _handPoses;
_presentUiModelTransform = _uiModelTransform;
_presentExtraLaser = _extraLaser;
_presentExtraLaserPose = _extraLaserPose;
});
auto compositorHelper = DependencyManager::get<CompositorHelper>();
glm::mat4 modelMat = compositorHelper->getModelTransform().getMatrix();
std::array<vec2, NUMBER_OF_HANDS> handGlowPoints{ { vec2(-1), vec2(-1) } };
vec2 extraGlowPoint(-1);
// compute the glow point interesections
for (size_t i = 0; i < NUMBER_OF_HANDS; ++i) {
@ -419,6 +429,55 @@ void HmdDisplayPlugin::updateFrameData() {
handGlowPoints[i] = yawPitch;
}
// compute the glow point interesections
if (_presentExtraLaser.valid()) {
const auto& handLaser = _presentExtraLaser;
const vec3& laserDirection = handLaser.direction;
mat4 model = _presentExtraLaserPose;
vec3 castStart = vec3(model[3]);
vec3 castDirection = glm::quat_cast(model) * laserDirection;
if (glm::abs(glm::length2(castDirection) - 1.0f) > EPSILON) {
castDirection = glm::normalize(castDirection);
castDirection = glm::inverse(_presentUiModelTransform.getRotation()) * castDirection;
}
// FIXME - no offset
vec3 grabPointOffset {0};
castStart += glm::quat_cast(model) * grabPointOffset;
// FIXME fetch the actual UI radius from... somewhere?
float uiRadius = 1.0f;
// Find the intersection of the laser with he UI and use it to scale the model matrix
float distance;
if (glm::intersectRaySphere(castStart, castDirection,
_presentUiModelTransform.getTranslation(), uiRadius * uiRadius, distance)) {
_presentExtraLaserPoints.first = castStart;
_presentExtraLaserPoints.second = _presentExtraLaserPoints.first + (castDirection * distance);
vec3 intersectionPosition = castStart + (castDirection * distance) - _presentUiModelTransform.getTranslation();
intersectionPosition = glm::inverse(_presentUiModelTransform.getRotation()) * intersectionPosition;
// Take the interesection normal and convert it to a texture coordinate
vec2 yawPitch;
{
vec2 xdir = glm::normalize(vec2(intersectionPosition.x, -intersectionPosition.z));
yawPitch.x = glm::atan(xdir.x, xdir.y);
yawPitch.y = (acosf(intersectionPosition.y) * -1.0f) + (float)M_PI_2;
}
vec2 halfFov = CompositorHelper::VIRTUAL_UI_TARGET_FOV / 2.0f;
// Are we out of range
if (!glm::any(glm::greaterThan(glm::abs(yawPitch), halfFov))) {
yawPitch /= CompositorHelper::VIRTUAL_UI_TARGET_FOV;
yawPitch += 0.5f;
extraGlowPoint = yawPitch;
}
}
}
for_each_eye([&](Eye eye) {
auto modelView = glm::inverse(_currentPresentFrameInfo.presentPose * getEyeToHeadTransform(eye)) * modelMat;
@ -432,6 +491,8 @@ void HmdDisplayPlugin::updateFrameData() {
uniforms.glowPoints = vec4(handGlowPoints[0], handGlowPoints[1]);
uniforms.glowColors[0] = _presentHandLasers[0].color;
uniforms.glowColors[1] = _presentHandLasers[1].color;
uniforms.extraGlowPoint = extraGlowPoint;
uniforms.extraGlowColor = _presentExtraLaser.color;
}
}
@ -607,6 +668,20 @@ bool HmdDisplayPlugin::setHandLaser(uint32_t hands, HandLaserMode mode, const ve
return true;
}
bool HmdDisplayPlugin::setExtraLaser(mat4 extraLaserPose, HandLaserMode mode, const vec4& color, const vec3& direction) {
HandLaserInfo info;
info.mode = mode;
info.color = color;
info.direction = direction;
withNonPresentThreadLock([&] {
_extraLaser = info;
_extraLaserPose = extraLaserPose;
});
// FIXME defer to a child class plugin to determine if hand lasers are actually
// available based on the presence or absence of hand controllers
return true;
}
void HmdDisplayPlugin::compositeExtra() {
// If neither hand laser is activated, exit
if (!_presentHandLasers[0].valid() && !_presentHandLasers[1].valid()) {
@ -628,14 +703,23 @@ void HmdDisplayPlugin::compositeExtra() {
return;
}
const auto& laser = _presentHandLasers[index];
const float glowIntensity = 1.0f;
const float glowWidth = 0.05f;
if (laser.valid()) {
const auto& points = _presentHandLaserPoints[index];
geometryCache->renderGlowLine(batch, points.first, points.second, laser.color);
geometryCache->renderGlowLine(batch, points.first, points.second, laser.color,
glowIntensity, glowWidth, _glowLineID);
}
});
});
}
HmdDisplayPlugin::HmdDisplayPlugin() {
_glowLineID = DependencyManager::get<GeometryCache>()->allocateID();
}
HmdDisplayPlugin::~HmdDisplayPlugin() {
qDebug() << "Destroying HmdDisplayPlugin";
DependencyManager::get<GeometryCache>()->releaseID(_glowLineID);
}

View file

@ -23,6 +23,7 @@
class HmdDisplayPlugin : public OpenGLDisplayPlugin {
using Parent = OpenGLDisplayPlugin;
public:
HmdDisplayPlugin();
~HmdDisplayPlugin();
bool isHmd() const override final { return true; }
float getIPD() const override final { return _ipd; }
@ -38,6 +39,7 @@ public:
virtual glm::mat4 getHeadPose() const override;
bool setHandLaser(uint32_t hands, HandLaserMode mode, const vec4& color, const vec3& direction) override;
bool setExtraLaser(mat4 extraLaserPose, HandLaserMode mode, const vec4& color, const vec3& direction) override;
bool wantVsync() const override {
return false;
@ -80,6 +82,12 @@ protected:
std::array<mat4, 2> _presentHandPoses;
std::array<std::pair<vec3, vec3>, 2> _presentHandLaserPoints;
HandLaserInfo _extraLaser;
HandLaserInfo _presentExtraLaser;
mat4 _extraLaserPose;
mat4 _presentExtraLaserPose;
std::pair<vec3, vec3> _presentExtraLaserPoints;
std::array<mat4, 2> _eyeOffsets;
std::array<mat4, 2> _eyeProjections;
std::array<mat4, 2> _eyeInverseProjections;
@ -130,6 +138,9 @@ private:
vec2 resolution { CompositorHelper::VIRTUAL_SCREEN_SIZE };
float radius { 0.005f };
float alpha { 1.0f };
vec4 extraGlowColor;
vec2 extraGlowPoint { -1 };
} uniforms;
struct Vertex {
@ -145,4 +156,6 @@ private:
void updatePipeline();
void render(HmdDisplayPlugin& plugin);
} _overlayRenderer;
int _glowLineID { -1 };
};

View file

@ -1,75 +0,0 @@
//
// Created by Bradley Austin Davis on 2016/07/11
// Copyright 2013-2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
uniform sampler2D sampler;
struct OverlayData {
mat4 mvp;
vec4 glowPoints;
vec4 glowColors[2];
vec4 resolutionRadiusAlpha;
};
layout(std140) uniform overlayBuffer {
OverlayData overlay;
};
vec2 resolution = overlay.resolutionRadiusAlpha.xy;
float radius = overlay.resolutionRadiusAlpha.z;
float alpha = overlay.resolutionRadiusAlpha.w;
vec4 glowPoints = overlay.glowPoints;
vec4 glowColors[2] = overlay.glowColors;
in vec3 vPosition;
in vec2 vTexCoord;
out vec4 FragColor;
float easeInOutCubic(float f) {
const float d = 1.0;
const float b = 0.0;
const float c = 1.0;
float t = f;
if ((t /= d / 2.0) < 1.0) return c / 2.0 * t * t * t + b;
return c / 2.0 * ((t -= 2.0) * t * t + 2.0) + b;
}
void main() {
FragColor = texture(sampler, vTexCoord);
vec2 aspect = resolution;
aspect /= resolution.x;
float glowIntensity = 0.0;
float dist1 = distance(vTexCoord * aspect, glowPoints.xy * aspect);
float dist2 = distance(vTexCoord * aspect, glowPoints.zw * aspect);
float dist = min(dist1, dist2);
vec3 glowColor = glowColors[0].rgb;
if (dist2 < dist1) {
glowColor = glowColors[1].rgb;
}
if (dist <= radius) {
glowIntensity = 1.0 - (dist / radius);
glowColor.rgb = pow(glowColor, vec3(1.0 - glowIntensity));
glowIntensity = easeInOutCubic(glowIntensity);
glowIntensity = pow(glowIntensity, 0.5);
}
if (alpha <= 0.0) {
if (glowIntensity <= 0.0) {
discard;
}
FragColor = vec4(glowColor, glowIntensity);
return;
}
FragColor.rgb = mix(FragColor.rgb, glowColor.rgb, glowIntensity);
FragColor.a *= alpha;
}

View file

@ -1,32 +0,0 @@
//
// Created by Bradley Austin Davis on 2016/07/11
// Copyright 2013-2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
struct OverlayData {
mat4 mvp;
vec4 glowPoints;
vec4 glowColors[2];
vec4 resolutionRadiusAlpha;
};
layout(std140) uniform overlayBuffer {
OverlayData overlay;
};
mat4 mvp = overlay.mvp;
layout(location = 0) in vec3 Position;
layout(location = 3) in vec2 TexCoord;
out vec3 vPosition;
out vec2 vTexCoord;
void main() {
gl_Position = mvp * vec4(Position, 1);
vTexCoord = TexCoord;
vPosition = Position;
}

View file

@ -115,6 +115,10 @@ public:
return false;
}
virtual bool setExtraLaser(mat4 extraLaserPose, HandLaserMode mode, const vec4& color, const vec3& direction) {
return false;
}
virtual bool suppressKeyboard() { return false; }
virtual void unsuppressKeyboard() {};
virtual bool isKeyboardVisible() { return false; }

View file

@ -1591,6 +1591,7 @@ void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm
}
// FIXME -- there's a memory leak of GPU buffers in this method
void GeometryCache::renderGlowLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
const glm::vec4& color, float glowIntensity, float glowWidth, int id) {