How to animate texture coordinates in javafx
Asked Answered
L

1

6

Is there some kind of animation for liquid surfaces that mimics waves by animating uvcoordinates like in the picture below? Can this method be recreated in the JavaFX framework?

enter image description here

Lugworm answered 17/5, 2022 at 23:17 Comment(0)
L
6

animating by replacing textcoordinate values

animating normals

Animating by replacing texture coordinate values . In this aproach , an integer property changes its value over time with the help of timeline object . there is a listener that will trigger an update in texture u and v coordinate values every time integer property changes . The result will remap normalmap over time bringing a sense of motion.

As you can see the animation only moves in one direction . even if the normal map is seamless tile texture ; this animation is not . it will be reset every 20 seconds . this aproach need improvements , but it's a good starting point I think.

This is a single javafx functional javafx app you can try

normal map file is at this page

App.java

public class App extends Application {

    private final float[] uvCoords = {3, 0, 3, 3, 0, 0, 0, 3};
    private final IntegerProperty keyCycle = new SimpleIntegerProperty();

    @Override
    public void start(Stage stage) {
        PerspectiveCamera camera = new PerspectiveCamera(true);
        camera.setTranslateZ(-8);
        camera.setTranslateY(10);
        camera.setRotationAxis(Rotate.X_AXIS);
        camera.setRotate(45);
        PointLight pointLight = new PointLight(Color.LIGHTYELLOW);

        pointLight.setTranslateZ(-2.5);
        pointLight.setTranslateY(-1.5);
        pointLight.setRotationAxis(Rotate.Y_AXIS);

        pointLight.setQuadraticAttenuation(0.1);
        MeshView meshView = makeMeshView();
        PhongMaterial material = new PhongMaterial(new Color(0, 1, 1, 0.5));
        material.setSpecularColor(Color.LIGHTYELLOW);
        material.setSpecularPower(512);

        Image image = new Image("normal.jpg");
        material.setBumpMap(image);
        meshView.setMaterial(material);

        makeCycle();

        keyCycle.addListener(e -> {

            float add = keyCycle.getValue() / 30000f;

            TriangleMesh mesh = (TriangleMesh) meshView.getMesh();
            for (int i = 0; i < uvCoords.length; i++) {
                uvCoords[i] += add;

            }
            mesh.getTexCoords().set(0, uvCoords, 0, uvCoords.length);

        });

        Group group3d = new Group(camera, meshView, pointLight);
        Scene scene = new Scene(group3d, 640, 480, true, SceneAntialiasing.BALANCED);
        scene.setCamera(camera);
        scene.setFill(Color.PERU);
        stage.setTitle("Animating uv coordinates in javafx");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }

    private MeshView makeMeshView() {
        TriangleMesh mesh = new TriangleMesh();

        MeshView mv = new MeshView(mesh);
        mesh.getPoints().addAll(-3, -3, 0, 3, -3, 0, -3, 3, 0, 3, 3, 0);
        mesh.getTexCoords().addAll(uvCoords);
        mesh.getFaces().addAll(0, 0, 3, 3, 1, 1, 0, 0, 2, 2, 3, 3);
        return mv;
    }

    private void makeCycle() {

        KeyValue start = new KeyValue(keyCycle, 0, Interpolator.LINEAR);

        KeyValue end = new KeyValue(keyCycle, 24 * 20, Interpolator.LINEAR);
        KeyFrame kf = new KeyFrame(Duration.seconds(20), start, end);

        Timeline tm = new Timeline(kf);
        tm.setCycleCount(100);
        tm.play();

    }

}
Lugworm answered 17/5, 2022 at 23:17 Comment(1)
You can also use animated GIFs as the image for maps in PhongMaterial, so by using one for the bump map you can also create such an effect.Upside

© 2022 - 2024 — McMap. All rights reserved.