Skip to content

Commit 4309b2f

Browse files
committed
#2416 Automate TestPBRLighting as a screenshot test
1 parent dcb2262 commit 4309b2f

1 file changed

Lines changed: 162 additions & 0 deletions

File tree

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
package org.jmonkeyengine.screenshottests.light.pbr;
2+
3+
import com.jme3.app.Application;
4+
import com.jme3.app.SimpleApplication;
5+
import com.jme3.app.state.BaseAppState;
6+
import com.jme3.asset.AssetManager;
7+
import com.jme3.environment.EnvironmentCamera;
8+
import com.jme3.environment.FastLightProbeFactory;
9+
import com.jme3.light.DirectionalLight;
10+
import com.jme3.light.LightProbe;
11+
import com.jme3.material.Material;
12+
import com.jme3.math.ColorRGBA;
13+
import com.jme3.math.Vector3f;
14+
import com.jme3.post.FilterPostProcessor;
15+
import com.jme3.post.filters.ToneMapFilter;
16+
import com.jme3.renderer.Camera;
17+
import com.jme3.scene.Geometry;
18+
import com.jme3.scene.Node;
19+
import com.jme3.scene.Spatial;
20+
import com.jme3.texture.plugins.ktx.KTXLoader;
21+
import com.jme3.util.SkyFactory;
22+
import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
23+
import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase;
24+
import org.junit.jupiter.api.TestInfo;
25+
import org.junit.jupiter.params.ParameterizedTest;
26+
import org.junit.jupiter.params.provider.Arguments;
27+
import org.junit.jupiter.params.provider.MethodSource;
28+
29+
import java.util.stream.Stream;
30+
31+
/**
32+
* Screenshot tests for PBR lighting.
33+
*
34+
* @author nehon - original test
35+
* @author Richard Tingle (aka richtea) - screenshot test adaptation
36+
*
37+
*/
38+
public class TestPBRLighting extends ScreenshotTestBase {
39+
40+
private static Stream<Arguments> testParameters() {
41+
return Stream.of(
42+
Arguments.of("LowRoughness", 0.1f, false),
43+
Arguments.of("HighRoughness", 1.0f, false),
44+
Arguments.of("DefaultDirectionalLight", 0.5f, false),
45+
Arguments.of("UpdatedDirectionalLight", 0.5f, true)
46+
);
47+
}
48+
49+
/**
50+
* Test PBR lighting with different parameters
51+
*
52+
* @param testName The name of the test (used for screenshot filename)
53+
* @param roughness The roughness value to use
54+
* @param updateLight Whether to update the directional light to match camera direction
55+
*/
56+
@ParameterizedTest(name = "{0}")
57+
@MethodSource("testParameters")
58+
public void testPBRLighting(String testName, float roughness, boolean updateLight, TestInfo testInfo) {
59+
60+
if(!testInfo.getTestClass().isPresent() || !testInfo.getTestMethod().isPresent()) {
61+
throw new RuntimeException("Test preconditions not met");
62+
}
63+
64+
String imageName = testInfo.getTestClass().get().getName() + "." + testInfo.getTestMethod().get().getName() + "_" + testName;
65+
66+
screenshotTest(new BaseAppState() {
67+
private static final int RESOLUTION = 256;
68+
69+
private Node modelNode;
70+
private int frame = 0;
71+
72+
@Override
73+
protected void initialize(Application app) {
74+
Camera cam = app.getCamera();
75+
cam.setLocation(new Vector3f(18, 10, 0));
76+
cam.lookAt(new Vector3f(0, 0, 0), Vector3f.UNIT_Y);
77+
78+
79+
AssetManager assetManager = app.getAssetManager();
80+
assetManager.registerLoader(KTXLoader.class, "ktx");
81+
82+
app.getViewPort().setBackgroundColor(ColorRGBA.White);
83+
84+
modelNode = new Node("modelNode");
85+
Geometry model = (Geometry) assetManager.loadModel("Models/Tank/tank.j3o");
86+
MikktspaceTangentGenerator.generate(model);
87+
modelNode.attachChild(model);
88+
89+
DirectionalLight dl = new DirectionalLight();
90+
dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());
91+
SimpleApplication simpleApp = (SimpleApplication) app;
92+
simpleApp.getRootNode().addLight(dl);
93+
dl.setColor(ColorRGBA.White);
94+
95+
// If we need to update the light direction to match camera
96+
if (updateLight) {
97+
dl.setDirection(app.getCamera().getDirection().normalize());
98+
}
99+
100+
simpleApp.getRootNode().attachChild(modelNode);
101+
102+
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
103+
int numSamples = app.getContext().getSettings().getSamples();
104+
if (numSamples > 0) {
105+
fpp.setNumSamples(numSamples);
106+
}
107+
108+
fpp.addFilter(new ToneMapFilter(Vector3f.UNIT_XYZ.mult(4.0f)));
109+
app.getViewPort().addProcessor(fpp);
110+
111+
Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Path.hdr", SkyFactory.EnvMapType.EquirectMap);
112+
simpleApp.getRootNode().attachChild(sky);
113+
114+
Material pbrMat = assetManager.loadMaterial("Models/Tank/tank.j3m");
115+
pbrMat.setFloat("Roughness", roughness);
116+
model.setMaterial(pbrMat);
117+
118+
// Set up environment camera
119+
EnvironmentCamera envCam = new EnvironmentCamera(RESOLUTION, new Vector3f(0, 3f, 0));
120+
app.getStateManager().attach(envCam);
121+
}
122+
123+
@Override
124+
protected void cleanup(Application app) {}
125+
126+
@Override
127+
protected void onEnable() {}
128+
129+
@Override
130+
protected void onDisable() {}
131+
132+
@Override
133+
public void update(float tpf) {
134+
frame++;
135+
136+
if (frame == 2) {
137+
modelNode.removeFromParent();
138+
LightProbe probe;
139+
140+
SimpleApplication simpleApp = (SimpleApplication) getApplication();
141+
probe = FastLightProbeFactory.makeProbe(simpleApp.getRenderManager(),
142+
simpleApp.getAssetManager(),
143+
RESOLUTION,
144+
Vector3f.ZERO,
145+
1f,
146+
1000f,
147+
simpleApp.getRootNode());
148+
149+
probe.getArea().setRadius(100);
150+
simpleApp.getRootNode().addLight(probe);
151+
}
152+
153+
if (frame > 10 && modelNode.getParent() == null) {
154+
SimpleApplication simpleApp = (SimpleApplication) getApplication();
155+
simpleApp.getRootNode().attachChild(modelNode);
156+
}
157+
}
158+
}).setBaseImageFileName(imageName)
159+
.setFramesToTakeScreenshotsOn(12)
160+
.run();
161+
}
162+
}

0 commit comments

Comments
 (0)