Merge pull request #8280 from samcake/skin

Update the upstream skin with master changes and bug fixes for skin
This commit is contained in:
samcake 2016-07-19 13:43:45 -07:00 committed by GitHub
commit 91a0b86d40
36 changed files with 480 additions and 343 deletions

View file

@ -1,19 +1,31 @@
include(ExternalProject) include(ExternalProject)
include(SelectLibraryConfigurations) include(SelectLibraryConfigurations)
set(EXTERNAL_NAME HiFiAudioCodec) set(EXTERNAL_NAME hifiAudioCodec)
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
ExternalProject_Add( if (WIN32 OR APPLE)
${EXTERNAL_NAME} ExternalProject_Add(
URL https://s3.amazonaws.com/hifi-public/dependencies/codecSDK-1.zip ${EXTERNAL_NAME}
URL_MD5 23ec3fe51eaa155ea159a4971856fc13 URL http://s3.amazonaws.com/hifi-public/dependencies/codecSDK-1.zip
CONFIGURE_COMMAND "" URL_MD5 23ec3fe51eaa155ea159a4971856fc13
BUILD_COMMAND "" CONFIGURE_COMMAND ""
INSTALL_COMMAND "" BUILD_COMMAND ""
LOG_DOWNLOAD 1 INSTALL_COMMAND ""
) LOG_DOWNLOAD 1
)
elseif(NOT ANDROID)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://s3.amazonaws.com/hifi-public/dependencies/codecSDK-linux.zip
URL_MD5 7d37914a18aa4de971d2f45dd3043bde
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
LOG_DOWNLOAD 1
)
endif()
# Hide this external target (for ide users) # Hide this external target (for ide users)
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
@ -23,11 +35,9 @@ ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE TYPE INTERNAL) set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE TYPE INTERNAL)
if (WIN32) if (WIN32)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/audio.lib CACHE TYPE INTERNAL) set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/audio.lib CACHE TYPE INTERNAL)
elseif(APPLE) elseif(APPLE)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/libaudio.a CACHE TYPE INTERNAL) set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/libaudio.a CACHE TYPE INTERNAL)
elseif(NOT ANDROID) elseif(NOT ANDROID)
# FIXME need to account for different architectures set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/libaudio.a CACHE TYPE INTERNAL)
#set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/linux64/audio.so CACHE TYPE INTERNAL)
endif() endif()

View file

@ -43,4 +43,4 @@ macro(ADD_DEPENDENCY_EXTERNAL_PROJECTS)
endforeach() endforeach()
endmacro() endmacro()

View file

@ -37,7 +37,7 @@ macro(SETUP_HIFI_CLIENT_SERVER_PLUGIN)
${CLIENT_PLUGIN_FULL_PATH} ${CLIENT_PLUGIN_FULL_PATH}
) )
# copy the client plugin binaries # copy the client plugin binaries
add_custom_command(TARGET ${DIR} POST_BUILD add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy COMMAND "${CMAKE_COMMAND}" -E copy
"$<TARGET_FILE:${TARGET_NAME}>" "$<TARGET_FILE:${TARGET_NAME}>"
${CLIENT_PLUGIN_FULL_PATH} ${CLIENT_PLUGIN_FULL_PATH}
@ -50,7 +50,7 @@ macro(SETUP_HIFI_CLIENT_SERVER_PLUGIN)
${SERVER_PLUGIN_FULL_PATH} ${SERVER_PLUGIN_FULL_PATH}
) )
# copy the server plugin binaries # copy the server plugin binaries
add_custom_command(TARGET ${DIR} POST_BUILD add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy COMMAND "${CMAKE_COMMAND}" -E copy
"$<TARGET_FILE:${TARGET_NAME}>" "$<TARGET_FILE:${TARGET_NAME}>"
${SERVER_PLUGIN_FULL_PATH} ${SERVER_PLUGIN_FULL_PATH}

View file

@ -305,6 +305,8 @@ public:
// Don't actually crash in debug builds, in case this apparent deadlock is simply from // Don't actually crash in debug builds, in case this apparent deadlock is simply from
// the developer actively debugging code // the developer actively debugging code
#ifdef NDEBUG #ifdef NDEBUG
deadlockDetectionCrash(); deadlockDetectionCrash();
#endif #endif
} }

View file

@ -207,8 +207,10 @@ void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) {
} }
withWriteLock([&]{ withWriteLock([&]{
if (_previousSet) { if (_previousSet &&
_positionalTarget != _previousPositionalTarget) { // don't average in a zero velocity if we get the same data
glm::vec3 oneFrameVelocity = (_positionalTarget - _previousPositionalTarget) / deltaTimeStep; glm::vec3 oneFrameVelocity = (_positionalTarget - _previousPositionalTarget) / deltaTimeStep;
_measuredLinearVelocities[_measuredLinearVelocitiesIndex++] = oneFrameVelocity; _measuredLinearVelocities[_measuredLinearVelocitiesIndex++] = oneFrameVelocity;
if (_measuredLinearVelocitiesIndex >= AvatarActionHold::velocitySmoothFrames) { if (_measuredLinearVelocitiesIndex >= AvatarActionHold::velocitySmoothFrames) {
_measuredLinearVelocitiesIndex = 0; _measuredLinearVelocitiesIndex = 0;
@ -228,9 +230,9 @@ void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) {
// 3 -- ignore i of 0 1 2 // 3 -- ignore i of 0 1 2
// 4 -- ignore i of 1 2 3 // 4 -- ignore i of 1 2 3
// 5 -- ignore i of 2 3 4 // 5 -- ignore i of 2 3 4
if ((i + 1) % 6 == _measuredLinearVelocitiesIndex || if ((i + 1) % AvatarActionHold::velocitySmoothFrames == _measuredLinearVelocitiesIndex ||
(i + 2) % 6 == _measuredLinearVelocitiesIndex || (i + 2) % AvatarActionHold::velocitySmoothFrames == _measuredLinearVelocitiesIndex ||
(i + 3) % 6 == _measuredLinearVelocitiesIndex) { (i + 3) % AvatarActionHold::velocitySmoothFrames == _measuredLinearVelocitiesIndex) {
continue; continue;
} }
measuredLinearVelocity += _measuredLinearVelocities[i]; measuredLinearVelocity += _measuredLinearVelocities[i];

View file

@ -862,6 +862,9 @@ void AudioClient::mixLocalAudioInjectors(int16_t* inputBuffer) {
static const float INT16_TO_FLOAT_SCALE_FACTOR = 1/32768.0f; static const float INT16_TO_FLOAT_SCALE_FACTOR = 1/32768.0f;
bool injectorsHaveData = false; bool injectorsHaveData = false;
// lock the injector vector
Lock lock(_injectorsMutex);
for (AudioInjector* injector : getActiveLocalAudioInjectors()) { for (AudioInjector* injector : getActiveLocalAudioInjectors()) {
if (injector->getLocalBuffer()) { if (injector->getLocalBuffer()) {
@ -871,6 +874,7 @@ void AudioClient::mixLocalAudioInjectors(int16_t* inputBuffer) {
AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL; AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL;
// get one frame from the injector (mono or stereo) // get one frame from the injector (mono or stereo)
memset(_scratchBuffer, 0, sizeof(_scratchBuffer));
if (0 < injector->getLocalBuffer()->readData((char*)_scratchBuffer, samplesToRead)) { if (0 < injector->getLocalBuffer()->readData((char*)_scratchBuffer, samplesToRead)) {
injectorsHaveData = true; injectorsHaveData = true;
@ -894,14 +898,14 @@ void AudioClient::mixLocalAudioInjectors(int16_t* inputBuffer) {
} else { } else {
qDebug() << "injector has no more data, marking finished for removal"; qDebug() << "injector has no more data, marking finished for removal";
injector->finish(); injector->finishLocalInjection();
injectorsToRemove.append(injector); injectorsToRemove.append(injector);
} }
} else { } else {
qDebug() << "injector has no local buffer, marking as finished for removal"; qDebug() << "injector has no local buffer, marking as finished for removal";
injector->finish(); injector->finishLocalInjection();
injectorsToRemove.append(injector); injectorsToRemove.append(injector);
} }
} }
@ -1003,6 +1007,7 @@ void AudioClient::setIsStereoInput(bool isStereoInput) {
bool AudioClient::outputLocalInjector(bool isStereo, AudioInjector* injector) { bool AudioClient::outputLocalInjector(bool isStereo, AudioInjector* injector) {
Lock lock(_injectorsMutex);
if (injector->getLocalBuffer() && _audioInput ) { if (injector->getLocalBuffer() && _audioInput ) {
// just add it to the vector of active local injectors, if // just add it to the vector of active local injectors, if
// not already there. // not already there.

View file

@ -15,6 +15,7 @@
#include <fstream> #include <fstream>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <mutex>
#include <QtCore/qsystemdetection.h> #include <QtCore/qsystemdetection.h>
#include <QtCore/QByteArray> #include <QtCore/QByteArray>
@ -83,6 +84,9 @@ public:
using AudioPositionGetter = std::function<glm::vec3()>; using AudioPositionGetter = std::function<glm::vec3()>;
using AudioOrientationGetter = std::function<glm::quat()>; using AudioOrientationGetter = std::function<glm::quat()>;
using Mutex = std::mutex;
using Lock = std::unique_lock<Mutex>;
class AudioOutputIODevice : public QIODevice { class AudioOutputIODevice : public QIODevice {
public: public:
AudioOutputIODevice(MixedProcessedAudioStream& receivedAudioStream, AudioClient* audio) : AudioOutputIODevice(MixedProcessedAudioStream& receivedAudioStream, AudioClient* audio) :
@ -219,6 +223,7 @@ private:
float azimuthForSource(const glm::vec3& relativePosition); float azimuthForSource(const glm::vec3& relativePosition);
float gainForSource(float distance, float volume); float gainForSource(float distance, float volume);
Mutex _injectorsMutex;
QByteArray firstInputFrame; QByteArray firstInputFrame;
QAudioInput* _audioInput; QAudioInput* _audioInput;
QAudioFormat _desiredInputFormat; QAudioFormat _desiredInputFormat;

View file

@ -28,6 +28,15 @@
int audioInjectorPtrMetaTypeId = qRegisterMetaType<AudioInjector*>(); int audioInjectorPtrMetaTypeId = qRegisterMetaType<AudioInjector*>();
AudioInjectorState operator& (AudioInjectorState lhs, AudioInjectorState rhs) {
return static_cast<AudioInjectorState>(static_cast<uint8_t>(lhs) & static_cast<uint8_t>(rhs));
};
AudioInjectorState& operator|= (AudioInjectorState& lhs, AudioInjectorState rhs) {
lhs = static_cast<AudioInjectorState>(static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs));
return lhs;
};
AudioInjector::AudioInjector(QObject* parent) : AudioInjector::AudioInjector(QObject* parent) :
QObject(parent) QObject(parent)
{ {
@ -48,6 +57,10 @@ AudioInjector::AudioInjector(const QByteArray& audioData, const AudioInjectorOpt
} }
bool AudioInjector::stateHas(AudioInjectorState state) const {
return (_state & state) == state;
}
void AudioInjector::setOptions(const AudioInjectorOptions& options) { void AudioInjector::setOptions(const AudioInjectorOptions& options) {
// since options.stereo is computed from the audio stream, // since options.stereo is computed from the audio stream,
// we need to copy it from existing options just in case. // we need to copy it from existing options just in case.
@ -56,10 +69,25 @@ void AudioInjector::setOptions(const AudioInjectorOptions& options) {
_options.stereo = currentlyStereo; _options.stereo = currentlyStereo;
} }
void AudioInjector::finishNetworkInjection() {
_state |= AudioInjectorState::NetworkInjectionFinished;
// if we are already finished with local
// injection, then we are finished
if(stateHas(AudioInjectorState::LocalInjectionFinished)) {
finish();
}
}
void AudioInjector::finishLocalInjection() {
_state |= AudioInjectorState::LocalInjectionFinished;
if(_options.localOnly || stateHas(AudioInjectorState::NetworkInjectionFinished)) {
finish();
}
}
void AudioInjector::finish() { void AudioInjector::finish() {
bool shouldDelete = (_state == State::NotFinishedWithPendingDelete); _state |= AudioInjectorState::Finished;
_state = State::Finished;
emit finished(); emit finished();
@ -69,7 +97,7 @@ void AudioInjector::finish() {
_localBuffer = NULL; _localBuffer = NULL;
} }
if (shouldDelete) { if (stateHas(AudioInjectorState::PendingDelete)) {
// we've been asked to delete after finishing, trigger a deleteLater here // we've been asked to delete after finishing, trigger a deleteLater here
deleteLater(); deleteLater();
} }
@ -121,23 +149,27 @@ void AudioInjector::restart() {
_hasSentFirstFrame = false; _hasSentFirstFrame = false;
// check our state to decide if we need extra handling for the restart request // check our state to decide if we need extra handling for the restart request
if (_state == State::Finished) { if (stateHas(AudioInjectorState::Finished)) {
// we finished playing, need to reset state so we can get going again // we finished playing, need to reset state so we can get going again
_hasSetup = false; _hasSetup = false;
_shouldStop = false; _shouldStop = false;
_state = State::NotFinished; _state = AudioInjectorState::NotFinished;
// call inject audio to start injection over again // call inject audio to start injection over again
setupInjection(); setupInjection();
// if we're a local injector, just inject again // inject locally
if (_options.localOnly) { if(injectLocally()) {
injectLocally();
} else { // if not localOnly, wake the AudioInjectorManager back up if it is stuck waiting
// wake the AudioInjectorManager back up if it's stuck waiting if (!_options.localOnly) {
if (!injectorManager->restartFinishedInjector(this)) {
_state = State::Finished; // we're not playing, so reset the state used by isPlaying. if (!injectorManager->restartFinishedInjector(this)) {
_state = AudioInjectorState::Finished; // we're not playing, so reset the state used by isPlaying.
}
} }
} else {
_state = AudioInjectorState::Finished; // we failed to play, so we are finished again
} }
} }
} }
@ -183,7 +215,7 @@ static const int64_t NEXT_FRAME_DELTA_ERROR_OR_FINISHED = -1;
static const int64_t NEXT_FRAME_DELTA_IMMEDIATELY = 0; static const int64_t NEXT_FRAME_DELTA_IMMEDIATELY = 0;
int64_t AudioInjector::injectNextFrame() { int64_t AudioInjector::injectNextFrame() {
if (_state == AudioInjector::State::Finished) { if (stateHas(AudioInjectorState::NetworkInjectionFinished)) {
qDebug() << "AudioInjector::injectNextFrame called but AudioInjector has finished and was not restarted. Returning."; qDebug() << "AudioInjector::injectNextFrame called but AudioInjector has finished and was not restarted. Returning.";
return NEXT_FRAME_DELTA_ERROR_OR_FINISHED; return NEXT_FRAME_DELTA_ERROR_OR_FINISHED;
} }
@ -234,8 +266,10 @@ int64_t AudioInjector::injectNextFrame() {
// pack the stereo/mono type of the stream // pack the stereo/mono type of the stream
audioPacketStream << _options.stereo; audioPacketStream << _options.stereo;
// pack the flag for loopback // pack the flag for loopback. Now, we don't loopback
uchar loopbackFlag = (uchar)true; // and _always_ play locally, so loopbackFlag should be
// false always.
uchar loopbackFlag = (uchar)false;
audioPacketStream << loopbackFlag; audioPacketStream << loopbackFlag;
// pack the position for injected audio // pack the position for injected audio
@ -333,7 +367,7 @@ int64_t AudioInjector::injectNextFrame() {
} }
if (_currentSendOffset >= _audioData.size() && !_options.loop) { if (_currentSendOffset >= _audioData.size() && !_options.loop) {
finish(); finishNetworkInjection();
return NEXT_FRAME_DELTA_ERROR_OR_FINISHED; return NEXT_FRAME_DELTA_ERROR_OR_FINISHED;
} }
@ -372,10 +406,10 @@ void AudioInjector::triggerDeleteAfterFinish() {
return; return;
} }
if (_state == State::Finished) { if (_state == AudioInjectorState::Finished) {
stopAndDeleteLater(); stopAndDeleteLater();
} else { } else {
_state = State::NotFinishedWithPendingDelete; _state |= AudioInjectorState::PendingDelete;
} }
} }
@ -421,7 +455,7 @@ AudioInjector* AudioInjector::playSoundAndDelete(const QByteArray& buffer, const
AudioInjector* sound = playSound(buffer, options, localInterface); AudioInjector* sound = playSound(buffer, options, localInterface);
if (sound) { if (sound) {
sound->_state = AudioInjector::State::NotFinishedWithPendingDelete; sound->_state |= AudioInjectorState::PendingDelete;
} }
return sound; return sound;
@ -438,21 +472,23 @@ AudioInjector* AudioInjector::playSound(const QByteArray& buffer, const AudioInj
// setup parameters required for injection // setup parameters required for injection
injector->setupInjection(); injector->setupInjection();
if (options.localOnly) { // we always inject locally
if (injector->injectLocally()) { //
// local injection succeeded, return the pointer to injector if (!injector->injectLocally()) {
return injector; // failed, so don't bother sending to server
} else { qDebug() << "AudioInjector::playSound failed to inject locally";
// unable to inject locally, return a nullptr return nullptr;
return nullptr;
}
} else {
// attempt to thread the new injector
if (injectorManager->threadInjector(injector)) {
return injector;
} else {
// we failed to thread the new injector (we are at the max number of injector threads)
return nullptr;
}
} }
// if localOnly, we are done, just return injector.
if (options.localOnly) {
return injector;
}
// send off to server for everyone else
if (!injectorManager->threadInjector(injector)) {
// we failed to thread the new injector (we are at the max number of injector threads)
qDebug() << "AudioInjector::playSound failed to thread injector";
}
return injector;
} }

View file

@ -32,24 +32,29 @@
class AbstractAudioInterface; class AbstractAudioInterface;
class AudioInjectorManager; class AudioInjectorManager;
enum class AudioInjectorState : uint8_t {
NotFinished = 0,
Finished = 1,
PendingDelete = 2,
LocalInjectionFinished = 4,
NetworkInjectionFinished = 8
};
AudioInjectorState operator& (AudioInjectorState lhs, AudioInjectorState rhs);
AudioInjectorState& operator|= (AudioInjectorState& lhs, AudioInjectorState rhs);
// In order to make scripting cleaner for the AudioInjector, the script now holds on to the AudioInjector object // In order to make scripting cleaner for the AudioInjector, the script now holds on to the AudioInjector object
// until it dies. // until it dies.
class AudioInjector : public QObject { class AudioInjector : public QObject {
Q_OBJECT Q_OBJECT
public: public:
enum class State : uint8_t {
NotFinished,
NotFinishedWithPendingDelete,
Finished
};
AudioInjector(QObject* parent); AudioInjector(QObject* parent);
AudioInjector(const Sound& sound, const AudioInjectorOptions& injectorOptions); AudioInjector(const Sound& sound, const AudioInjectorOptions& injectorOptions);
AudioInjector(const QByteArray& audioData, const AudioInjectorOptions& injectorOptions); AudioInjector(const QByteArray& audioData, const AudioInjectorOptions& injectorOptions);
bool isFinished() const { return _state == State::Finished; } bool isFinished() const { return (stateHas(AudioInjectorState::Finished)); }
int getCurrentSendOffset() const { return _currentSendOffset; } int getCurrentSendOffset() const { return _currentSendOffset; }
void setCurrentSendOffset(int currentSendOffset) { _currentSendOffset = currentSendOffset; } void setCurrentSendOffset(int currentSendOffset) { _currentSendOffset = currentSendOffset; }
@ -63,6 +68,7 @@ public:
bool isStereo() const { return _options.stereo; } bool isStereo() const { return _options.stereo; }
void setLocalAudioInterface(AbstractAudioInterface* localAudioInterface) { _localAudioInterface = localAudioInterface; } void setLocalAudioInterface(AbstractAudioInterface* localAudioInterface) { _localAudioInterface = localAudioInterface; }
bool stateHas(AudioInjectorState state) const ;
static AudioInjector* playSoundAndDelete(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface); static AudioInjector* playSoundAndDelete(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface);
static AudioInjector* playSound(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface); static AudioInjector* playSound(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface);
static AudioInjector* playSound(SharedSoundPointer sound, const float volume, const float stretchFactor, const glm::vec3 position); static AudioInjector* playSound(SharedSoundPointer sound, const float volume, const float stretchFactor, const glm::vec3 position);
@ -78,8 +84,10 @@ public slots:
void setOptions(const AudioInjectorOptions& options); void setOptions(const AudioInjectorOptions& options);
float getLoudness() const { return _loudness; } float getLoudness() const { return _loudness; }
bool isPlaying() const { return _state == State::NotFinished || _state == State::NotFinishedWithPendingDelete; } bool isPlaying() const { return !stateHas(AudioInjectorState::Finished); }
void finish(); void finish();
void finishLocalInjection();
void finishNetworkInjection();
signals: signals:
void finished(); void finished();
@ -92,7 +100,7 @@ private:
QByteArray _audioData; QByteArray _audioData;
AudioInjectorOptions _options; AudioInjectorOptions _options;
State _state { State::NotFinished }; AudioInjectorState _state { AudioInjectorState::NotFinished };
bool _hasSentFirstFrame { false }; bool _hasSentFirstFrame { false };
bool _hasSetup { false }; bool _hasSetup { false };
bool _shouldStop { false }; bool _shouldStop { false };
@ -111,4 +119,5 @@ private:
friend class AudioInjectorManager; friend class AudioInjectorManager;
}; };
#endif // hifi_AudioInjector_h #endif // hifi_AudioInjector_h

View file

@ -36,7 +36,15 @@ OffscreenGLCanvas::~OffscreenGLCanvas() {
delete _logger; delete _logger;
_logger = nullptr; _logger = nullptr;
} }
_context->doneCurrent(); _context->doneCurrent();
delete _context;
_context = nullptr;
_offscreenSurface->destroy();
delete _offscreenSurface;
_offscreenSurface = nullptr;
} }
bool OffscreenGLCanvas::create(QOpenGLContext* sharedContext) { bool OffscreenGLCanvas::create(QOpenGLContext* sharedContext) {

View file

@ -34,8 +34,8 @@ public:
protected: protected:
std::once_flag _reportOnce; std::once_flag _reportOnce;
QOpenGLContext* _context; QOpenGLContext* _context{ nullptr };
QOffscreenSurface* _offscreenSurface; QOffscreenSurface* _offscreenSurface{ nullptr };
QOpenGLDebugLogger* _logger{ nullptr }; QOpenGLDebugLogger* _logger{ nullptr };
}; };

View file

@ -28,16 +28,17 @@ QOpenGLContext* QOpenGLContextWrapper::currentContext() {
return QOpenGLContext::currentContext(); return QOpenGLContext::currentContext();
} }
QOpenGLContextWrapper::QOpenGLContextWrapper() : QOpenGLContextWrapper::QOpenGLContextWrapper() :
_context(new QOpenGLContext) _ownContext(true), _context(new QOpenGLContext) { }
{
}
QOpenGLContextWrapper::QOpenGLContextWrapper(QOpenGLContext* context) : QOpenGLContextWrapper::QOpenGLContextWrapper(QOpenGLContext* context) :
_context(context) _context(context) { }
{
QOpenGLContextWrapper::~QOpenGLContextWrapper() {
if (_ownContext) {
delete _context;
_context = nullptr;
}
} }
void QOpenGLContextWrapper::setFormat(const QSurfaceFormat& format) { void QOpenGLContextWrapper::setFormat(const QSurfaceFormat& format) {

View file

@ -23,6 +23,7 @@ class QOpenGLContextWrapper {
public: public:
QOpenGLContextWrapper(); QOpenGLContextWrapper();
QOpenGLContextWrapper(QOpenGLContext* context); QOpenGLContextWrapper(QOpenGLContext* context);
virtual ~QOpenGLContextWrapper();
void setFormat(const QSurfaceFormat& format); void setFormat(const QSurfaceFormat& format);
bool create(); bool create();
void swapBuffers(QSurface* surface); void swapBuffers(QSurface* surface);
@ -40,6 +41,7 @@ public:
private: private:
bool _ownContext { false };
QOpenGLContext* _context { nullptr }; QOpenGLContext* _context { nullptr };
}; };

View file

@ -187,7 +187,11 @@ GLTexture::~GLTexture() {
} }
} }
Backend::decrementTextureGPUCount(); if (_id) {
glDeleteTextures(1, &_id);
const_cast<GLuint&>(_id) = 0;
Backend::decrementTextureGPUCount();
}
Backend::updateTextureGPUMemoryUsage(_size, 0); Backend::updateTextureGPUMemoryUsage(_size, 0);
Backend::updateTextureGPUVirtualMemoryUsage(_virtualSize, 0); Backend::updateTextureGPUVirtualMemoryUsage(_virtualSize, 0);
} }

View file

@ -0,0 +1,61 @@
<!
// PackedNormal.slh
// libraries/gpu/src
//
// Created by Sam Gateau on 7/19/16.
// Copyright 2013 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
!>
<@if not PACKED_NORMAL_SLH@>
<@def PACKED_NORMAL_SLH@>
vec2 signNotZero(vec2 v) {
return vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);
}
vec2 float32x3_to_oct(in vec3 v) {
vec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));
return ((v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p);
}
vec3 oct_to_float32x3(in vec2 e) {
vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));
if (v.z < 0) {
v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);
}
return normalize(v);
}
vec3 snorm12x2_to_unorm8x3(vec2 f) {
vec2 u = vec2(round(clamp(f, -1.0, 1.0) * 2047.0 + 2047.0));
float t = floor(u.y / 256.0);
return floor(vec3(
u.x / 16.0,
fract(u.x / 16.0) * 256.0 + t,
u.y - t * 256.0
)) / 255.0;
}
vec2 unorm8x3_to_snorm12x2(vec3 u) {
u *= 255.0;
u.y *= (1.0 / 16.0);
vec2 s = vec2( u.x * 16.0 + floor(u.y),
fract(u.y) * (16.0 * 256.0) + u.z);
return clamp(s * (1.0 / 2047.0) - 1.0, vec2(-1.0), vec2(1.0));
}
// Recommended function to pack/unpack vec3<float> normals to vec3<uint8> rgb with best efficiency
vec3 packNormal(in vec3 n) {
return snorm12x2_to_unorm8x3(float32x3_to_oct(n));
}
vec3 unpackNormal(in vec3 p) {
return oct_to_float32x3(unorm8x3_to_snorm12x2(p));
}
<@endif@>

View file

@ -379,7 +379,6 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren
auto& deferredFramebuffer = inputs.get0(); auto& deferredFramebuffer = inputs.get0();
auto& linearDepthTarget = inputs.get1(); auto& linearDepthTarget = inputs.get1();
auto& surfaceGeometryFramebuffer = inputs.get2(); auto& surfaceGeometryFramebuffer = inputs.get2();
auto& diffusedCurvatureFramebuffer = inputs.get3();
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
batch.enableStereo(false); batch.enableStereo(false);
@ -414,7 +413,7 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren
batch.setResourceTexture(HalfNormal, linearDepthTarget->getHalfNormalTexture()); batch.setResourceTexture(HalfNormal, linearDepthTarget->getHalfNormalTexture());
batch.setResourceTexture(Curvature, surfaceGeometryFramebuffer->getCurvatureTexture()); batch.setResourceTexture(Curvature, surfaceGeometryFramebuffer->getCurvatureTexture());
batch.setResourceTexture(DiffusedCurvature, diffusedCurvatureFramebuffer->getRenderBuffer(0)); batch.setResourceTexture(DiffusedCurvature, surfaceGeometryFramebuffer->getLowCurvatureTexture());
if (DependencyManager::get<DeferredLightingEffect>()->isAmbientOcclusionEnabled()) { if (DependencyManager::get<DeferredLightingEffect>()->isAmbientOcclusionEnabled()) {
batch.setResourceTexture(AmbientOcclusion, framebufferCache->getOcclusionTexture()); batch.setResourceTexture(AmbientOcclusion, framebufferCache->getOcclusionTexture());
} else { } else {

View file

@ -11,6 +11,8 @@
<@if not DEFERRED_BUFFER_SLH@> <@if not DEFERRED_BUFFER_SLH@>
<@def DEFERRED_BUFFER_SLH@> <@def DEFERRED_BUFFER_SLH@>
<@include gpu/PackedNormal.slh@>
// Unpack the metallic-mode value // Unpack the metallic-mode value
const float FRAG_PACK_SHADED_NON_METALLIC = 0.0; const float FRAG_PACK_SHADED_NON_METALLIC = 0.0;
const float FRAG_PACK_SHADED_METALLIC = 0.1; const float FRAG_PACK_SHADED_METALLIC = 0.1;
@ -63,44 +65,7 @@ float packUnlit() {
return FRAG_PACK_UNLIT; return FRAG_PACK_UNLIT;
} }
<!
vec2 signNotZero(vec2 v) {
return vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);
}
vec2 float32x3_to_oct(in vec3 v) {
vec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));
return ((v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p);
}
vec3 oct_to_float32x3(in vec2 e) {
vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));
if (v.z < 0) {
v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);
}
return normalize(v);
}
vec3 snorm12x2_to_unorm8x3(vec2 f) {
vec2 u = vec2(round(clamp(f, -1.0, 1.0) * 2047.0 + 2047.0));
float t = floor(u.y / 256.0);
return floor(vec3(
u.x / 16.0,
fract(u.x / 16.0) * 256.0 + t,
u.y - t * 256.0
)) / 255.0;
}
vec2 unorm8x3_to_snorm12x2(vec3 u) {
u *= 255.0;
u.y *= (1.0 / 16.0);
vec2 s = vec2( u.x * 16.0 + floor(u.y),
fract(u.y) * (16.0 * 256.0) + u.z);
return clamp(s * (1.0 / 2047.0) - 1.0, vec2(-1.0), vec2(1.0));
}
uniform sampler2D normalFittingMap; uniform sampler2D normalFittingMap;
vec3 bestFitNormal(vec3 normal) { vec3 bestFitNormal(vec3 normal) {
@ -119,14 +84,6 @@ vec3 bestFitNormal(vec3 normal) {
return (cN * 0.5 + 0.5); return (cN * 0.5 + 0.5);
} }
!>
vec3 packNormal(in vec3 n) {
return snorm12x2_to_unorm8x3(float32x3_to_oct(n));
}
vec3 unpackNormal(in vec3 p) {
return oct_to_float32x3(unorm8x3_to_snorm12x2(p));
}
<@endif@> <@endif@>

View file

@ -12,7 +12,6 @@
<@def DEFERRED_BUFFER_WRITE_SLH@> <@def DEFERRED_BUFFER_WRITE_SLH@>
<@include DeferredBuffer.slh@> <@include DeferredBuffer.slh@>
<@include LightingModel.slh@>
layout(location = 0) out vec4 _fragColor0; layout(location = 0) out vec4 _fragColor0;
@ -40,7 +39,6 @@ void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness
if (alpha != 1.0) { if (alpha != 1.0) {
discard; discard;
} }
emissive *= isEmissiveEnabled();
_fragColor0 = vec4(albedo, ((scattering > 0.0) ? packScatteringMetallic(metallic) : packShadedMetallic(metallic))); _fragColor0 = vec4(albedo, ((scattering > 0.0) ? packScatteringMetallic(metallic) : packShadedMetallic(metallic)));
_fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0)); _fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0));
_fragColor2 = vec4(((scattering > 0.0) ? vec3(scattering) : emissive), occlusion); _fragColor2 = vec4(((scattering > 0.0) ? vec3(scattering) : emissive), occlusion);
@ -48,7 +46,6 @@ void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness
_fragColor3 = vec4(emissive, 1.0); _fragColor3 = vec4(emissive, 1.0);
} }
void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 albedo, float roughness, float metallic, vec3 fresnel, vec3 lightmap) { void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 albedo, float roughness, float metallic, vec3 fresnel, vec3 lightmap) {
if (alpha != 1.0) { if (alpha != 1.0) {
discard; discard;
@ -57,11 +54,8 @@ void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 albedo, float r
_fragColor0 = vec4(albedo, packLightmappedMetallic(metallic)); _fragColor0 = vec4(albedo, packLightmappedMetallic(metallic));
_fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0)); _fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0));
_fragColor2 = vec4(lightmap, 1.0); _fragColor2 = vec4(lightmap, 1.0);
_fragColor3 = vec4(lightmap * isLightmapEnabled(), 1.0); _fragColor3 = vec4(lightmap * albedo, 1.0);
if (isAlbedoEnabled() > 0.0) {
_fragColor3.rgb *= albedo;
}
} }
void packDeferredFragmentUnlit(vec3 normal, float alpha, vec3 color) { void packDeferredFragmentUnlit(vec3 normal, float alpha, vec3 color) {

View file

@ -448,7 +448,8 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c
batch.setResourceTexture(DEFERRED_BUFFER_CURVATURE_UNIT, surfaceGeometryFramebuffer->getCurvatureTexture()); batch.setResourceTexture(DEFERRED_BUFFER_CURVATURE_UNIT, surfaceGeometryFramebuffer->getCurvatureTexture());
} }
if (lowCurvatureNormalFramebuffer) { if (lowCurvatureNormalFramebuffer) {
batch.setResourceTexture(DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT, lowCurvatureNormalFramebuffer->getRenderBuffer(0)); // batch.setResourceTexture(DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT, lowCurvatureNormalFramebuffer->getRenderBuffer(0));
batch.setResourceTexture(DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT, surfaceGeometryFramebuffer->getLowCurvatureTexture());
} }
if (subsurfaceScatteringResource) { if (subsurfaceScatteringResource) {
batch.setUniformBuffer(SCATTERING_PARAMETERS_BUFFER_SLOT, subsurfaceScatteringResource->getParametersBuffer()); batch.setUniformBuffer(SCATTERING_PARAMETERS_BUFFER_SLOT, subsurfaceScatteringResource->getParametersBuffer());

View file

@ -20,7 +20,7 @@ struct LightingModel {
vec4 _ShowContourObscuranceSpare2; vec4 _ShowContourObscuranceSpare2;
}; };
uniform lightingModelBuffer { uniform lightingModelBuffer{
LightingModel lightingModel; LightingModel lightingModel;
}; };

View file

@ -134,18 +134,12 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
const auto surfaceGeometryPassOutputs = addJob<SurfaceGeometryPass>("SurfaceGeometry", surfaceGeometryPassInputs); const auto surfaceGeometryPassOutputs = addJob<SurfaceGeometryPass>("SurfaceGeometry", surfaceGeometryPassInputs);
const auto surfaceGeometryFramebuffer = surfaceGeometryPassOutputs.getN<SurfaceGeometryPass::Outputs>(0); const auto surfaceGeometryFramebuffer = surfaceGeometryPassOutputs.getN<SurfaceGeometryPass::Outputs>(0);
const auto curvatureFramebuffer = surfaceGeometryPassOutputs.getN<SurfaceGeometryPass::Outputs>(1); const auto curvatureFramebuffer = surfaceGeometryPassOutputs.getN<SurfaceGeometryPass::Outputs>(1);
const auto midCurvatureNormalFramebuffer = surfaceGeometryPassOutputs.getN<SurfaceGeometryPass::Outputs>(2);
const auto lowCurvatureNormalFramebuffer = surfaceGeometryPassOutputs.getN<SurfaceGeometryPass::Outputs>(3);
const auto curvatureRangeTimer = addJob<BeginGPURangeTimer>("BeginCurvatureRangeTimer"); // Simply update the scattering resource
// TODO: Push this 2 diffusion stages into surfaceGeometryPass as they are working together
const auto diffuseCurvaturePassInputs = BlurGaussianDepthAware::Inputs(curvatureFramebuffer, halfLinearDepthTexture).hasVarying();
const auto midCurvatureNormalFramebuffer = addJob<render::BlurGaussianDepthAware>("DiffuseCurvatureMid", diffuseCurvaturePassInputs);
const auto lowCurvatureNormalFramebuffer = addJob<render::BlurGaussianDepthAware>("DiffuseCurvatureLow", diffuseCurvaturePassInputs, true); // THis blur pass generates it s render resource
const auto scatteringResource = addJob<SubsurfaceScattering>("Scattering"); const auto scatteringResource = addJob<SubsurfaceScattering>("Scattering");
addJob<EndGPURangeTimer>("CurvatureRangeTimer", curvatureRangeTimer);
// AO job // AO job
addJob<AmbientOcclusionEffect>("AmbientOcclusion"); addJob<AmbientOcclusionEffect>("AmbientOcclusion");

View file

@ -282,6 +282,10 @@ void SurfaceGeometryFramebuffer::updateLinearDepth(const gpu::TexturePointer& li
void SurfaceGeometryFramebuffer::clear() { void SurfaceGeometryFramebuffer::clear() {
_curvatureFramebuffer.reset(); _curvatureFramebuffer.reset();
_curvatureTexture.reset(); _curvatureTexture.reset();
_lowCurvatureFramebuffer.reset();
_lowCurvatureTexture.reset();
_blurringFramebuffer.reset();
_blurringTexture.reset();
} }
gpu::TexturePointer SurfaceGeometryFramebuffer::getLinearDepthTexture() { gpu::TexturePointer SurfaceGeometryFramebuffer::getLinearDepthTexture() {
@ -293,9 +297,17 @@ void SurfaceGeometryFramebuffer::allocate() {
auto width = _frameSize.x; auto width = _frameSize.x;
auto height = _frameSize.y; auto height = _frameSize.y;
_curvatureTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width >> getResolutionLevel(), height >> getResolutionLevel(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _curvatureTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
_curvatureFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); _curvatureFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
_curvatureFramebuffer->setRenderBuffer(0, _curvatureTexture); _curvatureFramebuffer->setRenderBuffer(0, _curvatureTexture);
_lowCurvatureTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
_lowCurvatureFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
_lowCurvatureFramebuffer->setRenderBuffer(0, _lowCurvatureTexture);
_blurringTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
_blurringFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
_blurringFramebuffer->setRenderBuffer(0, _blurringTexture);
} }
gpu::FramebufferPointer SurfaceGeometryFramebuffer::getCurvatureFramebuffer() { gpu::FramebufferPointer SurfaceGeometryFramebuffer::getCurvatureFramebuffer() {
@ -312,6 +324,34 @@ gpu::TexturePointer SurfaceGeometryFramebuffer::getCurvatureTexture() {
return _curvatureTexture; return _curvatureTexture;
} }
gpu::FramebufferPointer SurfaceGeometryFramebuffer::getLowCurvatureFramebuffer() {
if (!_lowCurvatureFramebuffer) {
allocate();
}
return _lowCurvatureFramebuffer;
}
gpu::TexturePointer SurfaceGeometryFramebuffer::getLowCurvatureTexture() {
if (!_lowCurvatureTexture) {
allocate();
}
return _lowCurvatureTexture;
}
gpu::FramebufferPointer SurfaceGeometryFramebuffer::getBlurringFramebuffer() {
if (!_blurringFramebuffer) {
allocate();
}
return _blurringFramebuffer;
}
gpu::TexturePointer SurfaceGeometryFramebuffer::getBlurringTexture() {
if (!_blurringTexture) {
allocate();
}
return _blurringTexture;
}
void SurfaceGeometryFramebuffer::setResolutionLevel(int resolutionLevel) { void SurfaceGeometryFramebuffer::setResolutionLevel(int resolutionLevel) {
if (resolutionLevel != getResolutionLevel()) { if (resolutionLevel != getResolutionLevel()) {
clear(); clear();
@ -319,15 +359,18 @@ void SurfaceGeometryFramebuffer::setResolutionLevel(int resolutionLevel) {
} }
} }
SurfaceGeometryPass::SurfaceGeometryPass() { SurfaceGeometryPass::SurfaceGeometryPass() :
_diffusePass(false)
{
Parameters parameters; Parameters parameters;
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) &parameters)); _parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) &parameters));
} }
void SurfaceGeometryPass::configure(const Config& config) { void SurfaceGeometryPass::configure(const Config& config) {
const float CM_TO_M = 0.01f;
if ((config.depthThreshold * 100.0f) != getCurvatureDepthThreshold()) { if ((config.depthThreshold * CM_TO_M) != getCurvatureDepthThreshold()) {
_parametersBuffer.edit<Parameters>().curvatureInfo.x = config.depthThreshold * 100.0f; _parametersBuffer.edit<Parameters>().curvatureInfo.x = config.depthThreshold * CM_TO_M;
} }
if (config.basisScale != getCurvatureBasisScale()) { if (config.basisScale != getCurvatureBasisScale()) {
@ -341,7 +384,16 @@ void SurfaceGeometryPass::configure(const Config& config) {
if (!_surfaceGeometryFramebuffer) { if (!_surfaceGeometryFramebuffer) {
_surfaceGeometryFramebuffer = std::make_shared<SurfaceGeometryFramebuffer>(); _surfaceGeometryFramebuffer = std::make_shared<SurfaceGeometryFramebuffer>();
} }
_surfaceGeometryFramebuffer->setResolutionLevel(config.resolutionLevel); _surfaceGeometryFramebuffer->setResolutionLevel(config.resolutionLevel);
if (config.resolutionLevel != getResolutionLevel()) {
_parametersBuffer.edit<Parameters>().resolutionInfo.w = config.resolutionLevel;
}
auto filterRadius = (getResolutionLevel() > 0 ? config.diffuseFilterScale / 2.0f : config.diffuseFilterScale);
_diffusePass.getParameters()->setFilterRadiusScale(filterRadius);
_diffusePass.getParameters()->setDepthThreshold(config.diffuseDepthThreshold);
} }
@ -355,33 +407,53 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c
const auto deferredFramebuffer = inputs.get1(); const auto deferredFramebuffer = inputs.get1();
const auto linearDepthFramebuffer = inputs.get2(); const auto linearDepthFramebuffer = inputs.get2();
auto linearDepthTexture = linearDepthFramebuffer->getHalfLinearDepthTexture();
auto linearDepthTexture = linearDepthFramebuffer->getLinearDepthTexture();
auto normalTexture = deferredFramebuffer->getDeferredNormalTexture();
auto sourceViewport = args->_viewport;
auto curvatureViewport = sourceViewport;
if (_surfaceGeometryFramebuffer->getResolutionLevel() > 0) {
linearDepthTexture = linearDepthFramebuffer->getHalfLinearDepthTexture();
normalTexture = linearDepthFramebuffer->getHalfNormalTexture();
curvatureViewport = curvatureViewport >> _surfaceGeometryFramebuffer->getResolutionLevel();
}
if (!_surfaceGeometryFramebuffer) { if (!_surfaceGeometryFramebuffer) {
_surfaceGeometryFramebuffer = std::make_shared<SurfaceGeometryFramebuffer>(); _surfaceGeometryFramebuffer = std::make_shared<SurfaceGeometryFramebuffer>();
} }
_surfaceGeometryFramebuffer->updateLinearDepth(linearDepthTexture); _surfaceGeometryFramebuffer->updateLinearDepth(linearDepthTexture);
// auto normalTexture = deferredFramebuffer->getDeferredNormalTexture(); auto curvatureFramebuffer = _surfaceGeometryFramebuffer->getCurvatureFramebuffer();
auto normalTexture = linearDepthFramebuffer->getHalfNormalTexture(); auto curvatureTexture = _surfaceGeometryFramebuffer->getCurvatureTexture();
auto curvatureFBO = _surfaceGeometryFramebuffer->getCurvatureFramebuffer();
#ifdef USE_STENCIL_TEST #ifdef USE_STENCIL_TEST
if (curvatureFBO->getDepthStencilBuffer() != deferredFramebuffer->getPrimaryDepthTexture()) { if (curvatureFramebuffer->getDepthStencilBuffer() != deferredFramebuffer->getPrimaryDepthTexture()) {
curvatureFBO->setDepthStencilBuffer(deferredFramebuffer->getPrimaryDepthTexture(), deferredFramebuffer->getPrimaryDepthTexture()->getTexelFormat()); curvatureFramebuffer->setDepthStencilBuffer(deferredFramebuffer->getPrimaryDepthTexture(), deferredFramebuffer->getPrimaryDepthTexture()->getTexelFormat());
} }
#endif #endif
auto curvatureTexture = _surfaceGeometryFramebuffer->getCurvatureTexture();
auto lowCurvatureFramebuffer = _surfaceGeometryFramebuffer->getLowCurvatureFramebuffer();
auto lowCurvatureTexture = _surfaceGeometryFramebuffer->getLowCurvatureTexture();
auto blurringFramebuffer = _surfaceGeometryFramebuffer->getBlurringFramebuffer();
auto blurringTexture = _surfaceGeometryFramebuffer->getBlurringTexture();
outputs.edit0() = _surfaceGeometryFramebuffer; outputs.edit0() = _surfaceGeometryFramebuffer;
outputs.edit1() = curvatureFBO; outputs.edit1() = curvatureFramebuffer;
outputs.edit2() = curvatureFramebuffer;
outputs.edit3() = lowCurvatureFramebuffer;
auto curvaturePipeline = getCurvaturePipeline(); auto curvaturePipeline = getCurvaturePipeline();
auto diffuseVPipeline = _diffusePass.getBlurVPipeline();
auto diffuseHPipeline = _diffusePass.getBlurHPipeline();
auto depthViewport = args->_viewport; _diffusePass.getParameters()->setWidthHeight(curvatureViewport.z, curvatureViewport.w, args->_context->isStereo());
auto curvatureViewport = depthViewport >> 1; glm::ivec2 textureSize(curvatureTexture->getDimensions());
// >> _surfaceGeometryFramebuffer->getResolutionLevel(); _diffusePass.getParameters()->setTexcoordTransform(gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(textureSize, curvatureViewport));
_diffusePass.getParameters()->setDepthPerspective(args->getViewFrustum().getProjection()[1][1]);
_diffusePass.getParameters()->setLinearDepthPosFar(args->getViewFrustum().getFarClip());
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
_gpuTimer.begin(batch); _gpuTimer.begin(batch);
batch.enableStereo(false); batch.enableStereo(false);
@ -390,32 +462,64 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c
batch.setViewTransform(Transform()); batch.setViewTransform(Transform());
batch.setViewportTransform(curvatureViewport); batch.setViewportTransform(curvatureViewport);
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(_surfaceGeometryFramebuffer->getCurvatureFrameSize(), curvatureViewport)); batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(_surfaceGeometryFramebuffer->getSourceFrameSize(), curvatureViewport));
batch.setUniformBuffer(SurfaceGeometryPass_FrameTransformSlot, frameTransform->getFrameTransformBuffer());
batch.setUniformBuffer(SurfaceGeometryPass_ParamsSlot, _parametersBuffer);
// Curvature pass // Curvature pass
batch.setFramebuffer(curvatureFBO); batch.setUniformBuffer(SurfaceGeometryPass_FrameTransformSlot, frameTransform->getFrameTransformBuffer());
batch.setUniformBuffer(SurfaceGeometryPass_ParamsSlot, _parametersBuffer);
// We can avoid the clear by drawing the same clear vallue from the makeCurvature shader. same performances or no worse batch.setFramebuffer(curvatureFramebuffer);
// We can avoid the clear by drawing the same clear vallue from the makeCurvature shader. same performances or no worse
#ifdef USE_STENCIL_TEST #ifdef USE_STENCIL_TEST
// Except if stenciling out // Except if stenciling out
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0)); batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0));
#endif #endif
batch.setPipeline(curvaturePipeline); batch.setPipeline(curvaturePipeline);
batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, linearDepthTexture); batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, linearDepthTexture);
batch.setResourceTexture(SurfaceGeometryPass_NormalMapSlot, normalTexture); batch.setResourceTexture(SurfaceGeometryPass_NormalMapSlot, normalTexture);
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);
batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, nullptr); batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, nullptr);
batch.setResourceTexture(SurfaceGeometryPass_NormalMapSlot, nullptr); batch.setResourceTexture(SurfaceGeometryPass_NormalMapSlot, nullptr);
batch.setUniformBuffer(SurfaceGeometryPass_ParamsSlot, nullptr);
batch.setUniformBuffer(SurfaceGeometryPass_FrameTransformSlot, nullptr);
// Diffusion pass
const int BlurTask_ParamsSlot = 0;
const int BlurTask_SourceSlot = 0;
const int BlurTask_DepthSlot = 1;
batch.setUniformBuffer(BlurTask_ParamsSlot, _diffusePass.getParameters()->_parametersBuffer);
batch.setResourceTexture(BlurTask_DepthSlot, linearDepthTexture);
batch.setFramebuffer(blurringFramebuffer);
batch.setPipeline(diffuseVPipeline);
batch.setResourceTexture(BlurTask_SourceSlot, curvatureTexture);
batch.draw(gpu::TRIANGLE_STRIP, 4);
batch.setFramebuffer(curvatureFramebuffer);
batch.setPipeline(diffuseHPipeline);
batch.setResourceTexture(BlurTask_SourceSlot, blurringTexture);
batch.draw(gpu::TRIANGLE_STRIP, 4);
batch.setFramebuffer(blurringFramebuffer);
batch.setPipeline(diffuseVPipeline);
batch.setResourceTexture(BlurTask_SourceSlot, curvatureTexture);
batch.draw(gpu::TRIANGLE_STRIP, 4);
batch.setFramebuffer(lowCurvatureFramebuffer);
batch.setPipeline(diffuseHPipeline);
batch.setResourceTexture(BlurTask_SourceSlot, blurringTexture);
batch.draw(gpu::TRIANGLE_STRIP, 4);
batch.setResourceTexture(BlurTask_SourceSlot, nullptr);
batch.setResourceTexture(BlurTask_DepthSlot, nullptr);
batch.setUniformBuffer(BlurTask_ParamsSlot, nullptr);
_gpuTimer.end(batch); _gpuTimer.end(batch);
}); });
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig); auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
config->gpuTime = _gpuTimer.getAverage(); config->gpuTime = _gpuTimer.getAverage();
} }

View file

@ -15,6 +15,7 @@
#include <DependencyManager.h> #include <DependencyManager.h>
#include "render/DrawTask.h" #include "render/DrawTask.h"
#include "render/BlurTask.h"
#include "DeferredFrameTransform.h" #include "DeferredFrameTransform.h"
#include "DeferredFramebuffer.h" #include "DeferredFramebuffer.h"
@ -111,12 +112,17 @@ public:
gpu::FramebufferPointer getCurvatureFramebuffer(); gpu::FramebufferPointer getCurvatureFramebuffer();
gpu::TexturePointer getCurvatureTexture(); gpu::TexturePointer getCurvatureTexture();
gpu::FramebufferPointer getLowCurvatureFramebuffer();
gpu::TexturePointer getLowCurvatureTexture();
gpu::FramebufferPointer getBlurringFramebuffer();
gpu::TexturePointer getBlurringTexture();
// Update the source framebuffer size which will drive the allocation of all the other resources. // Update the source framebuffer size which will drive the allocation of all the other resources.
void updateLinearDepth(const gpu::TexturePointer& linearDepthBuffer); void updateLinearDepth(const gpu::TexturePointer& linearDepthBuffer);
gpu::TexturePointer getLinearDepthTexture(); gpu::TexturePointer getLinearDepthTexture();
const glm::ivec2& getSourceFrameSize() const { return _frameSize; } const glm::ivec2& getSourceFrameSize() const { return _frameSize; }
glm::ivec2 getCurvatureFrameSize() const { return _frameSize >> _resolutionLevel; }
void setResolutionLevel(int level); void setResolutionLevel(int level);
int getResolutionLevel() const { return _resolutionLevel; } int getResolutionLevel() const { return _resolutionLevel; }
@ -130,6 +136,12 @@ protected:
gpu::FramebufferPointer _curvatureFramebuffer; gpu::FramebufferPointer _curvatureFramebuffer;
gpu::TexturePointer _curvatureTexture; gpu::TexturePointer _curvatureTexture;
gpu::FramebufferPointer _blurringFramebuffer;
gpu::TexturePointer _blurringTexture;
gpu::FramebufferPointer _lowCurvatureFramebuffer;
gpu::TexturePointer _lowCurvatureTexture;
glm::ivec2 _frameSize; glm::ivec2 _frameSize;
int _resolutionLevel{ 0 }; int _resolutionLevel{ 0 };
}; };
@ -142,6 +154,10 @@ class SurfaceGeometryPassConfig : public render::Job::Config {
Q_PROPERTY(float basisScale MEMBER basisScale NOTIFY dirty) Q_PROPERTY(float basisScale MEMBER basisScale NOTIFY dirty)
Q_PROPERTY(float curvatureScale MEMBER curvatureScale NOTIFY dirty) Q_PROPERTY(float curvatureScale MEMBER curvatureScale NOTIFY dirty)
Q_PROPERTY(int resolutionLevel MEMBER resolutionLevel NOTIFY dirty) Q_PROPERTY(int resolutionLevel MEMBER resolutionLevel NOTIFY dirty)
Q_PROPERTY(float diffuseFilterScale MEMBER diffuseFilterScale NOTIFY dirty)
Q_PROPERTY(float diffuseDepthThreshold MEMBER diffuseDepthThreshold NOTIFY dirty)
Q_PROPERTY(double gpuTime READ getGpuTime) Q_PROPERTY(double gpuTime READ getGpuTime)
public: public:
SurfaceGeometryPassConfig() : render::Job::Config(true) {} SurfaceGeometryPassConfig() : render::Job::Config(true) {}
@ -149,7 +165,9 @@ public:
float depthThreshold{ 5.0f }; // centimeters float depthThreshold{ 5.0f }; // centimeters
float basisScale{ 1.0f }; float basisScale{ 1.0f };
float curvatureScale{ 10.0f }; float curvatureScale{ 10.0f };
int resolutionLevel{ 0 }; int resolutionLevel{ 1 };
float diffuseFilterScale{ 0.2f };
float diffuseDepthThreshold{ 1.0f };
double getGpuTime() { return gpuTime; } double getGpuTime() { return gpuTime; }
@ -162,7 +180,7 @@ signals:
class SurfaceGeometryPass { class SurfaceGeometryPass {
public: public:
using Inputs = render::VaryingSet3<DeferredFrameTransformPointer, DeferredFramebufferPointer, LinearDepthFramebufferPointer>; using Inputs = render::VaryingSet3<DeferredFrameTransformPointer, DeferredFramebufferPointer, LinearDepthFramebufferPointer>;
using Outputs = render::VaryingSet2<SurfaceGeometryFramebufferPointer, gpu::FramebufferPointer>; using Outputs = render::VaryingSet4<SurfaceGeometryFramebufferPointer, gpu::FramebufferPointer, gpu::FramebufferPointer, gpu::FramebufferPointer>;
using Config = SurfaceGeometryPassConfig; using Config = SurfaceGeometryPassConfig;
using JobModel = render::Job::ModelIO<SurfaceGeometryPass, Inputs, Outputs, Config>; using JobModel = render::Job::ModelIO<SurfaceGeometryPass, Inputs, Outputs, Config>;
@ -171,9 +189,11 @@ public:
void configure(const Config& config); void configure(const Config& config);
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs); void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs);
float getCurvatureDepthThreshold() const { return _parametersBuffer.get<Parameters>().curvatureInfo.x; } float getCurvatureDepthThreshold() const { return _parametersBuffer.get<Parameters>().curvatureInfo.x; }
float getCurvatureBasisScale() const { return _parametersBuffer.get<Parameters>().curvatureInfo.y; } float getCurvatureBasisScale() const { return _parametersBuffer.get<Parameters>().curvatureInfo.y; }
float getCurvatureScale() const { return _parametersBuffer.get<Parameters>().curvatureInfo.w; } float getCurvatureScale() const { return _parametersBuffer.get<Parameters>().curvatureInfo.w; }
int getResolutionLevel() const { return (int)_parametersBuffer.get<Parameters>().resolutionInfo.w; }
private: private:
typedef gpu::BufferView UniformBufferView; typedef gpu::BufferView UniformBufferView;
@ -182,7 +202,7 @@ private:
class Parameters { class Parameters {
public: public:
// Resolution info // Resolution info
glm::vec4 resolutionInfo { -1.0f, 0.0f, 0.0f, 0.0f }; glm::vec4 resolutionInfo { 0.0f, 0.0f, 0.0f, 1.0f }; // Default Curvature & Diffusion is running half res
// Curvature algorithm // Curvature algorithm
glm::vec4 curvatureInfo{ 0.0f }; glm::vec4 curvatureInfo{ 0.0f };
@ -190,11 +210,14 @@ private:
}; };
gpu::BufferView _parametersBuffer; gpu::BufferView _parametersBuffer;
SurfaceGeometryFramebufferPointer _surfaceGeometryFramebuffer; SurfaceGeometryFramebufferPointer _surfaceGeometryFramebuffer;
const gpu::PipelinePointer& getCurvaturePipeline(); const gpu::PipelinePointer& getCurvaturePipeline();
gpu::PipelinePointer _curvaturePipeline; gpu::PipelinePointer _curvaturePipeline;
render::BlurGaussianDepthAware _diffusePass;
gpu::RangeTimer _gpuTimer; gpu::RangeTimer _gpuTimer;

View file

@ -13,6 +13,7 @@
// //
<@include DeferredBufferWrite.slh@> <@include DeferredBufferWrite.slh@>
<@include LightingModel.slh@>
<@include model/Material.slh@> <@include model/Material.slh@>
<@include MaterialTextures.slh@> <@include MaterialTextures.slh@>

View file

@ -41,7 +41,7 @@ void main(void) {
#ifdef PROCEDURAL_V1 #ifdef PROCEDURAL_V1
specular = getProceduralColor().rgb; specular = getProceduralColor().rgb;
// Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline // Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline
specular = pow(specular, vec3(2.2)); //specular = pow(specular, vec3(2.2));
emissiveAmount = 1.0; emissiveAmount = 1.0;
#else #else
emissiveAmount = getProceduralColors(diffuse, specular, shininess); emissiveAmount = getProceduralColors(diffuse, specular, shininess);

View file

@ -10,35 +10,11 @@
// //
<@include gpu/PackedNormal.slh@>
uniform sampler2D linearDepthMap; uniform sampler2D linearDepthMap;
uniform sampler2D normalMap; uniform sampler2D normalMap;
vec2 signNotZero(vec2 v) {
return vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);
}
vec3 oct_to_float32x3(in vec2 e) {
vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));
if (v.z < 0) {
v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);
}
return normalize(v);
}
vec2 unorm8x3_to_snorm12x2(vec3 u) {
u *= 255.0;
u.y *= (1.0 / 16.0);
vec2 s = vec2( u.x * 16.0 + floor(u.y),
fract(u.y) * (16.0 * 256.0) + u.z);
return clamp(s * (1.0 / 2047.0) - 1.0, vec2(-1.0), vec2(1.0));
}
vec3 unpackNormal(in vec3 p) {
return oct_to_float32x3(unorm8x3_to_snorm12x2(p));
}
in vec2 varTexCoord0; in vec2 varTexCoord0;
out vec4 outLinearDepth; out vec4 outLinearDepth;
@ -46,43 +22,22 @@ out vec4 outNormal;
void main(void) { void main(void) {
// Gather 2 by 2 quads from texture // Gather 2 by 2 quads from texture
vec4 Zeyes = textureGather(linearDepthMap, varTexCoord0, 0);
// Try different filters for Z
// vec4 Zeyes = textureGather(linearDepthMap, varTexCoord0, 0);
// float Zeye = min(min(Zeyes.x, Zeyes.y), min(Zeyes.z, Zeyes.w));
float Zeye = texture(linearDepthMap, varTexCoord0).x;
vec4 rawNormalsX = textureGather(normalMap, varTexCoord0, 0); vec4 rawNormalsX = textureGather(normalMap, varTexCoord0, 0);
vec4 rawNormalsY = textureGather(normalMap, varTexCoord0, 1); vec4 rawNormalsY = textureGather(normalMap, varTexCoord0, 1);
vec4 rawNormalsZ = textureGather(normalMap, varTexCoord0, 2); vec4 rawNormalsZ = textureGather(normalMap, varTexCoord0, 2);
float Zeye = min(min(Zeyes.x, Zeyes.y), min(Zeyes.z, Zeyes.w));
vec3 normal = vec3(0.0); vec3 normal = vec3(0.0);
normal += unpackNormal(vec3(rawNormalsX[0], rawNormalsY[0], rawNormalsZ[0])); normal += unpackNormal(vec3(rawNormalsX[0], rawNormalsY[0], rawNormalsZ[0]));
normal += unpackNormal(vec3(rawNormalsX[1], rawNormalsY[1], rawNormalsZ[1])); normal += unpackNormal(vec3(rawNormalsX[1], rawNormalsY[1], rawNormalsZ[1]));
normal += unpackNormal(vec3(rawNormalsX[2], rawNormalsY[2], rawNormalsZ[2])); normal += unpackNormal(vec3(rawNormalsX[2], rawNormalsY[2], rawNormalsZ[2]));
normal += unpackNormal(vec3(rawNormalsX[3], rawNormalsY[3], rawNormalsZ[3])); normal += unpackNormal(vec3(rawNormalsX[3], rawNormalsY[3], rawNormalsZ[3]));
/*
ivec2 texpos = ivec2(gl_FragCoord.xy) * 2;
vec4 Zeyes;
Zeyes[0] = texelFetch(linearDepthMap, texpos, 0).x;
Zeyes[1] = texelFetch(linearDepthMap, texpos + ivec2(0, 1), 0).x;
Zeyes[2] = texelFetch(linearDepthMap, texpos + ivec2(1, 0), 0).x;
Zeyes[3] = texelFetch(linearDepthMap, texpos + ivec2(1, 1), 0).x;
vec3 rawNormals[4];
rawNormals[0] = texelFetch(normalMap, texpos, 0).xyz;
rawNormals[1] = texelFetch(normalMap, texpos + ivec2(0, 1), 0).xyz;
rawNormals[2] = texelFetch(normalMap, texpos + ivec2(1, 0), 0).xyz;
rawNormals[3] = texelFetch(normalMap, texpos + ivec2(1, 1), 0).xyz;
float Zeye = min(min(Zeyes.x, Zeyes.y), min(Zeyes.z, Zeyes.w));
vec3 normal = vec3(0.0);
normal += unpackNormal(rawNormals[0]);
normal += unpackNormal(rawNormals[1]);
normal += unpackNormal(rawNormals[2]);
normal += unpackNormal(rawNormals[3]);
*/
normal = normalize(normal); normal = normalize(normal);

View file

@ -12,6 +12,8 @@
<@include DeferredTransform.slh@> <@include DeferredTransform.slh@>
<$declareDeferredFrameTransform()$> <$declareDeferredFrameTransform()$>
<@include gpu/PackedNormal.slh@>
struct SurfaceGeometryParams { struct SurfaceGeometryParams {
// Resolution info // Resolution info
vec4 resolutionInfo; vec4 resolutionInfo;
@ -35,6 +37,10 @@ float getCurvatureScale() {
return params.curvatureInfo.w; return params.curvatureInfo.w;
} }
bool isFullResolution() {
return params.resolutionInfo.w == 0.0;
}
uniform sampler2D linearDepthMap; uniform sampler2D linearDepthMap;
float getZEye(ivec2 pixel) { float getZEye(ivec2 pixel) {
@ -44,29 +50,6 @@ float getZEyeLinear(vec2 texcoord) {
return -texture(linearDepthMap, texcoord).x; return -texture(linearDepthMap, texcoord).x;
} }
vec2 signNotZero(vec2 v) {
return vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);
}
vec3 oct_to_float32x3(in vec2 e) {
vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));
if (v.z < 0) {
v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);
}
return normalize(v);
}
vec2 unorm8x3_to_snorm12x2(vec3 u) {
u *= 255.0;
u.y *= (1.0 / 16.0);
vec2 s = vec2( u.x * 16.0 + floor(u.y),
fract(u.y) * (16.0 * 256.0) + u.z);
return clamp(s * (1.0 / 2047.0) - 1.0, vec2(-1.0), vec2(1.0));
}
vec3 unpackNormal(in vec3 p) {
return oct_to_float32x3(unorm8x3_to_snorm12x2(p));
}
vec2 sideToFrameTexcoord(vec2 side, vec2 texcoordPos) { vec2 sideToFrameTexcoord(vec2 side, vec2 texcoordPos) {
return vec2((texcoordPos.x + side.x) * side.y, texcoordPos.y); return vec2((texcoordPos.x + side.x) * side.y, texcoordPos.y);
} }
@ -78,10 +61,12 @@ vec3 getRawNormal(vec2 texcoord) {
} }
vec3 getWorldNormal(vec2 texcoord) { vec3 getWorldNormal(vec2 texcoord) {
// vec3 rawNormal = getRawNormal(texcoord);
// return unpackNormal(rawNormal);
vec3 rawNormal = getRawNormal(texcoord); vec3 rawNormal = getRawNormal(texcoord);
return normalize((rawNormal - vec3(0.5)) * 2.0); if (isFullResolution()) {
return unpackNormal(rawNormal);
} else {
return normalize((rawNormal - vec3(0.5)) * 2.0);
}
} }
vec3 getWorldNormalDiff(vec2 texcoord, vec2 delta) { vec3 getWorldNormalDiff(vec2 texcoord, vec2 delta) {

View file

@ -258,10 +258,10 @@ void BlurGaussian::run(const SceneContextPointer& sceneContext, const RenderCont
BlurGaussianDepthAware::BlurGaussianDepthAware(bool generateOutputFramebuffer) : BlurGaussianDepthAware::BlurGaussianDepthAware(bool generateOutputFramebuffer, const BlurParamsPointer& params) :
_inOutResources(generateOutputFramebuffer) _inOutResources(generateOutputFramebuffer),
_parameters((params ? params : std::make_shared<BlurParams>()))
{ {
_parameters = std::make_shared<BlurParams>();
} }
gpu::PipelinePointer BlurGaussianDepthAware::getBlurVPipeline() { gpu::PipelinePointer BlurGaussianDepthAware::getBlurVPipeline() {
@ -337,24 +337,23 @@ void BlurGaussianDepthAware::run(const SceneContextPointer& sceneContext, const
auto blurHPipeline = getBlurHPipeline(); auto blurHPipeline = getBlurHPipeline();
auto sourceViewport = args->_viewport; auto sourceViewport = args->_viewport;
auto blurViewport = sourceViewport >> 1;
_parameters->setWidthHeight(blurViewport.z, blurViewport.w, args->_context->isStereo()); _parameters->setWidthHeight(sourceViewport.z, sourceViewport.w, args->_context->isStereo());
glm::ivec2 textureSize(blurringResources.sourceTexture->getDimensions()); glm::ivec2 textureSize(blurringResources.sourceTexture->getDimensions());
_parameters->setTexcoordTransform(gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(textureSize, blurViewport)); _parameters->setTexcoordTransform(gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(textureSize, sourceViewport));
_parameters->setDepthPerspective(args->getViewFrustum().getProjection()[1][1]); _parameters->setDepthPerspective(args->getViewFrustum().getProjection()[1][1]);
_parameters->setLinearDepthPosFar(args->getViewFrustum().getFarClip()); _parameters->setLinearDepthPosFar(args->getViewFrustum().getFarClip());
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false); batch.enableStereo(false);
batch.setViewportTransform(blurViewport); batch.setViewportTransform(sourceViewport);
batch.setUniformBuffer(BlurTask_ParamsSlot, _parameters->_parametersBuffer); batch.setUniformBuffer(BlurTask_ParamsSlot, _parameters->_parametersBuffer);
batch.setResourceTexture(BlurTask_DepthSlot, depthTexture); batch.setResourceTexture(BlurTask_DepthSlot, depthTexture);
batch.setFramebuffer(blurringResources.blurringFramebuffer); batch.setFramebuffer(blurringResources.blurringFramebuffer);
// batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0)); // batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0));
batch.setPipeline(blurVPipeline); batch.setPipeline(blurVPipeline);
batch.setResourceTexture(BlurTask_SourceSlot, blurringResources.sourceTexture); batch.setResourceTexture(BlurTask_SourceSlot, blurringResources.sourceTexture);
@ -362,7 +361,7 @@ void BlurGaussianDepthAware::run(const SceneContextPointer& sceneContext, const
batch.setFramebuffer(blurringResources.finalFramebuffer); batch.setFramebuffer(blurringResources.finalFramebuffer);
if (_inOutResources._generateOutputFramebuffer) { if (_inOutResources._generateOutputFramebuffer) {
// batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0)); // batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0));
} }
batch.setPipeline(blurHPipeline); batch.setPipeline(blurHPipeline);

View file

@ -138,22 +138,22 @@ public:
using Config = BlurGaussianDepthAwareConfig; using Config = BlurGaussianDepthAwareConfig;
using JobModel = Job::ModelIO<BlurGaussianDepthAware, Inputs, gpu::FramebufferPointer, Config>; using JobModel = Job::ModelIO<BlurGaussianDepthAware, Inputs, gpu::FramebufferPointer, Config>;
BlurGaussianDepthAware(bool generateNewOutput = false); BlurGaussianDepthAware(bool generateNewOutput = false, const BlurParamsPointer& params = BlurParamsPointer());
void configure(const Config& config); void configure(const Config& config);
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const Inputs& SourceAndDepth, gpu::FramebufferPointer& blurredFramebuffer); void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const Inputs& SourceAndDepth, gpu::FramebufferPointer& blurredFramebuffer);
protected: const BlurParamsPointer& getParameters() const { return _parameters; }
BlurParamsPointer _parameters;
gpu::PipelinePointer _blurVPipeline;
gpu::PipelinePointer _blurHPipeline;
gpu::PipelinePointer getBlurVPipeline(); gpu::PipelinePointer getBlurVPipeline();
gpu::PipelinePointer getBlurHPipeline(); gpu::PipelinePointer getBlurHPipeline();
protected:
gpu::PipelinePointer _blurVPipeline;
gpu::PipelinePointer _blurHPipeline;
BlurInOutResource _inOutResources; BlurInOutResource _inOutResources;
BlurParamsPointer _parameters;
}; };
} }

View file

@ -126,7 +126,7 @@ vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep
// Accumulate the center sample // Accumulate the center sample
vec4 srcBlurred = gaussianDistributionCurve[0] * sampleCenter; vec4 srcBlurred = gaussianDistributionCurve[0] * sampleCenter;
/* for(int i = 1; i < NUM_TAPS; i++) { for(int i = 1; i < NUM_TAPS; i++) {
// Fetch color and depth for current sample. // Fetch color and depth for current sample.
vec2 sampleCoord = texcoord + (gaussianDistributionOffset[i] * finalStep); vec2 sampleCoord = texcoord + (gaussianDistributionOffset[i] * finalStep);
float srcDepth = texture(depthMap, sampleCoord).x; float srcDepth = texture(depthMap, sampleCoord).x;
@ -139,8 +139,8 @@ vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep
// Accumulate. // Accumulate.
srcBlurred += gaussianDistributionCurve[i] * srcSample; srcBlurred += gaussianDistributionCurve[i] * srcSample;
} }
*/
/*
for(int i = 1; i < NUM_HALF_TAPS; i++) { for(int i = 1; i < NUM_HALF_TAPS; i++) {
// Fetch color and depth for current sample. // Fetch color and depth for current sample.
vec2 texcoordOffset = (gaussianDistributionOffsetHalf[i] * finalStep); vec2 texcoordOffset = (gaussianDistributionOffsetHalf[i] * finalStep);
@ -159,7 +159,7 @@ vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep
// Accumulate. // Accumulate.
srcBlurred += gaussianDistributionCurveHalf[i] * (srcSampleP + srcSampleN); srcBlurred += gaussianDistributionCurveHalf[i] * (srcSampleP + srcSampleN);
} }*/
return srcBlurred; return srcBlurred;
} }

View file

@ -6,15 +6,11 @@
# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html # See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html
# #
if (WIN32 OR APPLE) set(TARGET_NAME hifiCodec)
set(TARGET_NAME hifiCodec) setup_hifi_client_server_plugin()
setup_hifi_client_server_plugin() link_hifi_libraries(audio shared plugins)
add_dependency_external_projects(hifiAudioCodec)
link_hifi_libraries(audio shared plugins) target_include_directories(${TARGET_NAME} PRIVATE ${HIFIAUDIOCODEC_INCLUDE_DIRS})
target_link_libraries(${TARGET_NAME} ${HIFIAUDIOCODEC_LIBRARIES})
add_dependency_external_projects(HiFiAudioCodec) install_beside_console()
target_include_directories(${TARGET_NAME} PRIVATE ${HIFIAUDIOCODEC_INCLUDE_DIRS})
target_link_libraries(${TARGET_NAME} ${HIFIAUDIOCODEC_LIBRARIES})
install_beside_console()
endif()

View file

@ -13,8 +13,7 @@ var qml = Script.resolvePath('surfaceGeometryPass.qml');
var window = new OverlayWindow({ var window = new OverlayWindow({
title: 'Surface Geometry Pass', title: 'Surface Geometry Pass',
source: qml, source: qml,
width: 400, height: 300, width: 400, height: 170,
}); });
window.setPosition(250, 400); window.setPosition(Window.innerWidth - 420, 50 + 550 + 50);
window.closed.connect(function() { Script.stop(); }); window.closed.connect(function() { Script.stop(); });

View file

@ -53,11 +53,6 @@ Item {
prop: "gpuTime", prop: "gpuTime",
label: "SurfaceGeometry", label: "SurfaceGeometry",
color: "#00FFFF" color: "#00FFFF"
},{
object: Render.getConfig("CurvatureRangeTimer"),
prop: "gpuTime",
label: "Curvature",
color: "#00FF00"
}, },
{ {
object: Render.getConfig("RenderDeferred"), object: Render.getConfig("RenderDeferred"),

View file

@ -30,7 +30,6 @@ Column {
model: [ model: [
"Basis Scale:basisScale:2.0:false", "Basis Scale:basisScale:2.0:false",
"Curvature Scale:curvatureScale:100.0:false", "Curvature Scale:curvatureScale:100.0:false",
"Downscale:resolutionLevel:4:true"
] ]
ConfigSlider { ConfigSlider {
label: qsTr(modelData.split(":")[0]) label: qsTr(modelData.split(":")[0])
@ -41,16 +40,16 @@ Column {
min: 0.0 min: 0.0
} }
} }
}
Column{
CheckBox { CheckBox {
text: "Diffuse Curvature Mid" text: "Half Resolution"
checked: true checked: Render.getConfig("SurfaceGeometry")["resolutionLevel"]
onCheckedChanged: { Render.getConfig("DiffuseCurvatureMid").enabled = checked } onCheckedChanged: { Render.getConfig("SurfaceGeometry")["resolutionLevel"] = checked }
} }
Repeater { Repeater {
model: [ "Blur Scale:DiffuseCurvatureMid:filterScale:2.0", "Blur Depth Threshold:DiffuseCurvatureMid:depthThreshold:1.0", "Blur Scale2:DiffuseCurvatureLow:filterScale:2.0", "Blur Depth Threshold 2:DiffuseCurvatureLow:depthThreshold:1.0"] model: [ "Diffusion Scale:SurfaceGeometry:diffuseFilterScale:2.0",
"Diffusion Depth Threshold:SurfaceGeometry:diffuseDepthThreshold:1.0"
]
ConfigSlider { ConfigSlider {
label: qsTr(modelData.split(":")[0]) label: qsTr(modelData.split(":")[0])
integral: false integral: false
@ -60,12 +59,6 @@ Column {
min: 0.0 min: 0.0
} }
} }
CheckBox {
text: "Diffuse Curvature Low"
checked: true
onCheckedChanged: { Render.getConfig("DiffuseCurvatureLow").enabled = checked }
}
} }
} }
} }

View file

@ -34,6 +34,7 @@ var OVERLAY_DATA_HMD = {
color: {red: 255, green: 255, blue: 255}, color: {red: 255, green: 255, blue: 255},
alpha: 1, alpha: 1,
scale: 2, scale: 2,
emissive: true,
isFacingAvatar: true, isFacingAvatar: true,
drawInFront: true drawInFront: true
}; };

View file

@ -202,8 +202,7 @@ CONTROLLER_STATE_MACHINE[STATE_NEAR_GRABBING] = {
CONTROLLER_STATE_MACHINE[STATE_HOLD] = { CONTROLLER_STATE_MACHINE[STATE_HOLD] = {
name: "hold", name: "hold",
enterMethod: "nearGrabbingEnter", enterMethod: "nearGrabbingEnter",
updateMethod: "nearGrabbing", updateMethod: "nearGrabbing"
exitMethod: "holdExit"
}; };
CONTROLLER_STATE_MACHINE[STATE_NEAR_TRIGGER] = { CONTROLLER_STATE_MACHINE[STATE_NEAR_TRIGGER] = {
name: "trigger", name: "trigger",
@ -228,7 +227,7 @@ function colorPow(color, power) {
return { return {
red: Math.pow(color.red / 255.0, power) * 255, red: Math.pow(color.red / 255.0, power) * 255,
green: Math.pow(color.green / 255.0, power) * 255, green: Math.pow(color.green / 255.0, power) * 255,
blue: Math.pow(color.blue / 255.0, power) * 255, blue: Math.pow(color.blue / 255.0, power) * 255
}; };
} }
@ -271,14 +270,12 @@ function propsArePhysical(props) {
return isPhysical; return isPhysical;
} }
// currently disabled. var USE_ATTACH_POINT_SETTINGS = true;
var USE_ATTACH_POINT_SETTINGS = false;
var ATTACH_POINT_SETTINGS = "io.highfidelity.attachPoints"; var ATTACH_POINT_SETTINGS = "io.highfidelity.attachPoints";
function getAttachPointSettings() { function getAttachPointSettings() {
try { try {
var str = Settings.getValue(ATTACH_POINT_SETTINGS); var str = Settings.getValue(ATTACH_POINT_SETTINGS);
print("getAttachPointSettings = " + str);
if (str === "false") { if (str === "false") {
return {}; return {};
} else { } else {
@ -291,7 +288,6 @@ function getAttachPointSettings() {
} }
function setAttachPointSettings(attachPointSettings) { function setAttachPointSettings(attachPointSettings) {
var str = JSON.stringify(attachPointSettings); var str = JSON.stringify(attachPointSettings);
print("setAttachPointSettings = " + str);
Settings.setValue(ATTACH_POINT_SETTINGS, str); Settings.setValue(ATTACH_POINT_SETTINGS, str);
} }
function getAttachPointForHotspotFromSettings(hotspot, hand) { function getAttachPointForHotspotFromSettings(hotspot, hand) {
@ -765,9 +761,8 @@ function MyController(hand) {
} }
}; };
var SEARCH_SPHERE_ALPHA = 0.5;
this.searchSphereOn = function (location, size, color) { this.searchSphereOn = function (location, size, color) {
var rotation = Quat.lookAt(location, Camera.getPosition(), Vec3.UP); var rotation = Quat.lookAt(location, Camera.getPosition(), Vec3.UP);
var brightColor = colorPow(color, 0.06); var brightColor = colorPow(color, 0.06);
if (this.searchSphere === null) { if (this.searchSphere === null) {
@ -790,7 +785,7 @@ function MyController(hand) {
position: location, position: location,
rotation: rotation, rotation: rotation,
innerColor: brightColor, innerColor: brightColor,
outerColor: color, outerColor: color,
innerAlpha: 1.0, innerAlpha: 1.0,
outerAlpha: 0.0, outerAlpha: 0.0,
outerRadius: size * 1.2, outerRadius: size * 1.2,
@ -1961,12 +1956,12 @@ function MyController(hand) {
this.currentObjectRotation = grabbedProperties.rotation; this.currentObjectRotation = grabbedProperties.rotation;
this.currentVelocity = ZERO_VEC; this.currentVelocity = ZERO_VEC;
this.currentAngularVelocity = ZERO_VEC; this.currentAngularVelocity = ZERO_VEC;
this.prevDropDetected = false;
}; };
this.nearGrabbing = function (deltaTime, timestamp) { this.nearGrabbing = function (deltaTime, timestamp) {
var dropDetected = this.dropGestureProcess(deltaTime);
if (this.state == STATE_NEAR_GRABBING && this.triggerSmoothedReleased()) { if (this.state == STATE_NEAR_GRABBING && this.triggerSmoothedReleased()) {
this.callEntityMethodOnGrabbed("releaseGrab"); this.callEntityMethodOnGrabbed("releaseGrab");
this.setState(STATE_OFF, "trigger released"); this.setState(STATE_OFF, "trigger released");
@ -1975,6 +1970,16 @@ function MyController(hand) {
if (this.state == STATE_HOLD) { if (this.state == STATE_HOLD) {
var dropDetected = this.dropGestureProcess(deltaTime);
if (this.triggerSmoothedReleased()) {
this.waitForTriggerRelease = false;
}
if (dropDetected && this.prevDropDetected != dropDetected) {
this.waitForTriggerRelease = true;
}
// highlight the grabbed hotspot when the dropGesture is detected. // highlight the grabbed hotspot when the dropGesture is detected.
if (dropDetected) { if (dropDetected) {
entityPropertiesCache.addEntity(this.grabbedHotspot.entityID); entityPropertiesCache.addEntity(this.grabbedHotspot.entityID);
@ -1982,17 +1987,24 @@ function MyController(hand) {
equipHotspotBuddy.highlightHotspot(this.grabbedHotspot); equipHotspotBuddy.highlightHotspot(this.grabbedHotspot);
} }
if (dropDetected && this.triggerSmoothedGrab()) { if (dropDetected && !this.waitForTriggerRelease && this.triggerSmoothedGrab()) {
this.callEntityMethodOnGrabbed("releaseEquip"); this.callEntityMethodOnGrabbed("releaseEquip");
this.setState(STATE_OFF, "drop gesture detected");
return;
}
if (this.thumbPressed()) { // store the offset attach points into preferences.
this.callEntityMethodOnGrabbed("releaseEquip"); if (USE_ATTACH_POINT_SETTINGS && this.grabbedHotspot && this.grabbedEntity) {
this.setState(STATE_OFF, "drop via thumb press"); var props = Entities.getEntityProperties(this.grabbedEntity, ["localPosition", "localRotation"]);
if (props && props.localPosition && props.localRotation) {
storeAttachPointForHotspotInSettings(this.grabbedHotspot, this.hand, props.localPosition, props.localRotation);
}
}
var grabbedEntity = this.grabbedEntity;
this.release();
this.grabbedEntity = grabbedEntity;
this.setState(STATE_NEAR_GRABBING, "drop gesture detected");
return; return;
} }
this.prevDropDetected = dropDetected;
} }
this.heartBeat(this.grabbedEntity); this.heartBeat(this.grabbedEntity);
@ -2088,22 +2100,6 @@ function MyController(hand) {
} }
}; };
this.holdExit = function () {
// store the offset attach points into preferences.
if (USE_ATTACH_POINT_SETTINGS && this.grabbedHotspot && this.grabbedEntity) {
entityPropertiesCache.addEntity(this.grabbedEntity);
var props = entityPropertiesCache.getProps(this.grabbedEntity);
var entityXform = new Xform(props.rotation, props.position);
var avatarXform = new Xform(MyAvatar.orientation, MyAvatar.position);
var handRot = (this.hand === RIGHT_HAND) ? MyAvatar.getRightPalmRotation() : MyAvatar.getLeftPalmRotation();
var avatarHandPos = (this.hand === RIGHT_HAND) ? MyAvatar.rightHandPosition : MyAvatar.leftHandPosition;
var palmXform = new Xform(handRot, avatarXform.xformPoint(avatarHandPos));
var offsetXform = Xform.mul(palmXform.inv(), entityXform);
storeAttachPointForHotspotInSettings(this.grabbedHotspot, this.hand, offsetXform.pos, offsetXform.rot);
}
};
this.nearTriggerEnter = function () { this.nearTriggerEnter = function () {
this.clearEquipHaptics(); this.clearEquipHaptics();