diff --git a/src/particles/particles.pri b/src/particles/particles.pri
index 9b41a30d6b9dfe6d4f5437031f8355127f24b112..b391050a58b701032e52026f25497b161e0459eb 100644
--- a/src/particles/particles.pri
+++ b/src/particles/particles.pri
@@ -63,6 +63,13 @@ SOURCES += \
     $$PWD/qquickparticlegroup.cpp \
     $$PWD/qquickgroupgoal.cpp
 
+OTHER_FILES += \
+    $$PWD/shaders/customparticletemplate.vert \
+    $$PWD/shaders/customparticle.vert \
+    $$PWD/shaders/customparticle.frag \
+    $$PWD/shaders/imageparticle.vert \
+    $$PWD/shaders/imageparticle.frag
+
 RESOURCES += \
     $$PWD/particles.qrc
 
diff --git a/src/particles/particles.qrc b/src/particles/particles.qrc
index 582520405f3163b90b2a09cc3b0ee16751f88c2f..689a5fb4e9444150934ec70f9e44d80e9892f690 100644
--- a/src/particles/particles.qrc
+++ b/src/particles/particles.qrc
@@ -5,4 +5,11 @@
         <file>particleresources/glowdot.png</file>
         <file>particleresources/star.png</file>
     </qresource>
+    <qresource prefix="/particles">
+        <file>shaders/customparticle.frag</file>
+        <file>shaders/customparticle.vert</file>
+        <file>shaders/customparticletemplate.vert</file>
+        <file>shaders/imageparticle.frag</file>
+        <file>shaders/imageparticle.vert</file>
+    </qresource>
 </RCC>
diff --git a/src/particles/qquickcustomparticle.cpp b/src/particles/qquickcustomparticle.cpp
index 9bba3ebb1805eafdea4ae329ba581e353e11ac31..71d58ae3919f3d61647fe843fb3021cb7daafd50 100644
--- a/src/particles/qquickcustomparticle.cpp
+++ b/src/particles/qquickcustomparticle.cpp
@@ -41,47 +41,11 @@
 
 #include "qquickcustomparticle_p.h"
 #include <QtQuick/private/qquickshadereffectmesh_p.h>
+#include <QtQuick/private/qsgshadersourcebuilder_p.h>
 #include <cstdlib>
 
 QT_BEGIN_NAMESPACE
 
-//Includes comments because the code isn't self explanatory
-static const char qt_particles_template_vertex_code[] =
-        "attribute highp vec2 qt_ParticlePos;\n"
-        "attribute highp vec2 qt_ParticleTex;\n"
-        "attribute highp vec4 qt_ParticleData; //  x = time,  y = lifeSpan, z = size,  w = endSize\n"
-        "attribute highp vec4 qt_ParticleVec; // x,y = constant velocity,  z,w = acceleration\n"
-        "attribute highp float qt_ParticleR;\n"
-        "uniform highp mat4 qt_Matrix;\n"
-        "uniform highp float qt_Timestamp;\n"
-        "varying highp vec2 qt_TexCoord0;\n"
-        "void defaultMain() {\n"
-        "    qt_TexCoord0 = qt_ParticleTex;\n"
-        "    highp float size = qt_ParticleData.z;\n"
-        "    highp float endSize = qt_ParticleData.w;\n"
-        "    highp float t = (qt_Timestamp - qt_ParticleData.x) / qt_ParticleData.y;\n"
-        "    highp float currentSize = mix(size, endSize, t * t);\n"
-        "    if (t < 0. || t > 1.)\n"
-        "        currentSize = 0.;\n"
-        "    highp vec2 pos = qt_ParticlePos\n"
-        "                   - currentSize / 2. + currentSize * qt_ParticleTex   // adjust size\n"
-        "                   + qt_ParticleVec.xy * t * qt_ParticleData.y         // apply velocity vector..\n"
-        "                   + 0.5 * qt_ParticleVec.zw * pow(t * qt_ParticleData.y, 2.);\n"
-        "    gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);\n"
-        "}";
-static const char qt_particles_default_vertex_code[] =
-        "void main() {        \n"
-        "    defaultMain();   \n"
-        "}";
-
-static const char qt_particles_default_fragment_code[] =
-        "uniform sampler2D source;                                  \n"
-        "varying highp vec2 qt_TexCoord0;                           \n"
-        "uniform lowp float qt_Opacity;                             \n"
-        "void main() {                                              \n"
-        "    gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;   \n"
-        "}";
-
 static QSGGeometry::Attribute PlainParticle_Attributes[] = {
     QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true),       // Position
     QSGGeometry::Attribute::create(1, 2, GL_FLOAT),             // TexCoord
@@ -309,11 +273,18 @@ QQuickShaderEffectNode *QQuickCustomParticle::prepareNextFrame(QQuickShaderEffec
         Q_ASSERT(material);
 
         Key s = m_common.source;
-        if (s.sourceCode[Key::FragmentShader].isEmpty())
-            s.sourceCode[Key::FragmentShader] = qt_particles_default_fragment_code;
+        QSGShaderSourceBuilder builder;
+        if (s.sourceCode[Key::FragmentShader].isEmpty()) {
+            builder.appendSourceFile(QStringLiteral(":/particles/shaders/customparticle.frag"));
+            s.sourceCode[Key::FragmentShader] = builder.source();
+            builder.clear();
+        }
+
+        builder.appendSourceFile(QStringLiteral(":/particles/shaders/customparticletemplate.vert"));
         if (s.sourceCode[Key::VertexShader].isEmpty())
-            s.sourceCode[Key::VertexShader] = qt_particles_default_vertex_code;
-        s.sourceCode[Key::VertexShader] = qt_particles_template_vertex_code + s.sourceCode[Key::VertexShader];
+            builder.appendSourceFile(QStringLiteral(":/particles/shaders/customparticle.vert"));
+        s.sourceCode[Key::VertexShader] = builder.source() + s.sourceCode[Key::VertexShader];
+
         s.className = metaObject()->className();
 
         material->setProgramSource(s);
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index 01cd48766452e1bd4426ac62ec1b4123e44db6a9..baaae86870e46ef24b4d6ac9e11fd2c137f0d970 100644
--- a/src/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
@@ -51,6 +51,7 @@
 #include <private/qquicksprite_p.h>
 #include <private/qquickspriteengine_p.h>
 #include <QOpenGLFunctions>
+#include <QtQuick/private/qsgshadersourcebuilder_p.h>
 #include <QtQuick/private/qsgtexture_p.h>
 #include <private/qqmlglobal_p.h>
 #include <QtQml/qqmlinfo.h>
@@ -64,183 +65,14 @@ QT_BEGIN_NAMESPACE
 #define SHADER_DEFINES ""
 #endif
 
-//TODO: Make it larger on desktop? Requires fixing up shader code with the same define
-#define UNIFORM_ARRAY_SIZE 64
-
-static const char vertexShaderCode[] =
-    "#if defined(DEFORM)\n"
-    "attribute highp vec4 vPosTex;\n"
-    "#else\n"
-    "attribute highp vec2 vPos;\n"
-    "#endif\n"
-    "attribute highp vec4 vData; //  x = time,  y = lifeSpan, z = size,  w = endSize\n"
-    "attribute highp vec4 vVec; // x,y = constant velocity,  z,w = acceleration\n"
-    "uniform highp float entry;\n"
-    "#if defined(COLOR)\n"
-    "attribute highp vec4 vColor;\n"
-    "#endif\n"
-    "#if defined(DEFORM)\n"
-    "attribute highp vec4 vDeformVec; //x,y x unit vector; z,w = y unit vector\n"
-    "attribute highp vec3 vRotation; //x = radians of rotation, y=rotation velocity, z= bool autoRotate\n"
-    "#endif\n"
-    "#if defined(SPRITE)\n"
-    "attribute highp vec3 vAnimData;// w,h(premultiplied of anim), interpolation progress\n"
-    "attribute highp vec4 vAnimPos;//x,y, x,y (two frames for interpolation)\n"
-    "#endif\n"
-    "\n"
-    "uniform highp mat4 qt_Matrix;\n"
-    "uniform highp float timestamp;\n"
-    "#if defined(TABLE)\n"
-    "varying lowp vec2 tt;//y is progress if Sprite mode\n"
-    "uniform highp float sizetable[64];\n"
-    "uniform highp float opacitytable[64];\n"
-    "#endif\n"
-    "#if defined(SPRITE)\n"
-    "varying highp vec4 fTexS;\n"
-    "#elif defined(DEFORM)\n"
-    "varying highp vec2 fTex;\n"
-    "#endif\n"
-    "#if defined(COLOR)\n"
-    "varying lowp vec4 fColor;\n"
-    "#else\n"
-    "varying lowp float fFade;\n"
-    "#endif\n"
-    "\n"
-    "\n"
-    "void main() {\n"
-    "\n"
-    "    highp float t = (timestamp - vData.x) / vData.y;\n"
-    "    if (t < 0. || t > 1.) {\n"
-    "#if defined(DEFORM)\n"
-    "        gl_Position = qt_Matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.);\n"
-    "#else\n"
-    "        gl_PointSize = 0.;\n"
-    "#endif\n"
-    "    } else {\n"
-    "#if defined(SPRITE)\n"
-    "        tt.y = vAnimData.z;\n"
-    "        //Calculate frame location in texture\n"
-    "        fTexS.xy = vAnimPos.xy + vPosTex.zw * vAnimData.xy;\n"
-    "        //Next frame is also passed, for interpolation\n"
-    "        fTexS.zw = vAnimPos.zw + vPosTex.zw * vAnimData.xy;\n"
-    "\n"
-    "#elif defined(DEFORM)\n"
-    "        fTex = vPosTex.zw;\n"
-    "#endif\n"
-    "        highp float currentSize = mix(vData.z, vData.w, t * t);\n"
-#if defined (Q_OS_BLACKBERRY)
-    "        highp float fade = 1.;\n"
+#if defined(Q_OS_BLACKBERRY)
+#define SHADER_PLATFORM_DEFINES "#define Q_OS_BLACKBERRY\n"
 #else
-    "        lowp float fade = 1.;\n"
+#define SHADER_PLATFORM_DEFINES
 #endif
-    "        highp float fadeIn = min(t * 10., 1.);\n"
-    "        highp float fadeOut = 1. - clamp((t - 0.75) * 4.,0., 1.);\n"
-    "\n"
-    "#if defined(TABLE)\n"
-    "        currentSize = currentSize * sizetable[int(floor(t*64.))];\n"
-    "        fade = fade * opacitytable[int(floor(t*64.))];\n"
-    "#endif\n"
-    "\n"
-    "        if (entry == 1.)\n"
-    "            fade = fade * fadeIn * fadeOut;\n"
-    "        else if (entry == 2.)\n"
-    "            currentSize = currentSize * fadeIn * fadeOut;\n"
-    "\n"
-    "        if (currentSize <= 0.) {\n"
-    "#if defined(DEFORM)\n"
-    "            gl_Position = qt_Matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.);\n"
-    "#else\n"
-    "            gl_PointSize = 0.;\n"
-    "#endif\n"
-    "        } else {\n"
-    "            if (currentSize < 3.)//Sizes too small look jittery as they move\n"
-    "                currentSize = 3.;\n"
-    "\n"
-    "            highp vec2 pos;\n"
-    "#if defined(DEFORM)\n"
-    "            highp float rotation = vRotation.x + vRotation.y * t * vData.y;\n"
-    "            if (vRotation.z == 1.0){\n"
-    "                highp vec2 curVel = vVec.zw * t * vData.y + vVec.xy;\n"
-    "                if (length(curVel) > 0.)\n"
-    "                    rotation += atan(curVel.y, curVel.x);\n"
-    "            }\n"
-    "            highp vec2 trigCalcs = vec2(cos(rotation), sin(rotation));\n"
-    "            highp vec4 deform = vDeformVec * currentSize * (vPosTex.zzww - 0.5);\n"
-    "            highp vec4 rotatedDeform = deform.xxzz * trigCalcs.xyxy;\n"
-    "            rotatedDeform = rotatedDeform + (deform.yyww * trigCalcs.yxyx * vec4(-1.,1.,-1.,1.));\n"
-    "            /* The readable version:\n"
-    "            highp vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5);\n"
-    "            highp vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5);\n"
-    "            highp vec2 xRotatedDeform;\n"
-    "            xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y;\n"
-    "            xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y;\n"
-    "            highp vec2 yRotatedDeform;\n"
-    "            yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y;\n"
-    "            yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y;\n"
-    "            */\n"
-    "            pos = vPosTex.xy\n"
-    "                  + rotatedDeform.xy\n"
-    "                  + rotatedDeform.zw\n"
-    "                  + vVec.xy * t * vData.y         // apply velocity\n"
-    "                  + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration\n"
-    "#else\n"
-    "            pos = vPos\n"
-    "                  + vVec.xy * t * vData.y         // apply velocity vector..\n"
-    "                  + 0.5 * vVec.zw * pow(t * vData.y, 2.);\n"
-    "            gl_PointSize = currentSize;\n"
-    "#endif\n"
-    "            gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);\n"
-    "\n"
-    "#if defined(COLOR)\n"
-    "            fColor = vColor * fade;\n"
-    "#else\n"
-    "            fFade = fade;\n"
-    "#endif\n"
-    "#if defined(TABLE)\n"
-    "            tt.x = t;\n"
-    "#endif\n"
-    "        }\n"
-    "    }\n"
-    "}\n";
-
-static const char fragmentShaderCode[] =
-    "uniform sampler2D _qt_texture;\n"
-    "uniform lowp float qt_Opacity;\n"
-    "\n"
-    "#if defined(SPRITE)\n"
-    "varying highp vec4 fTexS;\n"
-    "#elif defined(DEFORM)\n"
-    "varying highp vec2 fTex;\n"
-    "#endif\n"
-    "#if defined(COLOR)\n"
-    "varying lowp vec4 fColor;\n"
-    "#else\n"
-    "varying lowp float fFade;\n"
-    "#endif\n"
-    "#if defined(TABLE)\n"
-    "varying lowp vec2 tt;\n"
-    "uniform sampler2D colortable;\n"
-    "#endif\n"
-    "\n"
-    "void main() {\n"
-    "#if defined(SPRITE)\n"
-    "    gl_FragColor = mix(texture2D(_qt_texture, fTexS.xy), texture2D(_qt_texture, fTexS.zw), tt.y)\n"
-    "            * fColor\n"
-    "            * texture2D(colortable, tt)\n"
-    "            * qt_Opacity;\n"
-    "#elif defined(TABLE)\n"
-    "    gl_FragColor = texture2D(_qt_texture, fTex)\n"
-    "            * fColor\n"
-    "            * texture2D(colortable, tt)\n"
-    "            * qt_Opacity;\n"
-    "#elif defined(DEFORM)\n"
-    "    gl_FragColor = (texture2D(_qt_texture, fTex)) * fColor * qt_Opacity;\n"
-    "#elif defined(COLOR)\n"
-    "    gl_FragColor = (texture2D(_qt_texture, gl_PointCoord)) * fColor * qt_Opacity;\n"
-    "#else\n"
-    "    gl_FragColor = texture2D(_qt_texture, gl_PointCoord) * (fFade * qt_Opacity);\n"
-    "#endif\n"
-    "}\n";
+
+//TODO: Make it larger on desktop? Requires fixing up shader code with the same define
+#define UNIFORM_ARRAY_SIZE 64
 
 const qreal CONV = 0.017453292519943295;
 class ImageMaterialData
@@ -273,13 +105,18 @@ class TabledMaterial : public QSGSimpleMaterialShader<TabledMaterialData>
 public:
     TabledMaterial()
     {
-        m_vertex_code = QByteArray(SHADER_DEFINES)
-            + QByteArray("#define TABLE\n#define DEFORM\n#define COLOR\n")
-            + vertexShaderCode;
+        QSGShaderSourceBuilder builder;
 
-        m_fragment_code = QByteArray(SHADER_DEFINES)
-            + QByteArray("#define TABLE\n#define DEFORM\n#define COLOR\n")
-            + fragmentShaderCode;
+        builder.appendSource(QByteArray(SHADER_DEFINES) + QByteArray(SHADER_PLATFORM_DEFINES));
+        builder.appendSource(QByteArray("#define TABLE\n#define DEFORM\n#define COLOR\n"));
+        builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.vert"));
+        m_vertex_code = builder.source();
+        builder.clear();
+
+        builder.appendSource(QByteArray(SHADER_DEFINES));
+        builder.appendSource(QByteArray("#define TABLE\n#define DEFORM\n#define COLOR\n"));
+        builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.frag"));
+        m_fragment_code = builder.source();
 
         Q_ASSERT(!m_vertex_code.isNull());
         Q_ASSERT(!m_fragment_code.isNull());
@@ -335,13 +172,18 @@ class DeformableMaterial : public QSGSimpleMaterialShader<DeformableMaterialData
 public:
     DeformableMaterial()
     {
-        m_vertex_code = QByteArray(SHADER_DEFINES)
-            + QByteArray("#define DEFORM\n#define COLOR\n")
-            + vertexShaderCode;
+        QSGShaderSourceBuilder builder;
+
+        builder.appendSource(QByteArray(SHADER_DEFINES) + QByteArray(SHADER_PLATFORM_DEFINES));
+        builder.appendSource(QByteArray("#define DEFORM\n#define COLOR\n"));
+        builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.vert"));
+        m_vertex_code = builder.source();
+        builder.clear();
 
-        m_fragment_code = QByteArray(SHADER_DEFINES)
-            + QByteArray("#define DEFORM\n#define COLOR\n")
-            + fragmentShaderCode;
+        builder.appendSource(QByteArray(SHADER_DEFINES));
+        builder.appendSource(QByteArray("#define DEFORM\n#define COLOR\n"));
+        builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.frag"));
+        m_fragment_code = builder.source();
 
         Q_ASSERT(!m_vertex_code.isNull());
         Q_ASSERT(!m_fragment_code.isNull());
@@ -386,13 +228,18 @@ class SpriteMaterial : public QSGSimpleMaterialShader<SpriteMaterialData>
 public:
     SpriteMaterial()
     {
-        m_vertex_code = QByteArray(SHADER_DEFINES)
-            + QByteArray("#define SPRITE\n#define TABLE\n#define DEFORM\n#define COLOR\n")
-            + vertexShaderCode;
+        QSGShaderSourceBuilder builder;
+
+        builder.appendSource(QByteArray(SHADER_DEFINES) + QByteArray(SHADER_PLATFORM_DEFINES));
+        builder.appendSource(QByteArray("#define SPRITE\n#define TABLE\n#define DEFORM\n#define COLOR\n"));
+        builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.vert"));
+        m_vertex_code = builder.source();
+        builder.clear();
 
-        m_fragment_code = QByteArray(SHADER_DEFINES)
-            + QByteArray("#define SPRITE\n#define TABLE\n#define DEFORM\n#define COLOR\n")
-            + fragmentShaderCode;
+        builder.appendSource(QByteArray(SHADER_DEFINES));
+        builder.appendSource(QByteArray("#define SPRITE\n#define TABLE\n#define DEFORM\n#define COLOR\n"));
+        builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.frag"));
+        m_fragment_code = builder.source();
 
         Q_ASSERT(!m_vertex_code.isNull());
         Q_ASSERT(!m_fragment_code.isNull());
@@ -450,13 +297,18 @@ class ColoredMaterial : public QSGSimpleMaterialShader<ColoredMaterialData>
 public:
     ColoredMaterial()
     {
-        m_vertex_code = QByteArray(SHADER_DEFINES)
-            + QByteArray("#define COLOR\n")
-            + vertexShaderCode;
+        QSGShaderSourceBuilder builder;
 
-        m_fragment_code = QByteArray(SHADER_DEFINES)
-            + QByteArray("#define COLOR\n")
-            + fragmentShaderCode;
+        builder.appendSource(QByteArray(SHADER_DEFINES) + QByteArray(SHADER_PLATFORM_DEFINES));
+        builder.appendSource(QByteArray("#define COLOR\n"));
+        builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.vert"));
+        m_vertex_code = builder.source();
+        builder.clear();
+
+        builder.appendSource(QByteArray(SHADER_DEFINES));
+        builder.appendSource(QByteArray("#define COLOR\n"));
+        builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.frag"));
+        m_fragment_code = builder.source();
 
         Q_ASSERT(!m_vertex_code.isNull());
         Q_ASSERT(!m_fragment_code.isNull());
@@ -516,11 +368,16 @@ class SimpleMaterial : public QSGSimpleMaterialShader<SimpleMaterialData>
 public:
     SimpleMaterial()
     {
-        m_vertex_code = QByteArray(SHADER_DEFINES)
-            + vertexShaderCode;
+        QSGShaderSourceBuilder builder;
+
+        builder.appendSource(QByteArray(SHADER_DEFINES) + QByteArray(SHADER_PLATFORM_DEFINES));
+        builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.vert"));
+        m_vertex_code = builder.source();
+        builder.clear();
 
-        m_fragment_code = QByteArray(SHADER_DEFINES)
-            + fragmentShaderCode;
+        builder.appendSource(QByteArray(SHADER_DEFINES));
+        builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.frag"));
+        m_fragment_code = builder.source();
 
         Q_ASSERT(!m_vertex_code.isNull());
         Q_ASSERT(!m_fragment_code.isNull());
diff --git a/src/particles/shaders/customparticle.frag b/src/particles/shaders/customparticle.frag
new file mode 100644
index 0000000000000000000000000000000000000000..c1c15ecb0ce05ccfb00b762ecc9edf992304a288
--- /dev/null
+++ b/src/particles/shaders/customparticle.frag
@@ -0,0 +1,9 @@
+varying highp vec2 qt_TexCoord0;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+
+void main()
+{
+    gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;
+}
\ No newline at end of file
diff --git a/src/particles/shaders/customparticle.vert b/src/particles/shaders/customparticle.vert
new file mode 100644
index 0000000000000000000000000000000000000000..b99f73ea53a18ac9c3e25bb1acedb3735aef3fe4
--- /dev/null
+++ b/src/particles/shaders/customparticle.vert
@@ -0,0 +1,4 @@
+void main()
+{
+    defaultMain();
+}
\ No newline at end of file
diff --git a/src/particles/shaders/customparticletemplate.vert b/src/particles/shaders/customparticletemplate.vert
new file mode 100644
index 0000000000000000000000000000000000000000..c482c4207be6728e926781e2966874ab8abe33f2
--- /dev/null
+++ b/src/particles/shaders/customparticletemplate.vert
@@ -0,0 +1,26 @@
+attribute highp vec2 qt_ParticlePos;
+attribute highp vec2 qt_ParticleTex;
+attribute highp vec4 qt_ParticleData; // x = time, y = lifeSpan, z = size, w = endSize
+attribute highp vec4 qt_ParticleVec;  // x,y = constant velocity, z,w = acceleration
+attribute highp float qt_ParticleR;
+
+uniform highp mat4 qt_Matrix;
+uniform highp float qt_Timestamp;
+
+varying highp vec2 qt_TexCoord0;
+
+void defaultMain()
+{
+    qt_TexCoord0 = qt_ParticleTex;
+    highp float size = qt_ParticleData.z;
+    highp float endSize = qt_ParticleData.w;
+    highp float t = (qt_Timestamp - qt_ParticleData.x) / qt_ParticleData.y;
+    highp float currentSize = mix(size, endSize, t * t);
+    if (t < 0. || t > 1.)
+        currentSize = 0.;
+    highp vec2 pos = qt_ParticlePos
+                   - currentSize / 2. + currentSize * qt_ParticleTex   // adjust size
+                   + qt_ParticleVec.xy * t * qt_ParticleData.y         // apply velocity vector..
+                   + 0.5 * qt_ParticleVec.zw * pow(t * qt_ParticleData.y, 2.);
+    gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
+}
diff --git a/src/particles/shaders/imageparticle.frag b/src/particles/shaders/imageparticle.frag
new file mode 100644
index 0000000000000000000000000000000000000000..699b90babf6d7ff31163275c677478f6acdd8c8f
--- /dev/null
+++ b/src/particles/shaders/imageparticle.frag
@@ -0,0 +1,40 @@
+uniform sampler2D _qt_texture;
+uniform lowp float qt_Opacity;
+
+#if defined(SPRITE)
+varying highp vec4 fTexS;
+#elif defined(DEFORM)
+varying highp vec2 fTex;
+#endif
+
+#if defined(COLOR)
+varying lowp vec4 fColor;
+#else
+varying lowp float fFade;
+#endif
+
+#if defined(TABLE)
+varying lowp vec2 tt;
+uniform sampler2D colortable;
+#endif
+
+void main()
+{
+#if defined(SPRITE)
+    gl_FragColor = mix(texture2D(_qt_texture, fTexS.xy), texture2D(_qt_texture, fTexS.zw), tt.y)
+            * fColor
+            * texture2D(colortable, tt)
+            * qt_Opacity;
+#elif defined(TABLE)
+    gl_FragColor = texture2D(_qt_texture, fTex)
+            * fColor
+            * texture2D(colortable, tt)
+            * qt_Opacity;
+#elif defined(DEFORM)
+    gl_FragColor = (texture2D(_qt_texture, fTex)) * fColor * qt_Opacity;
+#elif defined(COLOR)
+    gl_FragColor = (texture2D(_qt_texture, gl_PointCoord)) * fColor * qt_Opacity;
+#else
+    gl_FragColor = texture2D(_qt_texture, gl_PointCoord) * (fFade * qt_Opacity);
+#endif
+}
\ No newline at end of file
diff --git a/src/particles/shaders/imageparticle.vert b/src/particles/shaders/imageparticle.vert
new file mode 100644
index 0000000000000000000000000000000000000000..9e607a74779153d3cc5a23a18c404b075d82b131
--- /dev/null
+++ b/src/particles/shaders/imageparticle.vert
@@ -0,0 +1,143 @@
+#if defined(DEFORM)
+attribute highp vec4 vPosTex;
+#else
+attribute highp vec2 vPos;
+#endif
+
+attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize
+attribute highp vec4 vVec;  // x,y = constant velocity,  z,w = acceleration
+uniform highp float entry;
+
+#if defined(COLOR)
+attribute highp vec4 vColor;
+#endif
+
+#if defined(DEFORM)
+attribute highp vec4 vDeformVec; // x,y x unit vector; z,w = y unit vector
+attribute highp vec3 vRotation;  // x = radians of rotation, y = rotation velocity, z = bool autoRotate
+#endif
+
+#if defined(SPRITE)
+attribute highp vec3 vAnimData; // w,h(premultiplied of anim), interpolation progress
+attribute highp vec4 vAnimPos;  // x,y, x,y (two frames for interpolation)
+#endif
+
+uniform highp mat4 qt_Matrix;
+uniform highp float timestamp;
+
+#if defined(TABLE)
+varying lowp vec2 tt;//y is progress if Sprite mode
+uniform highp float sizetable[64];
+uniform highp float opacitytable[64];
+#endif
+
+#if defined(SPRITE)
+varying highp vec4 fTexS;
+#elif defined(DEFORM)
+varying highp vec2 fTex;
+#endif
+
+#if defined(COLOR)
+varying lowp vec4 fColor;
+#else
+varying lowp float fFade;
+#endif
+
+
+void main()
+{
+    highp float t = (timestamp - vData.x) / vData.y;
+    if (t < 0. || t > 1.) {
+#if defined(DEFORM)
+        gl_Position = qt_Matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.);
+#else
+        gl_PointSize = 0.;
+#endif
+    } else {
+#if defined(SPRITE)
+        tt.y = vAnimData.z;
+
+        // Calculate frame location in texture
+        fTexS.xy = vAnimPos.xy + vPosTex.zw * vAnimData.xy;
+
+        // Next frame is also passed, for interpolation
+        fTexS.zw = vAnimPos.zw + vPosTex.zw * vAnimData.xy;
+
+#elif defined(DEFORM)
+        fTex = vPosTex.zw;
+#endif
+        highp float currentSize = mix(vData.z, vData.w, t * t);
+#if defined (Q_OS_BLACKBERRY)
+        highp float fade = 1.;
+#else
+        lowp float fade = 1.;
+#endif
+        highp float fadeIn = min(t * 10., 1.);
+        highp float fadeOut = 1. - clamp((t - 0.75) * 4.,0., 1.);
+
+#if defined(TABLE)
+        currentSize = currentSize * sizetable[int(floor(t*64.))];
+        fade = fade * opacitytable[int(floor(t*64.))];
+#endif
+
+        if (entry == 1.)
+            fade = fade * fadeIn * fadeOut;
+        else if (entry == 2.)
+            currentSize = currentSize * fadeIn * fadeOut;
+
+        if (currentSize <= 0.) {
+#if defined(DEFORM)
+            gl_Position = qt_Matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.);
+#else
+            gl_PointSize = 0.;
+#endif
+        } else {
+            if (currentSize < 3.) // Sizes too small look jittery as they move
+                currentSize = 3.;
+
+            highp vec2 pos;
+#if defined(DEFORM)
+            highp float rotation = vRotation.x + vRotation.y * t * vData.y;
+            if (vRotation.z == 1.0){
+                highp vec2 curVel = vVec.zw * t * vData.y + vVec.xy;
+                if (length(curVel) > 0.)
+                    rotation += atan(curVel.y, curVel.x);
+            }
+            highp vec2 trigCalcs = vec2(cos(rotation), sin(rotation));
+            highp vec4 deform = vDeformVec * currentSize * (vPosTex.zzww - 0.5);
+            highp vec4 rotatedDeform = deform.xxzz * trigCalcs.xyxy;
+            rotatedDeform = rotatedDeform + (deform.yyww * trigCalcs.yxyx * vec4(-1.,1.,-1.,1.));
+            /* The readable version:
+            highp vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5);
+            highp vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5);
+            highp vec2 xRotatedDeform;
+            xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y;
+            xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y;
+            highp vec2 yRotatedDeform;
+            yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y;
+            yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y;
+            */
+            pos = vPosTex.xy
+                  + rotatedDeform.xy
+                  + rotatedDeform.zw
+                  + vVec.xy * t * vData.y         // apply velocity
+                  + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration
+#else
+            pos = vPos
+                  + vVec.xy * t * vData.y         // apply velocity vector..
+                  + 0.5 * vVec.zw * pow(t * vData.y, 2.);
+            gl_PointSize = currentSize;
+#endif
+            gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
+
+#if defined(COLOR)
+            fColor = vColor * fade;
+#else
+            fFade = fade;
+#endif
+#if defined(TABLE)
+            tt.x = t;
+#endif
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri
index cbdc5fd80f31beb5bc52bcca52eccb3a17cea450..d0ebbcfcdbd129161caf8c11a9c1aac724ea9494 100644
--- a/src/quick/items/items.pri
+++ b/src/quick/items/items.pri
@@ -139,6 +139,15 @@ HEADERS += \
     $$PWD/qquickshadereffectnode_p.h \
     $$PWD/qquickshadereffectsource_p.h \
 
-include(context2d/context2d.pri)
+OTHER_FILES += \
+    $$PWD/shaders/sprite.vert \
+    $$PWD/shaders/sprite.frag \
+    $$PWD/shaders/shadereffect.vert \
+    $$PWD/shaders/shadereffect.frag \
+    $$PWD/shaders/shadereffectfallback.vert \
+    $$PWD/shaders/shadereffectfallback.frag
 
+RESOURCES += \
+    $$PWD/items.qrc
 
+include(context2d/context2d.pri)
diff --git a/src/quick/items/items.qrc b/src/quick/items/items.qrc
new file mode 100644
index 0000000000000000000000000000000000000000..837cffb65af2f174ef70781e5c51b6938706f040
--- /dev/null
+++ b/src/quick/items/items.qrc
@@ -0,0 +1,10 @@
+<RCC>
+    <qresource prefix="/items">
+        <file>shaders/sprite.frag</file>
+        <file>shaders/sprite.vert</file>
+        <file>shaders/shadereffect.vert</file>
+        <file>shaders/shadereffect.frag</file>
+        <file>shaders/shadereffectfallback.frag</file>
+        <file>shaders/shadereffectfallback.vert</file>
+    </qresource>
+</RCC>
diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp
index c90adc24a59612536b6b52ec53643cf903214a00..4c16a1e9e21d089f76636a43b8f7357b766e0c4c 100644
--- a/src/quick/items/qquickanimatedsprite.cpp
+++ b/src/quick/items/qquickanimatedsprite.cpp
@@ -57,39 +57,6 @@
 
 QT_BEGIN_NAMESPACE
 
-static const char vertexShaderCode[] =
-    "attribute highp vec2 vPos;\n"
-    "attribute highp vec2 vTex;\n"
-    "uniform highp vec3 animData;// w,h(premultiplied of anim), interpolation progress\n"
-    "uniform highp vec4 animPos;//x,y, x,y (two frames for interpolation)\n"
-    "\n"
-    "uniform highp mat4 qt_Matrix;\n"
-    "\n"
-    "varying highp vec4 fTexS;\n"
-    "varying lowp float progress;\n"
-    "\n"
-    "\n"
-    "void main() {\n"
-    "    progress = animData.z;\n"
-    "    //Calculate frame location in texture\n"
-    "    fTexS.xy = animPos.xy + vTex.xy * animData.xy;\n"
-    "    //Next frame is also passed, for interpolation\n"
-    "    fTexS.zw = animPos.zw + vTex.xy * animData.xy;\n"
-    "\n"
-    "    gl_Position = qt_Matrix * vec4(vPos.x, vPos.y, 0, 1);\n"
-    "}\n";
-
-static const char fragmentShaderCode[] =
-    "uniform sampler2D _qt_texture;\n"
-    "uniform lowp float qt_Opacity;\n"
-    "\n"
-    "varying highp vec4 fTexS;\n"
-    "varying lowp float progress;\n"
-    "\n"
-    "void main() {\n"
-    "    gl_FragColor = mix(texture2D(_qt_texture, fTexS.xy), texture2D(_qt_texture, fTexS.zw), progress) * qt_Opacity;\n"
-    "}\n";
-
 class QQuickAnimatedSpriteMaterial : public QSGMaterial
 {
 public:
@@ -134,8 +101,11 @@ QQuickAnimatedSpriteMaterial::~QQuickAnimatedSpriteMaterial()
 class AnimatedSpriteMaterialData : public QSGMaterialShader
 {
 public:
-    AnimatedSpriteMaterialData(const char * /* vertexFile */ = 0, const char * /* fragmentFile */ = 0)
+    AnimatedSpriteMaterialData()
+        : QSGMaterialShader()
     {
+        setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/items/shaders/sprite.vert"));
+        setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/items/shaders/sprite.frag"));
     }
 
     virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *)
@@ -158,9 +128,6 @@ public:
         m_animPos_id = program()->uniformLocation("animPos");
     }
 
-    virtual const char *vertexShader() const { return vertexShaderCode; }
-    virtual const char *fragmentShader() const { return fragmentShaderCode; }
-
     virtual char const *const *attributeNames() const {
         static const char *attr[] = {
            "vPos",
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp
index 354b9f751b0bb9bbd639f74d82d0f8dec9b1b267..9c766a162206ee45a6e4e88ba84348fee50eac63 100644
--- a/src/quick/items/qquickshadereffect.cpp
+++ b/src/quick/items/qquickshadereffect.cpp
@@ -43,6 +43,7 @@
 #include <private/qquickshadereffectnode_p.h>
 
 #include <QtQuick/qsgmaterial.h>
+#include <QtQuick/private/qsgshadersourcebuilder_p.h>
 #include "qquickitem_p.h"
 
 #include <QtQuick/private/qsgcontext_p.h>
@@ -57,24 +58,6 @@
 
 QT_BEGIN_NAMESPACE
 
-static const char qt_default_vertex_code[] =
-    "uniform highp mat4 qt_Matrix;                                  \n"
-    "attribute highp vec4 qt_Vertex;                                \n"
-    "attribute highp vec2 qt_MultiTexCoord0;                        \n"
-    "varying highp vec2 qt_TexCoord0;                               \n"
-    "void main() {                                                  \n"
-    "    qt_TexCoord0 = qt_MultiTexCoord0;                          \n"
-    "    gl_Position = qt_Matrix * qt_Vertex;                       \n"
-    "}";
-
-static const char qt_default_fragment_code[] =
-    "varying highp vec2 qt_TexCoord0;                                   \n"
-    "uniform sampler2D source;                                          \n"
-    "uniform lowp float qt_Opacity;                                     \n"
-    "void main() {                                                      \n"
-    "    gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;   \n"
-    "}";
-
 static const char qt_position_attribute_name[] = "qt_Vertex";
 static const char qt_texcoord_attribute_name[] = "qt_MultiTexCoord0";
 
@@ -979,10 +962,16 @@ QSGNode *QQuickShaderEffect::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDa
 
     if (m_dirtyProgram) {
         Key s = m_common.source;
-        if (s.sourceCode[Key::FragmentShader].isEmpty())
-            s.sourceCode[Key::FragmentShader] = qt_default_fragment_code;
-        if (s.sourceCode[Key::VertexShader].isEmpty())
-            s.sourceCode[Key::VertexShader] = qt_default_vertex_code;
+        QSGShaderSourceBuilder builder;
+        if (s.sourceCode[Key::FragmentShader].isEmpty()) {
+            builder.appendSourceFile(QStringLiteral(":/items/shaders/shadereffect.frag"));
+            s.sourceCode[Key::FragmentShader] = builder.source();
+            builder.clear();
+        }
+        if (s.sourceCode[Key::VertexShader].isEmpty()) {
+            builder.appendSourceFile(QStringLiteral(":/items/shaders/shadereffect.vert"));
+            s.sourceCode[Key::VertexShader] = builder.source();
+        }
         s.className = metaObject()->className();
 
         material->setProgramSource(s);
diff --git a/src/quick/items/qquickshadereffectnode.cpp b/src/quick/items/qquickshadereffectnode.cpp
index b84d251de5f6ac73535f0183858a055fa8911ab8..8788fa83620eb596024bf96926cbbe2491834346 100644
--- a/src/quick/items/qquickshadereffectnode.cpp
+++ b/src/quick/items/qquickshadereffectnode.cpp
@@ -45,6 +45,7 @@
 #include "qquickshadereffect_p.h"
 #include <QtQuick/qsgtextureprovider.h>
 #include <QtQuick/private/qsgrenderer_p.h>
+#include <QtQuick/private/qsgshadersourcebuilder_p.h>
 
 QT_BEGIN_NAMESPACE
 
@@ -276,20 +277,15 @@ void QQuickCustomMaterialShader::compile()
         m_log += program()->log();
     }
 
-    static const char fallbackVertexShader[] =
-            "uniform highp mat4 qt_Matrix;"
-            "attribute highp vec4 v;"
-            "void main() { gl_Position = qt_Matrix * v; }";
-    static const char fallbackFragmentShader[] =
-            "void main() { gl_FragColor = vec4(1., 0., 1., 1.); }";
-
     if (!m_compiled) {
         qWarning("QQuickCustomMaterialShader: Shader compilation failed:");
         qWarning() << program()->log();
 
-        program()->removeAllShaders();
-        program()->addShaderFromSourceCode(QOpenGLShader::Vertex, fallbackVertexShader);
-        program()->addShaderFromSourceCode(QOpenGLShader::Fragment, fallbackFragmentShader);
+        QSGShaderSourceBuilder::initializeProgramFromFiles(
+            program(),
+            QStringLiteral(":/items/shaders/shadereffectfallback.vert"),
+            QStringLiteral(":/items/shaders/shadereffectfallback.frag"));
+
 #ifndef QT_NO_DEBUG
         for (int i = 0; i < attrCount; ++i) {
 #else
diff --git a/src/quick/items/qquickspritesequence.cpp b/src/quick/items/qquickspritesequence.cpp
index 8a6789bb9f93209958fc8ace54520b0062b6f152..28f1397cc9d7b59a617f65e5781aeda54d9b1e41 100644
--- a/src/quick/items/qquickspritesequence.cpp
+++ b/src/quick/items/qquickspritesequence.cpp
@@ -56,39 +56,6 @@
 
 QT_BEGIN_NAMESPACE
 
-static const char vertexShaderCode[] =
-    "attribute highp vec2 vPos;\n"
-    "attribute highp vec2 vTex;\n"
-    "uniform highp vec3 animData;// w,h(premultiplied of anim), interpolation progress\n"
-    "uniform highp vec4 animPos;//x,y, x,y (two frames for interpolation)\n"
-    "\n"
-    "uniform highp mat4 qt_Matrix;\n"
-    "\n"
-    "varying highp vec4 fTexS;\n"
-    "varying lowp float progress;\n"
-    "\n"
-    "\n"
-    "void main() {\n"
-    "    progress = animData.z;\n"
-    "    //Calculate frame location in texture\n"
-    "    fTexS.xy = animPos.xy + vTex.xy * animData.xy;\n"
-    "    //Next frame is also passed, for interpolation\n"
-    "    fTexS.zw = animPos.zw + vTex.xy * animData.xy;\n"
-    "\n"
-    "    gl_Position = qt_Matrix * vec4(vPos.x, vPos.y, 0, 1);\n"
-    "}\n";
-
-static const char fragmentShaderCode[] =
-    "uniform sampler2D _qt_texture;\n"
-    "uniform lowp float qt_Opacity;\n"
-    "\n"
-    "varying highp vec4 fTexS;\n"
-    "varying lowp float progress;\n"
-    "\n"
-    "void main() {\n"
-    "    gl_FragColor = mix(texture2D(_qt_texture, fTexS.xy), texture2D(_qt_texture, fTexS.zw), progress) * qt_Opacity;\n"
-    "}\n";
-
 class QQuickSpriteSequenceMaterial : public QSGMaterial
 {
 public:
@@ -133,8 +100,11 @@ QQuickSpriteSequenceMaterial::~QQuickSpriteSequenceMaterial()
 class SpriteSequenceMaterialData : public QSGMaterialShader
 {
 public:
-    SpriteSequenceMaterialData(const char * /* vertexFile */ = 0, const char * /* fragmentFile */ = 0)
+    SpriteSequenceMaterialData()
+        : QSGMaterialShader()
     {
+        setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/items/shaders/sprite.vert"));
+        setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/items/shaders/sprite.frag"));
     }
 
     virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *)
@@ -157,9 +127,6 @@ public:
         m_animPos_id = program()->uniformLocation("animPos");
     }
 
-    virtual const char *vertexShader() const { return vertexShaderCode; }
-    virtual const char *fragmentShader() const { return fragmentShaderCode; }
-
     virtual char const *const *attributeNames() const {
         static const char *attr[] = {
            "vPos",
diff --git a/src/quick/items/shaders/shadereffect.frag b/src/quick/items/shaders/shadereffect.frag
new file mode 100644
index 0000000000000000000000000000000000000000..c1c15ecb0ce05ccfb00b762ecc9edf992304a288
--- /dev/null
+++ b/src/quick/items/shaders/shadereffect.frag
@@ -0,0 +1,9 @@
+varying highp vec2 qt_TexCoord0;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+
+void main()
+{
+    gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;
+}
\ No newline at end of file
diff --git a/src/quick/items/shaders/shadereffect.vert b/src/quick/items/shaders/shadereffect.vert
new file mode 100644
index 0000000000000000000000000000000000000000..ae1e84a50c44d6eec63ebb9018684ad6a8366761
--- /dev/null
+++ b/src/quick/items/shaders/shadereffect.vert
@@ -0,0 +1,12 @@
+uniform highp mat4 qt_Matrix;
+
+attribute highp vec4 qt_Vertex;
+attribute highp vec2 qt_MultiTexCoord0;
+
+varying highp vec2 qt_TexCoord0;
+
+void main()
+{
+    qt_TexCoord0 = qt_MultiTexCoord0;
+    gl_Position = qt_Matrix * qt_Vertex;
+}
\ No newline at end of file
diff --git a/src/quick/items/shaders/shadereffectfallback.frag b/src/quick/items/shaders/shadereffectfallback.frag
new file mode 100644
index 0000000000000000000000000000000000000000..d279e54083fb4717e96d85a77718a49ad72074d1
--- /dev/null
+++ b/src/quick/items/shaders/shadereffectfallback.frag
@@ -0,0 +1,4 @@
+void main()
+{
+    gl_FragColor = vec4(1., 0., 1., 1.);
+}
\ No newline at end of file
diff --git a/src/quick/items/shaders/shadereffectfallback.vert b/src/quick/items/shaders/shadereffectfallback.vert
new file mode 100644
index 0000000000000000000000000000000000000000..0a11a1d340798d8f8920dcd2acc8d1a603d9870c
--- /dev/null
+++ b/src/quick/items/shaders/shadereffectfallback.vert
@@ -0,0 +1,8 @@
+uniform highp mat4 qt_Matrix;
+
+attribute highp vec4 v;
+
+void main()
+{
+    gl_Position = qt_Matrix * v;
+}
\ No newline at end of file
diff --git a/src/quick/items/shaders/sprite.frag b/src/quick/items/shaders/sprite.frag
new file mode 100644
index 0000000000000000000000000000000000000000..e1fcb0f006bab09d97bef54bb52e64a30cb7e2c8
--- /dev/null
+++ b/src/quick/items/shaders/sprite.frag
@@ -0,0 +1,12 @@
+uniform sampler2D _qt_texture;
+uniform lowp float qt_Opacity;
+
+varying highp vec4 fTexS;
+varying lowp float progress;
+
+void main()
+{
+    gl_FragColor = mix(texture2D(_qt_texture, fTexS.xy),
+                       texture2D(_qt_texture, fTexS.zw),
+                       progress) * qt_Opacity;
+}
\ No newline at end of file
diff --git a/src/quick/items/shaders/sprite.vert b/src/quick/items/shaders/sprite.vert
new file mode 100644
index 0000000000000000000000000000000000000000..fc826f60b46c5258a6653a20df80466f74ff858a
--- /dev/null
+++ b/src/quick/items/shaders/sprite.vert
@@ -0,0 +1,23 @@
+attribute highp vec2 vPos;
+attribute highp vec2 vTex;
+
+uniform highp vec3 animData;// w,h(premultiplied of anim), interpolation progress
+uniform highp vec4 animPos;//x,y, x,y (two frames for interpolation)
+
+uniform highp mat4 qt_Matrix;
+
+varying highp vec4 fTexS;
+varying lowp float progress;
+
+void main()
+{
+    progress = animData.z;
+
+    // Calculate frame location in texture
+    fTexS.xy = animPos.xy + vTex.xy * animData.xy;
+
+    // Next frame is also passed, for interpolation
+    fTexS.zw = animPos.zw + vTex.xy * animData.xy;
+
+    gl_Position = qt_Matrix * vec4(vPos.x, vPos.y, 0, 1);
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 7a62dccc0f3316f719b4b1612c2f727a78516555..e7c611029da781830b6f22e9c1cfc0366cefcb0f 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -40,6 +40,7 @@
 ****************************************************************************/
 
 #include "qsgbatchrenderer_p.h"
+#include <private/qsgshadersourcebuilder_p.h>
 
 #include <QtCore/QElapsedTimer>
 
@@ -2322,23 +2323,11 @@ void Renderer::renderRenderNode(Batch *batch)
 
     if (!m_shaderManager->blitProgram) {
         m_shaderManager->blitProgram = new QOpenGLShaderProgram();
-        const char *vs =
-                "attribute highp vec4 av;               "
-                "attribute highp vec2 at;               "
-                "varying highp vec2 t;                  "
-                "void main() {                          "
-                "    gl_Position = av;                  "
-                "    t = at;                            "
-                "}                                      ";
-        const char *fs =
-                "uniform lowp sampler2D tex;            "
-                "varying highp vec2 t;                  "
-                "void main() {                          "
-                "    gl_FragColor = texture2D(tex, t);  "
-                "}                                      ";
-
-        m_shaderManager->blitProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vs);
-        m_shaderManager->blitProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fs);
+
+        QSGShaderSourceBuilder::initializeProgramFromFiles(
+            m_shaderManager->blitProgram,
+            QStringLiteral(":/scenegraph/shaders/rendernode.vert"),
+            QStringLiteral(":/scenegraph/shaders/rendernode.frag"));
         m_shaderManager->blitProgram->bindAttributeLocation("av", 0);
         m_shaderManager->blitProgram->bindAttributeLocation("at", 1);
         m_shaderManager->blitProgram->link();
diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
index d18682395864e3f7a1af867bc466bccad6f2cc16..686d1438b40499c41556e38541b7e485ffc38fe0 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp
+++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
@@ -41,9 +41,21 @@
 
 #include "qsgmaterial.h"
 #include "qsgrenderer_p.h"
+#include "qsgmaterialshader_p.h"
+#include <private/qsgshadersourcebuilder_p.h>
 
 QT_BEGIN_NAMESPACE
 
+const char *QSGMaterialShaderPrivate::loadShaderSource(QOpenGLShader::ShaderType type) const
+{
+    QStringList files = m_sourceFiles[type];
+    QSGShaderSourceBuilder builder;
+    Q_FOREACH (const QString &file, files)
+        builder.appendSourceFile(file);
+    m_sources[type] = builder.source();
+    return m_sources[type].constData();
+}
+
 #ifndef QT_NO_DEBUG
 static bool qsg_leak_check = !qgetenv("QML_LEAK_CHECK").isEmpty();
 #endif
@@ -165,14 +177,21 @@ static bool qsg_leak_check = !qgetenv("QML_LEAK_CHECK").isEmpty();
     Creates a new QSGMaterialShader.
  */
 QSGMaterialShader::QSGMaterialShader()
+    : d_ptr(new QSGMaterialShaderPrivate)
+{
+}
+
+QSGMaterialShader::QSGMaterialShader(QSGMaterialShaderPrivate &dd)
+    : d_ptr(&dd)
 {
-    Q_UNUSED(m_reserved);
 }
 
 /*!
-    \fn QSGMaterialShader::~QSGMaterialShader()
     \internal
  */
+QSGMaterialShader::~QSGMaterialShader()
+{
+}
 
 /*!
     \fn char const *const *QSGMaterialShader::attributeNames() const
@@ -194,6 +213,11 @@ QSGMaterialShader::QSGMaterialShader()
 
     The contents returned from this function should never change.
 */
+const char *QSGMaterialShader::vertexShader() const
+{
+    Q_D(const QSGMaterialShader);
+    return d->loadShaderSource(QOpenGLShader::Vertex);
+}
 
 
 /*!
@@ -204,6 +228,11 @@ QSGMaterialShader::QSGMaterialShader()
 
     The contents returned from this function should never change.
 */
+const char *QSGMaterialShader::fragmentShader() const
+{
+    Q_D(const QSGMaterialShader);
+    return d->loadShaderSource(QOpenGLShader::Fragment);
+}
 
 
 /*!
@@ -274,7 +303,35 @@ void QSGMaterialShader::updateState(const RenderState & /* state */, QSGMaterial
 {
 }
 
+/*!
+    Sets the GLSL source file for the shader stage \a type to \a sourceFile. The
+    default implementation of the vertexShader() and fragmentShader() functions
+    will load the source files set by this function.
+
+    This function is useful when you have a single source file for a given shader
+    stage. If your shader consists of multiple source files then use
+    setShaderSourceFiles()
+
+    \sa setShaderSourceFiles(), vertexShader(), fragmentShader()
+ */
+void QSGMaterialShader::setShaderSourceFile(QOpenGLShader::ShaderType type, const QString &sourceFile)
+{
+    Q_D(QSGMaterialShader);
+    d->m_sourceFiles[type] = (QStringList() << sourceFile);
+}
+
+/*!
+    Sets the GLSL source files for the shader stage \a type to \a sourceFiles. The
+    default implementation of the vertexShader() and fragmentShader() functions
+    will load the source files set by this function in the order given.
 
+    \sa setShaderSourceFile(), vertexShader(), fragmentShader()
+ */
+void QSGMaterialShader::setShaderSourceFiles(QOpenGLShader::ShaderType type, const QStringList &sourceFiles)
+{
+    Q_D(QSGMaterialShader);
+    d->m_sourceFiles[type] = sourceFiles;
+}
 
 /*!
     This function is called when the shader is initialized to compile the
diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.h b/src/quick/scenegraph/coreapi/qsgmaterial.h
index f3ef62d3e59f537e929c13f8c463e6f21a76193a..bfe570ca02b53eddd57d5c9d54d13bb2c142fcaf 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterial.h
+++ b/src/quick/scenegraph/coreapi/qsgmaterial.h
@@ -48,6 +48,7 @@
 QT_BEGIN_NAMESPACE
 
 class QSGMaterial;
+class QSGMaterialShaderPrivate;
 
 namespace QSGBatchRenderer {
     class ShaderManager;
@@ -88,7 +89,7 @@ public:
     };
 
     QSGMaterialShader();
-    virtual ~QSGMaterialShader() {};
+    virtual ~QSGMaterialShader();
 
     virtual void activate();
     virtual void deactivate();
@@ -99,18 +100,24 @@ public:
     inline QOpenGLShaderProgram *program() { return &m_program; }
 
 protected:
+    Q_DECLARE_PRIVATE(QSGMaterialShader)
+    QSGMaterialShader(QSGMaterialShaderPrivate &dd);
+
     friend class QSGContext;
     friend class QSGBatchRenderer::ShaderManager;
 
+    void setShaderSourceFile(QOpenGLShader::ShaderType type, const QString &sourceFile);
+    void setShaderSourceFiles(QOpenGLShader::ShaderType type, const QStringList &sourceFiles);
+
     virtual void compile();
     virtual void initialize() { }
 
-    virtual const char *vertexShader() const = 0;
-    virtual const char *fragmentShader() const = 0;
+    virtual const char *vertexShader() const;
+    virtual const char *fragmentShader() const;
 
 private:
     QOpenGLShaderProgram m_program;
-    void *m_reserved;
+    QScopedPointer<QSGMaterialShaderPrivate> d_ptr;
 };
 
 struct QSGMaterialType { };
diff --git a/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h b/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h
new file mode 100644
index 0000000000000000000000000000000000000000..fc8a35c41d5cb5f1bc694eef83e4a8149b1f51b3
--- /dev/null
+++ b/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSGMATERIALSHADER_P_H
+#define QSGMATERIALSHADER_P_H
+
+#include <private/qtquickglobal_p.h>
+#include <QOpenGLShader>
+
+QT_BEGIN_NAMESPACE
+
+class Q_QUICK_PRIVATE_EXPORT QSGMaterialShaderPrivate
+{
+public:
+    const char *loadShaderSource(QOpenGLShader::ShaderType type) const;
+
+    QHash<QOpenGLShader::ShaderType, QStringList> m_sourceFiles;
+    mutable QHash<QOpenGLShader::ShaderType, QByteArray> m_sources;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGMATERIALSHADER_P_H
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
index 7d982cee363215d30c995d434a5ec20fa027cc05..3c9c353bd8c8061070e708a8b92e6d53e85bf1a6 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
@@ -46,6 +46,7 @@
 #include "qsggeometry_p.h"
 
 #include <private/qsgadaptationlayer_p.h>
+#include <private/qsgshadersourcebuilder_p.h>
 
 #include <QOpenGLShaderProgram>
 #include <qopenglframebufferobject.h>
@@ -481,16 +482,10 @@ QSGRenderer::ClipType QSGRenderer::updateStencilClip(const QSGClipNode *clip)
         } else {
             if (!(clipType & StencilClip)) {
                 if (!m_clip_program.isLinked()) {
-                    m_clip_program.addShaderFromSourceCode(QOpenGLShader::Vertex,
-                        "attribute highp vec4 vCoord;       \n"
-                        "uniform highp mat4 matrix;         \n"
-                        "void main() {                      \n"
-                        "    gl_Position = matrix * vCoord; \n"
-                        "}");
-                    m_clip_program.addShaderFromSourceCode(QOpenGLShader::Fragment,
-                        "void main() {                                   \n"
-                        "    gl_FragColor = vec4(0.81, 0.83, 0.12, 1.0); \n" // Trolltech green ftw!
-                        "}");
+                    QSGShaderSourceBuilder::initializeProgramFromFiles(
+                        &m_clip_program,
+                        QStringLiteral(":/scenegraph/shaders/stencilclip.vert"),
+                        QStringLiteral(":/scenegraph/shaders/stencilclip.frag"));
                     m_clip_program.bindAttributeLocation("vCoord", 0);
                     m_clip_program.link();
                     m_clip_matrix_id = m_clip_program.uniformLocation("matrix");
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
index bf92bf8b39744bb4ebb13314f67339318191df44..35c4d1c506bf6d7191bfeae0d2d1e0fc9358a99f 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
@@ -40,6 +40,7 @@
 ****************************************************************************/
 
 #include "qsgdefaultglyphnode_p_p.h"
+#include <private/qsgmaterialshader_p.h>
 
 #include <qopenglshaderprogram.h>
 
@@ -75,8 +76,6 @@ public:
 
 protected:
     virtual void initialize();
-    virtual const char *vertexShader() const;
-    virtual const char *fragmentShader() const;
 
     int m_matrix_id;
     int m_color_id;
@@ -85,30 +84,6 @@ protected:
     QFontEngineGlyphCache::Type m_cacheType;
 };
 
-const char *QSGTextMaskShader::vertexShader() const {
-    return
-        "uniform highp mat4 matrix;                     \n"
-        "uniform highp vec2 textureScale;               \n"
-        "attribute highp vec4 vCoord;                   \n"
-        "attribute highp vec2 tCoord;                   \n"
-        "varying highp vec2 sampleCoord;                \n"
-        "void main() {                                  \n"
-        "     sampleCoord = tCoord * textureScale;      \n"
-        "     gl_Position = matrix * vCoord;            \n"
-        "}";
-}
-
-const char *QSGTextMaskShader::fragmentShader() const {
-    return
-        "varying highp vec2 sampleCoord;                \n"
-        "uniform sampler2D _qt_texture;                 \n"
-        "uniform lowp vec4 color;                       \n"
-        "void main() {                                  \n"
-        "    lowp vec4 glyph = texture2D(_qt_texture, sampleCoord); \n"
-        "    gl_FragColor = vec4(glyph.rgb * color.a, glyph.a); \n"
-        "}";
-}
-
 char const *const *QSGTextMaskShader::attributeNames() const
 {
     static char const *const attr[] = { "vCoord", "tCoord", 0 };
@@ -116,8 +91,11 @@ char const *const *QSGTextMaskShader::attributeNames() const
 }
 
 QSGTextMaskShader::QSGTextMaskShader(QFontEngineGlyphCache::Type cacheType)
-    : m_cacheType(cacheType)
+    : QSGMaterialShader(*new QSGMaterialShaderPrivate),
+      m_cacheType(cacheType)
 {
+    setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/textmask.vert"));
+    setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/textmask.frag"));
 }
 
 static inline qreal fontSmoothingGamma()
@@ -186,22 +164,13 @@ class QSG8BitTextMaskShader : public QSGTextMaskShader
 public:
     QSG8BitTextMaskShader(QFontEngineGlyphCache::Type cacheType)
         : QSGTextMaskShader(cacheType)
-    {}
+    {
+        setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/8bittextmask.frag"));
+    }
 
     virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
-    virtual const char *fragmentShader() const;
 };
 
-const char *QSG8BitTextMaskShader::fragmentShader() const {
-    return
-        "varying highp vec2 sampleCoord;                                \n"
-        "uniform lowp sampler2D texture;                                \n"
-        "uniform lowp vec4 color;                                       \n"
-        "void main() {                                                  \n"
-        "    gl_FragColor = color * texture2D(texture, sampleCoord).a;  \n"
-        "}";
-}
-
 void QSG8BitTextMaskShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
 {
     QSGTextMaskShader::updateState(state, newEffect, oldEffect);
@@ -220,28 +189,18 @@ public:
     QSG24BitTextMaskShader(QFontEngineGlyphCache::Type cacheType)
         : QSGTextMaskShader(cacheType)
         , m_useSRGB(false)
-    {}
+    {
+        setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/24bittextmask.frag"));
+    }
 
     virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
     virtual void initialize();
     void activate();
     void deactivate();
-    virtual const char *fragmentShader() const;
 
     uint m_useSRGB : 1;
 };
 
-const char *QSG24BitTextMaskShader::fragmentShader() const {
-    return
-        "varying highp vec2 sampleCoord;                            \n"
-        "uniform lowp sampler2D texture;                            \n"
-        "uniform lowp float color; // just the alpha, really...     \n"
-        "void main() {                                              \n"
-        "    lowp vec4 glyph = texture2D(texture, sampleCoord);     \n"
-        "    gl_FragColor = vec4(glyph.rgb * color, glyph.a);       \n"
-        "}";
-}
-
 void QSG24BitTextMaskShader::initialize()
 {
     QSGTextMaskShader::initialize();
@@ -302,14 +261,15 @@ class QSGStyledTextShader : public QSG8BitTextMaskShader
 public:
     QSGStyledTextShader(QFontEngineGlyphCache::Type cacheType)
         : QSG8BitTextMaskShader(cacheType)
-    { }
+    {
+        setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/styledtext.vert"));
+        setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/styledtext.frag"));
+    }
 
     virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
 
 private:
     virtual void initialize();
-    virtual const char *vertexShader() const;
-    virtual const char *fragmentShader() const;
 
     int m_shift_id;
     int m_styleColor_id;
@@ -367,98 +327,17 @@ void QSGStyledTextShader::updateState(const RenderState &state,
         program()->setUniformValue(m_matrix_id, state.combinedMatrix());
 }
 
-const char *QSGStyledTextShader::vertexShader() const
-{
-    return
-        "uniform highp mat4 matrix;                     \n"
-        "uniform highp vec2 textureScale;               \n"
-        "uniform highp vec2 shift;                      \n"
-        "attribute highp vec4 vCoord;                   \n"
-        "attribute highp vec2 tCoord;                   \n"
-        "varying highp vec2 sampleCoord;                \n"
-        "varying highp vec2 shiftedSampleCoord;         \n"
-        "void main() {                                  \n"
-        "     sampleCoord = tCoord * textureScale;      \n"
-        "     shiftedSampleCoord = (tCoord - shift) * textureScale; \n"
-        "     gl_Position = matrix * vCoord;            \n"
-        "}";
-}
-
-const char *QSGStyledTextShader::fragmentShader() const
-{
-    return
-        "varying highp vec2 sampleCoord;                \n"
-        "varying highp vec2 shiftedSampleCoord;         \n"
-        "uniform sampler2D _qt_texture;                 \n"
-        "uniform lowp vec4 color;                       \n"
-        "uniform lowp vec4 styleColor;                  \n"
-        "void main() {                                                                      \n"
-        "    lowp float glyph = texture2D(_qt_texture, sampleCoord).a;                      \n"
-        "    lowp float style = clamp(texture2D(_qt_texture, shiftedSampleCoord).a - glyph, \n"
-        "                             0.0, 1.0);                                            \n"
-        "    gl_FragColor = style * styleColor + glyph * color;                             \n"
-        "}";
-}
-
-
 class QSGOutlinedTextShader : public QSGStyledTextShader
 {
 public:
     QSGOutlinedTextShader(QFontEngineGlyphCache::Type cacheType)
         : QSGStyledTextShader(cacheType)
-    { }
-
-private:
-    const char *vertexShader() const;
-    const char *fragmentShader() const;
+    {
+        setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/outlinedtext.vert"));
+        setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/outlinedtext.frag"));
+    }
 };
 
-const char *QSGOutlinedTextShader::vertexShader() const
-{
-    return
-        "uniform highp mat4 matrix;                     \n"
-        "uniform highp vec2 textureScale;               \n"
-        "uniform highp vec2 shift;                      \n"
-        "attribute highp vec4 vCoord;                   \n"
-        "attribute highp vec2 tCoord;                   \n"
-        "varying highp vec2 sampleCoord;                \n"
-        "varying highp vec2 sCoordUp;                   \n"
-        "varying highp vec2 sCoordDown;                 \n"
-        "varying highp vec2 sCoordLeft;                 \n"
-        "varying highp vec2 sCoordRight;                \n"
-        "void main() {                                  \n"
-        "     sampleCoord = tCoord * textureScale;                    \n"
-        "     sCoordUp = (tCoord - vec2(0.0, -1.0)) * textureScale;   \n"
-        "     sCoordDown = (tCoord - vec2(0.0, 1.0)) * textureScale;  \n"
-        "     sCoordLeft = (tCoord - vec2(-1.0, 0.0)) * textureScale; \n"
-        "     sCoordRight = (tCoord - vec2(1.0, 0.0)) * textureScale; \n"
-        "     gl_Position = matrix * vCoord;                          \n"
-        "}";
-}
-
-const char *QSGOutlinedTextShader::fragmentShader() const
-{
-    return
-        "varying highp vec2 sampleCoord;                \n"
-        "varying highp vec2 sCoordUp;                   \n"
-        "varying highp vec2 sCoordDown;                 \n"
-        "varying highp vec2 sCoordLeft;                 \n"
-        "varying highp vec2 sCoordRight;                \n"
-        "uniform sampler2D _qt_texture;                 \n"
-        "uniform lowp vec4 color;                       \n"
-        "uniform lowp vec4 styleColor;                  \n"
-        "void main() {                                                                \n"
-            "lowp float glyph = texture2D(_qt_texture, sampleCoord).a;                \n"
-        "    lowp float outline = clamp(clamp(texture2D(_qt_texture, sCoordUp).a +    \n"
-        "                                     texture2D(_qt_texture, sCoordDown).a +  \n"
-        "                                     texture2D(_qt_texture, sCoordLeft).a +  \n"
-        "                                     texture2D(_qt_texture, sCoordRight).a,  \n"
-        "                                     0.0, 1.0) - glyph,                      \n"
-        "                               0.0, 1.0);                                    \n"
-        "    gl_FragColor = outline * styleColor + glyph * color;                     \n"
-        "}";
-}
-
 QSGTextMaskMaterial::QSGTextMaskMaterial(const QRawFont &font, int cacheType)
     : m_texture(0)
     , m_glyphCache(0)
diff --git a/src/quick/scenegraph/qsgdefaultimagenode.cpp b/src/quick/scenegraph/qsgdefaultimagenode.cpp
index 11d0e5dbeb4c4427835593f3a436f8aa372ce1ad..926c0c1f4a3fc61072d55d5c05e49f9eec87f86b 100644
--- a/src/quick/scenegraph/qsgdefaultimagenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultimagenode.cpp
@@ -40,6 +40,7 @@
 ****************************************************************************/
 
 #include "qsgdefaultimagenode_p.h"
+#include <private/qsgmaterialshader_p.h>
 
 #include <QtCore/qvarlengtharray.h>
 #include <QtCore/qmath.h>
@@ -75,13 +76,13 @@ namespace
 class SmoothTextureMaterialShader : public QSGTextureMaterialShader
 {
 public:
+    SmoothTextureMaterialShader();
+
     virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
     virtual char const *const *attributeNames() const;
 
 protected:
     virtual void initialize();
-    virtual const char *vertexShader() const;
-    virtual const char *fragmentShader() const;
 
     int m_pixelSizeLoc;
 };
@@ -109,6 +110,13 @@ QSGMaterialShader *QSGSmoothTextureMaterial::createShader() const
     return new SmoothTextureMaterialShader;
 }
 
+SmoothTextureMaterialShader::SmoothTextureMaterialShader()
+    : QSGTextureMaterialShader()
+{
+    setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/smoothtexture.vert"));
+    setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/smoothtexture.frag"));
+}
+
 void SmoothTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
 {
     if (oldEffect == 0) {
@@ -137,70 +145,6 @@ void SmoothTextureMaterialShader::initialize()
     QSGTextureMaterialShader::initialize();
 }
 
-const char *SmoothTextureMaterialShader::vertexShader() const
-{
-    return
-            "uniform highp vec2 pixelSize; \n"
-            "uniform highp mat4 qt_Matrix; \n"
-            "uniform lowp float opacity; \n"
-            "attribute highp vec4 vertex; \n"
-            "attribute highp vec2 multiTexCoord; \n"
-            "attribute highp vec2 vertexOffset; \n"
-            "attribute highp vec2 texCoordOffset; \n"
-            "varying highp vec2 texCoord; \n"
-            "varying lowp float vertexOpacity; \n"
-            "void main() { \n"
-            "    highp vec4 pos = qt_Matrix * vertex; \n"
-            "    gl_Position = pos; \n"
-            "    texCoord = multiTexCoord; \n"
-
-            "    if (vertexOffset.x != 0.) { \n"
-            "        highp vec4 delta = qt_Matrix[0] * vertexOffset.x; \n"
-            "        highp vec2 dir = delta.xy * pos.w - pos.xy * delta.w; \n"
-            "        highp vec2 ndir = .5 * pixelSize * normalize(dir / pixelSize);  \n"
-            "        dir -= ndir * delta.w * pos.w; \n"
-            "        highp float numerator = dot(dir, ndir * pos.w * pos.w); \n"
-            "        highp float scale = 0.0; \n"
-            "        if (numerator < 0.0) \n"
-            "            scale = 1.0; \n"
-            "        else \n"
-            "            scale = min(1.0, numerator / dot(dir, dir)); \n"
-            "        gl_Position += scale * delta; \n"
-            "        texCoord.x += scale * texCoordOffset.x; \n"
-            "    } \n"
-
-            "    if (vertexOffset.y != 0.) { \n"
-            "        highp vec4 delta = qt_Matrix[1] * vertexOffset.y; \n"
-            "        highp vec2 dir = delta.xy * pos.w - pos.xy * delta.w; \n"
-            "        highp vec2 ndir = .5 * pixelSize * normalize(dir / pixelSize);  \n"
-            "        dir -= ndir * delta.w * pos.w; \n"
-            "        highp float numerator = dot(dir, ndir * pos.w * pos.w); \n"
-            "        highp float scale = 0.0; \n"
-            "        if (numerator < 0.0) \n"
-            "            scale = 1.0; \n"
-            "        else \n"
-            "            scale = min(1.0, numerator / dot(dir, dir)); \n"
-            "        gl_Position += scale * delta; \n"
-            "        texCoord.y += scale * texCoordOffset.y; \n"
-            "    } \n"
-
-            "    bool onEdge = any(notEqual(vertexOffset, vec2(0.))); \n"
-            "    bool outerEdge = all(equal(texCoordOffset, vec2(0.))); \n"
-            "    vertexOpacity = onEdge && outerEdge ? 0. : opacity; \n"
-            "}";
-}
-
-const char *SmoothTextureMaterialShader::fragmentShader() const
-{
-    return
-            "uniform sampler2D qt_Texture; \n"
-            "varying highp vec2 texCoord; \n"
-            "varying lowp float vertexOpacity; \n"
-            "void main() { \n"
-            "    gl_FragColor = texture2D(qt_Texture, texCoord) * vertexOpacity; \n"
-            "}";
-}
-
 QSGDefaultImageNode::QSGDefaultImageNode()
     : m_innerSourceRect(0, 0, 1, 1)
     , m_subSourceRect(0, 0, 1, 1)
diff --git a/src/quick/scenegraph/qsgdefaultrectanglenode.cpp b/src/quick/scenegraph/qsgdefaultrectanglenode.cpp
index 14c61bae79343f8127f913b2b494870365ce6694..fb989fd6fb23d2dd8dd54993b9bf0f2c8a023f9f 100644
--- a/src/quick/scenegraph/qsgdefaultrectanglenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultrectanglenode.cpp
@@ -110,19 +110,26 @@ namespace
 class SmoothColorMaterialShader : public QSGMaterialShader
 {
 public:
+    SmoothColorMaterialShader();
+
     virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
     virtual char const *const *attributeNames() const;
 
 private:
     virtual void initialize();
-    virtual const char *vertexShader() const;
-    virtual const char *fragmentShader() const;
 
     int m_matrixLoc;
     int m_opacityLoc;
     int m_pixelSizeLoc;
 };
 
+SmoothColorMaterialShader::SmoothColorMaterialShader()
+    : QSGMaterialShader()
+{
+    setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/smoothcolor.vert"));
+    setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/smoothcolor.frag"));
+}
+
 void SmoothColorMaterialShader::updateState(const RenderState &state, QSGMaterial *, QSGMaterial *oldEffect)
 {
     if (state.isOpacityDirty())
@@ -156,61 +163,6 @@ void SmoothColorMaterialShader::initialize()
     m_pixelSizeLoc = program()->uniformLocation("pixelSize");
 }
 
-const char *SmoothColorMaterialShader::vertexShader() const
-{
-    return
-            "uniform highp vec2 pixelSize; \n"
-            "uniform highp mat4 matrix; \n"
-            "uniform lowp float opacity; \n"
-            "attribute highp vec4 vertex; \n"
-            "attribute lowp vec4 vertexColor; \n"
-            "attribute highp vec2 vertexOffset; \n"
-            "varying lowp vec4 color; \n"
-            "void main() { \n"
-            "    highp vec4 pos = matrix * vertex; \n"
-            "    gl_Position = pos; \n"
-
-            "    if (vertexOffset.x != 0.) { \n"
-            "        highp vec4 delta = matrix[0] * vertexOffset.x; \n"
-            "        highp vec2 dir = delta.xy * pos.w - pos.xy * delta.w; \n"
-            "        highp vec2 ndir = .5 * pixelSize * normalize(dir / pixelSize);  \n"
-            "        dir -= ndir * delta.w * pos.w; \n"
-            "        highp float numerator = dot(dir, ndir * pos.w * pos.w); \n"
-            "        highp float scale = 0.0; \n"
-            "        if (numerator < 0.0) \n"
-            "            scale = 1.0; \n"
-            "        else \n"
-            "            scale = min(1.0, numerator / dot(dir, dir)); \n"
-            "        gl_Position += scale * delta; \n"
-            "    } \n"
-
-            "    if (vertexOffset.y != 0.) { \n"
-            "        highp vec4 delta = matrix[1] * vertexOffset.y; \n"
-            "        highp vec2 dir = delta.xy * pos.w - pos.xy * delta.w; \n"
-            "        highp vec2 ndir = .5 * pixelSize * normalize(dir / pixelSize);  \n"
-            "        dir -= ndir * delta.w * pos.w; \n"
-            "        highp float numerator = dot(dir, ndir * pos.w * pos.w); \n"
-            "        highp float scale = 0.0; \n"
-            "        if (numerator < 0.0) \n"
-            "            scale = 1.0; \n"
-            "        else \n"
-            "            scale = min(1.0, numerator / dot(dir, dir)); \n"
-            "        gl_Position += scale * delta; \n"
-            "    } \n"
-
-            "    color = vertexColor * opacity; \n"
-            "}";
-}
-
-const char *SmoothColorMaterialShader::fragmentShader() const
-{
-    return
-            "varying lowp vec4 color; \n"
-            "void main() { \n"
-            "    gl_FragColor = color; \n"
-            "}";
-}
-
 QSGSmoothColorMaterial::QSGSmoothColorMaterial()
 {
     setFlag(RequiresFullMatrixExceptTranslate, true);
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
index 125243847ab591ffe378dce5c6fdff8cee2eccfb..ac936b6663ec2ab76d282f1ab69b987512de13e3 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
@@ -59,8 +59,6 @@ public:
 
 protected:
     virtual void initialize();
-    virtual const char *vertexShader() const;
-    virtual const char *fragmentShader() const;
 
     void updateAlphaRange(ThresholdFunc thresholdFunc, AntialiasingSpreadFunc spreadFunc);
     void updateColor(const QVector4D &c);
@@ -81,44 +79,20 @@ protected:
     float m_lastAlphaMax;
 };
 
-const char *QSGDistanceFieldTextMaterialShader::vertexShader() const {
-    return
-        "uniform highp mat4 matrix;                     \n"
-        "uniform highp vec2 textureScale;               \n"
-        "attribute highp vec4 vCoord;                   \n"
-        "attribute highp vec2 tCoord;                   \n"
-        "varying highp vec2 sampleCoord;                \n"
-        "void main() {                                  \n"
-        "     sampleCoord = tCoord * textureScale;      \n"
-        "     gl_Position = matrix * vCoord;            \n"
-        "}";
-}
-
-const char *QSGDistanceFieldTextMaterialShader::fragmentShader() const {
-    return
-        "varying highp vec2 sampleCoord;                                                \n"
-        "uniform mediump sampler2D _qt_texture;                                         \n"
-        "uniform lowp vec4 color;                                                       \n"
-        "uniform mediump float alphaMin;                                                \n"
-        "uniform mediump float alphaMax;                                                \n"
-        "void main() {                                                                  \n"
-        "    gl_FragColor = color * smoothstep(alphaMin,                                \n"
-        "                                      alphaMax,                                \n"
-        "                                      texture2D(_qt_texture, sampleCoord).a);  \n"
-        "}";
-}
-
 char const *const *QSGDistanceFieldTextMaterialShader::attributeNames() const {
     static char const *const attr[] = { "vCoord", "tCoord", 0 };
     return attr;
 }
 
 QSGDistanceFieldTextMaterialShader::QSGDistanceFieldTextMaterialShader()
-    : m_fontScale(1.0)
+    : QSGMaterialShader(),
+      m_fontScale(1.0)
     , m_matrixScale(1.0)
     , m_lastAlphaMin(-1)
     , m_lastAlphaMax(-1)
 {
+    setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/distancefieldtext.vert"));
+    setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/distancefieldtext.frag"));
 }
 
 void QSGDistanceFieldTextMaterialShader::updateAlphaRange(ThresholdFunc thresholdFunc, AntialiasingSpreadFunc spreadFunc)
@@ -287,7 +261,6 @@ public:
 
 protected:
     virtual void initialize();
-    virtual const char *fragmentShader() const = 0;
 
     int m_styleColor_id;
 };
@@ -355,7 +328,6 @@ public:
 
 protected:
     virtual void initialize();
-    virtual const char *fragmentShader() const;
 
     void updateOutlineAlphaRange(ThresholdFunc thresholdFunc, AntialiasingSpreadFunc spreadFunc, int dfRadius);
 
@@ -363,26 +335,10 @@ protected:
     int m_outlineAlphaMax1_id;
 };
 
-const char *DistanceFieldOutlineTextMaterialShader::fragmentShader() const {
-    return
-            "varying highp vec2 sampleCoord;                                                      \n"
-            "uniform sampler2D _qt_texture;                                                       \n"
-            "uniform lowp vec4 color;                                                             \n"
-            "uniform lowp vec4 styleColor;                                                        \n"
-            "uniform mediump float alphaMin;                                                      \n"
-            "uniform mediump float alphaMax;                                                      \n"
-            "uniform mediump float outlineAlphaMax0;                                              \n"
-            "uniform mediump float outlineAlphaMax1;                                              \n"
-            "void main() {                                                                        \n"
-            "    mediump float d = texture2D(_qt_texture, sampleCoord).a;                         \n"
-            "    gl_FragColor = mix(styleColor, color, smoothstep(alphaMin, alphaMax, d))         \n"
-            "                       * smoothstep(outlineAlphaMax0, outlineAlphaMax1, d);          \n"
-            "}";
-}
-
 DistanceFieldOutlineTextMaterialShader::DistanceFieldOutlineTextMaterialShader()
     : DistanceFieldStyledTextMaterialShader()
 {
+    setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/distancefieldoutlinetext.frag"));
 }
 
 void DistanceFieldOutlineTextMaterialShader::initialize()
@@ -454,8 +410,6 @@ public:
 
 protected:
     virtual void initialize();
-    virtual const char *vertexShader() const;
-    virtual const char *fragmentShader() const;
 
     void updateShift(qreal fontScale, const QPointF& shift);
 
@@ -465,6 +419,8 @@ protected:
 DistanceFieldShiftedStyleTextMaterialShader::DistanceFieldShiftedStyleTextMaterialShader()
     : DistanceFieldStyledTextMaterialShader()
 {
+    setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/distancefieldshiftedtext.vert"));
+    setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/distancefieldshiftedtext.frag"));
 }
 
 void DistanceFieldShiftedStyleTextMaterialShader::initialize()
@@ -495,41 +451,6 @@ void DistanceFieldShiftedStyleTextMaterialShader::updateShift(qreal fontScale, c
     program()->setUniformValue(m_shift_id, texel);
 }
 
-const char *DistanceFieldShiftedStyleTextMaterialShader::vertexShader() const
-{
-    return
-            "uniform highp mat4 matrix;                                 \n"
-            "uniform highp vec2 textureScale;                           \n"
-            "attribute highp vec4 vCoord;                               \n"
-            "attribute highp vec2 tCoord;                               \n"
-            "uniform highp vec2 shift;                                  \n"
-            "varying highp vec2 sampleCoord;                            \n"
-            "varying highp vec2 shiftedSampleCoord;                     \n"
-            "void main() {                                              \n"
-            "     sampleCoord = tCoord * textureScale;                  \n"
-            "     shiftedSampleCoord = (tCoord - shift) * textureScale; \n"
-            "     gl_Position = matrix * vCoord;                        \n"
-            "}";
-}
-
-const char *DistanceFieldShiftedStyleTextMaterialShader::fragmentShader() const {
-    return
-            "varying highp vec2 sampleCoord;                                                                 \n"
-            "varying highp vec2 shiftedSampleCoord;                                                          \n"
-            "uniform sampler2D _qt_texture;                                                                  \n"
-            "uniform lowp vec4 color;                                                                        \n"
-            "uniform lowp vec4 styleColor;                                                                   \n"
-            "uniform mediump float alphaMin;                                                                 \n"
-            "uniform mediump float alphaMax;                                                                 \n"
-            "void main() {                                                                                   \n"
-            "    highp float a = smoothstep(alphaMin, alphaMax, texture2D(_qt_texture, sampleCoord).a);      \n"
-            "    highp vec4 shifted = styleColor * smoothstep(alphaMin,                                      \n"
-            "                                                 alphaMax,                                      \n"
-            "                                                 texture2D(_qt_texture, shiftedSampleCoord).a); \n"
-            "    gl_FragColor = mix(shifted, color, a);                                                      \n"
-            "}";
-}
-
 QSGDistanceFieldShiftedStyleTextMaterial::QSGDistanceFieldShiftedStyleTextMaterial()
     : QSGDistanceFieldStyledTextMaterial()
 {
@@ -554,107 +475,24 @@ QSGMaterialShader *QSGDistanceFieldShiftedStyleTextMaterial::createShader() cons
 class QSGHiQSubPixelDistanceFieldTextMaterialShader : public QSGDistanceFieldTextMaterialShader
 {
 public:
+    QSGHiQSubPixelDistanceFieldTextMaterialShader();
+
     virtual void initialize();
     virtual void activate();
     virtual void deactivate();
     virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
 
-protected:
-    virtual const char *vertexShader() const;
-    virtual const char *fragmentShader() const;
-
 private:
     int m_fontScale_id;
     int m_vecDelta_id;
 };
 
-const char *QSGHiQSubPixelDistanceFieldTextMaterialShader::vertexShader() const {
-    return
-        "uniform highp mat4 matrix;                                             \n"
-        "uniform highp vec2 textureScale;                                       \n"
-        "uniform highp float fontScale;                                         \n"
-        "uniform highp vec4 vecDelta;                                           \n"
-        "attribute highp vec4 vCoord;                                           \n"
-        "attribute highp vec2 tCoord;                                           \n"
-        "varying highp vec2 sampleCoord;                                        \n"
-        "varying highp vec3 sampleFarLeft;                                      \n"
-        "varying highp vec3 sampleNearLeft;                                     \n"
-        "varying highp vec3 sampleNearRight;                                    \n"
-        "varying highp vec3 sampleFarRight;                                     \n"
-        "void main() {                                                          \n"
-        "     sampleCoord = tCoord * textureScale;                              \n"
-        "     gl_Position = matrix * vCoord;                                    \n"
-        // Calculate neighbour pixel position in item space.
-        "     highp vec3 wDelta = gl_Position.w * vecDelta.xyw;                 \n"
-        "     highp vec3 farLeft = vCoord.xyw - 0.667 * wDelta;                 \n"
-        "     highp vec3 nearLeft = vCoord.xyw - 0.333 * wDelta;                \n"
-        "     highp vec3 nearRight = vCoord.xyw + 0.333 * wDelta;               \n"
-        "     highp vec3 farRight = vCoord.xyw + 0.667 * wDelta;                \n"
-        // Calculate neighbour texture coordinate.
-        "     highp vec2 scale = textureScale / fontScale;                      \n"
-        "     highp vec2 base = sampleCoord - scale * vCoord.xy;                \n"
-        "     sampleFarLeft = vec3(base * farLeft.z + scale * farLeft.xy, farLeft.z); \n"
-        "     sampleNearLeft = vec3(base * nearLeft.z + scale * nearLeft.xy, nearLeft.z); \n"
-        "     sampleNearRight = vec3(base * nearRight.z + scale * nearRight.xy, nearRight.z); \n"
-        "     sampleFarRight = vec3(base * farRight.z + scale * farRight.xy, farRight.z); \n"
-        "}";
-}
-
-const char *QSGHiQSubPixelDistanceFieldTextMaterialShader::fragmentShader() const {
-    return
-        "varying highp vec2 sampleCoord;                                        \n"
-        "varying highp vec3 sampleFarLeft;                                      \n"
-        "varying highp vec3 sampleNearLeft;                                     \n"
-        "varying highp vec3 sampleNearRight;                                    \n"
-        "varying highp vec3 sampleFarRight;                                     \n"
-        "uniform sampler2D _qt_texture;                                         \n"
-        "uniform lowp vec4 color;                                               \n"
-        "uniform mediump float alphaMin;                                        \n"
-        "uniform mediump float alphaMax;                                        \n"
-        "void main() {                                                          \n"
-        "    highp vec4 n;                                                      \n"
-        "    n.x = texture2DProj(_qt_texture, sampleFarLeft).a;                 \n"
-        "    n.y = texture2DProj(_qt_texture, sampleNearLeft).a;                \n"
-        "    highp float c = texture2D(_qt_texture, sampleCoord).a;             \n"
-        "    n.z = texture2DProj(_qt_texture, sampleNearRight).a;               \n"
-        "    n.w = texture2DProj(_qt_texture, sampleFarRight).a;                \n"
-#if 0
-        // Blurrier, faster.
-        "    n = smoothstep(alphaMin, alphaMax, n);                             \n"
-        "    c = smoothstep(alphaMin, alphaMax, c);                             \n"
-#else
-        // Sharper, slower.
-        "    highp vec2 d = min(abs(n.yw - n.xz) * 2., 0.67);                   \n"
-        "    highp vec2 lo = mix(vec2(alphaMin), vec2(0.5), d);                 \n"
-        "    highp vec2 hi = mix(vec2(alphaMax), vec2(0.5), d);                 \n"
-        "    n = smoothstep(lo.xxyy, hi.xxyy, n);                               \n"
-        "    c = smoothstep(lo.x + lo.y, hi.x + hi.y, 2. * c);                  \n"
-#endif
-        "    gl_FragColor = vec4(0.333 * (n.xyz + n.yzw + c), c) * color.w;     \n"
-        "}";
-}
-
-//const char *QSGHiQSubPixelDistanceFieldTextMaterialShader::fragmentShader() const {
-//    return
-//        "#extension GL_OES_standard_derivatives: enable                         \n"
-//        "varying highp vec2 sampleCoord;                                        \n"
-//        "uniform sampler2D _qt_texture;                                         \n"
-//        "uniform lowp vec4 color;                                               \n"
-//        "uniform highp float alphaMin;                                          \n"
-//        "uniform highp float alphaMax;                                          \n"
-//        "void main() {                                                          \n"
-//        "    highp vec2 delta = dFdx(sampleCoord);                              \n"
-//        "    highp vec4 n;                                                      \n"
-//        "    n.x = texture2D(_qt_texture, sampleCoord - 0.667 * delta).a;       \n"
-//        "    n.y = texture2D(_qt_texture, sampleCoord - 0.333 * delta).a;       \n"
-//        "    highp float c = texture2D(_qt_texture, sampleCoord).a;             \n"
-//        "    n.z = texture2D(_qt_texture, sampleCoord + 0.333 * delta).a;       \n"
-//        "    n.w = texture2D(_qt_texture, sampleCoord + 0.667 * delta).a;       \n"
-//        "    n = smoothstep(alphaMin, alphaMax, n);                             \n"
-//        "    c = smoothstep(alphaMin, alphaMax, c);                             \n"
-//        "    gl_FragColor = vec4(0.333 * (n.xyz + n.yzw + c), c) * color.w;     \n"
-//        "}";
-//}
+QSGHiQSubPixelDistanceFieldTextMaterialShader::QSGHiQSubPixelDistanceFieldTextMaterialShader()
+    : QSGDistanceFieldTextMaterialShader()
+{
+    setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/hiqsubpixeldistancefieldtext.vert"));
+    setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/hiqsubpixeldistancefieldtext.frag"));
+}
 
 void QSGHiQSubPixelDistanceFieldTextMaterialShader::initialize()
 {
@@ -712,52 +550,15 @@ QSGMaterialShader *QSGHiQSubPixelDistanceFieldTextMaterial::createShader() const
 
 class QSGLoQSubPixelDistanceFieldTextMaterialShader : public QSGHiQSubPixelDistanceFieldTextMaterialShader
 {
-protected:
-    virtual const char *vertexShader() const;
-    virtual const char *fragmentShader() const;
+public:
+    QSGLoQSubPixelDistanceFieldTextMaterialShader();
 };
 
-const char *QSGLoQSubPixelDistanceFieldTextMaterialShader::vertexShader() const {
-    return
-        "uniform highp mat4 matrix;                                             \n"
-        "uniform highp vec2 textureScale;                                       \n"
-        "uniform highp float fontScale;                                         \n"
-        "uniform highp vec4 vecDelta;                                           \n"
-        "attribute highp vec4 vCoord;                                           \n"
-        "attribute highp vec2 tCoord;                                           \n"
-        "varying highp vec3 sampleNearLeft;                                     \n"
-        "varying highp vec3 sampleNearRight;                                    \n"
-        "void main() {                                                          \n"
-        "     highp vec2 sampleCoord = tCoord * textureScale;                   \n"
-        "     gl_Position = matrix * vCoord;                                    \n"
-        // Calculate neighbour pixel position in item space.
-        "     highp vec3 wDelta = gl_Position.w * vecDelta.xyw;                 \n"
-        "     highp vec3 nearLeft = vCoord.xyw - 0.25 * wDelta;                 \n"
-        "     highp vec3 nearRight = vCoord.xyw + 0.25 * wDelta;                \n"
-        // Calculate neighbour texture coordinate.
-        "     highp vec2 scale = textureScale / fontScale;                      \n"
-        "     highp vec2 base = sampleCoord - scale * vCoord.xy;                \n"
-        "     sampleNearLeft = vec3(base * nearLeft.z + scale * nearLeft.xy, nearLeft.z); \n"
-        "     sampleNearRight = vec3(base * nearRight.z + scale * nearRight.xy, nearRight.z); \n"
-        "}";
-}
-
-const char *QSGLoQSubPixelDistanceFieldTextMaterialShader::fragmentShader() const {
-    return
-        "varying highp vec3 sampleNearLeft;                                     \n"
-        "varying highp vec3 sampleNearRight;                                    \n"
-        "uniform sampler2D _qt_texture;                                         \n"
-        "uniform lowp vec4 color;                                               \n"
-        "uniform mediump float alphaMin;                                        \n"
-        "uniform mediump float alphaMax;                                        \n"
-        "void main() {                                                          \n"
-        "    highp vec2 n;                                                      \n"
-        "    n.x = texture2DProj(_qt_texture, sampleNearLeft).a;                \n"
-        "    n.y = texture2DProj(_qt_texture, sampleNearRight).a;               \n"
-        "    n = smoothstep(alphaMin, alphaMax, n);                             \n"
-        "    highp float c = 0.5 * (n.x + n.y);                                 \n"
-        "    gl_FragColor = vec4(n.x, c, n.y, c) * color.w;                     \n"
-        "}";
+QSGLoQSubPixelDistanceFieldTextMaterialShader::QSGLoQSubPixelDistanceFieldTextMaterialShader()
+    : QSGHiQSubPixelDistanceFieldTextMaterialShader()
+{
+    setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/loqsubpixeldistancefieldtext.vert"));
+    setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/loqsubpixeldistancefieldtext.frag"));
 }
 
 QSGMaterialType *QSGLoQSubPixelDistanceFieldTextMaterial::type() const
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index 2bcef4384369c0139b81abf31c50043f8218ecfd..aebc2ece9c9c390570326eee8bdc1d712d49788c 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -10,7 +10,8 @@ HEADERS += \
     $$PWD/coreapi/qsgnodeupdater_p.h \
     $$PWD/coreapi/qsgrenderer_p.h \
     $$PWD/coreapi/qsgrendernode_p.h \
-    $$PWD/coreapi/qsggeometry_p.h
+    $$PWD/coreapi/qsggeometry_p.h \
+    $$PWD/coreapi/qsgmaterialshader_p.h
 
 SOURCES += \
     $$PWD/coreapi/qsgbatchrenderer.cpp \
@@ -20,8 +21,7 @@ SOURCES += \
     $$PWD/coreapi/qsgnodeupdater.cpp \
     $$PWD/coreapi/qsgrenderer.cpp \
     $$PWD/coreapi/qsgrendernode.cpp \
-    $$PWD/coreapi/qsgshaderrewriter.cpp \
-    scenegraph/util/qsgsimplematerial.cpp
+    $$PWD/coreapi/qsgshaderrewriter.cpp
 
 # Util API
 HEADERS += \
@@ -39,7 +39,8 @@ HEADERS += \
     $$PWD/util/qsgtexture_p.h \
     $$PWD/util/qsgtextureprovider.h \
     $$PWD/util/qsgpainternode_p.h \
-    $$PWD/util/qsgdistancefieldutil_p.h
+    $$PWD/util/qsgdistancefieldutil_p.h \
+    $$PWD/util/qsgshadersourcebuilder_p.h
 
 SOURCES += \
     $$PWD/util/qsgareaallocator.cpp \
@@ -53,7 +54,9 @@ SOURCES += \
     $$PWD/util/qsgtexture.cpp \
     $$PWD/util/qsgtextureprovider.cpp \
     $$PWD/util/qsgpainternode.cpp \
-    $$PWD/util/qsgdistancefieldutil.cpp
+    $$PWD/util/qsgdistancefieldutil.cpp \
+    $$PWD/util/qsgsimplematerial.cpp \
+    $$PWD/util/qsgshadersourcebuilder.cpp
 
 # QML / Adaptations API
 HEADERS += \
@@ -87,3 +90,41 @@ SOURCES += \
     $$PWD/qsgrenderloop.cpp \
     $$PWD/qsgthreadedrenderloop.cpp \
     $$PWD/qsgwindowsrenderloop.cpp
+
+RESOURCES += \
+    $$PWD/scenegraph.qrc
+
+OTHER_FILES += \
+    $$PWD/shaders/24bittextmask.frag \
+    $$PWD/shaders/8bittextmask.frag \
+    $$PWD/shaders/distancefieldoutlinetext.frag \
+    $$PWD/shaders/distancefieldshiftedtext.frag \
+    $$PWD/shaders/distancefieldshiftedtext.vert \
+    $$PWD/shaders/distancefieldtext.frag \
+    $$PWD/shaders/distancefieldtext.vert \
+    $$PWD/shaders/flatcolor.frag \
+    $$PWD/shaders/flatcolor.vert \
+    $$PWD/shaders/hiqsubpixeldistancefieldtext.frag \
+    $$PWD/shaders/hiqsubpixeldistancefieldtext.vert \
+    $$PWD/shaders/loqsubpixeldistancefieldtext.frag \
+    $$PWD/shaders/loqsubpixeldistancefieldtext.vert \
+    $$PWD/shaders/opaquetexture.frag \
+    $$PWD/shaders/opaquetexture.vert \
+    $$PWD/shaders/outlinedtext.frag \
+    $$PWD/shaders/outlinedtext.vert \
+    $$PWD/shaders/rendernode.frag \
+    $$PWD/shaders/rendernode.vert \
+    $$PWD/shaders/smoothcolor.frag \
+    $$PWD/shaders/smoothcolor.vert \
+    $$PWD/shaders/smoothtexture.frag \
+    $$PWD/shaders/smoothtexture.vert \
+    $$PWD/shaders/stencilclip.frag \
+    $$PWD/shaders/stencilclip.vert \
+    $$PWD/shaders/styledtext.frag \
+    $$PWD/shaders/styledtext.vert \
+    $$PWD/shaders/textmask.frag \
+    $$PWD/shaders/textmask.vert \
+    $$PWD/shaders/texture.frag \
+    $$PWD/shaders/vertexcolor.frag \
+    $$PWD/shaders/vertexcolor.vert
+
diff --git a/src/quick/scenegraph/scenegraph.qrc b/src/quick/scenegraph/scenegraph.qrc
new file mode 100644
index 0000000000000000000000000000000000000000..5299ec6d9ff0e1a18b54b5b7d98c283c3191ed99
--- /dev/null
+++ b/src/quick/scenegraph/scenegraph.qrc
@@ -0,0 +1,36 @@
+<RCC>
+    <qresource prefix="/scenegraph">
+        <file>shaders/flatcolor.frag</file>
+        <file>shaders/flatcolor.vert</file>
+        <file>shaders/8bittextmask.frag</file>
+        <file>shaders/24bittextmask.frag</file>
+        <file>shaders/opaquetexture.frag</file>
+        <file>shaders/opaquetexture.vert</file>
+        <file>shaders/outlinedtext.frag</file>
+        <file>shaders/outlinedtext.vert</file>
+        <file>shaders/smoothcolor.frag</file>
+        <file>shaders/smoothcolor.vert</file>
+        <file>shaders/smoothtexture.frag</file>
+        <file>shaders/smoothtexture.vert</file>
+        <file>shaders/styledtext.frag</file>
+        <file>shaders/styledtext.vert</file>
+        <file>shaders/textmask.frag</file>
+        <file>shaders/textmask.vert</file>
+        <file>shaders/texture.frag</file>
+        <file>shaders/distancefieldoutlinetext.frag</file>
+        <file>shaders/distancefieldshiftedtext.frag</file>
+        <file>shaders/distancefieldshiftedtext.vert</file>
+        <file>shaders/distancefieldtext.frag</file>
+        <file>shaders/distancefieldtext.vert</file>
+        <file>shaders/hiqsubpixeldistancefieldtext.frag</file>
+        <file>shaders/hiqsubpixeldistancefieldtext.vert</file>
+        <file>shaders/loqsubpixeldistancefieldtext.frag</file>
+        <file>shaders/loqsubpixeldistancefieldtext.vert</file>
+        <file>shaders/vertexcolor.frag</file>
+        <file>shaders/vertexcolor.vert</file>
+        <file>shaders/rendernode.vert</file>
+        <file>shaders/rendernode.frag</file>
+        <file>shaders/stencilclip.frag</file>
+        <file>shaders/stencilclip.vert</file>
+    </qresource>
+</RCC>
diff --git a/src/quick/scenegraph/shaders/24bittextmask.frag b/src/quick/scenegraph/shaders/24bittextmask.frag
new file mode 100644
index 0000000000000000000000000000000000000000..ac62e7b642fb6a5e203a7961f071196a0fa9e7c3
--- /dev/null
+++ b/src/quick/scenegraph/shaders/24bittextmask.frag
@@ -0,0 +1,10 @@
+varying highp vec2 sampleCoord;
+
+uniform lowp sampler2D texture;
+uniform lowp float color; // just the alpha, really...
+
+void main()
+{
+    lowp vec4 glyph = texture2D(texture, sampleCoord);
+    gl_FragColor = vec4(glyph.rgb * color, glyph.a);
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/8bittextmask.frag b/src/quick/scenegraph/shaders/8bittextmask.frag
new file mode 100644
index 0000000000000000000000000000000000000000..f2f06e8e0705f6a28f169a79c4c7c514deb15b47
--- /dev/null
+++ b/src/quick/scenegraph/shaders/8bittextmask.frag
@@ -0,0 +1,9 @@
+varying highp vec2 sampleCoord;
+
+uniform lowp sampler2D texture;
+uniform lowp vec4 color;
+
+void main()
+{
+    gl_FragColor = color * texture2D(texture, sampleCoord).a;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/distancefieldoutlinetext.frag b/src/quick/scenegraph/shaders/distancefieldoutlinetext.frag
new file mode 100644
index 0000000000000000000000000000000000000000..250ed322a1f0bf8cb0d9dc900efebd7e3ab4cc95
--- /dev/null
+++ b/src/quick/scenegraph/shaders/distancefieldoutlinetext.frag
@@ -0,0 +1,16 @@
+varying highp vec2 sampleCoord;
+
+uniform sampler2D _qt_texture;
+uniform lowp vec4 color;
+uniform lowp vec4 styleColor;
+uniform mediump float alphaMin;
+uniform mediump float alphaMax;
+uniform mediump float outlineAlphaMax0;
+uniform mediump float outlineAlphaMax1;
+
+void main()
+{
+    mediump float d = texture2D(_qt_texture, sampleCoord).a;
+    gl_FragColor = mix(styleColor, color, smoothstep(alphaMin, alphaMax, d))
+                       * smoothstep(outlineAlphaMax0, outlineAlphaMax1, d);
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/distancefieldshiftedtext.frag b/src/quick/scenegraph/shaders/distancefieldshiftedtext.frag
new file mode 100644
index 0000000000000000000000000000000000000000..60c1c7468b233044f03b9bb100c335d62de0f7ce
--- /dev/null
+++ b/src/quick/scenegraph/shaders/distancefieldshiftedtext.frag
@@ -0,0 +1,17 @@
+varying highp vec2 sampleCoord;
+varying highp vec2 shiftedSampleCoord;
+
+uniform sampler2D _qt_texture;
+uniform lowp vec4 color;
+uniform lowp vec4 styleColor;
+uniform mediump float alphaMin;
+uniform mediump float alphaMax;
+
+void main()
+{
+    highp float a = smoothstep(alphaMin, alphaMax, texture2D(_qt_texture, sampleCoord).a);
+    highp vec4 shifted = styleColor * smoothstep(alphaMin,
+                                                 alphaMax,
+                                                 texture2D(_qt_texture, shiftedSampleCoord).a);
+    gl_FragColor = mix(shifted, color, a);
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/distancefieldshiftedtext.vert b/src/quick/scenegraph/shaders/distancefieldshiftedtext.vert
new file mode 100644
index 0000000000000000000000000000000000000000..800eadc4f1bde9a8bf28f441aae9f7ea53e44b2b
--- /dev/null
+++ b/src/quick/scenegraph/shaders/distancefieldshiftedtext.vert
@@ -0,0 +1,17 @@
+uniform highp mat4 matrix;
+uniform highp vec2 textureScale;
+
+attribute highp vec4 vCoord;
+attribute highp vec2 tCoord;
+
+uniform highp vec2 shift;
+
+varying highp vec2 sampleCoord;
+varying highp vec2 shiftedSampleCoord;
+
+void main()
+{
+     sampleCoord = tCoord * textureScale;
+     shiftedSampleCoord = (tCoord - shift) * textureScale;
+     gl_Position = matrix * vCoord;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/distancefieldtext.frag b/src/quick/scenegraph/shaders/distancefieldtext.frag
new file mode 100644
index 0000000000000000000000000000000000000000..951fb2a82546e25593f3627eb4d0d22715ad79db
--- /dev/null
+++ b/src/quick/scenegraph/shaders/distancefieldtext.frag
@@ -0,0 +1,13 @@
+varying highp vec2 sampleCoord;
+
+uniform mediump sampler2D _qt_texture;
+uniform lowp vec4 color;
+uniform mediump float alphaMin;
+uniform mediump float alphaMax;
+
+void main()
+{
+    gl_FragColor = color * smoothstep(alphaMin,
+                                      alphaMax,
+                                      texture2D(_qt_texture, sampleCoord).a);
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/distancefieldtext.vert b/src/quick/scenegraph/shaders/distancefieldtext.vert
new file mode 100644
index 0000000000000000000000000000000000000000..c4963977a5a827914b8fccbc5f95c3f6f43c4673
--- /dev/null
+++ b/src/quick/scenegraph/shaders/distancefieldtext.vert
@@ -0,0 +1,13 @@
+uniform highp mat4 matrix;
+uniform highp vec2 textureScale;
+
+attribute highp vec4 vCoord;
+attribute highp vec2 tCoord;
+
+varying highp vec2 sampleCoord;
+
+void main()
+{
+     sampleCoord = tCoord * textureScale;
+     gl_Position = matrix * vCoord;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/flatcolor.frag b/src/quick/scenegraph/shaders/flatcolor.frag
new file mode 100644
index 0000000000000000000000000000000000000000..8c225bf5a4ddc3b7db4bbf5d01e76632fd16f345
--- /dev/null
+++ b/src/quick/scenegraph/shaders/flatcolor.frag
@@ -0,0 +1,6 @@
+uniform lowp vec4 color;
+
+void main()
+{
+    gl_FragColor = color;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/flatcolor.vert b/src/quick/scenegraph/shaders/flatcolor.vert
new file mode 100644
index 0000000000000000000000000000000000000000..a61de97f853024f98cb5c6ec47af8c3236de485f
--- /dev/null
+++ b/src/quick/scenegraph/shaders/flatcolor.vert
@@ -0,0 +1,7 @@
+attribute highp vec4 vCoord;
+uniform highp mat4 matrix;
+
+void main()
+{
+    gl_Position = matrix * vCoord;
+}
diff --git a/src/quick/scenegraph/shaders/hiqsubpixeldistancefieldtext.frag b/src/quick/scenegraph/shaders/hiqsubpixeldistancefieldtext.frag
new file mode 100644
index 0000000000000000000000000000000000000000..9b65e5f79b09e8997c5ef6b7989f1b73b25f54d1
--- /dev/null
+++ b/src/quick/scenegraph/shaders/hiqsubpixeldistancefieldtext.frag
@@ -0,0 +1,58 @@
+varying highp vec2 sampleCoord;
+varying highp vec3 sampleFarLeft;
+varying highp vec3 sampleNearLeft;
+varying highp vec3 sampleNearRight;
+varying highp vec3 sampleFarRight;
+
+uniform sampler2D _qt_texture;
+uniform lowp vec4 color;
+uniform mediump float alphaMin;
+uniform mediump float alphaMax;
+
+void main()
+{
+    highp vec4 n;
+    n.x = texture2DProj(_qt_texture, sampleFarLeft).a;
+    n.y = texture2DProj(_qt_texture, sampleNearLeft).a;
+    highp float c = texture2D(_qt_texture, sampleCoord).a;
+    n.z = texture2DProj(_qt_texture, sampleNearRight).a;
+    n.w = texture2DProj(_qt_texture, sampleFarRight).a;
+#if 0
+    // Blurrier, faster.
+    n = smoothstep(alphaMin, alphaMax, n);
+    c = smoothstep(alphaMin, alphaMax, c);
+#else
+    // Sharper, slower.
+    highp vec2 d = min(abs(n.yw - n.xz) * 2., 0.67);
+    highp vec2 lo = mix(vec2(alphaMin), vec2(0.5), d);
+    highp vec2 hi = mix(vec2(alphaMax), vec2(0.5), d);
+    n = smoothstep(lo.xxyy, hi.xxyy, n);
+    c = smoothstep(lo.x + lo.y, hi.x + hi.y, 2. * c);
+#endif
+    gl_FragColor = vec4(0.333 * (n.xyz + n.yzw + c), c) * color.w;
+}
+
+/*
+#extension GL_OES_standard_derivatives: enable
+
+varying highp vec2 sampleCoord;
+
+uniform sampler2D _qt_texture;
+uniform lowp vec4 color;
+uniform highp float alphaMin;
+uniform highp float alphaMax;
+
+void main()
+{
+    highp vec2 delta = dFdx(sampleCoord);
+    highp vec4 n;
+    n.x = texture2D(_qt_texture, sampleCoord - 0.667 * delta).a;
+    n.y = texture2D(_qt_texture, sampleCoord - 0.333 * delta).a;
+    highp float c = texture2D(_qt_texture, sampleCoord).a;
+    n.z = texture2D(_qt_texture, sampleCoord + 0.333 * delta).a;
+    n.w = texture2D(_qt_texture, sampleCoord + 0.667 * delta).a;
+    n = smoothstep(alphaMin, alphaMax, n);
+    c = smoothstep(alphaMin, alphaMax, c);
+    gl_FragColor = vec4(0.333 * (n.xyz + n.yzw + c), c) * color.w;
+};
+*/
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/hiqsubpixeldistancefieldtext.vert b/src/quick/scenegraph/shaders/hiqsubpixeldistancefieldtext.vert
new file mode 100644
index 0000000000000000000000000000000000000000..62768e88e111c9d1b94a8016872641689821b671
--- /dev/null
+++ b/src/quick/scenegraph/shaders/hiqsubpixeldistancefieldtext.vert
@@ -0,0 +1,34 @@
+uniform highp mat4 matrix;
+uniform highp vec2 textureScale;
+uniform highp float fontScale;
+uniform highp vec4 vecDelta;
+
+attribute highp vec4 vCoord;
+attribute highp vec2 tCoord;
+
+varying highp vec2 sampleCoord;
+varying highp vec3 sampleFarLeft;
+varying highp vec3 sampleNearLeft;
+varying highp vec3 sampleNearRight;
+varying highp vec3 sampleFarRight;
+
+void main()
+{
+    sampleCoord = tCoord * textureScale;
+    gl_Position = matrix * vCoord;
+
+    // Calculate neighbor pixel position in item space.
+    highp vec3 wDelta = gl_Position.w * vecDelta.xyw;
+    highp vec3 farLeft = vCoord.xyw - 0.667 * wDelta;
+    highp vec3 nearLeft = vCoord.xyw - 0.333 * wDelta;
+    highp vec3 nearRight = vCoord.xyw + 0.333 * wDelta;
+    highp vec3 farRight = vCoord.xyw + 0.667 * wDelta;
+
+    // Calculate neighbor texture coordinate.
+    highp vec2 scale = textureScale / fontScale;
+    highp vec2 base = sampleCoord - scale * vCoord.xy;
+    sampleFarLeft = vec3(base * farLeft.z + scale * farLeft.xy, farLeft.z);
+    sampleNearLeft = vec3(base * nearLeft.z + scale * nearLeft.xy, nearLeft.z);
+    sampleNearRight = vec3(base * nearRight.z + scale * nearRight.xy, nearRight.z);
+    sampleFarRight = vec3(base * farRight.z + scale * farRight.xy, farRight.z);
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/loqsubpixeldistancefieldtext.frag b/src/quick/scenegraph/shaders/loqsubpixeldistancefieldtext.frag
new file mode 100644
index 0000000000000000000000000000000000000000..61b6c8dd9adc9ddbe6826b621b78b6af046d875c
--- /dev/null
+++ b/src/quick/scenegraph/shaders/loqsubpixeldistancefieldtext.frag
@@ -0,0 +1,17 @@
+varying highp vec3 sampleNearLeft;
+varying highp vec3 sampleNearRight;
+
+uniform sampler2D _qt_texture;
+uniform lowp vec4 color;
+uniform mediump float alphaMin;
+uniform mediump float alphaMax;
+
+void main()
+{
+    highp vec2 n;
+    n.x = texture2DProj(_qt_texture, sampleNearLeft).a;
+    n.y = texture2DProj(_qt_texture, sampleNearRight).a;
+    n = smoothstep(alphaMin, alphaMax, n);
+    highp float c = 0.5 * (n.x + n.y);
+    gl_FragColor = vec4(n.x, c, n.y, c) * color.w;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/loqsubpixeldistancefieldtext.vert b/src/quick/scenegraph/shaders/loqsubpixeldistancefieldtext.vert
new file mode 100644
index 0000000000000000000000000000000000000000..33cb7efb19627b8af29222f7bd3ac449307e1277
--- /dev/null
+++ b/src/quick/scenegraph/shaders/loqsubpixeldistancefieldtext.vert
@@ -0,0 +1,27 @@
+uniform highp mat4 matrix;
+uniform highp vec2 textureScale;
+uniform highp float fontScale;
+uniform highp vec4 vecDelta;
+
+attribute highp vec4 vCoord;
+attribute highp vec2 tCoord;
+
+varying highp vec3 sampleNearLeft;
+varying highp vec3 sampleNearRight;
+
+void main()
+{
+    highp vec2 sampleCoord = tCoord * textureScale;
+    gl_Position = matrix * vCoord;
+
+    // Calculate neighbor pixel position in item space.
+    highp vec3 wDelta = gl_Position.w * vecDelta.xyw;
+    highp vec3 nearLeft = vCoord.xyw - 0.25 * wDelta;
+    highp vec3 nearRight = vCoord.xyw + 0.25 * wDelta;
+
+    // Calculate neighbor texture coordinate.
+    highp vec2 scale = textureScale / fontScale;
+    highp vec2 base = sampleCoord - scale * vCoord.xy;
+    sampleNearLeft = vec3(base * nearLeft.z + scale * nearLeft.xy, nearLeft.z);
+    sampleNearRight = vec3(base * nearRight.z + scale * nearRight.xy, nearRight.z);
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/opaquetexture.frag b/src/quick/scenegraph/shaders/opaquetexture.frag
new file mode 100644
index 0000000000000000000000000000000000000000..b7e07de3851bc1079e2627cfa0fdee9aae41cf11
--- /dev/null
+++ b/src/quick/scenegraph/shaders/opaquetexture.frag
@@ -0,0 +1,8 @@
+varying highp vec2 qt_TexCoord;
+
+uniform sampler2D qt_Texture;
+
+void main()
+{
+    gl_FragColor = texture2D(qt_Texture, qt_TexCoord);
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/opaquetexture.vert b/src/quick/scenegraph/shaders/opaquetexture.vert
new file mode 100644
index 0000000000000000000000000000000000000000..32cf02df254dccdc81414caac245dac63b19c820
--- /dev/null
+++ b/src/quick/scenegraph/shaders/opaquetexture.vert
@@ -0,0 +1,12 @@
+uniform highp mat4 qt_Matrix;
+
+attribute highp vec4 qt_VertexPosition;
+attribute highp vec2 qt_VertexTexCoord;
+
+varying highp vec2 qt_TexCoord;
+
+void main()
+{
+    qt_TexCoord = qt_VertexTexCoord;
+    gl_Position = qt_Matrix * qt_VertexPosition;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/outlinedtext.frag b/src/quick/scenegraph/shaders/outlinedtext.frag
new file mode 100644
index 0000000000000000000000000000000000000000..b3e5475d5d0634b073d17972cb154d989aae8072
--- /dev/null
+++ b/src/quick/scenegraph/shaders/outlinedtext.frag
@@ -0,0 +1,21 @@
+varying highp vec2 sampleCoord;
+varying highp vec2 sCoordUp;
+varying highp vec2 sCoordDown;
+varying highp vec2 sCoordLeft;
+varying highp vec2 sCoordRight;
+
+uniform sampler2D _qt_texture;
+uniform lowp vec4 color;
+uniform lowp vec4 styleColor;
+
+void main()
+{
+    lowp float glyph = texture2D(_qt_texture, sampleCoord).a;
+    lowp float outline = clamp(clamp(texture2D(_qt_texture, sCoordUp).a +
+                                     texture2D(_qt_texture, sCoordDown).a +
+                                     texture2D(_qt_texture, sCoordLeft).a +
+                                     texture2D(_qt_texture, sCoordRight).a,
+                                     0.0, 1.0) - glyph,
+                               0.0, 1.0);
+    gl_FragColor = outline * styleColor + glyph * color;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/outlinedtext.vert b/src/quick/scenegraph/shaders/outlinedtext.vert
new file mode 100644
index 0000000000000000000000000000000000000000..ced8afd034500c0c9d92431fe9d98deac006a1ea
--- /dev/null
+++ b/src/quick/scenegraph/shaders/outlinedtext.vert
@@ -0,0 +1,22 @@
+uniform highp mat4 matrix;
+uniform highp vec2 textureScale;
+uniform highp vec2 shift;
+
+attribute highp vec4 vCoord;
+attribute highp vec2 tCoord;
+
+varying highp vec2 sampleCoord;
+varying highp vec2 sCoordUp;
+varying highp vec2 sCoordDown;
+varying highp vec2 sCoordLeft;
+varying highp vec2 sCoordRight;
+
+void main()
+{
+     sampleCoord = tCoord * textureScale;
+     sCoordUp = (tCoord - vec2(0.0, -1.0)) * textureScale;
+     sCoordDown = (tCoord - vec2(0.0, 1.0)) * textureScale;
+     sCoordLeft = (tCoord - vec2(-1.0, 0.0)) * textureScale;
+     sCoordRight = (tCoord - vec2(1.0, 0.0)) * textureScale;
+     gl_Position = matrix * vCoord;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/rendernode.frag b/src/quick/scenegraph/shaders/rendernode.frag
new file mode 100644
index 0000000000000000000000000000000000000000..b4e9b0209cb6492dcb5ac1478eb7ddad9f28b207
--- /dev/null
+++ b/src/quick/scenegraph/shaders/rendernode.frag
@@ -0,0 +1,8 @@
+uniform lowp sampler2D tex;
+
+varying highp vec2 t;
+
+void main()
+{
+    gl_FragColor = texture2D(tex, t);
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/rendernode.vert b/src/quick/scenegraph/shaders/rendernode.vert
new file mode 100644
index 0000000000000000000000000000000000000000..fbfe9ef8ae50ce60b1d78c57098f7c8868044277
--- /dev/null
+++ b/src/quick/scenegraph/shaders/rendernode.vert
@@ -0,0 +1,10 @@
+attribute highp vec4 av;
+attribute highp vec2 at;
+
+varying highp vec2 t;
+
+void main()
+{
+    gl_Position = av;
+    t = at;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/smoothcolor.frag b/src/quick/scenegraph/shaders/smoothcolor.frag
new file mode 100644
index 0000000000000000000000000000000000000000..71de9dbfc275e316b38fdf155184f34a07190406
--- /dev/null
+++ b/src/quick/scenegraph/shaders/smoothcolor.frag
@@ -0,0 +1,6 @@
+varying lowp vec4 color;
+
+void main()
+{
+    gl_FragColor = color;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/smoothcolor.vert b/src/quick/scenegraph/shaders/smoothcolor.vert
new file mode 100644
index 0000000000000000000000000000000000000000..df70fea92a4630ebfc72e530b8bf89d2174d3518
--- /dev/null
+++ b/src/quick/scenegraph/shaders/smoothcolor.vert
@@ -0,0 +1,45 @@
+uniform highp vec2 pixelSize;
+uniform highp mat4 matrix;
+uniform lowp float opacity;
+
+attribute highp vec4 vertex;
+attribute lowp vec4 vertexColor;
+attribute highp vec2 vertexOffset;
+
+varying lowp vec4 color;
+
+void main()
+{
+    highp vec4 pos = matrix * vertex;
+    gl_Position = pos;
+
+    if (vertexOffset.x != 0.) {
+        highp vec4 delta = matrix[0] * vertexOffset.x;
+        highp vec2 dir = delta.xy * pos.w - pos.xy * delta.w;
+        highp vec2 ndir = .5 * pixelSize * normalize(dir / pixelSize);
+        dir -= ndir * delta.w * pos.w;
+        highp float numerator = dot(dir, ndir * pos.w * pos.w);
+        highp float scale = 0.0;
+        if (numerator < 0.0)
+            scale = 1.0;
+        else
+            scale = min(1.0, numerator / dot(dir, dir));
+        gl_Position += scale * delta;
+    }
+
+    if (vertexOffset.y != 0.) {
+        highp vec4 delta = matrix[1] * vertexOffset.y;
+        highp vec2 dir = delta.xy * pos.w - pos.xy * delta.w;
+        highp vec2 ndir = .5 * pixelSize * normalize(dir / pixelSize);
+        dir -= ndir * delta.w * pos.w;
+        highp float numerator = dot(dir, ndir * pos.w * pos.w);
+        highp float scale = 0.0;
+        if (numerator < 0.0)
+            scale = 1.0;
+        else
+            scale = min(1.0, numerator / dot(dir, dir));
+        gl_Position += scale * delta;
+    }
+
+    color = vertexColor * opacity;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/smoothtexture.frag b/src/quick/scenegraph/shaders/smoothtexture.frag
new file mode 100644
index 0000000000000000000000000000000000000000..e4f6359f3d6093fe324fffb4013af957fb960278
--- /dev/null
+++ b/src/quick/scenegraph/shaders/smoothtexture.frag
@@ -0,0 +1,9 @@
+uniform sampler2D qt_Texture;
+
+varying highp vec2 texCoord;
+varying lowp float vertexOpacity;
+
+void main()
+{
+    gl_FragColor = texture2D(qt_Texture, texCoord) * vertexOpacity;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/smoothtexture.vert b/src/quick/scenegraph/shaders/smoothtexture.vert
new file mode 100644
index 0000000000000000000000000000000000000000..1ce824a68fce2cd30cde85f2fcd600bcb94f7d87
--- /dev/null
+++ b/src/quick/scenegraph/shaders/smoothtexture.vert
@@ -0,0 +1,52 @@
+uniform highp vec2 pixelSize;
+uniform highp mat4 qt_Matrix;
+uniform lowp float opacity;
+
+attribute highp vec4 vertex;
+attribute highp vec2 multiTexCoord;
+attribute highp vec2 vertexOffset;
+attribute highp vec2 texCoordOffset;
+
+varying highp vec2 texCoord;
+varying lowp float vertexOpacity;
+
+void main()
+{
+    highp vec4 pos = qt_Matrix * vertex;
+    gl_Position = pos;
+    texCoord = multiTexCoord;
+
+    if (vertexOffset.x != 0.) {
+        highp vec4 delta = qt_Matrix[0] * vertexOffset.x;
+        highp vec2 dir = delta.xy * pos.w - pos.xy * delta.w;
+        highp vec2 ndir = .5 * pixelSize * normalize(dir / pixelSize);
+        dir -= ndir * delta.w * pos.w;
+        highp float numerator = dot(dir, ndir * pos.w * pos.w);
+        highp float scale = 0.0;
+        if (numerator < 0.0)
+            scale = 1.0;
+        else
+            scale = min(1.0, numerator / dot(dir, dir));
+        gl_Position += scale * delta;
+        texCoord.x += scale * texCoordOffset.x;
+    }
+
+    if (vertexOffset.y != 0.) {
+        highp vec4 delta = qt_Matrix[1] * vertexOffset.y;
+        highp vec2 dir = delta.xy * pos.w - pos.xy * delta.w;
+        highp vec2 ndir = .5 * pixelSize * normalize(dir / pixelSize);
+        dir -= ndir * delta.w * pos.w;
+        highp float numerator = dot(dir, ndir * pos.w * pos.w);
+        highp float scale = 0.0;
+        if (numerator < 0.0)
+            scale = 1.0;
+        else
+            scale = min(1.0, numerator / dot(dir, dir));
+        gl_Position += scale * delta;
+        texCoord.y += scale * texCoordOffset.y;
+    }
+
+    bool onEdge = any(notEqual(vertexOffset, vec2(0.)));
+    bool outerEdge = all(equal(texCoordOffset, vec2(0.)));
+    vertexOpacity = onEdge && outerEdge ? 0. : opacity;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/stencilclip.frag b/src/quick/scenegraph/shaders/stencilclip.frag
new file mode 100644
index 0000000000000000000000000000000000000000..70b7717977377fed99453cc1df195b05a993a7d2
--- /dev/null
+++ b/src/quick/scenegraph/shaders/stencilclip.frag
@@ -0,0 +1,4 @@
+void main()
+{
+    gl_FragColor = vec4(0.81, 0.83, 0.12, 1.0); // Trolltech green ftw!
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/stencilclip.vert b/src/quick/scenegraph/shaders/stencilclip.vert
new file mode 100644
index 0000000000000000000000000000000000000000..0e546c81122df78a526e87efed8e32745fe865bf
--- /dev/null
+++ b/src/quick/scenegraph/shaders/stencilclip.vert
@@ -0,0 +1,8 @@
+attribute highp vec4 vCoord;
+
+uniform highp mat4 matrix;
+
+void main()
+{
+    gl_Position = matrix * vCoord;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/styledtext.frag b/src/quick/scenegraph/shaders/styledtext.frag
new file mode 100644
index 0000000000000000000000000000000000000000..662dbef2fc18fbe45c1d3e987c57b08876256c65
--- /dev/null
+++ b/src/quick/scenegraph/shaders/styledtext.frag
@@ -0,0 +1,14 @@
+varying highp vec2 sampleCoord;
+varying highp vec2 shiftedSampleCoord;
+
+uniform sampler2D _qt_texture;
+uniform lowp vec4 color;
+uniform lowp vec4 styleColor;
+
+void main()
+{
+    lowp float glyph = texture2D(_qt_texture, sampleCoord).a;
+    lowp float style = clamp(texture2D(_qt_texture, shiftedSampleCoord).a - glyph,
+                             0.0, 1.0);
+    gl_FragColor = style * styleColor + glyph * color;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/styledtext.vert b/src/quick/scenegraph/shaders/styledtext.vert
new file mode 100644
index 0000000000000000000000000000000000000000..3ad9497b65b8ffd8c734672ff26d4ea88ba4858b
--- /dev/null
+++ b/src/quick/scenegraph/shaders/styledtext.vert
@@ -0,0 +1,16 @@
+uniform highp mat4 matrix;
+uniform highp vec2 textureScale;
+uniform highp vec2 shift;
+
+attribute highp vec4 vCoord;
+attribute highp vec2 tCoord;
+
+varying highp vec2 sampleCoord;
+varying highp vec2 shiftedSampleCoord;
+
+void main()
+{
+     sampleCoord = tCoord * textureScale;
+     shiftedSampleCoord = (tCoord - shift) * textureScale;
+     gl_Position = matrix * vCoord;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/textmask.frag b/src/quick/scenegraph/shaders/textmask.frag
new file mode 100644
index 0000000000000000000000000000000000000000..7715688eccc52c874ddb4b54a38428229acddfe4
--- /dev/null
+++ b/src/quick/scenegraph/shaders/textmask.frag
@@ -0,0 +1,10 @@
+varying highp vec2 sampleCoord;
+
+uniform sampler2D _qt_texture;
+uniform lowp vec4 color;
+
+void main()
+{
+    lowp vec4 glyph = texture2D(_qt_texture, sampleCoord);
+    gl_FragColor = vec4(glyph.rgb * color.a, glyph.a);
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/textmask.vert b/src/quick/scenegraph/shaders/textmask.vert
new file mode 100644
index 0000000000000000000000000000000000000000..1f45e9cf713bf563fc3f3273b2cd4f8dc5cb3090
--- /dev/null
+++ b/src/quick/scenegraph/shaders/textmask.vert
@@ -0,0 +1,13 @@
+uniform highp mat4 matrix;
+uniform highp vec2 textureScale;
+
+attribute highp vec4 vCoord;
+attribute highp vec2 tCoord;
+
+varying highp vec2 sampleCoord;
+
+void main()
+{
+     sampleCoord = tCoord * textureScale;
+     gl_Position = matrix * vCoord;
+}
diff --git a/src/quick/scenegraph/shaders/texture.frag b/src/quick/scenegraph/shaders/texture.frag
new file mode 100644
index 0000000000000000000000000000000000000000..2d97f2e66ab8f1ea52f21f069cb3d4734987d94d
--- /dev/null
+++ b/src/quick/scenegraph/shaders/texture.frag
@@ -0,0 +1,9 @@
+varying highp vec2 qt_TexCoord;
+
+uniform sampler2D qt_Texture;
+uniform lowp float opacity;
+
+void main()
+{
+    gl_FragColor = texture2D(qt_Texture, qt_TexCoord) * opacity;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/vertexcolor.frag b/src/quick/scenegraph/shaders/vertexcolor.frag
new file mode 100644
index 0000000000000000000000000000000000000000..71de9dbfc275e316b38fdf155184f34a07190406
--- /dev/null
+++ b/src/quick/scenegraph/shaders/vertexcolor.frag
@@ -0,0 +1,6 @@
+varying lowp vec4 color;
+
+void main()
+{
+    gl_FragColor = color;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/vertexcolor.vert b/src/quick/scenegraph/shaders/vertexcolor.vert
new file mode 100644
index 0000000000000000000000000000000000000000..750d520114b92d5c16165dd8b1c1c980cbb52573
--- /dev/null
+++ b/src/quick/scenegraph/shaders/vertexcolor.vert
@@ -0,0 +1,13 @@
+attribute highp vec4 vertexCoord;
+attribute highp vec4 vertexColor;
+
+uniform highp mat4 matrix;
+uniform highp float opacity;
+
+varying lowp vec4 color;
+
+void main()
+{
+    gl_Position = matrix * vertexCoord;
+    color = vertexColor * opacity;
+}
\ No newline at end of file
diff --git a/src/quick/scenegraph/util/qsgflatcolormaterial.cpp b/src/quick/scenegraph/util/qsgflatcolormaterial.cpp
index 83264e2930c01e208e6af11062756b2b16b1f662..c603c62a2039f1eddfc3f1fd2cd47d0ab41be8dd 100644
--- a/src/quick/scenegraph/util/qsgflatcolormaterial.cpp
+++ b/src/quick/scenegraph/util/qsgflatcolormaterial.cpp
@@ -40,6 +40,7 @@
 ****************************************************************************/
 
 #include "qsgflatcolormaterial.h"
+#include <private/qsgmaterialshader_p.h>
 
 #include <qopenglshaderprogram.h>
 
@@ -48,6 +49,8 @@ QT_BEGIN_NAMESPACE
 class FlatColorMaterialShader : public QSGMaterialShader
 {
 public:
+    FlatColorMaterialShader();
+
     virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
     virtual char const *const *attributeNames() const;
 
@@ -55,8 +58,6 @@ public:
 
 private:
     virtual void initialize();
-    virtual const char *vertexShader() const;
-    virtual const char *fragmentShader() const;
 
     int m_matrix_id;
     int m_color_id;
@@ -64,6 +65,13 @@ private:
 
 QSGMaterialType FlatColorMaterialShader::type;
 
+FlatColorMaterialShader::FlatColorMaterialShader()
+    : QSGMaterialShader(*new QSGMaterialShaderPrivate)
+{
+    setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/flatcolor.vert"));
+    setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/flatcolor.frag"));
+}
+
 void FlatColorMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
 {
     Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());
@@ -98,23 +106,6 @@ void FlatColorMaterialShader::initialize()
     m_color_id = program()->uniformLocation("color");
 }
 
-const char *FlatColorMaterialShader::vertexShader() const {
-    return
-        "attribute highp vec4 vCoord;                   \n"
-        "uniform highp mat4 matrix;                     \n"
-        "void main() {                                  \n"
-        "    gl_Position = matrix * vCoord;             \n"
-        "}";
-}
-
-const char *FlatColorMaterialShader::fragmentShader() const {
-    return
-        "uniform lowp vec4 color;                       \n"
-        "void main() {                                  \n"
-        "    gl_FragColor = color;                      \n"
-        "}";
-}
-
 
 
 /*!
diff --git a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c7dd1a97998aa428db93ffc1f553d9b6cfb5f14b
--- /dev/null
+++ b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsgshadersourcebuilder_p.h"
+
+#include <QtGui/qopenglshaderprogram.h>
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qfile.h>
+
+QT_BEGIN_NAMESPACE
+
+QSGShaderSourceBuilder::QSGShaderSourceBuilder()
+{
+}
+
+void QSGShaderSourceBuilder::initializeProgramFromFiles(QOpenGLShaderProgram *program,
+                                                        const QString &vertexShader,
+                                                        const QString &fragmentShader)
+{
+    Q_ASSERT(program);
+    program->removeAllShaders();
+
+    QSGShaderSourceBuilder builder;
+
+    builder.appendSourceFile(vertexShader);
+    program->addShaderFromSourceCode(QOpenGLShader::Vertex, builder.source());
+    builder.clear();
+
+    builder.appendSourceFile(fragmentShader);
+    program->addShaderFromSourceCode(QOpenGLShader::Fragment, builder.source());
+}
+
+QByteArray QSGShaderSourceBuilder::source() const
+{
+    return m_source;
+}
+
+void QSGShaderSourceBuilder::clear()
+{
+    m_source.clear();
+}
+
+void QSGShaderSourceBuilder::appendSource(const QByteArray &source)
+{
+    m_source += source;
+}
+
+void QSGShaderSourceBuilder::appendSourceFile(const QString &fileName)
+{
+    const QString resolvedFileName = resolveShaderPath(fileName);
+    QFile f(fileName);
+    if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
+        qWarning() << "Failed to find shader" << resolvedFileName;
+        return;
+    }
+    m_source += f.readAll();
+}
+
+QString QSGShaderSourceBuilder::resolveShaderPath(const QString &path) const
+{
+    // For now, just return the path unaltered.
+    // TODO: Resolve to more specific filename based upon OpenGL profile and
+    // version, platform, GPU type etc
+    return path;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgshadersourcebuilder_p.h b/src/quick/scenegraph/util/qsgshadersourcebuilder_p.h
new file mode 100644
index 0000000000000000000000000000000000000000..8def250d4f51ea11101c5ab8206ddccfea814f6f
--- /dev/null
+++ b/src/quick/scenegraph/util/qsgshadersourcebuilder_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSGSHADERSOURCEBUILDER_P_H
+#define QSGSHADERSOURCEBUILDER_P_H
+
+#include <private/qtquickglobal_p.h>
+
+#include <QtCore/qbytearray.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLShaderProgram;
+
+class Q_QUICK_PRIVATE_EXPORT QSGShaderSourceBuilder
+{
+public:
+    QSGShaderSourceBuilder();
+
+    static void initializeProgramFromFiles(QOpenGLShaderProgram *program,
+                                           const QString &vertexShader,
+                                           const QString &fragmentShader);
+
+    QByteArray source() const;
+    void clear();
+
+    void appendSource(const QByteArray &source);
+    void appendSourceFile(const QString &fileName);
+
+protected:
+    virtual QString resolveShaderPath(const QString &path) const;
+
+private:
+    QByteArray m_source;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGSHADERSOURCEBUILDER_P_H
diff --git a/src/quick/scenegraph/util/qsgtexturematerial.cpp b/src/quick/scenegraph/util/qsgtexturematerial.cpp
index ba98c836823cf31bb302141482512cf820e01987..df55404504a6a6ec8ff143f15847ba1a5f1c5d3d 100644
--- a/src/quick/scenegraph/util/qsgtexturematerial.cpp
+++ b/src/quick/scenegraph/util/qsgtexturematerial.cpp
@@ -54,36 +54,15 @@ inline static bool isPowerOfTwo(int x)
 }
 #endif
 
-const char qt_scenegraph_texture_material_vertex_code[] =
-    "uniform highp mat4 qt_Matrix;                      \n"
-    "attribute highp vec4 qt_VertexPosition;            \n"
-    "attribute highp vec2 qt_VertexTexCoord;            \n"
-    "varying highp vec2 qt_TexCoord;                    \n"
-    "void main() {                                      \n"
-    "    qt_TexCoord = qt_VertexTexCoord;               \n"
-    "    gl_Position = qt_Matrix * qt_VertexPosition;   \n"
-    "}";
-
-const char qt_scenegraph_texture_material_fragment[] =
-    "varying highp vec2 qt_TexCoord;                    \n"
-    "uniform sampler2D qt_Texture;                      \n"
-    "void main() {                                      \n"
-    "    gl_FragColor = texture2D(qt_Texture, qt_TexCoord);\n"
-    "}";
-
-
-const char *QSGOpaqueTextureMaterialShader::vertexShader() const
-{
-    return qt_scenegraph_texture_material_vertex_code;
-}
+QSGMaterialType QSGOpaqueTextureMaterialShader::type;
 
-const char *QSGOpaqueTextureMaterialShader::fragmentShader() const
+QSGOpaqueTextureMaterialShader::QSGOpaqueTextureMaterialShader()
+    : QSGMaterialShader()
 {
-    return qt_scenegraph_texture_material_fragment;
+    setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/opaquetexture.vert"));
+    setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/opaquetexture.frag"));
 }
 
-QSGMaterialType QSGOpaqueTextureMaterialShader::type;
-
 char const *const *QSGOpaqueTextureMaterialShader::attributeNames() const
 {
     static char const *const attr[] = { "qt_VertexPosition", "qt_VertexTexCoord", 0 };
@@ -353,14 +332,6 @@ int QSGOpaqueTextureMaterial::compare(const QSGMaterial *o) const
     a material in the scene graph.
  */
 
-static const char qt_scenegraph_texture_material_opacity_fragment[] =
-    "varying highp vec2 qt_TexCoord;                       \n"
-    "uniform sampler2D qt_Texture;                         \n"
-    "uniform lowp float opacity;                        \n"
-    "void main() {                                      \n"
-    "    gl_FragColor = texture2D(qt_Texture, qt_TexCoord) * opacity; \n"
-    "}";
-
 QSGMaterialType QSGTextureMaterialShader::type;
 
 
@@ -385,6 +356,12 @@ QSGMaterialShader *QSGTextureMaterial::createShader() const
     return new QSGTextureMaterialShader;
 }
 
+QSGTextureMaterialShader::QSGTextureMaterialShader()
+    : QSGOpaqueTextureMaterialShader()
+{
+    setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/texture.frag"));
+}
+
 void QSGTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
 {
     Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());
@@ -400,9 +377,4 @@ void QSGTextureMaterialShader::initialize()
     m_opacity_id = program()->uniformLocation("opacity");
 }
 
-const char *QSGTextureMaterialShader::fragmentShader() const
-{
-    return qt_scenegraph_texture_material_opacity_fragment;
-}
-
 QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgtexturematerial_p.h b/src/quick/scenegraph/util/qsgtexturematerial_p.h
index 077337d21195725ad868e8ad6204f60c87fbf6a2..db65d8573860d798a88c15a0b918f4c13d2b2fae 100644
--- a/src/quick/scenegraph/util/qsgtexturematerial_p.h
+++ b/src/quick/scenegraph/util/qsgtexturematerial_p.h
@@ -50,6 +50,8 @@ QT_BEGIN_NAMESPACE
 class Q_QUICK_PRIVATE_EXPORT QSGOpaqueTextureMaterialShader : public QSGMaterialShader
 {
 public:
+    QSGOpaqueTextureMaterialShader();
+
     virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
     virtual char const *const *attributeNames() const;
 
@@ -57,8 +59,6 @@ public:
 
 protected:
     virtual void initialize();
-    virtual const char *vertexShader() const;
-    virtual const char *fragmentShader() const;
 
     int m_matrix_id;
 };
@@ -66,14 +66,14 @@ protected:
 class QSGTextureMaterialShader : public QSGOpaqueTextureMaterialShader
 {
 public:
+    QSGTextureMaterialShader();
+
     virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
     virtual void initialize();
 
     static QSGMaterialType type;
 
 protected:
-    virtual const char *fragmentShader() const;
-
     int m_opacity_id;
 };
 
diff --git a/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp b/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp
index f205f34ce4f73ea44a9bd04f8aa1e93a447a0fd7..ef2455f702963beac6a60fe42e0d89e5dc324b3d 100644
--- a/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp
+++ b/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp
@@ -48,6 +48,8 @@ QT_BEGIN_NAMESPACE
 class QSGVertexColorMaterialShader : public QSGMaterialShader
 {
 public:
+    QSGVertexColorMaterialShader();
+
     virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
     virtual char const *const *attributeNames() const;
 
@@ -55,8 +57,6 @@ public:
 
 private:
     virtual void initialize();
-    virtual const char *vertexShader() const;
-    virtual const char *fragmentShader() const;
 
     int m_matrix_id;
     int m_opacity_id;
@@ -64,6 +64,13 @@ private:
 
 QSGMaterialType QSGVertexColorMaterialShader::type;
 
+QSGVertexColorMaterialShader::QSGVertexColorMaterialShader()
+    : QSGMaterialShader()
+{
+    setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/vertexcolor.vert"));
+    setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/vertexcolor.frag"));
+}
+
 void QSGVertexColorMaterialShader::updateState(const RenderState &state, QSGMaterial * /*newEffect*/, QSGMaterial *)
 {
     if (state.isOpacityDirty())
@@ -85,28 +92,6 @@ void QSGVertexColorMaterialShader::initialize()
     m_opacity_id = program()->uniformLocation("opacity");
 }
 
-const char *QSGVertexColorMaterialShader::vertexShader() const {
-    return
-        "attribute highp vec4 vertexCoord;              \n"
-        "attribute highp vec4 vertexColor;              \n"
-        "uniform highp mat4 matrix;                     \n"
-        "uniform highp float opacity;                   \n"
-        "varying lowp vec4 color;                       \n"
-        "void main() {                                  \n"
-        "    gl_Position = matrix * vertexCoord;        \n"
-        "    color = vertexColor * opacity;             \n"
-        "}";
-}
-
-const char *QSGVertexColorMaterialShader::fragmentShader() const {
-    return
-        "varying lowp vec4 color;                       \n"
-        "void main() {                                  \n"
-        "    gl_FragColor = color;                      \n"
-        "}";
-}
-
-
 
 /*!
     \class QSGVertexColorMaterial