@quake2ts/engine 0.0.841 → 0.0.842

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.
@@ -884,32 +884,34 @@ struct VertexOutput {
884
884
  fn vertexMain(@location(0) position: vec3<f32>) -> VertexOutput {
885
885
  var output: VertexOutput;
886
886
 
887
- // Normalize input position (Quake Coordinates)
888
- var qDir = normalize(position);
887
+ // Pass the RAW position (not normalized) as direction
888
+ // This preserves the face-relative direction and avoids corner tie issues
889
+ // The cubemap sampler handles normalization internally
890
+ var dir = position;
889
891
 
890
- // Apply scrolling in Quake Coordinates (Horizontal Plane X/Y)
891
- // This ensures clouds scroll horizontally regardless of the final mapping.
892
- qDir.x += uniforms.scroll.x;
893
- qDir.y += uniforms.scroll.y;
894
-
895
- // Transform Quake coordinates (X-Fwd, Y-Left, Z-Up)
896
- // to WebGPU/GL cubemap coordinates (Right-handed? -Z Fwd, +X Right, +Y Up)
897
- // Quake X -> GL -Z
898
- // Quake Y -> GL -X
899
- // Quake Z -> GL Y
900
- var dir = vec3<f32>(-qDir.y, qDir.z, -qDir.x);
892
+ // Apply scrolling in Quake horizontal plane (X/Y)
893
+ // Small scrolling offset that doesn't break dominant component detection
894
+ dir.x += uniforms.scroll.x * 0.01;
895
+ dir.y += uniforms.scroll.y * 0.01;
901
896
 
902
897
  output.direction = dir;
903
-
904
898
  output.position = uniforms.viewProjection * vec4<f32>(position, 1.0);
905
899
  return output;
906
900
  }
907
901
 
908
902
  @fragment
909
903
  fn fragmentMain(@location(0) direction: vec3<f32>) -> @location(0) vec4<f32> {
910
- return textureSample(t_skybox, s_skybox, direction);
904
+ // Transform from Quake coordinates to GL/WebGPU cubemap coordinates
905
+ // Quake: +X forward, +Y left, +Z up
906
+ // GL cubemap: +X right, +Y up, -Z forward
907
+ var cubemapDir: vec3<f32>;
908
+ cubemapDir.x = -direction.y; // Quake +Y (left) \u2192 GL -X (left)
909
+ cubemapDir.y = direction.z; // Quake +Z (up) \u2192 GL +Y (up)
910
+ cubemapDir.z = -direction.x; // Quake +X (forward) \u2192 GL -Z (forward)
911
+
912
+ return textureSample(t_skybox, s_skybox, cubemapDir);
911
913
  }
912
- `;var jd=(n=>(n.QUAKE="quake",n.OPENGL="opengl",n.WEBGPU="webgpu",n))(jd||{});var ka=class{constructor(){this.coordinateSystem="webgpu"}buildProjectionMatrix(e){let r=F.create(),n=1/Math.tan(e.fov*Ce/2),i=1/(e.near-e.far);return r[0]=n/e.aspect,r[5]=n,r[10]=e.far*i,r[11]=-1,r[14]=e.near*e.far*i,r}buildViewMatrix(e){let[r,n,i]=e.angles,a=r*Ce,o=n*Ce,s=i*Ce,c=F.create();F.identity(c),F.rotateZ(c,c,-o),F.rotateY(c,c,-a),F.rotateX(c,c,-s);let l=F.fromValues(0,0,-1,0,-1,0,0,0,0,1,0,0,0,0,0,1),u=F.fromValues(0,0,-1,0,-1,0,0,0,0,1,0,0,0,0,0,1),d=F.create();F.multiply(d,u,c);let f=L.fromValues(e.position[0],e.position[1],e.position[2]),h=L.transformMat4(L.create(),f,d);L.negate(h,h);let m=F.clone(d);return m[12]=h[0],m[13]=h[1],m[14]=h[2],m}};var Zd=new Float32Array([1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1]),Fc=class{constructor(e,r){this.device=e;this.format=r;this.matrixBuilder=new ka;let n=e.createShaderModule({label:"skybox-shader",code:yp});this.vertexBuffer=e.createBuffer({label:"skybox-vertex-buffer",size:Zd.byteLength,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),new Float32Array(this.vertexBuffer.getMappedRange()).set(Zd),this.vertexBuffer.unmap(),this.uniformBuffer=e.createBuffer({label:"skybox-uniform-buffer",size:80,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.sampler=e.createSampler({label:"skybox-sampler",minFilter:"linear",magFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",addressModeW:"clamp-to-edge"});let i=e.createBindGroupLayout({label:"skybox-bind-group-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"cube"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}}]});this.pipeline=e.createRenderPipeline({label:"skybox-pipeline",layout:e.createPipelineLayout({bindGroupLayouts:[i]}),vertex:{module:n,entryPoint:"vertexMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},fragment:{module:n,entryPoint:"fragmentMain",targets:[{format:this.format,blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},depthStencil:{format:"depth24plus",depthWriteEnabled:!1,depthCompare:"always"},primitive:{topology:"triangle-list",cullMode:"none"}}),this.bindGroupHelper=new Qd(e,i,this.uniformBuffer,this.sampler)}draw(e,r){let n,i=0;if(r.cameraState){let s=this.matrixBuilder.buildViewMatrix(r.cameraState),c=this.matrixBuilder.buildProjectionMatrix(r.cameraState);s[12]=0,s[13]=0,s[14]=0;let l=F.create();F.multiply(l,c,s),n=l,i=1}else if(r.viewProjection)n=r.viewProjection,i=0;else throw new Error("SkyboxPipeline: Either cameraState or viewProjection must be provided");let a=new Float32Array(20);a.set(n),a[16]=r.scroll[0],a[17]=r.scroll[1],a[18]=i,this.device.queue.writeBuffer(this.uniformBuffer,0,a);let o=this.bindGroupHelper.getBindGroup(r.cubemap);e.setPipeline(this.pipeline),e.setBindGroup(0,o),e.setVertexBuffer(0,this.vertexBuffer),e.draw(Zd.length/3)}destroy(){this.vertexBuffer.destroy(),this.uniformBuffer.destroy()}},Qd=class{constructor(e,r,n,i){this.device=e;this.layout=r;this.uniformBuffer=n;this.sampler=i;this.bindGroupCache=new Map}getBindGroup(e){if(this.bindGroupCache.has(e))return this.bindGroupCache.get(e);let r=this.device.createBindGroup({layout:this.layout,entries:[{binding:0,resource:{buffer:this.uniformBuffer}},{binding:1,resource:e.createView()},{binding:2,resource:this.sampler}]});return this.bindGroupCache.set(e,r),r}};var bp=`struct DLight {
914
+ `;var jd=(n=>(n.QUAKE="quake",n.OPENGL="opengl",n.WEBGPU="webgpu",n))(jd||{});var ka=class{constructor(){this.coordinateSystem="webgpu"}buildProjectionMatrix(e){let r=F.create(),n=1/Math.tan(e.fov*Ce/2),i=1/(e.near-e.far);return r[0]=n/e.aspect,r[5]=n,r[10]=e.far*i,r[11]=-1,r[14]=e.near*e.far*i,r[15]=0,r}buildViewMatrix(e){let[r,n,i]=e.angles,a=r*Ce,o=n*Ce,s=i*Ce,c=F.create();F.identity(c),F.rotateZ(c,c,-o),F.rotateY(c,c,-a),F.rotateX(c,c,-s);let l=F.fromValues(0,0,-1,0,-1,0,0,0,0,1,0,0,0,0,0,1),u=F.fromValues(0,0,-1,0,-1,0,0,0,0,1,0,0,0,0,0,1),d=F.create();F.multiply(d,u,c);let f=L.fromValues(e.position[0],e.position[1],e.position[2]),h=L.transformMat4(L.create(),f,d);L.negate(h,h);let m=F.clone(d);return m[12]=h[0],m[13]=h[1],m[14]=h[2],m}};var Zd=new Float32Array([1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1]),Fc=class{constructor(e,r){this.device=e;this.format=r;this.matrixBuilder=new ka;let n=e.createShaderModule({label:"skybox-shader",code:yp});this.vertexBuffer=e.createBuffer({label:"skybox-vertex-buffer",size:Zd.byteLength,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),new Float32Array(this.vertexBuffer.getMappedRange()).set(Zd),this.vertexBuffer.unmap(),this.uniformBuffer=e.createBuffer({label:"skybox-uniform-buffer",size:80,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.sampler=e.createSampler({label:"skybox-sampler",minFilter:"linear",magFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",addressModeW:"clamp-to-edge"});let i=e.createBindGroupLayout({label:"skybox-bind-group-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"cube"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}}]});this.pipeline=e.createRenderPipeline({label:"skybox-pipeline",layout:e.createPipelineLayout({bindGroupLayouts:[i]}),vertex:{module:n,entryPoint:"vertexMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},fragment:{module:n,entryPoint:"fragmentMain",targets:[{format:this.format,blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},depthStencil:{format:"depth24plus",depthWriteEnabled:!0,depthCompare:"less-equal"},primitive:{topology:"triangle-list",cullMode:"none"}}),this.bindGroupHelper=new Qd(e,i,this.uniformBuffer,this.sampler)}draw(e,r){let n,i=0;if(r.cameraState){let s=this.matrixBuilder.buildViewMatrix(r.cameraState),c=this.matrixBuilder.buildProjectionMatrix(r.cameraState);s[12]=0,s[13]=0,s[14]=0;let l=F.create();F.multiply(l,c,s),n=l,i=1}else if(r.viewProjection)n=r.viewProjection,i=0;else throw new Error("SkyboxPipeline: Either cameraState or viewProjection must be provided");let a=new Float32Array(20);a.set(n),a[16]=r.scroll[0],a[17]=r.scroll[1],a[18]=i,this.device.queue.writeBuffer(this.uniformBuffer,0,a);let o=this.bindGroupHelper.getBindGroup(r.cubemap);e.setPipeline(this.pipeline),e.setBindGroup(0,o),e.setVertexBuffer(0,this.vertexBuffer),e.draw(Zd.length/3)}destroy(){this.vertexBuffer.destroy(),this.uniformBuffer.destroy()}},Qd=class{constructor(e,r,n,i){this.device=e;this.layout=r;this.uniformBuffer=n;this.sampler=i;this.bindGroupCache=new Map}getBindGroup(e){if(this.bindGroupCache.has(e))return this.bindGroupCache.get(e);let r=this.device.createBindGroup({layout:this.layout,entries:[{binding:0,resource:{buffer:this.uniformBuffer}},{binding:1,resource:e.createView()},{binding:2,resource:this.sampler}]});return this.bindGroupCache.set(e,r),r}};var bp=`struct DLight {
913
915
  position: vec3<f32>,
914
916
  intensity: f32,
915
917
  color: vec3<f32>,