diff --git a/cmake/macros/AutoScribeShader.cmake b/cmake/macros/AutoScribeShader.cmake index 1d1e5970d9..9c5ad70c78 100755 --- a/cmake/macros/AutoScribeShader.cmake +++ b/cmake/macros/AutoScribeShader.cmake @@ -9,7 +9,6 @@ # macro(AUTOSCRIBE_SHADER) - message(STATUS "Processing shader ${SHADER_FILE}") unset(SHADER_INCLUDE_FILES) # Grab include files foreach(includeFile ${ARGN}) diff --git a/cmake/macros/TargetJson.cmake b/cmake/macros/TargetJson.cmake index 057024cd0a..9262c2ce48 100644 --- a/cmake/macros/TargetJson.cmake +++ b/cmake/macros/TargetJson.cmake @@ -8,6 +8,5 @@ macro(TARGET_JSON) add_dependency_external_projects(json) find_package(JSON REQUIRED) - message("JSON_INCLUDE_DIRS ${JSON_INCLUDE_DIRS}") target_include_directories(${TARGET_NAME} PUBLIC ${JSON_INCLUDE_DIRS}) endmacro() \ No newline at end of file diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2b9233fbde..e2cb9a1dfa 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2664,6 +2664,10 @@ Application::~Application() { void Application::initializeGL() { qCDebug(interfaceapp) << "Created Display Window."; +#ifdef DISABLE_QML + setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity); +#endif + // initialize glut for shape drawing; Qt apparently initializes it on OS X if (_isGLInitialized) { return; @@ -6872,6 +6876,9 @@ bool Application::askToLoadScript(const QString& scriptFilenameOrURL) { shortName = shortName.mid(startIndex, endIndex - startIndex); } +#ifdef DISABLE_QML + DependencyManager::get()->loadScript(scriptFilenameOrURL); +#else QString message = "Would you like to run this script:\n" + shortName; ModalDialogListener* dlg = OffscreenUi::asyncQuestion(getWindow(), "Run Script", message, QMessageBox::Yes | QMessageBox::No); @@ -6886,7 +6893,7 @@ bool Application::askToLoadScript(const QString& scriptFilenameOrURL) { } QObject::disconnect(dlg, &ModalDialogListener::response, this, nullptr); }); - +#endif return true; } diff --git a/libraries/display-plugins/src/display-plugins/InterleavedSrgbToLinear.slf b/libraries/display-plugins/src/display-plugins/InterleavedSrgbToLinear.slf index 5f7b3f3411..17dedce7f9 100644 --- a/libraries/display-plugins/src/display-plugins/InterleavedSrgbToLinear.slf +++ b/libraries/display-plugins/src/display-plugins/InterleavedSrgbToLinear.slf @@ -11,7 +11,7 @@ layout(location=0) in vec2 varTexCoord0; layout(location=0) out vec4 outFragColor; void main(void) { - ivec2 texCoord = ivec2(floor(varTexCoord0 * textureData.textureSize)); + ivec2 texCoord = ivec2(floor(varTexCoord0 * vec2(textureData.textureSize))); texCoord.x /= 2; int row = int(floor(gl_FragCoord.y)); if (row % 2 > 0) { diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 2da5c30dc0..a4a5a34683 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -1609,6 +1609,7 @@ PolyVoxEntityRenderer::PolyVoxEntityRenderer(const EntityItemPointer& entity) : _vertexFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); _vertexFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 12); }); + _params = std::make_shared(sizeof(glm::vec4), nullptr); } ShapeKey PolyVoxEntityRenderer::getShapeKey() { @@ -1671,9 +1672,12 @@ void PolyVoxEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& s void PolyVoxEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { _lastVoxelToWorldMatrix = entity->voxelToWorldMatrix(); + _lastVoxelVolumeSize = entity->getVoxelVolumeSize(); + _params->setSubData(0, vec4(_lastVoxelVolumeSize, 0.0)); graphics::MeshPointer newMesh; entity->withReadLock([&] { newMesh = entity->_mesh; + }); if (newMesh && newMesh->getIndexBuffer()._buffer) { @@ -1686,6 +1690,7 @@ void PolyVoxEntityRenderer::doRender(RenderArgs* args) { return; } + PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render"); gpu::Batch& batch = *args->_batch; @@ -1695,6 +1700,7 @@ void PolyVoxEntityRenderer::doRender(RenderArgs* args) { batch.setInputBuffer(gpu::Stream::POSITION, _mesh->getVertexBuffer()._buffer, 0, sizeof(PolyVox::PositionMaterialNormal)); + // TODO -- should we be setting this? // batch.setInputBuffer(gpu::Stream::NORMAL, mesh->getVertexBuffer()._buffer, // 12, @@ -1710,7 +1716,7 @@ void PolyVoxEntityRenderer::doRender(RenderArgs* args) { } } - batch._glUniform3f(entities_renderer::slot::uniform::PolyvoxVoxelSize, _lastVoxelVolumeSize.x, _lastVoxelVolumeSize.y, _lastVoxelVolumeSize.z); + batch.setUniformBuffer(0, _params); batch.drawIndexed(gpu::TRIANGLES, (gpu::uint32)_mesh->getNumIndices(), 0); } diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index 7afb9b41b4..366a3fdc70 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -187,6 +187,7 @@ private: #endif graphics::MeshPointer _mesh; + gpu::BufferPointer _params; std::array _xyzTextures; glm::vec3 _lastVoxelVolumeSize; glm::mat4 _lastVoxelToWorldMatrix; diff --git a/libraries/entities-renderer/src/entities-renderer/ShaderConstants.h b/libraries/entities-renderer/src/entities-renderer/ShaderConstants.h index 58b0bf5688..d01075846a 100644 --- a/libraries/entities-renderer/src/entities-renderer/ShaderConstants.h +++ b/libraries/entities-renderer/src/entities-renderer/ShaderConstants.h @@ -15,7 +15,6 @@ #define ENTITIES_SHADER_CONSTANTS_H // Polyvox -#define ENTITIES_UNIFORM_POLYVOX_VOXEL_SIZE 0 #define ENTITIES_TEXTURE_POLYVOX_XMAP 0 #define ENTITIES_TEXTURE_POLYVOX_YMAP 1 #define ENTITIES_TEXTURE_POLYVOX_ZMAP 2 @@ -26,17 +25,6 @@ namespace entities_renderer { namespace slot { -namespace uniform { -enum Uniform { - PolyvoxVoxelSize = ENTITIES_UNIFORM_POLYVOX_VOXEL_SIZE, -}; -} - -namespace buffer { -enum Buffer { -}; -} // namespace buffer - namespace texture { enum Texture { PolyvoxXMap = ENTITIES_TEXTURE_POLYVOX_XMAP, diff --git a/libraries/entities-renderer/src/paintStroke_fade.slf b/libraries/entities-renderer/src/paintStroke_fade.slf index 8739c9bb9b..e5f70c8038 100644 --- a/libraries/entities-renderer/src/paintStroke_fade.slf +++ b/libraries/entities-renderer/src/paintStroke_fade.slf @@ -45,7 +45,7 @@ void main(void) { int frontCondition = 1 -int(gl_FrontFacing) * 2; vec3 color = varColor.rgb; packDeferredFragmentTranslucent( - interpolatedNormal * frontCondition, + interpolatedNormal * float(frontCondition), texel.a * varColor.a, polyline.color * texel.rgb + fadeEmissive, vec3(0.01, 0.01, 0.01), diff --git a/libraries/entities-renderer/src/polyvox.slf b/libraries/entities-renderer/src/polyvox.slf index ba2fd7031b..441dfc11e5 100644 --- a/libraries/entities-renderer/src/polyvox.slf +++ b/libraries/entities-renderer/src/polyvox.slf @@ -23,15 +23,22 @@ layout(location=RENDER_UTILS_ATTR_POSITION_WS) in vec4 _worldPosition; layout(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap; layout(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap; layout(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap; -layout(location=ENTITIES_UNIFORM_POLYVOX_VOXEL_SIZE) uniform vec3 voxelVolumeSize; + +struct PolyvoxParams { + vec4 voxelVolumeSize; +}; + +layout(binding=0) uniform polyvoxParamsBuffer { + PolyvoxParams params; +}; void main(void) { vec3 worldNormal = cross(dFdy(_worldPosition.xyz), dFdx(_worldPosition.xyz)); worldNormal = normalize(worldNormal); - float inPositionX = (_worldPosition.x - 0.5) / voxelVolumeSize.x; - float inPositionY = (_worldPosition.y - 0.5) / voxelVolumeSize.y; - float inPositionZ = (_worldPosition.z - 0.5) / voxelVolumeSize.z; + float inPositionX = (_worldPosition.x - 0.5) / params.voxelVolumeSize.x; + float inPositionY = (_worldPosition.y - 0.5) / params.voxelVolumeSize.y; + float inPositionZ = (_worldPosition.z - 0.5) / params.voxelVolumeSize.z; vec4 xyDiffuse = texture(xMap, vec2(-inPositionX, -inPositionY)); vec4 xzDiffuse = texture(yMap, vec2(-inPositionX, inPositionZ)); diff --git a/libraries/entities-renderer/src/polyvox_fade.slf b/libraries/entities-renderer/src/polyvox_fade.slf index 2247e472ea..6e236193aa 100644 --- a/libraries/entities-renderer/src/polyvox_fade.slf +++ b/libraries/entities-renderer/src/polyvox_fade.slf @@ -27,7 +27,13 @@ layout(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap; layout(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap; layout(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap; -layout(location=ENTITIES_UNIFORM_POLYVOX_VOXEL_SIZE) uniform vec3 voxelVolumeSize; +struct PolyvoxParams { + vec4 voxelVolumeSize; +}; + +layout(binding=0) uniform polyvoxParamsBuffer { + PolyvoxParams params; +}; // Declare after all samplers to prevent sampler location mix up with voxel shading (sampler locations are hardcoded in RenderablePolyVoxEntityItem) <$declareFadeFragment()$> @@ -42,9 +48,9 @@ void main(void) { vec3 worldNormal = cross(dFdy(_worldPosition.xyz), dFdx(_worldPosition.xyz)); worldNormal = normalize(worldNormal); - float inPositionX = (_worldPosition.x - 0.5) / voxelVolumeSize.x; - float inPositionY = (_worldPosition.y - 0.5) / voxelVolumeSize.y; - float inPositionZ = (_worldPosition.z - 0.5) / voxelVolumeSize.z; + float inPositionX = (_worldPosition.x - 0.5) / params.voxelVolumeSize.x; + float inPositionY = (_worldPosition.y - 0.5) / params.voxelVolumeSize.y; + float inPositionZ = (_worldPosition.z - 0.5) / params.voxelVolumeSize.z; vec4 xyDiffuse = texture(xMap, vec2(-inPositionX, -inPositionY)); vec4 xzDiffuse = texture(yMap, vec2(-inPositionX, inPositionZ)); diff --git a/libraries/gpu/src/gpu/Color.slh b/libraries/gpu/src/gpu/Color.slh index 384b8bd329..16eb7487ed 100644 --- a/libraries/gpu/src/gpu/Color.slh +++ b/libraries/gpu/src/gpu/Color.slh @@ -31,29 +31,29 @@ vec4 color_sRGBAToLinear(vec4 srgba) { } vec3 color_LinearToYCoCg(vec3 rgb) { - // Y = R/4 + G/2 + B/4 - // Co = R/2 - B/2 - // Cg = -R/4 + G/2 - B/4 - return vec3( - rgb.x/4.0 + rgb.y/2.0 + rgb.z/4.0, - rgb.x/2.0 - rgb.z/2.0, - -rgb.x/4.0 + rgb.y/2.0 - rgb.z/4.0 - ); + // Y = R/4 + G/2 + B/4 + // Co = R/2 - B/2 + // Cg = -R/4 + G/2 - B/4 + return vec3( + rgb.x/4.0 + rgb.y/2.0 + rgb.z/4.0, + rgb.x/2.0 - rgb.z/2.0, + -rgb.x/4.0 + rgb.y/2.0 - rgb.z/4.0 + ); } vec3 color_YCoCgToUnclampedLinear(vec3 ycocg) { - // R = Y + Co - Cg - // G = Y + Cg - // B = Y - Co - Cg - return vec3( - ycocg.x + ycocg.y - ycocg.z, - ycocg.x + ycocg.z, - ycocg.x - ycocg.y - ycocg.z - ); + // R = Y + Co - Cg + // G = Y + Cg + // B = Y - Co - Cg + return vec3( + ycocg.x + ycocg.y - ycocg.z, + ycocg.x + ycocg.z, + ycocg.x - ycocg.y - ycocg.z + ); } vec3 color_YCoCgToLinear(vec3 ycocg) { - return clamp(color_YCoCgToUnclampedLinear(ycocg), vec3(0.0), vec3(1.0)); + return clamp(color_YCoCgToUnclampedLinear(ycocg), vec3(0.0), vec3(1.0)); } <@func declareColorWheel()@> diff --git a/libraries/gpu/src/gpu/DrawColor.slf b/libraries/gpu/src/gpu/DrawColor.slf index 2540d56d69..fdea26fa68 100644 --- a/libraries/gpu/src/gpu/DrawColor.slf +++ b/libraries/gpu/src/gpu/DrawColor.slf @@ -13,12 +13,16 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -<@include gpu/ShaderConstants.h@> +struct DrawColorParams { + vec4 color; +}; -layout(location=GPU_UNIFORM_COLOR) uniform vec4 color; +layout(binding=0) uniform drawColorParamsBuffer { + DrawColorParams params; +}; layout(location=0) out vec4 outFragColor; void main(void) { - outFragColor = color; + outFragColor = params.color; } diff --git a/libraries/gpu/src/gpu/DrawColoredTexture.slf b/libraries/gpu/src/gpu/DrawColoredTexture.slf index 632bf18391..0fe3707b1c 100755 --- a/libraries/gpu/src/gpu/DrawColoredTexture.slf +++ b/libraries/gpu/src/gpu/DrawColoredTexture.slf @@ -13,14 +13,19 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -<@include gpu/ShaderConstants.h@> - layout(binding=0) uniform sampler2D colorMap; -layout(location=GPU_UNIFORM_COLOR) uniform vec4 color; + +struct DrawColorParams { + vec4 color; +}; + +layout(binding=0) uniform drawColorParams { + DrawColorParams params; +}; layout(location=0) in vec2 varTexCoord0; layout(location=0) out vec4 outFragColor; void main(void) { - outFragColor = texture(colorMap, varTexCoord0) * color; + outFragColor = texture(colorMap, varTexCoord0) * params.color; } diff --git a/libraries/gpu/src/gpu/DrawTexcoordRectTransformUnitQuad.slv b/libraries/gpu/src/gpu/DrawTexcoordRectTransformUnitQuad.slv index d401fc40c2..8849cb494a 100755 --- a/libraries/gpu/src/gpu/DrawTexcoordRectTransformUnitQuad.slv +++ b/libraries/gpu/src/gpu/DrawTexcoordRectTransformUnitQuad.slv @@ -21,7 +21,13 @@ <$declareStandardTransform()$> -layout(location=GPU_UNIFORM_TEXCOORD_RECT) uniform vec4 texcoordRect; +struct TexCoordRectParams { + vec4 texcoordRect; +}; + +layout(binding=0) uniform texcoordRectBuffer { + TexCoordRectParams params; +}; layout(location=0) out vec2 varTexCoord0; @@ -39,5 +45,5 @@ void main(void) { TransformObject obj = getTransformObject(); <$transformModelToClipPos(cam, obj, pos, gl_Position)$> - varTexCoord0 = ((pos.xy + 1.0) * 0.5) * texcoordRect.zw + texcoordRect.xy; + varTexCoord0 = ((pos.xy + 1.0) * 0.5) * params.texcoordRect.zw + params.texcoordRect.xy; } diff --git a/libraries/gpu/src/gpu/Noise.slh b/libraries/gpu/src/gpu/Noise.slh index b390945957..d300e71ba9 100644 --- a/libraries/gpu/src/gpu/Noise.slh +++ b/libraries/gpu/src/gpu/Noise.slh @@ -284,14 +284,14 @@ float hifi_noise(in vec2 x) { // https://www.shadertoy.com/view/MdX3Rr // https://en.wikipedia.org/wiki/Fractional_Brownian_motion float hifi_fbm(in vec2 p) { - const mat2 m2 = mat2(0.8, -0.6, 0.6, 0.8); - float f = 0.0; - f += 0.5000 * hifi_noise(p); p = m2 * p * 2.02; - f += 0.2500 * hifi_noise(p); p = m2 * p * 2.03; - f += 0.1250 * hifi_noise(p); p = m2 * p * 2.01; - f += 0.0625 * hifi_noise(p); + const mat2 m2 = mat2(0.8, -0.6, 0.6, 0.8); + float f = 0.0; + f += 0.5000 * hifi_noise(p); p = m2 * p * 2.02; + f += 0.2500 * hifi_noise(p); p = m2 * p * 2.03; + f += 0.1250 * hifi_noise(p); p = m2 * p * 2.01; + f += 0.0625 * hifi_noise(p); - return f / 0.9375; + return f / 0.9375; } <@endif@> \ No newline at end of file diff --git a/libraries/gpu/src/gpu/Paint.slh b/libraries/gpu/src/gpu/Paint.slh index 5f49b20b30..54a1214e12 100644 --- a/libraries/gpu/src/gpu/Paint.slh +++ b/libraries/gpu/src/gpu/Paint.slh @@ -17,7 +17,7 @@ float paintStripe(float value, float offset, float scale, float edge) { float width = fwidth(value); float normalizedWidth = width * scale; - float x0 = (value + offset) * scale - normalizedWidth / 2; + float x0 = (value + offset) * scale - normalizedWidth / 2.0; float x1 = x0 + normalizedWidth; float balance = 1.0 - edge; diff --git a/libraries/gpu/src/gpu/ShaderConstants.h b/libraries/gpu/src/gpu/ShaderConstants.h index dc5879e7ad..13dfd1be9c 100644 --- a/libraries/gpu/src/gpu/ShaderConstants.h +++ b/libraries/gpu/src/gpu/ShaderConstants.h @@ -40,8 +40,6 @@ // OSX seems to have an issue using 14 as an attribute location for passing from the vertex to the fragment shader #define GPU_ATTR_V2F_STEREO_SIDE 8 -#define GPU_UNIFORM_COLOR 101 -#define GPU_UNIFORM_TEXCOORD_RECT 102 #define GPU_UNIFORM_EXTRA0 110 #define GPU_UNIFORM_EXTRA1 111 #define GPU_UNIFORM_EXTRA2 112 @@ -98,8 +96,6 @@ enum Attribute { namespace uniform { enum Uniform { - Color = GPU_UNIFORM_COLOR, - TexCoordRect = GPU_UNIFORM_TEXCOORD_RECT, Extra0 = GPU_UNIFORM_EXTRA0, Extra1 = GPU_UNIFORM_EXTRA1, Extra2 = GPU_UNIFORM_EXTRA2, diff --git a/libraries/gpu/src/gpu/TransformCamera_shared.slh b/libraries/gpu/src/gpu/TransformCamera_shared.slh index 37521d8201..e4a0f8c2cc 100644 --- a/libraries/gpu/src/gpu/TransformCamera_shared.slh +++ b/libraries/gpu/src/gpu/TransformCamera_shared.slh @@ -2,11 +2,11 @@ #ifdef __cplusplus # define _MAT4 Mat4 # define _VEC4 Vec4 -# define _MUTABLE mutable +# define _MUTABLE mutable #else # define _MAT4 mat4 # define _VEC4 vec4 -# define _MUTABLE +# define _MUTABLE #endif struct _TransformCamera { diff --git a/libraries/procedural/src/procedural/ShaderConstants.h b/libraries/procedural/src/procedural/ShaderConstants.h index 1995996c97..bfbf2a2691 100644 --- a/libraries/procedural/src/procedural/ShaderConstants.h +++ b/libraries/procedural/src/procedural/ShaderConstants.h @@ -14,7 +14,6 @@ #ifndef PROCEDURAL_SHADER_CONSTANTS_H #define PROCEDURAL_SHADER_CONSTANTS_H -// Polyvox #define PROCEDURAL_UNIFORM_TIME 200 #define PROCEDURAL_UNIFORM_DATE 201 #define PROCEDURAL_UNIFORM_FRAME_COUNT 202 diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index 2b17ba3c01..17c13df19a 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -29,7 +29,6 @@ namespace ru { - using render_utils::slot::uniform::Uniform; using render_utils::slot::texture::Texture; using render_utils::slot::buffer::Buffer; } @@ -39,13 +38,7 @@ namespace gr { using graphics::slot::buffer::Buffer; } -#define ANTIALIASING_USE_TAA 1 - #if !ANTIALIASING_USE_TAA -#include "fxaa_vert.h" -#include "fxaa_frag.h" -#include "fxaa_blend_frag.h" - Antialiasing::Antialiasing() { _geometryId = DependencyManager::get()->allocateID(); @@ -58,30 +51,9 @@ Antialiasing::~Antialiasing() { } } -const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline(RenderArgs* args) { - int width = args->_viewport.z; - int height = args->_viewport.w; - - if (_antialiasingBuffer && _antialiasingBuffer->getSize() != uvec2(width, height)) { - _antialiasingBuffer.reset(); - } - - if (!_antialiasingBuffer) { - // Link the antialiasing FBO to texture - _antialiasingBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("antialiasing")); - auto format = gpu::Element::COLOR_SRGBA_32; - auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); - _antialiasingTexture = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, defaultSampler); - _antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture); - } - +const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() { if (!_antialiasingPipeline) { - auto vs = fxaa_vert::getShader(); - auto ps = fxaa_frag::getShader(); - gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); - - _texcoordOffsetLoc = program->getUniforms().findLocation("texcoordOffset"); - + gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::fxaa); gpu::StatePointer state = gpu::StatePointer(new gpu::State()); state->setDepthTest(false, false, gpu::LESS_EQUAL); @@ -96,9 +68,7 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline(RenderArgs* ar const gpu::PipelinePointer& Antialiasing::getBlendPipeline() { if (!_blendPipeline) { - auto vs = fxaa_vert::getShader(); - auto ps = fxaa_blend_frag::getShader(); - gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::fxaa_blend); gpu::StatePointer state = gpu::StatePointer(new gpu::State()); state->setDepthTest(false, false, gpu::LESS_EQUAL); PrepareStencil::testNoAA(*state); @@ -119,13 +89,30 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const batch.enableStereo(false); batch.setViewportTransform(args->_viewport); - // FIXME: NEED to simplify that code to avoid all the GeometryCahce call, this is purely pixel manipulation - float fbWidth = renderContext->args->_viewport.z; - float fbHeight = renderContext->args->_viewport.w; - // float sMin = args->_viewport.x / fbWidth; - // float sWidth = args->_viewport.z / fbWidth; - // float tMin = args->_viewport.y / fbHeight; - // float tHeight = args->_viewport.w / fbHeight; + if (!_paramsBuffer) { + _paramsBuffer = std::make_shared(sizeof(glm::vec4), nullptr); + } + + { + int width = args->_viewport.z; + int height = args->_viewport.w; + if (_antialiasingBuffer && _antialiasingBuffer->getSize() != uvec2(width, height)) { + _antialiasingBuffer.reset(); + } + + if (!_antialiasingBuffer) { + // Link the antialiasing FBO to texture + _antialiasingBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("antialiasing")); + auto format = gpu::Element::COLOR_SRGBA_32; + auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); + _antialiasingTexture = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, defaultSampler); + _antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture); + glm::vec2 fbExtent { args->_viewport.z, args->_viewport.w }; + glm::vec2 inverseFbExtent = 1.0f / fbExtent; + _paramsBuffer->setSubData(0, glm::vec4(inverseFbExtent, 0.0, 0.0)); + } + } + glm::mat4 projMat; Transform viewMat; @@ -136,40 +123,18 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const batch.setModelTransform(Transform()); // FXAA step - auto pipeline = getAntialiasingPipeline(renderContext->args); + auto pipeline = getAntialiasingPipeline(); batch.setResourceTexture(0, sourceBuffer->getRenderBuffer(0)); batch.setFramebuffer(_antialiasingBuffer); batch.setPipeline(pipeline); - - // initialize the view-space unpacking uniforms using frustum data - float left, right, bottom, top, nearVal, farVal; - glm::vec4 nearClipPlane, farClipPlane; - - args->getViewFrustum().computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); - - // float depthScale = (farVal - nearVal) / farVal; - // float nearScale = -1.0f / nearVal; - // float depthTexCoordScaleS = (right - left) * nearScale / sWidth; - // float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; - // float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; - // float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; - - batch._glUniform2f(_texcoordOffsetLoc, 1.0f / fbWidth, 1.0f / fbHeight); - - glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f); - glm::vec2 bottomLeft(-1.0f, -1.0f); - glm::vec2 topRight(1.0f, 1.0f); - glm::vec2 texCoordTopLeft(0.0f, 0.0f); - glm::vec2 texCoordBottomRight(1.0f, 1.0f); - DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color, _geometryId); - + batch.setUniformBuffer(0, _paramsBuffer); + batch.draw(gpu::TRIANGLE_STRIP, 4); // Blend step batch.setResourceTexture(0, _antialiasingTexture); batch.setFramebuffer(sourceBuffer); batch.setPipeline(getBlendPipeline()); - - DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color, _geometryId); + batch.draw(gpu::TRIANGLE_STRIP, 4); }); } #else @@ -314,7 +279,11 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const // Must match the bindg point in the fxaa_blend.slf shader batch.setResourceFramebufferSwapChainTexture(0, _antialiasingBuffers, 1); // Disable sharpen if FXAA - batch._glUniform1f(ru::Uniform::TaaSharpenIntensity, _sharpen * _params.get().regionInfo.z); + if (!_blendParamsBuffer) { + _blendParamsBuffer = std::make_shared(sizeof(glm::vec4), nullptr); + } + _blendParamsBuffer->setSubData(0, _sharpen * _params.get().regionInfo.z); + batch.setUniformBuffer(0, _blendParamsBuffer); } batch.draw(gpu::TRIANGLE_STRIP, 4); batch.advance(_antialiasingBuffers); diff --git a/libraries/render-utils/src/AntialiasingEffect.h b/libraries/render-utils/src/AntialiasingEffect.h index 61da352154..936ade043d 100644 --- a/libraries/render-utils/src/AntialiasingEffect.h +++ b/libraries/render-utils/src/AntialiasingEffect.h @@ -134,6 +134,10 @@ signals: #define SET_BIT(bitfield, bitIndex, value) bitfield = ((bitfield) & ~(1 << (bitIndex))) | ((value) << (bitIndex)) #define GET_BIT(bitfield, bitIndex) ((bitfield) & (1 << (bitIndex))) +#define ANTIALIASING_USE_TAA 1 + +#if ANTIALIASING_USE_TAA + struct TAAParams { float nope{ 0.0f }; float blend{ 0.15f }; @@ -186,7 +190,7 @@ private: gpu::FramebufferSwapChainPointer _antialiasingBuffers; gpu::TexturePointer _antialiasingTextures[2]; - + gpu::BufferPointer _blendParamsBuffer; gpu::PipelinePointer _antialiasingPipeline; gpu::PipelinePointer _blendPipeline; gpu::PipelinePointer _debugBlendPipeline; @@ -197,7 +201,7 @@ private: }; -/* +#else class AntiAliasingConfig : public render::Job::Config { Q_OBJECT Q_PROPERTY(bool enabled MEMBER enabled) @@ -219,18 +223,15 @@ public: const gpu::PipelinePointer& getBlendPipeline(); private: - - // Uniforms for AA - gpu::int32 _texcoordOffsetLoc; - gpu::FramebufferPointer _antialiasingBuffer; gpu::TexturePointer _antialiasingTexture; + gpu::BufferPointer _paramsBuffer; gpu::PipelinePointer _antialiasingPipeline; gpu::PipelinePointer _blendPipeline; int _geometryId { 0 }; }; -*/ +#endif #endif // hifi_AntialiasingEffect_h diff --git a/libraries/render-utils/src/BloomEffect.cpp b/libraries/render-utils/src/BloomEffect.cpp index 3a35e736a9..e6217eb825 100644 --- a/libraries/render-utils/src/BloomEffect.cpp +++ b/libraries/render-utils/src/BloomEffect.cpp @@ -184,6 +184,7 @@ void BloomDraw::run(const render::RenderContextPointer& renderContext, const Inp } DebugBloom::DebugBloom() { + _params = std::make_shared(sizeof(glm::vec4), nullptr); } void DebugBloom::configure(const Config& config) { @@ -227,7 +228,8 @@ void DebugBloom::run(const render::RenderContextPointer& renderContext, const In Transform modelTransform; if (_mode == DebugBloomConfig::MODE_ALL_LEVELS) { - batch._glUniform4f(gpu::slot::uniform::TexCoordRect, 0.0f, 0.0f, 1.f, 1.f); + _params->setSubData(0, vec4(0.0f, 0.0f, 1.f, 1.f)); + batch.setUniformBuffer(0, _params); modelTransform = gpu::Framebuffer::evalSubregionTexcoordTransform(framebufferSize, args->_viewport / 2); modelTransform.postTranslate(glm::vec3(-1.0f, 1.0f, 0.0f)); @@ -255,7 +257,8 @@ void DebugBloom::run(const render::RenderContextPointer& renderContext, const In viewport.z /= 2; - batch._glUniform4f(gpu::slot::uniform::TexCoordRect, 0.5f, 0.0f, 0.5f, 1.f); + _params->setSubData(0, vec4(0.5f, 0.0f, 0.5f, 1.f)); + batch.setUniformBuffer(0, _params); modelTransform = gpu::Framebuffer::evalSubregionTexcoordTransform(framebufferSize, viewport); modelTransform.postTranslate(glm::vec3(-1.0f, 0.0f, 0.0f)); diff --git a/libraries/render-utils/src/BloomEffect.h b/libraries/render-utils/src/BloomEffect.h index 7789c70190..12c94bb929 100644 --- a/libraries/render-utils/src/BloomEffect.h +++ b/libraries/render-utils/src/BloomEffect.h @@ -121,6 +121,7 @@ public: private: gpu::PipelinePointer _pipeline; + gpu::BufferPointer _params; DebugBloomConfig::Mode _mode; }; diff --git a/libraries/render-utils/src/BloomThreshold.shared.slh b/libraries/render-utils/src/BloomThreshold.shared.slh index 8aaf8ec311..5ad490a1ca 100644 --- a/libraries/render-utils/src/BloomThreshold.shared.slh +++ b/libraries/render-utils/src/BloomThreshold.shared.slh @@ -8,7 +8,7 @@ struct Parameters { BT_VEC2 _deltaUV; - float _threshold; + float _threshold; int _sampleCount; }; diff --git a/libraries/render-utils/src/BloomThreshold.slf b/libraries/render-utils/src/BloomThreshold.slf index 621aa31622..47a1fb0d9f 100644 --- a/libraries/render-utils/src/BloomThreshold.slf +++ b/libraries/render-utils/src/BloomThreshold.slf @@ -30,7 +30,7 @@ void main(void) { for (int x=0 ; x diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index cbc9b40129..2fe811c97b 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -2104,9 +2104,7 @@ void GeometryCache::useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend) { auto stateNoBlend = std::make_shared(); PrepareStencil::testMaskDrawShape(*stateNoBlend); - auto noBlendPS = gpu::Shader::createVertex(shader::gpu::fragment::DrawTextureOpaque); auto programNoBlend = gpu::Shader::createProgram(shader::render_utils::program::standardDrawTextureNoBlend); - _standardDrawPipelineNoBlend = gpu::Pipeline::create(programNoBlend, stateNoBlend); }); diff --git a/libraries/render-utils/src/Highlight.slh b/libraries/render-utils/src/Highlight.slh index 56a999f508..fe77c38fd5 100644 --- a/libraries/render-utils/src/Highlight.slh +++ b/libraries/render-utils/src/Highlight.slh @@ -22,8 +22,8 @@ layout(binding=RENDER_UTILS_BUFFER_HIGHLIGHT_PARAMS) uniform highlightParamsBuff layout(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_SCENE_DEPTH) uniform sampler2D sceneDepthMap; layout(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_DEPTH) uniform sampler2D highlightedDepthMap; -in vec2 varTexCoord0; -out vec4 outFragColor; +layout(location=0) in vec2 varTexCoord0; +layout(location=0) out vec4 outFragColor; const float FAR_Z = 1.0; const float LINEAR_DEPTH_BIAS = 5e-3; @@ -55,10 +55,10 @@ void main(void) { discard; <@endif@> } else { - vec2 halfTexel = getInvWidthHeight() / 2; + vec2 halfTexel = getInvWidthHeight() / 2.0; vec2 texCoord0 = varTexCoord0+halfTexel; float weight = 0.0; - vec2 deltaUv = params._size / params._blurKernelSize; + vec2 deltaUv = params._size / float(params._blurKernelSize); vec2 lineStartUv = texCoord0 - params._size / 2.0; vec2 uv; int x; @@ -87,7 +87,7 @@ void main(void) { } } - if (intensity > 0) { + if (intensity > 0.0) { // sumOutlineDepth /= intensity; } else { sumOutlineDepth = FAR_Z; diff --git a/libraries/render-utils/src/HighlightEffect.cpp b/libraries/render-utils/src/HighlightEffect.cpp index 7e2e55c768..11326b1120 100644 --- a/libraries/render-utils/src/HighlightEffect.cpp +++ b/libraries/render-utils/src/HighlightEffect.cpp @@ -28,7 +28,6 @@ using namespace render; namespace ru { using render_utils::slot::texture::Texture; using render_utils::slot::buffer::Buffer; - using render_utils::slot::uniform::Uniform; } namespace gr { diff --git a/libraries/render-utils/src/Shadow.slh b/libraries/render-utils/src/Shadow.slh index 85a30d5889..5115a876fe 100644 --- a/libraries/render-utils/src/Shadow.slh +++ b/libraries/render-utils/src/Shadow.slh @@ -45,7 +45,7 @@ struct ShadowSampleOffsets { }; ShadowSampleOffsets evalShadowFilterOffsets(vec4 position) { - float shadowScale = getShadowScale(); + float shadowScale = getShadowScale(); ShadowSampleOffsets offsets; #if SHADOW_SCREEN_SPACE_DITHER @@ -67,10 +67,10 @@ ShadowSampleOffsets evalShadowFilterOffsets(vec4 position) { ivec2 offset = coords & ivec2(1,1); offset.y = (offset.x+offset.y) & 1; - offsets.points[0] = shadowScale * vec3(offset + PCFkernel[0], 0.0); - offsets.points[1] = shadowScale * vec3(offset + PCFkernel[1], 0.0); - offsets.points[2] = shadowScale * vec3(offset + PCFkernel[2], 0.0); - offsets.points[3] = shadowScale * vec3(offset + PCFkernel[3], 0.0); + offsets.points[0] = shadowScale * vec3(vec2(offset) + PCFkernel[0], 0.0); + offsets.points[1] = shadowScale * vec3(vec2(offset) + PCFkernel[1], 0.0); + offsets.points[2] = shadowScale * vec3(vec2(offset) + PCFkernel[2], 0.0); + offsets.points[3] = shadowScale * vec3(vec2(offset) + PCFkernel[3], 0.0); return offsets; } @@ -104,7 +104,7 @@ float evalShadowAttenuation(vec3 worldLightDir, vec4 worldPosition, float viewDe vec3 cascadeMix; bvec4 isPixelOnCascade; int cascadeIndex; - float oneMinusNdotL = 1.0 - clamp(dot(worldLightDir, worldNormal), 0, 1); + float oneMinusNdotL = 1.0 - clamp(dot(worldLightDir, worldNormal), 0.0, 1.0); for (cascadeIndex=0 ; cascadeIndex layout(std140, binding=RENDER_UTILS_BUFFER_SHADOW_PARAMS) uniform shadowTransformBuffer { - ShadowParameters shadow; + ShadowParameters shadow; }; int getShadowCascadeCount() { @@ -30,26 +30,26 @@ float evalShadowFalloff(float depth) { } mat4 getShadowReprojection(int cascadeIndex) { - return shadow.cascades[cascadeIndex].reprojection; + return shadow.cascades[cascadeIndex].reprojection; } float getShadowScale() { - return shadow.invMapSize; + return shadow.invMapSize; } float getShadowFixedBias(int cascadeIndex) { - return shadow.cascades[cascadeIndex].fixedBias; + return shadow.cascades[cascadeIndex].fixedBias; } float getShadowSlopeBias(int cascadeIndex) { - return shadow.cascades[cascadeIndex].slopeBias; + return shadow.cascades[cascadeIndex].slopeBias; } // Compute the texture coordinates from world coordinates vec4 evalShadowTexcoord(int cascadeIndex, vec4 position) { - vec4 shadowCoord = getShadowReprojection(cascadeIndex) * position; - return vec4(shadowCoord.xyz, 1.0); + vec4 shadowCoord = getShadowReprojection(cascadeIndex) * position; + return vec4(shadowCoord.xyz, 1.0); } bool isShadowCascadeProjectedOnPixel(vec4 cascadeTexCoords) { diff --git a/libraries/render-utils/src/Shadows_shared.slh b/libraries/render-utils/src/Shadows_shared.slh index bc8063e018..9cb46587a2 100644 --- a/libraries/render-utils/src/Shadows_shared.slh +++ b/libraries/render-utils/src/Shadows_shared.slh @@ -8,8 +8,8 @@ #define SHADOW_CASCADE_MAX_COUNT 4 struct ShadowTransform { - MAT4 reprojection; - float fixedBias; + MAT4 reprojection; + float fixedBias; float slopeBias; float _padding1; float _padding2; diff --git a/libraries/render-utils/src/TextRenderer3D.cpp b/libraries/render-utils/src/TextRenderer3D.cpp index dd9167d248..8ef0dc0d73 100644 --- a/libraries/render-utils/src/TextRenderer3D.cpp +++ b/libraries/render-utils/src/TextRenderer3D.cpp @@ -70,9 +70,8 @@ void TextRenderer3D::draw(gpu::Batch& batch, float x, float y, const QString& st const glm::vec2& bounds, bool layered) { // The font does all the OpenGL work if (_font) { - // Cache color so that the pointer stays valid. _color = color; - _font->drawString(batch, x, y, str, &_color, _effectType, bounds, layered); + _font->drawString(batch, _drawInfo, str, _color, _effectType, { x, y }, bounds, layered); } } diff --git a/libraries/render-utils/src/TextRenderer3D.h b/libraries/render-utils/src/TextRenderer3D.h index 175802ef6e..6c91411e1d 100644 --- a/libraries/render-utils/src/TextRenderer3D.h +++ b/libraries/render-utils/src/TextRenderer3D.h @@ -15,12 +15,14 @@ #include #include #include +#include namespace gpu { class Batch; } class Font; +#include "text/Font.h" #include "text/EffectType.h" #include "text/FontFamilies.h" @@ -51,7 +53,7 @@ private: // text color glm::vec4 _color; - + Font::DrawInfo _drawInfo; std::shared_ptr _font; }; diff --git a/libraries/render-utils/src/debug_deferred_buffer_shared.slh b/libraries/render-utils/src/debug_deferred_buffer_shared.slh index 2d11a66d61..f5d6797c50 100644 --- a/libraries/render-utils/src/debug_deferred_buffer_shared.slh +++ b/libraries/render-utils/src/debug_deferred_buffer_shared.slh @@ -7,7 +7,7 @@ struct DebugParameters { - INT32 _shadowCascadeIndex; + INT32 _shadowCascadeIndex; }; // <@if 1@> diff --git a/libraries/render-utils/src/deferred_light_limited.slv b/libraries/render-utils/src/deferred_light_limited.slv index fb59b8e78f..1c835aacf7 100644 --- a/libraries/render-utils/src/deferred_light_limited.slv +++ b/libraries/render-utils/src/deferred_light_limited.slv @@ -18,7 +18,8 @@ <$declareStandardTransform()$> -uniform vec4 sphereParam; +// FIXME make into a uniform buffer or push constant if this shader ever comes into use +vec4 sphereParam = vec4(0.0); layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01; @@ -41,7 +42,7 @@ void main(void) { } #endif #endif - _texCoord01.xy = vec4(projected.xy, 0.0, 1.0) * gl_Position.w; + _texCoord01 = vec4(projected.xy, 0.0, 1.0) * gl_Position.w; } else { const float depth = -1.0; //Draw at near plane const vec4 UNIT_QUAD[4] = vec4[4]( @@ -60,7 +61,7 @@ void main(void) { #endif #endif - _texCoord01.xy = vec4((pos.xy + 1.0) * 0.5, 0.0, 1.0); + _texCoord01 = vec4((pos.xy + 1.0) * 0.5, 0.0, 1.0); #ifdef GPU_TRANSFORM_IS_STEREO #ifdef GPU_TRANSFORM_STEREO_SPLIT_SCREEN diff --git a/libraries/render-utils/src/drawWorkloadProxy.slf b/libraries/render-utils/src/drawWorkloadProxy.slf index 32dceab00a..f0bd9d474c 100644 --- a/libraries/render-utils/src/drawWorkloadProxy.slf +++ b/libraries/render-utils/src/drawWorkloadProxy.slf @@ -13,9 +13,9 @@ <@include DeferredBufferWrite.slh@> <@include gpu/Paint.slh@> -in vec4 varColor; -in vec3 varTexcoord; -in vec3 varEyePos; +layout(location=0) in vec4 varColor; +layout(location=1) in vec3 varTexcoord; +layout(location=2) in vec3 varEyePos; void main(void) { if (varColor.w > 0.0) { diff --git a/libraries/render-utils/src/drawWorkloadProxy.slv b/libraries/render-utils/src/drawWorkloadProxy.slv index 28a62070f9..7a01702107 100644 --- a/libraries/render-utils/src/drawWorkloadProxy.slv +++ b/libraries/render-utils/src/drawWorkloadProxy.slv @@ -19,9 +19,9 @@ <$declareWorkloadProxies()$> -out vec4 varColor; -out vec3 varTexcoord; -out vec3 varEyePos; +layout(location=0) out vec4 varColor; +layout(location=1) out vec3 varTexcoord; +layout(location=2) out vec3 varEyePos; void main(void) { const vec4 UNIT_SPRITE[3] = vec4[3]( diff --git a/libraries/render-utils/src/drawWorkloadView.slf b/libraries/render-utils/src/drawWorkloadView.slf index c44dae4a24..b638824204 100644 --- a/libraries/render-utils/src/drawWorkloadView.slf +++ b/libraries/render-utils/src/drawWorkloadView.slf @@ -14,9 +14,9 @@ <@include DeferredBufferWrite.slh@> <@include gpu/Paint.slh@> -in vec4 varColor; -in vec3 varTexcoord; -in vec3 varEyePos; +layout(location=0) in vec4 varColor; +layout(location=1) in vec3 varTexcoord; +layout(location=2) in vec3 varEyePos; void main(void) { if (varColor.w > 0.0) { diff --git a/libraries/render-utils/src/drawWorkloadView.slv b/libraries/render-utils/src/drawWorkloadView.slv index 291a8c86cd..db4a33c450 100644 --- a/libraries/render-utils/src/drawWorkloadView.slv +++ b/libraries/render-utils/src/drawWorkloadView.slv @@ -18,9 +18,9 @@ <@include WorkloadResource.slh@> <$declareWorkloadViews()$> -out vec4 varColor; -out vec3 varTexcoord; -out vec3 varEyePos; +layout(location=0) out vec4 varColor; +layout(location=1) out vec3 varTexcoord; +layout(location=2) out vec3 varEyePos; const int NUM_VERTICES_PER_SEGMENT = 2; const int NUM_SEGMENT_PER_VIEW_REGION = 65; @@ -79,7 +79,7 @@ void main(void) { <$transformModelToEyeDir(cam, obj, originSpaceTan, tanEye)$> lateralDir = normalize(cross(vec3(0.0, 0.0, 1.0), normalize(tanEye))); - posEye.xyz += (0.005 * abs(posEye.z) * (regionID + 1)) * (-1.0 + 2.0 * float(segmentVertexID)) * lateralDir; + posEye.xyz += (0.005 * abs(posEye.z) * float(regionID + 1)) * (-1.0 + 2.0 * float(segmentVertexID)) * lateralDir; varEyePos = posEye.xyz; <$transformEyeToClipPos(cam, posEye, gl_Position)$> diff --git a/libraries/render-utils/src/fxaa.slf b/libraries/render-utils/src/fxaa.slf index 2dddcc795b..f1096a3054 100644 --- a/libraries/render-utils/src/fxaa.slf +++ b/libraries/render-utils/src/fxaa.slf @@ -24,7 +24,9 @@ precision mediump int; layout(binding=0) uniform sampler2D colorTexture; //uniform sampler2D historyTexture; -layout(location=0) uniform vec2 texcoordOffset; + +// FIXME make into a uniform buffer or push constant if this shader ever comes into use +vec2 texcoordOffset = vec2(0.0); layout(location=0) in vec2 varTexCoord0; layout(location=0) out vec4 outFragColor; @@ -66,7 +68,7 @@ void main() { outFragColor.w = 1.0; }*/ - if (gl_FragCoord.x > 800) { + if (gl_FragCoord.x > 800.0) { /* // filter width limit for dependent "two-tap" texture samples float FXAA_SPAN_MAX = 8.0; diff --git a/libraries/render-utils/src/fxaa_blend.slf b/libraries/render-utils/src/fxaa_blend.slf index aca050f047..c051801659 100644 --- a/libraries/render-utils/src/fxaa_blend.slf +++ b/libraries/render-utils/src/fxaa_blend.slf @@ -18,7 +18,14 @@ layout(location=0) in vec2 varTexCoord0; layout(location=0) out vec4 outFragColor; layout(binding=0) uniform sampler2D colorTexture; -layout(location=GPU_UNIFORM_EXTRA0) uniform float sharpenIntensity; + +struct FxaaBlendParams { + vec4 sharpenIntensity; +}; + +layout(binding=0) uniform fxaaBlendParamsBuffer { + FxaaBlendParams params; +}; void main(void) { vec4 pixels[9]; @@ -37,7 +44,7 @@ void main(void) { sharpenedPixel = pixels[4]*6.8 - (pixels[1]+pixels[3]+pixels[5]+pixels[7]) - (pixels[0]+pixels[2]+pixels[6]+pixels[8])*0.7; - vec4 minColor = max(vec4(0), pixels[4]-vec4(0.5)); - vec4 maxColor = pixels[4]+vec4(0.5); - outFragColor = clamp(pixels[4] + sharpenedPixel * sharpenIntensity, minColor, maxColor); + vec4 minColor = max(vec4(0), pixels[4]-vec4(0.5)); + vec4 maxColor = pixels[4]+vec4(0.5); + outFragColor = clamp(pixels[4] + sharpenedPixel * params.sharpenIntensity.x, minColor, maxColor); } diff --git a/libraries/render-utils/src/glowLine.slf b/libraries/render-utils/src/glowLine.slf index 4e80b3358a..c65d8d6488 100644 --- a/libraries/render-utils/src/glowLine.slf +++ b/libraries/render-utils/src/glowLine.slf @@ -22,9 +22,9 @@ void main(void) { float alpha = 1.0 - abs(distanceFromCenter); // Convert from a linear alpha curve to a sharp peaked one - alpha = _color.a * pow(alpha, 10.0); - - // Drop everything where the curve falls off to nearly nothing + alpha = _color.a * pow(alpha, 10.0); + + // Drop everything where the curve falls off to nearly nothing if (alpha <= 0.05) { discard; } diff --git a/libraries/render-utils/src/lightClusters_drawClusterContent.slf b/libraries/render-utils/src/lightClusters_drawClusterContent.slf index 65ae8f423e..27cb838566 100644 --- a/libraries/render-utils/src/lightClusters_drawClusterContent.slf +++ b/libraries/render-utils/src/lightClusters_drawClusterContent.slf @@ -42,7 +42,7 @@ void main(void) { ivec3 cluster = clusterGrid_getCluster(clusterIndex); int numLights = cluster.x + cluster.y; - float numLightsScale = clamp(numLights * 0.05, 0.01, 1.0); + float numLightsScale = clamp(float(numLights) * 0.05, 0.01, 1.0); int clusterOffset = cluster.z; @@ -90,6 +90,6 @@ void main(void) { numLightTouching++; } - _fragColor = vec4(colorRamp(1.0 - (numLightTouching / 12.0f)), (numLightTouching > 0 ? 0.5 + 0.5 * numLightsScale : 0.0)); + _fragColor = vec4(colorRamp(1.0 - (float(numLightTouching) / 12.0f)), (numLightTouching > 0 ? 0.5 + 0.5 * numLightsScale : 0.0)); } diff --git a/libraries/render-utils/src/lightClusters_drawClusterContent.slv b/libraries/render-utils/src/lightClusters_drawClusterContent.slv index d7e4a66a6a..1303cf3926 100644 --- a/libraries/render-utils/src/lightClusters_drawClusterContent.slv +++ b/libraries/render-utils/src/lightClusters_drawClusterContent.slv @@ -56,7 +56,7 @@ void main(void) { ivec3 cluster = clusterGrid_getCluster(gpu_InstanceID()); int numLights = cluster.x + cluster.y; - float numLightsScale = clamp(numLights * 0.1, 0.0, 1.0); + float numLightsScale = clamp(float(numLights) * 0.1, 0.0, 1.0); ivec3 clusterPos = frustumGrid_indexToCluster(gpu_InstanceID()); diff --git a/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slf b/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slf index 4efb60a259..abbd86dd70 100644 --- a/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slf +++ b/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slf @@ -39,7 +39,7 @@ void main(void) { ivec3 cluster = clusterGrid_getCluster(frustumGrid_clusterToIndex(clusterPos)); int numLights = cluster.x + cluster.y; - float numLightsScale = clamp(numLights * 0.05, 0.01, 1.0); + float numLightsScale = clamp(float(numLights) * 0.05, 0.01, 1.0); ivec3 dims = frustumGrid.dims.xyz; diff --git a/libraries/render-utils/src/model_translucent_normal_map.slf b/libraries/render-utils/src/model_translucent_normal_map.slf index 45eee9d160..7ac6982cfa 100644 --- a/libraries/render-utils/src/model_translucent_normal_map.slf +++ b/libraries/render-utils/src/model_translucent_normal_map.slf @@ -87,7 +87,7 @@ void main(void) { 1.0, occlusionTex, fragPositionES, - fragPositionWS, + fragPositionWS, albedo, fresnel, metallic, diff --git a/libraries/render-utils/src/model_translucent_normal_map_fade.slf b/libraries/render-utils/src/model_translucent_normal_map_fade.slf index 2ede2bfbaa..2c182aeb19 100644 --- a/libraries/render-utils/src/model_translucent_normal_map_fade.slf +++ b/libraries/render-utils/src/model_translucent_normal_map_fade.slf @@ -97,7 +97,7 @@ void main(void) { 1.0, occlusionTex, fragPositionES, - fragPositionWS, + fragPositionWS, albedo, fresnel, metallic, diff --git a/libraries/render-utils/src/render-utils/ShaderConstants.h b/libraries/render-utils/src/render-utils/ShaderConstants.h index 6a88a62287..ccf6314a39 100644 --- a/libraries/render-utils/src/render-utils/ShaderConstants.h +++ b/libraries/render-utils/src/render-utils/ShaderConstants.h @@ -43,9 +43,6 @@ #define RENDER_UTILS_BUFFER_AMBIENT_LIGHT 6 #define RENDER_UTILS_BUFFER_LIGHT_INDEX 7 -#define RENDER_UTILS_UNIFORM_LIGHT_RADIUS 0 -#define RENDER_UTILS_UNIFORM_LIGHT_TEXCOORD_TRANSFORM 1 - // Deferred lighting resolution #define RENDER_UTILS_TEXTURE_DEFERRRED_COLOR 0 #define RENDER_UTILS_TEXTURE_DEFERRRED_NORMAL 1 @@ -140,8 +137,6 @@ enum Uniform { TextOutline = RENDER_UTILS_UNIFORM_TEXT_OUTLINE, TaaSharpenIntensity = GPU_UNIFORM_EXTRA0, HighlightOutlineWidth = GPU_UNIFORM_EXTRA0, - LightRadius = RENDER_UTILS_UNIFORM_LIGHT_RADIUS, - TexcoordTransform = RENDER_UTILS_UNIFORM_LIGHT_TEXCOORD_TRANSFORM, }; } diff --git a/libraries/render-utils/src/render-utils/fxaa.slp b/libraries/render-utils/src/render-utils/fxaa.slp new file mode 100644 index 0000000000..c2c4bfbebd --- /dev/null +++ b/libraries/render-utils/src/render-utils/fxaa.slp @@ -0,0 +1 @@ +VERTEX gpu::vertex::DrawUnitQuadTexcoord diff --git a/libraries/render-utils/src/sdf_text3D.slf b/libraries/render-utils/src/sdf_text3D.slf index 2fbaa03900..d35396e469 100644 --- a/libraries/render-utils/src/sdf_text3D.slf +++ b/libraries/render-utils/src/sdf_text3D.slf @@ -14,8 +14,15 @@ <@include render-utils/ShaderConstants.h@> layout(binding=0) uniform sampler2D Font; -layout(location=RENDER_UTILS_UNIFORM_TEXT_OUTLINE) uniform bool Outline; -layout(location=RENDER_UTILS_UNIFORM_TEXT_COLOR) uniform vec4 Color; + +struct TextParams { + vec4 color; + vec4 outline; +}; + +layout(binding=0) uniform textParamsBuffer { + TextParams params; +}; // the interpolated normal layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS; @@ -32,7 +39,7 @@ const float taaBias = pow(2.0, TAA_TEXTURE_LOD_BIAS); float evalSDF(vec2 texCoord) { // retrieve signed distance float sdf = textureLod(Font, texCoord, TAA_TEXTURE_LOD_BIAS).g; - if (Outline) { + if (params.outline.x > 0.0) { if (sdf > interiorCutoff) { sdf = 1.0 - sdf; } else { @@ -47,12 +54,12 @@ void main() { vec2 dxTexCoord = dFdx(_texCoord0) * 0.5 * taaBias; vec2 dyTexCoord = dFdy(_texCoord0) * 0.5 * taaBias; - // Perform 4x supersampling for anisotropic filtering + // Perform 4x supersampling for anisotropic filtering float a; - a = evalSDF(_texCoord0); - a += evalSDF(_texCoord0+dxTexCoord); - a += evalSDF(_texCoord0+dyTexCoord); - a += evalSDF(_texCoord0+dxTexCoord+dyTexCoord); + a = evalSDF(_texCoord0); + a += evalSDF(_texCoord0+dxTexCoord); + a += evalSDF(_texCoord0+dyTexCoord); + a += evalSDF(_texCoord0+dxTexCoord+dyTexCoord); a *= 0.25; // discard if invisible @@ -62,8 +69,8 @@ void main() { packDeferredFragment( normalize(_normalWS), - a * Color.a, - Color.rgb, + a * params.color.a, + params.color.rgb, DEFAULT_ROUGHNESS, DEFAULT_METALLIC, DEFAULT_EMISSIVE, diff --git a/libraries/render-utils/src/sdf_text3D_transparent.slf b/libraries/render-utils/src/sdf_text3D_transparent.slf index 218236c26b..9dffca2038 100644 --- a/libraries/render-utils/src/sdf_text3D_transparent.slf +++ b/libraries/render-utils/src/sdf_text3D_transparent.slf @@ -14,8 +14,15 @@ <@include render-utils/ShaderConstants.h@> layout(binding=0) uniform sampler2D Font; -layout(location=RENDER_UTILS_UNIFORM_TEXT_OUTLINE) uniform bool Outline; -layout(location=RENDER_UTILS_UNIFORM_TEXT_COLOR) uniform vec4 Color; + +struct TextParams { + vec4 color; + vec4 outline; +}; + +layout(binding=0) uniform textParamsBuffer { + TextParams params; +}; // the interpolated normal layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS; @@ -31,7 +38,7 @@ const float outlineExpansion = 0.2; void main() { // retrieve signed distance float sdf = texture(Font, _texCoord0).g; - if (Outline) { + if (params.outline.x > 0.0) { if (sdf > interiorCutoff) { sdf = 1.0 - sdf; } else { @@ -51,8 +58,8 @@ void main() { packDeferredFragmentTranslucent( normalize(_normalWS), - a * Color.a, - Color.rgb, + a * params.color.a, + params.color.rgb, DEFAULT_FRESNEL, DEFAULT_ROUGHNESS); } \ No newline at end of file diff --git a/libraries/render-utils/src/simple_fade.slf b/libraries/render-utils/src/simple_fade.slf index e9f94c29bc..97ed0c570c 100644 --- a/libraries/render-utils/src/simple_fade.slf +++ b/libraries/render-utils/src/simple_fade.slf @@ -91,7 +91,7 @@ void main(void) { normal, 1.0, diffuse+fadeEmissive, - max(0, 1.0 - shininess / 128.0), + max(0.0, 1.0 - shininess / 128.0), DEFAULT_METALLIC, specular, specular); @@ -100,7 +100,7 @@ void main(void) { normal, 1.0, diffuse, - max(0, 1.0 - shininess / 128.0), + max(0.0, 1.0 - shininess / 128.0), length(specular), DEFAULT_EMISSIVE+fadeEmissive, DEFAULT_OCCLUSION, diff --git a/libraries/render-utils/src/simple_transparent_textured.slf b/libraries/render-utils/src/simple_transparent_textured.slf index 0e6198de68..5573a7aa22 100644 --- a/libraries/render-utils/src/simple_transparent_textured.slf +++ b/libraries/render-utils/src/simple_transparent_textured.slf @@ -17,7 +17,7 @@ <@include render-utils/ShaderConstants.h@> // the albedo texture -layout(location=0) uniform sampler2D originalTexture; +layout(binding=0) uniform sampler2D originalTexture; // the interpolated normal layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS; diff --git a/libraries/render-utils/src/ssao.slh b/libraries/render-utils/src/ssao.slh index 5341a1682a..b149d8f912 100644 --- a/libraries/render-utils/src/ssao.slh +++ b/libraries/render-utils/src/ssao.slh @@ -137,14 +137,14 @@ float getBlurCoef(int c) { float getAngleDitheringWorldPos(in vec3 pixelWorldPos) { vec3 worldPosFract = fract(pixelWorldPos * 1.0); - ivec3 pixelPos = ivec3(worldPosFract * 256); + ivec3 pixelPos = ivec3(worldPosFract * 256.0); - return isDitheringEnabled() * ((3 * pixelPos.x ^ pixelPos.y + pixelPos.x * pixelPos.y) + (3 * pixelPos.y ^ pixelPos.z + pixelPos.x * pixelPos.z)) * 10 + getFrameDithering(); + return isDitheringEnabled() * float(((3 * pixelPos.x ^ pixelPos.y + pixelPos.x * pixelPos.y) + (3 * pixelPos.y ^ pixelPos.z + pixelPos.x * pixelPos.z)) * 10) + getFrameDithering(); } float getAngleDithering(in ivec2 pixelPos) { // Hash function used in the AlchemyAO paper - return isDitheringEnabled() * (3 * pixelPos.x ^ pixelPos.y + pixelPos.x * pixelPos.y) * 10 + getFrameDithering(); + return isDitheringEnabled() * float((3 * pixelPos.x ^ pixelPos.y + pixelPos.x * pixelPos.y) * 10) + getFrameDithering(); } float evalDiskRadius(float Zeye, vec2 imageSize) { @@ -162,7 +162,7 @@ const float TWO_PI = 6.28; vec3 getUnitTapLocation(int sampleNumber, float spinAngle){ // Radius relative to ssR - float alpha = float(sampleNumber + 0.5) * getInvNumSamples(); + float alpha = (float(sampleNumber) + 0.5) * getInvNumSamples(); float angle = alpha * (getNumSpiralTurns() * TWO_PI) + spinAngle; return vec3(cos(angle), sin(angle), alpha); } @@ -219,7 +219,7 @@ vec3 getTapLocationClamped(int sampleNumber, float spinAngle, float outerRadius, if (redoTap) { tap.xy = tapPos - pixelPos; tap.z = length(tap.xy); - tap.z = 0; + tap.z = 0.0; } return tap; @@ -253,7 +253,7 @@ vec3 fetchTapUnfiltered(ivec4 side, ivec2 ssC, vec3 tap, vec2 imageSize) { vec2 tapUV = (vec2(ssP) + vec2(0.5)) / imageSize; - vec2 fetchUV = vec2(tapUV.x + side.w * 0.5 * (side.x - tapUV.x), tapUV.y); + vec2 fetchUV = vec2(tapUV.x + float(side.w) * 0.5 * (float(side.x) - tapUV.x), tapUV.y); vec3 P; P.xy = tapUV; @@ -263,7 +263,7 @@ vec3 fetchTapUnfiltered(ivec4 side, ivec2 ssC, vec3 tap, vec2 imageSize) { } vec3 fetchTap(ivec4 side, ivec2 ssC, vec3 tap, vec2 imageSize) { - int mipLevel = evalMipFromRadius(tap.z * doFetchMips()); + int mipLevel = evalMipFromRadius(tap.z * float(doFetchMips())); ivec2 ssP = ivec2(tap.xy) + ssC; ivec2 ssPFull = ivec2(ssP.x + side.y, ssP.y); @@ -276,7 +276,7 @@ vec3 fetchTap(ivec4 side, ivec2 ssC, vec3 tap, vec2 imageSize) { ivec2 mipP = clamp(ssPFull >> mipLevel, ivec2(0), mipSize - ivec2(1)); vec2 tapUV = (vec2(ssP) + vec2(0.5)) / imageSize; - vec2 fetchUV = vec2(tapUV.x + side.w * 0.5 * (side.x - tapUV.x), tapUV.y); + vec2 fetchUV = vec2(tapUV.x + float(side.w) * 0.5 * (float(side.x) - tapUV.x), tapUV.y); // vec2 tapUV = (vec2(mipP) + vec2(0.5)) / vec2(mipSize); vec3 P; diff --git a/libraries/render-utils/src/ssao_debugOcclusion.slf b/libraries/render-utils/src/ssao_debugOcclusion.slf index 007fd0cd7b..ab7989e35e 100644 --- a/libraries/render-utils/src/ssao_debugOcclusion.slf +++ b/libraries/render-utils/src/ssao_debugOcclusion.slf @@ -84,15 +84,15 @@ void main(void) { float keepTapRadius = 1.0; int keepedMip = -1; bool keep = false; - - for (int i = 0; i < getNumSamples(); ++i) { + int sampleCount = int(getNumSamples()); + for (int i = 0; i < sampleCount; ++i) { vec3 tap = getTapLocationClamped(i, randomPatternRotationAngle, ssDiskRadius, cursorPixelPos, imageSize); // The occluding point in camera space vec2 fragToTap = vec2(ssC) + tap.xy - fragCoord.xy; if (dot(fragToTap,fragToTap) < keepTapRadius) { keep = true; - keepedMip = evalMipFromRadius(tap.z * doFetchMips()); + keepedMip = evalMipFromRadius(tap.z * float(doFetchMips())); } vec3 tapUVZ = fetchTap(side, ssC, tap, imageSize); diff --git a/libraries/render-utils/src/ssao_makeOcclusion.slf b/libraries/render-utils/src/ssao_makeOcclusion.slf index 1b638d4270..3934b9eddc 100644 --- a/libraries/render-utils/src/ssao_makeOcclusion.slf +++ b/libraries/render-utils/src/ssao_makeOcclusion.slf @@ -52,8 +52,9 @@ void main(void) { // Accumulate the Obscurance for each samples float sum = 0.0; - for (int i = 0; i < getNumSamples(); ++i) { - vec3 tap = getTapLocationClamped(i, randomPatternRotationAngle, ssDiskRadius, ssC, imageSize); + int sampleCount = int(getNumSamples()); + for (int i = 0; i < sampleCount; ++i) { + vec3 tap = getTapLocationClamped(i, randomPatternRotationAngle, ssDiskRadius, vec2(ssC), imageSize); vec3 tapUVZ = fetchTap(side, ssC, tap, imageSize); @@ -68,10 +69,10 @@ void main(void) { // Bilateral box-filter over a quad for free, respecting depth edges // (the difference that this makes is subtle) if (abs(dFdx(Cp.z)) < 0.02) { - A -= dFdx(A) * ((ssC.x & 1) - 0.5); + A -= dFdx(A) * (float(ssC.x & 1) - 0.5); } if (abs(dFdy(Cp.z)) < 0.02) { - A -= dFdy(A) * ((ssC.y & 1) - 0.5); + A -= dFdy(A) * (float(ssC.y & 1) - 0.5); } diff --git a/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf b/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf index 00b60d6fd4..8664fa16fd 100644 --- a/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf +++ b/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf @@ -26,7 +26,8 @@ layout(location=0) in vec2 varTexCoord0; layout(location=0) out vec4 _fragColor; -layout(location=GPU_UNIFORM_EXTRA0) uniform vec2 uniformCursorTexcoord = vec2(0.5); +// FIXME make into a uniform buffer or push constant if this shader ever comes into use +vec2 uniformCursorTexcoord = vec2(0.5); //uniform vec3 uniformLightVector = vec3(1.0); @@ -79,7 +80,7 @@ vec3 drawScatteringTableUV(vec2 cursor, vec2 texcoord) { vec3 distance = vec3(0.0); for (int c = 0; c < 3; c++) { - vec2 BRDFuv = vec2(clamp(bentNdotL[c] * 0.5 + 0.5, 0.0, 1.0), clamp(2 * curvature, 0.0, 1.0)); + vec2 BRDFuv = vec2(clamp(bentNdotL[c] * 0.5 + 0.5, 0.0, 1.0), clamp(2.0 * curvature, 0.0, 1.0)); vec2 delta = BRDFuv - texcoord; distance[c] = 1.0 - dot(delta, delta); } diff --git a/libraries/render-utils/src/surfaceGeometry_copyDepth.slf b/libraries/render-utils/src/surfaceGeometry_copyDepth.slf index 7eb097224e..f018ee1105 100644 --- a/libraries/render-utils/src/surfaceGeometry_copyDepth.slf +++ b/libraries/render-utils/src/surfaceGeometry_copyDepth.slf @@ -16,7 +16,7 @@ layout(binding=0) uniform sampler2D depthMap; layout(location=0) out vec4 outFragColor; void main(void) { - float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x; - outFragColor = vec4(Zdb, 0.0, 0.0, 1.0); + float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x; + outFragColor = vec4(Zdb, 0.0, 0.0, 1.0); } diff --git a/libraries/render-utils/src/taa.slh b/libraries/render-utils/src/taa.slh index 26ffe55263..2161ad9524 100644 --- a/libraries/render-utils/src/taa.slh +++ b/libraries/render-utils/src/taa.slh @@ -24,10 +24,10 @@ layout(binding=RENDER_UTILS_TEXTURE_TAA_NEXT) uniform sampler2D nextMap; struct TAAParams { - float none; - float blend; - float covarianceGamma; - float debugShowVelocityThreshold; + float none; + float blend; + float covarianceGamma; + float debugShowVelocityThreshold; ivec4 flags; vec4 pixelInfo_orbZoom; vec4 regionInfo; @@ -77,47 +77,47 @@ vec2 taa_getRegionFXAA() { #define USE_YCOCG 1 vec4 taa_fetchColor(sampler2D map, vec2 uv) { - vec4 c = texture(map, uv); - // Apply rapid pseudo tonemapping as TAA is applied to a tonemapped image, using luminance as weight, as proposed in - // https://de45xmedrsdbp.cloudfront.net/Resources/files/TemporalAA_small-59732822.pdf - float lum = dot(vec3(0.3,0.5,0.2),c.rgb); - c.rgb = c.rgb / (1.0+lum); + vec4 c = texture(map, uv); + // Apply rapid pseudo tonemapping as TAA is applied to a tonemapped image, using luminance as weight, as proposed in + // https://de45xmedrsdbp.cloudfront.net/Resources/files/TemporalAA_small-59732822.pdf + float lum = dot(vec3(0.3,0.5,0.2),c.rgb); + c.rgb = c.rgb / (1.0+lum); #if USE_YCOCG - return vec4(color_LinearToYCoCg(c.rgb), c.a); + return vec4(color_LinearToYCoCg(c.rgb), c.a); #else - return c; + return c; #endif } vec3 taa_resolveColor(vec3 color) { #if USE_YCOCG - color = max(vec3(0), color_YCoCgToUnclampedLinear(color)); + color = max(vec3(0), color_YCoCgToUnclampedLinear(color)); #endif - // Apply rapid inverse tonemapping, using luminance as weight, as proposed in - // https://de45xmedrsdbp.cloudfront.net/Resources/files/TemporalAA_small-59732822.pdf - float lum = dot(vec3(0.3,0.5,0.2),color.rgb); - color = color / (1.0-lum); - return color; + // Apply rapid inverse tonemapping, using luminance as weight, as proposed in + // https://de45xmedrsdbp.cloudfront.net/Resources/files/TemporalAA_small-59732822.pdf + float lum = dot(vec3(0.3,0.5,0.2),color.rgb); + color = color / (1.0-lum); + return color; } vec4 taa_fetchSourceMap(vec2 uv) { - return taa_fetchColor(sourceMap, uv); + return taa_fetchColor(sourceMap, uv); } vec4 taa_fetchHistoryMap(vec2 uv) { - return taa_fetchColor(historyMap, uv); + return taa_fetchColor(historyMap, uv); } vec4 taa_fetchNextMap(vec2 uv) { - return taa_fetchColor(nextMap, uv); + return taa_fetchColor(nextMap, uv); } vec2 taa_fetchVelocityMap(vec2 uv) { - return texture(velocityMap, uv).xy; + return texture(velocityMap, uv).xy; } float taa_fetchDepth(vec2 uv) { - return -texture(depthMap, vec2(uv), 0).x; + return -texture(depthMap, vec2(uv), 0.0).x; } @@ -141,35 +141,35 @@ vec2 taa_getTexelSize() { vec3 taa_findClosestFragment3x3(vec2 uv) { - vec2 dd = abs(taa_getTexelSize()); - vec2 du = vec2(dd.x, 0.0); - vec2 dv = vec2(0.0, dd.y); + vec2 dd = abs(taa_getTexelSize()); + vec2 du = vec2(dd.x, 0.0); + vec2 dv = vec2(0.0, dd.y); - vec3 dtl = vec3(-1, -1, taa_fetchDepth(uv - dv - du)); - vec3 dtc = vec3( 0, -1, taa_fetchDepth(uv - dv)); - vec3 dtr = vec3( 1, -1, taa_fetchDepth(uv - dv + du)); + vec3 dtl = vec3(-1, -1, taa_fetchDepth(uv - dv - du)); + vec3 dtc = vec3( 0, -1, taa_fetchDepth(uv - dv)); + vec3 dtr = vec3( 1, -1, taa_fetchDepth(uv - dv + du)); - vec3 dml = vec3(-1, 0, taa_fetchDepth(uv - du)); - vec3 dmc = vec3( 0, 0, taa_fetchDepth(uv)); - vec3 dmr = vec3( 1, 0, taa_fetchDepth(uv + du)); + vec3 dml = vec3(-1, 0, taa_fetchDepth(uv - du)); + vec3 dmc = vec3( 0, 0, taa_fetchDepth(uv)); + vec3 dmr = vec3( 1, 0, taa_fetchDepth(uv + du)); - vec3 dbl = vec3(-1, 1, taa_fetchDepth(uv + dv - du)); - vec3 dbc = vec3( 0, 1, taa_fetchDepth(uv + dv)); - vec3 dbr = vec3( 1, 1, taa_fetchDepth(uv + dv + du)); + vec3 dbl = vec3(-1, 1, taa_fetchDepth(uv + dv - du)); + vec3 dbc = vec3( 0, 1, taa_fetchDepth(uv + dv)); + vec3 dbr = vec3( 1, 1, taa_fetchDepth(uv + dv + du)); - vec3 dmin = dtl; - if (ZCMP_GT(dmin.z, dtc.z)) dmin = dtc; - if (ZCMP_GT(dmin.z, dtr.z)) dmin = dtr; + vec3 dmin = dtl; + if (ZCMP_GT(dmin.z, dtc.z)) dmin = dtc; + if (ZCMP_GT(dmin.z, dtr.z)) dmin = dtr; - if (ZCMP_GT(dmin.z, dml.z)) dmin = dml; - if (ZCMP_GT(dmin.z, dmc.z)) dmin = dmc; - if (ZCMP_GT(dmin.z, dmr.z)) dmin = dmr; + if (ZCMP_GT(dmin.z, dml.z)) dmin = dml; + if (ZCMP_GT(dmin.z, dmc.z)) dmin = dmc; + if (ZCMP_GT(dmin.z, dmr.z)) dmin = dmr; - if (ZCMP_GT(dmin.z, dbl.z)) dmin = dbl; - if (ZCMP_GT(dmin.z, dbc.z)) dmin = dbc; - if (ZCMP_GT(dmin.z, dbr.z)) dmin = dbr; + if (ZCMP_GT(dmin.z, dbl.z)) dmin = dbl; + if (ZCMP_GT(dmin.z, dbc.z)) dmin = dbc; + if (ZCMP_GT(dmin.z, dbr.z)) dmin = dbr; - return vec3(uv + dd.xy * dmin.xy, dmin.z); + return vec3(uv + dd.xy * dmin.xy, dmin.z); } vec2 taa_fetchVelocityMapBest(vec2 uv) { @@ -230,7 +230,7 @@ vec2 taa_fromEyeUVToFragUV(vec2 eyeUV, int stereoSide) { vec2 fragUV = eyeUV; if (isStereo()) { fragUV.x *= 0.5; - fragUV.x += stereoSide*0.5; + fragUV.x += float(stereoSide)*0.5; } return fragUV; } @@ -264,8 +264,8 @@ mat3 taa_evalNeighbourColorVariance(vec3 sourceColor, vec2 fragUV, vec2 fragVelo vec2 texelSize = taa_getTexelSize(); - vec2 du = vec2(texelSize.x, 0.0); - vec2 dv = vec2(0.0, texelSize.y); + vec2 du = vec2(texelSize.x, 0.0); + vec2 dv = vec2(0.0, texelSize.y); vec3 sampleColor = taa_fetchSourceMap(fragUV - dv - du).rgb; vec3 sumSamples = sampleColor; @@ -320,72 +320,72 @@ mat3 taa_evalNeighbourColorRegion(vec3 sourceColor, vec2 fragUV, vec2 fragVeloci vec3 cmin, cmax, cavg; #if MINMAX_3X3_ROUNDED - vec2 du = vec2(texelSize.x, 0.0); - vec2 dv = vec2(0.0, texelSize.y); + vec2 du = vec2(texelSize.x, 0.0); + vec2 dv = vec2(0.0, texelSize.y); - vec3 ctl = taa_fetchSourceMap(fragUV - dv - du).rgb; - vec3 ctc = taa_fetchSourceMap(fragUV - dv).rgb; - vec3 ctr = taa_fetchSourceMap(fragUV - dv + du).rgb; - vec3 cml = taa_fetchSourceMap(fragUV - du).rgb; - vec3 cmc = sourceColor; //taa_fetchSourceMap(fragUV).rgb; // could resuse the same osurce sample isn't it ? - vec3 cmr = taa_fetchSourceMap(fragUV + du).rgb; - vec3 cbl = taa_fetchSourceMap(fragUV + dv - du).rgb; - vec3 cbc = taa_fetchSourceMap(fragUV + dv).rgb; - vec3 cbr = taa_fetchSourceMap(fragUV + dv + du).rgb; + vec3 ctl = taa_fetchSourceMap(fragUV - dv - du).rgb; + vec3 ctc = taa_fetchSourceMap(fragUV - dv).rgb; + vec3 ctr = taa_fetchSourceMap(fragUV - dv + du).rgb; + vec3 cml = taa_fetchSourceMap(fragUV - du).rgb; + vec3 cmc = sourceColor; //taa_fetchSourceMap(fragUV).rgb; // could resuse the same osurce sample isn't it ? + vec3 cmr = taa_fetchSourceMap(fragUV + du).rgb; + vec3 cbl = taa_fetchSourceMap(fragUV + dv - du).rgb; + vec3 cbc = taa_fetchSourceMap(fragUV + dv).rgb; + vec3 cbr = taa_fetchSourceMap(fragUV + dv + du).rgb; - cmin = min(ctl, min(ctc, min(ctr, min(cml, min(cmc, min(cmr, min(cbl, min(cbc, cbr)))))))); - cmax = max(ctl, max(ctc, max(ctr, max(cml, max(cmc, max(cmr, max(cbl, max(cbc, cbr)))))))); + cmin = min(ctl, min(ctc, min(ctr, min(cml, min(cmc, min(cmr, min(cbl, min(cbc, cbr)))))))); + cmax = max(ctl, max(ctc, max(ctr, max(cml, max(cmc, max(cmr, max(cbl, max(cbc, cbr)))))))); - #if MINMAX_3X3_ROUNDED || USE_YCOCG || USE_CLIPPING - cavg = (ctl + ctc + ctr + cml + cmc + cmr + cbl + cbc + cbr) / 9.0; + #if MINMAX_3X3_ROUNDED || USE_YCOCG || USE_CLIPPING + cavg = (ctl + ctc + ctr + cml + cmc + cmr + cbl + cbc + cbr) / 9.0; #elif cavg = (cmin + cmax ) * 0.5; - #endif + #endif - #if MINMAX_3X3_ROUNDED - vec3 cmin5 = min(ctc, min(cml, min(cmc, min(cmr, cbc)))); - vec3 cmax5 = max(ctc, max(cml, max(cmc, max(cmr, cbc)))); - vec3 cavg5 = (ctc + cml + cmc + cmr + cbc) / 5.0; - cmin = 0.5 * (cmin + cmin5); - cmax = 0.5 * (cmax + cmax5); - cavg = 0.5 * (cavg + cavg5); - #endif + #if MINMAX_3X3_ROUNDED + vec3 cmin5 = min(ctc, min(cml, min(cmc, min(cmr, cbc)))); + vec3 cmax5 = max(ctc, max(cml, max(cmc, max(cmr, cbc)))); + vec3 cavg5 = (ctc + cml + cmc + cmr + cbc) / 5.0; + cmin = 0.5 * (cmin + cmin5); + cmax = 0.5 * (cmax + cmax5); + cavg = 0.5 * (cavg + cavg5); + #endif #else - const float _SubpixelThreshold = 0.5; - const float _GatherBase = 0.5; - const float _GatherSubpixelMotion = 0.1666; + const float _SubpixelThreshold = 0.5; + const float _GatherBase = 0.5; + const float _GatherSubpixelMotion = 0.1666; - vec2 texel_vel = fragVelocity * imageSize; - float texel_vel_mag = length(texel_vel) * -fragZe; - float k_subpixel_motion = clamp(_SubpixelThreshold / (0.0001 + texel_vel_mag), 0.0, 1.0); - float k_min_max_support = _GatherBase + _GatherSubpixelMotion * k_subpixel_motion; + vec2 texel_vel = fragVelocity * imageSize; + float texel_vel_mag = length(texel_vel) * -fragZe; + float k_subpixel_motion = clamp(_SubpixelThreshold / (0.0001 + texel_vel_mag), 0.0, 1.0); + float k_min_max_support = _GatherBase + _GatherSubpixelMotion * k_subpixel_motion; - vec2 ss_offset01 = k_min_max_support * vec2(-texelSize.x, texelSize.y); - vec2 ss_offset11 = k_min_max_support * vec2(texelSize.x, texelSize.y); - vec3 c00 = taa_fetchSourceMap(fragUV - ss_offset11).rgb; - vec3 c10 = taa_fetchSourceMap(fragUV - ss_offset01).rgb; - vec3 c01 = taa_fetchSourceMap(fragUV + ss_offset01).rgb; - vec3 c11 = taa_fetchSourceMap(fragUV + ss_offset11).rgb; + vec2 ss_offset01 = k_min_max_support * vec2(-texelSize.x, texelSize.y); + vec2 ss_offset11 = k_min_max_support * vec2(texelSize.x, texelSize.y); + vec3 c00 = taa_fetchSourceMap(fragUV - ss_offset11).rgb; + vec3 c10 = taa_fetchSourceMap(fragUV - ss_offset01).rgb; + vec3 c01 = taa_fetchSourceMap(fragUV + ss_offset01).rgb; + vec3 c11 = taa_fetchSourceMap(fragUV + ss_offset11).rgb; - cmin = min(c00, min(c10, min(c01, c11))); - cmax = max(c00, max(c10, max(c01, c11))); + cmin = min(c00, min(c10, min(c01, c11))); + cmax = max(c00, max(c10, max(c01, c11))); cavg = (cmin + cmax ) * 0.5; - #if USE_YCOCG || USE_CLIPPING - cavg = (c00 + c10 + c01 + c11) / 4.0; + #if USE_YCOCG || USE_CLIPPING + cavg = (c00 + c10 + c01 + c11) / 4.0; #elif cavg = (cmin + cmax ) * 0.5; - #endif + #endif #endif - // shrink chroma min-max - #if USE_YCOCG - vec2 chroma_extent = vec2(0.25 * 0.5 * (cmax.r - cmin.r)); - vec2 chroma_center = sourceColor.gb; - cmin.yz = chroma_center - chroma_extent; - cmax.yz = chroma_center + chroma_extent; - cavg.yz = chroma_center; - #endif + // shrink chroma min-max + #if USE_YCOCG + vec2 chroma_extent = vec2(0.25 * 0.5 * (cmax.r - cmin.r)); + vec2 chroma_center = sourceColor.gb; + cmin.yz = chroma_center - chroma_extent; + cmax.yz = chroma_center + chroma_extent; + cavg.yz = chroma_center; + #endif return mat3(cmin, cmax, cavg); } @@ -393,22 +393,22 @@ mat3 taa_evalNeighbourColorRegion(vec3 sourceColor, vec2 fragUV, vec2 fragVeloci //#define USE_OPTIMIZATIONS 0 vec3 taa_clampColor(vec3 colorMin, vec3 colorMax, vec3 colorSource, vec3 color) { - const float eps = 0.00001; + const float eps = 0.00001; vec3 p = colorSource; vec3 q = color; - // note: only clips towards aabb center (but fast!) - vec3 p_clip = 0.5 * (colorMax + colorMin); - vec3 e_clip = 0.5 * (colorMax - colorMin) + vec3(eps); + // note: only clips towards aabb center (but fast!) + vec3 p_clip = 0.5 * (colorMax + colorMin); + vec3 e_clip = 0.5 * (colorMax - colorMin) + vec3(eps); - vec3 v_clip = q - p_clip; - vec3 v_unit = v_clip.xyz / e_clip; - vec3 a_unit = abs(v_unit); - float ma_unit = max(a_unit.x, max(a_unit.y, a_unit.z)); + vec3 v_clip = q - p_clip; + vec3 v_unit = v_clip.xyz / e_clip; + vec3 a_unit = abs(v_unit); + float ma_unit = max(a_unit.x, max(a_unit.y, a_unit.z)); - if (ma_unit > 1.0) - return p_clip + v_clip / ma_unit; - else - return q;// point inside aabb + if (ma_unit > 1.0) + return p_clip + v_clip / ma_unit; + else + return q;// point inside aabb } vec3 taa_evalConstrainColor(vec3 sourceColor, vec2 sourceUV, vec2 sourceVel, vec3 candidateColor) { @@ -416,25 +416,25 @@ vec3 taa_evalConstrainColor(vec3 sourceColor, vec2 sourceUV, vec2 sourceVel, vec colorMinMaxAvg = taa_evalNeighbourColorVariance(sourceColor, sourceUV, sourceVel); - // clamp history to neighbourhood of current sample + // clamp history to neighbourhood of current sample return taa_clampColor(colorMinMaxAvg[0], colorMinMaxAvg[1], sourceColor, candidateColor); } vec3 taa_evalFeedbackColor(vec3 sourceColor, vec3 historyColor, float blendFactor) { const float _FeedbackMin = 0.1; const float _FeedbackMax = 0.9; - // feedback weight from unbiased luminance diff (t.lottes) - #if USE_YCOCG - float lum0 = sourceColor.r; - float lum1 = historyColor.r; - #else - float lum0 = Luminance(sourceColor.rgb); - float lum1 = Luminance(historyColor.rgb); - #endif - float unbiased_diff = abs(lum0 - lum1) / max(lum0, max(lum1, 0.2)); - float unbiased_weight = 1.0 - unbiased_diff; - float unbiased_weight_sqr = unbiased_weight * unbiased_weight; - float k_feedback = mix(_FeedbackMin, _FeedbackMax, unbiased_weight_sqr); + // feedback weight from unbiased luminance diff (t.lottes) + #if USE_YCOCG + float lum0 = sourceColor.r; + float lum1 = historyColor.r; + #else + float lum0 = Luminance(sourceColor.rgb); + float lum1 = Luminance(historyColor.rgb); + #endif + float unbiased_diff = abs(lum0 - lum1) / max(lum0, max(lum1, 0.2)); + float unbiased_weight = 1.0 - unbiased_diff; + float unbiased_weight_sqr = unbiased_weight * unbiased_weight; + float k_feedback = mix(_FeedbackMin, _FeedbackMax, unbiased_weight_sqr); vec3 nextColor = mix(historyColor, sourceColor, k_feedback * blendFactor).xyz; @@ -478,7 +478,7 @@ vec3 taa_evalFXAA(vec2 fragUV) { vec3 rgbSW = texture(sourceMap, fragUV + (vec2(-1.0, +1.0) * texelSize)).xyz; vec3 rgbSE = texture(sourceMap, fragUV + (vec2(+1.0, +1.0) * texelSize)).xyz; vec3 rgbM = texture(sourceMap, fragUV).xyz; - + // convert RGB values to luminance vec3 luma = vec3(0.299, 0.587, 0.114); float lumaNW = dot(rgbNW, luma); @@ -486,11 +486,11 @@ vec3 taa_evalFXAA(vec2 fragUV) { float lumaSW = dot(rgbSW, luma); float lumaSE = dot(rgbSE, luma); float lumaM = dot( rgbM, luma); - + // luma range of local neighborhood float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - + // direction perpendicular to local luma gradient vec2 dir; dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); @@ -502,7 +502,7 @@ vec3 taa_evalFXAA(vec2 fragUV) { float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin)) * texelSize; - + // perform additional texture sampling perpendicular to gradient vec3 rgbA = (1.0 / 2.0) * ( texture(sourceMap, fragUV + dir * (1.0 / 3.0 - 0.5)).xyz + diff --git a/libraries/render-utils/src/taa_blend.slf b/libraries/render-utils/src/taa_blend.slf index d2e23b590f..50575a6a07 100644 --- a/libraries/render-utils/src/taa_blend.slf +++ b/libraries/render-utils/src/taa_blend.slf @@ -23,7 +23,7 @@ void main(void) { // Pixel being shaded - vec3 sourceColor = texture(sourceMap, varTexCoord0).xyz; + vec3 sourceColor = texture(sourceMap, varTexCoord0).xyz; vec2 imageSize = getWidthHeight(0); vec2 texelSize = getInvWidthHeight(); @@ -57,7 +57,7 @@ void main(void) { vec2 cursorVelocityDir = cursorVelocity / cursorVelocityLength; vec2 cursorVelocityNor = vec2(cursorVelocityDir.y, -cursorVelocityDir.x); - if ((dot(cursorVelocityDir, cursorToFragVec) < 0) && abs(dot(cursorVelocityNor, cursorToFragVec)) < 1.0) { + if ((dot(cursorVelocityDir, cursorToFragVec) < 0.0) && abs(dot(cursorVelocityNor, cursorToFragVec)) < 1.0) { vec3 speedColor = taa_getVelocityColorRelative(cursorToFragLength); @@ -69,7 +69,7 @@ void main(void) { float tenPercentHeight = 0.1 * imageSize.y; float centerWidth = imageSize.x * 0.5; - //vec2 nextOrbPos = vec2(centerWidth, imageSize.y - 3 * tenPercentHeight); + //vec2 nextOrbPos = vec2(centerWidth, imageSize.y - 3.0 * tenPercentHeight); vec2 nextOrbPos = cursorPos; vec2 nextOrbPosToPix = pixPos - nextOrbPos; float nextOrbPosToPixLength = length(nextOrbPosToPix); @@ -124,9 +124,9 @@ void main(void) { // draw region splitter if ((abs(distToRegionDebug) < getInvWidthHeight().x) || (abs(distToRegionFXAA) < getInvWidthHeight().x)) { - outFragColor.rgb = vec3(1.0, 1.0, 0.0); - return; - } + outFragColor.rgb = vec3(1.0, 1.0, 0.0); + return; + } if (distToRegionFXAA > 0.0) { return; @@ -138,7 +138,7 @@ void main(void) { return; } - outFragColor = vec4(nextColor, 1.0); + outFragColor = vec4(nextColor, 1.0); vec3 prevColor = nextColor; @@ -146,7 +146,7 @@ void main(void) { prevColor = texture(historyMap, prevTexCoord).xyz; } - outFragColor.xyz = mix(prevColor, vec3(1,0,1), clamp(distance(prevColor, nextColor) - 0.01, 0, 1)); + outFragColor.xyz = mix(prevColor, vec3(1,0,1), clamp(distance(prevColor, nextColor) - 0.01, 0.0, 1.0)); if (pixVelocityLength > params.debugShowVelocityThreshold) { vec3 speedColor = taa_getVelocityColorAboveThreshold(pixVelocityLength); diff --git a/libraries/render-utils/src/text/Font.cpp b/libraries/render-utils/src/text/Font.cpp index aca6ddb79f..68a1e59dc3 100644 --- a/libraries/render-utils/src/text/Font.cpp +++ b/libraries/render-utils/src/text/Font.cpp @@ -256,29 +256,30 @@ void Font::setupGPU() { } } -void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2& bounds) { - _verticesBuffer = std::make_shared(); - _numVertices = 0; - _indicesBuffer = std::make_shared(); - _numIndices = 0; +void Font::buildVertices(Font::DrawInfo& drawInfo, const QString& str, const glm::vec2& origin, const glm::vec2& bounds) { + drawInfo.verticesBuffer = std::make_shared(); + drawInfo.indicesBuffer = std::make_shared(); + drawInfo.indexCount = 0; + int numVertices = 0; - _lastStringRendered = str; - _lastBounds = bounds; + drawInfo.string = str; + drawInfo.bounds = bounds; + drawInfo.origin = origin; // Top left of text - glm::vec2 advance = glm::vec2(x, y); + glm::vec2 advance = origin; foreach(const QString& token, tokenizeForWrapping(str)) { bool isNewLine = (token == QString('\n')); bool forceNewLine = false; // Handle wrapping - if (!isNewLine && (bounds.x != -1) && (advance.x + computeExtent(token).x > x + bounds.x)) { + if (!isNewLine && (bounds.x != -1) && (advance.x + computeExtent(token).x > origin.x + bounds.x)) { // We are out of the x bound, force new line forceNewLine = true; } if (isNewLine || forceNewLine) { // Character return, move the advance to a new line - advance = glm::vec2(x, advance.y - _leading); + advance = glm::vec2(origin.x, advance.y - _leading); if (isNewLine) { // No need to draw anything, go directly to next token @@ -288,7 +289,7 @@ void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2 break; } } - if ((bounds.y != -1) && (advance.y - _fontSize < -y - bounds.y)) { + if ((bounds.y != -1) && (advance.y - _fontSize < -origin.y - bounds.y)) { // We are out of the y bound, stop drawing break; } @@ -297,11 +298,11 @@ void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2 if (!isNewLine) { for (auto c : token) { auto glyph = _glyphs[c]; - quint16 verticesOffset = _numVertices; + quint16 verticesOffset = numVertices; QuadBuilder qd(glyph, advance - glm::vec2(0.0f, _ascent)); - _verticesBuffer->append(sizeof(QuadBuilder), (const gpu::Byte*)&qd); - _numVertices += 4; + drawInfo.verticesBuffer->append(qd); + numVertices += 4; // Sam's recommended triangle slices // Triangle tri1 = { v0, v1, v3 }; @@ -327,8 +328,8 @@ void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2 indices[3] = verticesOffset + 2; indices[4] = verticesOffset + 1; indices[5] = verticesOffset + 3; - _indicesBuffer->append(sizeof(indices), (const gpu::Byte*)indices); - _numIndices += NUMBER_OF_INDICES_PER_QUAD; + drawInfo.indicesBuffer->append(sizeof(indices), (const gpu::Byte*)indices); + drawInfo.indexCount += NUMBER_OF_INDICES_PER_QUAD; // Advance by glyph size @@ -341,26 +342,39 @@ void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2 } } -void Font::drawString(gpu::Batch& batch, float x, float y, const QString& str, const glm::vec4* color, - EffectType effectType, const glm::vec2& bounds, bool layered) { +void Font::drawString(gpu::Batch& batch, Font::DrawInfo& drawInfo, const QString& str, const glm::vec4& color, + EffectType effectType, const glm::vec2& origin, const glm::vec2& bounds, bool layered) { if (str == "") { return; } - if (str != _lastStringRendered || bounds != _lastBounds) { - rebuildVertices(x, y, str, bounds); + if (str != drawInfo.string || bounds != drawInfo.bounds || origin != drawInfo.origin) { + buildVertices(drawInfo, str, origin, bounds); } setupGPU(); - batch.setPipeline(((*color).a < 1.0f || layered) ? _transparentPipeline : _pipeline); - batch.setResourceTexture(render_utils::slot::texture::TextFont, _texture); - batch._glUniform1i(render_utils::slot::uniform::TextOutline, (effectType == OUTLINE_EFFECT)); + struct GpuDrawParams { + glm::vec4 color; + glm::vec4 outline; + }; + + if (!drawInfo.paramsBuffer || drawInfo.params.color != color || drawInfo.params.effect != effectType) { + drawInfo.params.color = color; + drawInfo.params.effect = effectType; + GpuDrawParams gpuDrawParams; + gpuDrawParams.color = ColorUtils::sRGBToLinearVec4(drawInfo.params.color); + gpuDrawParams.outline.x = (drawInfo.params.effect == OUTLINE_EFFECT) ? 1 : 0; + drawInfo.paramsBuffer = std::make_shared(sizeof(GpuDrawParams), nullptr); + drawInfo.paramsBuffer->setSubData(0, sizeof(GpuDrawParams), (const gpu::Byte*)&gpuDrawParams); + } // need the gamma corrected color here - glm::vec4 lrgba = ColorUtils::sRGBToLinearVec4(*color); - batch._glUniform4fv(render_utils::slot::uniform::TextColor, 1, (const float*)&lrgba); + + batch.setPipeline((color.a < 1.0f || layered) ? _transparentPipeline : _pipeline); batch.setInputFormat(_format); - batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride); - batch.setIndexBuffer(gpu::UINT16, _indicesBuffer, 0); - batch.drawIndexed(gpu::TRIANGLES, _numIndices, 0); + batch.setInputBuffer(0, drawInfo.verticesBuffer, 0, _format->getChannels().at(0)._stride); + batch.setResourceTexture(render_utils::slot::texture::TextFont, _texture); + batch.setUniformBuffer(0, drawInfo.paramsBuffer, 0, sizeof(GpuDrawParams)); + batch.setIndexBuffer(gpu::UINT16, drawInfo.indicesBuffer, 0); + batch.drawIndexed(gpu::TRIANGLES, drawInfo.indexCount, 0); } diff --git a/libraries/render-utils/src/text/Font.h b/libraries/render-utils/src/text/Font.h index 2fa2b65fa5..9a0a9b4734 100644 --- a/libraries/render-utils/src/text/Font.h +++ b/libraries/render-utils/src/text/Font.h @@ -23,16 +23,34 @@ public: void read(QIODevice& path); + struct DrawParams { + vec4 color{ -1 }; + EffectType effect; + }; + + struct DrawInfo { + gpu::BufferPointer verticesBuffer; + gpu::BufferPointer indicesBuffer; + gpu::BufferPointer paramsBuffer; + uint32_t indexCount; + + QString string; + glm::vec2 origin; + glm::vec2 bounds; + DrawParams params; + }; + glm::vec2 computeExtent(const QString& str) const; float getFontSize() const { return _fontSize; } // Render string to batch - void drawString(gpu::Batch& batch, float x, float y, const QString& str, - const glm::vec4* color, EffectType effectType, - const glm::vec2& bound, bool layered = false); + void drawString(gpu::Batch& batch, DrawInfo& drawInfo, const QString& str, + const glm::vec4& color, EffectType effectType, + const glm::vec2& origin, const glm::vec2& bound, bool layered = false); static Pointer load(const QString& family); + private: static Pointer load(QIODevice& fontFile); QStringList tokenizeForWrapping(const QString& str) const; @@ -40,7 +58,7 @@ private: glm::vec2 computeTokenExtent(const QString& str) const; const Glyph& getGlyph(const QChar& c) const; - void rebuildVertices(float x, float y, const QString& str, const glm::vec2& bounds); + void buildVertices(DrawInfo& drawInfo, const QString& str, const glm::vec2& origin, const glm::vec2& bounds); void setupGPU(); @@ -66,15 +84,7 @@ private: gpu::PipelinePointer _transparentPipeline; gpu::TexturePointer _texture; gpu::Stream::FormatPointer _format; - gpu::BufferPointer _verticesBuffer; - gpu::BufferPointer _indicesBuffer; gpu::BufferStreamPointer _stream; - unsigned int _numVertices = 0; - unsigned int _numIndices = 0; - - // last string render characteristics - QString _lastStringRendered; - glm::vec2 _lastBounds; }; #endif diff --git a/libraries/render-utils/src/velocityBuffer_cameraMotion.slf b/libraries/render-utils/src/velocityBuffer_cameraMotion.slf index 6932766d63..083440dbf8 100644 --- a/libraries/render-utils/src/velocityBuffer_cameraMotion.slf +++ b/libraries/render-utils/src/velocityBuffer_cameraMotion.slf @@ -27,11 +27,11 @@ void main(void) { ivec4 stereoSide; ivec2 framePixelPos = getPixelPosTexcoordPosAndSide(gl_FragCoord.xy, pixelPos, texcoordPos, stereoSide); - float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x; + float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x; - // The position of the pixel fragment in Eye space then in world space + // The position of the pixel fragment in Eye space then in world space vec3 eyePos = evalUnjitteredEyePositionFromZdb(stereoSide.x, Zdb, texcoordPos); - vec3 worldPos = (getViewInverse() * vec4(eyePos, 1.0)).xyz; + vec3 worldPos = (getViewInverse() * vec4(eyePos, 1.0)).xyz; vec3 prevEyePos = (getPreviousView() * vec4(worldPos, 1.0)).xyz; vec4 prevClipPos = (getUnjitteredProjection(stereoSide.x) * vec4(prevEyePos, 1.0)); diff --git a/libraries/render-utils/src/zone_drawAmbient.slf b/libraries/render-utils/src/zone_drawAmbient.slf index e560d91308..f20d83e913 100644 --- a/libraries/render-utils/src/zone_drawAmbient.slf +++ b/libraries/render-utils/src/zone_drawAmbient.slf @@ -44,7 +44,7 @@ void main(void) { // vec3 ambient = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(lightAmbient), fragNormal).xyz; // _fragColor = vec4( 0.5 * (fragNormal + vec3(1.0)), 1.0); - vec3 color = (sphereUV.x > 0 ? ambientMap : ambientSH); + vec3 color = (sphereUV.x > 0.0 ? ambientMap : ambientSH); color = color * 1.0 - base.w + base.xyz * base.w; const float INV_GAMMA_22 = 1.0 / 2.2; diff --git a/libraries/render-utils/src/zone_drawKeyLight.slf b/libraries/render-utils/src/zone_drawKeyLight.slf index 99e9357cb0..7174914ed8 100644 --- a/libraries/render-utils/src/zone_drawKeyLight.slf +++ b/libraries/render-utils/src/zone_drawKeyLight.slf @@ -36,7 +36,7 @@ void main(void) { vec3 outSpherePos = normalize(vec3(sphereUV, -sqrt(1.0 - sphereR2))); vec3 outNormal = vec3(getViewInverse() * vec4(outSpherePos, 0.0)); - float val = step(SUN_THRESHOLD, dot(-lightDirection, outNormal)); + float val = step(SUN_THRESHOLD, dot(-lightDirection, outNormal)); color = lightIrradiance * vec3(val); @@ -45,7 +45,7 @@ void main(void) { vec3 inSpherePos = normalize(vec3(inSphereUV, sqrt(1.0 - dot(inSphereUV.xy, inSphereUV.xy)))); vec3 inNormal = vec3(getViewInverse() * vec4(inSpherePos, 0.0)); - vec3 marbleColor = max(lightIrradiance * vec3(dot(-lightDirection, inNormal)), vec3(0.01)); + vec3 marbleColor = max(lightIrradiance * vec3(dot(-lightDirection, inNormal)), vec3(0.01)); color += marbleColor; } diff --git a/libraries/render/src/render/DrawSceneOctree.cpp b/libraries/render/src/render/DrawSceneOctree.cpp index 2cb8a5d8ef..6c87d2f56b 100644 --- a/libraries/render/src/render/DrawSceneOctree.cpp +++ b/libraries/render/src/render/DrawSceneOctree.cpp @@ -36,6 +36,9 @@ const gpu::PipelinePointer DrawSceneOctree::getDrawCellBoundsPipeline() { // Good to go add the brand new pipeline _drawCellBoundsPipeline = gpu::Pipeline::create(program, state); + _cellBoundsFormat = std::make_shared(); + _cellBoundsFormat->setAttribute(0, 0, gpu::Element(gpu::VEC4, gpu::INT32, gpu::XYZW), 0, gpu::Stream::PER_INSTANCE); + _cellBoundsBuffer = std::make_shared(); } return _drawCellBoundsPipeline; } @@ -82,8 +85,11 @@ void DrawSceneOctree::run(const RenderContextPointer& renderContext, const ItemS // bind the one gpu::Pipeline we need batch.setPipeline(getDrawCellBoundsPipeline()); + batch.setInputFormat(_cellBoundsFormat); - auto drawCellBounds = [this, &scene, &batch](const std::vector& cells) { + std::vector cellBounds; + auto drawCellBounds = [this, &cellBounds, &scene, &batch](const std::vector& cells) { + cellBounds.reserve(cellBounds.size() + cells.size()); for (const auto& cellID : cells) { auto cell = scene->getSpatialTree().getConcreteCell(cellID); auto cellLoc = cell.getlocation(); @@ -98,14 +104,19 @@ void DrawSceneOctree::run(const RenderContextPointer& renderContext, const ItemS } else if (!empty && !_showVisibleCells) { continue; } - - batch._glUniform4iv(gpu::slot::uniform::Extra0, 1, ((const int*)(&cellLocation))); - batch.draw(gpu::LINES, 24, 0); + cellBounds.push_back(cellLocation); } }; drawCellBounds(inSelection.cellSelection.insideCells); drawCellBounds(inSelection.cellSelection.partialCells); + auto size = cellBounds.size() * sizeof(ivec4); + if (size > _cellBoundsBuffer->getSize()) { + _cellBoundsBuffer->resize(size); + } + _cellBoundsBuffer->setSubData(0, cellBounds); + batch.setInputBuffer(0, _cellBoundsBuffer, 0, sizeof(ivec4)); + batch.drawInstanced((uint32_t)cellBounds.size(), gpu::LINES, 24); // Draw the LOD Reticle { diff --git a/libraries/render/src/render/DrawSceneOctree.h b/libraries/render/src/render/DrawSceneOctree.h index 0b2cd6f685..3f7c07ded3 100644 --- a/libraries/render/src/render/DrawSceneOctree.h +++ b/libraries/render/src/render/DrawSceneOctree.h @@ -54,6 +54,8 @@ namespace render { gpu::PipelinePointer _drawCellBoundsPipeline; gpu::PipelinePointer _drawLODReticlePipeline; gpu::PipelinePointer _drawItemBoundPipeline; + gpu::BufferPointer _cellBoundsBuffer; + gpu::Stream::FormatPointer _cellBoundsFormat; bool _showVisibleCells; // initialized by Config bool _showEmptyCells; // initialized by Config diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index 9b7d4ace2b..a1b61a4e77 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -170,13 +170,45 @@ void DrawStatus::run(const RenderContextPointer& renderContext, const Input& inp batch.setPipeline(getDrawItemStatusPipeline()); if (_showNetwork) { - for (size_t i = 0; i < itemBounds.size(); i++) { - batch._glUniform3fv(gpu::slot::uniform::Extra0, 1, (const float*)&itemBounds[i].bound.getCorner()); - batch._glUniform3fv(gpu::slot::uniform::Extra1, 1, ((const float*)&itemBounds[i].bound.getScale())); - batch._glUniform4iv(gpu::slot::uniform::Extra2, 1, (const int*)&(itemStatus[i].first)); - batch._glUniform4iv(gpu::slot::uniform::Extra3, 1, (const int*)&(itemStatus[i].second)); - batch.draw(gpu::TRIANGLES, 24 * NUM_STATUS_VEC4_PER_ITEM, 0); + if (!_instanceBuffer) { + _instanceBuffer = std::make_shared(); } + + struct InstanceData { + vec4 boundPos; + vec4 boundDim; + ivec4 status0; + ivec4 status1; + }; + + if (!_vertexFormat) { + _vertexFormat = std::make_shared(); + _vertexFormat->setAttribute(0, 0, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW), offsetof(InstanceData, boundPos), gpu::Stream::PER_INSTANCE); + _vertexFormat->setAttribute(1, 0, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW), offsetof(InstanceData, boundDim), gpu::Stream::PER_INSTANCE); + _vertexFormat->setAttribute(2, 0, gpu::Element(gpu::VEC4, gpu::INT32, gpu::XYZW), offsetof(InstanceData, status0), gpu::Stream::PER_INSTANCE); + _vertexFormat->setAttribute(3, 0, gpu::Element(gpu::VEC4, gpu::INT32, gpu::XYZW), offsetof(InstanceData, status1), gpu::Stream::PER_INSTANCE); + } + + batch.setInputFormat(_vertexFormat); + std::vector instanceData; + instanceData.resize(itemBounds.size()); + for (size_t i = 0; i < itemBounds.size(); i++) { + InstanceData& item = instanceData[i]; + const auto& bound = itemBounds[i].bound; + const auto& status = itemStatus[i]; + item.boundPos = vec4(bound.getCorner(), 1.0f); + item.boundDim = vec4(bound.getScale(), 1.0f); + item.status0 = status.first; + item.status1 = status.second; + } + + auto instanceBufferSize = sizeof(InstanceData) * instanceData.size(); + if (_instanceBuffer->getSize() < instanceBufferSize) { + _instanceBuffer->resize(instanceBufferSize); + } + _instanceBuffer->setSubData(0, instanceData); + batch.setInputBuffer(0, _instanceBuffer, 0, sizeof(InstanceData)); + batch.drawInstanced((uint32_t)instanceData.size(), gpu::TRIANGLES, 24 * NUM_STATUS_VEC4_PER_ITEM); } batch.setResourceTexture(0, 0); }); diff --git a/libraries/render/src/render/DrawStatus.h b/libraries/render/src/render/DrawStatus.h index 96269fda4d..2959ca59c5 100644 --- a/libraries/render/src/render/DrawStatus.h +++ b/libraries/render/src/render/DrawStatus.h @@ -63,6 +63,8 @@ namespace render { gpu::PipelinePointer _drawItemStatusPipeline; gpu::BufferPointer _boundsBuffer; + gpu::BufferPointer _instanceBuffer; + gpu::Stream::FormatPointer _vertexFormat; gpu::TexturePointer _statusIconMap; }; } diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 8fb800291e..12f75049b2 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -184,8 +184,13 @@ void DrawBounds::run(const RenderContextPointer& renderContext, _drawBuffer = std::make_shared(sizeOfItemBound); } - _drawBuffer->setData(numItems * sizeOfItemBound, (const gpu::Byte*) items.data()); + if (!_paramsBuffer) { + _paramsBuffer = std::make_shared(sizeof(vec4), nullptr); + } + _drawBuffer->setData(numItems * sizeOfItemBound, (const gpu::Byte*) items.data()); + glm::vec4 color(glm::vec3(0.0f), -(float) numItems); + _paramsBuffer->setSubData(0, color); gpu::doInBatch("DrawBounds::run", args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; @@ -202,7 +207,7 @@ void DrawBounds::run(const RenderContextPointer& renderContext, batch.setPipeline(getPipeline()); glm::vec4 color(glm::vec3(0.0f), -(float) numItems); - batch._glUniform4fv(gpu::slot::uniform::Color, 1, (const float*)(&color)); + batch.setUniformBuffer(0, _paramsBuffer); batch.setResourceBuffer(0, _drawBuffer); static const int NUM_VERTICES_PER_CUBE = 24; @@ -212,9 +217,10 @@ void DrawBounds::run(const RenderContextPointer& renderContext, gpu::Stream::FormatPointer DrawQuadVolume::_format; -DrawQuadVolume::DrawQuadVolume(const glm::vec3& color) : - _color{ color } { +DrawQuadVolume::DrawQuadVolume(const glm::vec3& color) { _meshVertices = gpu::BufferView(std::make_shared(sizeof(glm::vec3) * 8, nullptr), gpu::Element::VEC3F_XYZ); + _params = std::make_shared(sizeof(glm::vec4), nullptr); + _params->setSubData(0, vec4(color, 1.0)); if (!_format) { _format = std::make_shared(); _format->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); @@ -248,8 +254,7 @@ void DrawQuadVolume::run(const render::RenderContextPointer& renderContext, cons batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); batch.setPipeline(getPipeline()); - - batch._glUniform4f(0, _color.x, _color.y, _color.z, 1.0f); + batch.setUniformBuffer(0, _params); batch.setInputFormat(_format); batch.setInputBuffer(gpu::Stream::POSITION, _meshVertices); batch.setIndexBuffer(indices); diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index 6b98fb2977..1ef4b8caf1 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -66,6 +66,7 @@ private: const gpu::PipelinePointer getPipeline(); gpu::PipelinePointer _boundsPipeline; gpu::BufferPointer _drawBuffer; + gpu::BufferPointer _paramsBuffer; }; class DrawQuadVolumeConfig : public render::JobConfig { @@ -95,7 +96,7 @@ protected: const gpu::BufferView& indices, int indexCount); gpu::BufferView _meshVertices; - glm::vec3 _color; + gpu::BufferPointer _params; bool _isUpdateEnabled{ true }; static gpu::Stream::FormatPointer _format; diff --git a/libraries/render/src/render/drawCellBounds.slv b/libraries/render/src/render/drawCellBounds.slv index f3cc4c6411..24cc6254fd 100644 --- a/libraries/render/src/render/drawCellBounds.slv +++ b/libraries/render/src/render/drawCellBounds.slv @@ -20,8 +20,7 @@ <$declareColorWheel()$> <@include SceneOctree.slh@> -layout(location=GPU_UNIFORM_EXTRA0) uniform ivec4 inCellLocation; - +layout(location=0) in ivec4 inCellLocation; layout(location=0) out vec4 varColor; void main(void) { @@ -62,5 +61,5 @@ void main(void) { TransformObject obj = getTransformObject(); <$transformModelToClipPos(cam, obj, pos, gl_Position)$> - varColor = vec4(colorWheel(fract(float(inCellLocation.w) / 5.0)), 0.8 + 0.2 * cellIsEmpty); + varColor = vec4(colorWheel(fract(float(inCellLocation.w) / 5.0)), 0.8 + 0.2 * float(cellIsEmpty)); } \ No newline at end of file diff --git a/libraries/render/src/render/drawItemBounds.slv b/libraries/render/src/render/drawItemBounds.slv index 8925009160..ea4d0f24e6 100644 --- a/libraries/render/src/render/drawItemBounds.slv +++ b/libraries/render/src/render/drawItemBounds.slv @@ -20,7 +20,14 @@ <@include gpu/Color.slh@> <$declareColorWheel()$> -layout(location=GPU_UNIFORM_COLOR) uniform vec4 inColor; +struct DrawItemBoundsParams { + vec4 color; +}; + +layout(binding=0) uniform drawItemBoundsParamsBuffer { + DrawItemBoundsParams params; +}; + struct ItemBound { vec4 id_boundPos; @@ -91,10 +98,10 @@ void main(void) { TransformObject obj = getTransformObject(); <$transformModelToClipPos(cam, obj, pos, gl_Position)$> - if (inColor.w < 0.0) { - varColor = vec4(colorWheel(float(boundID)/(-inColor.w)), 1.0); + if (params.color.w < 0.0) { + varColor = vec4(colorWheel(float(boundID)/(-params.color.w)), 1.0); } else { - varColor = vec4(colorWheel(float(inColor.w)), 1.0); + varColor = vec4(colorWheel(float(params.color.w)), 1.0); } varTexcoord = vec2(cubeVec.w, length(boundDim)); diff --git a/libraries/render/src/render/drawItemStatus.slf b/libraries/render/src/render/drawItemStatus.slf index 309a73ae15..9409ee6171 100644 --- a/libraries/render/src/render/drawItemStatus.slf +++ b/libraries/render/src/render/drawItemStatus.slf @@ -18,7 +18,7 @@ layout(location=0) out vec4 outFragColor; layout(binding=0) uniform sampler2D _icons; vec2 getIconTexcoord(float icon, vec2 uv) { const vec2 ICON_COORD_SIZE = vec2(0.0625, 1.0); - return vec2((uv.x + icon) * ICON_COORD_SIZE.x, uv.y * ICON_COORD_SIZE.y); + return vec2((uv.x + icon) * ICON_COORD_SIZE.x, uv.y * ICON_COORD_SIZE.y); } void main(void) { diff --git a/libraries/render/src/render/drawItemStatus.slv b/libraries/render/src/render/drawItemStatus.slv index e92bdda248..7aac26fe2e 100644 --- a/libraries/render/src/render/drawItemStatus.slv +++ b/libraries/render/src/render/drawItemStatus.slv @@ -20,10 +20,10 @@ layout(location=0) out vec4 varColor; layout(location=1) out vec3 varTexcoord; -layout(location=GPU_UNIFORM_EXTRA0) uniform vec3 inBoundPos; -layout(location=GPU_UNIFORM_EXTRA1) uniform vec3 inBoundDim; -layout(location=GPU_UNIFORM_EXTRA2) uniform ivec4 inStatus0; -layout(location=GPU_UNIFORM_EXTRA3) uniform ivec4 inStatus1; +layout(location=0) in vec3 inBoundPos; +layout(location=1) in vec3 inBoundDim; +layout(location=2) in ivec4 inStatus0; +layout(location=3) in ivec4 inStatus1; vec3 paintRainbow(float normalizedHue) { float v = normalizedHue * 6.f; diff --git a/tests/shaders/src/ShaderTests.cpp b/tests/shaders/src/ShaderTests.cpp index 4dd15710f9..03dc034cd0 100644 --- a/tests/shaders/src/ShaderTests.cpp +++ b/tests/shaders/src/ShaderTests.cpp @@ -230,8 +230,8 @@ void ShaderTests::testShaderLoad() { auto glBackend = std::static_pointer_cast(_gpuContext->getBackend()); auto glshader = gpu::gl::GLShader::sync(*glBackend, *program); if (!glshader) { - qDebug() << "Failed to compile or link vertex " << vertexId << " fragment " << fragmentId; - continue; + qWarning() << "Failed to compile or link vertex " << vertexId << " fragment " << fragmentId; + QFAIL("Program link error"); } QVERIFY(glshader != nullptr); @@ -301,7 +301,7 @@ void ShaderTests::testShaderLoad() { QFAIL(error.what()); } - for (uint32_t i = 0; i <= maxShader; ++i) { + for (uint32_t i = 1; i <= maxShader; ++i) { auto used = usedShaders.count(i); if (0 != usedShaders.count(i)) { continue;