<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>てst</title>
</head>
<body>
<!-- canvas:用来展示WebGPU渲染的结果 -->
<canvas id="webgpu" width="500" height="500"></canvas>
translationx:<input type="range" min="0" max="500" step="0.1" name="translationx" value="230.2" /><br>
translationy:<input type="range" min="0" max="500" step="0.1" name="translationy" value="230.2" /><br>
rotationx:<input type="range" min="0" max="360" step="0.1" name="rotationx" value="0" /><br>
rotationy:<input type="range" min="0" max="360" step="0.1" name="rotationy" value="0" /><br>
rotationz:<input type="range" min="0" max="360" step="0.1" name="rotationz" value="0" /><br>
scalex:<input type="range" min="-5" max="5" step="0.1" name="scalex" value="1.1" /><br>
scaley:<input type="range" min="-5" max="5" step="0.1" name="scaley" value="1.1" /><br>
<script type="module">
//"C:\Program Files\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="D:\angular\webgpu\n" --disable-site-isolation-trials
import * as glMatrix from './dist/esm/index.js';
function createTranVertices() {
const vertexData = new Float32Array([
// 左栏
0, 0, 0,
30, 0, 0,
0, 150, 0,
30, 150, 0,
// 顶部梯级
30, 0, 0,
100, 0, 0,
30, 30, 0,
100, 30, 0,
// 中间梯级
30, 60, 0,
70, 60, 0,
30, 90, 0,
70, 90, 0,
// 左栏后退
0, 0, 30,
30, 0, 30,
0, 150, 30,
30, 150, 30,
// 顶部回档
30, 0, 30,
100, 0, 30,
30, 30, 30,
100, 30, 30,
// 中间梯级后面
30, 60, 30,
70, 60, 30,
30, 90, 30,
70, 90, 30,
]);
const indexData = new Uint32Array([
// 正面
0, 1, 2, 2, 1, 3, // 左栏
4, 5, 6, 6, 5, 7, // 顶部运行
8, 9, 10, 10, 9, 11, // 中间运行
// 后退
12, 13, 14, 14, 13, 15, // 左栏后退
16, 17, 18, 18, 17, 19, // 顶部跑回
20, 21, 22, 22, 21, 23, // 中间跑回
0, 5, 12, 12, 5, 17, // 顶部
5, 7, 17, 17, 7, 19, // 右上横档
6, 7, 18, 18, 7, 19, // 顶部梯级底部
6, 8, 18, 18, 8, 20, // 顶部和中间梯级之间
8, 9, 20, 20, 9, 21, // 中间梯级顶部
9, 11, 21, 21, 11, 23, // 右中横档
10, 11, 22, 22, 11, 23, // 中间梯级底部
10, 3, 22, 22, 3, 15, // 右干
2, 3, 14, 14, 3, 15, // 底部
0, 2, 12, 12, 2, 14, // 左边
]);
return {
vertexData,
indexData,
numVertices: indexData.length,
};
}
async function main() {
const adapter = await navigator.gpu?.requestAdapter();
const device = await adapter?.requestDevice();
if (!device) {
fail('need a browser that supports WebGPU');
return;
}
// Get a WebGPU context from the canvas and configure it
const canvas = document.querySelector('canvas');
const context = canvas.getContext('webgpu');
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
context.configure({
device,
format: presentationFormat,
alphaMode: 'premultiplied',
});
const module = device.createShaderModule({
code: `
struct Uniforms {
color: vec4f,
matrix: mat4x4f,
};
struct Vertex {
@location(0) position: vec4f,
};
struct VSOutput {
@builtin(position) position: vec4f,
};
@group(0) @binding(0) var<uniform> uni: Uniforms;
@vertex fn vs(vert: Vertex) -> VSOutput {
var vsOut: VSOutput;
vsOut.position = uni.matrix * vert.position;
return vsOut;
}
@fragment fn fs(vsOut: VSOutput) -> @location(0) vec4f {
return uni.color;
}
`
});
const pipeline = device.createRenderPipeline({
label: 'just 2d position',
layout: 'auto',
vertex: {
module,
entryPoint: 'vs',
buffers: [
{
arrayStride: (3) * 4, // (2) floats, 4 bytes each
attributes: [
{ shaderLocation: 0, offset: 0, format: 'float32x3' }, // position
],
},
],
},
fragment: {
module,
entryPoint: 'fs',
targets: [{ format: presentationFormat }],
},
});
// color, resolution, padding, matrix
const uniformBufferSize = (4 + 16) * 4;
const uniformBuffer = device.createBuffer({
label: 'uniforms',
size: uniformBufferSize,
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
});
const uniformValues = new Float32Array(uniformBufferSize / 4);
// offsets to the various uniform values in float32 indices
const kColorOffset = 0;
const kMatrixOffset = 4;
const colorValue = uniformValues.subarray(kColorOffset, kColorOffset + 4);
const matrixValue = uniformValues.subarray(kMatrixOffset, kMatrixOffset + 16);
// The color will not change so let's set it once at init time
colorValue.set([Math.random(), Math.random(), Math.random(), 1]);
const { vertexData, indexData, numVertices } = createTranVertices();
const vertexBuffer = device.createBuffer({
label: 'vertex buffer vertices',
size: vertexData.byteLength,
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
});
device.queue.writeBuffer(vertexBuffer, 0, vertexData);
const indexBuffer = device.createBuffer({
label: 'index buffer',
size: indexData.byteLength,
usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,
});
device.queue.writeBuffer(indexBuffer, 0, indexData);
const bindGroup = device.createBindGroup({
label: 'bind group for object',
layout: pipeline.getBindGroupLayout(0),
entries: [
{ binding: 0, resource: { buffer: uniformBuffer } },
],
});
const renderPassDescriptor = {
label: 'our basic canvas renderPass',
colorAttachments: [
{
// view: <- to be filled out when we render
loadOp: 'clear',
storeOp: 'store',
},
],
};
function render() {
// Get the current texture from the canvas context and
// set it as the texture to render to.
renderPassDescriptor.colorAttachments[0].view =
context.getCurrentTexture().createView();
const encoder = device.createCommandEncoder();
const pass = encoder.beginRenderPass(renderPassDescriptor);
pass.setPipeline(pipeline);
pass.setVertexBuffer(0, vertexBuffer);
pass.setIndexBuffer(indexBuffer, 'uint32');
let translationx = document
.querySelector('input[name="translationx"]')
.value;
let translationy = document
.querySelector('input[name="translationy"]')
.value;
let rotationx = document
.querySelector('input[name="rotationx"]')
.value;
rotationx = rotationx * Math.PI / 180;
let rotationy = document
.querySelector('input[name="rotationy"]')
.value;
rotationy = rotationy * Math.PI / 180;
let rotationz = document
.querySelector('input[name="rotationz"]')
.value;
rotationz = rotationz * Math.PI / 180;
let scalex = document
.querySelector('input[name="scalex"]')
.value;
let scaley = document
.querySelector('input[name="scaley"]')
.value;
let translationMatrix = glMatrix.mat4.create();
glMatrix.mat4.translate(translationMatrix, translationMatrix, glMatrix.vec3 .fromValues(translationx, translationy,1));
let rotationMatrix = glMatrix.mat4.create();
// glMatrix.mat4.rotate(rotationMatrix, rotationMatrix, 1, glMatrix.vec3.fromValues(Math.sin(rotation), Math.cos(rotation), 0));
//glMatrix.mat4.rotate(rotationMatrix, rotationMatrix, rotation);
glMatrix.mat4.rotateX(rotationMatrix, rotationMatrix, rotationx);
glMatrix.mat4.rotateY(rotationMatrix, rotationMatrix, rotationy);
glMatrix.mat4.rotateZ(rotationMatrix, rotationMatrix, rotationz);
let scaleMatrix = glMatrix.mat4.create();
glMatrix.mat4.scale(scaleMatrix, scaleMatrix, [scalex, scaley, 1]);
// make a matrix that will move the origin of the 'F' to its center.
// const moveOriginMatrix = mat3.translation([-50, -75]);
let moveOriginMatrix = glMatrix.mat4.create();
//glMatrix.mat4.translate(moveOriginMatrix, moveOriginMatrix, glMatrix.vec2.fromValues(-50, -70));
//-------------
//固定相机,正交投影
// const aspect = Math.abs(canvas.width / canvas.height);
let projectionMatrix = glMatrix.mat4.create();
// glMatrix.mat4.perspective(projectionMatrix, (2 * Math.PI) / 5, aspect, 1, 100.0);
// glMatrix.mat4.projection(projectionMatrix,400,canvas.clientWidth, canvas.clientHeight);
glMatrix.mat4.ortho(projectionMatrix,0,canvas.clientWidth, 0,canvas.clientHeight,400,-400);
/*
mat4.ortho(
0, // 左边
canvas.clientWidth, // 正确的
canvas.clientHeight, // 底部
0, // 顶部
400, // 靠近
-400, // 远的
matrixValue, // 夏令时
);
*/
//-------------
let matrix = glMatrix.mat4.create();
//glMatrix.mat4.multiply(matrix, translationMatrix, rotationMatrix);
glMatrix.mat4.multiply(matrix,projectionMatrix, translationMatrix);
glMatrix.mat4.multiply(matrix, matrix, rotationMatrix);
glMatrix.mat4.multiply(matrix, matrix, scaleMatrix);
// matrix = mat3.multiply(matrix, moveOriginMatrix);
glMatrix.mat4.multiply(matrix, matrix, moveOriginMatrix);
/*
console.log('matrix:' + matrix);
console.log('matrix0-3:' + matrix.slice(0, 3));
console.log('matrixValue:' + matrixValue);
*/
// Set the uniform values in our JavaScript side Float32Array
// resolutionValue.set([canvas.width, canvas.height]);
/*
matrixValue.set([
...matrix.slice(0, 3), 0,
...matrix.slice(3, 6), 0,
...matrix.slice(6, 9), 0,
]);
*/
//console.log(matrix)
matrixValue.set(matrix);
// upload the uniform values to the uniform buffer
device.queue.writeBuffer(uniformBuffer, 0, uniformValues);
pass.setBindGroup(0, bindGroup);
// pass.drawIndexed(numVertices);
//pass.draw(3);
pass.drawIndexed(numVertices);
pass.end();
const commandBuffer = encoder.finish();
device.queue.submit([commandBuffer]);
}
//-----------------
document
.querySelector('input[name="translationx"]')
.addEventListener("input", (e) => {
render();
});
document
.querySelector('input[name="translationy"]')
.addEventListener("input", (e) => {
render();
});
document
.querySelector('input[name="rotationx"]')
.addEventListener("input", (e) => {
render();
});
document
.querySelector('input[name="rotationy"]')
.addEventListener("input", (e) => {
render();
});
document
.querySelector('input[name="rotationz"]')
.addEventListener("input", (e) => {
render();
});
document
.querySelector('input[name="scalex"]')
.addEventListener("input", (e) => {
render();
});
document
.querySelector('input[name="scaley"]')
.addEventListener("input", (e) => {
render();
});
const observer = new ResizeObserver(entries => {
for (const entry of entries) {
const canvas = entry.target;
const width = entry.contentBoxSize[0].inlineSize;
const height = entry.contentBoxSize[0].blockSize;
canvas.width = Math.max(1, Math.min(width, device.limits.maxTextureDimension2D));
canvas.height = Math.max(1, Math.min(height, device.limits.maxTextureDimension2D));
// re-render
render();
}
});
observer.observe(canvas);
}
function fail(msg) {
alert(msg);
}
main();
</script>
</body>文章来源:https://www.toymoban.com/news/detail-837303.html
</html>文章来源地址https://www.toymoban.com/news/detail-837303.html
到了这里,关于3d,正交投影,所有面都一种颜色的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!