如何上下移动物体并使其在碰到屋顶和底部时变形?如何沿y轴平移球体(它只是上升,所以不会翻译下来)以及如何变形
我已经创建了一个球体,它通过沿y轴平移而无限旋转和移动,但现在我不得不将它向下移动,并且当它碰撞到底部时我想要它变形,现在我的问题是: ( 1)我如何让我的球体在y轴上上下移动? (2)如何在接触顶部时变形?并在上下移动的过程中恢复与顶部或底部完成接触相同的形状。
我的旋转球是(我按照第11课上的Git枢纽教程这个链接https://github.com/gpjt/webgl-lessons/blob/master/lesson11/index.html上)代码:
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);
}
怎么在这个加代码,它将旋转并且必须接触顶部和底部(letssay,距离y轴中心250和-250处,因为运动必须沿着y轴) 以及如何使其变形当球体在上升时触及250,并且-250 wh如果球体与顶部或底部之间的接触完成,立即恢复并立即恢复,并且该过程应该无限重复。
编辑:
在这个问题上moonVertexIndexBuffer包含广场上打勾功能顶点。 这是我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");
}
**我无法理解如何将它移因为球体是由正方形构成的(取决于在initBuffers()中传递的纬度和经度func(因为我们有一个数组中的所有方块) )**
我的尝试是这样的(但球体只是无限上升,永远不会回落,如何把它)?
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
];
}
EDIT2: 在顶点着色器我保持一致的建议是这样的::我的缩放变形,第一个答案后尝试
<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);
}
在我的蜱()我尝试这样做:
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轴变形工作,同时向上和向下的顶部和底部,什么球的触摸我的代码错了?
谢谢你的上下运动,它是像天堂工作:)。为变形,我正在尝试你的逻辑,因为它的作品,我会标记你的答案,直到然后请求生存+1与你的答案..再次感谢:) – struggling
请参阅编辑的问题,变形不工作,我已更新我的代码,我无法知道我做错了什么,我试着回顾一下你的方法。你能否让我知道我做错了什么,请相应地更新你的答案,以便我将你标记为答案(第一部分为我工作,但不是第二部分) – struggling
又是什么样的这个minDiff?我也无法理解你的第二个答案的逻辑,实际上我想在撞墙时像球一样变形。 – struggling