TriangleMesh - 背面可见
TriangleMesh - Backside faces are visible
美好的一天!我有以下问题。图形模型显示不正确:模型的一些应该被正面隐藏的背面仍然可见。这里有一些例子需要说明:(isometry)
(问题)
这个问题在应用光和 material 时尤为明显。所以问题是如何为 JavaFX 解决这个问题?
更新:
public class VertexTest extends Application {
PerspectiveCamera camera;
Cam cam = new Cam();
double mouseOldX, mouseOldY, mousePosX, mousePosY, mouseDeltaX, mouseDeltaY;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
TriangleMesh mesh = new Shape3DRectangle(100, 100, 100);
MeshView view = new MeshView(mesh);
view.setDrawMode(DrawMode.LINE);
view.setMaterial(new PhongMaterial(Color.RED));
cam.getChildren().add(view);
Scene scene = new Scene(cam, 1000, 1000, true);
addEvents(view, scene);
camera = new PerspectiveCamera();
camera.setTranslateX(-500);
camera.setTranslateY(-500);
camera.setTranslateZ(1000);
scene.setCamera(camera);
primaryStage.setScene(scene);
primaryStage.show();
}
private void addEvents(MeshView view, Scene s) {
s.setOnMouseDragged(new EventHandler<MouseEvent>() {
public void handle(MouseEvent me) {
mouseOldX = mousePosX;
mouseOldY = mousePosY;
mousePosX = me.getX();
mousePosY = me.getY();
mouseDeltaX = mousePosX - mouseOldX;
mouseDeltaY = mousePosY - mouseOldY;
cam.ry.setAngle(cam.ry.getAngle() - mouseDeltaX);
cam.rx.setAngle(cam.rx.getAngle() + mouseDeltaY);
}
});
}
class Cam extends Group {
Translate t = new Translate();
Translate p = new Translate();
Translate ip = new Translate();
Rotate rx = new Rotate();
{
rx.setAxis(Rotate.X_AXIS);
}
Rotate ry = new Rotate();
{
ry.setAxis(Rotate.Y_AXIS);
}
Rotate rz = new Rotate();
{
rz.setAxis(Rotate.Z_AXIS);
}
Scale s = new Scale();
public Cam() {
super();
getTransforms().addAll(t, p, rx, rz, ry, s, ip);
}
}
public class Shape3DRectangle extends TriangleMesh {
public Shape3DRectangle(float Width, float Height, float deep) {
this.getPoints().setAll(-Width / 2, Height / 2, deep / 2, // idx p0
Width / 2, Height / 2, deep / 2, // idx p1
-Width / 2, -Height / 2, deep / 2, // idx p2
Width / 2, -Height / 2, deep / 2, // idx p3
-Width / 2, Height / 2, -deep / 2, // idx p4
Width / 2, Height / 2, -deep / 2, // idx p5
-Width / 2, -Height / 2, -deep / 2, // idx p6
Width, -Height / 2, -deep / 2 // idx p7
);
this.getTexCoords().addAll(0.0f, 0.0f);
this.getFaces().addAll(5, 0, 4, 0, 0, 0 // P5,T1 ,P4,T0 ,P0,T3
, 5, 0, 0, 0, 1, 0 // P5,T1 ,P0,T3 ,P1,T4
, 0, 0, 4, 0, 6, 0 // P0,T3 ,P4,T2 ,P6,T7
, 0, 0, 6, 0, 2, 0 // P0,T3 ,P6,T7 ,P2,T8
, 1, 0, 0, 0, 2, 0 // P1,T4 ,P0,T3 ,P2,T8
, 1, 0, 2, 0, 3, 0 // P1,T4 ,P2,T8 ,P3,T9
, 5, 0, 1, 0, 3, 0 // P5,T5 ,P1,T4 ,P3,T9
, 5, 0, 3, 0, 7, 0 // P5,T5 ,P3,T9 ,P7,T10
, 4, 0, 5, 0, 7, 0 // P4,T6 ,P5,T5 ,P7,T10
, 4, 0, 7, 0, 6, 0 // P4,T6 ,P7,T10 ,P6,T11
, 3, 0, 2, 0, 6, 0 // P3,T9 ,P2,T8 ,P6,T12
, 3, 0, 6, 0, 7, 0 // P3,T9 ,P6,T12 ,P7,T13
);
}
}
}
您可以为每个 Shape3D 设置 cullFaceProperty。我想这就是你所需要的,但我不确定我是否准确地理解了你的问题。
我一直在研究你的样本,我想我已经找到了你的问题的原因。
首先,我检查了面部的缠绕。它们都是逆时针方向的,所以它们的法线都应该向外。
然后我修改了其他顶点而不是最后一个。在某些情况下没有问题,在其他情况下,问题仍然存在。
基本上,当存在 "concave" 个曲面时会出现此问题,这意味着两个面的法线会交叉。当所有表面都是 "convex" 时,这不会发生,这意味着它们的法线指向外部并且不会交叉。
这是从 here:
截取的两种类型网格的清晰图像
回到你的例子,你正在定义一个凹面网格:
但是如果我们不修改顶点 #7,而是让 #5 变大,我们就有了一个凸网格,没有渲染问题:
显然,虽然这解决了渲染问题,但它改变了您的初始形状。
如果您想保留初始几何形状,另一种可能的解决方案是更改面,这样您就没有任何凹面。
让我们看一下面 5-1-3 和 5-3-7,假设我们现在要移动顶点 #1。
如果我们保留你的三角形,面 5-1-3 和 5-3-7 将定义一个要渲染的凹面(它们的法线会交叉),而如果我们将这些三角形更改为 5-1-7和 1-3-7,则表面将是凸面(它们的法线不会交叉):
回到你的初始形状,这两个面的变化将解决渲染问题。
虽然顶点相同,但几何形状略有不同。所以它需要一些改进(更多元素)。添加这些元素应该牢记这个凸概念。但是,正如您所见 here.
,问题并非微不足道
Jose 的分析很好,但在我看来,OP 似乎忘记在他的这行代码中将宽度除以 2。
Width, -Height / 2, -deep / 2 // idx p7
应该是
Width / 2, -Height / 2, -deep / 2 // idx p7
class 被称为 Shape3DRectangle 但有这个错误
几何形状不再是矩形了。
美好的一天!我有以下问题。图形模型显示不正确:模型的一些应该被正面隐藏的背面仍然可见。这里有一些例子需要说明:(isometry)
(问题)
这个问题在应用光和 material 时尤为明显。所以问题是如何为 JavaFX 解决这个问题?
更新:
public class VertexTest extends Application {
PerspectiveCamera camera;
Cam cam = new Cam();
double mouseOldX, mouseOldY, mousePosX, mousePosY, mouseDeltaX, mouseDeltaY;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
TriangleMesh mesh = new Shape3DRectangle(100, 100, 100);
MeshView view = new MeshView(mesh);
view.setDrawMode(DrawMode.LINE);
view.setMaterial(new PhongMaterial(Color.RED));
cam.getChildren().add(view);
Scene scene = new Scene(cam, 1000, 1000, true);
addEvents(view, scene);
camera = new PerspectiveCamera();
camera.setTranslateX(-500);
camera.setTranslateY(-500);
camera.setTranslateZ(1000);
scene.setCamera(camera);
primaryStage.setScene(scene);
primaryStage.show();
}
private void addEvents(MeshView view, Scene s) {
s.setOnMouseDragged(new EventHandler<MouseEvent>() {
public void handle(MouseEvent me) {
mouseOldX = mousePosX;
mouseOldY = mousePosY;
mousePosX = me.getX();
mousePosY = me.getY();
mouseDeltaX = mousePosX - mouseOldX;
mouseDeltaY = mousePosY - mouseOldY;
cam.ry.setAngle(cam.ry.getAngle() - mouseDeltaX);
cam.rx.setAngle(cam.rx.getAngle() + mouseDeltaY);
}
});
}
class Cam extends Group {
Translate t = new Translate();
Translate p = new Translate();
Translate ip = new Translate();
Rotate rx = new Rotate();
{
rx.setAxis(Rotate.X_AXIS);
}
Rotate ry = new Rotate();
{
ry.setAxis(Rotate.Y_AXIS);
}
Rotate rz = new Rotate();
{
rz.setAxis(Rotate.Z_AXIS);
}
Scale s = new Scale();
public Cam() {
super();
getTransforms().addAll(t, p, rx, rz, ry, s, ip);
}
}
public class Shape3DRectangle extends TriangleMesh {
public Shape3DRectangle(float Width, float Height, float deep) {
this.getPoints().setAll(-Width / 2, Height / 2, deep / 2, // idx p0
Width / 2, Height / 2, deep / 2, // idx p1
-Width / 2, -Height / 2, deep / 2, // idx p2
Width / 2, -Height / 2, deep / 2, // idx p3
-Width / 2, Height / 2, -deep / 2, // idx p4
Width / 2, Height / 2, -deep / 2, // idx p5
-Width / 2, -Height / 2, -deep / 2, // idx p6
Width, -Height / 2, -deep / 2 // idx p7
);
this.getTexCoords().addAll(0.0f, 0.0f);
this.getFaces().addAll(5, 0, 4, 0, 0, 0 // P5,T1 ,P4,T0 ,P0,T3
, 5, 0, 0, 0, 1, 0 // P5,T1 ,P0,T3 ,P1,T4
, 0, 0, 4, 0, 6, 0 // P0,T3 ,P4,T2 ,P6,T7
, 0, 0, 6, 0, 2, 0 // P0,T3 ,P6,T7 ,P2,T8
, 1, 0, 0, 0, 2, 0 // P1,T4 ,P0,T3 ,P2,T8
, 1, 0, 2, 0, 3, 0 // P1,T4 ,P2,T8 ,P3,T9
, 5, 0, 1, 0, 3, 0 // P5,T5 ,P1,T4 ,P3,T9
, 5, 0, 3, 0, 7, 0 // P5,T5 ,P3,T9 ,P7,T10
, 4, 0, 5, 0, 7, 0 // P4,T6 ,P5,T5 ,P7,T10
, 4, 0, 7, 0, 6, 0 // P4,T6 ,P7,T10 ,P6,T11
, 3, 0, 2, 0, 6, 0 // P3,T9 ,P2,T8 ,P6,T12
, 3, 0, 6, 0, 7, 0 // P3,T9 ,P6,T12 ,P7,T13
);
}
}
}
您可以为每个 Shape3D 设置 cullFaceProperty。我想这就是你所需要的,但我不确定我是否准确地理解了你的问题。
我一直在研究你的样本,我想我已经找到了你的问题的原因。
首先,我检查了面部的缠绕。它们都是逆时针方向的,所以它们的法线都应该向外。
然后我修改了其他顶点而不是最后一个。在某些情况下没有问题,在其他情况下,问题仍然存在。
基本上,当存在 "concave" 个曲面时会出现此问题,这意味着两个面的法线会交叉。当所有表面都是 "convex" 时,这不会发生,这意味着它们的法线指向外部并且不会交叉。
这是从 here:
截取的两种类型网格的清晰图像回到你的例子,你正在定义一个凹面网格:
但是如果我们不修改顶点 #7,而是让 #5 变大,我们就有了一个凸网格,没有渲染问题:
显然,虽然这解决了渲染问题,但它改变了您的初始形状。
如果您想保留初始几何形状,另一种可能的解决方案是更改面,这样您就没有任何凹面。
让我们看一下面 5-1-3 和 5-3-7,假设我们现在要移动顶点 #1。
如果我们保留你的三角形,面 5-1-3 和 5-3-7 将定义一个要渲染的凹面(它们的法线会交叉),而如果我们将这些三角形更改为 5-1-7和 1-3-7,则表面将是凸面(它们的法线不会交叉):
回到你的初始形状,这两个面的变化将解决渲染问题。
虽然顶点相同,但几何形状略有不同。所以它需要一些改进(更多元素)。添加这些元素应该牢记这个凸概念。但是,正如您所见 here.
,问题并非微不足道Jose 的分析很好,但在我看来,OP 似乎忘记在他的这行代码中将宽度除以 2。
Width, -Height / 2, -deep / 2 // idx p7
应该是
Width / 2, -Height / 2, -deep / 2 // idx p7
class 被称为 Shape3DRectangle 但有这个错误 几何形状不再是矩形了。