Jos*_*eda 11
JavaFX 3D网格中的着色方式取决于您指定的材质.对于一个网格,有一种材质,并且不可能将不同的材料分配到同一网格的不同三角形.
因此,如果你想避免纹理,我担心唯一的方法是在同一个网格中将相同颜色的三角形分组,并创建如此多的网格作为颜色.
相反,纹理相对容易......因为你只有一个网格,一个材质和一个具有所有着色的图像.
我做了一个二十面体的例子,为它构建了一个三角形网格,并添加了一个纹理来为所有面部着色.
为此,我们需要:
和20个面孔.每个面由6个索引p0,t0,p1,t1,p3,t3定义,其中p0,p1,p2和p3是点阵列的索引,并且t0,t1,t2和t3是texCoords阵列的索引.
公共类IcosahedronMesh扩展MeshView {
public IcosahedronMesh(){
setMesh(createCube());
}
private TriangleMesh createCube() {
TriangleMesh m = new TriangleMesh();
// POINTS
m.getPoints().addAll(
0f, 0f, -0.951057f,
0f, 0f, 0.951057f,
-0.850651f, 0f, -0.425325f,
0.850651f, 0f, 0.425325f,
0.688191f, -0.5f, -0.425325f,
0.688191f, 0.5f, -0.425325f,
-0.688191f, -0.5f, 0.425325f,
-0.688191f, 0.5f, 0.425325f,
-0.262866f, -0.809017f, -0.425325f,
-0.262866f, 0.809017f, -0.425325f,
0.262866f, -0.809017f, 0.425325f,
0.262866f, 0.809017f, 0.425325f
);
// TEXTURES
m.getTexCoords().addAll(
0.181818f, 0f,
0.363636f, 0f,
0.545455f, 0f,
0.727273f, 0f,
0.909091f, 0f,
0.0909091f, 0.333333f,
0.272727f, 0.333333f,
0.454545f, 0.333333f,
0.636364f, 0.333333f,
0.818182f, 0.333333f,
1f, 0.333333f,
0f, 0.666667f,
0.181818f, 0.666667f,
0.363636f, 0.666667f,
0.545455f, 0.666667f,
0.727273f, 0.666667f,
0.909091f, 0.666667f,
0.0909091f, 1f,
0.272727f, 1f,
0.454545f, 1f,
0.636364f, 1f,
0.818182f, 1f
);
// FACES
m.getFaces().addAll(
1, 6, 11, 5, 7, 0,
1, 12, 7, 11, 6, 5,
1, 7, 6, 6, 10, 1,
1, 13, 10, 12, 3, 6,
1, 8, 3, 7, 11, 2,
4, 14, 8, 13, 0, 7,
5, 9, 4, 8, 0, 3,
9, 15, 5, 14, 0, 8,
2, 10, 9, 9, 0, 4,
8, 16, 2, 15, 0, 9,
11, 5, 9, 6, 7, 12,
7, 11, 2, 12, 6, 17,
6, 6, 8, 7, 10, 13,
10, 12, 4, 13, 3, 18,
3, 7, 5, 8, 11, 14,
4, 13, 10, 14, 8, 19,
5, 8, 3, 9, 4, 15,
9, 14, 11, 15, 5, 20,
2, 9, 7, 10, 9, 16,
8, 15, 6, 16, 2, 21
);
return m;
}
Run Code Online (Sandbox Code Playgroud)
}
现在我们需要一个基于二十面体网的每个面部着色的图像,如下所示:

(图片在这里找到)
注意,映射是从(0,0)到(1,1)归一化坐标到图像(左,上)到(右,下)像素完成的.
让我们最终创建场景,加载网格并将纹理添加到其材质:
@Override
public void start(Stage primaryStage) throws Exception {
Group sceneRoot = new Group();
Scene scene = new Scene(sceneRoot, 600, 600, true, SceneAntialiasing.BALANCED);
scene.setFill(Color.BLACK);
PerspectiveCamera camera = new PerspectiveCamera(true);
camera.setNearClip(0.1);
camera.setFarClip(10000.0);
camera.setTranslateZ(-4);
scene.setCamera(camera);
IcosahedronMesh mesh = new IcosahedronMesh();
mesh.setCullFace(CullFace.FRONT);
PhongMaterial mat = new PhongMaterial();
mat.setDiffuseMap(new Image(getClass().getResourceAsStream("icosah_net.png")));
mesh.setMaterial(mat);
Rotate rotateY = new Rotate(0, 0, 0, 0, Rotate.Y_AXIS);
mesh.getTransforms().addAll(new Rotate(30,Rotate.X_AXIS),rotateY);
sceneRoot.getChildren().addAll(mesh, new AmbientLight(Color.WHITE));
primaryStage.setTitle("JavaFX 3D - Icosahedron");
primaryStage.setScene(scene);
primaryStage.show();
}
Run Code Online (Sandbox Code Playgroud)
这是它的样子:

编辑
现在,如果你考虑如何应用纹理,你可以使用你需要的颜色调色板将图像简化为几个正方形:

纹理坐标可以真正简化:
m.getTexCoords().addAll(
0.1f, 0.5f, // 0 red
0.3f, 0.5f, // 1 green
0.5f, 0.5f, // 2 blue
0.7f, 0.5f, // 3 yellow
0.9f, 0.5f // 4 orange
);
Run Code Online (Sandbox Code Playgroud)
最后,我们必须在我们的脸上映射这些点.遵循与网络图像相同的模式:
m.getFaces().addAll(
1, 0, 11, 0, 7, 0,
1, 4, 7, 4, 6, 4,
1, 4, 6, 4, 10, 4,
1, 2, 10, 2, 3, 2,
1, 2, 3, 2, 11, 2,
4, 3, 8, 3, 0, 3,
5, 3, 4, 3, 0, 3,
9, 1, 5, 1, 0, 1,
2, 1, 9, 1, 0, 1,
8, 0, 2, 0, 0, 0,
11, 3, 9, 3, 7, 3,
7, 1, 2, 1, 6, 1,
6, 1, 8, 1, 10, 1,
10, 0, 4, 0, 3, 0,
3, 0, 5, 0, 11, 0,
4, 4, 10, 4, 8, 4,
5, 4, 3, 4, 4, 4,
9, 2, 11, 2, 5, 2,
2, 2, 7, 2, 9, 2,
8, 3, 6, 3, 2, 3
);
Run Code Online (Sandbox Code Playgroud)
现在我们将拥有一个非常整洁的二十面体,因为我们摆脱了边框和图像分辨率不佳:

这可以扩展到任何三角形网格,或使用任何算法来细化三角形.
| 归档时间: |
|
| 查看次数: |
4786 次 |
| 最近记录: |