mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Adding glow to hand lasers
This commit is contained in:
parent
0efc684992
commit
6242816f68
11 changed files with 493 additions and 309 deletions
35
interface/resources/shaders/hmd_hand_lasers.frag
Normal file
35
interface/resources/shaders/hmd_hand_lasers.frag
Normal file
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
#version 410 core
|
||||
|
||||
uniform vec4 color = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
layout(location = 0) in vec3 inLineDistance;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
vec2 d = inLineDistance.xy;
|
||||
d.y = abs(d.y);
|
||||
d.x = abs(d.x);
|
||||
if (d.x > 1.0) {
|
||||
d.x = (d.x - 1.0) / 0.02;
|
||||
} else {
|
||||
d.x = 0.0;
|
||||
}
|
||||
float alpha = 1.0 - length(d);
|
||||
if (alpha <= 0.0) {
|
||||
discard;
|
||||
}
|
||||
alpha = pow(alpha, 10.0);
|
||||
if (alpha < 0.05) {
|
||||
discard;
|
||||
}
|
||||
FragColor = vec4(color.rgb, alpha);
|
||||
}
|
70
interface/resources/shaders/hmd_hand_lasers.geom
Normal file
70
interface/resources/shaders/hmd_hand_lasers.geom
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// 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
|
||||
//
|
||||
#version 410 core
|
||||
#extension GL_EXT_geometry_shader4 : enable
|
||||
|
||||
layout(location = 0) out vec3 outLineDistance;
|
||||
|
||||
layout(lines) in;
|
||||
layout(triangle_strip, max_vertices = 24) out;
|
||||
|
||||
vec3[2] getOrthogonals(in vec3 n, float scale) {
|
||||
float yDot = abs(dot(n, vec3(0, 1, 0)));
|
||||
|
||||
vec3 result[2];
|
||||
if (yDot < 0.9) {
|
||||
result[0] = normalize(cross(n, vec3(0, 1, 0)));
|
||||
} else {
|
||||
result[0] = normalize(cross(n, vec3(1, 0, 0)));
|
||||
}
|
||||
// The cross of result[0] and n is orthogonal to both, which are orthogonal to each other
|
||||
result[1] = cross(result[0], n);
|
||||
result[0] *= scale;
|
||||
result[1] *= scale;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
vec2 orthogonal(vec2 v) {
|
||||
vec2 result = v.yx;
|
||||
result.y *= -1.0;
|
||||
return result;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 endpoints[2];
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
endpoints[i] = gl_PositionIn[i].xy / gl_PositionIn[i].w;
|
||||
}
|
||||
vec2 lineNormal = normalize(endpoints[1] - endpoints[0]);
|
||||
vec2 lineOrthogonal = orthogonal(lineNormal);
|
||||
lineNormal *= 0.02;
|
||||
lineOrthogonal *= 0.02;
|
||||
|
||||
gl_Position = gl_PositionIn[0];
|
||||
gl_Position.xy -= lineOrthogonal;
|
||||
outLineDistance = vec3(-1.02, -1, gl_Position.z);
|
||||
EmitVertex();
|
||||
|
||||
gl_Position = gl_PositionIn[0];
|
||||
gl_Position.xy += lineOrthogonal;
|
||||
outLineDistance = vec3(-1.02, 1, gl_Position.z);
|
||||
EmitVertex();
|
||||
|
||||
gl_Position = gl_PositionIn[1];
|
||||
gl_Position.xy -= lineOrthogonal;
|
||||
outLineDistance = vec3(1.02, -1, gl_Position.z);
|
||||
EmitVertex();
|
||||
|
||||
gl_Position = gl_PositionIn[1];
|
||||
gl_Position.xy += lineOrthogonal;
|
||||
outLineDistance = vec3(1.02, 1, gl_Position.z);
|
||||
EmitVertex();
|
||||
|
||||
EndPrimitive();
|
||||
}
|
15
interface/resources/shaders/hmd_hand_lasers.vert
Normal file
15
interface/resources/shaders/hmd_hand_lasers.vert
Normal file
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// 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
|
||||
//
|
||||
#version 410 core
|
||||
uniform mat4 mvp = mat4(1);
|
||||
|
||||
in vec3 Position;
|
||||
|
||||
void main() {
|
||||
gl_Position = mvp * vec4(Position, 1);
|
||||
}
|
78
interface/resources/shaders/hmd_reproject.frag
Normal file
78
interface/resources/shaders/hmd_reproject.frag
Normal file
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
#version 410 core
|
||||
|
||||
uniform sampler2D sampler;
|
||||
uniform mat3 reprojection = mat3(1);
|
||||
uniform mat4 inverseProjections[2];
|
||||
uniform mat4 projections[2];
|
||||
|
||||
in vec2 vTexCoord;
|
||||
in vec3 vPosition;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
vec2 uv = vTexCoord;
|
||||
|
||||
mat4 eyeInverseProjection;
|
||||
mat4 eyeProjection;
|
||||
|
||||
float xoffset = 1.0;
|
||||
vec2 uvmin = vec2(0.0);
|
||||
vec2 uvmax = vec2(1.0);
|
||||
// determine the correct projection and inverse projection to use.
|
||||
if (vTexCoord.x < 0.5) {
|
||||
uvmax.x = 0.5;
|
||||
eyeInverseProjection = inverseProjections[0];
|
||||
eyeProjection = projections[0];
|
||||
} else {
|
||||
xoffset = -1.0;
|
||||
uvmin.x = 0.5;
|
||||
uvmax.x = 1.0;
|
||||
eyeInverseProjection = inverseProjections[1];
|
||||
eyeProjection = projections[1];
|
||||
}
|
||||
|
||||
// Account for stereo in calculating the per-eye NDC coordinates
|
||||
vec4 ndcSpace = vec4(vPosition, 1.0);
|
||||
ndcSpace.x *= 2.0;
|
||||
ndcSpace.x += xoffset;
|
||||
|
||||
// Convert from NDC to eyespace
|
||||
vec4 eyeSpace = eyeInverseProjection * ndcSpace;
|
||||
eyeSpace /= eyeSpace.w;
|
||||
|
||||
// Convert to a noramlized ray
|
||||
vec3 ray = eyeSpace.xyz;
|
||||
ray = normalize(ray);
|
||||
|
||||
// Adjust the ray by the rotation
|
||||
ray = reprojection * ray;
|
||||
|
||||
// Project back on to the texture plane
|
||||
ray *= eyeSpace.z / ray.z;
|
||||
|
||||
// Update the eyespace vector
|
||||
eyeSpace.xyz = ray;
|
||||
|
||||
// Reproject back into NDC
|
||||
ndcSpace = eyeProjection * eyeSpace;
|
||||
ndcSpace /= ndcSpace.w;
|
||||
ndcSpace.x -= xoffset;
|
||||
ndcSpace.x /= 2.0;
|
||||
|
||||
// Calculate the new UV coordinates
|
||||
uv = (ndcSpace.xy / 2.0) + 0.5;
|
||||
if (any(greaterThan(uv, uvmax)) || any(lessThan(uv, uvmin))) {
|
||||
FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
} else {
|
||||
FragColor = texture(sampler, uv);
|
||||
}
|
||||
}
|
20
interface/resources/shaders/hmd_reproject.vert
Normal file
20
interface/resources/shaders/hmd_reproject.vert
Normal file
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
#version 410 core
|
||||
in vec3 Position;
|
||||
in vec2 TexCoord;
|
||||
|
||||
out vec3 vPosition;
|
||||
out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(Position, 1);
|
||||
vTexCoord = TexCoord;
|
||||
vPosition = Position;
|
||||
}
|
65
interface/resources/shaders/hmd_ui_glow.frag
Normal file
65
interface/resources/shaders/hmd_ui_glow.frag
Normal file
|
@ -0,0 +1,65 @@
|
|||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
#version 410 core
|
||||
|
||||
uniform sampler2D sampler;
|
||||
uniform float alpha = 1.0;
|
||||
uniform vec4 glowPoints = vec4(-1);
|
||||
uniform vec4 glowColors[2];
|
||||
uniform vec2 resolution = vec2(3960.0, 1188.0);
|
||||
uniform float radius = 0.005;
|
||||
|
||||
in vec3 vPosition;
|
||||
in vec2 vTexCoord;
|
||||
in vec4 vGlowPoints;
|
||||
|
||||
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() {
|
||||
vec2 aspect = resolution;
|
||||
aspect /= resolution.x;
|
||||
FragColor = texture(sampler, vTexCoord);
|
||||
|
||||
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;
|
||||
}
|
23
interface/resources/shaders/hmd_ui_glow.vert
Normal file
23
interface/resources/shaders/hmd_ui_glow.vert
Normal file
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
#version 410 core
|
||||
|
||||
uniform mat4 mvp = mat4(1);
|
||||
|
||||
in vec3 Position;
|
||||
in vec2 TexCoord;
|
||||
|
||||
out vec3 vPosition;
|
||||
out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = mvp * vec4(Position, 1);
|
||||
vTexCoord = TexCoord;
|
||||
vPosition = Position;
|
||||
}
|
|
@ -95,252 +95,6 @@ void HmdDisplayPlugin::internalDeactivate() {
|
|||
Parent::internalDeactivate();
|
||||
}
|
||||
|
||||
|
||||
static const char * REPROJECTION_VS = R"VS(#version 410 core
|
||||
in vec3 Position;
|
||||
in vec2 TexCoord;
|
||||
|
||||
out vec3 vPosition;
|
||||
out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(Position, 1);
|
||||
vTexCoord = TexCoord;
|
||||
vPosition = Position;
|
||||
}
|
||||
|
||||
)VS";
|
||||
|
||||
static GLint REPROJECTION_MATRIX_LOCATION = -1;
|
||||
static GLint INVERSE_PROJECTION_MATRIX_LOCATION = -1;
|
||||
static GLint PROJECTION_MATRIX_LOCATION = -1;
|
||||
static const char * REPROJECTION_FS = R"FS(#version 410 core
|
||||
|
||||
uniform sampler2D sampler;
|
||||
uniform mat3 reprojection = mat3(1);
|
||||
uniform mat4 inverseProjections[2];
|
||||
uniform mat4 projections[2];
|
||||
|
||||
in vec2 vTexCoord;
|
||||
in vec3 vPosition;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
vec2 uv = vTexCoord;
|
||||
|
||||
mat4 eyeInverseProjection;
|
||||
mat4 eyeProjection;
|
||||
|
||||
float xoffset = 1.0;
|
||||
vec2 uvmin = vec2(0.0);
|
||||
vec2 uvmax = vec2(1.0);
|
||||
// determine the correct projection and inverse projection to use.
|
||||
if (vTexCoord.x < 0.5) {
|
||||
uvmax.x = 0.5;
|
||||
eyeInverseProjection = inverseProjections[0];
|
||||
eyeProjection = projections[0];
|
||||
} else {
|
||||
xoffset = -1.0;
|
||||
uvmin.x = 0.5;
|
||||
uvmax.x = 1.0;
|
||||
eyeInverseProjection = inverseProjections[1];
|
||||
eyeProjection = projections[1];
|
||||
}
|
||||
|
||||
// Account for stereo in calculating the per-eye NDC coordinates
|
||||
vec4 ndcSpace = vec4(vPosition, 1.0);
|
||||
ndcSpace.x *= 2.0;
|
||||
ndcSpace.x += xoffset;
|
||||
|
||||
// Convert from NDC to eyespace
|
||||
vec4 eyeSpace = eyeInverseProjection * ndcSpace;
|
||||
eyeSpace /= eyeSpace.w;
|
||||
|
||||
// Convert to a noramlized ray
|
||||
vec3 ray = eyeSpace.xyz;
|
||||
ray = normalize(ray);
|
||||
|
||||
// Adjust the ray by the rotation
|
||||
ray = reprojection * ray;
|
||||
|
||||
// Project back on to the texture plane
|
||||
ray *= eyeSpace.z / ray.z;
|
||||
|
||||
// Update the eyespace vector
|
||||
eyeSpace.xyz = ray;
|
||||
|
||||
// Reproject back into NDC
|
||||
ndcSpace = eyeProjection * eyeSpace;
|
||||
ndcSpace /= ndcSpace.w;
|
||||
ndcSpace.x -= xoffset;
|
||||
ndcSpace.x /= 2.0;
|
||||
|
||||
// Calculate the new UV coordinates
|
||||
uv = (ndcSpace.xy / 2.0) + 0.5;
|
||||
if (any(greaterThan(uv, uvmax)) || any(lessThan(uv, uvmin))) {
|
||||
FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
} else {
|
||||
FragColor = texture(sampler, uv);
|
||||
}
|
||||
}
|
||||
)FS";
|
||||
|
||||
#ifdef DEBUG_REPROJECTION_SHADER
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QDateTime>
|
||||
#include <PathUtils.h>
|
||||
|
||||
static const QString REPROJECTION_FS_FILE = "c:/Users/bdavis/Git/hifi/interface/resources/shaders/reproject.frag";
|
||||
|
||||
static ProgramPtr getReprojectionProgram() {
|
||||
static ProgramPtr _currentProgram;
|
||||
uint64_t now = usecTimestampNow();
|
||||
static uint64_t _lastFileCheck = now;
|
||||
|
||||
bool modified = false;
|
||||
if ((now - _lastFileCheck) > USECS_PER_MSEC * 100) {
|
||||
QFileInfo info(REPROJECTION_FS_FILE);
|
||||
QDateTime lastModified = info.lastModified();
|
||||
static QDateTime _lastModified = lastModified;
|
||||
qDebug() << lastModified.toTime_t();
|
||||
qDebug() << _lastModified.toTime_t();
|
||||
if (lastModified > _lastModified) {
|
||||
_lastModified = lastModified;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_currentProgram || modified) {
|
||||
_currentProgram.reset();
|
||||
try {
|
||||
QFile shaderFile(REPROJECTION_FS_FILE);
|
||||
shaderFile.open(QIODevice::ReadOnly);
|
||||
QString fragment = shaderFile.readAll();
|
||||
compileProgram(_currentProgram, REPROJECTION_VS, fragment.toLocal8Bit().data());
|
||||
} catch (const std::runtime_error& error) {
|
||||
qDebug() << "Failed to build: " << error.what();
|
||||
}
|
||||
if (!_currentProgram) {
|
||||
_currentProgram = loadDefaultShader();
|
||||
}
|
||||
}
|
||||
return _currentProgram;
|
||||
}
|
||||
#endif
|
||||
|
||||
static GLint PREVIEW_TEXTURE_LOCATION = -1;
|
||||
|
||||
static const char * LASER_VS = R"VS(#version 410 core
|
||||
uniform mat4 mvp = mat4(1);
|
||||
|
||||
in vec3 Position;
|
||||
|
||||
out vec3 vPosition;
|
||||
|
||||
void main() {
|
||||
gl_Position = mvp * vec4(Position, 1);
|
||||
vPosition = Position;
|
||||
}
|
||||
|
||||
)VS";
|
||||
|
||||
static const char * LASER_GS = R"GS(
|
||||
)GS";
|
||||
|
||||
static const char * LASER_FS = R"FS(#version 410 core
|
||||
|
||||
uniform vec4 color = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
in vec3 vPosition;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
FragColor = color;
|
||||
}
|
||||
|
||||
)FS";
|
||||
|
||||
|
||||
static const char * LASER_GLOW_VS = R"VS(#version 410 core
|
||||
|
||||
uniform mat4 mvp = mat4(1);
|
||||
|
||||
in vec3 Position;
|
||||
in vec2 TexCoord;
|
||||
|
||||
out vec3 vPosition;
|
||||
out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = mvp * vec4(Position, 1);
|
||||
vTexCoord = TexCoord;
|
||||
vPosition = Position;
|
||||
}
|
||||
|
||||
)VS";
|
||||
|
||||
static const char * LASER_GLOW_FS = R"FS(#version 410 core
|
||||
#line 286
|
||||
uniform sampler2D sampler;
|
||||
uniform float alpha = 1.0;
|
||||
uniform vec4 glowPoints = vec4(-1);
|
||||
uniform vec4 glowColor1 = vec4(0.01, 0.7, 0.9, 1.0);
|
||||
uniform vec4 glowColor2 = vec4(0.9, 0.7, 0.01, 1.0);
|
||||
uniform vec2 resolution = vec2(3960.0, 1188.0);
|
||||
uniform float radius = 0.005;
|
||||
|
||||
in vec3 vPosition;
|
||||
in vec2 vTexCoord;
|
||||
in vec4 vGlowPoints;
|
||||
|
||||
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() {
|
||||
vec2 aspect = resolution;
|
||||
aspect /= resolution.x;
|
||||
FragColor = texture(sampler, vTexCoord);
|
||||
|
||||
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 = glowColor1.rgb;
|
||||
if (dist2 < dist1) {
|
||||
glowColor = glowColor2.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;
|
||||
}
|
||||
)FS";
|
||||
|
||||
void HmdDisplayPlugin::customizeContext() {
|
||||
Parent::customizeContext();
|
||||
// Only enable mirroring if we know vsync is disabled
|
||||
|
@ -354,76 +108,139 @@ void HmdDisplayPlugin::customizeContext() {
|
|||
if (!_enablePreview) {
|
||||
const std::string version("#version 410 core\n");
|
||||
compileProgram(_previewProgram, version + DrawUnitQuadTexcoord_vert, version + DrawTexture_frag);
|
||||
PREVIEW_TEXTURE_LOCATION = Uniform<int>(*_previewProgram, "colorMap").Location();
|
||||
_previewUniforms.previewTexture = Uniform<int>(*_previewProgram, "colorMap").Location();
|
||||
}
|
||||
|
||||
updateGlowProgram();
|
||||
compileProgram(_laserProgram, LASER_VS, LASER_FS);
|
||||
updateReprojectionProgram();
|
||||
updateOverlayProgram();
|
||||
updateLaserProgram();
|
||||
|
||||
_laserGeometry = loadLaser(_laserProgram);
|
||||
|
||||
compileProgram(_reprojectionProgram, REPROJECTION_VS, REPROJECTION_FS);
|
||||
REPROJECTION_MATRIX_LOCATION = Uniform<glm::mat3>(*_reprojectionProgram, "reprojection").Location();
|
||||
INVERSE_PROJECTION_MATRIX_LOCATION = Uniform<glm::mat4>(*_reprojectionProgram, "inverseProjections").Location();
|
||||
PROJECTION_MATRIX_LOCATION = Uniform<glm::mat4>(*_reprojectionProgram, "projections").Location();
|
||||
}
|
||||
//#define LIVE_SHADER_RELOAD 1
|
||||
|
||||
#if 0
|
||||
static QString readFile(const char* filename) {
|
||||
static QString readFile(const QString& filename) {
|
||||
QFile file(filename);
|
||||
file.open(QFile::Text | QFile::ReadOnly);
|
||||
QString result;
|
||||
result.append(QTextStream(&file).readAll());
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void HmdDisplayPlugin::updateGlowProgram() {
|
||||
#if 0
|
||||
void HmdDisplayPlugin::updateReprojectionProgram() {
|
||||
static const QString vsFile = PathUtils::resourcesPath() + "/shaders/hmd_reproject.vert";
|
||||
static const QString fsFile = PathUtils::resourcesPath() + "/shaders/hmd_reproject.frag";
|
||||
#if LIVE_SHADER_RELOAD
|
||||
static qint64 vsBuiltAge = 0;
|
||||
static qint64 fsBuiltAge = 0;
|
||||
QFileInfo vsInfo(vsFile);
|
||||
QFileInfo fsInfo(fsFile);
|
||||
auto vsAge = vsInfo.lastModified().toMSecsSinceEpoch();
|
||||
auto fsAge = fsInfo.lastModified().toMSecsSinceEpoch();
|
||||
if (!_reprojectionProgram || vsAge > vsBuiltAge || fsAge > fsBuiltAge) {
|
||||
vsBuiltAge = vsAge;
|
||||
fsBuiltAge = fsAge;
|
||||
#else
|
||||
if (!_reprojectionProgram) {
|
||||
#endif
|
||||
QString vsSource = readFile(vsFile);
|
||||
QString fsSource = readFile(fsFile);
|
||||
ProgramPtr program;
|
||||
try {
|
||||
compileProgram(program, vsSource.toLocal8Bit().toStdString(), fsSource.toLocal8Bit().toStdString());
|
||||
if (program) {
|
||||
using namespace oglplus;
|
||||
_reprojectionUniforms.reprojectionMatrix = Uniform<glm::mat3>(*program, "reprojection").Location();
|
||||
_reprojectionUniforms.inverseProjectionMatrix = Uniform<glm::mat4>(*program, "inverseProjections").Location();
|
||||
_reprojectionUniforms.projectionMatrix = Uniform<glm::mat4>(*program, "projections").Location();
|
||||
_reprojectionProgram = program;
|
||||
}
|
||||
} catch (std::runtime_error& error) {
|
||||
qWarning() << "Error building reprojection shader " << error.what();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::updateLaserProgram() {
|
||||
static const QString vsFile = PathUtils::resourcesPath() + "/shaders/hmd_hand_lasers.vert";
|
||||
static const QString gsFile = PathUtils::resourcesPath() + "/shaders/hmd_hand_lasers.geom";
|
||||
static const QString fsFile = PathUtils::resourcesPath() + "/shaders/hmd_hand_lasers.frag";
|
||||
|
||||
#if LIVE_SHADER_RELOAD
|
||||
static qint64 vsBuiltAge = 0;
|
||||
static qint64 gsBuiltAge = 0;
|
||||
static qint64 fsBuiltAge = 0;
|
||||
QFileInfo vsInfo(vsFile);
|
||||
QFileInfo fsInfo(fsFile);
|
||||
QFileInfo gsInfo(fsFile);
|
||||
auto vsAge = vsInfo.lastModified().toMSecsSinceEpoch();
|
||||
auto fsAge = fsInfo.lastModified().toMSecsSinceEpoch();
|
||||
auto gsAge = gsInfo.lastModified().toMSecsSinceEpoch();
|
||||
if (!_laserProgram || vsAge > vsBuiltAge || fsAge > fsBuiltAge || gsAge > gsBuiltAge) {
|
||||
vsBuiltAge = vsAge;
|
||||
gsBuiltAge = gsAge;
|
||||
fsBuiltAge = fsAge;
|
||||
#else
|
||||
if (!_laserProgram) {
|
||||
#endif
|
||||
|
||||
QString vsSource = readFile(vsFile);
|
||||
QString fsSource = readFile(fsFile);
|
||||
QString gsSource = readFile(gsFile);
|
||||
ProgramPtr program;
|
||||
try {
|
||||
compileProgram(program, vsSource.toLocal8Bit().toStdString(), gsSource.toLocal8Bit().toStdString(), fsSource.toLocal8Bit().toStdString());
|
||||
if (program) {
|
||||
using namespace oglplus;
|
||||
_laserUniforms.color = Uniform<glm::vec4>(*program, "color").Location();
|
||||
_laserUniforms.mvp = Uniform<glm::mat4>(*program, "mvp").Location();
|
||||
_laserProgram = program;
|
||||
}
|
||||
} catch (std::runtime_error& error) {
|
||||
qWarning() << "Error building hand laser composite shader " << error.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::updateOverlayProgram() {
|
||||
static const QString vsFile = PathUtils::resourcesPath() + "/shaders/hmd_ui_glow.vert";
|
||||
static const QString fsFile = PathUtils::resourcesPath() + "/shaders/hmd_ui_glow.frag";
|
||||
|
||||
#if LIVE_SHADER_RELOAD
|
||||
static qint64 vsBuiltAge = 0;
|
||||
static qint64 fsBuiltAge = 0;
|
||||
static const char* vsFile = "H:/glow_vert.glsl";
|
||||
static const char* fsFile = "H:/glow_frag.glsl";
|
||||
QFileInfo vsInfo(vsFile);
|
||||
QFileInfo fsInfo(fsFile);
|
||||
auto vsAge = vsInfo.lastModified().toMSecsSinceEpoch();
|
||||
auto fsAge = fsInfo.lastModified().toMSecsSinceEpoch();
|
||||
if (!_overlayProgram || vsAge > vsBuiltAge || fsAge > fsBuiltAge) {
|
||||
QString vsSource = readFile(vsFile);
|
||||
QString fsSource = readFile(fsFile);
|
||||
ProgramPtr newOverlayProgram;
|
||||
compileProgram(newOverlayProgram, vsSource.toLocal8Bit().toStdString(), fsSource.toLocal8Bit().toStdString());
|
||||
if (newOverlayProgram) {
|
||||
using namespace oglplus;
|
||||
_overlayProgram = newOverlayProgram;
|
||||
auto uniforms = _overlayProgram->ActiveUniforms();
|
||||
_overlayUniforms.mvp = Uniform<glm::mat4>(*_overlayProgram, "mvp").Location();
|
||||
_overlayUniforms.alpha = Uniform<float>(*_overlayProgram, "alpha").Location();
|
||||
_overlayUniforms.glowPoints = Uniform<glm::vec4>(*_overlayProgram, "glowPoints").Location();
|
||||
_overlayUniforms.resolution = Uniform<glm::vec2>(*_overlayProgram, "resolution").Location();
|
||||
_overlayUniforms.radius = Uniform<float>(*_overlayProgram, "radius").Location();
|
||||
useProgram(_overlayProgram);
|
||||
Uniform<glm::vec2>(*_overlayProgram, _overlayUniforms.resolution).Set(CompositorHelper::VIRTUAL_SCREEN_SIZE);
|
||||
}
|
||||
vsBuiltAge = vsAge;
|
||||
fsBuiltAge = fsAge;
|
||||
|
||||
}
|
||||
#else
|
||||
if (!_overlayProgram) {
|
||||
compileProgram(_overlayProgram, LASER_GLOW_VS, LASER_GLOW_FS);
|
||||
using namespace oglplus;
|
||||
auto uniforms = _overlayProgram->ActiveUniforms();
|
||||
_overlayUniforms.mvp = Uniform<glm::mat4>(*_overlayProgram, "mvp").Location();
|
||||
_overlayUniforms.alpha = Uniform<float>(*_overlayProgram, "alpha").Location();
|
||||
_overlayUniforms.glowPoints = Uniform<glm::vec4>(*_overlayProgram, "glowPoints").Location();
|
||||
_overlayUniforms.resolution = Uniform<glm::vec2>(*_overlayProgram, "resolution").Location();
|
||||
_overlayUniforms.radius = Uniform<float>(*_overlayProgram, "radius").Location();
|
||||
useProgram(_overlayProgram);
|
||||
Uniform<glm::vec2>(*_overlayProgram, _overlayUniforms.resolution).Set(CompositorHelper::VIRTUAL_SCREEN_SIZE);
|
||||
}
|
||||
|
||||
#endif
|
||||
QString vsSource = readFile(vsFile);
|
||||
QString fsSource = readFile(fsFile);
|
||||
ProgramPtr program;
|
||||
try {
|
||||
compileProgram(program, vsSource.toLocal8Bit().toStdString(), fsSource.toLocal8Bit().toStdString());
|
||||
if (program) {
|
||||
using namespace oglplus;
|
||||
_overlayUniforms.mvp = Uniform<glm::mat4>(*program, "mvp").Location();
|
||||
_overlayUniforms.alpha = Uniform<float>(*program, "alpha").Location();
|
||||
_overlayUniforms.glowColors = Uniform<glm::vec4>(*program, "glowColors").Location();
|
||||
_overlayUniforms.glowPoints = Uniform<glm::vec4>(*program, "glowPoints").Location();
|
||||
_overlayUniforms.resolution = Uniform<glm::vec2>(*program, "resolution").Location();
|
||||
_overlayUniforms.radius = Uniform<float>(*program, "radius").Location();
|
||||
_overlayProgram = program;
|
||||
useProgram(_overlayProgram);
|
||||
Uniform<glm::vec2>(*_overlayProgram, _overlayUniforms.resolution).Set(CompositorHelper::VIRTUAL_SCREEN_SIZE);
|
||||
}
|
||||
} catch (std::runtime_error& error) {
|
||||
qWarning() << "Error building overlay composite shader " << error.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::uncustomizeContext() {
|
||||
|
@ -459,12 +276,12 @@ void HmdDisplayPlugin::compositeScene() {
|
|||
using namespace oglplus;
|
||||
Texture::MinFilter(TextureTarget::_2D, TextureMinFilter::Linear);
|
||||
Texture::MagFilter(TextureTarget::_2D, TextureMagFilter::Linear);
|
||||
Uniform<glm::mat3>(*_reprojectionProgram, REPROJECTION_MATRIX_LOCATION).Set(_currentPresentFrameInfo.presentReprojection);
|
||||
Uniform<glm::mat3>(*_reprojectionProgram, _reprojectionUniforms.reprojectionMatrix).Set(_currentPresentFrameInfo.presentReprojection);
|
||||
//Uniform<glm::mat4>(*_reprojectionProgram, PROJECTION_MATRIX_LOCATION).Set(_eyeProjections);
|
||||
//Uniform<glm::mat4>(*_reprojectionProgram, INVERSE_PROJECTION_MATRIX_LOCATION).Set(_eyeInverseProjections);
|
||||
// FIXME what's the right oglplus mechanism to do this? It's not that ^^^ ... better yet, switch to a uniform buffer
|
||||
glUniformMatrix4fv(INVERSE_PROJECTION_MATRIX_LOCATION, 2, GL_FALSE, &(_eyeInverseProjections[0][0][0]));
|
||||
glUniformMatrix4fv(PROJECTION_MATRIX_LOCATION, 2, GL_FALSE, &(_eyeProjections[0][0][0]));
|
||||
glUniformMatrix4fv(_reprojectionUniforms.inverseProjectionMatrix, 2, GL_FALSE, &(_eyeInverseProjections[0][0][0]));
|
||||
glUniformMatrix4fv(_reprojectionUniforms.projectionMatrix, 2, GL_FALSE, &(_eyeProjections[0][0][0]));
|
||||
_plane->UseInProgram(*_reprojectionProgram);
|
||||
_plane->Draw();
|
||||
}
|
||||
|
@ -530,7 +347,11 @@ void HmdDisplayPlugin::compositeOverlay() {
|
|||
handGlowPoints[i] = yawPitch;
|
||||
}
|
||||
|
||||
updateGlowProgram();
|
||||
updateOverlayProgram();
|
||||
if (!_overlayProgram) {
|
||||
return;
|
||||
}
|
||||
|
||||
useProgram(_overlayProgram);
|
||||
// Setup the uniforms
|
||||
{
|
||||
|
@ -541,6 +362,12 @@ void HmdDisplayPlugin::compositeOverlay() {
|
|||
vec4 glowPoints(handGlowPoints[0], handGlowPoints[1]);
|
||||
Uniform<glm::vec4>(*_overlayProgram, _overlayUniforms.glowPoints).Set(glowPoints);
|
||||
}
|
||||
if (_overlayUniforms.glowColors >= 0) {
|
||||
std::array<glm::vec4, NUMBER_OF_HANDS> glowColors;
|
||||
glowColors[0] = _presentHandLasers[0].color;
|
||||
glowColors[1] = _presentHandLasers[1].color;
|
||||
glProgramUniform4fv(GetName(*_overlayProgram), _overlayUniforms.glowColors, 2, &glowColors[0].r);
|
||||
}
|
||||
}
|
||||
|
||||
_sphereSection->Use();
|
||||
|
@ -634,7 +461,7 @@ void HmdDisplayPlugin::internalPresent() {
|
|||
glClearColor(0, 0, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glViewport(targetViewportPosition.x, targetViewportPosition.y, targetViewportSize.x, targetViewportSize.y);
|
||||
glUniform1i(PREVIEW_TEXTURE_LOCATION, 0);
|
||||
glUniform1i(_previewUniforms.previewTexture, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, _previewTextureID);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
@ -698,6 +525,8 @@ void HmdDisplayPlugin::compositeExtra() {
|
|||
return;
|
||||
}
|
||||
|
||||
updateLaserProgram();
|
||||
|
||||
// Render hand lasers
|
||||
using namespace oglplus;
|
||||
useProgram(_laserProgram);
|
||||
|
@ -739,6 +568,7 @@ void HmdDisplayPlugin::compositeExtra() {
|
|||
handLaserModelMatrices[i] = model;
|
||||
}
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
for_each_eye([&](Eye eye) {
|
||||
eyeViewport(eye);
|
||||
auto eyePose = _currentPresentFrameInfo.presentPose * getEyeToHeadTransform(eye);
|
||||
|
@ -753,4 +583,5 @@ void HmdDisplayPlugin::compositeExtra() {
|
|||
_laserGeometry->Draw();
|
||||
}
|
||||
});
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
|
|
@ -61,15 +61,6 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
ProgramPtr _overlayProgram;
|
||||
struct OverlayUniforms {
|
||||
int32_t mvp { -1 };
|
||||
int32_t alpha { -1 };
|
||||
int32_t glowPoints { -1 };
|
||||
int32_t resolution { -1 };
|
||||
int32_t radius { -1 };
|
||||
} _overlayUniforms;
|
||||
|
||||
Transform _uiModelTransform;
|
||||
std::array<HandLaserInfo, 2> _handLasers;
|
||||
std::array<glm::mat4, 2> _handPoses;
|
||||
|
@ -82,8 +73,6 @@ protected:
|
|||
std::array<glm::mat4, 2> _eyeProjections;
|
||||
std::array<glm::mat4, 2> _eyeInverseProjections;
|
||||
|
||||
|
||||
|
||||
glm::mat4 _cullingProjection;
|
||||
glm::uvec2 _renderTargetSize;
|
||||
float _ipd { 0.064f };
|
||||
|
@ -103,23 +92,49 @@ protected:
|
|||
FrameInfo _currentRenderFrameInfo;
|
||||
|
||||
private:
|
||||
void updateGlowProgram();
|
||||
void updateOverlayProgram();
|
||||
void updateLaserProgram();
|
||||
void updateReprojectionProgram();
|
||||
|
||||
bool _enablePreview { false };
|
||||
bool _monoPreview { true };
|
||||
bool _enableReprojection { true };
|
||||
bool _firstPreview { true };
|
||||
|
||||
ProgramPtr _overlayProgram;
|
||||
struct OverlayUniforms {
|
||||
int32_t mvp { -1 };
|
||||
int32_t alpha { -1 };
|
||||
int32_t glowColors { -1 };
|
||||
int32_t glowPoints { -1 };
|
||||
int32_t resolution { -1 };
|
||||
int32_t radius { -1 };
|
||||
} _overlayUniforms;
|
||||
|
||||
ProgramPtr _previewProgram;
|
||||
struct PreviewUniforms {
|
||||
int32_t previewTexture { -1 };
|
||||
} _previewUniforms;
|
||||
|
||||
float _previewAspect { 0 };
|
||||
GLuint _previewTextureID { 0 };
|
||||
glm::uvec2 _prevWindowSize { 0, 0 };
|
||||
qreal _prevDevicePixelRatio { 0 };
|
||||
|
||||
ProgramPtr _reprojectionProgram;
|
||||
struct ReprojectionUniforms {
|
||||
int32_t reprojectionMatrix { -1 };
|
||||
int32_t inverseProjectionMatrix { -1 };
|
||||
int32_t projectionMatrix { -1 };
|
||||
} _reprojectionUniforms;
|
||||
|
||||
ShapeWrapperPtr _sphereSection;
|
||||
|
||||
ProgramPtr _laserProgram;
|
||||
struct LaserUniforms {
|
||||
int32_t mvp { -1 };
|
||||
int32_t color { -1 };
|
||||
} _laserUniforms;
|
||||
ShapeWrapperPtr _laserGeometry;
|
||||
};
|
||||
|
||||
|
|
|
@ -87,6 +87,36 @@ ProgramPtr loadCubemapShader() {
|
|||
return result;
|
||||
}
|
||||
|
||||
void compileProgram(ProgramPtr & result, const std::string& vs, const std::string& gs, const std::string& fs) {
|
||||
using namespace oglplus;
|
||||
try {
|
||||
result = std::make_shared<Program>();
|
||||
// attach the shaders to the program
|
||||
result->AttachShader(
|
||||
VertexShader()
|
||||
.Source(GLSLSource(vs))
|
||||
.Compile()
|
||||
);
|
||||
result->AttachShader(
|
||||
GeometryShader()
|
||||
.Source(GLSLSource(gs))
|
||||
.Compile()
|
||||
);
|
||||
result->AttachShader(
|
||||
FragmentShader()
|
||||
.Source(GLSLSource(fs))
|
||||
.Compile()
|
||||
);
|
||||
result->Link();
|
||||
} catch (ProgramBuildError& err) {
|
||||
Q_UNUSED(err);
|
||||
qWarning() << err.Log().c_str();
|
||||
Q_ASSERT_X(false, "compileProgram", "Failed to build shader program");
|
||||
qFatal("%s", (const char*)err.Message);
|
||||
result.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void compileProgram(ProgramPtr & result, const std::string& vs, const std::string& fs) {
|
||||
using namespace oglplus;
|
||||
try {
|
||||
|
|
|
@ -62,6 +62,8 @@ using Mat4Uniform = oglplus::Uniform<mat4>;
|
|||
ProgramPtr loadDefaultShader();
|
||||
ProgramPtr loadCubemapShader();
|
||||
void compileProgram(ProgramPtr & result, const std::string& vs, const std::string& fs);
|
||||
void compileProgram(ProgramPtr & result, const std::string& vs, const std::string& gs, const std::string& fs);
|
||||
|
||||
ShapeWrapperPtr loadSkybox(ProgramPtr program);
|
||||
ShapeWrapperPtr loadPlane(ProgramPtr program, float aspect = 1.0f);
|
||||
ShapeWrapperPtr loadSphereSection(ProgramPtr program, float fov = PI / 3.0f * 2.0f, float aspect = 16.0f / 9.0f, int slices = 128, int stacks = 128);
|
||||
|
|
Loading…
Reference in a new issue