From 972f839cada24ac7d4870e3d04713e9089d8dc29 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Fri, 22 Dec 2023 13:52:01 +0100 Subject: [PATCH] Qt5 implementation of QskSceneTexture --- src/CMakeLists.txt | 7 +- src/controls/QskQuick.cpp | 8 + src/controls/QskQuick.h | 6 +- src/nodes/QskBoxNode.cpp | 8 +- src/nodes/QskGradientMaterial.cpp | 2 +- src/nodes/QskSceneTexture.cpp | 256 +++++++++++++++++----- src/nodes/QskSceneTexture.h | 15 +- src/nodes/QskTextureRenderer.cpp | 4 +- src/nodes/shaders/boxshadow.frag.qsb | Bin 2639 -> 2656 bytes src/nodes/shaders/boxshadow.vert.qsb | Bin 1552 -> 1559 bytes src/nodes/shaders/crisplines.frag.qsb | Bin 871 -> 872 bytes src/nodes/shaders/crisplines.vert.qsb | Bin 1865 -> 1871 bytes src/nodes/shaders/gradientconic.frag.qsb | Bin 1830 -> 1826 bytes src/nodes/shaders/gradientconic.vert.qsb | Bin 1617 -> 1624 bytes src/nodes/shaders/gradientlinear.frag.qsb | Bin 1424 -> 1444 bytes src/nodes/shaders/gradientlinear.vert.qsb | Bin 1592 -> 1582 bytes src/nodes/shaders/gradientradial.frag.qsb | Bin 1526 -> 1550 bytes src/nodes/shaders/gradientradial.vert.qsb | Bin 1472 -> 1479 bytes src/nodes/shaders/vulkan2qsb.sh | 1 + 19 files changed, 238 insertions(+), 69 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 43feec2c..3906ad94 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -120,6 +120,7 @@ list(APPEND HEADERS nodes/QskPaintedNode.h nodes/QskPlainTextRenderer.h nodes/QskRichTextRenderer.h + nodes/QskSceneTexture.h nodes/QskSGNode.h nodes/QskStrokeNode.h nodes/QskStippledLineRenderer.h @@ -157,6 +158,7 @@ list(APPEND SOURCES nodes/QskPlainTextRenderer.cpp nodes/QskRectangleNode.cpp nodes/QskRichTextRenderer.cpp + nodes/QskSceneTexture.cpp nodes/QskSGNode.cpp nodes/QskStrokeNode.cpp nodes/QskStippledLineRenderer.cpp @@ -169,11 +171,6 @@ list(APPEND SOURCES nodes/QskVertex.cpp ) -if (QT_VERSION_MAJOR VERSION_GREATER 5) - list(APPEND HEADERS nodes/QskSceneTexture.h) - list(APPEND SOURCES nodes/QskSceneTexture.cpp) -endif() - qt_add_resources(SOURCES nodes/shaders.qrc) list(APPEND HEADERS diff --git a/src/controls/QskQuick.cpp b/src/controls/QskQuick.cpp index 7760e916..9d223a36 100644 --- a/src/controls/QskQuick.cpp +++ b/src/controls/QskQuick.cpp @@ -19,6 +19,14 @@ QSK_QT_PRIVATE_END #include #include +QRhi* qskRenderingHardwareInterface( const QQuickWindow* window ) +{ + if ( auto w = const_cast< QQuickWindow* >( window ) ) + return QQuickWindowPrivate::get( w )->rhi; + + return nullptr; +} + QRectF qskItemRect( const QQuickItem* item ) { auto d = QQuickItemPrivate::get( item ); diff --git a/src/controls/QskQuick.h b/src/controls/QskQuick.h index 622b108d..c8afaafd 100644 --- a/src/controls/QskQuick.h +++ b/src/controls/QskQuick.h @@ -18,14 +18,16 @@ class QSGNode; class QSGTransformNode; class QSGRootNode; class QRectF; +class QRhi; template< typename T > class QList; /* - Exporting methods from QQuickItemPrivate, that should be part - of QQuickItem. + Exporting useful methods from QQuickItemPrivate/QQuickWindowPrivate */ +QSK_EXPORT QRhi* qskRenderingHardwareInterface( const QQuickWindow* ); + QSK_EXPORT bool qskIsItemInDestructor( const QQuickItem* ); QSK_EXPORT bool qskIsItemComplete( const QQuickItem* ); QSK_EXPORT bool qskIsAncestorOf( const QQuickItem* item, const QQuickItem* child ); diff --git a/src/nodes/QskBoxNode.cpp b/src/nodes/QskBoxNode.cpp index 58329d1b..4de2242c 100644 --- a/src/nodes/QskBoxNode.cpp +++ b/src/nodes/QskBoxNode.cpp @@ -78,11 +78,9 @@ void QskBoxNode::updateNode( const QRectF& rect, } /* - QskBoxRectangleNode supports vertical/horizontal and many tilted - linear gradients. If our gradient doesn't fall into this category - we use a QskBoxFillNode. - - However the border is always done with a QskBoxRectangleNode + QskBoxRectangleNode is more efficient and creates batchable geometries. + So we prefer using it where possible. + Note, that the border is always done with a QskBoxRectangleNode */ if ( QskBoxRenderer::isGradientSupported( shape, gradient ) ) diff --git a/src/nodes/QskGradientMaterial.cpp b/src/nodes/QskGradientMaterial.cpp index 7be7d994..29771012 100644 --- a/src/nodes/QskGradientMaterial.cpp +++ b/src/nodes/QskGradientMaterial.cpp @@ -22,7 +22,7 @@ #endif #if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) - #include + #include using RhiShader = QSGMaterialRhiShader; #else using RhiShader = QSGMaterialShader; diff --git a/src/nodes/QskSceneTexture.cpp b/src/nodes/QskSceneTexture.cpp index 8660fdcb..9fa8af44 100644 --- a/src/nodes/QskSceneTexture.cpp +++ b/src/nodes/QskSceneTexture.cpp @@ -10,11 +10,28 @@ QSK_QT_PRIVATE_BEGIN #include +#include + +#define QT_BUILD_QUICK_LIB // suppress Qt5 warnings #include +#undef QT_BUILD_QUICK_LIB + QSK_QT_PRIVATE_END +/* + With Qt 5.15 Rhi can optionally be enbled by setting "export QSG_RHI=1". + So we need to have a native QOpenGL implementation and one using + the Rhi abstraction layer. For Qt6 we can rely on Rhi. + Once Qt5 support has been dropped we can eliminate this #ifdef jungle + */ + +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) +#include +#endif + namespace { +#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) inline QSGRendererInterface::RenderMode contextRenderMode( QSGDefaultRenderContext* context ) { @@ -22,6 +39,7 @@ namespace ? QSGRendererInterface::RenderMode2D : QSGRendererInterface::RenderMode2DNoDepthBuffer; } +#endif class Renderer final : public QSGBatchRenderer::Renderer { @@ -31,8 +49,16 @@ namespace Renderer( QskSceneTexture*, QSGDefaultRenderContext* ); ~Renderer() override; +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) + inline int textureId() const { return m_fbo ? m_fbo->texture() : 0; } + inline void renderScene() { Inherited::renderScene( textureId() ); } +#endif + + inline QRhiTexture* rhiTexture() const { return m_rhiTexture; } + + inline bool isDirty() const { return m_dirty; } + void setFinalNode( QSGTransformNode* ); - QRhiTexture* texture() const { return m_rhiTexture; } void setProjection( const QRectF& ); void setTextureSize( const QSize& ); @@ -45,15 +71,30 @@ namespace void createTarget( const QSize& ); void clearTarget(); - private: - QRhiTexture* m_rhiTexture = nullptr; QSGTransformNode* m_finalNode = nullptr; - QskSceneTexture* m_texture = nullptr; + +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) + QOpenGLFramebufferObject* m_fbo; + + struct RenderTarget + { + QRhiRenderTarget* rt = nullptr; + QRhiRenderPassDescriptor* rpDesc = nullptr; + QRhiCommandBuffer* cb = nullptr; + } m_rt; +#endif + QRhiTexture* m_rhiTexture = nullptr; + + bool m_dirty = true; }; Renderer::Renderer( QskSceneTexture* texture, QSGDefaultRenderContext* context ) +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) + : Inherited( context ) +#else : Inherited( context, contextRenderMode( context ) ) +#endif , m_texture( texture ) { setClearColor( Qt::transparent ); @@ -74,11 +115,18 @@ namespace void Renderer::setProjection( const QRectF& rect ) { - const auto rhi = context()->rhi(); + bool flipFramebuffer = true; + bool flipMatrix = false; + + if ( const auto rhi = context()->rhi() ) + { + flipFramebuffer = rhi->isYUpInFramebuffer(); + flipMatrix = !rhi->isYUpInNDC(); + } auto r = rect; - if ( rhi->isYUpInFramebuffer() ) + if ( flipFramebuffer ) { r.moveTop( r.bottom() ); r.setHeight( -r.height() ); @@ -86,7 +134,7 @@ namespace MatrixTransformFlags matrixFlags; - if ( !rhi->isYUpInNDC() ) + if ( flipMatrix ) matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY; setProjectionMatrixToRect( r, matrixFlags ); @@ -94,11 +142,24 @@ namespace void Renderer::setTextureSize( const QSize& size ) { - if ( m_rt.rt && m_rt.rt->pixelSize() != size ) - clearTarget(); + if ( const auto rhi = context()->rhi() ) + { + if ( m_rt.rt && m_rt.rt->pixelSize() != size ) + clearTarget(); - if ( m_rt.rt == nullptr ) - createTarget( size ); + if ( m_rt.rt == nullptr ) + createTarget( size ); + } + else + { +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) + if ( m_fbo && m_fbo->size() != size ) + clearTarget(); + + if ( m_fbo == nullptr ) + createTarget( size ); +#endif + } const QRect r( 0, 0, size.width(), size.height() ); @@ -108,8 +169,13 @@ namespace void Renderer::render() { + m_dirty = false; + qskTryBlockTrailingNodes( m_finalNode, rootNode(), true, false ); + #if 0 + static int counter = 0; + qDebug() << ++counter; QSGNodeDumper::dump( rootNode() ); #endif Inherited::render(); @@ -118,51 +184,92 @@ namespace void Renderer::nodeChanged( QSGNode* node, QSGNode::DirtyState state ) { - // do not forward nodes that are blocked while rendering + Inherited::nodeChanged( node, state ); - const bool isTrailingNode = false; // TODO ... + /* + We want to limit updates to nodes, that are actually rendered. TODO ... - if ( !isTrailingNode ) + In any case we need to block update requests, when the textureNode reports + that it has been updated by us to the renderer of the window. + */ + if ( ( state != QSGNode::DirtyMaterial ) + || ( node != m_texture->textureNode() ) ) { - Inherited::nodeChanged( node, state ); + m_dirty = true; Q_EMIT m_texture->updateRequested(); } } void Renderer::createTarget( const QSize& size ) { - const auto rhi = context()->rhi(); + if ( const auto rhi = context()->rhi() ) + { + auto flags = QRhiTexture::RenderTarget | QRhiTexture::UsedAsTransferSource; - auto flags = QRhiTexture::RenderTarget | QRhiTexture::UsedAsTransferSource; + m_rhiTexture = rhi->newTexture( QRhiTexture::RGBA8, size, 1, flags ); +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) + m_rhiTexture->build(); +#else + m_rhiTexture->create(); +#endif - m_rhiTexture = rhi->newTexture( QRhiTexture::RGBA8, size, 1, flags ); - m_rhiTexture->create(); + QRhiColorAttachment color0( m_rhiTexture ); + auto target = rhi->newTextureRenderTarget( { color0 } ); - QRhiColorAttachment color0( m_rhiTexture ); - auto target = rhi->newTextureRenderTarget( { color0 } ); + target->setRenderPassDescriptor( + target->newCompatibleRenderPassDescriptor() ); - target->setRenderPassDescriptor( - target->newCompatibleRenderPassDescriptor() ); +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) + target->build(); +#else + target->create(); +#endif - target->create(); + m_rt.rt = target; + m_rt.rpDesc = target->renderPassDescriptor(); - m_rt.rt = target; - m_rt.rpDesc = target->renderPassDescriptor(); + auto defaultContext = qobject_cast< QSGDefaultRenderContext* >( context() ); + m_rt.cb = defaultContext->currentFrameCommandBuffer(); - auto defaultContext = qobject_cast< QSGDefaultRenderContext* >( context() ); - m_rt.cb = defaultContext->currentFrameCommandBuffer(); +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) + setRenderTarget( m_rt.rt ); + setCommandBuffer( m_rt.cb ); + setRenderPassDescriptor( m_rt.rpDesc ); +#endif + } + else + { +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) + QOpenGLFramebufferObjectFormat format; + format.setInternalTextureFormat( GL_RGBA8 ); + format.setSamples( 0 ); + format.setAttachment( QOpenGLFramebufferObject::CombinedDepthStencil ); + + m_fbo = new QOpenGLFramebufferObject( size, format ); +#endif + } } void Renderer::clearTarget() { - delete m_rt.rt; - m_rt.rt = nullptr; + if ( const auto rhi = context()->rhi() ) + { + delete m_rt.rt; + m_rt.rt = nullptr; - delete m_rt.rpDesc; - m_rt.rpDesc = nullptr; + delete m_rt.rpDesc; + m_rt.rpDesc = nullptr; - delete m_rhiTexture; - m_rhiTexture = nullptr; + delete m_rhiTexture; + m_rhiTexture = nullptr; + } + else + { +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) + delete m_fbo; + m_fbo = nullptr; +#endif + } } } @@ -170,22 +277,39 @@ class QskSceneTexturePrivate final : public QSGTexturePrivate { public: QskSceneTexturePrivate( const QQuickWindow* window, QskSceneTexture* texture ) +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) + : QSGTexturePrivate() +#else : QSGTexturePrivate( texture ) +#endif , devicePixelRatio( window->effectiveDevicePixelRatio() ) { - context = dynamic_cast< QSGDefaultRenderContext* >( - QQuickWindowPrivate::get( window )->context ); + Q_UNUSED( texture ); + + // Qt5 needs the extra const_cast + auto dw = QQuickWindowPrivate::get( const_cast< QQuickWindow* >( window ) ); + context = dynamic_cast< QSGDefaultRenderContext* >( dw->context ); } +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) + int comparisonKey() const override + { return int( qintptr( rhiTexture() ) ); } + + QRhiTexture *rhiTexture() const override + { return renderer ? renderer->rhiTexture() : nullptr; } +#endif + QRectF rect; const qreal devicePixelRatio; Renderer* renderer = nullptr; QSGDefaultRenderContext* context = nullptr; + + const QSGGeometryNode* textureNode = nullptr; }; QskSceneTexture::QskSceneTexture( const QQuickWindow* window ) - : Inherited(*( new QskSceneTexturePrivate( window, this ) ) ) + : Inherited( *new QskSceneTexturePrivate( window, this ) ) { Q_ASSERT( d_func()->context ); } @@ -195,6 +319,16 @@ QskSceneTexture::~QskSceneTexture() delete d_func()->renderer; } +void QskSceneTexture::setTextureNode( const QSGGeometryNode* node ) +{ + d_func()->textureNode = node; +} + +const QSGGeometryNode* QskSceneTexture::textureNode() const +{ + return d_func()->textureNode; +} + QSize QskSceneTexture::textureSize() const { Q_D( const QskSceneTexture ); @@ -213,17 +347,6 @@ QSize QskSceneTexture::textureSize() const return size; } -qint64 QskSceneTexture::comparisonKey() const -{ - return qint64( rhiTexture() ); -} - -QRhiTexture* QskSceneTexture::rhiTexture() const -{ - Q_D( const QskSceneTexture ); - return d->renderer ? d->renderer->texture() : nullptr; -} - void QskSceneTexture::render( const QSGRootNode* rootNode, const QSGTransformNode* finalNode, const QRectF& rect ) { @@ -231,8 +354,6 @@ void QskSceneTexture::render( const QSGRootNode* rootNode, d->rect = rect; - const auto pixelSize = textureSize(); - if ( d->renderer == nullptr ) { d->renderer = new Renderer( this, d->context ); @@ -243,7 +364,7 @@ void QskSceneTexture::render( const QSGRootNode* rootNode, d->renderer->setFinalNode( const_cast< QSGTransformNode* >( finalNode ) ); d->renderer->setProjection( d->rect ); - d->renderer->setTextureSize( pixelSize ); + d->renderer->setTextureSize( textureSize() ); d->renderer->renderScene(); } @@ -262,9 +383,38 @@ bool QskSceneTexture::hasMipmaps() const return false; } -void QskSceneTexture::commitTextureOperations( QRhi*, QRhiResourceUpdateBatch* ) +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) + +void QskSceneTexture::bind() { - // what to do here ? + if ( d_func()->rhiTexture() == nullptr ) + { + auto funcs = QOpenGLContext::currentContext()->functions(); + funcs->glBindTexture( GL_TEXTURE_2D, textureId() ); + + updateBindOptions(); + } } +int QskSceneTexture::textureId() const +{ + Q_D( const QskSceneTexture ); + return d->renderer ? d->renderer->textureId() : 0; +} + +#else + +qint64 QskSceneTexture::comparisonKey() const +{ + return qint64( rhiTexture() ); +} + +QRhiTexture* QskSceneTexture::rhiTexture() const +{ + Q_D( const QskSceneTexture ); + return d->renderer ? d->renderer->rhiTexture() : nullptr; +} + +#endif + #include "moc_QskSceneTexture.cpp" diff --git a/src/nodes/QskSceneTexture.h b/src/nodes/QskSceneTexture.h index 1a66f931..56acdb3e 100644 --- a/src/nodes/QskSceneTexture.h +++ b/src/nodes/QskSceneTexture.h @@ -13,6 +13,7 @@ class QskSceneTexturePrivate; class QSGRootNode; class QSGTransformNode; +class QSGGeometryNode; class QQuickWindow; class QSK_EXPORT QskSceneTexture : public QSGTexture @@ -25,19 +26,31 @@ class QSK_EXPORT QskSceneTexture : public QSGTexture QskSceneTexture( const QQuickWindow* ); ~QskSceneTexture(); +#if 1 + // to avoid recursive update - need to find a better solution TODO + void setTextureNode( const QSGGeometryNode* ); + const QSGGeometryNode* textureNode() const; +#endif + void render( const QSGRootNode*, const QSGTransformNode*, const QRectF& ); QSize textureSize() const override; +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) + void bind() override; + int textureId() const override; +#else qint64 comparisonKey() const override; QRhiTexture* rhiTexture() const override; +#endif QRectF normalizedTextureSubRect() const override; // satisfy the QSGTexture API bool hasAlphaChannel() const override; bool hasMipmaps() const override; - void commitTextureOperations( QRhi*, QRhiResourceUpdateBatch* ) override; + + bool isDirty() const; Q_SIGNALS: void updateRequested(); diff --git a/src/nodes/QskTextureRenderer.cpp b/src/nodes/QskTextureRenderer.cpp index d7279b90..4d545736 100644 --- a/src/nodes/QskTextureRenderer.cpp +++ b/src/nodes/QskTextureRenderer.cpp @@ -4,6 +4,7 @@ *****************************************************************************/ #include "QskTextureRenderer.h" +#include "QskQuick.h" #include #include @@ -17,7 +18,6 @@ QSK_QT_PRIVATE_BEGIN #include #include -#include QSK_QT_PRIVATE_END #if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) @@ -89,7 +89,7 @@ void QskTextureRenderer::setTextureId( QQuickWindow* window, if ( plainTexture == nullptr ) return; - auto rhi = QQuickWindowPrivate::get( window )->rhi; + auto rhi = qskRenderingHardwareInterface( window ); #if QT_VERSION >= QT_VERSION_CHECK( 6, 4, 0 ) diff --git a/src/nodes/shaders/boxshadow.frag.qsb b/src/nodes/shaders/boxshadow.frag.qsb index 9a7990780c64b70fef57497c0cc5678079420cf5..8ecfc828aa472382eb72816fe916e075d05238ff 100644 GIT binary patch literal 2656 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 OxxYvD%Krzc77pV!&2d2h literal 2639 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 diff --git a/src/nodes/shaders/boxshadow.vert.qsb b/src/nodes/shaders/boxshadow.vert.qsb index 4d37149243a5e43d074dc658723291e6f1a8ba4b..d9831605a22608de23815ce59e348623f0add7e8 100644 GIT binary patch literal 1559 zcmV+y2I%RM|3>IH3$Szi-bf(DpV;- zjpOqLw?6yuBMG2LRi%D_{?o71kI=8vf2ww7clJEC??6GN3N#z}ygT#Td9HmkNrVvN zLXAKt5at zhU`F|QL<>5d_+%(b&-k=%nrg`&wC6t0oSzX3L7kmzz4K?igNILBVg!^4 zDBzj{a4Inc;B^jMP(YQi0`LY0DqNPvBDVgjjHdLKpj$PSaX4>w;yK!67X4O^)z5vN znB^`nhh>U0OzTBr0o;Y7t55pM^1~-jt@}|J$JWE3mnM{b<8kQgWPqE>`vE3APLqNSkMbht*7N3P$tt1raX?sRW*){)hkB3o zgQf@r98lXsxlkZZspsRFJKZI$c8~cJxk(xY1tmND%_Ha=QoniHqm{V>I5pr~{R%OT z!V3yt`%_Sg;Qi}IE05}N(ylkJH`KTGs1_g&3q#KF`&#Rm6slmsqT)1M=TQbAkbahQ z;ChPIDCZj}^$rnls*f3!w2I`9L5ZQpIN|krj_#axfb?tH2;uHBT7_uKj5bQNXN)#R zwC9XAPBfqF)bh};lW@Pl{5(l9(CgEMIGm?7+I$S8R3v^>+Jf_wFvFtIgzFUG5jR0R z6V?aGZlt$pJxMg=8|1&{8x-Rak~c&0#-tr8<}eIOSChYq{usHGRg>5EU^NNv&|D?y1;r9l zQU1f)af}WPjfyqr1&*J#UGuB1o7lbuFKXXgzhh+d*z2~x#E<&(JK$!F^>JW#-59)g zO}VQzAol%AlgFQm2$lh&@ElMb@=jSGGtk=xeuoVzZB|#)7|LTmbb>~0ZEa|Iv%1=& zDS}GUyY~0~z{D@)!U> zH3U+5t^X`&iFhrVuXmJLAu9&Fpitt3rK+NM&WhCz6%nDT9q{OlOU)wRU&A%>^Z%m1 z&N$_!;9q{!cV8rn!JT>`J0EeU{-I=t_xxBJ{ITEj@0p(eJ@@t>dh5QIdhrjf$;L}<^&?EQxN{Wa8kz2SXJ1BykG_YpRrK-$~25bt3j36Yu#;un6$^G1GY J|3AYhu2G@K4xRu2 literal 1552 zcmV+r2JiU*03numob6icZq!x~K6^<*9Kt1B(iRGaP}l{u-9*bpY=c06S|lVQQlUyw zY8Kf1nPj_kibi$!6tzEPzVb`QMtVk*}>%2NyxoN5MaImC}UN>SUtIPnGiA1VS{(ODFDe$Q6~Q;4tv_*H4z8G{UIUXx(V4 zxGSmQqheC-G2))-c(|Vw>d3IHXHXxc$U8^&k)9$NZG0ofz@}PLDW)QMWht*hfz=u# zd_vFBZ_b+_-wCfoxOT)F)Q;?vCI%2 zWB8Q#i&V$6Oh z?e_Zt+Q7IkQqK2*!h9|>{3V9FLb6}LF48s9y~1>_GTl1)yGqz0_a7uWB7I*d-JaX9 zgV6CkeZJY$v@i-{E7I5EuJ%^bVfDl)s~D6+iK~S@A?6w1GD4AVaiz0&9HA< zkz#aR-vpCx96Z{JY%j<4`=;eYuiM&oThn6C>H0wrz3VZ20BgexUOV2pGHUsL&}nOC z1ktR;k*&CnXABdxPyo3__7>XlosNzrsMRSksiQA4b>yzQ#*!a85f)@o2GLN->sPtG zZA}|dQ@Bb$|1WBqNt9dTRb+sQ9sK*{E9alGP@D9(S}-|tv|JNvMLz}nqyjBj!aSsPb= zx4=yo^f2=~dSI_RVPprjwPq4);BOi|^9MgrnYFfBGBkriyQ4!LfAqWE(2i@5y9ZC7K6}{ARVnes0P`w| zAs(K_QNaaeFv5H;b-*k?XNA~K+8rY_cHHy5*sZ1MUFUsPmyJ9ax0Zz>ea;D>&I6HR|}U zBHtg3`mPyuF33GAKJG0bt3&p{$N;zY{yk#n&&FMIOUc5_!&rChl{-&WWPdZk8<8>R zc$OP?Z2haA9ht5XMjh8#yQ^jV(CKx)#E-_yyYM;|;x`M=?AakqsI5z__Kd4_(S?SXjK?BwuZ`9Tpzzi=ATQjT-zy)cFUUvHPO^&na{Uc(Y_52H CiwlAP diff --git a/src/nodes/shaders/crisplines.frag.qsb b/src/nodes/shaders/crisplines.frag.qsb index fb01e7de9c15f8fe71bad655c574129a2385816f..274f8d5544268d1261e03ef12bbadf8984a5f083 100644 GIT binary patch literal 872 zcmV-u1DE^&00~8SoXu9-Zqq;z-P{`Lrgv^n$Pfu7LJB5I5u&6jD&itlqM}eCRh8v9 zw!0A9(b_JNs{BSjfe+!C58?&E?Cdz%CiH;^Bvx8`XLjc7oU`kd8Dka3SedC-fWEc$cVT}SZSitwI{looM zlJ;AjElbX?AYY};D#VnDLg;W=AX`K#CG=HgK8&RA4&lEByGG**+Lei2pTtakRgxz6 z6)0|3^A*W=fa{eeKDqV^yzdcKZr>$)6QYV}mynel--MAA%Y=Rl;;STH8GU6`zC?9x zlf6j3+h7|sSEl?W$}ge@s@^2-#9l+XrYsKj(tDz(uQj_ z6%Q4v0S?fDR*;VAL#BWe!0qr2XEdT*?S^R68mkI4zrX9 z%%;E!he!5%M+9DKDRh)n2H2N$ou+g(Dk$mvYUW%jfhnecNB~NKXUAx$Al=i_SJ(LB zo_J{{q8Wg(zRzX)*z$e;Q0I|5$oii7Ec8-mV8ews;JqDV>Q8vse<&ZV(;YZ?36BCZ zazZbG{qRi8`qP=7oC^J1ljhpVrk&Q$HbKdXEy?1l{W?BIoQBmrIZ>H%F7zTTSB)BO z9Dyhi)^{KG46@Y;$MojpL(KDJ@0#ahRb@P*yZ#|*!pBN)DR>2;=)M?D6=xUId!udr ymv@1z_(H4r>$Kvne^#;78}sx}c%H^pn=pTy&D>~{dz;bk&dir^dHy#x?c~a-3$$qf literal 871 zcmV-t1DN~(011kCoXu9-Zqq;z-6m;Eo%GJ_2^k`xL`cCzDMEx+MMYesN>mgoq^h!9 z$8i^8J6hW%QkCE6C-5OW^Fh2InAsi2D<|{`Bvx8`XZFn5nKSFOjIkxgScR!E2Xlk< znP3j{*&d770H(+gzi6--149?sDN7-ov1{yO+C4jdH2Jh$Lk_4*6+-a+YX5M* z6(_w`XUoF<6{&~PZWS=k(5Bd*N8OZFz9O42UNs&IW1Rw$MU^A_M2NxX{mRb*$% zlvkJRCGy<{+n~J)#aAi5BsEa^W|%5*F4KOEIG3f)%69|oRmulze?ayc*%-f0Smb;R zXOvj}d0<{Yz=K*phbLk;h#xt&sm4w6??A*7*+1cgC-M|lq5h)Lqc@Ik^>a_eJPOT6 zmSqfu=W=PCasO;+_6L!Zbf?@r1g8-vB6SnJ~h6y8Zk`6uuA9bbU+;cmo8x0~c zvD;=OxX;6`F$Rh>!8E^fwjH5JBaec^gPsPqCW3qc?1$bH8c>#0ZU4ZsIArE|N z3eV?p;)%womGO$`iyb(hfLGqH&Zr~lZB-V;3?27#)bGb$(r~S&s!Kr?Q07s;LW=udrw4hY`;yDVVY#Z6hh#H!z25>BYZEh6uVRt z0rr)W+PS3Dr%iW*$W)~>0-z+{vmu;Gu)fS>Ldxj*JX?;$=~XFG5aV;=fu=mcI2{qRf~HS2d|ax3(EPMT{s zojR@Gb)v$IEv({C{W?CDJPoUPa-t$}FYrPwR;?Ot6oM$B%OCy xxouvIRhCgfcl|@sgpZWoDEPdjqA#oPbxnS^8U0UG=*rZ7<}2dl_zl9ku{*Pqy}clW z=n(3P!F^CH3tM=?ho38ALb&kH6M5jYBjj(oMDW@xGU6e~WC)EKgxCgmR}%?A{7$hT zs-gg`?eNs?yA0I^caJEEEa>-y16~QyO}uf2+pQah$blP0>56iDoU{4WBSDT>gu6^L zFfD!A;MGII!*x=7dv2jxDA=9}5A&Sq*^5rax4rm6GGRP6Ot?JvQKppr!u8BT(ariJ zD&@mw;Il0piqfH}7a!a>{!#|p6=~IRqR9;9ANs zjEbN2ot##@Sj8mrhGZUU$sbsE}m#RJu zu2BZ;-@1HvVrpvUQc{_YP%%~Y8+0(2K*#KD<{)ZWcAdPm0~6UH{Cv?_7&Gehic`uD;t%WdF~g``RLPZUb(+*Q;+-}h zucaF61BzQzcaMXu#uU=)%?g%>XQ>W)wOJb}4(rqgD^wezN`nBgkx{8*r`%eoZOAVAm5*zbma8}b_bs^Z!F>fddhK?|en+j}M^8=zXXK7U z)3yA7g#=?Fh3wL+$PwrcKhczI%j6zxDw&CiS(+ z8Bp84Hkc(LOt@bMJmNZOK1}$zon-Mo1bu_r?S$_pd`#L=aXGU!uOgp!tnk>s$Ht7d z=9v6v)b3>b2QOX#LEucoV-8#QT{~`jCYiH-;w=OB#ZPXL_1CNerEGb$fq-e z`vc;ml#u<3!hUdy!~74?bw( z*97r&9$X^%31;&$vx#$XxrS5x4>^I!4*lSUyjpe&u2+(02)LI5Qf>3Bq=PTz@?ALa8Z1Fko7@+? z!-eg(>(ylB<~t61$HZpe?$-TYUEl8w?R}$Pi9_j?r)Ma=lCAV=rPqIuUO!Xmf_BWV zr`PCnOD}khZ_Fzo%8{FyhkgbqwzsKs?NxnQZ}Otf$ktcDs09(+b2b^vlwYQGiH@-|?)X99^iy)A#53O-C9pFQ`YWtyefUghm zqe>7*oo*fTztTI0ryTQ#Sh6&M7G9mgkVhN(Kmb?QFZ=_6{_BE`eIV$P?Whj~TlwQa z>tn#y{20(Wyl)-ew+`=Hhxc3c@P3`cbUcpw{$(Gg*Lhp%aH@3>`n->=__2H_QD4rn zd@E5~iP|ht^#MOzvEG+!U-$D6zFLI-rd@xDRR0k`G@Rf!@I!y|`c!^{ J{6F~|#be=Rv#|gG literal 1865 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 Q|LZ%j+Z>Gj6C?0OCtn__e*gdg literal 1830 zcmV+>2if=l02nxUob6caPa8)NU%))-kfccy+B7A-LX(^m;~2+)!z)memxKfYlte=4 zbezxTTKmqrTN7v$^+Q#upZc-?Q~!qkBmL6H%+X9>&0Nm-zs9L7?5V0l*IUu?v?0Fz6 z{d}r|NnU9X;s6feQ$p8If{qCNHn=8%np#h2* zGb#Ojr-{GqHALSPjkP$?KRJy0(-7qo;$DJ;qs4O|g5OWpx7TwKujGm|c^T$F?Ds`B zEP}(kVSAV&b`$Or!<`)v{9)7qPq@<)WJA%PF||)AcAeG+1w9zklk~0ghMBA!#p@&7 zipJ|F-cyY?K)iL0mm=P##v3Hwj_`FL)`xzNC*l~VI24WX-_YoiMt=ZW`UQSK_=3-4 z@PwOVh&v@>8>S8W5a(o-jAaQ#k!bd!LZ(b+U)_IPtCmeS>1}Bl}2yO8QaW zAgt2&IbpAmKBR9F5B1$5eJUQLZ__%;n@r8H_IfrEKNkAW7k^q&{uG$39h9G==Ml1x zbcuKhUuLp~X5q7+wFdxVegV!P$;v&Hd#UJEqE`WBFj-sUl#?a$Z-V%vKp{P;#WX>( z7-xoZb6baL>AdhR)w4T>uxKA+@G@V7_ ze@k*RB#Zp-h&M~I;o34}?;7!xjtAs}qUVWLd08MoM`%siS|r&8&Bvu4d0r;I()W<` zrD#pXyh1u3lAo)@djRWb`wJ%Deyf_jHL_RM>^&m>4CBY zaW>2W4(lgPwKhunvEMH-+3U*QWx{QO9_**9#KZo7LAu9C4%dDIeMpz&bVw zk<&jndFY0b7x>0>KA&!euHy;nz^ffJjcPrx`9c@l^MRR;c-V5dvEQnuU#AVY8a6ND zN9Y|b2*#o76b#4pxf_;)AgoBPP-@sw({=ck&AmWpN8Ap12cv2GIvq4^$K%Hf={Mj) z%lE25*gzkQ7JO(d>1kv)nsqlUtQk&F55g@V0dr`F$DUs!|D8cRmx)qE3O&S8KV zawc7+?jVd6+>}_I{+fPDr#WIZx z|6seM3i*F}nfzZM@1{V0)C%N$yFh0Cr3K>o9kmg(xFO1;3Rx;6?#%V_AF7r(31=;o zemZy1mD+FsTy;aSFY}PFnioM0nEUxShruhWVSfpxgrCKuqA*~|>H!%r^i@!;MlLs< zydF|P0=242po<*|5MZs=lHlCe-Efh{F5s&kK*(JJH`9%xq$Pp5Zt5>W@qhFPj7EN+j?%5!yt;RXMVHA z^};1JU~A{m%ksv?)>>W$(nENo#S_w+JD zr04f)_TAl91Vg1BIKD0?=7{IlJs-xAWpfC4zr|h4f_ACDvX3K6E@m>x*5(JHYgd5u zBQ8zdGN@72Nvt9VqBak+>b2fxZ37*iI2_qn%3^W%oNe$Sdb`s^2sZs;6LMl{m z?CoV`0Jbj*;Fjn`0La&$$na_508*VIB(!&QXi+W*SSCJhDIf7(GG4z~c#G48{GZUB zpQmx=`MG$a#n12Jv=JmmLC0Ln>U*Bp>#oCyw)24;7&tKoMSkdXk~pErU+wYg@%wLL U#GHy{to>`nXoAoF0C7n|7(Wh=0RR91 diff --git a/src/nodes/shaders/gradientconic.vert.qsb b/src/nodes/shaders/gradientconic.vert.qsb index e1b0505ce22435643e08ffde070d5f92dd807372..f807bce7b1287f7efd47d412f9699dabc4694044 100644 GIT binary patch literal 1624 zcmV-e2B-M|03<4Sob6g)PuxZjU+#{7hJ=I!+O$dIgcR<8m1_kiY0+$!n0A>;=e}ghmaFb->+yf&|WK z%vSVgPSKC(F1E`WtOBDRc*^mXg6e|1pVgQJmITZN`x)z_xyK6biX04s0S@!Hvq8ey z42krxHrFt$5VAT5*&w>k*KA!F()v9fW(V z@G`_(R(M(Btth-4@zxYxC-FA9t=XnNw0jVqcNIU7zN6T9kH&pXOqTPce3AS{AFcs6 z!{xKwHgP<&e4FcVe*}2MbE8{Zq#>`Y`H@EkRBx75YX4icGN#X^mU?9eu%K$%KQz*zfWk~Mfz@$K1TRk z6hEo&Hu>Jg`6AXD&3#UD_sCYHM~Nrb9wXg|&(qoiMBgW@)HlUsp%VI#E-JpFZPSW= zq-ROzEbNU8i%%_L{s0c{wMEL?CCbezLtvyD1G3MjMm+_dOc>Dx1NKX=Gg7jd149e*ktz!^Q+WLTU^aLoh>k9=xt>8*D zCw-bB*^(kVr^wFIdUJ&R6SDJ=XNcvf4kGb$oVt!*M)sW`bbU{MFjLgDFbW!Wr0+H= z+AB?mt7b(d{0ZE{1}lP0yvPZbd_O1)Zl&s5k#2=`$Bx#m$n{lr7+FD-VAL&7 zrTw~PyV22tcD$fz4bQFkK@Dxt8}I`xzY)>8Vnx?OvIIXt_~sEr zHFUi_-Lq;A1mAXaF164m;XH<=!(`Gq^S@0y8G`;6O-Q(E4kcdS-fo0Wkgxi-S1j!8 zD7s3CJZx{*X^5bdcGpYzs-_7N@^pzK@05uOLNs5JB5rna1=I+8358G2<ZU~m-cZ<^Sz&|i+*0+8TA9Y;Kq}Aqih~0O7r4l+(-Yymr1%Lw;-&)Wm6)nJu zpRHiyWg5;in*tuR0Yb)Ga5HHX?SodJaa0gn1GXnvX1A#!3yG=bCQ0HGc~Pel?;tt? z8*9(jpPNg8ABN^Lub!-M$s#nbZ+^YCw7R*ep|$VxkPt_4Z}7z4~Mc zo!2*>E5SIHX8_GK-~1q$uR93lYYsxKQOzrwC)K@L_$M#bbcn>cPNhee^&H01S2anC zDj;1lV=IzCWoJl@6i>luW1kTBIUztQr=^%D_HYU-lVzuBdvcLuwZ>p+KUBUMe~nB0 z^tmbV@!a|SiexNqv>^LOwb3#~+_!7Ah*s4}jh2fhi;%x)s=Pl{)a9gLRG+w;@G z_z*sC)m{j`xPQCoh5S#wkbm3r_>fx~@32SlzBM0MvcG(Onh$5G1gAd>TmJD$w)(~Y Wn@N8UnGI3up;#U literal 1617 zcmV-X2Cn%403?Zcob6g$Z`4*0KH1&e93b41mKKU36n43oCEXB28U#wK1}RdafDlp? zS&rA6y4|&deVhv@PgURg(idL(8~OwKWBNb(QnfSZjO}B4H-uJAA;ieLo;lxK&&>F& z2xDxB$*TnSINM|n3mAvbZ8pbz_!qDytW*&47hNoOon|I`0YWChQ3Ydta1Ztp!9|VP ziiOf%77#wb)>y<^3|)?r=jRG)0PbU~!z}P6U@nBf*a)pXRB$KbhjH-0VV;OL$i!PB zks;RQ8V3s@+W;XOM3;p<7eu9>^KrWJmj*%{z?feNUFZcJ68bH0O#+vC0Z)Kg1lr&L zXFCLc+6(?quRi)dM&HeJsq#~~G%<(}4cxv>+*6Q26dHj|!S8Pto-7z4ZyJrMy7ar8 zC?2IOqsJY~#hBSJ8M}(Iu!8hwq#NmD3Ox^Wyrunu?oa561e5Z>S@9h6`Uv+>;gyIt zukgymTTplv;w>q>e&Rh9zLpbx==W*(zO2N7^d-f|EA%{)V9J7r@@L?)B=BY7i|p94 zD0?05k3b*BHb84S&_m=m@@I%1CLZE7!dD1C!s6bP_z~I%jmB)0+V$T>$^y? z4+y@@tww8~)7lmC73r(Qi)~*c-H5M}?NOp{5f=5`g}p4XvD&aM+b&c_YP$Il>x^i9It zAU&90gZAVa*)a(BCuHlM98;BehOl%_!9xF%I;ZZ@!rRTMVe#B+PNBfjtV-qU6gS3j zG`rrP*@g6N79YB#KBVhPtmxaMq95tIr1NO@9qjCjeZ50_^av>Q>k9=xso)y47RNM2 zvJFLcT9Lg=_NEEjW!56mWXUmP) zo)L^q$DY(}$Ky^g=lelZa$9ZR;<^=XI5uClxa+IzkXr%IFg7etrTq=dcKObXwmYL~ zk>|Gjpo2c>5qtn^(+YN6Z=GyQs}={J)*|j8w*emkcecqRZPRy~I!0WrQ5-@_pH*?j z_Kto_m@o?Q2)MDMU!RqLLS*Z0bIA`~j+rBj%#waR>&vdD^+-S5eZL;Y^rvf5zxjfj zu;2vm*3RU>#!G-Ft^!zH+v>KF+bp@%KAJo<8~HBnR`2xZ`snba|3m4c*GeBfPd9Sv zo!v-3;+ai!z4xwpUMtP>%c03RFb{95l<0IwSNS&^47ETGvvgk%oOL$@$E$1gIL^S| zGCS6Heju~b*lq~tOmgnN4mtncZ?!^)SM7RD*^WsGR8o;cH&nC)D{0Atjh98ZsE7h^ zs|ye+C5M|TqNslIKx3ySOA5*wJhLeiYNls0OG$xc@!8g<7J0Jtc=?$*7x-alKK3>u zPI)iNfLl+$em=LjxcpUJ`qM?lV#ISg$eFCPVnHpu`}&h-N=&$HdQ~8^3 zDF05>t}2>uswGzwHC>EZwr3%oI5pNC)5Yi5c{QoCD!?doni9EWbTKRy_=1oim1AT> z%M?uk8>iJyJqR2g1zyg`Zm*_>SzMVvYU=-~snw;-`{Q3Wdm2(Y=~KY;hdmA6{)Ko@ z!z1+~3sfrOeVH*8mi~Vrj-1^I*R$JE)6u`|INWMO*EZYk+5;`+hi<2N8$XP1AHZ=e z#Gfsm)p4M0ZATYUGhI%K$wX35i*fD#hv!9d1mmq^4!U*C%1RW%AZ`1$SFf$E_UxRM zl?{4CP(i!v_3rzXmEsb?DkqxQPW5D+w3YM-cf*4UsHL=*1jq~_k%9^+YLs4Sd%*&7S?lfeb4o7@{DZc P^~6_RUR-|zA(JGiM*lJj diff --git a/src/nodes/shaders/gradientlinear.frag.qsb b/src/nodes/shaders/gradientlinear.frag.qsb index 0d0426783b8b383520696f0bee424b35d38816a5..be5fa92c530aaab819c11b1cd8d79624d60c7e02 100644 GIT binary patch literal 1444 zcmV;V1zY+601;7moaI+pZyPrdrX^q9I7ySbX>)I^CS9eDsv1t3R;DBzC`8YC2A)(mYV^e%^6jJ1&fft7ZI2W7$d42w~hDek@kTqh2V|rFAz*!X(`S5~PPb zJ(h8ou(V_&Zi^!np+C)eqC6u%awDzLgY&7e2 z2oDew*@h*_*efs$Y>%fra#sf2qqH0P-=@5~&K2Kn?iC6UjW(#ecl8<@{R}t`?k9Sn zg#T(Ke6OGI`~O|SlUy0#4y8Qc#CYX2^A zFR+T%w_!Y9h%uH9GC3~c=5D(>7S#dTPInvjN_c72e*-q*` zGWjfc(}b}={%#S*0_7Wd9|HXe*-TK(NZ+<%yhC%udjLKvtbZb4oWBESim)+{*D0SX zwEi0u^D1axC;BU}z!+~bbAloN3GmR@rxf393&SJ+FJxCITaR$B5bqCI#Y1==kX~^* z;y!-~dKi~OG0zb`?%f62x5D2=(%S@_d7UT2!@Yb#*q6u-Wq$%5(htp>Qq(!7YKfJj z$^&Q$9g*s0_%-yWuFRB3z5Qm{vXWPR#D9X8qFc}M(XwtNzUjJP0}bV6(&=PEc|o&o zbzM?4-FQfG*;X`q)R~49@7GP!-YJf(M+SSf-=Xce6-Kaay7;!@O1OTh=TmpL^)u9m zbA>Az6j57U-WCjYdOC`>H#fGP`)g^EW&TFo%hf=e?puJ*oo{|zd-iN=y=fLS2H;t) zh7hb^0Ac&Nzr)k6Py|6L?>=wJ6f{g~ywRjA8i)27)UgjCjKe?8lgPJEqR}jvQ*R`_ zF6>BG_!8$uAXb)FY!yHm6}P%X&|&Tn_@gu@717QFB)Dy{z>B zBI0fka=6d6CGW;bhA*6iNh;dz!o3%f%rdy`-Rq@^O4M;rWDAZ{lW`E{ZQ(wOgyNwO zhj1wOS1o=fqxR?c(>Pd#`wc?4F^@zBSr@LhYK^&2l{Ic(s^~p?$F+*EaIH;T|4Hxh z?ylY!uUX&Q8)GTslS*iJH_xDC!z74pTV0_t4rL6*?sElk@8?SRzUT4q6+g~=Bdphl z3q~EJg13Q;GiBV}aq0CZQE^djo33Luol?bE7peQ+yhy}W za?Q*uQU>dX^c3&@-rk}Ki^qCz@92U91=H(w<`>_xHqb0?s77`C>d>PRXtjEICof{e zXT^Q}rZuKt$athYlcD+=Xd8=m>W8vCa<{c|o|r1cGMv(p(Y>P0$~)A=&;75AX4C1V yB9NLoklllxiMutzma!UFK&SmhVx0Z&J_IYHcNI;Ke7VyX{ZMN?S@&;Z&k$F4LC^C5 literal 1424 zcmV;B1#kKQ01<$AoaI;DPa8)NUoc;FNYbPIX50I)?)C^M%5&fP*uScOP+$5nvpaXU9EP-N)IM~jvv+1^elz=(iF}4ahSzAJy_` zAvX$}Qa8>_jdI-(**&&&!=&5L@oI$*V>c?fHYisd?|{{?mTQ^`oL_?(671+_M8_W| z(%%Dlg61RIZ-l+YOsk;Hb&xL7dbQHId=v05!S_YNzf5}6Es>m`$&W!E(|MYK@uvuX znEbCZ(+m^jkMa%D;rdOMx0G2&d75Z;|{tcwmknFw^*`e*!v; z^%3QF$HH(){}cH&$=4;^8>IUUcJUCN2V|FDDp=>wzz*}OQ_howkF~o(b<5*jCA$s4 znbJHN9oBM(u&hPPlU(S zUf_L|@ZK6%e7C)q8$dSNq3PVyJ8hLb)a#WJ9kF5zeOs1jzWp!I{=X#rXN&N?lJLd< zj_^2B2Dl45Tg8Q?x{Urg|8JiCBEi2)Jl@;$CGj=xgK<|Rnxrov@19JRNZkE)v6c9R z7xM2Rlul{kXh8??Of|p<0{swoyQxsF-)>sfAVX87is6E7XzVECis53@6mvU2%8v~8 zN?AEOZ-p6bnd)vSu7u+ib{&Kp-C0={2=QH=TRsW4?Ors5Xk)%OP|WH^9g>m4p!jaLkK70p-6#s;b^Zx zKPZYGw=Y{dXRo<#2@Chy#{Hjlj(2x;UEFqaZ*PF7jLvGI-Q6sOmJMP*vVC=j$|#T# zG`q(Yv&f;7Z{j(U9)`NcEB=! zOBvI_yTgcPL7O#;_i~;iKFiL_S4#u#1{s}d#kkT-C$5M&o9znAr`~TC=dtNHY`IaL e8NKi-FFh^mG2kzKrAN=TWh7U9^!O7u83^EqYs;Jf diff --git a/src/nodes/shaders/gradientlinear.vert.qsb b/src/nodes/shaders/gradientlinear.vert.qsb index 55c4d629e7c1a141bd3ae663a8de54dbcd0aa6ab..4a4a0b36b8119e3e992b7dadc3315511c0600028 100644 GIT binary patch literal 1582 zcmV+}2GRKd03$1Sob6g|Zxcrl-o$nSCcHzTl#+uKutP8=BtT<=K%r_QAteHYDxv7) z*yr?G`!3v_i37@~s#3pJs@ndA{-XYseyQ4--DiD!X9ox^Rnq#R^X<$$Gdnvow`&gw zA#y@p!*qWjUI<47BBIZZSP(w_1)@%pEJOapC6d=MVTJ*^@T6V`vh8MK*@##bZPB37K6>i$69bi@drY)Mm3#_>E3F=Y?4E%;q6cGg*)@Xu z()BEWM?|0N5P{aoc8x4YViR61>lp3i8pE?5FE7{33{Q;mFi-2d1HnEbV!s@-H?6Ac>50baF4BF2^-0RSbFlvf(R#5tN$0xsL>CkD zMiCs%8v^d0!5ao|S2wmCQZksD2) z0X>gg9Yj8sh|By#;2nfb_Uk@bJSl5I#r=e#e+qo9e;T|~hW@vt&$16;pD}mI+x_5a z`ychOe-?ag|6}mZA_f`QIs@4}YShBoHGLjy|B>e6*k1tVyn&ejM$@09bS?tJ{O`fL z1X~y3$2fSrCa#4ktZ5QY4t^jVrmq20f*r1*>q6DtB<8se9NS<&W>81> ziQ;;`W#DfbxZ99@2me2X?rlT2V(89cz6!8^P)2X7lO~HjGArW!n6t7m;d-@ZyY5(b zT254L+O*v^-PODKm>;^W`ZfM2eRVgVZ-=h8W_i_?6RuZljwQ7!`Ft1!?OJ55wj23Z zd5f+_)2~J|of)fDjRLn*F__j1rxy8v!LocZ=0=;9{8ns>T`t>xJ2EX=HNWWxi(cL7 zSkIodLnkOS{hC)UuB;@cSZmtLe&|N7?-6btLk9KC;Ccy{$-5wOIt#uZ)Je4(k^8Id z$SJ5fSY07v2i2&c%~>wb8AjDLhp3g6DRSB)(v$JIWVPv&0QA`)_t|U_9>f;;p0{3Y z8H<{>Xc@$Gy^`T#sk3Qal_pCnti(ttQJy@~G7&E~6oMux8S$LA>V8z9Nv5Py(YhuX zJO(FLGvf>6D$&+t%0ZDSL#9RK*uW`Jm-)FqLZ&IJIzo-VAys`9#KGsq)`*~!OiWBVltfauDmjv&w zj=-jDBb`J(Pp9J~X2)u3JCOmOqt|WC4I|oJR?9jxfxlt5s$cs-yfw3PHk_NYD1G1f zjYjB1g<83o*i9u+g(d}@F@Xw)I!FO$i>ffFzN(R1>$6W+Qldn#Oi`jf5(2Y0P{)s# z7au*f7Xm*F?L}`rd730Q`#I~$XJ0NXEj@ZrHWwA=BnI3{oFnEOOYLZV`y;FW6v^Xi z&U*aR2+Ec&bavHFRD0rB=v(jh8_xv$pRV{;yIC-NnKG-aSK%$HzBjt+o$tx4rH@=1 z#~VVN-+2?zdql-vB!NazX^TjMV)XG(sr!;pAd{0iJQJ@#4>pkxv+#{mH96f@db6+N z$qzf;?901vv)|)8dUA^vBJO!G`xmq4q4(~c^*r_|OQL_zbEAP?&3*U(E0)3n%i~s-t literal 1592 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 A)c^nh literal 1526 zcmVSZxuxppZ4~FOA*0>@(_kraThL^Yf}&{ZNOHAgoLJTz@%w5 z)7`zdtNXawoh_}1pZ#R~+W<7uk)@REg6e&Ti>`1W*w#^C;igTFj7*lDn70X6-ig>-9|I2Kv?vEtq#yg` z6!l7J?=<07DZVqr!~S_ny3djv?)?t>kiMh4bByi+Bz#u2?8q;(yFr$RX~IA1cCA4c zc%hj(~I$%df+>hKZGSOcVQfzj&K%#U{X>j;8EmNn& zvKlqqW7Qbht!p^f{nzU9f3L{TMn%4_D{||qgse5KuqaW_;wYK|u zt?inveK0NhTph?Yhtl)|H^g=6nRa5)-0FDsbz_908AFU|(Nqx{WO6!YFh-jgDSuhP z3-he%KOyV0`rYgRRK$XNk$@+}4@EyobL_Ve7Fpo)nHx{zFwfzExiQF6nace^kk44w zY?yda;RpO~97qwl@V8PFZZ8@9JdFLD_|e%}f*TW6@I=Hx4!I7vk{b3aPIV=imv`CE z&Fh=^ueiX;2IioPc{!}jH#b#x*j;C9Ylvi+3_D$$n?(+%I7+?5lv9T`OrkJ>^Y01? zv1}JIa9!IL(KE51yL!`cnrBJwWP$L3OmeABUFCE#%IDhGH;{1wwacfdW~~FA9eNry z+7;P z7P5}>nOvRXejg=i9rpLr^0U2#4(3nSEyV+1Z)n1{h<5 zOk5fGTxEOAWG?gJyThu?fghJOU?zuOCP{LKl zAZU31;mPI`&GQ@D@=8f?%5ogeO%QEl)7C8;$D_2^4BEmB%Ab>Ol*c7`4dgJOgIpf$ z%K0uP(g9gM4s`>Bdm!mDq+648S<-EA4%sda`Aot6mc$R`FQm1v(Ri$j$#NaqUxx1t z$7lH(q6o4OImT4@d;OKW|g648O zu0wop6XZW!8~t1&4wK{uxdXAH1`?tzec`Mo*`Z6 z>pH~`@i)lV1j)Aui~hcbm}gj&;i&%`G?*V1iq8d#!8))(J{L)MfozcTL$H|U=OOla zh3toUoQ3`uzzp*^3LmIng%w9hhdypFk*`y?DslQ9Y!oJP=qBmW5AHEf zak){mbnp!E(xGv+TgM3IBp|>UhaW* z^@bIANuc&hh62>!3B=GOpnUhOcgJJbwDTUUePMt3S4P1D`^d_6200egC4mzW(%4N#0P` zsRXz$Hqv8_^}tUoLc8eWKDK?pY(AHQfotqJR)f>5W11AgqZd9a@&>fdfx4JFSFx77 zNJVW2t%78@AZJZ6WuUzRlPC&vvAKO2B2_z<{-05`4{YXv zwTH`nxl-z;7Mu%3sg1cJjwsxu0jZTdXs#87Dkm`&q)4g2wwjLH=Fb&8c~AjGawuF` zHj0T_17*6-cz(WpYHCNMCdbh8Yfeoi!12;j3U`i0FGTpP{VH$SMk{ET>UV9^*IRXX z-)ULft4gHztajrberZ3hLeM>_$z&8tG4gP@Qh=`mR z6+(Bag=>bzy0x_cd~FbI9ABs&mQps7i_Lgbpq>4J8 zYH?4oDt1KiVmb|SQdGVjseH|-e3wqXeD`$s0Mk=0;qF=WsN`tw)D|=zK!fghn~4sf z^x+@C2}U^{HpZfc5JH#p<%aMcO&qTw9OdJF4dE<1`%NL@XK6pk?Yv2R_e~B0}6U zf1J07@1RAD_(rexGV1=v&`2h1c&7t6x!FlV_K($qvUmq{3R=+jR_1c!nCRS3LF0G^ hI`>@qwJ+@A#eZ~J>VF}r`NW^|-Z-DK{|~_h0=*k1+@$~j literal 1472 zcmV;x1wZ-#03RcGob6fvPuo@yeWK?;nG(b^*kHyPes2L>jydA@EU-wc_IupY-a zfDC|Hz`-N%T0ih*@VN`{I>3E)K*?+n-4i8?3o9spO1@DZm*h2&!=evzc`%am z5hm6FS$-et1_<{^(q%}uCh4-I+u$6s5f1rG!OuGqKa@X{V&9ZtS*RRiDx4pIKjb__YbwYi#0T{il1E90c!lse!jG|VDg=Iv>WjLML7t$s9IxvT z&uxPIhq2Mm72+^Seo&qw-89Hoi8K10Bl#N1Xg^KZVID`+K%uoyi2n`pjq(iXLSHwj zeu%$Cz9vY%Ls<0p71TV#;weD=U!cMMs8W3{Q4Q9C4f456x=Un(oF9Y5G=Cl<&ue5q z%K*HQRD{R%`JB^~;>#YDeOQ4UqA`EAmNoK)iUJJ={p^w4e6qaVyMPj$IT zaq@)w8yJ5rMl~1C5sPOP7IMBks}E@5-DY)^-}jrUPjnUMngbZNo3) z#kD#WuGll{i)!7pebZfa9Je89U87+Io=`Mfj^V4$u2HxAgNkxkQIx>8nvUB>=V|~K zQ0*D+fo1QIQ{m3=A=q}{o2V_r#r4e&g;Mq$tD#~lg(4B;R%%toX`KUgfrrq#i0-uX z4ac*5%(yBrB0KedGSs1>^eG#h1Lm13Tf8Rx>o0vB7EJe4E1CjpuK*q~0kFKb-|GQ% zSaisJyZHV;fd92`!?LCN_6(Hmob>G*sc$Fa2e5Sd55NihMDZ>AeQVY?QnPNp|Fr_; znQcwneJ#eVnO&_zpeER15tdcg+_601RoE_tX}He5-Zp-6T#8RvmMQ2`Q9NAe9K*NjL|QINC9xDe>Lfln z9MpxI8&96S&{ti@^Ykb7Zs1dix@~~e^Y4CGU0;9pZAtLy;bJ}TQ$C1H(prij_sFuk z`9jL+Fzi8Op&!2y^&=Xw9kdFP;k^9ti@dwKQxbE~RV@`tykqJX-iO@enpI_h*46V; zVnWd)uyEjTL4ah9mP{?t6J6M_YW0|bYx;p}r-B^z8!vd9W&gYwucOCHUP`=E|Kr%j z3B|9+81V31&*i&+Bu;CLV-`uE^x)6RwC7m-fAcu}U*;{l-U=F~`c2#Pjh62Djh3~& zqQrX7YBwI>Mf-6Db|4<^jBTTBdN5?B%B?Crc0JL%LEiadP=mFBf1IO zX^@jj^%HzOGJjn3(+Tubug`#tdiWu9UCM@k4*(~B64H?UWA$t57mDa_mW=-7o7xd| at*73hZ(Z+Y&nQOPPk5y5`SC9%Dgxx{-1Yka diff --git a/src/nodes/shaders/vulkan2qsb.sh b/src/nodes/shaders/vulkan2qsb.sh index 22e28e10..765f5127 100755 --- a/src/nodes/shaders/vulkan2qsb.sh +++ b/src/nodes/shaders/vulkan2qsb.sh @@ -3,6 +3,7 @@ function qsbcompile { qsbfile=`echo $1 | sed 's/-vulkan//'` qsb --glsl 100es,120,150 --hlsl 50 --msl 12 -b -o ${qsbfile}.qsb $1 + # qsb --qt6 -b -o ${qsbfile}.qsb $1 } qsbcompile boxshadow-vulkan.vert