var t = model_transform;
model_transform = t;
var temp = Math.PI/180;
var degreeOfRot = 45;
var time = Math.sin(graphics_state.animation_time/2000); //Represents the graphics time
model_transform = mult(model_transform, translation(0,0,0));
model_transform = mult(model_transform, rotation(degreeOfRot*time, 0.0,0.0,1.0));
model_transform = mult(model_transform, scale(0.3,0.9,0));
this.shapes.box.draw(graphics_state,model_transform,this.red);
我一直在寻找堆叠上的其他答案但仍然无法理解......我觉得它与数学有关但不确定
答案 0 :(得分:2)
我认为你需要类似的东西(注意:我使用以原点为中心的单位立方体,因此有一个额外的比例使其变长并且需要额外的平移以移动原点)
// spread the blades round the circle
const rotationOffset = i / settings.numBlades * Math.PI * 2;
// rotate around Z
world = m4.multiply(world, m4.rotationZ(rotationOffset + time));
// move it away from center
world = m4.multiply(world, m4.translation([settings.xoff, settings.yoff, 0]));
// scale the unit cube to be long in Y
world = m4.multiply(world, m4.scaling([1, 10, 1]));
// the unit cube is centered around the origin. It's 1 unit big
// so this tranlation will move it's origin to the bottom left edge
world = m4.multiply(world, m4.translation([-.5, .5, 0]));
您可能会发现this article有用,可能是this one或this one
const vs = `
uniform mat4 u_worldViewProjection;
attribute vec4 position;
void main() {
gl_Position = u_worldViewProjection * position;
}
`;
const fs = `
precision mediump float;
uniform vec4 u_color;
void main() {
gl_FragColor = u_color;
}
`;
"use strict";
const m4 = twgl.m4;
const v3 = twgl.v3;
const gl = document.getElementById("c").getContext("webgl");
const settings = {
xoff: 0,
yoff: 0,
numBlades: 1,
};
// compiles shaders, links program, looks up locations
const programInfo = twgl.createProgramInfo(gl, [vs, fs]);
// calls gl.createBuffer, gl.bindBuffer, gl.bufferData for positions, texcoords
const centerBufferInfo = twgl.primitives.createSphereBufferInfo(gl, 1, 24, 12);
const bladeBufferInfo = twgl.primitives.createCubeBufferInfo(gl);
function render(time) {
time *= 0.001;
twgl.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
const fov = 45 * Math.PI / 180;
const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
const zNear = 0.5;
const zFar = 100;
const projection = m4.perspective(fov, aspect, zNear, zFar);
const eye = [0, 0, -40];
const target = [0, 0, 0];
const up = [0, 1, 0];
const camera = m4.lookAt(eye, target, up);
const view = m4.inverse(camera);
const viewProjection = m4.multiply(projection, view);
gl.useProgram(programInfo.program);
// draw center
// calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
twgl.setBuffersAndAttributes(gl, programInfo, centerBufferInfo);
// calls gl.uniformXXX
twgl.setUniforms(programInfo, {
u_color: [1, 0.5, 1, 1],
u_worldViewProjection: m4.translate(viewProjection, [0, 0, 1]),
});
// calls gl.drawArrays or gl.drawElements
twgl.drawBufferInfo(gl, centerBufferInfo);
// draw blades
// calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
twgl.setBuffersAndAttributes(gl, programInfo, bladeBufferInfo);
for (let i = 0; i < settings.numBlades; ++i) {
let world = m4.identity();
// spread the blades round the circle
const rotationOffset = i / settings.numBlades * Math.PI * 2;
// rotate around Z
world = m4.multiply(world, m4.rotationZ(rotationOffset + time));
// move it away from center
world = m4.multiply(world, m4.translation([settings.xoff, settings.yoff, 0]));
// scale the unit cube to be long in Y
world = m4.multiply(world, m4.scaling([1, 10, 1]));
// the unit cube is centered around the origin. It's 1 unit big
// so this tranlation will move it's origin to the bottom left edge
world = m4.multiply(world, m4.translation([-.5, .5, 0]));
// calls gl.uniformXXX
twgl.setUniforms(programInfo, {
u_color: [1, 0, 0, 1],
u_worldViewProjection: m4.multiply(viewProjection, world),
});
// calls gl.drawArrays or gl.drawElements
twgl.drawBufferInfo(gl, bladeBufferInfo);
}
requestAnimationFrame(render);
}
requestAnimationFrame(render);
setupSlider("#xoffSlider", "#xoff", "xoff", 10);
setupSlider("#yoffSlider", "#yoff", "yoff", 10);
setupSlider("#bladesSlider", "#blades", "numBlades", 1);
function setupSlider(sliderId, labelId, property, divisor) {
const slider = document.querySelector(sliderId);
const label = document.querySelector(labelId);
function updateLabel() {
label.textContent = settings[property];
}
slider.addEventListener('input', e => {
settings[property] = parseInt(slider.value) / divisor;
updateLabel();
});
updateLabel();
slider.value = settings[property];
}
&#13;
body { margin: 0; }
canvas { display: block; width: 100vw; height: 100vh; }
#ui {
position: absolute;
left: 10px;
top: 10px;
z-index: 2;
background: rgba(255, 255, 255, 0.9);
padding: .5em;
}
&#13;
<script src="https://twgljs.org/dist/3.x/twgl-full.min.js"></script>
<canvas id="c"></canvas>
<div id="ui">
<div><input id="xoffSlider" type="range" min="0" max="100"/><label>xoff: <span id="xoff"></span></label></div>
<div><input id="yoffSlider" type="range" min="0" max="100"/><label>yoff: <span id="yoff"></span></label></div>
<div><input id="bladesSlider" type="range" min="1" max="20"/><label>blades: <span id="blades"></span></label></div>
</div>
&#13;