为什么我的webgl着色器无法正确更改像素片段? [英] Why is my webgl shader not changing pixel fragments correctly?

查看:175
本文介绍了为什么我的webgl着色器无法正确更改像素片段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图获取片段的位置并更改位置的颜色,但是当我尝试执行此操作时,我得到了一种奇怪的效果,即它们不想完全改变.

I'm trying to get position of a fragment and change the color at positions, but when I try to do it, I get a weird effect where they don't want to be changed completely.

请注意青色的颜色,但是该部分应该是透明的.似乎有一些奇怪的四舍五入发生了,我不确定如何解决它.这是怎么回事?

Notice how there is a cyan color, but that part should be transparent. It seems like there's some weird rounding happening, and I'm not sure how to fix it. What is happening here?

        void main() {
        vec4 c0 = vec4(0,1,0,1);
        c0.a *= step(132.0,gl_FragCoord.x);
        gl_FragColor = c0;
        }

推荐答案

您需要显示更多代码.您启用混合了吗?您选择了哪些混合函数和混合方程式.您的画布上有Alpha吗?画布的背景是什么颜色?结束了什么?

You need to show more code. Did you enable blending? What blending functions and blending equations did you pick. Does your canvas have alpha? What color is the background of the canvas or whatever it's over?

这是一个使用您的示例的小程序

Here's a small program using your example

"use strict";
var gl = twgl.getWebGLContext(document.getElementById("c"));
var programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);

var arrays = {
  position: [-1, -1, 0, 1, -1, 0, -1, 1, 0, -1, 1, 0, 1, -1, 0, 1, 1, 0],
};
var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);

var uniforms = { };

gl.useProgram(programInfo.program);
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
twgl.setUniforms(programInfo, uniforms);
twgl.drawBufferInfo(gl, gl.TRIANGLES, bufferInfo);

html, body {
  background: red;
}

<canvas id="c"></canvas>
<script id="vs" type="notjs">
attribute vec4 position;

void main() {
  gl_Position = position;
}
</script>
<script id="fs" type="notjs">
precision mediump float;
void main() {
  vec4 c0 = vec4(0,1,0,1);
  c0.a *= step(132.0,gl_FragCoord.x);
  gl_FragColor = c0;
}
</script>
<script src="https://twgljs.org/dist/twgl-full.min.js"></script>

WebGL将画布与HTML合成.在这种情况下,它将使用预乘alpha red页面

WebGL composites the canvas with HTML. In this case it draws the canvas using premultiplied alpha over the a red page

gl_FragCoord.x小于132 是无效的颜色时,您的着色器将输出0,1,0,0.

Your shader is outputting 0,1,0,0 when gl_FragCoord.x is less than 132 which is an invalid color.

我确定这听起来似乎没有任何意义,但它是无效,因为浏览器需要预乘的颜色.由于alpha为0,这意味着R,G和B不能为零,因为* 0 =0.这是另一种说法,这种情况下浏览器显示的内容是不确定的,因为它是无效的颜色.结果在每个浏览器中可以不同.

I'm sure that sounds like it makes no sense but it's invalid because the browser expects premultiplied colors. Since alpha is 0, that means R, G, and B can't be anything other than zero since anything * 0 = 0. That's another way of saying that what the browser displays in this case is undefined because it's an invalid color The result can be different in each browser.

一些选择

  1. 将Alpha乘以

  1. Premultiply the alpha

将其放在着色器的末尾

gl_FragColor.rgb *= gl.FragColor.a;

  • 告诉WebGL您正在使用未预乘的alpha

  • Tell WebGL you're using un-premultiplied alpha

    gl = someCanvas.getContext("webgl", { premultipliedAlpha: false });
    

    在这种情况下,0,1,0,0是有效颜色

    In that case 0,1,0,0 is a valid color

    如果不需要Alpha,请将其关闭

    If you don't need alpha turn it off

    gl = someCanvas.getContext("webgl", { alpha: false });
    

  • 另一个想法是,如果您的画布与显示的画布大小不同,则浏览器将绘制经过过滤的画布.这些滤波后的像素既不是0,1,0,0也不是0,1,0,1,而是两者之间的双线性插值.

    Another idea is if your canvas is not the same size as it's being displayed then the browser will draw the canvas filtered. Those filtered pixels will be neither 0,1,0,0 nor 0,1,0,1 but instead a bilinear interpolation between the two.

    作为一个示例,让我们制作一个画布,该画布只有10个像素,但显示300个像素.我们会将您的更改从3更改为132.

    As an example let's make a canvas that only has 10 pixels across but display 300 pixels across. We'll change your change to 3 instead of 132.

    "use strict";
    var gl = twgl.getWebGLContext(document.getElementById("c"));
    var programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);
    
    var arrays = {
      position: [-1, -1, 0, 1, -1, 0, -1, 1, 0, -1, 1, 0, 1, -1, 0, 1, 1, 0],
    };
    var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);
    
    var uniforms = {};
    
    gl.useProgram(programInfo.program);
    twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
    twgl.setUniforms(programInfo, uniforms);
    twgl.drawBufferInfo(gl, gl.TRIANGLES, bufferInfo);

    html, body {
      background: red;
    }

    <canvas id="c" width="10" style="width: 300px; height: 150px;"></canvas>
    <script id="vs" type="notjs">
    attribute vec4 position;
    
    void main() {
      gl_Position = position;
    }
    </script>
    <script id="fs" type="notjs">
    precision mediump float;
    void main() {
      vec4 c0 = vec4(0,1,0,1);
      c0.a *= step(3.0,gl_FragCoord.x);
      gl_FragColor = c0;
    }
    </script>
    <script src="https://twgljs.org/dist/twgl-full.min.js"></script>

    这篇关于为什么我的webgl着色器无法正确更改像素片段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆