Я пытаюсь отобразить различные текстовые объекты внутри 3D-сцены.
Проблема в том, что когда я приближаюсь к тексту, он выглядит очень размытым.
Вот скриншот из моего приложения
Вопрос: как улучшить графическое качество текста на экране?
Я попытался установить кеш, как в 2D-текст JavaFX с фоном в 3D-сцене потому что это, казалось, улучшило качество графики на снимках экрана с ответами, но в моем случае это не помогло.
Ниже приведен компилируемый пример, урезанный из моего приложения. Он просто создает несколько случайных текстовых объектов с позициями и дает вам возможность перемещаться. Обратите внимание, как тексты отображаются ужасно, когда вы увеличиваете масштаб.
Вы F10 и F11 для увеличения и уменьшения масштаба и перетаскивания мышью для перемещения камеры.
package timelinefx;
import static javafx.application.Application.launch;
import java.util.Random;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.SubScene;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
import javafx.scene.CacheHint;
public class TextInto3DScene extends Application {
static Stage stage;
static Scene scene;
static Group root;
static Group subSceneRoot;
static PerspectiveCamera camera;
static SubScene subScene;
static boolean cached = true;
static int width = 1000;
static int height = width;
@Override
public void start(Stage primaryStage) throws Exception {
createWindow();
}
protected static void createWindow(){
stage = new Stage();
root = new Group();
root.setCache(cached);
root.setCacheHint(CacheHint.QUALITY); //doesn't work
scene = new Scene(root, 1500, 700, true, SceneAntialiasing.BALANCED);
//Initialize the camera
camera = new PerspectiveCamera(true);
camera.setNearClip(0.1);
camera.setFarClip(5000);
camera.setTranslateZ(-200);
//creates the SubScene and add the camera to it!
subSceneRoot = new Group();
subSceneRoot.setCache(cached); //doesn't work
subScene = new SubScene(subSceneRoot, 1800, 700, true, SceneAntialiasing.BALANCED);
subScene.setCache(cached);
root.getChildren().add(subScene);
subScene.setFill(Color.WHITE);
subScene.setCamera(camera);
//Create random texts
for( int i = 0;i<=100;++i){
Text text = new Text(Math.random()* width-width/2, Math.random()*height-height/2, randomText() );
text.setFill( Color.BLACK );
text.setTranslateZ( Math.random()*750 );
text.setCache(cached); //doesn't work
text.setCacheHint(CacheHint.QUALITY);
subSceneRoot.getChildren().add(text);
}
stage.setScene(scene);
setEventHandlers();
stage.show();
}
static void setEventHandlers() {
scene.setOnMouseDragged((event) -> {
//camera.setRotate(event.getX());
double translateX = (event.getSceneX() - 0) / stage.getWidth();
translateX = translateX * width - width/2;
double translateY = (event.getSceneY() - 0) / stage.getHeight();
translateY = translateY * height - height/2;
double tz;
if(!camera.getTransforms().isEmpty()){
tz = camera.getTransforms().get(0).getTz();
} else {
tz = camera.getTranslateZ();
}
camera.getTransforms().clear();
camera.getTransforms().addAll( new Translate(translateX, translateY, tz) );
});
//KEY PRESSED
scene.setOnKeyPressed((event) -> {
switch (event.getCode().toString()) {
case "F10":
double amt = event.isControlDown() ? 100 : 30;
camera.setTranslateZ(camera.getTranslateZ() + amt);
break;
case "F11":
amt = event.isControlDown() ? -100 : -30;
camera.setTranslateZ(camera.getTranslateZ() + amt);
break;
}
});
}
static String randomText(){
String out = "";
Random r = new Random();
for(int i = 0;i<=10;++i){
char c = (char) (r.nextInt(26) + 'a');
out += c;
}
return out;
}
public static void main(String[] args) {
launch(args);
}
}