@quake2ts/engine 0.0.857 → 0.0.859
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.
|
@@ -936,10 +936,6 @@ fn fragmentMain(@builtin(position) fragCoord: vec4<f32>) -> @location(0) vec4<f3
|
|
|
936
936
|
// Manually unroll: worldDir = col0 * viewDir.x + col1 * viewDir.y + col2 * viewDir.z
|
|
937
937
|
var worldDir = col0 * viewDir.x + col1 * viewDir.y + col2 * viewDir.z;
|
|
938
938
|
|
|
939
|
-
// Apply small scroll offset in Quake horizontal plane
|
|
940
|
-
worldDir.x += uniforms.scroll.x * 0.01;
|
|
941
|
-
worldDir.y += uniforms.scroll.y * 0.01;
|
|
942
|
-
|
|
943
939
|
// Transform from Quake coordinates to GL/WebGPU cubemap coordinates
|
|
944
940
|
// Quake: +X forward, +Y left, +Z up
|
|
945
941
|
// GL cubemap: +X right, +Y up, -Z forward
|
|
@@ -948,6 +944,21 @@ fn fragmentMain(@builtin(position) fragCoord: vec4<f32>) -> @location(0) vec4<f3
|
|
|
948
944
|
cubemapDir.y = worldDir.z; // Quake +Z (up) \u2192 GL +Y (up)
|
|
949
945
|
cubemapDir.z = -worldDir.x; // Quake +X (forward) \u2192 GL -Z (forward)
|
|
950
946
|
|
|
947
|
+
// Apply skybox scroll by rotating the cubemap around the vertical (Y) axis
|
|
948
|
+
// This rotates the entire skybox, scrolling textures while maintaining face relationships
|
|
949
|
+
// Rotation around Y axis: newX = X*cos(\u03B8) - Z*sin(\u03B8), newZ = X*sin(\u03B8) + Z*cos(\u03B8)
|
|
950
|
+
// For 2 checkerboard squares (90\xB0 rotation): need ~1.57 radians at scroll=2.0
|
|
951
|
+
let scrollAngle = uniforms.scroll.x * 0.8; // Scale to radians
|
|
952
|
+
let cosAngle = cos(scrollAngle);
|
|
953
|
+
let sinAngle = sin(scrollAngle);
|
|
954
|
+
|
|
955
|
+
let rotatedX = cubemapDir.x * cosAngle - cubemapDir.z * sinAngle;
|
|
956
|
+
let rotatedZ = cubemapDir.x * sinAngle + cubemapDir.z * cosAngle;
|
|
957
|
+
|
|
958
|
+
cubemapDir.x = rotatedX;
|
|
959
|
+
cubemapDir.z = rotatedZ;
|
|
960
|
+
// cubemapDir.y unchanged - rotation around Y axis
|
|
961
|
+
|
|
951
962
|
return textureSample(t_skybox, s_skybox, cubemapDir);
|
|
952
963
|
}
|
|
953
964
|
`;var Qd=(n=>(n.QUAKE="quake",n.OPENGL="opengl",n.WEBGPU="webgpu",n))(Qd||{});var Ua=class{constructor(){this.coordinateSystem="webgpu"}buildProjectionMatrix(e){let r=F.create(),n=1/Math.tan(e.fov*Ae/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*Ae,o=n*Ae,s=i*Ae,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=T.fromValues(e.position[0],e.position[1],e.position[2]),h=T.transformMat4(T.create(),f,d);T.negate(h,h);let m=F.clone(d);return m[12]=h[0],m[13]=h[1],m[14]=h[2],m}};var vp=new Float32Array([-1,-1,1,-1,1,1,-1,-1,1,1,-1,1]),Ic=class{constructor(e,r){this.device=e;this.format=r;this.matrixBuilder=new Ua;let n=e.createShaderModule({label:"skybox-shader",code:xp});this.vertexBuffer=e.createBuffer({label:"skybox-vertex-buffer",size:vp.byteLength,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),new Float32Array(this.vertexBuffer.getMappedRange()).set(vp),this.vertexBuffer.unmap(),this.uniformBuffer=e.createBuffer({label:"skybox-uniform-buffer",size:64,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|GPUShaderStage.FRAGMENT,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:8,attributes:[{shaderLocation:0,offset:0,format:"float32x2"}]}]},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 Jd(e,i,this.uniformBuffer,this.sampler)}draw(e,r){if(!r.cameraState)throw new Error("SkyboxPipeline: cameraState is required for full-screen skybox rendering");let n=r.cameraState,i=this.matrixBuilder.buildViewMatrix(n),a=hs.fromValues(i[0],i[4],i[8],i[1],i[5],i[9],i[2],i[6],i[10]),o=Math.tan(n.fov*Ae/2),s=n.aspect,c=new Float32Array(16);c[0]=a[0],c[1]=a[1],c[2]=a[2],c[3]=0,c[4]=a[3],c[5]=a[4],c[6]=a[5],c[7]=0,c[8]=a[6],c[9]=a[7],c[10]=a[8],c[11]=0,c[12]=o,c[13]=s,c[14]=r.scroll[0],c[15]=r.scroll[1],this.device.queue.writeBuffer(this.uniformBuffer,0,c);let l=this.bindGroupHelper.getBindGroup(r.cubemap);e.setPipeline(this.pipeline),e.setBindGroup(0,l),e.setVertexBuffer(0,this.vertexBuffer),e.draw(6)}destroy(){this.vertexBuffer.destroy(),this.uniformBuffer.destroy()}},Jd=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 _p=`struct DLight {
|