fwe*_*eth 9 javascript gpu intel glsl webgl
我遇到的情况是,着色器在我的 Apple (M1) iMac(以及 iPhone)上产生的输出与我的 Intel(i5-4300U / Haswell-ULT 集成图形控制器)Thinkpad 440 上产生的输出完全不同(更多信息见评论)。然而,Chrome 和 Safari 等浏览器之间似乎没有区别。Chrome 和 GNOME Web 在 iMac 上分别生成相同的图像。笔记本电脑。我的 Intel Thinkpad 13 Chromebook 也显示 Intel 版本(显然无法测试除 Chrome 之外的其他浏览器)。这可能是什么原因?
[编辑] 大多数人(朋友和下面评论的人)似乎都获得了苹果版本,所以只有我和我的两台笔记本电脑显然获得了英特尔版本?
这是着色器:
const gl = document.querySelector("canvas").getContext("webgl");
gl.canvas.width = gl.canvas.height = 512
gl.viewport(0, 0, 512, 512);
const programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);
const bufferInfo = twgl.createBufferInfoFromArrays(gl, {
a_Position: {
numComponents: 2,
data: [-1, -1, -1, 3, 3, -1]
},
});
gl.useProgram(programInfo.program);
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
twgl.drawBufferInfo(gl, bufferInfo);Run Code Online (Sandbox Code Playgroud)
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<script id="vs" type="x-shader/x-vertex">
attribute vec4 a_Position;
varying vec2 v_Position;
varying vec2 v_TexCoord;
void main() {
v_Position = a_Position.xy;
v_TexCoord = a_Position.xy / 2.0 + 0.5;
gl_Position = a_Position;
}
</script>
<script id="fs" type="x-shader/x-vertex">
precision highp float;
varying vec2 v_Position;
varying vec2 v_TexCoord;
vec2 compMult(vec2 u, vec2 v) {
return vec2(u.x * v.x - u.y * v.y, u.x * v.y + u.y * v.x);
}
vec2 G(vec3 x) {
float lenx = length(x);
float ang = 350.0 * lenx;
return vec2(cos(ang), sin(ang)) / lenx;
}
void main() {
gl_FragColor.a = 1.0;
vec3 x0 = vec3(v_TexCoord, 1);
vec2 amplitude;
for(int i = 0; i < 10; i++) {
for(int j = 0; j < 10; j++) {
vec2 pos = 0.05 + vec2(i, j) / 10.0;
vec3 x = vec3(0.4 + 0.2 * pos, 0);
float disx0x = distance(x0, x);
amplitude += compMult(
G(x - vec3(-0.4765625, -0.671875, 300)),
compMult(
vec2(-1.0 / disx0x, 350.0),
G(x - x0) / disx0x
)
);
}
}
gl_FragColor.r = length(amplitude) / 10.0;
}
</script>
<canvas></canvas>Run Code Online (Sandbox Code Playgroud)
以下是不同的输出:
(苹果)
(英特尔)
[编辑]我认为我已经非常接近了,请看以下片段:
const gl = document.querySelector("canvas").getContext("webgl");
gl.canvas.width = gl.canvas.height = 512
gl.viewport(0, 0, 512, 512);
const programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);
const bufferInfo = twgl.createBufferInfoFromArrays(gl, {
a_Position: {
numComponents: 2,
data: [-1, -1, -1, 3, 3, -1]
},
});
gl.useProgram(programInfo.program);
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
twgl.drawBufferInfo(gl, bufferInfo);Run Code Online (Sandbox Code Playgroud)
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<script id="vs" type="x-shader/x-vertex">
attribute vec4 a_Position;
varying vec2 v_Position;
varying vec2 v_TexCoord;
void main() {
v_Position = a_Position.xy;
v_TexCoord = a_Position.xy / 2.0 + 0.5;
gl_Position = a_Position;
}
</script>
<script id="fs" type="x-shader/x-vertex">
precision highp float;
varying vec2 v_Position;
varying vec2 v_TexCoord;
vec2 compMult(vec2 u, vec2 v) {
return vec2(u.x * v.x - u.y * v.y, u.x * v.y + u.y * v.x);
}
vec2 G(vec3 x) {
float lenx = length(x);
float ang = 350.0 * lenx;
return vec2(cos(ang), sin(ang)) / lenx;
}
void main() {
gl_FragColor.a = 1.0;
vec3 x0 = vec3(v_TexCoord, 1);
vec2 pos = floor(8.0 * v_TexCoord) / 8.0;
vec3 x = vec3(0.375 + 0.25 * pos, 0);
float disx0x = distance(x0, x);
vec2 amplitude = compMult(
G(x - vec3(-0.46875, -0.5, 300.0)),
compMult(
vec2(-1.0 / disx0x, 350.0),
G(x - x0)
)
);
gl_FragColor.rgb = vec3(0.5 + amplitude, 0.5);
}
</script>
<canvas></canvas>Run Code Online (Sandbox Code Playgroud)
这是我的 Intel 机器上的样子:

我认为,从算法来看(甚至不再有循环),很明显灰色区域不应该是灰色的,而应该与其他图块类似。另请注意,我从不除以小数x。x0有分别的 z 坐标0。1,所以distance(x, x0)和distance(x, vec3(-0.46875, -0.5, 300))永远不会小,这是我用作分隔符的唯一值。我还更改了一些常量,以便现在所有数字都具有精确的二进制表示形式。
这只是英特尔系统上的sin和功能的问题。cos该参数似乎超出了定义的值范围。允许的值范围取决于供应商。这个可以用函数来解决mod。(4.0*acos(0.0)是 2*PI)
float ang = 350.0 * lenx;
float ang = mod(350.0*lenx, 4.0*acos(0.0));
Run Code Online (Sandbox Code Playgroud)
const gl = document.querySelector("canvas").getContext("webgl");
gl.canvas.width = gl.canvas.height = 512
gl.viewport(0, 0, 512, 512);
const programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);
const bufferInfo = twgl.createBufferInfoFromArrays(gl, {
a_Position: {
numComponents: 2,
data: [-1, -1, -1, 3, 3, -1]
},
});
gl.useProgram(programInfo.program);
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
twgl.drawBufferInfo(gl, bufferInfo);Run Code Online (Sandbox Code Playgroud)
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<script id="vs" type="x-shader/x-vertex">
attribute vec4 a_Position;
varying vec2 v_Position;
varying vec2 v_TexCoord;
void main() {
v_Position = a_Position.xy;
v_TexCoord = a_Position.xy / 2.0 + 0.5;
gl_Position = a_Position;
}
</script>
<script id="fs" type="x-shader/x-vertex">
precision highp float;
varying vec2 v_Position;
varying vec2 v_TexCoord;
vec2 compMult(vec2 u, vec2 v) {
return vec2(u.x * v.x - u.y * v.y, u.x * v.y + u.y * v.x);
}
vec2 G(vec3 x) {
float lenx = length(x);
float ang = mod(350.0*lenx, 4.0*acos(0.0));
return vec2(cos(ang), sin(ang)) / lenx;
}
void main() {
gl_FragColor.a = 1.0;
vec3 x0 = vec3(v_TexCoord, 1);
vec2 amplitude;
for(int i = 0; i < 10; i++) {
for(int j = 0; j < 10; j++) {
vec2 pos = 0.05 + vec2(i, j) / 10.0;
vec3 x = vec3(0.4 + 0.2 * pos, 0);
float disx0x = distance(x0, x);
amplitude += compMult(
G(x - vec3(-0.4765625, -0.671875, 300)),
compMult(
vec2(-1.0 / disx0x, 350.0),
G(x - x0) / disx0x
)
);
}
}
gl_FragColor.r = length(amplitude) / 10.0;
}
</script>
<canvas></canvas>Run Code Online (Sandbox Code Playgroud)