Javascript 如何使用gl_位置编程平移纹理

Javascript 如何使用gl_位置编程平移纹理,javascript,textures,webgl,opengl-es-2.0,Javascript,Textures,Webgl,Opengl Es 2.0,我可以很容易地缩放纹理,但无法正确平移 以下是着色器的代码片段: var vertexShader = createVertexShader([ 'attribute vec3 attrVertexPos;', 'attribute vec2 attrTextureCoord;', 'varying highp vec2 vTextureCoord;', 'uniform float zoomFactor;', 'uniform vec2 panCoord

我可以很容易地缩放纹理,但无法正确平移

以下是着色器的代码片段:

var vertexShader = createVertexShader([
    'attribute vec3 attrVertexPos;',
    'attribute vec2 attrTextureCoord;',
    'varying highp vec2 vTextureCoord;',
    'uniform float zoomFactor;',
    'uniform vec2 panCoord;',
    'void main(void) {',
        '\tgl_Position = vec4(attrVertexPos.xy  + panCoord.xy, 0, zoomFactor);',
        '\tvTextureCoord = attrTextureCoord;',
    '}'
  ].join('\n'));

//create and compile Fragment Shader
var fragmentShader = createFragmentShader([
'#ifdef GL_FRAGMENT_PRECISION_HIGH',
    'precision highp float;',
'#else',
    'precision mediump float;',
'#endif',
    'varying highp vec2 vTextureCoord;',
    'uniform sampler2D uImage;',
    'void main(void) {',
        '\tgl_FragColor = texture2D(uImage, vTextureCoord);',
    '}'
   ].join('\n'));
Javascript代码:

document.getElementById('canvas').onmousedown = function(e) {
if(startX === undefined) {
    startX = e.clientX;
    startY = e.clientY;
} else {
    startX = lastX;
    startY = lastY;
}
isMouseDown = true;
};
document.getElementById('canvas').onmouseup = function() {
    isMouseDown = false;
    previousTranslation[0] = xVal/100*zoomFactor;
    previousTranslation[1] = yVal/100*zoomFactor;
};
document.getElementById('canvas').onmouseout = function() {
    isMouseDown = false;
};
document.getElementById('canvas').onmousemove = function(e) {
    if (isMouseDown) {
        xVal = (lastX-startX)/canvas.width*100;
    yVal = (startY-lastY)/canvas.height*100;
    console.log(xVal/100*2.0 + ',' +yVal/100*2.0);
    gl.uniform2fv(pan, new Float32Array([previousTranslation[0] + xVal/100*zoomFactor, previousTranslation[1] + yVal/100*zoomFactor]));
    }
};

我认为可以在javascript方面做一些事情,因为着色器看起来很好。有什么建议吗?

发生错误的原因是您试图将vec4写入浮点,但这行不通。浮点数与vec4相乘得到vec4,因此有如下情况:

gl_Position.x = aVertexPosition.x * u_CosB - aVertexPosition.y * u_SinB
     float    =     float        *  vec4   -       float       * vec4
编辑

如果这真的是关于平移(移动对象),那么我不明白为什么会涉及到sin和cos术语。此外:为什么x坐标会根据y坐标进行修改?只有在进行某些轮换(不是pan)时才需要这样做。最后,对象根本不可见,因为您将所有顶点的y坐标设置为0,这意味着它们折叠为一条线

因此,为了实现平移,代码可能看起来像这样:

//Contains offset in normalized device coordinates along x and y direction
uniform vec2 pan;

attribute vec4 aVertexPosition;

void main()
{
    gl_Position = vec4(aVertexPosition.xy + pan.xy, 0, 1.0);
}
编辑2

在mouseMove中计算平移的方法是错误的。您必须计算到鼠标按下位置的距离(不确定您现在计算的是什么):

当您需要时,更快/更慢地将
xVal
yVal
乘以常数因子。当平底锅走错方向时,你可能需要反转其中一个方向

编辑3

mousedown函数现在没有什么意义了?为什么在第一次单击后它的行为会有所不同?唯一的代码应该是:

document.getElementById('canvas').onmousedown = function(e) {
    startX = e.clientX;
    startY = e.clientY;
    isMouseDown = true;
};
此外,当第二次调用鼠标向上移动功能时,您会覆盖
previousTranslation
的值,而不是将当前翻译添加到该值中。正确:

document.getElementById('canvas').onmouseup = function() {
    isMouseDown = false;

    if (previousTranslation[0] == undefined)
    {
        previousTranslation[0] = 0.0;
        previousTranslation[1] = 0.0;
    }

    previousTranslation[0] += xVal/100*zoomFactor;
    previousTranslation[1] += yVal/100*zoomFactor;
};

你得到了哪一个错误?刚刚修复了它,是一个小错误,我用vec4代替float来表示u_CosB和u_SinB,但正如预期的那样,纹理不适合我平移。有什么建议吗?很难说,因为你没有提供任何关于你的CosB等的信息。使用MVCE的新问题将是一个好主意。抱歉,我无法关闭它,我认为问题是在webgl纹理中实现平移功能,而不是修复错误。然后更新此问题并提供所有必要的信息。制服是什么,它们设置了哪些值?这是问题的一部分。好的,pan.xy期望值是多少?希望对象在两个方向上移动的距离(在标准化设备坐标中,当不使用投影时,用于指定顶点的同一坐标系).在长时间阅读书籍和做一些示例后,我对WebGL有点适应,我写了这个,它在鼠标滚轮上放大/缩小,但平移对我来说仍然是一个难题,你能修改小提琴来修复平移吗?这不是工作原理。请发布包含相关代码的新问题。
document.getElementById('canvas').onmouseup = function() {
    isMouseDown = false;

    if (previousTranslation[0] == undefined)
    {
        previousTranslation[0] = 0.0;
        previousTranslation[1] = 0.0;
    }

    previousTranslation[0] += xVal/100*zoomFactor;
    previousTranslation[1] += yVal/100*zoomFactor;
};