@certe/atmos-renderer 0.8.3 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,7 @@
6
6
  export declare const PBR_FUNCTIONS_WGSL = "\n// GGX/Trowbridge-Reitz normal distribution\nfn distributionGGX(N: vec3<f32>, H: vec3<f32>, roughness: f32) -> f32 {\n let a = roughness * roughness;\n let a2 = a * a;\n let NdotH = max(dot(N, H), 0.0);\n let NdotH2 = NdotH * NdotH;\n let denom = NdotH2 * (a2 - 1.0) + 1.0;\n return a2 / (PI * denom * denom);\n}\n\n// Schlick-GGX geometry function\nfn geometrySchlickGGX(NdotV: f32, roughness: f32) -> f32 {\n let r = roughness + 1.0;\n let k = (r * r) / 8.0;\n return NdotV / (NdotV * (1.0 - k) + k);\n}\n\n// Smith's geometry function\nfn geometrySmith(N: vec3<f32>, V: vec3<f32>, L: vec3<f32>, roughness: f32) -> f32 {\n let NdotV = max(dot(N, V), 0.0);\n let NdotL = max(dot(N, L), 0.0);\n return geometrySchlickGGX(NdotV, roughness) * geometrySchlickGGX(NdotL, roughness);\n}\n\n// Fresnel-Schlick approximation\nfn fresnelSchlick(cosTheta: f32, F0: vec3<f32>) -> vec3<f32> {\n return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);\n}\n\n// Compute PBR contribution from a single light direction\nfn computePBR(\n N: vec3<f32>, V: vec3<f32>, L: vec3<f32>,\n albedo: vec3<f32>, metallic: f32, roughness: f32,\n F0: vec3<f32>, radiance: vec3<f32>,\n) -> vec3<f32> {\n let H = normalize(V + L);\n let NDF = distributionGGX(N, H, roughness);\n let G = geometrySmith(N, V, L, roughness);\n let F = fresnelSchlick(max(dot(H, V), 0.0), F0);\n\n let numerator = NDF * G * F;\n let denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001;\n let specular = numerator / denominator;\n\n let kS = F;\n let kD = (vec3<f32>(1.0) - kS) * (1.0 - metallic);\n let NdotL = max(dot(N, L), 0.0);\n\n return (kD * albedo / PI + specular) * radiance * NdotL;\n}\n\n// Compute cotangent-frame TBN from screen-space derivatives\nfn computeTBN(worldPos: vec3<f32>, worldNormal: vec3<f32>, uv: vec2<f32>) -> mat3x3<f32> {\n let dp1 = dpdx(worldPos);\n let dp2 = dpdy(worldPos);\n let duv1 = dpdx(uv);\n let duv2 = dpdy(uv);\n let T = normalize(dp1 * duv2.y - dp2 * duv1.y);\n let B = normalize(dp2 * duv1.x - dp1 * duv2.x);\n let N = normalize(worldNormal);\n return mat3x3(T, B, N);\n}\n";
7
7
  /** Light loop WGSL: iterates dir/point/spot lights with PBR + shadow sampling.
8
8
  * Expects: N, V, albedo, metallic, roughness, F0, worldPosition in scope. Writes to Lo. */
9
- export declare const LIGHT_LOOP_WGSL = "\n // Directional lights\n for (var i = 0u; i < scene.numDirLights; i = i + 1u) {\n let light = scene.dirLights[i];\n let L = normalize(-light.direction.xyz);\n let intensity = light.color.w;\n let radiance = light.color.rgb * intensity;\n var contribution = computePBR(N, V, L, albedo, metallic, roughness, F0, radiance);\n let dirSlot = shadow.dirLightToSlot[i];\n if (dirSlot != 0xFFFFFFFFu) {\n contribution = contribution * sampleDirShadow(dirSlot, worldPosition);\n }\n Lo = Lo + contribution;\n }\n\n // Point lights\n for (var i = 0u; i < scene.numPointLights; i = i + 1u) {\n let light = scene.pointLights[i];\n let lightPos = light.position.xyz;\n let range = light.position.w;\n let intensity = light.color.w;\n\n let toLight = lightPos - worldPosition;\n let dist = length(toLight);\n let L = toLight / max(dist, 0.0001);\n\n // Smooth distance attenuation with range cutoff\n let attenuation = max(1.0 - (dist * dist) / (range * range), 0.0);\n let radiance = light.color.rgb * intensity * attenuation * attenuation;\n\n var contribution = computePBR(N, V, L, albedo, metallic, roughness, F0, radiance);\n let pointSlot = shadow.pointLightToSlot[i];\n if (pointSlot != 0xFFFFFFFFu) {\n contribution = contribution * samplePointShadow(pointSlot, worldPosition, N);\n }\n Lo = Lo + contribution;\n }\n\n // Spot lights\n for (var i = 0u; i < scene.numSpotLights; i = i + 1u) {\n let light = scene.spotLights[i];\n let lightPos = light.position.xyz;\n let range = light.position.w;\n let spotDir = light.direction.xyz;\n let outerCos = light.direction.w;\n let innerCos = light.extra.x;\n let intensity = light.color.w;\n\n let toLight = lightPos - worldPosition;\n let dist = length(toLight);\n let L = toLight / max(dist, 0.0001);\n\n // Distance attenuation (same as point light)\n let distAtt = max(1.0 - (dist * dist) / (range * range), 0.0);\n\n // Cone attenuation: smoothstep between outer and inner cosines\n let cosAngle = dot(-L, spotDir);\n let coneAtt = smoothstep(outerCos, innerCos, cosAngle);\n\n let attenuation = distAtt * distAtt * coneAtt;\n let radiance = light.color.rgb * intensity * attenuation;\n\n var contribution = computePBR(N, V, L, albedo, metallic, roughness, F0, radiance);\n let spotSlot = shadow.spotLightToSlot[i];\n if (spotSlot != 0xFFFFFFFFu) {\n contribution = contribution * sampleSpotShadow(spotSlot, worldPosition);\n }\n Lo = Lo + contribution;\n }\n";
9
+ export declare const LIGHT_LOOP_WGSL = "\n // Directional lights\n for (var i = 0u; i < scene.numDirLights; i = i + 1u) {\n let light = scene.dirLights[i];\n let L = normalize(-light.direction.xyz);\n let intensity = light.color.w;\n let radiance = light.color.rgb * intensity;\n var contribution = computePBR(N, V, L, albedo, metallic, roughness, F0, radiance);\n let dirSlot = shadow.dirLightToSlot[i];\n if (dirSlot != 0xFFFFFFFFu) {\n contribution = contribution * sampleDirShadow(dirSlot, worldPosition);\n }\n Lo = Lo + contribution;\n }\n\n // Point lights\n for (var i = 0u; i < scene.numPointLights; i = i + 1u) {\n let light = scene.pointLights[i];\n let lightPos = light.position.xyz;\n let range = light.position.w;\n let intensity = light.color.w;\n\n let toLight = lightPos - worldPosition;\n let dist = length(toLight);\n let L = toLight / max(dist, 0.0001);\n\n // Smooth distance attenuation with range cutoff\n let attenuation = max(1.0 - (dist * dist) / (range * range), 0.0);\n let radiance = light.color.rgb * intensity * attenuation * attenuation;\n\n var contribution = computePBR(N, V, L, albedo, metallic, roughness, F0, radiance);\n let pointSlot = shadow.pointLightToSlot[i];\n if (pointSlot != 0xFFFFFFFFu) {\n contribution = contribution * samplePointShadow(pointSlot, worldPosition, N);\n }\n Lo = Lo + contribution;\n }\n\n // Spot lights\n for (var i = 0u; i < scene.numSpotLights; i = i + 1u) {\n let light = scene.spotLights[i];\n let lightPos = light.position.xyz;\n let range = light.position.w;\n let spotDir = light.direction.xyz;\n let outerCos = light.direction.w;\n let innerCos = light.extra.x;\n let intensity = light.color.w;\n\n let toLight = lightPos - worldPosition;\n let dist = length(toLight);\n let L = toLight / max(dist, 0.0001);\n\n // Distance attenuation (same as point light)\n let distAtt = max(1.0 - (dist * dist) / (range * range), 0.0);\n\n // Cone attenuation: smoothstep between outer and inner cosines\n let cosAngle = dot(-L, spotDir);\n let coneAtt = smoothstep(outerCos, innerCos, cosAngle);\n\n let attenuation = distAtt * distAtt * coneAtt;\n let radiance = light.color.rgb * intensity * attenuation;\n\n var contribution = computePBR(N, V, L, albedo, metallic, roughness, F0, radiance);\n let spotSlot = shadow.spotLightToSlot[i];\n if (spotSlot != 0xFFFFFFFFu) {\n contribution = contribution * sampleSpotShadow(spotSlot, worldPosition, N);\n }\n Lo = Lo + contribution;\n }\n";
10
10
  /** Fog calculation WGSL. Expects: scene, worldPosition, color in scope. Modifies color. */
11
11
  export declare const FOG_WGSL = "\n // Distance fog\n if (scene.fogEnabled != 0u) {\n let fogDist = length(scene.cameraPos.xyz - worldPosition);\n var fogFactor: f32;\n if (scene.fogMode == 0u) {\n // Linear\n fogFactor = saturate((scene.fogEnd - fogDist) / (scene.fogEnd - scene.fogStart));\n } else {\n // Exponential\u00B2\n let d = scene.fogDensity * fogDist;\n fogFactor = exp(-(d * d));\n }\n color = mix(scene.fogColor.rgb, color, fogFactor);\n }\n";
12
12
  //# sourceMappingURL=pbr-wgsl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pbr-wgsl.d.ts","sourceRoot":"","sources":["../src/pbr-wgsl.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wFAAwF;AACxF,eAAO,MAAM,kBAAkB,2lEA+D9B,CAAC;AAEF;4FAC4F;AAC5F,eAAO,MAAM,eAAe,2gFAqE3B,CAAC;AAEF,2FAA2F;AAC3F,eAAO,MAAM,QAAQ,ydAepB,CAAC"}
1
+ {"version":3,"file":"pbr-wgsl.d.ts","sourceRoot":"","sources":["../src/pbr-wgsl.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wFAAwF;AACxF,eAAO,MAAM,kBAAkB,2lEA+D9B,CAAC;AAEF;4FAC4F;AAC5F,eAAO,MAAM,eAAe,8gFAqE3B,CAAC;AAEF,2FAA2F;AAC3F,eAAO,MAAM,QAAQ,ydAepB,CAAC"}
package/dist/pbr-wgsl.js CHANGED
@@ -134,7 +134,7 @@ export const LIGHT_LOOP_WGSL = /* wgsl */ `
134
134
  var contribution = computePBR(N, V, L, albedo, metallic, roughness, F0, radiance);
135
135
  let spotSlot = shadow.spotLightToSlot[i];
136
136
  if (spotSlot != 0xFFFFFFFFu) {
137
- contribution = contribution * sampleSpotShadow(spotSlot, worldPosition);
137
+ contribution = contribution * sampleSpotShadow(spotSlot, worldPosition, N);
138
138
  }
139
139
  Lo = Lo + contribution;
140
140
  }
@@ -1 +1 @@
1
- {"version":3,"file":"shadow-fragment-wgsl.d.ts","sourceRoot":"","sources":["../src/shadow-fragment-wgsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAkNH,eAAO,MAAM,oBAAoB,QAAmB,CAAC"}
1
+ {"version":3,"file":"shadow-fragment-wgsl.d.ts","sourceRoot":"","sources":["../src/shadow-fragment-wgsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA2NH,eAAO,MAAM,oBAAoB,QAAmB,CAAC"}
@@ -70,12 +70,21 @@ function genPointSlot(slot) {
70
70
  }
71
71
  function genSpotSlot(slot) {
72
72
  const tex = `spotDepthMap${slot}`;
73
- return `fn _sampleSpotSlot${slot}(worldPos: vec3<f32>) -> f32 {
73
+ return `fn _sampleSpotSlot${slot}(worldPos: vec3<f32>, N: vec3<f32>) -> f32 {
74
74
  let s = shadow.spotSlots[${slot}];
75
- let clip = s.shadowVP * vec4(worldPos, 1.0);
75
+ let toFrag = worldPos - s.posAndFar.xyz;
76
+ let dist = length(toFrag);
77
+ let lightDir = toFrag / max(dist, 0.0001);
78
+ let cosTheta = abs(dot(lightDir, N));
79
+ // Normal offset in world space: scales with texel size at this distance
80
+ let res = f32(textureDimensions(${tex}, 0).x);
81
+ let texelWorld = dist * 2.0 / res;
82
+ let normalOffset = N * texelWorld * max(1.0 - cosTheta, 0.1);
83
+ let samplePos = worldPos + normalOffset;
84
+ let clip = s.shadowVP * vec4(samplePos, 1.0);
76
85
  let ndc = clip.xyz / clip.w;
77
86
  let uv = ndc.xy * vec2(0.5, -0.5) + 0.5;
78
- let depth = ndc.z - s.bias;
87
+ let depth = ndc.z - 0.0005;
79
88
  let inBounds = uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0 && ndc.z >= 0.0 && ndc.z <= 1.0;
80
89
  let texelSize = 1.0 / f32(textureDimensions(${tex}, 0).x);
81
90
  var vis = 0.0;
@@ -191,12 +200,12 @@ fn samplePointShadow(slot: u32, worldPos: vec3<f32>, N: vec3<f32>) -> f32 {
191
200
  }
192
201
  }
193
202
 
194
- fn sampleSpotShadow(slot: u32, worldPos: vec3<f32>) -> f32 {
203
+ fn sampleSpotShadow(slot: u32, worldPos: vec3<f32>, N: vec3<f32>) -> f32 {
195
204
  switch(slot) {
196
- case 0u: { return _sampleSpotSlot0(worldPos); }
197
- case 1u: { return _sampleSpotSlot1(worldPos); }
198
- case 2u: { return _sampleSpotSlot2(worldPos); }
199
- case 3u: { return _sampleSpotSlot3(worldPos); }
205
+ case 0u: { return _sampleSpotSlot0(worldPos, N); }
206
+ case 1u: { return _sampleSpotSlot1(worldPos, N); }
207
+ case 2u: { return _sampleSpotSlot2(worldPos, N); }
208
+ case 3u: { return _sampleSpotSlot3(worldPos, N); }
200
209
  default: { return 1.0; }
201
210
  }
202
211
  }
@@ -1 +1 @@
1
- {"version":3,"file":"shadow-fragment-wgsl.js","sourceRoot":"","sources":["../src/shadow-fragment-wgsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,uEAAuE;AAEvE,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAC/B,MAAM,sBAAsB,GAAG,CAAC,CAAC;AACjC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEhC,uEAAuE;AAEvE,SAAS,SAAS,CAAC,IAAY,EAAE,OAAc;IAC7C,MAAM,GAAG,GAAG,aAAa,OAAO,IAAI,IAAI,EAAE,CAAC;IAC3C,MAAM,OAAO,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC;IAC5D,OAAO,aAAa,OAAO,IAAI,IAAI;4BACT,IAAI;iBACf,OAAO;;;;gDAIwB,GAAG;;;kCAGjB,GAAG;;;EAGnC,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,oBAAoB,IAAI;4BACL,IAAI;wBACR,IAAI;wBACJ,IAAI;;;;;;;;;;;;;EAa1B,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,GAAG,GAAG,eAAe,IAAI,EAAE,CAAC;IAClC,OAAO,sBAAsB,IAAI;8BACL,IAAI;;;;;;;;mCAQC,GAAG;;;;;EAKpC,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,MAAM,GAAG,GAAG,eAAe,IAAI,EAAE,CAAC;IAClC,OAAO,qBAAqB,IAAI;6BACL,IAAI;;;;;;gDAMe,GAAG;;;kCAGjB,GAAG;;;;;EAKnC,CAAC;AACH,CAAC;AAED,uEAAuE;AAEvE,MAAM,KAAK,GAAa,EAAE,CAAC;AAE3B,UAAU;AACV,KAAK,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCV,CAAC,CAAC;AAEH,qBAAqB;AACrB,KAAK,CAAC,IAAI,CAAC;;;;;;;;;;;;;CAaV,CAAC,CAAC;AAEH,iBAAiB;AACjB,KAAK,CAAC,IAAI,CAAC;;;;;;;;;;;;CAYV,CAAC,CAAC;AAEH,2BAA2B;AAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,oBAAoB,EAAE,CAAC,EAAE,EAAE,CAAC;IAC9C,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5B,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5B,CAAC;AAED,iBAAiB;AACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,sBAAsB,EAAE,CAAC,EAAE,EAAE,CAAC;IAChD,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,gBAAgB;AAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,qBAAqB,EAAE,CAAC,EAAE,EAAE,CAAC;IAC/C,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7B,CAAC;AAED,qBAAqB;AACrB,KAAK,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BV,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"shadow-fragment-wgsl.js","sourceRoot":"","sources":["../src/shadow-fragment-wgsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,uEAAuE;AAEvE,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAC/B,MAAM,sBAAsB,GAAG,CAAC,CAAC;AACjC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEhC,uEAAuE;AAEvE,SAAS,SAAS,CAAC,IAAY,EAAE,OAAc;IAC7C,MAAM,GAAG,GAAG,aAAa,OAAO,IAAI,IAAI,EAAE,CAAC;IAC3C,MAAM,OAAO,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC;IAC5D,OAAO,aAAa,OAAO,IAAI,IAAI;4BACT,IAAI;iBACf,OAAO;;;;gDAIwB,GAAG;;;kCAGjB,GAAG;;;EAGnC,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,oBAAoB,IAAI;4BACL,IAAI;wBACR,IAAI;wBACJ,IAAI;;;;;;;;;;;;;EAa1B,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,GAAG,GAAG,eAAe,IAAI,EAAE,CAAC;IAClC,OAAO,sBAAsB,IAAI;8BACL,IAAI;;;;;;;;mCAQC,GAAG;;;;;EAKpC,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,MAAM,GAAG,GAAG,eAAe,IAAI,EAAE,CAAC;IAClC,OAAO,qBAAqB,IAAI;6BACL,IAAI;;;;;;oCAMG,GAAG;;;;;;;;;gDASS,GAAG;;;kCAGjB,GAAG;;;;;EAKnC,CAAC;AACH,CAAC;AAED,uEAAuE;AAEvE,MAAM,KAAK,GAAa,EAAE,CAAC;AAE3B,UAAU;AACV,KAAK,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCV,CAAC,CAAC;AAEH,qBAAqB;AACrB,KAAK,CAAC,IAAI,CAAC;;;;;;;;;;;;;CAaV,CAAC,CAAC;AAEH,iBAAiB;AACjB,KAAK,CAAC,IAAI,CAAC;;;;;;;;;;;;CAYV,CAAC,CAAC;AAEH,2BAA2B;AAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,oBAAoB,EAAE,CAAC,EAAE,EAAE,CAAC;IAC9C,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5B,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5B,CAAC;AAED,iBAAiB;AACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,sBAAsB,EAAE,CAAC,EAAE,EAAE,CAAC;IAChD,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,gBAAgB;AAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,qBAAqB,EAAE,CAAC,EAAE,EAAE,CAAC;IAC/C,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7B,CAAC;AAED,qBAAqB;AACrB,KAAK,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BV,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC"}
@@ -69,8 +69,8 @@ export class SpotShadowPass {
69
69
  depthWriteEnabled: true,
70
70
  depthCompare: 'less',
71
71
  format: 'depth32float',
72
- depthBias: 2,
73
- depthBiasSlopeScale: 2.0,
72
+ depthBias: 1,
73
+ depthBiasSlopeScale: 1.0,
74
74
  },
75
75
  });
76
76
  }
@@ -84,7 +84,7 @@ export class SpotShadowPass {
84
84
  execute(encoder, scene, lightPos, lightDir, outerAngle, range, extraDraw) {
85
85
  // Perspective projection: FOV = outerAngle * 2, aspect 1:1
86
86
  const fov = outerAngle * 2;
87
- Mat4.perspective(this._proj, fov, 1.0, 0.1, range);
87
+ Mat4.perspective(this._proj, fov, 1.0, 0.5, range);
88
88
  // View matrix: lookAt from lightPos toward lightPos + lightDir
89
89
  this._target[0] = lightPos[0] + lightDir[0];
90
90
  this._target[1] = lightPos[1] + lightDir[1];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@certe/atmos-renderer",
3
3
  "description": "WebGPU PBR renderer for the Atmos Engine — lights, shadows, skinning, post-processing",
4
- "version": "0.8.3",
4
+ "version": "0.8.5",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/certesolutions-cyber/atmos.git",
@@ -29,8 +29,8 @@
29
29
  "LICENCE"
30
30
  ],
31
31
  "dependencies": {
32
- "@certe/atmos-core": "^0.8.3",
33
- "@certe/atmos-math": "^0.8.3"
32
+ "@certe/atmos-core": "^0.8.5",
33
+ "@certe/atmos-math": "^0.8.5"
34
34
  },
35
35
  "scripts": {
36
36
  "test": "vitest run"