JavaScript - 移除线框后三角形之间的间隙
JavaScript - Gap between triangles when wire-frame is removed
我对 JavaScript 比较陌生,为了掌握它,我一直在研究 3D 引擎,但我偶然发现了一些奇怪的东西。
当我在禁用线框的情况下渲染填充网格时,三角形之间会出现间隙。
这是一个例子:
// vertices
var v1 = [40,20];
var v2 = [125,35];
var v3 = [165,105];
var v4 = [35,95];
// draw on screen 1
var canvas = document.getElementById("screen");
var context = canvas.getContext("2d");
triangle(v1,v2,v3,context,true);
triangle(v3,v4,v1,context,true);
// draw on screen 2
var canvas = document.getElementById("screen2");
var context = canvas.getContext("2d");
triangle(v1,v2,v3,context,false);
triangle(v3,v4,v1,context,false);
// draw triangle method
function triangle(v1,v2,v3, context,wireframe)
{
context.beginPath();
context.moveTo(v1[0],v1[1]);
context.lineTo(v2[0],v2[1]);
context.lineTo(v3[0],v3[1]);
context.lineTo(v1[0],v1[1]);
context.closePath();
context.fillStyle = "#333";
context.fill();
if (wireframe)
{
context.strokeStyle = "#0f3";
context.stroke();
}
}
body
{
background-color: #ddd;
}
canvas
{
border:2px solid #000;
}
<canvas id="screen" width="200" height="150" ></canvas>
<canvas id="screen2" width="200" height="150"></canvas>
本质上,这两个多边形似乎没有正确连接。
- 使线框与三角形颜色相同不是解决方案。我想在看不到边缘的情况下应用纹理。
- 绘制连接的多边形不是解决方案,每个三角形可能有自己的纹理变换。
- 我应该透支三角形来弥补差距吗?
- 这是抗锯齿问题吗?
提前致谢。
上图:禁用线框后显示三角形之间的间隙
2017 年 4 月 9 日更新
我考虑了多种解决问题的方法,包括编写三角形例程。下图。但是,绘制两个三角形会大大降低我的 FPS。我需要一种更快的方法来将像素放在 canvas 上,但那是另一个 post 的方法,因为它不是主题。
但是,我认为将三角形扩大半个像素是 better/faster 的解决方案,因为 fill() 方法是由浏览器内部执行的,而不是 JavaScript.
一种解决方案是将三角形稍微充气以填充间隙。此代码膨胀了 1%。
我认为更理想的是膨胀 0.5 像素的代码,但是,该代码会稍微贵一些,因为它涉及计算向量长度...
// vertices
var v1 = [80,40];
var v2 = [250,70];
var v3 = [230,210];
var v4 = [70,190];
// draw on screen 1
var canvas = document.getElementById("screen");
var context = canvas.getContext("2d");
triangle(v1,v2,v3,context,true);
triangle(v3,v4,v1,context,true);
// draw on screen 2
var canvas = document.getElementById("screen2");
var context = canvas.getContext("2d");
inflateTriangle(v1,v2,v3,context,false);
inflateTriangle(v3,v4,v1,context,false);
// draw triangle method
function inflateTriangle(v1,v2,v3, context,wireframe)
{
//centre of tri
xc=(v1[0]+v2[0]+v3[0])/3;
yc=(v1[1]+v2[1]+v3[1])/3;
//inflate tri by 1%
x1= xc+(v1[0]-xc)*1.01;
x2= xc+(v2[0]-xc)*1.01;
x3= xc+(v3[0]-xc)*1.01;
y1= yc+(v1[1]-yc)*1.01;
y2= yc+(v2[1]-yc)*1.01;
y3= yc+(v3[1]-yc)*1.01;
context.beginPath();
context.moveTo(x1,y1);
context.lineTo(x2,y2);
context.lineTo(x3,y3);
context.closePath();
context.fillStyle = "#333";
context.fill();
if (wireframe)
{
context.strokeStyle = "#0f3";
context.stroke();
}
}
<body>
<canvas id="screen" width="400" height="300" style="border:2px solid #000;"></canvas>
<canvas id="screen2" width="400" height="300" style="border:2px solid #000;"></canvas>
</body>
我对 JavaScript 比较陌生,为了掌握它,我一直在研究 3D 引擎,但我偶然发现了一些奇怪的东西。 当我在禁用线框的情况下渲染填充网格时,三角形之间会出现间隙。
这是一个例子:
// vertices
var v1 = [40,20];
var v2 = [125,35];
var v3 = [165,105];
var v4 = [35,95];
// draw on screen 1
var canvas = document.getElementById("screen");
var context = canvas.getContext("2d");
triangle(v1,v2,v3,context,true);
triangle(v3,v4,v1,context,true);
// draw on screen 2
var canvas = document.getElementById("screen2");
var context = canvas.getContext("2d");
triangle(v1,v2,v3,context,false);
triangle(v3,v4,v1,context,false);
// draw triangle method
function triangle(v1,v2,v3, context,wireframe)
{
context.beginPath();
context.moveTo(v1[0],v1[1]);
context.lineTo(v2[0],v2[1]);
context.lineTo(v3[0],v3[1]);
context.lineTo(v1[0],v1[1]);
context.closePath();
context.fillStyle = "#333";
context.fill();
if (wireframe)
{
context.strokeStyle = "#0f3";
context.stroke();
}
}
body
{
background-color: #ddd;
}
canvas
{
border:2px solid #000;
}
<canvas id="screen" width="200" height="150" ></canvas>
<canvas id="screen2" width="200" height="150"></canvas>
本质上,这两个多边形似乎没有正确连接。
- 使线框与三角形颜色相同不是解决方案。我想在看不到边缘的情况下应用纹理。
- 绘制连接的多边形不是解决方案,每个三角形可能有自己的纹理变换。
- 我应该透支三角形来弥补差距吗?
- 这是抗锯齿问题吗?
提前致谢。
2017 年 4 月 9 日更新
我考虑了多种解决问题的方法,包括编写三角形例程。下图。但是,绘制两个三角形会大大降低我的 FPS。我需要一种更快的方法来将像素放在 canvas 上,但那是另一个 post 的方法,因为它不是主题。
但是,我认为将三角形扩大半个像素是 better/faster 的解决方案,因为 fill() 方法是由浏览器内部执行的,而不是 JavaScript.
一种解决方案是将三角形稍微充气以填充间隙。此代码膨胀了 1%。
我认为更理想的是膨胀 0.5 像素的代码,但是,该代码会稍微贵一些,因为它涉及计算向量长度...
// vertices
var v1 = [80,40];
var v2 = [250,70];
var v3 = [230,210];
var v4 = [70,190];
// draw on screen 1
var canvas = document.getElementById("screen");
var context = canvas.getContext("2d");
triangle(v1,v2,v3,context,true);
triangle(v3,v4,v1,context,true);
// draw on screen 2
var canvas = document.getElementById("screen2");
var context = canvas.getContext("2d");
inflateTriangle(v1,v2,v3,context,false);
inflateTriangle(v3,v4,v1,context,false);
// draw triangle method
function inflateTriangle(v1,v2,v3, context,wireframe)
{
//centre of tri
xc=(v1[0]+v2[0]+v3[0])/3;
yc=(v1[1]+v2[1]+v3[1])/3;
//inflate tri by 1%
x1= xc+(v1[0]-xc)*1.01;
x2= xc+(v2[0]-xc)*1.01;
x3= xc+(v3[0]-xc)*1.01;
y1= yc+(v1[1]-yc)*1.01;
y2= yc+(v2[1]-yc)*1.01;
y3= yc+(v3[1]-yc)*1.01;
context.beginPath();
context.moveTo(x1,y1);
context.lineTo(x2,y2);
context.lineTo(x3,y3);
context.closePath();
context.fillStyle = "#333";
context.fill();
if (wireframe)
{
context.strokeStyle = "#0f3";
context.stroke();
}
}
<body>
<canvas id="screen" width="400" height="300" style="border:2px solid #000;"></canvas>
<canvas id="screen2" width="400" height="300" style="border:2px solid #000;"></canvas>
</body>