浏览器缩放时片段着色器位置会更改

时间:2016-07-16 02:24:39

标签: javascript webgl shader cocos2d-js

我使用cocos2d-js webgl模式创建一个非常简单的着色器效果:

绘制一个具有给定中心位置和半径的实心圆。

片段着色器:

uniform vec2 position;
uniform vec3 lightColor;
uniform float lightSize;

    void main()
    {
        float distance = distance(gl_FragCoord.xy, position);
        if (distance <= lightSize) {
            gl_FragColor = vec4(lightColor, 1.0);
        }
        else {
            gl_FragColor = vec4(lightColor, 0.0);   
        }
    }

当浏览器未缩放(100%)时,此代码可以正常工作。

但是,当我尝试将浏览器缩放到80%或120%时,我发现圆圈的绘制偏离了我设置的中心位置。

我不知道如何解决这个问题,以确保无论我如何缩放浏览器,圆圈始终位于我设置的中心位置。

任何建议都将不胜感激,谢谢:)

2 个答案:

答案 0 :(得分:0)

如果你的窗口是(200,200),那么中心是(100,100)。但如果你的窗户突然变成(400,400),(100,100)不再是中心,对吗?这就是“窗口空间”的含义:相对于窗口的空间。

如果要在不依赖于窗口属性的空间中进行计算,则必须将gl_FragCoord转换为该空间。当然,您的position也必须在同一个空间内。

一个常见的解决方案是获取窗口的大小并将其作为制服传递。然后将gl_FragCoord.xy除以该大小。此空间中窗口的中心始终为(0.5,0.5)。但是,每当窗口改变尺寸时,您必须确保更新此统一

答案 1 :(得分:0)

尝试下面的着色器我看到没有问题

&#13;
&#13;
var fs = `
precision mediump float;
uniform vec2 position;
uniform vec3 lightColor;
uniform float lightSize;

    void main()
    {
        float distance = distance(gl_FragCoord.xy, position);
        if (distance <= lightSize) {
            gl_FragColor = vec4(lightColor, 1.0);
        }
        else {
            gl_FragColor = vec4(lightColor, 0.0);   
        }
    }
`;
var vs = `
attribute vec4 a_position;
void main() {
  gl_Position = a_position;
}
`;

var gl = document.querySelector("canvas").getContext("webgl");
var programInfo = twgl.createProgramInfo(gl, [vs, fs]);
var bufferInfo = twgl.createBufferInfoFromArrays(gl, {
  a_position: { 
    numComponents: 2,
    data: [
      -1, -1,
      -1,  1,
       1, -1,
       1, -1,
      -1,  1,
       1,  1,
    ],
  },
});

function render(time) {
  time *= 0.001;
  twgl.resizeCanvasToDisplaySize(gl.canvas);
  gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

  var uniforms = {
    position: [gl.canvas.width / 2, gl.canvas.height / 2],
    lightColor: [0.5 + Math.sin(time * 10) * 0.25, 0, 0],
    lightSize: 100,
  };    
      
  gl.useProgram(programInfo.program);
  twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
  twgl.setUniforms(programInfo, uniforms);
  twgl.drawBufferInfo(gl, gl.TRIANGLES, bufferInfo);
  requestAnimationFrame(render);
}
requestAnimationFrame(render);
      
&#13;
body { margin: 0; }
canvas { display: block; width: 100vw; height: 100vh; }
&#13;
<script src="https://twgljs.org/dist/twgl.min.js"></script>
<canvas></canvas>
&#13;
&#13;
&#13;

你有什么设定位置?上面的代码将其设置为gl.canvas.width / 2, gl.canvas.height / 2,它是画布的中间部分