diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,16 @@
 # Changelog for keid-render-basic
 
+## 0.1.4.0
+
+Update to match `keid-core-0.1.4.0`.
+
+- Changed `allocatePipelines` to use `msaa` directly.
+  (`allocatePipelines_` remains unchanged.)
+- Fixed litMain check for missing shadowmap.
+- Relaxed `Set0.allocate`, `Set0.allocateEmpty` to any `MonadVulkan` under `ResourceT`.
+- Added pipeline config exports.
+- Added shared pipeline params to collection.
+
 ## 0.1.3.0
 
 - Replaced RIO in resource loaders with constraints.
diff --git a/keid-render-basic.cabal b/keid-render-basic.cabal
--- a/keid-render-basic.cabal
+++ b/keid-render-basic.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           keid-render-basic
-version:        0.1.3.0
+version:        0.1.4.0
 synopsis:       Basic rendering programs for Keid engine.
 category:       Game Engine
 author:         IC Rainbow
@@ -139,7 +139,7 @@
     , distributive
     , file-embed >=0.0.10
     , geomancy
-    , keid-core >=0.1.2.0
+    , keid-core >=0.1.4.0
     , keid-geometry
     , neat-interpolation
     , resourcet
diff --git a/src/Render/Basic.hs b/src/Render/Basic.hs
--- a/src/Render/Basic.hs
+++ b/src/Render/Basic.hs
@@ -13,10 +13,11 @@
 
 -- keid-core
 
-import Engine.Types qualified as Engine
 import Engine.Types (StageRIO)
+import Engine.Types qualified as Engine
 import Engine.Vulkan.Pipeline qualified as Pipeline
-import Engine.Vulkan.Types (DsBindings, HasSwapchain(getMultisample), RenderPass(..))
+import Engine.Vulkan.Swapchain qualified as Swapchain
+import Engine.Vulkan.Types (DsBindings, HasSwapchain, RenderPass(..))
 
 -- keid-render-basic
 
@@ -69,7 +70,10 @@
     refcountRenderpass rpShadowPass
 
 data Pipelines = Pipelines
-  { pEvanwSdf :: EvanwSdf.Pipeline
+  { pMSAA       :: Vk.SampleCountFlagBits
+  , pSceneBinds :: Tagged Scene DsBindings
+
+  , pEvanwSdf :: EvanwSdf.Pipeline
   , pSkybox   :: Skybox.Pipeline
   , pDebug    :: Debug.Pipeline
 
@@ -96,38 +100,37 @@
   -> RenderPasses
   -> ResourceT (StageRIO st) Pipelines
 allocatePipelines_ swapchain renderpasses = do
-  (_, samplers) <- Samplers.allocate swapchain
+  (_, samplers) <- Samplers.allocate
+    (Swapchain.getAnisotropy swapchain)
+
   allocatePipelines
     (Scene.mkBindings samplers Nothing Nothing 0)
-    swapchain
+    (Swapchain.getMultisample swapchain)
     renderpasses
 
 allocatePipelines
-  :: HasSwapchain swapchain
-  => Tagged Scene DsBindings
-  -> swapchain
+  :: Tagged Scene DsBindings
+  -> Vk.SampleCountFlagBits
   -> RenderPasses
   -> ResourceT (StageRIO st) Pipelines
-allocatePipelines sceneBinds swapchain RenderPasses{..} = do
-  let msaa = getMultisample swapchain
-
-  pDebug    <- Debug.allocate msaa sceneBinds rpForwardMsaa
-  pEvanwSdf <- EvanwSdf.allocate msaa sceneBinds rpForwardMsaa
-  pSkybox   <- Skybox.allocate msaa sceneBinds rpForwardMsaa
+allocatePipelines pSceneBinds pMSAA RenderPasses{..} = do
+  pDebug    <- Debug.allocate pMSAA pSceneBinds rpForwardMsaa
+  pEvanwSdf <- EvanwSdf.allocate pMSAA pSceneBinds rpForwardMsaa
+  pSkybox   <- Skybox.allocate pMSAA pSceneBinds rpForwardMsaa
 
-  pLitColored       <- LitColored.allocate msaa sceneBinds rpForwardMsaa
-  pLitColoredBlend  <- LitColored.allocateBlend msaa sceneBinds rpForwardMsaa
-  pLitMaterial      <- LitMaterial.allocate msaa sceneBinds rpForwardMsaa
-  pLitMaterialBlend <- LitMaterial.allocateBlend msaa sceneBinds rpForwardMsaa
-  pLitTextured      <- LitTextured.allocate msaa sceneBinds rpForwardMsaa
-  pLitTexturedBlend <- LitTextured.allocateBlend msaa sceneBinds rpForwardMsaa
+  pLitColored       <- LitColored.allocate pMSAA pSceneBinds rpForwardMsaa
+  pLitColoredBlend  <- LitColored.allocateBlend pMSAA pSceneBinds rpForwardMsaa
+  pLitMaterial      <- LitMaterial.allocate pMSAA pSceneBinds rpForwardMsaa
+  pLitMaterialBlend <- LitMaterial.allocateBlend pMSAA pSceneBinds rpForwardMsaa
+  pLitTextured      <- LitTextured.allocate pMSAA pSceneBinds rpForwardMsaa
+  pLitTexturedBlend <- LitTextured.allocateBlend pMSAA pSceneBinds rpForwardMsaa
 
-  pUnlitColored        <- UnlitColored.allocate True msaa sceneBinds rpForwardMsaa
-  pUnlitColoredNoDepth <- UnlitColored.allocate False msaa sceneBinds rpForwardMsaa
-  pUnlitTextured       <- UnlitTextured.allocate msaa sceneBinds rpForwardMsaa
-  pUnlitTexturedBlend  <- UnlitTextured.allocateBlend msaa sceneBinds rpForwardMsaa
-  pWireframe           <- UnlitColored.allocateWireframe True msaa sceneBinds rpForwardMsaa
-  pWireframeNoDepth    <- UnlitColored.allocateWireframe False msaa sceneBinds rpForwardMsaa
+  pUnlitColored        <- UnlitColored.allocate True pMSAA pSceneBinds rpForwardMsaa
+  pUnlitColoredNoDepth <- UnlitColored.allocate False pMSAA pSceneBinds rpForwardMsaa
+  pUnlitTextured       <- UnlitTextured.allocate pMSAA pSceneBinds rpForwardMsaa
+  pUnlitTexturedBlend  <- UnlitTextured.allocateBlend pMSAA pSceneBinds rpForwardMsaa
+  pWireframe           <- UnlitColored.allocateWireframe True pMSAA pSceneBinds rpForwardMsaa
+  pWireframeNoDepth    <- UnlitColored.allocateWireframe False pMSAA pSceneBinds rpForwardMsaa
 
   let sunBinds = Sun.set0
   pShadowCast <- ShadowPipe.allocate sunBinds rpShadowPass ShadowPipe.defaults
diff --git a/src/Render/Code/Lit.hs b/src/Render/Code/Lit.hs
--- a/src/Render/Code/Lit.hs
+++ b/src/Render/Code/Lit.hs
@@ -141,7 +141,7 @@
       vec3 lightDir = normalize(lights[l].direction.xyz); // L
 
       float shade = 1.0; // XXX: 0 - occluded, 1 - lit
-      if (lights[l].shadow.w > 0) {
+      if (lights[l].shadow.z > 0) {
         vec4 light_space_pos = lights[l].viewProjection * fPosition;
         vec4 shadowCoord = light_space_pos /= light_space_pos.w;
 
diff --git a/src/Render/DescSets/Set0.hs b/src/Render/DescSets/Set0.hs
--- a/src/Render/DescSets/Set0.hs
+++ b/src/Render/DescSets/Set0.hs
@@ -45,11 +45,10 @@
 import Vulkan.Utils.Debug qualified as Debug
 import Vulkan.Zero (Zero(..))
 
-import Engine.Types (StageRIO)
 import Engine.Vulkan.DescSets (Bound, Extend, extendDS, withBoundDescriptorSets0)
 import Engine.Vulkan.Pipeline (Pipeline)
 import Engine.Vulkan.Pipeline qualified as Pipeline
-import Engine.Vulkan.Types (DsBindings, HasVulkan(..))
+import Engine.Vulkan.Types (DsBindings, MonadVulkan, HasVulkan(..))
 import Engine.Worker qualified as Worker
 import Global.Resource.CubeMap.Base qualified as BaseCubeMap
 import Global.Resource.Texture.Base qualified as BaseTexture
@@ -240,14 +239,17 @@
 -- * Setup
 
 allocate
-  :: (Traversable textures, Traversable cubes)
+  :: ( Traversable textures
+     , Traversable cubes
+     , MonadVulkan env m
+     )
   => Tagged '[Scene] Vk.DescriptorSetLayout
   -> textures (Texture.Texture Texture.Flat)
   -> cubes (Texture.Texture Texture.CubeMap)
   -> Maybe (Buffer.Allocated 'Buffer.Coherent Sun)
   -> "shadow maps" ::: Vector Vk.ImageView
   -> Maybe (Buffer.Allocated 'Buffer.Coherent Material)
-  -> ResourceT (StageRIO st) (FrameResource '[Scene])
+  -> ResourceT m (FrameResource '[Scene])
 allocate (Tagged set0layout) textures cubes lightsData shadowViews materialsData = do
   context <- asks id
 
@@ -317,12 +319,18 @@
 
 -- | Minimal viable 'Scene' without textures and lighting.
 allocateEmpty
-  :: Tagged '[Scene] Vk.DescriptorSetLayout
-  -> ResourceT (StageRIO st) (FrameResource '[Scene])
-allocateEmpty taggedLayout = allocate taggedLayout [] [] Nothing mempty Nothing
+  :: MonadVulkan env m
+  => Tagged '[Scene] Vk.DescriptorSetLayout
+  -> ResourceT m (FrameResource '[Scene])
+allocateEmpty taggedLayout =
+  allocate taggedLayout [] [] Nothing mempty Nothing
 
 updateSet0Ds
-  :: (HasVulkan context, Traversable textures, Traversable cubes)
+  :: ( HasVulkan context
+     , Traversable textures
+     , Traversable cubes
+     , MonadIO m
+     )
   => context
   -> Tagged '[Scene] (Vector Vk.DescriptorSet)
   -> Buffer.Allocated 'Buffer.Coherent Scene
@@ -331,7 +339,7 @@
   -> Maybe (Buffer.Allocated 'Buffer.Coherent Sun)
   -> Vector (Vk.Sampler, Vk.ImageView)
   -> Maybe (Buffer.Allocated 'Buffer.Coherent Material)
-  -> ResourceT (StageRIO st) ()
+  -> m ()
 updateSet0Ds context (Tagged ds) sceneData textures cubes lightsData shadowMaps materialsData =
   Vk.updateDescriptorSets (getDevice context) writeSets mempty
 
@@ -504,10 +512,9 @@
   -> Vk.CommandBuffer
   -> Bound ds Void Void m b
   -> m b
-withBoundSet0 FrameResource{frDescSets} refPipeline cb action =
+withBoundSet0 FrameResource{frDescSets} refPipeline cb =
   withBoundDescriptorSets0
     cb
     Vk.PIPELINE_BIND_POINT_GRAPHICS
     (Pipeline.pLayout refPipeline)
     frDescSets
-    action
diff --git a/src/Render/Lit/Colored/Pipeline.hs b/src/Render/Lit/Colored/Pipeline.hs
--- a/src/Render/Lit/Colored/Pipeline.hs
+++ b/src/Render/Lit/Colored/Pipeline.hs
@@ -2,6 +2,10 @@
   ( Pipeline
   , allocate
   , allocateBlend
+
+  , Config
+  , config
+  , configBlend
   ) where
 
 import RIO
diff --git a/src/Render/Lit/Material/Pipeline.hs b/src/Render/Lit/Material/Pipeline.hs
--- a/src/Render/Lit/Material/Pipeline.hs
+++ b/src/Render/Lit/Material/Pipeline.hs
@@ -2,6 +2,10 @@
   ( Pipeline
   , allocate
   , allocateBlend
+
+  , Config
+  , config
+  , configBlend
   ) where
 
 import RIO
diff --git a/src/Render/Lit/Textured/Pipeline.hs b/src/Render/Lit/Textured/Pipeline.hs
--- a/src/Render/Lit/Textured/Pipeline.hs
+++ b/src/Render/Lit/Textured/Pipeline.hs
@@ -2,6 +2,10 @@
   ( Pipeline
   , allocate
   , allocateBlend
+
+  , Config
+  , config
+  , configBlend
   ) where
 
 import RIO
diff --git a/src/Render/ShadowMap/Pipeline.hs b/src/Render/ShadowMap/Pipeline.hs
--- a/src/Render/ShadowMap/Pipeline.hs
+++ b/src/Render/ShadowMap/Pipeline.hs
@@ -1,8 +1,12 @@
 module Render.ShadowMap.Pipeline
-  ( Pipeline
-  , allocate
-  , Settings(..)
+  ( Settings(..)
   , defaults
+
+  , Pipeline
+  , allocate
+
+  , Config
+  , config
   ) where
 
 import RIO
diff --git a/src/Render/Unlit/Colored/Pipeline.hs b/src/Render/Unlit/Colored/Pipeline.hs
--- a/src/Render/Unlit/Colored/Pipeline.hs
+++ b/src/Render/Unlit/Colored/Pipeline.hs
@@ -2,6 +2,10 @@
   ( Pipeline
   , allocate
   , allocateWireframe
+
+  , Config
+  , config
+  , configWireframe
   ) where
 
 import RIO
diff --git a/src/Render/Unlit/Textured/Pipeline.hs b/src/Render/Unlit/Textured/Pipeline.hs
--- a/src/Render/Unlit/Textured/Pipeline.hs
+++ b/src/Render/Unlit/Textured/Pipeline.hs
@@ -2,6 +2,10 @@
   ( Pipeline
   , allocate
   , allocateBlend
+
+  , Config
+  , config
+  , configBlend
   ) where
 
 import RIO
diff --git a/src/Stage/Loader/Setup.hs b/src/Stage/Loader/Setup.hs
--- a/src/Stage/Loader/Setup.hs
+++ b/src/Stage/Loader/Setup.hs
@@ -13,6 +13,7 @@
 import Engine.Types qualified as Engine
 import Engine.UI.Layout qualified as Layout
 import Engine.UI.Message qualified as Message
+import Engine.Vulkan.Swapchain qualified as Swapchain
 import Engine.Vulkan.Types (Queues)
 import Engine.Worker qualified as Worker
 import Geometry.Quad qualified as Quad
@@ -134,8 +135,12 @@
   where
     allocatePipelines swapchain rps = do
       logDebug "Allocating loader pipelines"
-      (_, samplers) <- Samplers.allocate swapchain
-      Basic.allocatePipelines (sceneBinds samplers) swapchain rps
+      (_, samplers) <- Samplers.allocate
+        (Swapchain.getAnisotropy swapchain)
+      Basic.allocatePipelines
+        (sceneBinds samplers)
+        (Swapchain.getMultisample swapchain)
+        rps
 
     sceneBinds samplers = Set0.mkBindings
       samplers
