gpt4 book ai didi

javascript - 如何沿 y 轴平移球体(它只是向上移动,因此平移时不会向下移动)以及如何变形

转载 作者:行者123 更新时间:2023-11-27 23:46:18 25 4
gpt4 key购买 nike

如何让物体上下移动并使其在接触到顶部和底部时变形?

我创建了一个球体,它通过沿 y 轴平移来无限旋转和向上移动,但现在我必须将其向下移动,并且我希望它在向上和底部碰撞时变形,现在我的问题是: (1) 如何让我的球体在 y 轴上上下移动? (2)触顶时如何变形?当上下移动时与顶部或底部接触完成时恢复相同的形状。

我的旋转球体代码是(我已按照此链接 https://github.com/gpjt/webgl-lessons/blob/master/lesson11/index.html 上的 Git Hub 教程第 11 课进行操作):

 var newRotationMatrix = mat4.create();
mat4.identity(newRotationMatrix);
mat4.rotate(newRotationMatrix, degToRad(2 / 10), [0, 1, 0]);
mat4.multiply(newRotationMatrix, [1,0,0], moonRotationMatrix);
gl.drawElements(gl.TRIANGLES, moonVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);

完整功能是:

function tick()
{
requestAnimFrame(tick);
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);

gl.uniform1i(shaderProgram.useLightingUniform, false);
mat4.identity(mvMatrix);
mat4.translate(mvMatrix, [0, 0, -6]);
mat4.multiply(mvMatrix, moonRotationMatrix);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, moonTexture);
gl.uniform1i(shaderProgram.samplerUniform, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, moonVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexTextureCoordBuffer);
gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, moonVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexNormalBuffer);
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, moonVertexNormalBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, moonVertexIndexBuffer);
setMatrixUniforms();

/*rotation part is below*/
var newRotationMatrix = mat4.create();
mat4.identity(newRotationMatrix);
mat4.rotate(newRotationMatrix, degToRad(2 / 10), [0, 1, 0]);
mat4.multiply(newRotationMatrix, [1,0,0], moonRotationMatrix);
gl.drawElements(gl.TRIANGLES, moonVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);

}

在此代码中添加什么,使其旋转并且必须接触顶部和底部(假设它们距离中心沿 y 轴为 250 和 -250,因为运动必须沿 y-轴)以及当球体向上触及250,向下触及-250时如何使其变形,并在球体与顶部或底部接触完成后立即恢复,并且这个过程应该无限重复。

编辑:

在这个问题中,moonVertexIndexBuffer包含tick函数中正方形的顶点。这是我的 initfuffer 函数

function initBuffers(latitudeBands, longitudeBands)
{
var radius = 1;
var vertexPositionData = [];
var normalData = [];
var textureCoordData = [];
for (var latNumber = 0; latNumber <= latitudeBands; latNumber++)
{
var theta = latNumber * Math.PI / latitudeBands;
var sinTheta = Math.sin(theta);
var cosTheta = Math.cos(theta);
for (var longNumber = 0; longNumber <= longitudeBands; longNumber++)
{
var phi = longNumber * 2 * Math.PI / longitudeBands;
var sinPhi = Math.sin(phi);
var cosPhi = Math.cos(phi);
var x = cosPhi * sinTheta;
var y = cosTheta;
var z = sinPhi * sinTheta;
var u = 1 - (longNumber / longitudeBands);
var v = 1 - (latNumber / latitudeBands);
normalData.push(x);
normalData.push(y);
normalData.push(z);
textureCoordData.push(u);
textureCoordData.push(v);
vertexPositionData.push(radius * x);
vertexPositionData.push(radius * y);
vertexPositionData.push(radius * z);
}
}
alert("vertexPositionData:" + vertexPositionData);
var indexData = [];
for (var latNumber = 0; latNumber < latitudeBands; latNumber++) {
for (var longNumber = 0; longNumber < longitudeBands; longNumber++) {
var first = (latNumber * (longitudeBands + 1)) + longNumber;
var second = first + longitudeBands + 1;
indexData.push(first);
indexData.push(second);
indexData.push(first + 1);
indexData.push(second);
indexData.push(second + 1);
indexData.push(first + 1);
//console.log("four points for iteration" + latNumber, +longNumber + " are " + "1: " + first + "2 :" + (first + 1) + "3: " + (second) + "4 :" + (second + 1));
}
}
moonVertexNormalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexNormalBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normalData), gl.STATIC_DRAW);
moonVertexNormalBuffer.itemSize = 3;
moonVertexNormalBuffer.numItems = normalData.length / 3;

moonVertexTextureCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexTextureCoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordData), gl.STATIC_DRAW);
moonVertexTextureCoordBuffer.itemSize = 2;
moonVertexTextureCoordBuffer.numItems = textureCoordData.length / 2;
///
moonVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), gl.STATIC_DRAW);
moonVertexPositionBuffer.itemSize = 3;
moonVertexPositionBuffer.numItems = vertexPositionData.length / 3;

moonVertexIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, moonVertexIndexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), gl.DYNAMIC_DRAW);
moonVertexIndexBuffer.itemSize = 1;
moonVertexIndexBuffer.numItems = indexData.length;
}

function tick()
{
requestAnimFrame(tick);
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);
// var lighting = false;
gl.uniform1i(shaderProgram.useLightingUniform, false);

/*I removed some part here */

mat4.identity(mvMatrix);
mat4.translate(mvMatrix, [0, 0, -6]);
mat4.multiply(mvMatrix, moonRotationMatrix);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, moonTexture);
gl.uniform1i(shaderProgram.samplerUniform, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, moonVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexTextureCoordBuffer);
gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, moonVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexNormalBuffer);
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, moonVertexNormalBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, moonVertexIndexBuffer);
setMatrixUniforms();

var newRotationMatrix = mat4.create();
mat4.identity(newRotationMatrix);
mat4.rotate(newRotationMatrix, degToRad(2 / 10), [0, 1, 0], newRotationMatrix);
mat4.multiply(newRotationMatrix, moonRotationMatrix, moonRotationMatrix);

gl.drawElements(gl.TRIANGLES, moonVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);

}

这是我的顶点着色器:

 <script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;
attribute vec2 aTextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;
uniform vec3 uAmbientColor;
uniform vec3 uLightingDirection;
uniform vec3 uDirectionalColor;
uniform bool uUseLighting;
varying vec2 vTextureCoord;
varying vec3 vLightWeighting;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vTextureCoord = aTextureCoord;
if (!uUseLighting) {
vLightWeighting = vec3(1.0, 1.0, 1.0);
} else {
vec3 transformedNormal = uNMatrix * aVertexNormal;
float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);
vLightWeighting = uAmbientColor + uDirectionalColor * directionalLightWeighting;
}
}
</script>

这是 initshaders 函数

 function initShaders()
{
var fragmentShader = getShader(gl, "shader-fs");
var vertexShader = getShader(gl, "shader-vs");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialise shaders");
}
gl.useProgram(shaderProgram);
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);
shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
shaderProgram.nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix");
shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
shaderProgram.useLightingUniform = gl.getUniformLocation(shaderProgram, "uUseLighting");
shaderProgram.ambientColorUniform = gl.getUniformLocation(shaderProgram, "uAmbientColor");
shaderProgram.lightingDirectionUniform = gl.getUniformLocation(shaderProgram, "uLightingDirection");
shaderProgram.directionalColorUniform = gl.getUniformLocation(shaderProgram, "uDirectionalColor");
}

**我无法理解如何无限地上下移动它(沿 y 轴平移它),因为我们将所有正方形都放在一个数组中,因为球体是由正方形组成的(取决于传入的纬度和经度) initBuffers() 函数)**

我的尝试是这样的(但是球体只是无限上升,永远不会下降,如何将其降低)?

   var translation = [0, 0.5,0];
function tick()
{
....//I am elminating the code which was shown previously
var translationMatrix = makeTranslation(translation[0], translation[1], translation[2]);
mat4.multiply(moonRotationMatrix, translationMatrix, moonRotationMatrix);
}
function makeTranslation(tx, ty, tz) {

return [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
tx, ty, tz, 1
];
}

编辑2:在第一个答案之后,我尝试缩放变形:在顶点着色器中,我按照建议保持统一,如下所示:

 <script id="shader-vs" type="x-shader/x-vertex">
uniform vec4 uScaleY;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
}
}
</script>

在 initshader() 中我这样做:

shaderProgram.uScaleYAttribute = gl.getUniformLocation(shaderProgram, "uScaleY");

在 setuniform 中我这样做:

var yScale =[0,1,0];
function setMatrixUniforms()
{
gl.uniformMatrix4fv(shaderProgram.uScaleYAttribute, false, yScale);
}

在我的tick()中我尝试这样做:

  var newRotationMatrix = mat4.create();
mat4.identity(newRotationMatrix);
mat4.rotate(newRotationMatrix, degToRad(2 / 10), [0, 1, 0]);
mat4.multiply(newRotationMatrix, moonRotationMatrix, moonRotationMatrix);
translateMatrix = translation(translate[0], translate[1], translate[2]);
mat4.multiply(moonRotationMatrix, translateMatrix,moonRotationMatrix);
var maxY =1.5;
var moonPosY = moonRotationMatrix[3 * 4 +1];
if (moonPosY > maxY || moonPosY < (-maxY))
{
translate[1] *= -1;
}

var maxDiff = 0.05;
var minDiff = 0.01;
var diff = Math.abs(moonPosY - maxY);

if (diff < maxDiff)//sphere when go up
{
yScale = 1 - (minDiff - diff) * 0.1;
}
/*
else if (moonPosY > (-maxDiff)) // scaling when sphere come down
{
yScale = 1 - (minDiff - diff) * 0.1;
}
*/
gl.drawElements(gl.TRIANGLES, moonVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);

当上下触摸顶部和底部的球体时,缩放不适用于沿 y 轴的变形,我的代码有什么问题吗?

最佳答案

更改您的tick,以便它跟踪总翻译并在达到阈值时反转使用的翻译向量。

它会是这样的:

var maxY = 100;
var moonPosY = moonRotationMatrix[/*row*/ 3 * 4 + /*col*/ 1];

if (moonPosY < maxY || moonPosY < (-maxY)) {
translation = translation.map(a => -a);
// or simply
// translation[1] *= -1;
// if you want to reverse it just on Y axis
}

要对其进行变形,这取决于您想要的变形,但如果您只是想沿 Y 轴挤压它,您可以为 Y 缩放的顶点着色器添加一个统一,并用以下内容填充它:

var yScale = 1;
var maxDiff = 10;

var diff = Math.abs(moonPosY - maxY);

if (diff < maxDiff) {
yScale = 1 - (minDiff - diff) * 0.1;
}

关于javascript - 如何沿 y 轴平移球体(它只是向上移动,因此平移时不会向下移动)以及如何变形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33148865/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com