diff --git a/CMakeLists.txt b/CMakeLists.txt
index bbec4a0884..25fd4731e6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,6 +13,11 @@ include("cmake/init.cmake")
 
 include("cmake/compiler.cmake")
 
+if (BUILD_SCRIBE_ONLY)
+    add_subdirectory(tools/scribe)
+    return()
+endif()
+
 if (NOT DEFINED SERVER_ONLY)
   set(SERVER_ONLY 0)
 endif()
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 300dc80269..a2f008beef 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -18,7 +18,7 @@ android {
                     '-DANDROID_TOOLCHAIN=clang',
                     '-DANDROID_STL=c++_shared',
                     '-DQT_CMAKE_PREFIX_PATH=' + HIFI_ANDROID_PRECOMPILED + '/qt/lib/cmake',
-                    '-DNATIVE_SCRIBE=' + HIFI_ANDROID_PRECOMPILED + '/scribe',
+                    '-DNATIVE_SCRIBE=' + HIFI_ANDROID_PRECOMPILED + '/scribe' + EXEC_SUFFIX,
                     '-DHIFI_ANDROID_PRECOMPILED=' + HIFI_ANDROID_PRECOMPILED,
                     '-DRELEASE_NUMBER=' + RELEASE_NUMBER,
                     '-DRELEASE_TYPE=' + RELEASE_TYPE,
diff --git a/android/build.gradle b/android/build.gradle
index 006318a576..764b337cba 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -144,16 +144,16 @@ def packages = [
 def scribeLocalFile='scribe' + EXEC_SUFFIX
 
 def scribeFile='scribe_linux_x86_64'
-def scribeChecksum='c98678d9726bd8bbf1bab792acf3ff6c'
-def scribeVersion='onfeBkJWcJiTwiGOyZPVBjlyhoYQ4Axn'
+def scribeChecksum='ca4b904f52f4f993c29175ba96798fa6'
+def scribeVersion='wgpf4dB2Ltzg4Lb2jJ4nPFsHoDkmK_OO'
 if (Os.isFamily(Os.FAMILY_MAC)) {
     scribeFile = 'scribe_osx_x86_64'
-    scribeChecksum='a137ad62c1bf7cca739da219544a9a16'
-    scribeVersion='kU.Aq512HVe65uRnkFEWQEqeQfaYF2c0'
+    scribeChecksum='72db9d32d4e1e50add755570ac5eb749'
+    scribeVersion='o_NbPrktzEYtBkQf3Tn7zc1nZWzM52w6'
 } else if (Os.isFamily(Os.FAMILY_WINDOWS)) {
     scribeFile = 'scribe_win32_x86_64.exe'
-    scribeChecksum='75c2ce9ed45d17de375e3988bfaba816'
-    scribeVersion='24TfWFh1FBY.t6i_LdzAXZYeQOtmQNZp'
+    scribeChecksum='678e43d290c90fda670c6fefe038a06d'
+    scribeVersion='GCCJxlmd2irvNOFWfZR0U1UCLHndHQrC'
 }
 
 def options = [
diff --git a/cmake/macros/AutoScribeShader.cmake b/cmake/macros/AutoScribeShader.cmake
index 1919ecf00a..c4cd2d186a 100755
--- a/cmake/macros/AutoScribeShader.cmake
+++ b/cmake/macros/AutoScribeShader.cmake
@@ -39,56 +39,41 @@ function(AUTOSCRIBE_SHADER SHADER_FILE)
   get_filename_component(SHADER_TARGET ${SHADER_FILE} NAME_WE)
   get_filename_component(SHADER_EXT ${SHADER_FILE} EXT)
   if(SHADER_EXT STREQUAL .slv)
-    set(SHADER_TARGET ${SHADER_TARGET}_vert.h)
+    set(SHADER_TYPE vert)
   elseif(${SHADER_EXT} STREQUAL .slf)
-    set(SHADER_TARGET ${SHADER_TARGET}_frag.h)
+    set(SHADER_TYPE frag)
   elseif(${SHADER_EXT} STREQUAL .slg)
-    set(SHADER_TARGET ${SHADER_TARGET}_geom.h)
+    set(SHADER_TYPE geom)
   endif()
+  set(SHADER_TARGET ${SHADER_TARGET}_${SHADER_TYPE})
 
   set(SHADER_TARGET "${SHADERS_DIR}/${SHADER_TARGET}")
+  set(SHADER_TARGET_HEADER ${SHADER_TARGET}.h)
+  set(SHADER_TARGET_SOURCE ${SHADER_TARGET}.cpp)
+  set(SCRIBE_COMMAND scribe)
 
   # Target dependant Custom rule on the SHADER_FILE
   if (APPLE)
     set(GLPROFILE MAC_GL)
-    set(SCRIBE_ARGS -c++ -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
-
-    add_custom_command(OUTPUT ${SHADER_TARGET} COMMAND scribe ${SCRIBE_ARGS} DEPENDS scribe ${SHADER_INCLUDE_FILES} ${SHADER_FILE})
   elseif (ANDROID)
     set(GLPROFILE LINUX_GL)
-    set(SCRIBE_ARGS -c++ -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
-
-    # for an android build, we can't use the scribe that cmake would normally produce as a target,
-    # since it's unrunnable by the cross-compiling build machine
-
-    # so, we require the compiling user to point us at a compiled executable version for their native toolchain
-    if (NOT NATIVE_SCRIBE)
-        find_program(NATIVE_SCRIBE scribe PATHS ${SCRIBE_PATH} ENV SCRIBE_PATH)
-    endif()
-
-    if (NOT NATIVE_SCRIBE)
-      message(FATAL_ERROR "The High Fidelity scribe tool is required for shader pre-processing. \
-        Please compile scribe using your native toolchain and set SCRIBE_PATH to the path containing the scribe executable in your ENV.\
-      ")
-    endif ()
-
-    add_custom_command(OUTPUT ${SHADER_TARGET} COMMAND ${NATIVE_SCRIBE} ${SCRIBE_ARGS} DEPENDS ${SHADER_INCLUDE_FILES} ${SHADER_FILE})
+    set(SCRIBE_COMMAND ${NATIVE_SCRIBE})
   elseif (UNIX)
     set(GLPROFILE LINUX_GL)
-    set(SCRIBE_ARGS -c++ -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
-
-    add_custom_command(OUTPUT ${SHADER_TARGET} COMMAND scribe ${SCRIBE_ARGS} DEPENDS scribe ${SHADER_INCLUDE_FILES} ${SHADER_FILE})
   else ()
     set(GLPROFILE PC_GL)
-    set(SCRIBE_ARGS -c++ -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
-
-    add_custom_command(OUTPUT ${SHADER_TARGET} COMMAND scribe ${SCRIBE_ARGS} DEPENDS scribe ${SHADER_INCLUDE_FILES} ${SHADER_FILE})
   endif()
+  set(SCRIBE_ARGS -c++ -T ${SHADER_TYPE} -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
+  add_custom_command(
+    OUTPUT ${SHADER_TARGET_HEADER} ${SHADER_TARGET_SOURCE} 
+    COMMAND ${SCRIBE_COMMAND} ${SCRIBE_ARGS} 
+    DEPENDS ${SCRIBE_COMMAND} ${SHADER_INCLUDE_FILES} ${SHADER_FILE}
+  )
 
   #output the generated file name
-  set(AUTOSCRIBE_SHADER_RETURN ${SHADER_TARGET} PARENT_SCOPE)
+  set(AUTOSCRIBE_SHADER_RETURN ${SHADER_TARGET_HEADER} ${SHADER_TARGET_SOURCE} PARENT_SCOPE)
 
-  file(GLOB INCLUDE_FILES ${SHADER_TARGET})
+  file(GLOB INCLUDE_FILES ${SHADER_TARGET_HEADER})
 
 endfunction()
 
@@ -126,7 +111,7 @@ macro(AUTOSCRIBE_SHADER_LIB)
   if (WIN32)
     source_group("Shaders" FILES ${SHADER_INCLUDE_FILES})
     source_group("Shaders" FILES ${SHADER_SOURCE_FILES})
-    source_group("Shaders" FILES ${AUTOSCRIBE_SHADER_SRC})
+    source_group("Shaders\\generated" FILES ${AUTOSCRIBE_SHADER_SRC})
   endif()
 
   list(APPEND AUTOSCRIBE_SHADER_LIB_SRC ${SHADER_INCLUDE_FILES})
@@ -136,4 +121,7 @@ macro(AUTOSCRIBE_SHADER_LIB)
   # Link library shaders, if they exist
   include_directories("${SHADERS_DIR}")
 
+  # Add search directory to find gpu/Shader.h
+  include_directories("${HIFI_LIBRARY_DIR}/gpu/src")
+
 endmacro()
diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp
index 90bb83a663..ce38b5ae00 100644
--- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp
+++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp
@@ -395,8 +395,8 @@ void HmdDisplayPlugin::HUDRenderer::build() {
 
 void HmdDisplayPlugin::HUDRenderer::updatePipeline() {
     if (!pipeline) {
-        auto vs = gpu::Shader::createVertex(std::string(hmd_ui_vert));
-        auto ps = gpu::Shader::createPixel(std::string(hmd_ui_frag));
+        auto vs = hmd_ui_vert::getShader();
+        auto ps = hmd_ui_frag::getShader();
         auto program = gpu::Shader::createProgram(vs, ps);
         gpu::gl::GLBackend::makeProgram(*program, gpu::Shader::BindingSet());
         uniformsLocation = program->getUniformBuffers().findLocation("hudBuffer");
diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp
index 2059487426..bca339dd18 100644
--- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp
+++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp
@@ -36,8 +36,8 @@ static ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, co
             gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
         PrepareStencil::testMask(*state);
 
-        auto vertShader = gpu::Shader::createVertex(std::string(textured_particle_vert));
-        auto fragShader = gpu::Shader::createPixel(std::string(textured_particle_frag));
+        auto vertShader = textured_particle_vert::getShader();
+        auto fragShader = textured_particle_frag::getShader();
 
         auto program = gpu::Shader::createProgram(vertShader, fragShader);
         _texturedPipeline = texturedPipeline = gpu::Pipeline::create(program, state);
diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp
index 4d223669b4..d1881f3e2a 100644
--- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp
+++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp
@@ -48,8 +48,8 @@ struct PolyLineUniforms {
 
 static render::ShapePipelinePointer shapePipelineFactory(const render::ShapePlumber& plumber, const render::ShapeKey& key, gpu::Batch& batch) {
     if (!polylinePipeline) {
-        auto VS = gpu::Shader::createVertex(std::string(paintStroke_vert));
-        auto PS = gpu::Shader::createPixel(std::string(paintStroke_frag));
+        auto VS = paintStroke_vert::getShader();
+        auto PS = paintStroke_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(VS, PS);
 #ifdef POLYLINE_ENTITY_USE_FADE_EFFECT
         auto fadeVS = gpu::Shader::createVertex(std::string(paintStroke_fade_vert));
diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp
index aadd49fde8..019ef0e414 100644
--- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp
+++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp
@@ -27,6 +27,7 @@
 #include <StencilMaskPass.h>
 
 #include "EntityTreeRenderer.h"
+
 #include "polyvox_vert.h"
 #include "polyvox_frag.h"
 #include "polyvox_fade_vert.h"
@@ -70,6 +71,7 @@
 #include "StencilMaskPass.h"
 
 #include "EntityTreeRenderer.h"
+
 #include "polyvox_vert.h"
 #include "polyvox_frag.h"
 #include "polyvox_fade_vert.h"
@@ -1459,8 +1461,8 @@ static gpu::Stream::FormatPointer _vertexFormat;
 
 ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const ShapeKey& key, gpu::Batch& batch) {
     if (!_pipelines[0]) {
-        gpu::ShaderPointer vertexShaders[2] = { gpu::Shader::createVertex(std::string(polyvox_vert)), gpu::Shader::createVertex(std::string(polyvox_fade_vert)) };
-        gpu::ShaderPointer pixelShaders[2] = { gpu::Shader::createPixel(std::string(polyvox_frag)), gpu::Shader::createPixel(std::string(polyvox_fade_frag)) };
+        gpu::ShaderPointer vertexShaders[2] = { polyvox_vert::getShader(), polyvox_fade_vert::getShader() };
+        gpu::ShaderPointer pixelShaders[2] = { polyvox_frag::getShader(), polyvox_fade_frag::getShader() };
 
         gpu::Shader::BindingSet slotBindings;
         slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT));
diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp
index cdee2c5ec9..0c4f8cbd39 100644
--- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp
+++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp
@@ -16,8 +16,8 @@
 #include <GeometryCache.h>
 #include <PerfStat.h>
 
-#include <render-utils/simple_vert.h>
-#include <render-utils/simple_frag.h>
+#include "render-utils/simple_vert.h"
+#include "render-utils/simple_frag.h"
 
 //#define SHAPE_ENTITY_USE_FADE_EFFECT
 #ifdef SHAPE_ENTITY_USE_FADE_EFFECT
@@ -32,8 +32,8 @@ static const float SPHERE_ENTITY_SCALE = 0.5f;
 
 
 ShapeEntityRenderer::ShapeEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {
-    _procedural._vertexSource = simple_vert;
-    _procedural._fragmentSource = simple_frag;
+    _procedural._vertexSource = simple_vert::getSource();
+    _procedural._fragmentSource = simple_frag::getSource();
     _procedural._opaqueState->setCullMode(gpu::State::CULL_NONE);
     _procedural._opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL);
     PrepareStencil::testMaskDrawShape(*_procedural._opaqueState);
diff --git a/libraries/gpu/src/gpu/StandardShaderLib.cpp b/libraries/gpu/src/gpu/StandardShaderLib.cpp
index 0d8d131e0b..0d829fb21f 100755
--- a/libraries/gpu/src/gpu/StandardShaderLib.cpp
+++ b/libraries/gpu/src/gpu/StandardShaderLib.cpp
@@ -73,42 +73,42 @@ ShaderPointer StandardShaderLib::getProgram(GetShader getVS, GetShader getPS) {
 
 ShaderPointer StandardShaderLib::getDrawUnitQuadTexcoordVS() {
     if (!_drawUnitQuadTexcoordVS) {
-        _drawUnitQuadTexcoordVS = gpu::Shader::createVertex(std::string(DrawUnitQuadTexcoord_vert));
+        _drawUnitQuadTexcoordVS = DrawUnitQuadTexcoord_vert::getShader();
     }
     return _drawUnitQuadTexcoordVS;
 }
 
 ShaderPointer StandardShaderLib::getDrawTransformUnitQuadVS() {
     if (!_drawTransformUnitQuadVS) {
-        _drawTransformUnitQuadVS = gpu::Shader::createVertex(std::string(DrawTransformUnitQuad_vert));
+        _drawTransformUnitQuadVS = DrawTransformUnitQuad_vert::getShader();
     }
     return _drawTransformUnitQuadVS;
 }
 
 ShaderPointer StandardShaderLib::getDrawTexcoordRectTransformUnitQuadVS() {
     if (!_drawTexcoordRectTransformUnitQuadVS) {
-        _drawTexcoordRectTransformUnitQuadVS = gpu::Shader::createVertex(std::string(DrawTexcoordRectTransformUnitQuad_vert));
+        _drawTexcoordRectTransformUnitQuadVS = DrawTexcoordRectTransformUnitQuad_vert::getShader();
     }
     return _drawTexcoordRectTransformUnitQuadVS;
 }
 
 ShaderPointer StandardShaderLib::getDrawViewportQuadTransformTexcoordVS() {
     if (!_drawViewportQuadTransformTexcoordVS) {
-        _drawViewportQuadTransformTexcoordVS = gpu::Shader::createVertex(std::string(DrawViewportQuadTransformTexcoord_vert));
+        _drawViewportQuadTransformTexcoordVS = DrawViewportQuadTransformTexcoord_vert::getShader();
     }
     return _drawViewportQuadTransformTexcoordVS;
 }
 
 ShaderPointer StandardShaderLib::getDrawVertexPositionVS() {
     if (!_drawVertexPositionVS) {
-        _drawVertexPositionVS = gpu::Shader::createVertex(std::string(DrawVertexPosition_vert));
+        _drawVertexPositionVS = DrawVertexPosition_vert::getShader();
     }
     return _drawVertexPositionVS;
 }
 
 ShaderPointer StandardShaderLib::getDrawTransformVertexPositionVS() {
     if (!_drawTransformVertexPositionVS) {
-        _drawTransformVertexPositionVS = gpu::Shader::createVertex(std::string(DrawTransformVertexPosition_vert));
+        _drawTransformVertexPositionVS = DrawTransformVertexPosition_vert::getShader();
     }
     return _drawTransformVertexPositionVS;
 }
@@ -122,42 +122,42 @@ ShaderPointer StandardShaderLib::getDrawNadaPS() {
 
 ShaderPointer StandardShaderLib::getDrawWhitePS() {
     if (!_drawWhitePS) {
-        _drawWhitePS = gpu::Shader::createPixel(std::string(DrawWhite_frag));
+        _drawWhitePS = DrawWhite_frag::getShader();
     }
     return _drawWhitePS;
 }
 
 ShaderPointer StandardShaderLib::getDrawColorPS() {
     if (!_drawColorPS) {
-        _drawColorPS = gpu::Shader::createPixel(std::string(DrawColor_frag));
+        _drawColorPS = DrawColor_frag::getShader();
     }
     return _drawColorPS;
 }
 
 ShaderPointer StandardShaderLib::getDrawTexturePS() {
     if (!_drawTexturePS) {
-        _drawTexturePS = gpu::Shader::createPixel(std::string(DrawTexture_frag));
+        _drawTexturePS = DrawTexture_frag::getShader();
     }
     return _drawTexturePS;
 }
 
 ShaderPointer StandardShaderLib::getDrawTextureMirroredXPS() {
     if (!_drawTextureMirroredXPS) {
-        _drawTextureMirroredXPS = gpu::Shader::createPixel(std::string(DrawTextureMirroredX_frag));
+        _drawTextureMirroredXPS = DrawTextureMirroredX_frag::getShader();
     }
     return _drawTextureMirroredXPS;
 }
 
 ShaderPointer StandardShaderLib::getDrawTextureOpaquePS() {
     if (!_drawTextureOpaquePS) {
-        _drawTextureOpaquePS = gpu::Shader::createPixel(std::string(DrawTextureOpaque_frag));
+        _drawTextureOpaquePS = DrawTextureOpaque_frag::getShader();
     }
     return _drawTextureOpaquePS;
 }
 
 ShaderPointer StandardShaderLib::getDrawColoredTexturePS() {
     if (!_drawColoredTexturePS) {
-        _drawColoredTexturePS = gpu::Shader::createPixel(std::string(DrawColoredTexture_frag));
+        _drawColoredTexturePS = DrawColoredTexture_frag::getShader();
     }
     return _drawColoredTexturePS;
 }
diff --git a/libraries/graphics/src/graphics/Skybox.cpp b/libraries/graphics/src/graphics/Skybox.cpp
index e05a66104a..f4dd9ae052 100755
--- a/libraries/graphics/src/graphics/Skybox.cpp
+++ b/libraries/graphics/src/graphics/Skybox.cpp
@@ -85,8 +85,8 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky
     static std::once_flag once;
     std::call_once(once, [&] {
         {
-            auto skyVS = gpu::Shader::createVertex(std::string(skybox_vert));
-            auto skyFS = gpu::Shader::createPixel(std::string(skybox_frag));
+            auto skyVS = skybox_vert::getShader();
+            auto skyFS = skybox_frag::getShader();
             auto skyShader = gpu::Shader::createProgram(skyVS, skyFS);
 
             batch.runLambda([skyShader] {
diff --git a/libraries/procedural/src/procedural/Procedural.cpp b/libraries/procedural/src/procedural/Procedural.cpp
index 98721d9896..d8b72c8838 100644
--- a/libraries/procedural/src/procedural/Procedural.cpp
+++ b/libraries/procedural/src/procedural/Procedural.cpp
@@ -245,7 +245,7 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm
         std::string fragmentShaderSource = _fragmentSource;
         size_t replaceIndex = fragmentShaderSource.find(PROCEDURAL_COMMON_BLOCK);
         if (replaceIndex != std::string::npos) {
-            fragmentShaderSource.replace(replaceIndex, PROCEDURAL_COMMON_BLOCK.size(), ProceduralCommon_frag);
+            fragmentShaderSource.replace(replaceIndex, PROCEDURAL_COMMON_BLOCK.size(), ProceduralCommon_frag::getSource());
         }
 
         replaceIndex = fragmentShaderSource.find(PROCEDURAL_VERSION);
diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp
index f0c60e2101..43633e47ad 100644
--- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp
+++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp
@@ -19,8 +19,8 @@
 #include <graphics/skybox_frag.h>
 
 ProceduralSkybox::ProceduralSkybox() : graphics::Skybox() {
-    _procedural._vertexSource = skybox_vert;
-    _procedural._fragmentSource = skybox_frag;
+    _procedural._vertexSource = skybox_vert::getSource();
+    _procedural._fragmentSource = skybox_frag::getSource();
     // Adjust the pipeline state for background using the stencil test
     _procedural.setDoesFade(false);
     // Must match PrepareStencil::STENCIL_BACKGROUND
diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp
index 83753131c8..015f5678c8 100644
--- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp
+++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp
@@ -263,7 +263,7 @@ void AmbientOcclusionEffect::configure(const Config& config) {
 const gpu::PipelinePointer& AmbientOcclusionEffect::getOcclusionPipeline() {
     if (!_occlusionPipeline) {
         auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(ssao_makeOcclusion_frag));
+        auto ps = ssao_makeOcclusion_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -288,7 +288,7 @@ const gpu::PipelinePointer& AmbientOcclusionEffect::getOcclusionPipeline() {
 const gpu::PipelinePointer& AmbientOcclusionEffect::getHBlurPipeline() {
     if (!_hBlurPipeline) {
         auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(ssao_makeHorizontalBlur_frag));
+        auto ps = ssao_makeHorizontalBlur_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
         
         gpu::Shader::BindingSet slotBindings;
@@ -311,7 +311,7 @@ const gpu::PipelinePointer& AmbientOcclusionEffect::getHBlurPipeline() {
 const gpu::PipelinePointer& AmbientOcclusionEffect::getVBlurPipeline() {
     if (!_vBlurPipeline) {
         auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(ssao_makeVerticalBlur_frag));
+        auto ps = ssao_makeVerticalBlur_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
         
         gpu::Shader::BindingSet slotBindings;
@@ -458,7 +458,7 @@ void DebugAmbientOcclusion::configure(const Config& config) {
 const gpu::PipelinePointer& DebugAmbientOcclusion::getDebugPipeline() {
     if (!_debugPipeline) {
         auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(ssao_debugOcclusion_frag));
+        auto ps = ssao_debugOcclusion_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
diff --git a/libraries/render-utils/src/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp
index 9416d26762..69696deaf1 100644
--- a/libraries/render-utils/src/AnimDebugDraw.cpp
+++ b/libraries/render-utils/src/AnimDebugDraw.cpp
@@ -13,12 +13,12 @@
 #include <gpu/Batch.h>
 #include <GLMHelpers.h>
 
-#include "animdebugdraw_vert.h"
-#include "animdebugdraw_frag.h"
 #include "AbstractViewStateInterface.h"
 #include "RenderUtilsLogging.h"
 #include "DebugDraw.h"
 
+#include "animdebugdraw_vert.h"
+#include "animdebugdraw_frag.h"
 
 class AnimDebugDrawData {
 public:
@@ -102,8 +102,8 @@ AnimDebugDraw::AnimDebugDraw() :
     state->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD,
                             gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA,
                             gpu::State::BLEND_OP_ADD, gpu::State::ONE);
-    auto vertShader = gpu::Shader::createVertex(std::string(animdebugdraw_vert));
-    auto fragShader = gpu::Shader::createPixel(std::string(animdebugdraw_frag));
+    auto vertShader = animdebugdraw_vert::getShader();
+    auto fragShader = animdebugdraw_frag::getShader();
     auto program = gpu::Shader::createProgram(vertShader, fragShader);
     _pipeline = gpu::Pipeline::create(program, state);
 
diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp
index 70c2e3b5ce..bdd8f19a5c 100644
--- a/libraries/render-utils/src/AntialiasingEffect.cpp
+++ b/libraries/render-utils/src/AntialiasingEffect.cpp
@@ -57,8 +57,8 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline(RenderArgs* ar
     }
 
     if (!_antialiasingPipeline) {
-        auto vs = gpu::Shader::createVertex(std::string(fxaa_vert));
-        auto ps = gpu::Shader::createPixel(std::string(fxaa_frag));
+        auto vs = fxaa_vert::getShader();
+        auto ps = fxaa_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -82,8 +82,8 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline(RenderArgs* ar
 
 const gpu::PipelinePointer& Antialiasing::getBlendPipeline() {
     if (!_blendPipeline) {
-        auto vs = gpu::Shader::createVertex(std::string(fxaa_vert));
-        auto ps = gpu::Shader::createPixel(std::string(fxaa_blend_frag));
+        auto vs = fxaa_vert::getShader();
+        auto ps = fxaa_blend_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
diff --git a/libraries/render-utils/src/BloomEffect.cpp b/libraries/render-utils/src/BloomEffect.cpp
index 9d9367a6d5..89a83a651a 100644
--- a/libraries/render-utils/src/BloomEffect.cpp
+++ b/libraries/render-utils/src/BloomEffect.cpp
@@ -61,7 +61,7 @@ void BloomThreshold::run(const render::RenderContextPointer& renderContext, cons
 
     if (!_pipeline) {
         auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS();
-        auto ps = gpu::Shader::createPixel(std::string(BloomThreshold_frag));
+        auto ps = BloomThreshold_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -113,7 +113,7 @@ void BloomApply::run(const render::RenderContextPointer& renderContext, const In
 
     if (!_pipeline) {
         auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS();
-        auto ps = gpu::Shader::createPixel(std::string(BloomApply_frag));
+        auto ps = BloomApply_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
diff --git a/libraries/render-utils/src/DebugDeferredBuffer.cpp b/libraries/render-utils/src/DebugDeferredBuffer.cpp
index fe03ead4e1..24cffe2fb8 100644
--- a/libraries/render-utils/src/DebugDeferredBuffer.cpp
+++ b/libraries/render-utils/src/DebugDeferredBuffer.cpp
@@ -369,8 +369,7 @@ bool DebugDeferredBuffer::pipelineNeedsUpdate(Mode mode, std::string customFile)
 
 const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Mode mode, std::string customFile) {
     if (pipelineNeedsUpdate(mode, customFile)) {
-        static const std::string VERTEX_SHADER { debug_deferred_buffer_vert };
-        static const std::string FRAGMENT_SHADER { debug_deferred_buffer_frag };
+        static const std::string FRAGMENT_SHADER { debug_deferred_buffer_frag::getSource() };
         static const std::string SOURCE_PLACEHOLDER { "//SOURCE_PLACEHOLDER" };
         static const auto SOURCE_PLACEHOLDER_INDEX = FRAGMENT_SHADER.find(SOURCE_PLACEHOLDER);
         Q_ASSERT_X(SOURCE_PLACEHOLDER_INDEX != std::string::npos, Q_FUNC_INFO,
@@ -380,7 +379,7 @@ const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Mode mode, std::str
         bakedFragmentShader.replace(SOURCE_PLACEHOLDER_INDEX, SOURCE_PLACEHOLDER.size(),
                                     getShaderSourceCode(mode, customFile));
         
-        static const auto vs = gpu::Shader::createVertex(VERTEX_SHADER);
+        const auto vs = debug_deferred_buffer_vert::getShader();
         const auto ps = gpu::Shader::createPixel(bakedFragmentShader);
         const auto program = gpu::Shader::createProgram(vs, ps);
         
diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp
index d0d9708c04..14edab86c1 100644
--- a/libraries/render-utils/src/DeferredLightingEffect.cpp
+++ b/libraries/render-utils/src/DeferredLightingEffect.cpp
@@ -83,7 +83,7 @@ enum DeferredShader_BufferSlot {
     LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT,
 };
 
-static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations);
+static void loadLightProgram(const gpu::ShaderPointer& vertShader, const gpu::ShaderPointer& fragShader, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations);
 
 void DeferredLightingEffect::init() {
     _directionalAmbientSphereLightLocations = std::make_shared<LightLocations>();
@@ -95,14 +95,14 @@ void DeferredLightingEffect::init() {
     _localLightLocations = std::make_shared<LightLocations>();
     _localLightOutlineLocations = std::make_shared<LightLocations>();
 
-    loadLightProgram(deferred_light_vert, directional_ambient_light_frag, false, _directionalAmbientSphereLight, _directionalAmbientSphereLightLocations);
-    loadLightProgram(deferred_light_vert, directional_skybox_light_frag, false, _directionalSkyboxLight, _directionalSkyboxLightLocations);
+    loadLightProgram(deferred_light_vert::getShader(), directional_ambient_light_frag::getShader(), false, _directionalAmbientSphereLight, _directionalAmbientSphereLightLocations);
+    loadLightProgram(deferred_light_vert::getShader(), directional_skybox_light_frag::getShader(), false, _directionalSkyboxLight, _directionalSkyboxLightLocations);
 
-    loadLightProgram(deferred_light_vert, directional_ambient_light_shadow_frag, false, _directionalAmbientSphereLightShadow, _directionalAmbientSphereLightShadowLocations);
-    loadLightProgram(deferred_light_vert, directional_skybox_light_shadow_frag, false, _directionalSkyboxLightShadow, _directionalSkyboxLightShadowLocations);
+    loadLightProgram(deferred_light_vert::getShader(), directional_ambient_light_shadow_frag::getShader(), false, _directionalAmbientSphereLightShadow, _directionalAmbientSphereLightShadowLocations);
+    loadLightProgram(deferred_light_vert::getShader(), directional_skybox_light_shadow_frag::getShader(), false, _directionalSkyboxLightShadow, _directionalSkyboxLightShadowLocations);
 
-    loadLightProgram(deferred_light_vert, local_lights_shading_frag, true, _localLight, _localLightLocations);
-    loadLightProgram(deferred_light_vert, local_lights_drawOutline_frag, true, _localLightOutline, _localLightOutlineLocations);
+    loadLightProgram(deferred_light_vert::getShader(), local_lights_shading_frag::getShader(), true, _localLight, _localLightLocations);
+    loadLightProgram(deferred_light_vert::getShader(), local_lights_drawOutline_frag::getShader(), true, _localLightOutline, _localLightOutlineLocations);
 }
 
 void DeferredLightingEffect::setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit) {
@@ -171,12 +171,8 @@ void DeferredLightingEffect::unsetLocalLightsBatch(gpu::Batch& batch, int cluste
     }
 }
 
-static gpu::ShaderPointer makeLightProgram(const char* vertSource, const char* fragSource, LightLocationsPtr& locations) {
-    auto VS = gpu::Shader::createVertex(std::string(vertSource));
-    auto PS = gpu::Shader::createPixel(std::string(fragSource));
-    
-    gpu::ShaderPointer program = gpu::Shader::createProgram(VS, PS);
-
+static gpu::ShaderPointer makeLightProgram(const gpu::ShaderPointer& vertShader, const gpu::ShaderPointer& fragShader, LightLocationsPtr& locations) {
+    gpu::ShaderPointer program = gpu::Shader::createProgram(vertShader, fragShader);
     gpu::Shader::BindingSet slotBindings;
     slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), DEFERRED_BUFFER_COLOR_UNIT));
     slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), DEFERRED_BUFFER_NORMAL_UNIT));
@@ -224,9 +220,9 @@ static gpu::ShaderPointer makeLightProgram(const char* vertSource, const char* f
     return program;
 }
 
-static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& pipeline, LightLocationsPtr& locations) {
+static void loadLightProgram(const gpu::ShaderPointer& vertShader, const gpu::ShaderPointer& fragShader, bool lightVolume, gpu::PipelinePointer& pipeline, LightLocationsPtr& locations) {
 
-    gpu::ShaderPointer program = makeLightProgram(vertSource, fragSource, locations);
+    gpu::ShaderPointer program = makeLightProgram(vertShader, fragShader, locations);
 
     auto state = std::make_shared<gpu::State>();
     state->setColorWriteMask(true, true, true, false);
diff --git a/libraries/render-utils/src/DrawHaze.cpp b/libraries/render-utils/src/DrawHaze.cpp
index 8cb2d41723..c0db1597ca 100644
--- a/libraries/render-utils/src/DrawHaze.cpp
+++ b/libraries/render-utils/src/DrawHaze.cpp
@@ -133,7 +133,7 @@ void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inpu
     RenderArgs* args = renderContext->args;
 
     if (!_hazePipeline) {
-        gpu::ShaderPointer ps = gpu::Shader::createPixel(std::string(Haze_frag));
+        gpu::ShaderPointer ps = Haze_frag::getShader();
         gpu::ShaderPointer vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
 
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp
index 23473e74f2..a082a681c9 100644
--- a/libraries/render-utils/src/GeometryCache.cpp
+++ b/libraries/render-utils/src/GeometryCache.cpp
@@ -1946,8 +1946,8 @@ void GeometryCache::renderGlowLine(gpu::Batch& batch, const glm::vec3& p1, const
     static std::once_flag once;
     std::call_once(once, [&] {
         auto state = std::make_shared<gpu::State>();
-        auto VS = gpu::Shader::createVertex(std::string(glowLine_vert));
-        auto PS = gpu::Shader::createPixel(std::string(glowLine_frag));
+        auto VS = glowLine_vert::getShader();
+        auto PS = glowLine_frag::getShader();
         auto program = gpu::Shader::createProgram(VS, PS);
         state->setCullMode(gpu::State::CULL_NONE);
         state->setDepthTest(true, false, gpu::LESS_EQUAL);
@@ -2003,8 +2003,8 @@ void GeometryCache::renderGlowLine(gpu::Batch& batch, const glm::vec3& p1, const
 void GeometryCache::useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend) {
     static std::once_flag once;
     std::call_once(once, [&]() {
-        auto vs = gpu::Shader::createVertex(std::string(standardTransformPNTC_vert));
-        auto ps = gpu::Shader::createPixel(std::string(standardDrawTexture_frag));
+        auto vs = standardTransformPNTC_vert::getShader();
+        auto ps = standardDrawTexture_frag::getShader();
         auto program = gpu::Shader::createProgram(vs, ps);
 
         auto state = std::make_shared<gpu::State>();
@@ -2039,8 +2039,8 @@ void GeometryCache::useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend) {
 
 void GeometryCache::useGridPipeline(gpu::Batch& batch, GridBuffer gridBuffer, bool isLayered) {
     if (!_gridPipeline) {
-        auto vs = gpu::Shader::createVertex(std::string(standardTransformPNTC_vert));
-        auto ps = gpu::Shader::createPixel(std::string(grid_frag));
+        auto vs = standardTransformPNTC_vert::getShader();
+        auto ps = grid_frag::getShader();
         auto program = gpu::Shader::createProgram(vs, ps);
         gpu::Shader::makeProgram((*program));
         _gridSlot = program->getUniformBuffers().findLocation("gridBuffer");
@@ -2123,12 +2123,9 @@ inline bool operator==(const SimpleProgramKey& a, const SimpleProgramKey& b) {
     return a.getRaw() == b.getRaw();
 }
 
-static void buildWebShader(const std::string& vertShaderText, const std::string& fragShaderText, bool blendEnable,
+static void buildWebShader(const gpu::ShaderPointer& vertShader, const gpu::ShaderPointer& fragShader, bool blendEnable,
                            gpu::ShaderPointer& shaderPointerOut, gpu::PipelinePointer& pipelinePointerOut) {
-    auto VS = gpu::Shader::createVertex(vertShaderText);
-    auto PS = gpu::Shader::createPixel(fragShaderText);
-
-    shaderPointerOut = gpu::Shader::createProgram(VS, PS);
+    shaderPointerOut = gpu::Shader::createProgram(vertShader, fragShader);
 
     gpu::Shader::BindingSet slotBindings;
     gpu::Shader::makeProgram(*shaderPointerOut, slotBindings);
@@ -2151,8 +2148,8 @@ void GeometryCache::bindWebBrowserProgram(gpu::Batch& batch, bool transparent) {
 gpu::PipelinePointer GeometryCache::getWebBrowserProgram(bool transparent) {
     static std::once_flag once;
     std::call_once(once, [&]() {
-        buildWebShader(simple_vert, simple_opaque_web_browser_frag, false, _simpleOpaqueWebBrowserShader, _simpleOpaqueWebBrowserPipelineNoAA);
-        buildWebShader(simple_vert, simple_transparent_web_browser_frag, true, _simpleTransparentWebBrowserShader, _simpleTransparentWebBrowserPipelineNoAA);
+        buildWebShader(simple_vert::getShader(), simple_opaque_web_browser_frag::getShader(), false, _simpleOpaqueWebBrowserShader, _simpleOpaqueWebBrowserPipelineNoAA);
+        buildWebShader(simple_vert::getShader(), simple_transparent_web_browser_frag::getShader(), true, _simpleTransparentWebBrowserShader, _simpleTransparentWebBrowserPipelineNoAA);
     });
 
     return transparent ? _simpleTransparentWebBrowserPipelineNoAA : _simpleOpaqueWebBrowserPipelineNoAA;
@@ -2181,9 +2178,9 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp
     if (!fading) {
         static std::once_flag once;
         std::call_once(once, [&]() {
-            auto VS = gpu::Shader::createVertex(std::string(simple_vert));
-            auto PS = gpu::Shader::createPixel(std::string(simple_textured_frag));
-            auto PSUnlit = gpu::Shader::createPixel(std::string(simple_textured_unlit_frag));
+            auto VS = simple_vert::getShader();
+            auto PS = simple_textured_frag::getShader();
+            auto PSUnlit = simple_textured_unlit_frag::getShader();
 
             _simpleShader = gpu::Shader::createProgram(VS, PS);
             _unlitShader = gpu::Shader::createProgram(VS, PSUnlit);
@@ -2196,9 +2193,9 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp
     } else {
         static std::once_flag once;
         std::call_once(once, [&]() {
-            auto VS = gpu::Shader::createVertex(std::string(simple_fade_vert));
-            auto PS = gpu::Shader::createPixel(std::string(simple_textured_fade_frag));
-            auto PSUnlit = gpu::Shader::createPixel(std::string(simple_textured_unlit_fade_frag));
+            auto VS = simple_fade_vert::getShader();
+            auto PS = simple_textured_fade_frag::getShader();
+            auto PSUnlit = simple_textured_unlit_fade_frag::getShader();
 
             _simpleFadeShader = gpu::Shader::createProgram(VS, PS);
             _unlitFadeShader = gpu::Shader::createProgram(VS, PSUnlit);
diff --git a/libraries/render-utils/src/HighlightEffect.cpp b/libraries/render-utils/src/HighlightEffect.cpp
index fee1f4a568..9501a74d52 100644
--- a/libraries/render-utils/src/HighlightEffect.cpp
+++ b/libraries/render-utils/src/HighlightEffect.cpp
@@ -130,8 +130,8 @@ void DrawHighlightMask::run(const render::RenderContextPointer& renderContext, c
         fillState->setColorWriteMask(false, false, false, false);
         fillState->setCullMode(gpu::State::CULL_FRONT);
 
-        auto vs = gpu::Shader::createVertex(std::string(Highlight_aabox_vert));
-        auto ps = gpu::Shader::createPixel(std::string(nop_frag));
+        auto vs = Highlight_aabox_vert::getShader();
+        auto ps = nop_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -313,7 +313,7 @@ const gpu::PipelinePointer& DrawHighlight::getPipeline(const render::HighlightSt
         state->setStencilTest(true, 0, gpu::State::StencilTest(OUTLINE_STENCIL_MASK, 0xFF, gpu::EQUAL));
 
         auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(Highlight_frag));
+        auto ps = Highlight_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -325,7 +325,7 @@ const gpu::PipelinePointer& DrawHighlight::getPipeline(const render::HighlightSt
 
         _pipeline = gpu::Pipeline::create(program, state);
 
-        ps = gpu::Shader::createPixel(std::string(Highlight_filled_frag));
+        ps = Highlight_filled_frag::getShader();
         program = gpu::Shader::createProgram(vs, ps);
         gpu::Shader::makeProgram(*program, slotBindings);
         _pipelineFilled = gpu::Pipeline::create(program, state);
@@ -385,8 +385,7 @@ void DebugHighlight::run(const render::RenderContextPointer& renderContext, cons
 }
 
 void DebugHighlight::initializePipelines() {
-    static const std::string VERTEX_SHADER{ debug_deferred_buffer_vert };
-    static const std::string FRAGMENT_SHADER{ debug_deferred_buffer_frag };
+    static const std::string FRAGMENT_SHADER{ debug_deferred_buffer_frag::getSource() };
     static const std::string SOURCE_PLACEHOLDER{ "//SOURCE_PLACEHOLDER" };
     static const auto SOURCE_PLACEHOLDER_INDEX = FRAGMENT_SHADER.find(SOURCE_PLACEHOLDER);
     Q_ASSERT_X(SOURCE_PLACEHOLDER_INDEX != std::string::npos, Q_FUNC_INFO,
@@ -396,7 +395,7 @@ void DebugHighlight::initializePipelines() {
     state->setDepthTest(gpu::State::DepthTest(false, false));
     state->setStencilTest(true, 0, gpu::State::StencilTest(OUTLINE_STENCIL_MASK, 0xFF, gpu::EQUAL));
 
-    const auto vs = gpu::Shader::createVertex(VERTEX_SHADER);
+    const auto vs = debug_deferred_buffer_vert::getShader();
 
     // Depth shader
     {
@@ -553,14 +552,14 @@ const render::Varying DrawHighlightTask::addSelectItemJobs(JobModel& task, const
 #include "model_shadow_frag.h"
 
 void DrawHighlightTask::initMaskPipelines(render::ShapePlumber& shapePlumber, gpu::StatePointer state) {
-    auto modelVertex = gpu::Shader::createVertex(std::string(model_shadow_vert));
-    auto modelPixel = gpu::Shader::createPixel(std::string(model_shadow_frag));
+    auto modelVertex = model_shadow_vert::getShader();
+    auto modelPixel = model_shadow_frag::getShader();
     gpu::ShaderPointer modelProgram = gpu::Shader::createProgram(modelVertex, modelPixel);
     shapePlumber.addPipeline(
         ShapeKey::Filter::Builder().withoutSkinned(),
         modelProgram, state);
 
-    auto skinVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_vert));
+    auto skinVertex = skin_model_shadow_vert::getShader();
     gpu::ShaderPointer skinProgram = gpu::Shader::createProgram(skinVertex, modelPixel);
     shapePlumber.addPipeline(
         ShapeKey::Filter::Builder().withSkinned(),
diff --git a/libraries/render-utils/src/LightClusters.cpp b/libraries/render-utils/src/LightClusters.cpp
index d6ac7fd2e2..ea02edb601 100644
--- a/libraries/render-utils/src/LightClusters.cpp
+++ b/libraries/render-utils/src/LightClusters.cpp
@@ -605,8 +605,8 @@ void DebugLightClusters::configure(const Config& config) {
 
 const gpu::PipelinePointer DebugLightClusters::getDrawClusterGridPipeline() {
     if (!_drawClusterGrid) {
-        auto vs = gpu::Shader::createVertex(std::string(lightClusters_drawGrid_vert));
-        auto ps = gpu::Shader::createPixel(std::string(lightClusters_drawGrid_frag));
+        auto vs = lightClusters_drawGrid_vert::getShader();
+        auto ps = lightClusters_drawGrid_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -635,7 +635,7 @@ const gpu::PipelinePointer DebugLightClusters::getDrawClusterFromDepthPipeline()
     if (!_drawClusterFromDepth) {
        // auto vs = gpu::Shader::createVertex(std::string(lightClusters_drawGrid_vert));
         auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(lightClusters_drawClusterFromDepth_frag));
+        auto ps = lightClusters_drawClusterFromDepth_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -665,7 +665,7 @@ const gpu::PipelinePointer DebugLightClusters::getDrawClusterContentPipeline() {
     if (!_drawClusterContent) {
       //  auto vs = gpu::Shader::createVertex(std::string(lightClusters_drawClusterContent_vert));
         auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(lightClusters_drawClusterContent_frag));
+        auto ps = lightClusters_drawClusterContent_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp
index a73d7ff923..f9a2b613a3 100644
--- a/libraries/render-utils/src/RenderPipelines.cpp
+++ b/libraries/render-utils/src/RenderPipelines.cpp
@@ -121,16 +121,16 @@ void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderAr
 static bool forceLightBatchSetter{ false };
 
 void initOverlay3DPipelines(ShapePlumber& plumber, bool depthTest) {
-    auto vertex = gpu::Shader::createVertex(std::string(overlay3D_vert));
-    auto vertexModel = gpu::Shader::createVertex(std::string(model_vert));
-    auto pixel = gpu::Shader::createPixel(std::string(overlay3D_frag));
-    auto pixelTranslucent = gpu::Shader::createPixel(std::string(overlay3D_translucent_frag));
-    auto pixelUnlit = gpu::Shader::createPixel(std::string(overlay3D_unlit_frag));
-    auto pixelTranslucentUnlit = gpu::Shader::createPixel(std::string(overlay3D_translucent_unlit_frag));
-    auto pixelModel = gpu::Shader::createPixel(std::string(overlay3D_model_frag));
-    auto pixelModelTranslucent = gpu::Shader::createPixel(std::string(overlay3D_model_translucent_frag));
-    auto pixelModelUnlit = gpu::Shader::createPixel(std::string(overlay3D_model_unlit_frag));
-    auto pixelModelTranslucentUnlit = gpu::Shader::createPixel(std::string(overlay3D_model_translucent_unlit_frag));
+    auto vertex = overlay3D_vert::getShader();
+    auto vertexModel = model_vert::getShader();
+    auto pixel = overlay3D_frag::getShader();
+    auto pixelTranslucent = overlay3D_translucent_frag::getShader();
+    auto pixelUnlit = overlay3D_unlit_frag::getShader();
+    auto pixelTranslucentUnlit = overlay3D_translucent_unlit_frag::getShader();
+    auto pixelModel = overlay3D_model_frag::getShader();
+    auto pixelModelTranslucent = overlay3D_model_translucent_frag::getShader();
+    auto pixelModelUnlit = overlay3D_model_unlit_frag::getShader();
+    auto pixelModelTranslucentUnlit = overlay3D_model_translucent_unlit_frag::getShader();
 
     auto opaqueProgram = gpu::Shader::createProgram(vertex, pixel);
     auto translucentProgram = gpu::Shader::createProgram(vertex, pixelTranslucent);
@@ -187,64 +187,64 @@ void initOverlay3DPipelines(ShapePlumber& plumber, bool depthTest) {
 
 void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter) {
     // Vertex shaders
-    auto simpleVertex = gpu::Shader::createVertex(std::string(simple_vert));
-    auto modelVertex = gpu::Shader::createVertex(std::string(model_vert));
-    auto modelNormalMapVertex = gpu::Shader::createVertex(std::string(model_normal_map_vert));
-    auto modelLightmapVertex = gpu::Shader::createVertex(std::string(model_lightmap_vert));
-    auto modelLightmapNormalMapVertex = gpu::Shader::createVertex(std::string(model_lightmap_normal_map_vert));
-    auto modelTranslucentVertex = gpu::Shader::createVertex(std::string(model_translucent_vert));
-    auto modelTranslucentFadeVertex = gpu::Shader::createVertex(std::string(model_translucent_fade_vert));
-    auto modelShadowVertex = gpu::Shader::createVertex(std::string(model_shadow_vert));
-    auto skinModelVertex = gpu::Shader::createVertex(std::string(skin_model_vert));
-    auto skinModelNormalMapVertex = gpu::Shader::createVertex(std::string(skin_model_normal_map_vert));
-    auto skinModelShadowVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_vert));
-    auto modelLightmapFadeVertex = gpu::Shader::createVertex(std::string(model_lightmap_fade_vert));
-    auto modelLightmapNormalMapFadeVertex = gpu::Shader::createVertex(std::string(model_lightmap_normal_map_fade_vert));
-    auto skinModelFadeVertex = gpu::Shader::createVertex(std::string(skin_model_fade_vert));
-    auto skinModelNormalMapFadeVertex = gpu::Shader::createVertex(std::string(skin_model_normal_map_fade_vert));
+    auto simpleVertex = simple_vert::getShader();
+    auto modelVertex = model_vert::getShader();
+    auto modelNormalMapVertex = model_normal_map_vert::getShader();
+    auto modelLightmapVertex = model_lightmap_vert::getShader();
+    auto modelLightmapNormalMapVertex = model_lightmap_normal_map_vert::getShader();
+    auto modelTranslucentVertex = model_translucent_vert::getShader();
+    auto modelTranslucentFadeVertex = model_translucent_fade_vert::getShader();
+    auto modelShadowVertex = model_shadow_vert::getShader();
+    auto skinModelVertex = skin_model_vert::getShader();
+    auto skinModelNormalMapVertex = skin_model_normal_map_vert::getShader();
+    auto skinModelShadowVertex = skin_model_shadow_vert::getShader();
+    auto modelLightmapFadeVertex = model_lightmap_fade_vert::getShader();
+    auto modelLightmapNormalMapFadeVertex = model_lightmap_normal_map_fade_vert::getShader();
+    auto skinModelFadeVertex = skin_model_fade_vert::getShader();
+    auto skinModelNormalMapFadeVertex = skin_model_normal_map_fade_vert::getShader();
     auto skinModelTranslucentVertex = skinModelFadeVertex;  // We use the same because it ouputs world position per vertex
     auto skinModelNormalMapTranslucentVertex = skinModelNormalMapFadeVertex;  // We use the same because it ouputs world position per vertex
 
-    auto modelFadeVertex = gpu::Shader::createVertex(std::string(model_fade_vert));
-    auto modelNormalMapFadeVertex = gpu::Shader::createVertex(std::string(model_normal_map_fade_vert));
-    auto simpleFadeVertex = gpu::Shader::createVertex(std::string(simple_fade_vert));
-    auto modelShadowFadeVertex = gpu::Shader::createVertex(std::string(model_shadow_fade_vert));
-    auto skinModelShadowFadeVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_fade_vert));
+    auto modelFadeVertex = model_fade_vert::getShader();
+    auto modelNormalMapFadeVertex = model_normal_map_fade_vert::getShader();
+    auto simpleFadeVertex = simple_fade_vert::getShader();
+    auto modelShadowFadeVertex = model_shadow_fade_vert::getShader();
+    auto skinModelShadowFadeVertex = skin_model_shadow_fade_vert::getShader();
 
     // Pixel shaders
-    auto simplePixel = gpu::Shader::createPixel(std::string(simple_textured_frag));
-    auto simpleUnlitPixel = gpu::Shader::createPixel(std::string(simple_textured_unlit_frag));
-    auto simpleTranslucentPixel = gpu::Shader::createPixel(std::string(simple_transparent_textured_frag));
-    auto simpleTranslucentUnlitPixel = gpu::Shader::createPixel(std::string(simple_transparent_textured_unlit_frag));
-    auto modelPixel = gpu::Shader::createPixel(std::string(model_frag));
-    auto modelUnlitPixel = gpu::Shader::createPixel(std::string(model_unlit_frag));
-    auto modelNormalMapPixel = gpu::Shader::createPixel(std::string(model_normal_map_frag));
-    auto modelSpecularMapPixel = gpu::Shader::createPixel(std::string(model_specular_map_frag));
-    auto modelNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(model_normal_specular_map_frag));
-    auto modelTranslucentPixel = gpu::Shader::createPixel(std::string(model_translucent_frag));
-    auto modelTranslucentUnlitPixel = gpu::Shader::createPixel(std::string(model_translucent_unlit_frag));
-    auto modelShadowPixel = gpu::Shader::createPixel(std::string(model_shadow_frag));
-    auto modelLightmapPixel = gpu::Shader::createPixel(std::string(model_lightmap_frag));
-    auto modelLightmapNormalMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_map_frag));
-    auto modelLightmapSpecularMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_specular_map_frag));
-    auto modelLightmapNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_specular_map_frag));
-    auto modelLightmapFadePixel = gpu::Shader::createPixel(std::string(model_lightmap_fade_frag));
-    auto modelLightmapNormalMapFadePixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_map_fade_frag));
-    auto modelLightmapSpecularMapFadePixel = gpu::Shader::createPixel(std::string(model_lightmap_specular_map_fade_frag));
-    auto modelLightmapNormalSpecularMapFadePixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_specular_map_fade_frag));
+    auto simplePixel = simple_textured_frag::getShader();
+    auto simpleUnlitPixel = simple_textured_unlit_frag::getShader();
+    auto simpleTranslucentPixel = simple_transparent_textured_frag::getShader();
+    auto simpleTranslucentUnlitPixel = simple_transparent_textured_unlit_frag::getShader();
+    auto modelPixel = model_frag::getShader();
+    auto modelUnlitPixel = model_unlit_frag::getShader();
+    auto modelNormalMapPixel = model_normal_map_frag::getShader();
+    auto modelSpecularMapPixel = model_specular_map_frag::getShader();
+    auto modelNormalSpecularMapPixel = model_normal_specular_map_frag::getShader();
+    auto modelTranslucentPixel = model_translucent_frag::getShader();
+    auto modelTranslucentUnlitPixel = model_translucent_unlit_frag::getShader();
+    auto modelShadowPixel = model_shadow_frag::getShader();
+    auto modelLightmapPixel = model_lightmap_frag::getShader();
+    auto modelLightmapNormalMapPixel = model_lightmap_normal_map_frag::getShader();
+    auto modelLightmapSpecularMapPixel = model_lightmap_specular_map_frag::getShader();
+    auto modelLightmapNormalSpecularMapPixel = model_lightmap_normal_specular_map_frag::getShader();
+    auto modelLightmapFadePixel = model_lightmap_fade_frag::getShader();
+    auto modelLightmapNormalMapFadePixel = model_lightmap_normal_map_fade_frag::getShader();
+    auto modelLightmapSpecularMapFadePixel = model_lightmap_specular_map_fade_frag::getShader();
+    auto modelLightmapNormalSpecularMapFadePixel = model_lightmap_normal_specular_map_fade_frag::getShader();
 
-    auto modelFadePixel = gpu::Shader::createPixel(std::string(model_fade_frag));
-    auto modelUnlitFadePixel = gpu::Shader::createPixel(std::string(model_unlit_fade_frag));
-    auto modelNormalMapFadePixel = gpu::Shader::createPixel(std::string(model_normal_map_fade_frag));
-    auto modelSpecularMapFadePixel = gpu::Shader::createPixel(std::string(model_specular_map_fade_frag));
-    auto modelNormalSpecularMapFadePixel = gpu::Shader::createPixel(std::string(model_normal_specular_map_fade_frag));
-    auto modelShadowFadePixel = gpu::Shader::createPixel(std::string(model_shadow_fade_frag));
-    auto modelTranslucentFadePixel = gpu::Shader::createPixel(std::string(model_translucent_fade_frag));
-    auto modelTranslucentUnlitFadePixel = gpu::Shader::createPixel(std::string(model_translucent_unlit_fade_frag));
-    auto simpleFadePixel = gpu::Shader::createPixel(std::string(simple_textured_fade_frag));
-    auto simpleUnlitFadePixel = gpu::Shader::createPixel(std::string(simple_textured_unlit_fade_frag));
-    auto simpleTranslucentFadePixel = gpu::Shader::createPixel(std::string(simple_transparent_textured_fade_frag));
-    auto simpleTranslucentUnlitFadePixel = gpu::Shader::createPixel(std::string(simple_transparent_textured_unlit_fade_frag));
+    auto modelFadePixel = model_fade_frag::getShader();
+    auto modelUnlitFadePixel = model_unlit_fade_frag::getShader();
+    auto modelNormalMapFadePixel = model_normal_map_fade_frag::getShader();
+    auto modelSpecularMapFadePixel = model_specular_map_fade_frag::getShader();
+    auto modelNormalSpecularMapFadePixel = model_normal_specular_map_fade_frag::getShader();
+    auto modelShadowFadePixel = model_shadow_fade_frag::getShader();
+    auto modelTranslucentFadePixel = model_translucent_fade_frag::getShader();
+    auto modelTranslucentUnlitFadePixel = model_translucent_unlit_fade_frag::getShader();
+    auto simpleFadePixel = simple_textured_fade_frag::getShader();
+    auto simpleUnlitFadePixel = simple_textured_unlit_fade_frag::getShader();
+    auto simpleTranslucentFadePixel = simple_transparent_textured_fade_frag::getShader();
+    auto simpleTranslucentUnlitFadePixel = simple_transparent_textured_unlit_fade_frag::getShader();
 
     using Key = render::ShapeKey;
     auto addPipeline = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, _3, _4, _5);
@@ -446,20 +446,20 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
 
 void initForwardPipelines(ShapePlumber& plumber, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter) {
     // Vertex shaders
-    auto modelVertex = gpu::Shader::createVertex(std::string(model_vert));
-    auto modelNormalMapVertex = gpu::Shader::createVertex(std::string(model_normal_map_vert));
-    auto skinModelVertex = gpu::Shader::createVertex(std::string(skin_model_vert));
-    auto skinModelNormalMapVertex = gpu::Shader::createVertex(std::string(skin_model_normal_map_vert));
-    auto skinModelNormalMapFadeVertex = gpu::Shader::createVertex(std::string(skin_model_normal_map_fade_vert));
+    auto modelVertex = model_vert::getShader();
+    auto modelNormalMapVertex = model_normal_map_vert::getShader();
+    auto skinModelVertex = skin_model_vert::getShader();
+    auto skinModelNormalMapVertex = skin_model_normal_map_vert::getShader();
+    auto skinModelNormalMapFadeVertex = skin_model_normal_map_fade_vert::getShader();
 
     // Pixel shaders
-    auto modelPixel = gpu::Shader::createPixel(std::string(forward_model_frag));
-    auto modelUnlitPixel = gpu::Shader::createPixel(std::string(forward_model_unlit_frag));
-    auto modelNormalMapPixel = gpu::Shader::createPixel(std::string(forward_model_normal_map_frag));
-    auto modelSpecularMapPixel = gpu::Shader::createPixel(std::string(forward_model_specular_map_frag));
-    auto modelNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(forward_model_normal_specular_map_frag));
-    auto modelNormalMapFadePixel = gpu::Shader::createPixel(std::string(model_normal_map_fade_frag));
-    auto modelTranslucentPixel = gpu::Shader::createPixel(std::string(forward_model_translucent_frag));
+    auto modelPixel = forward_model_frag::getShader();
+    auto modelUnlitPixel = forward_model_unlit_frag::getShader();
+    auto modelNormalMapPixel = forward_model_normal_map_frag::getShader();
+    auto modelSpecularMapPixel = forward_model_specular_map_frag::getShader();
+    auto modelNormalSpecularMapPixel = forward_model_normal_specular_map_frag::getShader();
+    auto modelNormalMapFadePixel = model_normal_map_fade_frag::getShader();
+    auto modelTranslucentPixel = forward_model_translucent_frag::getShader();
 
     using Key = render::ShapeKey;
     auto addPipelineBind = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, _3, _4, _5);
@@ -592,29 +592,29 @@ void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderAr
 }
 
 void initZPassPipelines(ShapePlumber& shapePlumber, gpu::StatePointer state) {
-    auto modelVertex = gpu::Shader::createVertex(std::string(model_shadow_vert));
-    auto modelPixel = gpu::Shader::createPixel(std::string(model_shadow_frag));
+    auto modelVertex = model_shadow_vert::getShader();
+    auto modelPixel = model_shadow_frag::getShader();
     gpu::ShaderPointer modelProgram = gpu::Shader::createProgram(modelVertex, modelPixel);
     shapePlumber.addPipeline(
         ShapeKey::Filter::Builder().withoutSkinned().withoutFade(),
         modelProgram, state);
 
-    auto skinVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_vert));
-    auto skinPixel = gpu::Shader::createPixel(std::string(skin_model_shadow_frag));
+    auto skinVertex = skin_model_shadow_vert::getShader();
+    auto skinPixel = skin_model_shadow_frag::getShader();
     gpu::ShaderPointer skinProgram = gpu::Shader::createProgram(skinVertex, skinPixel);
     shapePlumber.addPipeline(
         ShapeKey::Filter::Builder().withSkinned().withoutFade(),
         skinProgram, state);
 
-    auto modelFadeVertex = gpu::Shader::createVertex(std::string(model_shadow_fade_vert));
-    auto modelFadePixel = gpu::Shader::createPixel(std::string(model_shadow_fade_frag));
+    auto modelFadeVertex = model_shadow_fade_vert::getShader();
+    auto modelFadePixel = model_shadow_fade_frag::getShader();
     gpu::ShaderPointer modelFadeProgram = gpu::Shader::createProgram(modelFadeVertex, modelFadePixel);
     shapePlumber.addPipeline(
         ShapeKey::Filter::Builder().withoutSkinned().withFade(),
         modelFadeProgram, state);
 
-    auto skinFadeVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_fade_vert));
-    auto skinFadePixel = gpu::Shader::createPixel(std::string(skin_model_shadow_fade_frag));
+    auto skinFadeVertex = skin_model_shadow_fade_vert::getShader();
+    auto skinFadePixel = skin_model_shadow_fade_frag::getShader();
     gpu::ShaderPointer skinFadeProgram = gpu::Shader::createProgram(skinFadeVertex, skinFadePixel);
     shapePlumber.addPipeline(
         ShapeKey::Filter::Builder().withSkinned().withFade(),
diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp
index de8de9abcf..f9af157e7c 100644
--- a/libraries/render-utils/src/StencilMaskPass.cpp
+++ b/libraries/render-utils/src/StencilMaskPass.cpp
@@ -60,7 +60,7 @@ gpu::PipelinePointer PrepareStencil::getMeshStencilPipeline() {
 gpu::PipelinePointer PrepareStencil::getPaintStencilPipeline() {
     if (!_paintStencilPipeline) {
         auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(stencil_drawMask_frag));
+        auto ps = stencil_drawMask_frag::getShader();
         auto program = gpu::Shader::createProgram(vs, ps);
         gpu::Shader::makeProgram((*program));
 
diff --git a/libraries/render-utils/src/SubsurfaceScattering.cpp b/libraries/render-utils/src/SubsurfaceScattering.cpp
index 2183f95565..ff415accc3 100644
--- a/libraries/render-utils/src/SubsurfaceScattering.cpp
+++ b/libraries/render-utils/src/SubsurfaceScattering.cpp
@@ -308,7 +308,7 @@ void diffuseProfileGPU(gpu::TexturePointer& profileMap, RenderArgs* args) {
     gpu::PipelinePointer makePipeline;
     {
         auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(subsurfaceScattering_makeProfile_frag));
+        auto ps = subsurfaceScattering_makeProfile_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -344,7 +344,7 @@ void diffuseScatterGPU(const gpu::TexturePointer& profileMap, gpu::TexturePointe
     gpu::PipelinePointer makePipeline;
     {
         auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(subsurfaceScattering_makeLUT_frag));
+        auto ps = subsurfaceScattering_makeLUT_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -382,7 +382,7 @@ void computeSpecularBeckmannGPU(gpu::TexturePointer& beckmannMap, RenderArgs* ar
     gpu::PipelinePointer makePipeline;
     {
         auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(subsurfaceScattering_makeSpecularBeckmann_frag));
+        auto ps = subsurfaceScattering_makeSpecularBeckmann_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -457,7 +457,7 @@ void DebugSubsurfaceScattering::configure(const Config& config) {
 gpu::PipelinePointer DebugSubsurfaceScattering::getScatteringPipeline() {
     if (!_scatteringPipeline) {
         auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(subsurfaceScattering_drawScattering_frag));
+        auto ps = subsurfaceScattering_drawScattering_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp
index c4eea7ce7f..afed9ee8fd 100644
--- a/libraries/render-utils/src/SurfaceGeometryPass.cpp
+++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp
@@ -212,7 +212,7 @@ void LinearDepthPass::run(const render::RenderContextPointer& renderContext, con
 const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline() {
     if (!_linearDepthPipeline) {
         auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(surfaceGeometry_makeLinearDepth_frag));
+        auto ps = surfaceGeometry_makeLinearDepth_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -239,7 +239,7 @@ const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline() {
 const gpu::PipelinePointer& LinearDepthPass::getDownsamplePipeline() {
     if (!_downsamplePipeline) {
         auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(surfaceGeometry_downsampleDepthNormal_frag));
+        auto ps = surfaceGeometry_downsampleDepthNormal_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -540,7 +540,7 @@ void SurfaceGeometryPass::run(const render::RenderContextPointer& renderContext,
 const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() {
     if (!_curvaturePipeline) {
         auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(surfaceGeometry_makeCurvature_frag));
+        auto ps = surfaceGeometry_makeCurvature_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
diff --git a/libraries/render-utils/src/ToneMappingEffect.cpp b/libraries/render-utils/src/ToneMappingEffect.cpp
index 72d692c5b2..e1abefd681 100644
--- a/libraries/render-utils/src/ToneMappingEffect.cpp
+++ b/libraries/render-utils/src/ToneMappingEffect.cpp
@@ -28,7 +28,7 @@ ToneMappingEffect::ToneMappingEffect() {
 }
 
 void ToneMappingEffect::init() {
-    auto blitPS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(toneMapping_frag)));
+    auto blitPS = toneMapping_frag::getShader();
 
     auto blitVS = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
     auto blitProgram = gpu::ShaderPointer(gpu::Shader::createProgram(blitVS, blitPS));
diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp
index 11e5b8d2f5..1d358ff895 100644
--- a/libraries/render-utils/src/ZoneRenderer.cpp
+++ b/libraries/render-utils/src/ZoneRenderer.cpp
@@ -78,7 +78,7 @@ void SetupZones::run(const RenderContextPointer& context, const Inputs& inputs)
 const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() {
     if (!_keyLightPipeline) {
         auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS();
-        auto ps = gpu::Shader::createPixel(std::string(zone_drawKeyLight_frag));
+        auto ps = zone_drawKeyLight_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -99,7 +99,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() {
 const gpu::PipelinePointer& DebugZoneLighting::getAmbientPipeline() {
     if (!_ambientPipeline) {
         auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS();
-        auto ps = gpu::Shader::createPixel(std::string(zone_drawAmbient_frag));
+        auto ps = zone_drawAmbient_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -120,7 +120,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getAmbientPipeline() {
 const gpu::PipelinePointer& DebugZoneLighting::getBackgroundPipeline() {
     if (!_backgroundPipeline) {
         auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS();
-        auto ps = gpu::Shader::createPixel(std::string(zone_drawSkybox_frag));
+        auto ps = zone_drawSkybox_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
diff --git a/libraries/render-utils/src/text/Font.cpp b/libraries/render-utils/src/text/Font.cpp
index 1c4e35381d..d3d25431d0 100644
--- a/libraries/render-utils/src/text/Font.cpp
+++ b/libraries/render-utils/src/text/Font.cpp
@@ -223,9 +223,9 @@ void Font::setupGPU() {
 
         // Setup render pipeline
         {
-            auto vertexShader = gpu::Shader::createVertex(std::string(sdf_text3D_vert));
-            auto pixelShader = gpu::Shader::createPixel(std::string(sdf_text3D_frag));
-            auto pixelShaderTransparent = gpu::Shader::createPixel(std::string(sdf_text3D_transparent_frag));
+            auto vertexShader = sdf_text3D_vert::getShader();
+            auto pixelShader = sdf_text3D_frag::getShader();
+            auto pixelShaderTransparent = sdf_text3D_transparent_frag::getShader();
             gpu::ShaderPointer program = gpu::Shader::createProgram(vertexShader, pixelShader);
             gpu::ShaderPointer programTransparent = gpu::Shader::createProgram(vertexShader, pixelShaderTransparent);
 
diff --git a/libraries/render/src/render/BlurTask.cpp b/libraries/render/src/render/BlurTask.cpp
index 2be6f8fad2..0625179a6d 100644
--- a/libraries/render/src/render/BlurTask.cpp
+++ b/libraries/render/src/render/BlurTask.cpp
@@ -210,7 +210,7 @@ BlurGaussian::BlurGaussian(bool generateOutputFramebuffer, unsigned int downsamp
 gpu::PipelinePointer BlurGaussian::getBlurVPipeline() {
     if (!_blurVPipeline) {
         auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(blurGaussianV_frag));
+        auto ps = blurGaussianV_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -232,7 +232,7 @@ gpu::PipelinePointer BlurGaussian::getBlurVPipeline() {
 gpu::PipelinePointer BlurGaussian::getBlurHPipeline() {
     if (!_blurHPipeline) {
         auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(blurGaussianH_frag));
+        auto ps = blurGaussianH_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -324,7 +324,7 @@ BlurGaussianDepthAware::BlurGaussianDepthAware(bool generateOutputFramebuffer, c
 gpu::PipelinePointer BlurGaussianDepthAware::getBlurVPipeline() {
     if (!_blurVPipeline) {
         auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(blurGaussianDepthAwareV_frag));
+        auto ps = blurGaussianDepthAwareV_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -347,7 +347,7 @@ gpu::PipelinePointer BlurGaussianDepthAware::getBlurVPipeline() {
 gpu::PipelinePointer BlurGaussianDepthAware::getBlurHPipeline() {
     if (!_blurHPipeline) {
         auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
-        auto ps = gpu::Shader::createPixel(std::string(blurGaussianDepthAwareH_frag));
+        auto ps = blurGaussianDepthAwareH_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
diff --git a/libraries/render/src/render/DrawSceneOctree.cpp b/libraries/render/src/render/DrawSceneOctree.cpp
index 36663a454a..f1e85dbb71 100644
--- a/libraries/render/src/render/DrawSceneOctree.cpp
+++ b/libraries/render/src/render/DrawSceneOctree.cpp
@@ -34,8 +34,8 @@ using namespace render;
 
 const gpu::PipelinePointer DrawSceneOctree::getDrawCellBoundsPipeline() {
     if (!_drawCellBoundsPipeline) {
-        auto vs = gpu::Shader::createVertex(std::string(drawCellBounds_vert));
-        auto ps = gpu::Shader::createPixel(std::string(drawCellBounds_frag));
+        auto vs = drawCellBounds_vert::getShader();
+        auto ps = drawCellBounds_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -59,7 +59,7 @@ const gpu::PipelinePointer DrawSceneOctree::getDrawCellBoundsPipeline() {
 const gpu::PipelinePointer DrawSceneOctree::getDrawLODReticlePipeline() {
     if (!_drawLODReticlePipeline) {
         auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS();
-        auto ps = gpu::Shader::createPixel(std::string(drawLODReticle_frag));
+        auto ps = drawLODReticle_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -162,8 +162,8 @@ void DrawSceneOctree::run(const RenderContextPointer& renderContext, const ItemS
 
 const gpu::PipelinePointer DrawItemSelection::getDrawItemBoundPipeline() {
     if (!_drawItemBoundPipeline) {
-        auto vs = gpu::Shader::createVertex(std::string(drawItemBounds_vert));
-        auto ps = gpu::Shader::createPixel(std::string(drawItemBounds_frag));
+        auto vs = drawItemBounds_vert::getShader();
+        auto ps = drawItemBounds_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp
index 148e104453..a11e9b1a88 100644
--- a/libraries/render/src/render/DrawStatus.cpp
+++ b/libraries/render/src/render/DrawStatus.cpp
@@ -35,8 +35,8 @@ void DrawStatusConfig::dirtyHelper() {
 
 const gpu::PipelinePointer DrawStatus::getDrawItemBoundsPipeline() {
     if (!_drawItemBoundsPipeline) {
-        auto vs = gpu::Shader::createVertex(std::string(drawItemBounds_vert));
-        auto ps = gpu::Shader::createPixel(std::string(drawItemBounds_frag));
+        auto vs = drawItemBounds_vert::getShader();
+        auto ps = drawItemBounds_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
@@ -63,8 +63,8 @@ const gpu::PipelinePointer DrawStatus::getDrawItemBoundsPipeline() {
 
 const gpu::PipelinePointer DrawStatus::getDrawItemStatusPipeline() {
     if (!_drawItemStatusPipeline) {
-        auto vs = gpu::Shader::createVertex(std::string(drawItemStatus_vert));
-        auto ps = gpu::Shader::createPixel(std::string(drawItemStatus_frag));
+        auto vs = drawItemStatus_vert::getShader();
+        auto ps = drawItemStatus_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp
index 629cc55ccb..88d38d1c66 100755
--- a/libraries/render/src/render/DrawTask.cpp
+++ b/libraries/render/src/render/DrawTask.cpp
@@ -22,8 +22,8 @@
 #include <gpu/Context.h>
 #include <gpu/StandardShaderLib.h>
 
-#include <drawItemBounds_vert.h>
-#include <drawItemBounds_frag.h>
+#include "drawItemBounds_vert.h"
+#include "drawItemBounds_frag.h"
 
 using namespace render;
 
@@ -155,8 +155,8 @@ void DrawLight::run(const RenderContextPointer& renderContext, const ItemBounds&
 
 const gpu::PipelinePointer DrawBounds::getPipeline() {
     if (!_boundsPipeline) {
-        auto vs = gpu::Shader::createVertex(std::string(drawItemBounds_vert));
-        auto ps = gpu::Shader::createPixel(std::string(drawItemBounds_frag));
+        auto vs = drawItemBounds_vert::getShader();
+        auto ps = drawItemBounds_frag::getShader();
         gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
 
         gpu::Shader::BindingSet slotBindings;
diff --git a/libraries/render/src/render/drawItemBounds.slf b/libraries/render/src/render/drawItemBounds.slf
index e01d1607bd..84c47d0933 100644
--- a/libraries/render/src/render/drawItemBounds.slf
+++ b/libraries/render/src/render/drawItemBounds.slf
@@ -15,7 +15,6 @@ in vec4 varColor;
 in vec2 varTexcoord;
 out vec4 outFragColor;
 
-
 void main(void) {
     float var = step(fract(varTexcoord.x * varTexcoord.y * 1.0), 0.5);
 
diff --git a/tests/shaders/src/main.cpp b/tests/shaders/src/main.cpp
index cd307ba362..d97d70585b 100644
--- a/tests/shaders/src/main.cpp
+++ b/tests/shaders/src/main.cpp
@@ -101,6 +101,7 @@ public:
 
         show();
         makeCurrent();
+        gl::initModuleGl();
         gpu::Context::init<gpu::gl::GLBackend>();
         makeCurrent();
         resize(QSize(800, 600));
@@ -135,7 +136,7 @@ const std::string PIXEL_SHADER_DEFINES{ R"GLSL(
 #define GPU_TRANSFORM_STEREO_SPLIT_SCREEN
 )GLSL" };
 
-void testShaderBuild(const char* vs_src, const char * fs_src) {
+void testShaderBuild(const std::string& vs_src, const std::string& fs_src) {
     std::string error;
     GLuint vs, fs;
     if (!gl::compileShader(GL_VERTEX_SHADER, vs_src, VERTEX_SHADER_DEFINES, vs, error) || 
@@ -159,54 +160,54 @@ void QTestWindow::draw() {
 
     static std::once_flag once;
     std::call_once(once, [&]{
-        testShaderBuild(sdf_text3D_vert, sdf_text3D_frag);
+        testShaderBuild(sdf_text3D_vert::getSource(), sdf_text3D_frag::getSource());
 
-        testShaderBuild(DrawTransformUnitQuad_vert, DrawTexture_frag);
-        testShaderBuild(DrawTexcoordRectTransformUnitQuad_vert, DrawTexture_frag);
-        testShaderBuild(DrawViewportQuadTransformTexcoord_vert, DrawTexture_frag);
-        testShaderBuild(DrawTransformUnitQuad_vert, DrawTextureOpaque_frag);
-        testShaderBuild(DrawTransformUnitQuad_vert, DrawColoredTexture_frag);
+        testShaderBuild(DrawTransformUnitQuad_vert::getSource(), DrawTexture_frag::getSource());
+        testShaderBuild(DrawTexcoordRectTransformUnitQuad_vert::getSource(), DrawTexture_frag::getSource());
+        testShaderBuild(DrawViewportQuadTransformTexcoord_vert::getSource(), DrawTexture_frag::getSource());
+        testShaderBuild(DrawTransformUnitQuad_vert::getSource(), DrawTextureOpaque_frag::getSource());
+        testShaderBuild(DrawTransformUnitQuad_vert::getSource(), DrawColoredTexture_frag::getSource());
 
-        testShaderBuild(skybox_vert, skybox_frag);
-        testShaderBuild(simple_vert, simple_frag);
-        testShaderBuild(simple_vert, simple_textured_frag);
-        testShaderBuild(simple_vert, simple_textured_unlit_frag);
-        testShaderBuild(deferred_light_vert, directional_ambient_light_frag);
-        testShaderBuild(deferred_light_vert, directional_skybox_light_frag);
-        testShaderBuild(standardTransformPNTC_vert, standardDrawTexture_frag);
-        testShaderBuild(standardTransformPNTC_vert, DrawTextureOpaque_frag);
+        testShaderBuild(skybox_vert::getSource(), skybox_frag::getSource());
+        testShaderBuild(simple_vert::getSource(), simple_frag::getSource());
+        testShaderBuild(simple_vert::getSource(), simple_textured_frag::getSource());
+        testShaderBuild(simple_vert::getSource(), simple_textured_unlit_frag::getSource());
+        testShaderBuild(deferred_light_vert::getSource(), directional_ambient_light_frag::getSource());
+        testShaderBuild(deferred_light_vert::getSource(), directional_skybox_light_frag::getSource());
+        testShaderBuild(standardTransformPNTC_vert::getSource(), standardDrawTexture_frag::getSource());
+        testShaderBuild(standardTransformPNTC_vert::getSource(), DrawTextureOpaque_frag::getSource());
 
-        testShaderBuild(model_vert, model_frag);
-        testShaderBuild(model_normal_map_vert, model_normal_map_frag);
-        testShaderBuild(model_vert, model_specular_map_frag);
-        testShaderBuild(model_normal_map_vert, model_normal_specular_map_frag);
-        testShaderBuild(model_vert, model_translucent_frag);
-        testShaderBuild(model_normal_map_vert, model_translucent_frag);
-        testShaderBuild(model_lightmap_vert, model_lightmap_frag);
-        testShaderBuild(model_lightmap_normal_map_vert, model_lightmap_normal_map_frag);
-        testShaderBuild(model_lightmap_vert, model_lightmap_specular_map_frag);
-        testShaderBuild(model_lightmap_normal_map_vert, model_lightmap_normal_specular_map_frag);
+        testShaderBuild(model_vert::getSource(), model_frag::getSource());
+        testShaderBuild(model_normal_map_vert::getSource(), model_normal_map_frag::getSource());
+        testShaderBuild(model_vert::getSource(), model_specular_map_frag::getSource());
+        testShaderBuild(model_normal_map_vert::getSource(), model_normal_specular_map_frag::getSource());
+        testShaderBuild(model_vert::getSource(), model_translucent_frag::getSource());
+        testShaderBuild(model_normal_map_vert::getSource(), model_translucent_frag::getSource());
+        testShaderBuild(model_lightmap_vert::getSource(), model_lightmap_frag::getSource());
+        testShaderBuild(model_lightmap_normal_map_vert::getSource(), model_lightmap_normal_map_frag::getSource());
+        testShaderBuild(model_lightmap_vert::getSource(), model_lightmap_specular_map_frag::getSource());
+        testShaderBuild(model_lightmap_normal_map_vert::getSource(), model_lightmap_normal_specular_map_frag::getSource());
 
-        testShaderBuild(skin_model_vert, model_frag);
-        testShaderBuild(skin_model_normal_map_vert, model_normal_map_frag);
-        testShaderBuild(skin_model_vert, model_specular_map_frag);
-        testShaderBuild(skin_model_normal_map_vert, model_normal_specular_map_frag);
-        testShaderBuild(skin_model_vert, model_translucent_frag);
-        testShaderBuild(skin_model_normal_map_vert, model_translucent_frag);
+        testShaderBuild(skin_model_vert::getSource(), model_frag::getSource());
+        testShaderBuild(skin_model_normal_map_vert::getSource(), model_normal_map_frag::getSource());
+        testShaderBuild(skin_model_vert::getSource(), model_specular_map_frag::getSource());
+        testShaderBuild(skin_model_normal_map_vert::getSource(), model_normal_specular_map_frag::getSource());
+        testShaderBuild(skin_model_vert::getSource(), model_translucent_frag::getSource());
+        testShaderBuild(skin_model_normal_map_vert::getSource(), model_translucent_frag::getSource());
 
-        testShaderBuild(model_shadow_vert, model_shadow_frag);
-        testShaderBuild(textured_particle_vert, textured_particle_frag);
+        testShaderBuild(model_shadow_vert::getSource(), model_shadow_frag::getSource());
+        testShaderBuild(textured_particle_vert::getSource(), textured_particle_frag::getSource());
 /* FIXME: Bring back the ssao shader tests
-        testShaderBuild(gaussian_blur_vertical_vert, gaussian_blur_frag);
-        testShaderBuild(gaussian_blur_horizontal_vert, gaussian_blur_frag);
-        testShaderBuild(ambient_occlusion_vert, ambient_occlusion_frag);
-        testShaderBuild(ambient_occlusion_vert, occlusion_blend_frag);
+        testShaderBuild(gaussian_blur_vert::getSource()ical_vert::getSource(), gaussian_blur_frag::getSource());
+        testShaderBuild(gaussian_blur_horizontal_vert::getSource(), gaussian_blur_frag::getSource());
+        testShaderBuild(ambient_occlusion_vert::getSource(), ambient_occlusion_frag::getSource());
+        testShaderBuild(ambient_occlusion_vert::getSource(), occlusion_blend_frag::getSource());
 */
 
-        testShaderBuild(overlay3D_vert, overlay3D_frag);
+        testShaderBuild(overlay3D_vert::getSource(), overlay3D_frag::getSource());
 
-        testShaderBuild(paintStroke_vert,paintStroke_frag);
-        testShaderBuild(polyvox_vert, polyvox_frag);
+        testShaderBuild(paintStroke_vert::getSource(),paintStroke_frag::getSource());
+        testShaderBuild(polyvox_vert::getSource(), polyvox_frag::getSource());
 
     });
     _context.swapBuffers(this);
diff --git a/tools/scribe/CMakeLists.txt b/tools/scribe/CMakeLists.txt
index e62a3467e0..9c71aeec9c 100755
--- a/tools/scribe/CMakeLists.txt
+++ b/tools/scribe/CMakeLists.txt
@@ -1,3 +1,8 @@
 set(TARGET_NAME scribe)
 
-setup_hifi_project()
+# don't use the setup_hifi_project macro as we don't want Qt or GLM dependencies
+file(GLOB TARGET_SRCS src/*)
+add_executable(${TARGET_NAME} ${TARGET_SRCS})
+if (WIN32)
+ set_property(TARGET ${TARGET_NAME} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG "/OPT:NOREF /OPT:NOICF")
+endif()
diff --git a/tools/scribe/src/main.cpp b/tools/scribe/src/main.cpp
index 810f6c0f45..c8c540c362 100755
--- a/tools/scribe/src/main.cpp
+++ b/tools/scribe/src/main.cpp
@@ -41,9 +41,23 @@ int main (int argc, char** argv) {
         GRAB_VAR_VALUE,
         GRAB_INCLUDE_PATH,
         GRAB_TARGET_NAME,
+        GRAB_SHADER_TYPE,
         EXIT,
     } mode = READY;
 
+    enum Type {
+        VERTEX = 0,
+        FRAGMENT,
+        GEOMETRY,
+    } type = VERTEX;
+    static const char* shaderTypeString[] = {
+        "VERTEX", "PIXEL", "GEOMETRY"
+    };
+    static const char* shaderCreateString[] = {
+        "Vertex", "Pixel", "Geometry"
+    };
+    std::string shaderStage{ "vert" };
+
     for (int ii = 1; (mode != EXIT) && (ii < argc); ii++) {
         inputs.push_back(argv[ii]);
 
@@ -66,6 +80,8 @@ int main (int argc, char** argv) {
                 } else if (inputs.back() == "-c++") {
                     makeCPlusPlus = true;
                     mode = READY;
+                } else if (inputs.back() == "-T") {
+                    mode = GRAB_SHADER_TYPE;
                 } else {
                     // just grabbed the source filename, stop parameter parsing
                     srcFilename = inputs.back();
@@ -106,6 +122,24 @@ int main (int argc, char** argv) {
             }
             break;
                 
+            case GRAB_SHADER_TYPE:
+            {
+                if (inputs.back() == "frag") {
+                    shaderStage = inputs.back();
+                    type = FRAGMENT;
+                } else if (inputs.back() == "geom") {
+                    shaderStage = inputs.back();
+                    type = GEOMETRY;
+                } else if (inputs.back() == "vert") {
+                    shaderStage = inputs.back();
+                    type = VERTEX;
+                } else {
+                    cerr << "Unrecognized shader type. Supported is vert, frag or geom" << endl;
+                }
+                mode = READY;
+            }
+            break;
+
             case EXIT: {
                 // THis shouldn't happen
             }
@@ -123,11 +157,13 @@ int main (int argc, char** argv) {
         cerr << "       varname and varvalue must be made of alpha numerical characters with no spaces." << endl;
         cerr << "  -listVars : Will list the vars name and value in the standard output." << endl;
         cerr << "  -showParseTree : Draw the tree obtained while parsing the source" << endl;
-        cerr << "  -c++ : Generate a c++ header file containing the output file stream stored as a char[] variable" << endl;
+        cerr << "  -c++ : Generate a c++ source file containing the output file stream stored as a char[] variable" << endl;
+        cerr << "  -T vert/frag/geom : define the type of the shader. Defaults to VERTEX if not specified." << endl;
+        cerr << "       This is necessary if the -c++ option is used." << endl;
         return 0;
     }
 
-    // Define targetName: if none, get destFilenmae, if none get srcFilename
+    // Define targetName: if none, get destFilename, if none get srcFilename
     if (targetName.empty()) {
         if (destFilename.empty()) {
             targetName = srcFilename;
@@ -163,7 +199,7 @@ int main (int argc, char** argv) {
     srcStream.open(srcFilename, std::fstream::in);
     if (!srcStream.is_open()) {
         cerr << "Failed to open source file <" << srcFilename << ">" << endl;
-        return 0;
+        return 1;
     }
 
     auto scribe = std::make_shared<TextTemplate>(srcFilename, config);
@@ -173,7 +209,7 @@ int main (int argc, char** argv) {
     int numErrors = scribe->scribe(destStringStream, srcStream, vars);
     if (numErrors) {
         cerr << "Scribe " << srcFilename << "> failed: " << numErrors << " errors." << endl;
-        return 0;
+        return 1;
     };
 
 
@@ -186,7 +222,6 @@ int main (int argc, char** argv) {
         scribe->displayTree(cerr, level);
     }
 
-    std::ostringstream targetStringStream;
     if (makeCPlusPlus) {
         // Because there is a maximum size for literal strings declared in source we need to partition the 
         // full source string stream into pages that seems to be around that value...
@@ -208,35 +243,108 @@ int main (int argc, char** argv) {
             pageSize += lineSize;
         }
 
-        targetStringStream << "// File generated by Scribe " << vars["_SCRIBE_DATE"] << std::endl;
-        targetStringStream << "#ifndef scribe_" << targetName << "_h" << std::endl;
-        targetStringStream << "#define scribe_" << targetName << "_h" << std::endl << std::endl;
+        std::stringstream headerStringStream;
+        std::stringstream sourceStringStream;
+        std::string headerFileName = destFilename + ".h";
+        std::string sourceFileName = destFilename + ".cpp";
 
-        targetStringStream << "const char " << targetName << "[] = \n";
+        sourceStringStream << "// File generated by Scribe " << vars["_SCRIBE_DATE"] << std::endl;
 
+        // Write header file
+        headerStringStream << "#ifndef " << targetName << "_h" << std::endl;
+        headerStringStream << "#define " << targetName << "_h\n" << std::endl;
+        headerStringStream << "#include <gpu/Shader.h>\n" << std::endl;
+        headerStringStream << "class " << targetName << " {" << std::endl;
+        headerStringStream << "public:" << std::endl;
+        headerStringStream << "\tstatic gpu::Shader::Type getType() { return gpu::Shader::" << shaderTypeString[type] << "; }" << std::endl;
+        headerStringStream << "\tstatic const std::string& getSource() { return _source; }" << std::endl;
+        headerStringStream << "\tstatic gpu::ShaderPointer getShader();" << std::endl;
+        headerStringStream << "private:" << std::endl;
+        headerStringStream << "\tstatic const std::string _source;" << std::endl;
+        headerStringStream << "\tstatic gpu::ShaderPointer _shader;" << std::endl;
+        headerStringStream << "};\n" << std::endl;
+        headerStringStream << "#endif // " << targetName << "_h" << std::endl;
+
+        bool mustOutputHeader = destFilename.empty();
+        // Compare with existing file
+        {
+            std::fstream headerFile;
+            headerFile.open(headerFileName, std::fstream::in);
+            if (headerFile.is_open()) {
+                // Skip first line
+                std::string line;
+                std::stringstream previousHeaderStringStream;
+                std::getline(headerFile, line);
+
+                previousHeaderStringStream << headerFile.rdbuf();
+                mustOutputHeader = mustOutputHeader || previousHeaderStringStream.str() != headerStringStream.str();
+            } else {
+                mustOutputHeader = true;
+            }
+        }
+
+        if (mustOutputHeader) {
+            if (!destFilename.empty()) {
+                // File content has changed so write it
+                std::fstream headerFile;
+                headerFile.open(headerFileName, std::fstream::out);
+                if (headerFile.is_open()) {
+                    // First line contains the date of modification
+                    headerFile << sourceStringStream.str();
+                    headerFile << headerStringStream.str();
+                } else {
+                    cerr << "Scribe output file <" << headerFileName << "> failed to open." << endl;
+                    return 1;
+                }
+            } else {
+                cerr << sourceStringStream.str();
+                cerr << headerStringStream.str();
+            }
+        }
+
+        // Write source file
+        sourceStringStream << "#include \"" << targetName << ".h\"\n" << std::endl;
+        sourceStringStream << "gpu::ShaderPointer " << targetName << "::_shader;" << std::endl;
+        sourceStringStream << "const std::string " << targetName << "::_source = std::string()";
         // Write the pages content
         for (auto page : pages) {
-            targetStringStream << "R\"SCRIBE(\n" << page->str() << "\n)SCRIBE\"\n";
+            sourceStringStream << "+ std::string(R\"SCRIBE(\n" << page->str() << "\n)SCRIBE\")\n";
         }
-        targetStringStream << ";\n" << std::endl << std::endl;
+        sourceStringStream << ";\n" << std::endl << std::endl;
 
-        targetStringStream << "#endif" << std::endl;
-    } else {
-        targetStringStream << destStringStream.str();
-    }
+        sourceStringStream << "gpu::ShaderPointer " << targetName << "::getShader() {" << std::endl;
+        sourceStringStream << "\tif (_shader==nullptr) {" << std::endl;
+        sourceStringStream << "\t\t_shader = gpu::Shader::create" << shaderCreateString[type] << "(std::string(_source));" << std::endl;
+        sourceStringStream << "\t}" << std::endl;
+        sourceStringStream << "\treturn _shader;" << std::endl;
+        sourceStringStream << "}\n" << std::endl;
 
-    // Destination stream
-    if (!destFilename.empty()) {
-        std::fstream destFileStream;
-        destFileStream.open(destFilename, std::fstream::out);
-        if (!destFileStream.is_open()) {
-            cerr << "Scribe output file " << destFilename << "> failed to open." << endl;
-            return 0;
+        // Destination stream
+        if (!destFilename.empty()) {
+            std::fstream sourceFile;
+            sourceFile.open(sourceFileName, std::fstream::out);
+            if (!sourceFile.is_open()) {
+                cerr << "Scribe output file <" << sourceFileName << "> failed to open." << endl;
+                return 1;
+            }
+            sourceFile << sourceStringStream.str();
+        } else {
+            cerr << sourceStringStream.str();
         }
-        
-        destFileStream << targetStringStream.str();
     } else {
-        cerr << targetStringStream.str();
+        // Destination stream
+        if (!destFilename.empty()) {
+            std::fstream destFileStream;
+            destFileStream.open(destFilename, std::fstream::out);
+            if (!destFileStream.is_open()) {
+                cerr << "Scribe output file <" << destFilename << "> failed to open." << endl;
+                return 1;
+            }
+
+            destFileStream << destStringStream.str();
+        } else {
+            cerr << destStringStream.str();
+        }
     }
 
     return 0;