JDK-8311022 : Enable mip filter for D3D 3D texture maps
  • Type: Bug
  • Component: javafx
  • Sub-Component: graphics
  • Affected Version: jfx11,8,jfx20
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: windows
  • CPU: generic
  • Submitted: 2023-06-28
  • Updated: 2024-01-26
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Description
While implementing JDK-8310109, noticed below behaviour in D3D pipeline:

1. In OpenGL we set GL_TEXTURE_MIN_FILTER as GL_LINEAR_MIPMAP_LINEAR
2. In Metal i am also planning to do the same. Set MIP_FILTER as well as MIN_FILTER to Linear
3. But in D3D what is see is we don’t set D3DSAMP_MIPFILTER at all for 3D Texture maps. We set only D3DSAMP_MINFILTER & D3DSAMP_MAGFILTER filters to D3DTEXF_LINEAR. If we don’t set D3DSAMP_MIPFILTER, default is D3DTEXF_NONE

We actually set D3DUSAGE_AUTOGENMIPMAP in D3DResourceManager.cc before creating the texture as described at https://learn.microsoft.com/en-us/windows/win32/direct3d9/automatic-generation-of-mipmaps

But we dont set any MIP filter. I think we need to do proper state management and enable MIP filter when we use diffuse and selfllum texture maps. I think currently we are not using mipmaps in case of diffuse and selfllum texture maps in D3D in case of minification.
Comments
There is difference in how we initialize sampler states in HLSL shader between Direct3D 9 and Direct3D 10 : https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-sample This also should be taken care if we create texture samplers in shaders.
30-06-2023

One more thing i noticed while going through the code is, SetSamplerState() expects us to set sampler parameters for a particular sampler stage index: https://learn.microsoft.com/en-us/windows/win32/api/d3d9/nf-d3d9-idirect3ddevice9-setsamplerstate We are setting sampler states only for stage index 0 in D3DContext::setDeviceParametersFor3D(): SUCCEEDED(res = pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP)) && SUCCEEDED(res = pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP)) && // Set texture filter to bilinear for 3D rendering SUCCEEDED(res = pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR)) && SUCCEEDED(res = pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR)); But in Mtl1PS.hlsl we map each texture maps to different stage indices: // sampler mapping see sampler mapDiffuse : register(s0); sampler mapSpecular : register(s1); sampler mapBumpHeight : register(s2); sampler mapSelfIllum : register(s3); Looks like we are applying linear filter only for diffuseMap and might be using D3DTEXF_POINT for Min/Mag and D3DTEXF_NONE for Mip Filter for other texture maps. This also needs to be verified.
30-06-2023

While working on JDK-8310109 noticed that we generate automated mipmaps for 3D texture maps in D3D but we dont enable mip filter. Verified that we see the difference in diffuse texture maps between D3D and other pipelines since we don't use mipmapped textures. We need to enable mip filter in D3D also to match output of other pipelines.
30-06-2023

I can reproduce this as far back as JDK 8. It's still a bug in mainline.
28-06-2023

I verified in Windows OpenGL pipeline also and i see mipmap getting used. Attached image for the same.
28-06-2023

Added mip filter by default in D3DContext::setDeviceParametersFor3D() and i can see visible differences with and without mipmapping in Windows D3D. Looks like we are using generated mipmapped images in 3D rendering of D3D pipeline. Trying to build ES2 pipeline on windows and check difference with D3D. Attached output with of and without mipmapping on D3D pipeline. Mipmapped output of D3D matches mipmapped output of OpenGL and Metal in macOS.
28-06-2023

We can see visible difference with & without mipmap when we apply large textures on small 3D primitives. We create mipmapped textures for diffuse texture map in JavaFX 3D implementation. Sample program : import javafx.application.Application; import javafx.geometry.Point3D; import javafx.scene.Group; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.scene.paint.PhongMaterial; import javafx.scene.shape.Cylinder; import javafx.stage.Stage; public class DiffuseMap_3D extends Application { final int SCENE_WIDTH = 600; final int SCENE_HEIGHT = 600; public Parent createContent() throws Exception { Cylinder testCylinder = new Cylinder(100.0, 200.0); testCylinder.setLayoutX(SCENE_WIDTH/4); testCylinder.setLayoutY(SCENE_HEIGHT/2); Image diffuseMap = new Image("04.jpg"); //Image diffuseMap = new Image("duke.png"); PhongMaterial phongMaterial = new PhongMaterial(); phongMaterial.setDiffuseMap(diffuseMap); testCylinder.setMaterial(phongMaterial); testCylinder.setRotationAxis(new Point3D(1,1,1)); testCylinder.setRotate(45); Group root = new Group(); root.getChildren().add(testCylinder); return root; } @Override public void start(Stage primaryStage) throws Exception { Scene scene = new Scene(createContent(), SCENE_WIDTH, SCENE_HEIGHT); primaryStage.setScene(scene); primaryStage.show(); } /** * Java main for when running without JavaFX launcher */ public static void main(String[] args) { launch(args); } } Attached large image also.
28-06-2023