diff --git a/CMakeLists.txt b/CMakeLists.txt
index d50d7b896d059121030dbea80b9a59c0d4bf9f7c..89e362ad875a2641d6dcebc901ccab9bf21bbfdd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -742,12 +742,18 @@ message("=======================================================================
             SOURCE_FILES
                 strategy/native_forward/native_stereo_forward.vert
                 strategy/native_forward/native_stereo_forward.frag
+                strategy/native_forward/native_stereo_forward_shadow.frag
+                strategy/native_forward/native_stereo_forward_indirect.frag
+                strategy/native_forward/native_stereo_forward_indirect_shadow.frag
 
                 strategy/native_deferred/native_stereo_deferred.vert
                 strategy/native_deferred/native_stereo_deferred.frag
 
                 strategy/multi_view/multi_view_stereo.vert
                 strategy/multi_view/multi_view_stereo.frag
+                strategy/multi_view/multi_view_stereo_shadow.frag
+                strategy/multi_view/multi_view_stereo_indirect.frag
+                strategy/multi_view/multi_view_stereo_indirect_shadow.frag
 
                 strategy/depth_peeling_reprojection/depth_peeling_reprojection_stereo.vert
                 strategy/depth_peeling_reprojection/depth_peeling_reprojection_stereo.geom
diff --git a/res/dpr/strategy/multi_view/multi_view_stereo.frag b/res/dpr/strategy/multi_view/multi_view_stereo.frag
index 9dd9da3b03a32adb155e1f29ab714d25e745c76a..086b6ff281f30ab522c87f02267dabf443241ff7 100644
--- a/res/dpr/strategy/multi_view/multi_view_stereo.frag
+++ b/res/dpr/strategy/multi_view/multi_view_stereo.frag
@@ -4,55 +4,5 @@
 
 #define MATERIAL_DESCRIPTOR_SET 3
 #define LIGHT_DESCRIPTOR_SET 4
-#define SHADOW_DESCRIPTOR_SET 5
-#define INDIRECT_DESCRIPTOR_SET 6
 
-#include "math_library.glsl"
-#include "material_library.glsl"
-#include "light_library.glsl"
-
-#include "per_frame.inc"
-
-layout(location = 0) out vec4 outFragColor;
-
-layout(location = 0) in vec3 inPos;
-layout(location = 1) in vec3 inNormal;
-layout(location = 2) in vec3 inTangent;
-layout(location = 3) in vec2 inUV;
-
-layout(set = 0, binding = 0) uniform LeftFrame 
-{
-    PerFrameData left_frame;
-};
-
-layout(set = 1, binding = 0) uniform RightFrame
-{
-    PerFrameData right_frame;
-};
-
-void main()
-{
-    Material material = lookup_material(inUV);
-    
-    if (material.opacity < EPSILON)
-    {
-        discard;
-    }
-
-    vec3 eye_position = vec3(0.0);
-
-    if (gl_ViewIndex == 0) //Left Eye
-    {
-        eye_position = left_frame.eyePosition;
-    }
-
-    else if (gl_ViewIndex == 1) //Right Eye
-    {
-        eye_position = right_frame.eyePosition;
-    }
-    
-    vec3 normal = lookup_normal(inUV, inNormal, inTangent);
-    vec3 lighting = apply_lighting(eye_position, inPos, normal, material);
-
-    outFragColor = vec4(lighting, 1.0);
-}
+#include "multi_view_stereo_base.glsl"
\ No newline at end of file
diff --git a/res/dpr/strategy/multi_view/multi_view_stereo_base.glsl b/res/dpr/strategy/multi_view/multi_view_stereo_base.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..01cff12117eac9ec1365fc0720bdfde6d35f3509
--- /dev/null
+++ b/res/dpr/strategy/multi_view/multi_view_stereo_base.glsl
@@ -0,0 +1,49 @@
+#include "math_library.glsl"
+#include "material_library.glsl"
+#include "light_library.glsl"
+
+#include "per_frame.inc"
+
+layout(location = 0) out vec4 outFragColor;
+
+layout(location = 0) in vec3 inPos;
+layout(location = 1) in vec3 inNormal;
+layout(location = 2) in vec3 inTangent;
+layout(location = 3) in vec2 inUV;
+
+layout(set = 0, binding = 0) uniform LeftFrame 
+{
+    PerFrameData left_frame;
+};
+
+layout(set = 1, binding = 0) uniform RightFrame
+{
+    PerFrameData right_frame;
+};
+
+void main()
+{
+    Material material = lookup_material(inUV);
+    
+    if (material.opacity < EPSILON)
+    {
+        discard;
+    }
+
+    vec3 eye_position = vec3(0.0);
+
+    if (gl_ViewIndex == 0) //Left Eye
+    {
+        eye_position = left_frame.eyePosition;
+    }
+
+    else if (gl_ViewIndex == 1) //Right Eye
+    {
+        eye_position = right_frame.eyePosition;
+    }
+    
+    vec3 normal = lookup_normal(inUV, inNormal, inTangent);
+    vec3 lighting = apply_lighting(eye_position, inPos, normal, material);
+
+    outFragColor = vec4(lighting, 1.0);
+}
diff --git a/res/dpr/strategy/multi_view/multi_view_stereo_indirect.frag b/res/dpr/strategy/multi_view/multi_view_stereo_indirect.frag
new file mode 100644
index 0000000000000000000000000000000000000000..7a4d1a83681e50bdbc3ea2728e139cfb75c2a349
--- /dev/null
+++ b/res/dpr/strategy/multi_view/multi_view_stereo_indirect.frag
@@ -0,0 +1,9 @@
+#version 450 core
+#extension GL_GOOGLE_include_directive : require
+#extension GL_EXT_multiview : require
+
+#define MATERIAL_DESCRIPTOR_SET 3
+#define LIGHT_DESCRIPTOR_SET 4
+#define INDIRECT_DESCRIPTOR_SET 5
+
+#include "multi_view_stereo_base.glsl"
\ No newline at end of file
diff --git a/res/dpr/strategy/multi_view/multi_view_stereo_indirect_shadow.frag b/res/dpr/strategy/multi_view/multi_view_stereo_indirect_shadow.frag
new file mode 100644
index 0000000000000000000000000000000000000000..5c938628778a5608599e84974dfe1d8dc6c3884f
--- /dev/null
+++ b/res/dpr/strategy/multi_view/multi_view_stereo_indirect_shadow.frag
@@ -0,0 +1,10 @@
+#version 450 core
+#extension GL_GOOGLE_include_directive : require
+#extension GL_EXT_multiview : require
+
+#define MATERIAL_DESCRIPTOR_SET 3
+#define LIGHT_DESCRIPTOR_SET 4
+#define SHADOW_DESCRIPTOR_SET 5
+#define INDIRECT_DESCRIPTOR_SET 6
+
+#include "multi_view_stereo_base.glsl"
\ No newline at end of file
diff --git a/res/dpr/strategy/multi_view/multi_view_stereo_shadow.frag b/res/dpr/strategy/multi_view/multi_view_stereo_shadow.frag
new file mode 100644
index 0000000000000000000000000000000000000000..5cec80462ccd152fc4b5985be4ae038ecc9c4ed4
--- /dev/null
+++ b/res/dpr/strategy/multi_view/multi_view_stereo_shadow.frag
@@ -0,0 +1,9 @@
+#version 450 core
+#extension GL_GOOGLE_include_directive : require
+#extension GL_EXT_multiview : require
+
+#define MATERIAL_DESCRIPTOR_SET 3
+#define LIGHT_DESCRIPTOR_SET 4
+#define SHADOW_DESCRIPTOR_SET 5
+
+#include "multi_view_stereo_base.glsl"
\ No newline at end of file
diff --git a/res/dpr/strategy/native_forward/native_stereo_forward.frag b/res/dpr/strategy/native_forward/native_stereo_forward.frag
index 1245f0d2f37929b9f5255c0f09cc1c3772fc7e4b..2958a87dd5e7b0885cff47d51726ff056c496db7 100644
--- a/res/dpr/strategy/native_forward/native_stereo_forward.frag
+++ b/res/dpr/strategy/native_forward/native_stereo_forward.frag
@@ -3,38 +3,5 @@
 
 #define MATERIAL_DESCRIPTOR_SET 1
 #define LIGHT_DESCRIPTOR_SET 3
-#define SHADOW_DESCRIPTOR_SET 4
-#define INDIRECT_DESCRIPTOR_SET 5
 
-#include "math_library.glsl"
-#include "material_library.glsl"
-#include "light_library.glsl"
-
-#include "per_frame.inc"
-
-layout(location = 0) out vec4 outFragColor;
-
-layout(location = 0) in vec3 inPos;
-layout(location = 1) in vec3 inNormal;
-layout(location = 2) in vec3 inTangent;
-layout(location = 3) in vec2 inUV;
-
-layout(set = 0, binding = 0) uniform Frame
-{
-    PerFrameData frame;
-};
-
-void main()
-{
-    Material material = lookup_material(inUV);
-    
-    if (material.opacity < EPSILON)
-    {
-        discard;
-    }
-    
-    vec3 normal = lookup_normal(inUV, inNormal, inTangent);
-    vec3 lighting = apply_lighting(frame.eyePosition, inPos, normal, material);
-
-    outFragColor = vec4(lighting, 1.0);
-}
+#include "native_stereo_forward_base.glsl"
\ No newline at end of file
diff --git a/res/dpr/strategy/native_forward/native_stereo_forward_base.glsl b/res/dpr/strategy/native_forward/native_stereo_forward_base.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..703e60828f2f755606460d0e49425b749ddb555b
--- /dev/null
+++ b/res/dpr/strategy/native_forward/native_stereo_forward_base.glsl
@@ -0,0 +1,32 @@
+#include "math_library.glsl"
+#include "material_library.glsl"
+#include "light_library.glsl"
+
+#include "per_frame.inc"
+
+layout(location = 0) out vec4 outFragColor;
+
+layout(location = 0) in vec3 inPos;
+layout(location = 1) in vec3 inNormal;
+layout(location = 2) in vec3 inTangent;
+layout(location = 3) in vec2 inUV;
+
+layout(set = 0, binding = 0) uniform Frame
+{
+    PerFrameData frame;
+};
+
+void main()
+{
+    Material material = lookup_material(inUV);
+    
+    if (material.opacity < EPSILON)
+    {
+        discard;
+    }
+    
+    vec3 normal = lookup_normal(inUV, inNormal, inTangent);
+    vec3 lighting = apply_lighting(frame.eyePosition, inPos, normal, material);
+
+    outFragColor = vec4(lighting, 1.0);
+}
diff --git a/res/dpr/strategy/native_forward/native_stereo_forward_indirect.frag b/res/dpr/strategy/native_forward/native_stereo_forward_indirect.frag
new file mode 100644
index 0000000000000000000000000000000000000000..adf9e9b61704a79699d452c7f48e880fa9e5c1c5
--- /dev/null
+++ b/res/dpr/strategy/native_forward/native_stereo_forward_indirect.frag
@@ -0,0 +1,8 @@
+#version 450 core
+#extension GL_GOOGLE_include_directive : require
+
+#define MATERIAL_DESCRIPTOR_SET 1
+#define LIGHT_DESCRIPTOR_SET 3
+#define INDIRECT_DESCRIPTOR_SET 4
+
+#include "native_stereo_forward_base.glsl"
\ No newline at end of file
diff --git a/res/dpr/strategy/native_forward/native_stereo_forward_indirect_shadow.frag b/res/dpr/strategy/native_forward/native_stereo_forward_indirect_shadow.frag
new file mode 100644
index 0000000000000000000000000000000000000000..52d863f34d2ff031a283bee24d6f181e073a8403
--- /dev/null
+++ b/res/dpr/strategy/native_forward/native_stereo_forward_indirect_shadow.frag
@@ -0,0 +1,9 @@
+#version 450 core
+#extension GL_GOOGLE_include_directive : require
+
+#define MATERIAL_DESCRIPTOR_SET 1
+#define LIGHT_DESCRIPTOR_SET 3
+#define SHADOW_DESCRIPTOR_SET 4
+#define INDIRECT_DESCRIPTOR_SET 5
+
+#include "native_stereo_forward_base.glsl"
\ No newline at end of file
diff --git a/res/dpr/strategy/native_forward/native_stereo_forward_shadow.frag b/res/dpr/strategy/native_forward/native_stereo_forward_shadow.frag
new file mode 100644
index 0000000000000000000000000000000000000000..c57004b06c34ca2c150218b7eb1de5542cdcbde1
--- /dev/null
+++ b/res/dpr/strategy/native_forward/native_stereo_forward_shadow.frag
@@ -0,0 +1,8 @@
+#version 450 core
+#extension GL_GOOGLE_include_directive : require
+
+#define MATERIAL_DESCRIPTOR_SET 1
+#define LIGHT_DESCRIPTOR_SET 3
+#define SHADOW_DESCRIPTOR_SET 4
+
+#include "native_stereo_forward_base.glsl"
\ No newline at end of file
diff --git a/src/strategy/multi_view_stereo.cpp b/src/strategy/multi_view_stereo.cpp
index b76e3cac147880251e1dc4dbece269d0b49f6182..ba8d00736ad19032c089bfcbc6a8f85a25c9a82c 100644
--- a/src/strategy/multi_view_stereo.cpp
+++ b/src/strategy/multi_view_stereo.cpp
@@ -78,9 +78,14 @@ bool MultiViewStereo::on_render(VkCommandBuffer command_buffer, lava::index fram
     std::array<uint8_t, 1> metadata = { 0x00 };
     this->get_headset()->submit_metadata(metadata);
 
-    this->get_pass_timer()->begin_pass(command_buffer, "shadow");
-    this->get_application()->get_shadow_cache()->compute_shadow(command_buffer, frame);
-    this->get_pass_timer()->end_pass(command_buffer);
+    ShadowCache::Ptr shadow_cache = this->get_application()->get_shadow_cache();
+
+    if (shadow_cache != nullptr)
+    {
+        this->get_pass_timer()->begin_pass(command_buffer, "shadow");
+        shadow_cache->compute_shadow(command_buffer, frame);
+        this->get_pass_timer()->end_pass(command_buffer);
+    }
 
     this->get_pass_timer()->begin_pass(command_buffer, "multi_eye");
     this->render_pass->process(command_buffer, 0);
@@ -109,15 +114,26 @@ const char* MultiViewStereo::get_name() const
 
 bool MultiViewStereo::create_pipeline_layout()
 {
+    ShadowCache::Ptr shadow_cache = this->get_application()->get_shadow_cache();
+    IndirectCache::Ptr indirect_cache = this->get_application()->get_indirect_cache();
+
     this->pipeline_layout = lava::make_pipeline_layout();
     this->pipeline_layout->add(this->get_stereo_transform()->get_descriptor());
     this->pipeline_layout->add(this->get_stereo_transform()->get_descriptor());
     this->pipeline_layout->add(this->get_scene()->get_mesh_descriptor());
     this->pipeline_layout->add(this->get_scene()->get_material_descriptor());
     this->pipeline_layout->add(this->get_scene()->get_light_descriptor());
-    this->pipeline_layout->add(this->get_application()->get_shadow_cache()->get_descriptor());
-    this->pipeline_layout->add(this->get_application()->get_indirect_cache()->get_descriptor());
     
+    if (shadow_cache != nullptr)
+    {
+        this->pipeline_layout->add(shadow_cache->get_descriptor());    
+    }
+    
+    if (indirect_cache != nullptr)
+    {
+        this->pipeline_layout->add(indirect_cache->get_descriptor());
+    }
+
     if (!this->pipeline_layout->create(this->get_device()))
     {
         lava::log()->error("Can't create pipeline layout for multi-view stereo!");
@@ -229,6 +245,9 @@ bool MultiViewStereo::create_render_pass()
 
 bool MultiViewStereo::create_pipeline()
 {
+    ShadowCache::Ptr shadow_cache = this->get_application()->get_shadow_cache();
+    IndirectCache::Ptr indirect_cache = this->get_application()->get_indirect_cache();
+
     VkPipelineColorBlendAttachmentState blend_state;
     blend_state.blendEnable = VK_FALSE;
     blend_state.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO;
@@ -255,7 +274,21 @@ bool MultiViewStereo::create_pipeline()
         return false;
     }
 
-    if (!this->pipeline->add_shader(lava::file_data("dpr/binary/multi_view_stereo_fragment.spirv"), VK_SHADER_STAGE_FRAGMENT_BIT))
+    std::string shader_name = "dpr/binary/multi_view_stereo";
+
+    if (indirect_cache != nullptr)
+    {
+        shader_name += "_indirect";
+    }
+
+    if (shadow_cache != nullptr)
+    {
+        shader_name += "_shadow";
+    }
+
+    shader_name += "_fragment.spirv";
+
+    if (!this->pipeline->add_shader(lava::file_data(shader_name), VK_SHADER_STAGE_FRAGMENT_BIT))
     {
         lava::log()->error("Can't load fragment shader for multi-view stereo!");
 
@@ -281,13 +314,29 @@ bool MultiViewStereo::create_pipeline()
 
 void MultiViewStereo::pipeline_function(VkCommandBuffer command_buffer)
 {
+    ShadowCache::Ptr shadow_cache = this->get_application()->get_shadow_cache();
+    IndirectCache::Ptr indirect_cache = this->get_application()->get_indirect_cache();
     uint32_t frame_index = this->get_application()->get_frame_index();
 
     this->pipeline_layout->bind(command_buffer, this->get_stereo_transform()->get_descriptor_set(EYE_LEFT, frame_index), 0);
     this->pipeline_layout->bind(command_buffer, this->get_stereo_transform()->get_descriptor_set(EYE_RIGHT, frame_index), 1);
     this->pipeline_layout->bind(command_buffer, this->get_scene()->get_light_descriptor_set(frame_index), 4);
-    this->pipeline_layout->bind(command_buffer, this->get_application()->get_shadow_cache()->get_descriptor_set(), 5);
-    this->pipeline_layout->bind(command_buffer, this->get_application()->get_indirect_cache()->get_descriptor_set(), 6);
+    
+    if (shadow_cache != nullptr && indirect_cache != nullptr)
+    {
+        this->pipeline_layout->bind(command_buffer, shadow_cache->get_descriptor_set(), 5);
+        this->pipeline_layout->bind(command_buffer, indirect_cache->get_descriptor_set(), 6);
+    }
+
+    else if (shadow_cache != nullptr)
+    {
+        this->pipeline_layout->bind(command_buffer, shadow_cache->get_descriptor_set(), 5);
+    }
+
+    else if (indirect_cache != nullptr)
+    {
+        this->pipeline_layout->bind(command_buffer, indirect_cache->get_descriptor_set(), 5);
+    }
 
     const std::vector<SceneMaterial>& materials = this->get_scene()->get_materials();
 
diff --git a/src/strategy/native_stereo_deferred.cpp b/src/strategy/native_stereo_deferred.cpp
index 37be5aa60c0d1ea2c4b61a8f2722a1500250b041..179a7fbb2a5ee6c1b20563189769e71e5b76f497 100644
--- a/src/strategy/native_stereo_deferred.cpp
+++ b/src/strategy/native_stereo_deferred.cpp
@@ -72,9 +72,14 @@ bool NativeStereoDeferred::on_render(VkCommandBuffer command_buffer, lava::index
     std::array<uint8_t, 1> metadata = { 0x00 };
     this->get_headset()->submit_metadata(metadata);
 
-    this->get_pass_timer()->begin_pass(command_buffer, "shadow");
-    this->get_application()->get_shadow_cache()->compute_shadow(command_buffer, frame);
-    this->get_pass_timer()->end_pass(command_buffer);
+    ShadowCache::Ptr shadow_cache = this->get_application()->get_shadow_cache();
+
+    if (shadow_cache != nullptr)
+    {
+        this->get_pass_timer()->begin_pass(command_buffer, "shadow");
+        shadow_cache->compute_shadow(command_buffer, frame);
+        this->get_pass_timer()->end_pass(command_buffer);
+    }
 
     this->get_pass_timer()->begin_pass(command_buffer, "left_eye");
     this->eye_passes[0].render_pass->process(command_buffer, 0);
diff --git a/src/strategy/native_stereo_forward.cpp b/src/strategy/native_stereo_forward.cpp
index bbe14e4ed302bf212671ec3bbfea836ac518e82b..df6cfad1146a9f930e2ac0e69e1107b9e3abd359 100644
--- a/src/strategy/native_stereo_forward.cpp
+++ b/src/strategy/native_stereo_forward.cpp
@@ -72,9 +72,14 @@ bool NativeStereoForward::on_render(VkCommandBuffer command_buffer, lava::index
     std::array<uint8_t, 1> metadata = { 0x00 };
     this->get_headset()->submit_metadata(metadata);
 
-    this->get_pass_timer()->begin_pass(command_buffer, "shadow");
-    this->get_application()->get_shadow_cache()->compute_shadow(command_buffer, frame);
-    this->get_pass_timer()->end_pass(command_buffer);
+    ShadowCache::Ptr shadow_cache = this->get_application()->get_shadow_cache();
+
+    if (shadow_cache != nullptr)
+    {
+        this->get_pass_timer()->begin_pass(command_buffer, "shadow");
+        shadow_cache->compute_shadow(command_buffer, frame);
+        this->get_pass_timer()->end_pass(command_buffer);
+    }
 
     this->get_pass_timer()->begin_pass(command_buffer, "left_eye");
     this->eye_passes[0].render_pass->process(command_buffer, 0);
@@ -107,13 +112,24 @@ const char* NativeStereoForward::get_name() const
 
 bool NativeStereoForward::create_pipeline_layout()
 {
+    ShadowCache::Ptr shadow_cache = this->get_application()->get_shadow_cache();
+    IndirectCache::Ptr indirect_cache = this->get_application()->get_indirect_cache();
+
     this->pipeline_layout = lava::make_pipeline_layout();
     this->pipeline_layout->add(this->get_stereo_transform()->get_descriptor());
     this->pipeline_layout->add(this->get_scene()->get_material_descriptor());
     this->pipeline_layout->add(this->get_scene()->get_mesh_descriptor());
     this->pipeline_layout->add(this->get_scene()->get_light_descriptor());
-    this->pipeline_layout->add(this->get_application()->get_shadow_cache()->get_descriptor());
-    this->pipeline_layout->add(this->get_application()->get_indirect_cache()->get_descriptor());
+
+    if (shadow_cache != nullptr)
+    {
+        this->pipeline_layout->add(shadow_cache->get_descriptor());    
+    }
+    
+    if (indirect_cache != nullptr)
+    {
+        this->pipeline_layout->add(indirect_cache->get_descriptor());
+    }
     
     if (!this->pipeline_layout->create(this->get_device()))
     {
@@ -215,6 +231,9 @@ bool NativeStereoForward::create_render_pass(Eye eye)
 
 bool NativeStereoForward::create_pipeline(Eye eye)
 {
+    ShadowCache::Ptr shadow_cache = this->get_application()->get_shadow_cache();
+    IndirectCache::Ptr indirect_cache = this->get_application()->get_indirect_cache();
+
     VkPipelineColorBlendAttachmentState blend_state;
     blend_state.blendEnable = VK_FALSE;
     blend_state.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO;
@@ -241,7 +260,21 @@ bool NativeStereoForward::create_pipeline(Eye eye)
         return false;
     }
 
-    if (!pipeline->add_shader(lava::file_data("dpr/binary/native_stereo_forward_fragment.spirv"), VK_SHADER_STAGE_FRAGMENT_BIT))
+    std::string shader_name = "dpr/binary/native_stereo_forward";
+
+    if (indirect_cache != nullptr)
+    {
+        shader_name += "_indirect";
+    }
+
+    if (shadow_cache != nullptr)
+    {
+        shader_name += "_shadow";
+    }
+
+    shader_name += "_fragment.spirv";
+
+    if (!pipeline->add_shader(lava::file_data(shader_name), VK_SHADER_STAGE_FRAGMENT_BIT))
     {
         lava::log()->error("Can't load fragment shader for native stereo forward!");
 
@@ -270,12 +303,28 @@ bool NativeStereoForward::create_pipeline(Eye eye)
 
 void NativeStereoForward::pipeline_function(VkCommandBuffer command_buffer, Eye eye)
 {
+    ShadowCache::Ptr shadow_cache = this->get_application()->get_shadow_cache();
+    IndirectCache::Ptr indirect_cache = this->get_application()->get_indirect_cache();
     uint32_t frame_index = this->get_application()->get_frame_index();
 
     this->pipeline_layout->bind(command_buffer, this->get_stereo_transform()->get_descriptor_set(eye, frame_index), 0);
     this->pipeline_layout->bind(command_buffer, this->get_scene()->get_light_descriptor_set(frame_index), 3);
-    this->pipeline_layout->bind(command_buffer, this->get_application()->get_shadow_cache()->get_descriptor_set(), 4);
-    this->pipeline_layout->bind(command_buffer, this->get_application()->get_indirect_cache()->get_descriptor_set(), 5);
+
+    if (shadow_cache != nullptr && indirect_cache != nullptr)
+    {
+        this->pipeline_layout->bind(command_buffer, shadow_cache->get_descriptor_set(), 4);
+        this->pipeline_layout->bind(command_buffer, indirect_cache->get_descriptor_set(), 5);
+    }
+
+    else if (shadow_cache != nullptr)
+    {
+        this->pipeline_layout->bind(command_buffer, shadow_cache->get_descriptor_set(), 4);
+    }
+
+    else if (indirect_cache != nullptr)
+    {
+        this->pipeline_layout->bind(command_buffer, indirect_cache->get_descriptor_set(), 4);
+    }
 
     const std::vector<SceneMaterial>& materials = this->get_scene()->get_materials();
 
diff --git a/src/utility/command_parser.cpp b/src/utility/command_parser.cpp
index 7face99e7d314b897cbc2f20175d51b17f0d49ba..a46039b5ad61ded1dd17d0f651eb5a01004f19ce 100644
--- a/src/utility/command_parser.cpp
+++ b/src/utility/command_parser.cpp
@@ -20,6 +20,16 @@ bool CommandParser::parse_command(const argh::parser& cmd_line)
             this->write_frames = true;
         }
 
+        else if (flag == "disable-indirect-lighting")
+        {
+            this->disable_indirect_lighting = true;
+        }
+
+        else if (flag == "disable-shadows")
+        {
+            this->disable_shadows = true;
+        }
+
         else if (flag == "help")
         {
             this->show_help();
@@ -294,6 +304,16 @@ bool CommandParser::should_write_frames() const
     return this->write_frames;
 }
 
+bool CommandParser::should_disable_indirect_lighting() const
+{
+    return this->disable_indirect_lighting;
+}
+
+bool CommandParser::should_disbale_shadows() const
+{
+    return this->disable_shadows;
+}
+
 void CommandParser::show_help()
 {
     std::cout << "Usage:" << std::endl;
@@ -328,6 +348,8 @@ void CommandParser::show_help()
     std::cout << "   --show-companion-window              Show companion window. If not set, writes to the companion window are ignored." << std::endl;
     std::cout << "   --write-frames                       Write frames to files. If not set, frames will not be written to files." << std::endl;
     std::cout << "                                        This parameter is only allowed during a benchmark." << std::endl;
+    std::cout << "   --disable-indirect-lighting          Disable indirect lighting and the allocation and computation of an indirect light cache." << std::endl;
+    std::cout << "   --disable-shadows                    Disable shadows and the allocation and computation of shadow maps." << std::endl;
     std::cout << "   --help                               Show help information." << std::endl;
 }
 
diff --git a/src/utility/command_parser.hpp b/src/utility/command_parser.hpp
index 9d8759d80e93d8cd37b7e1dcd30219af743f9709..774547607bb5a8b38f4e87c5130fc4f52575e4f6 100644
--- a/src/utility/command_parser.hpp
+++ b/src/utility/command_parser.hpp
@@ -41,6 +41,8 @@ public:
     bool should_benchmark() const;
     bool should_show_companion_window() const;
     bool should_write_frames() const;
+    bool should_disable_indirect_lighting() const;
+    bool should_disbale_shadows() const;
 
 private:
     void show_help();
@@ -72,4 +74,6 @@ private:
     bool benchmark = false;
     bool show_companion_window = false;
     bool write_frames = false;
+    bool disable_indirect_lighting = false;
+    bool disable_shadows = false;
 };
\ No newline at end of file
diff --git a/src/utility/geometry_buffer.cpp b/src/utility/geometry_buffer.cpp
index 27ff69206ced121be6a6f4d0eadbfdc4d893bfb7..313446d364beaa37ca9008449367f91deee9ed72 100644
--- a/src/utility/geometry_buffer.cpp
+++ b/src/utility/geometry_buffer.cpp
@@ -573,7 +573,7 @@ void GeometryBuffer::pipline_function(VkCommandBuffer command_buffer)
 
     else if (this->indirect_cache != nullptr)
     {
-        this->pipeline_layout->bind(command_buffer, this->indirect_cache->get_descriptor_set(), 4);
+        this->pipeline_layout->bind(command_buffer, this->indirect_cache->get_descriptor_set(), 3);
     }
 
     vkCmdDraw(command_buffer, 4, 1, 0, 0); //draw fullscreen quad
diff --git a/src/vr_application.cpp b/src/vr_application.cpp
index 9168aac7514a2520dc22885687df900a6e7146aa..ffb8fa3e3ea3660081476ae5509ad2888f459d26 100644
--- a/src/vr_application.cpp
+++ b/src/vr_application.cpp
@@ -444,22 +444,28 @@ bool VRApplication::on_create()
         return false;
     }
 
-    this->shadow_cache = make_shadow_cache();
-
-    if (!this->shadow_cache->create(this->scene, ShadowCacheSettings()))
+    if (!this->command_parser.should_disbale_shadows())
     {
-        lava::log()->error("Can't create shadow cache!");
+        this->shadow_cache = make_shadow_cache();
 
-        return false;
-    }
+        if (!this->shadow_cache->create(this->scene, ShadowCacheSettings()))
+        {
+            lava::log()->error("Can't create shadow cache!");
 
-    this->indirect_cache = make_indirect_cache();
+            return false;
+        }
+    }
 
-    if (!this->indirect_cache->create(this->scene, IndirectCacheSettings()))
+    if (!this->command_parser.should_disable_indirect_lighting())
     {
-        lava::log()->error("Can't create indirect cache!");
+        this->indirect_cache = make_indirect_cache();
 
-        return false;
+        if (!this->indirect_cache->create(this->scene, IndirectCacheSettings()))
+        {
+            lava::log()->error("Can't create indirect cache!");
+
+            return false;
+        }
     }
 
     return this->create_config();
@@ -704,9 +710,16 @@ bool VRApplication::on_render(VkCommandBuffer command_buffer, lava::index frame)
 
     if (!this->cache_filled)
     {
-        this->shadow_cache->compute_shadow(command_buffer, frame);
-        this->indirect_cache->compute_indirect(command_buffer, frame);
+        if (this->shadow_cache != nullptr)
+        {
+            this->shadow_cache->compute_shadow(command_buffer, frame);
+        }
 
+        if (this->indirect_cache != nullptr)
+        {
+            this->indirect_cache->compute_indirect(command_buffer, frame);
+        }
+        
         this->cache_filled = true;
     }
 
diff --git a/src/vr_application.hpp b/src/vr_application.hpp
index 63cccf9163b9cb41c4dc0877d6c632297bd146da..5735831a51f941e91b4679e4d1785cd3dd8e3491 100644
--- a/src/vr_application.hpp
+++ b/src/vr_application.hpp
@@ -43,8 +43,8 @@ public:
     FrameCapture::Ptr get_frame_capture() const;
     StereoTransform::Ptr get_stereo_transform() const;
 
-    ShadowCache::Ptr get_shadow_cache() const;
-    IndirectCache::Ptr get_indirect_cache() const;
+    ShadowCache::Ptr get_shadow_cache() const;          //NOTE: If shadow is disabled, nullptr is returned
+    IndirectCache::Ptr get_indirect_cache() const;      //NOTE: If indirect lighting is disabled, nullptr is returned
 
     StatisticLog::Ptr get_statistic_log() const;