【问题标题】:How to set LinearGradient for 3D Box in JavaFX如何在 JavaFX 中为 3D 框设置 LinearGradient
【发布时间】:2019-07-15 18:32:14
【问题描述】:

我找到了一些与我的问题类似的答案,但该解决方案专门针对该领域。不管怎样,我试过了,当然这不是我所期望的。

我使用的代码是:

Scene aux2 = new Scene(new StackPane(), 100, 100,
                new LinearGradient(0, 0, 1, 0, true, CycleMethod.REFLECT,
                        new Stop(0, Color.GREEN), new Stop(0.3, Color.YELLOW),
                        new Stop(0.6, Color.BLUE), new Stop(0.9, Color.RED)));


        WritableImage snapshot = aux2.snapshot(null);

        PhongMaterial material = new PhongMaterial();
        material.setDiffuseMap(snapshot);

        box.setMaterial(material);

效果在这里:https://imagizer.imageshack.com/img922/589/VEL43d.png

如何在盒子周围获得相同的填充(椭圆形),并将顶部表面设置为渐变的顶部颜色?

【问题讨论】:

    标签: java javafx 3d javafx-3d


    【解决方案1】:

    您提到的球体solution 不适用于 3D 盒子,因为内置盒子会将完全相同的漫反射图像应用于盒子的每个平面 6 个面。

    另一个solution 为 3D 框使用自定义网格,因此您可以以不同的方式播放漫反射图像。

    我们可以根据您的用例调整该解决方案,因为如果我做对了,您希望将具有线性渐变的相同图像应用于 4 个垂直面,同时保持 2 个水平面上的边框颜色。

    所以我们需要这样的图像:

    Scene aux2 = new Scene(new StackPane(), 10, 100,
                new LinearGradient(0, 1, 0, 0, true, CycleMethod.REFLECT,
                        new Stop(0, Color.GREEN), new Stop(0.3, Color.YELLOW),
                        new Stop(0.6, Color.BLUE), new Stop(0.9, Color.RED)));
    
    WritableImage snapshot = aux2.snapshot(null);
    PhongMaterial material = new PhongMaterial(Color.WHITE);
    material.setDiffuseMap(snapshot);
    

    请注意,我设置了垂直线性渐变。如果你渲染那个图像,你会得到类似的东西:

    现在你需要生成一个长方体网格:

    public MeshView createCuboid(float w, float h, float d) {
        float hw = w / 2f;
        float hh = h / 2f;
        float hd = d / 2f;
    
        float points[] = {
                hw,  hh,  hd,
                hw,  hh, -hd,
                hw, -hh,  hd,
                hw, -hh, -hd,
                -hw,  hh,  hd,
                -hw,  hh, -hd,
                -hw, -hh,  hd,
                -hw, -hh, -hd};
    
        float tex[] = {
                0.01f, 0.01f,
                0.01f, 0.99f};
    
        float normals[] = {
                1f,  0f,  0f,
                -1f,  0f,  0f,
                0f,  1f,  0f,
                0f, -1f,  0f,
                0f,  0f,  1f,
                0f,  0f, -1f,
        };
    
        int faces[] = {
                0, 0, 0, 2, 0, 1, 1, 0, 0,
                2, 0, 1, 3, 0, 1, 1, 0, 0,
                4, 1, 0, 5, 1, 0, 6, 1, 1,
                6, 1, 1, 5, 1, 0, 7, 1, 1,
                0, 2, 0, 1, 2, 0, 4, 2, 0,
                4, 2, 0, 1, 2, 0, 5, 2, 0,
                2, 3, 1, 6, 3, 1, 3, 3, 1,
                3, 3, 1, 6, 3, 1, 7, 3, 1,
                0, 4, 0, 4, 4, 0, 2, 4, 1,
                2, 4, 1, 4, 4, 0, 6, 4, 1,
                1, 5, 0, 3, 5, 1, 5, 5, 0,
                5, 5, 0, 3, 5, 1, 7, 5, 1};
    
        TriangleMesh mesh = new TriangleMesh();
        mesh.setVertexFormat(VertexFormat.POINT_NORMAL_TEXCOORD);
        mesh.getPoints().addAll(points);
        mesh.getTexCoords().addAll(tex);
        mesh.getNormals().addAll(normals);
        mesh.getFaces().addAll(faces);
    
        return new MeshView(mesh);
    }
    

    如果你检查纹理坐标,我刚刚选择了两对坐标,一个几乎在漫反射图像的底部,一个几乎在顶部。 JavaFX 将从给定图像中插入每个像素来完成其余的工作。我没有选择边框以防止图像边框出现任何可能出现的不同颜色问题。

    faces 数组列出了每个三角形(最多 12 个)的三个顶点、三个法线和三个纹理坐标的索引。

    例如,第一个三角形的顶点索引为 0、2、1,每个顶点的法线为 0,纹理索引为 0、1、0(底部 - 顶部 - 底部)。下一个三角形的索引为 2、3、1,相同的法线为 0,纹理索引为 1、1、0(顶部 - 顶部 - 底部)。注意底部是红色,顶部是绿色(Y坐标从图像的左上角向下)。

    索引为 4、5 的面的纹理索引为 0、0、0,因此它们位于底部,而面 6、7 的索引为 1、1、1,因此它们位于顶部。

    所以现在我们需要的是:

    MeshView mv = createCuboid(10, 100, 10);
    mv.setMaterial(material);
    Group cuboidGroup = new Group(mv);
    Scene scene = new Scene(cuboidGroup, 400, 600, true, SceneAntialiasing.BALANCED);
    

    结果如下:

    希望这是您正在寻找的结果。否则,您可以使用渐变和网格来实现它。

    【讨论】:

    • 非常感谢。这正是我一直在寻找的。对我来说又是一个宝贵的教训。但在我使用它之前,我必须阅读更多关于所有点、面孔、法线等的信息。对于像我这样的其他新手,我强烈建议阅读这两个链接:MeshViewnormals - 它会澄清一切何塞所写的。顺便提一句。为什么我的长方体比你的暗得多? imagizer.imageshack.com/img924/7917/wTY4CL.png
    • 我在群组中添加了AmbientLight()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-29
    相关资源
    最近更新 更多