packages feed

keid-render-basic 0.1.9.0 → 0.1.10.0

raw patch · 15 files changed

+90/−86 lines, 15 filesdep ~geomancydep ~keid-core

Dependency ranges changed: geomancy, keid-core

Files

ChangeLog.md view
@@ -1,5 +1,11 @@ # Changelog for keid-render-basic +## 0.1.10.0++- Update to follow the changes in keid-core-0.1.11 and geomancy-0.3.+- Fix lit pipelines by removing spurious sign flips.+- Require LitColored to participate in the depth pre-pass.+ ## 0.1.9.0  - Moved to geomancy-layout.
keid-render-basic.cabal view
@@ -1,17 +1,17 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.2.+-- This file has been generated from package.yaml by hpack version 0.38.1. -- -- see: https://github.com/sol/hpack  name:           keid-render-basic-version:        0.1.9.0+version:        0.1.10.0 synopsis:       Basic rendering programs for Keid engine. category:       Game Engine homepage:       https://keid.haskell-game.dev author:         IC Rainbow maintainer:     keid@aenor.ru-copyright:      2023 IC Rainbow+copyright:      2025 IC Rainbow license:        BSD3 license-file:   LICENSE build-type:     Simple@@ -132,10 +132,10 @@     , derive-storable     , derive-storable-plugin     , file-embed >=0.0.10-    , geomancy+    , geomancy >=0.3.0.0     , geomancy-layout     , gl-block-    , keid-core >=0.1.9.0+    , keid-core >=0.1.11.0     , keid-geometry     , neat-interpolation     , resourcet
src/Render/Code/Lit.hs view
@@ -127,10 +127,10 @@       baseColor.rgb;     vec3 F0 = mix(vec3(0.04), albedo, metallic); -    vec3 ray = scene.viewPosition.xyz - fPosition.xyz;-    vec3 rayDir = normalize(ray); // V-    float quadrance = dot(ray, ray);-    float distance = sqrt(quadrance);+    vec3 rayDir = normalize(scene.viewPosition.xyz - fPosition.xyz); // V+    // vec3 rayDir = normalize(ray); // V+    // float quadrance = dot(ray, ray);+    // float viewDistance = sqrt(quadrance); // XXX: not used for directional lights      // XXX: provided by caller     // vec3 normal = normalize(fNormal); // N@@ -138,7 +138,7 @@     vec3 Lo = vec3(0.0);     for (int l = 0; l < scene.numLights; l++) {       // XXX: directional lights' hit angle doesn't depend on fragment position-      vec3 lightDir = normalize(lights[l].direction.xyz); // L+      vec3 lightDir = lights[l].direction.xyz; // L, pre-normalized        float shade = 1.0; // XXX: 0 - occluded, 1 - lit       if (lights[l].shadow.z > -1) {@@ -147,12 +147,13 @@          // TODO: pick on specialization constant         shade = filterPCF(shadowCoord.xyz, lights[l].shadow.z);-        // shade = shadow_factor(shadowCoord.xyz, lights[l].shadow.z, vec2(0));+        // shade = shadow_factor(shadowCoord.xyz, lights[l].shadow.z, vec2(0)); // looks like crap+        // TODO: VSM shadows       }        Lo += brdfSpecular(-        lightDir,-        ray,+        -lightDir, // XXX: according to PBR convention+        rayDir,         normal,         F0,         metallic,@@ -162,7 +163,8 @@       ) * shade;     } -    vec3 reflection = prefilteredReflection(reflect(rayDir, normal), roughness).rgb;+    vec3 R = reflect(-rayDir, normal);+    vec3 reflection = prefilteredReflection(R, roughness).rgb;      // IBL     vec3 irradiance = vec3(0);@@ -172,7 +174,7 @@           cubes[nonuniformEXT(scene.envCubeId)],           samplers[0]         ),-        -normal,+        normal * vec3(1, -1, 1),         IRRADIANCE_LOD       ).rgb;     }@@ -208,12 +210,13 @@     vec3 color = Lo + ambient;      // Tone mapping+    // TODO: make configurable     color =       Uncharted2Tonemap(color * 4.5) /       Uncharted2Tonemap(vec3(11.2)); // White point      // Gamma correction-    // XXX: not needed, we're in linear already+    // XXX: not needed, we're in sRGB after tonemap     // color = pow(color, vec3(1.0/2.2));      // Happily ever after@@ -257,8 +260,9 @@      vec3 prefilteredReflection(vec3 R, float roughness) {       vec3 color = vec3(0);+      vec3 R_cube = R * vec3(1, -1, 1); -      if (scene.envCubeId > -1) {+      if (scene.envCubeId > -1) { // TODO: wrap the whole call         float lod = roughness * MAX_REFLECTION_LOD;         float lodf = floor(lod);         float lodc = ceil(lod);@@ -268,7 +272,7 @@             cubes[nonuniformEXT(scene.envCubeId)],             samplers[0]           ),-          R,+          R_cube,           lodf         ).rgb; @@ -277,7 +281,7 @@             cubes[nonuniformEXT(scene.envCubeId)],             samplers[0]           ),-          R,+          R_cube,           lodc         ).rgb; @@ -302,6 +306,7 @@       float dotNH = clamp(dot(N, H), 0.0, 1.0);       float dotNV = clamp(dot(N, V), 0.0, 1.0);       float dotNL = clamp(dot(N, L), 0.0, 1.0);+      float dotVH = clamp(dot(V, H), 0.0, 1.0);        vec3 color = vec3(0.0); @@ -312,7 +317,7 @@         float rroughness = max(0.05, roughness);         float G = G_SchlicksmithGGX(dotNL, dotNV, rroughness);         // F = Fresnel factor (Reflectance depending on angle of incidence)-        vec3 F = F_Schlick(dotNV, F0);+        vec3 F = F_Schlick(dotVH, F0);         vec3 spec = D * F * G / (4.0 * dotNL * dotNV + 0.001);         vec3 kD = (vec3(1.0) - F) * (1.0 - metallic);         color += (kD * ALBEDO / 3.1415926535897932384626433832795 + spec) * dotNL * lightColor;
src/Render/Debug/Code.hs view
@@ -86,28 +86,28 @@           break;          case 2:-          float d0 = 1.0;+          float d0 = 0.0;           if ((shadow_mask & 1) == 1)             d0 = texture(               shadowmaps,               vec3(fTexCoord, 0.0)             ).x; -          float d1 = 1.0;+          float d1 = 0.0;           if ((shadow_mask & 2) == 2)             d1 = texture(               shadowmaps,               vec3(fTexCoord, 1.0)             ).x; -          float d2 = 1.0;+          float d2 = 0.0;           if ((shadow_mask & 4) == 4)             d2 = texture(               shadowmaps,               vec3(fTexCoord, 2.0)             ).x; -          texel = vec4(1-d0, 1-d1, 1-d2, 1.0);+          texel = vec4(d0, d1, d2, 1.0);           break;          default:
src/Render/DescSets/Set0.hs view
@@ -258,7 +258,7 @@       , Vk.magFilter     = shadowFilter       , Vk.minFilter     = shadowFilter       , Vk.compareEnable = True-      , Vk.compareOp     = Vk.COMPARE_OP_LESS+      , Vk.compareOp     = Vk.COMPARE_OP_GREATER       }    let ifor = flip Vector.imapM
src/Render/DescSets/Sun.hs view
@@ -33,6 +33,7 @@ import Geomancy (Vec3, Vec4, vec3, vec4) import Geomancy.Transform (Transform) import Geomancy.Transform qualified as Transform+import Geomancy.Quaternion qualified as Quaternion import Geomancy.Vec4 qualified as Vec4 import Vulkan.Core10 qualified as Vk import Vulkan.CStruct.Extends (SomeStruct(..))@@ -173,7 +174,7 @@   , siRadius      = Camera.PROJECTION_FAR / 2   , siTarget      = 0 -  , siDepthRange = Camera.PROJECTION_FAR+  , siDepthRange = Camera.PROJECTION_FAR -- TODO: use explicit near/far   , siSize       = 512   , siShadowIx   = -1   }@@ -192,7 +193,7 @@ mkSun SunInput{..} =   ( bbTransform   , Sun-      { sunViewProjection = mconcat vp+      { sunViewProjection = pv       , sunShadow         = vec4 0 0 siShadowIx siSize       , sunPosition       = Vec4.fromVec3 position 0       , sunDirection      = Vec4.fromVec3 direction 0@@ -200,39 +201,26 @@       }   )   where-    vp =-      [ Transform.rotateY (-siAzimuth)-      , Transform.rotateX (-siInclination)--      , Transform.translate 0 0 siRadius--      -- XXX: some area beyond the near plane receives light, but not shadows-      , Transform.scale3-          (1 / siSize)-          (1 / siSize)-          (1 / siDepthRange)-      ]--    position = Transform.apply (vec3 0 0 siRadius) rotation--    direction = Transform.apply (vec3 0 0 $ -1) rotation+    pv = p <> v+    p = -- just a scaled ortho box+      Transform.scale3+        (1 / siSize)+        (1 / siSize)+        (1 / siDepthRange)+    v =+      Transform.dirPos+        (Quaternion.extrinsic (-siAzimuth) (-siInclination) 0)+        (vec3 0 0 siRadius)      bbTransform = mconcat-      [ -- XXX: orient wire box "green/near -> far/red"-        Transform.rotateX (τ/4)-        -- XXX: the rest must be matched with VP flipped-      , Transform.translate 0 0 0.5                 -- XXX: shift origin to the near face--        -- XXX: reverse light transform-      , Transform.scale3 siSize siSize siDepthRange -- XXX: size to projection volume-      , Transform.translate 0 0 (-siRadius)         -- XXX: translate near face to radius-      , rotation                                    -- XXX: apply sphere coords+      [ Transform.inverse pv+      , Transform.translate 0 0 0.5 -- shift origin to the near face+      , Transform.rotateX (τ/4) -- put the green side towards the light       ] -    rotation = mconcat-      [ Transform.rotateX siInclination-      , Transform.rotateY siAzimuth-      ]+    position = rotation `Quaternion.rotate` vec3 0 0 siRadius+    direction = rotation `Quaternion.rotate` vec3 0 0 (-1)+    rotation = Quaternion.intrinsic 0 (siInclination) (siAzimuth)  type Observer = Worker.ObserverIO (VectorS.Vector ("bounding box" ::: Transform)) 
src/Render/ForwardMsaa.hs view
@@ -78,7 +78,7 @@       }     clear = Vector.fromList       [ clearColor-      , Vk.DepthStencil (Vk.ClearDepthStencilValue 1.0 0)+      , Vk.DepthStencil (Vk.ClearDepthStencilValue 0.0 0)       , clearColor       ]     clearColor = Vk.Color zero
src/Render/Lit/Colored/Pipeline.hs view
@@ -65,11 +65,16 @@   { Graphics.cDescLayouts  = Tagged @'[Scene] [set0]   , Graphics.cStages       = stageSpirv   , Graphics.cVertexInput  = Graphics.vertexInput @Pipeline+  , Graphics.cDepthWrite   = False -- XXX: Lit pipelines require depth pre-pass+  , Graphics.cDepthCompare = Vk.COMPARE_OP_EQUAL   }  configBlend :: Tagged Scene DsLayoutBindings -> Config configBlend tset0 = (config tset0)   { Graphics.cBlend = True+  , Graphics.cDepthCompare =+      -- XXX: blended objects aren't a part of depth prepass+      Vk.COMPARE_OP_GREATER_OR_EQUAL   }  stageCode :: Graphics.StageCode
src/Render/Lit/Material/Pipeline.hs view
@@ -75,7 +75,7 @@       True   , Graphics.cDepthCompare =       -- XXX: blended objects aren't a part of depth prepass-      Vk.COMPARE_OP_LESS_OR_EQUAL+      Vk.COMPARE_OP_GREATER_OR_EQUAL   }  stageCode :: Graphics.StageCode
src/Render/Lit/Textured/Pipeline.hs view
@@ -71,8 +71,10 @@  configBlend :: Tagged Scene DsLayoutBindings -> Config configBlend tset0 = (config tset0)-  { Graphics.cBlend      = True-  , Graphics.cDepthCompare = Vk.COMPARE_OP_LESS_OR_EQUAL+  { Graphics.cBlend = True+  , Graphics.cDepthCompare =+      -- XXX: blended objects aren't a part of depth prepass+      Vk.COMPARE_OP_GREATER_OR_EQUAL   }  stageCode :: Graphics.StageCode
src/Render/ShadowMap/Pipeline.hs view
@@ -37,8 +37,8 @@  defaults :: Settings defaults = Settings-  { cull      = Vk.CULL_MODE_BACK_BIT-  , depthBias = Just (2.0, 2.5)+  { cull      = Vk.CULL_MODE_FRONT_BIT+  , depthBias = Just (-2.0, -2.5)   }  allocate
src/Render/ShadowMap/RenderPass.hs view
@@ -87,7 +87,7 @@       }      clear = Vector.fromList-      [ Vk.DepthStencil (Vk.ClearDepthStencilValue 1.0 0)+      [ Vk.DepthStencil (Vk.ClearDepthStencilValue 0.0 0)       ]  -- ** Render pass
src/Render/Skybox/Code.hs view
@@ -15,21 +15,20 @@      ${set0binding0} -    layout(location = 0) out vec3 fragUVW;+    layout(location = 0) out vec3 fUVW; -    float farZ = 0.9999; // 1 - 1e-7;+    float farZ = 5.960464478e-8; // FLT_EPS      void main() {       vec4 pos = vec4(0.0);       switch(gl_VertexIndex) {           case 0: pos = vec4(-1.0,  3.0, farZ, 1.0); break;-          case 1: pos = vec4(-1.0, -1.0, farZ, 1.0); break; // XXX: swapped with 2. culling?+          case 1: pos = vec4(-1.0, -1.0, farZ, 1.0); break;           case 2: pos = vec4( 3.0, -1.0, farZ, 1.0); break;       }        vec3 unProjected = (scene.invProjection * pos).xyz;-      unProjected *= -1;-      fragUVW = mat3(scene.invView) * unProjected;+      fUVW = mat3(scene.invView) * unProjected;        gl_Position = pos;     }@@ -46,18 +45,20 @@     ${set0binding1}     ${set0binding3} -    layout(location = 0) in vec3 fragUVW;+    layout(location = 0) in vec3 fUVW;      layout(location = 0) out vec4 outColor;      void main() {       if (scene.envCubeId > -1) {+        vec3 dir = fUVW;+        dir.y *= -1; // TODO: make customizable         outColor = texture(           samplerCube(             cubes[nonuniformEXT(scene.envCubeId)],             samplers[3] // XXX: linear           ),-          fragUVW+          dir         );       }     }
src/Render/Unlit/Colored/Code.hs view
@@ -40,11 +40,10 @@   [glsl|     #version 450 -    layout(location = 0) in vec4 fragColor;-+    layout(location = 0) in vec4 fColor;     layout(location = 0) out vec4 outColor;      void main() {-      outColor = fragColor;+      outColor = fColor;     }   |]
src/Stage/Loader/UI.hs view
@@ -13,7 +13,7 @@  import Control.Monad.Trans.Resource (ResourceT) import Control.Monad.Trans.Resource qualified as Resource-import Geomancy (vec4)+import Geomancy (vec4, withVec2) import Geomancy.Layout qualified as Layout import Geomancy.Layout.Alignment qualified as Alignment import Geomancy.Layout.Box qualified as Box@@ -119,24 +119,22 @@   -- Spinner    spinnerTransformTimeP <--    Worker.spawnTimed_ True 100 mempty do-      t <- getMonotonicTime-      pure $ Transform.rotateZ (realToFrac t)--  spinnerTransformBoxP <--    Worker.spawnMerge1-      (Box.mkTransform) -- FIXME: . Layout.boxFitScale 64)-      subtitleBoxP+    Worker.spawnTimed_ True 100 0.0 Engine.secondsSinceStart    spinnerP <-     Worker.spawnMerge2-      ( \place turn ->-          UnlitTextured.stores1+      ( \box time ->+          withVec2 box.position \x y ->+            withVec2 box.size \w h ->+            UnlitTextured.stores1               (Samplers.linear Samplers.indices)               spinnerIx-              [turn, place]+              [ Transform.translate x y 0+              , Transform.rotateZ time+              , Transform.scale (min 256 $ min w h)+              ]       )-      spinnerTransformBoxP+      subtitleBoxP       spinnerTransformTimeP    -- Models