31
Support / Re: Lighting on merged Object3Ds
« on: December 12, 2021, 04:32:09 am »Actually, if the normals have been calculated (or loaded from file with Config.useNormalsFromOBJ=true) already before merging, they won't be recalculated after the merge when you call build on the merged object. I'm not sure if your issue is related to merging at all, though. I rather think it's caused by normal vectors that aren't calculated in a why that fits your scene. Does the file from which these objects come includes normals? In that case, you could try the config switch mentioned above.I'm not using models from files, but I create them using Object3D#addTriangle (as they are simple planes sort of...)
I don't think the Config switch would do anything for this...
I was able to create a test case, however... (it doesn't look amazing but it shows the problem I guess...)
Code: [Select]
final GLSurfaceView.Renderer testRenderer = new GLSurfaceView.Renderer() {
private FrameBuffer frameBuffer;
private World world;
private Object3D master;
private Object3D plane1;
private Object3D plane2;
private Object3D plane3;
private Camera camera;
@Override
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
}
@Override
public void onSurfaceChanged(GL10 gl10, int w, int h) {
Config.nearPlane = 1f;
Config.glIgnoreNearPlane = false;
frameBuffer = new FrameBuffer(w, h);
world = new World();
world.setAmbientLight(0, 0, 0);
Light l1 = new Light(world);
l1.setPosition(new SimpleVector(0f, 6f, 0f));
camera = world.getCamera();
final Texture sphereTexture = new Texture(2, 2, new RGBColor(75, 0, 0));
final Texture overlayTexture = new Texture(2, 2, new RGBColor(0, 0, 75));
final Texture planeTexture = new Texture(2, 2, new RGBColor(0, 75, 0));
final TextureManager textureManager = TextureManager.getInstance();
textureManager.addTexture("tex0", sphereTexture);
textureManager.addTexture("tex1", overlayTexture);
textureManager.addTexture("tex2", planeTexture);
master = Object3D.createDummyObj();
plane1 = new Object3D(4);
plane2 = new Object3D(8);
plane3 = new Object3D(8);
plane1.addTriangle(new SimpleVector(-5.55, -0.941941941, -1.0), 0.0f, 0.0f, new SimpleVector(-5.55, -0.941941941, 1.0), 0.0f, 1.0f, new SimpleVector(5.55, -0.941941941, -1.0), 1.0f, 0.0f);
plane1.addTriangle(new SimpleVector(5.55, -0.941941941, 1.0), 1.0f, 1.0f, new SimpleVector(5.55, -0.941941941, -1.0), 1.0f, 0.0f, new SimpleVector(-5.55, -0.941941941, 1.0), 0.0f, 1.0f);
//roadMaster.setAdditionalColor(100, 100, 100);
plane1.setAdditionalColor(100, 100, 100);
plane1.compile(false, true);
plane1.strip();
plane1.build();
plane1.setTexture("tex0");
plane2.addTriangle(new SimpleVector(-6.6, -0.939, -1.02), 0.5f, 0.0f, new SimpleVector(-6.6, -0.939, 1.02), 0.5f, 1.0f, new SimpleVector(-5.55, -0.941941941, -1.02), 1.0f, 0.0f);
plane2.addTriangle(new SimpleVector(-5.55, -0.941941941, 1.02), 1.0f, 1.0f, new SimpleVector(-5.55, -0.941941941, -1.02), 1.0f, 0.0f, new SimpleVector(-6.6, -0.939, 1.02), 0.5f, 1.0f);
plane2.addTriangle(new SimpleVector(5.55, -0.941941941, -1.02), 0.0f, 0.0f, new SimpleVector(5.55, -0.941941941, 1.02), 0.0f, 1.0f, new SimpleVector(6.6, -0.939, -1.02), 0.5f, 0.0f);
plane2.addTriangle(new SimpleVector(6.6, -0.939, 1.02), 0.5f, 1.0f, new SimpleVector(6.6, -0.939, -1.02), 0.5f, 0.0f, new SimpleVector(5.55, -0.941941941, 1.02), 0.0f, 1.0f);
plane2.setAdditionalColor(100, 100, 100);
plane2.compile(false, true);
plane2.strip();
plane2.build();
plane2.setTexture("tex1");
float heightMultiplier = 333f;
float lastHeightLeft = 0.03f;
float newHeightLeft = 0.024f;
float newHeightRight = 0.012f;
float lastHeightRight = 0.01f;
// base
plane3.setAdditionalColor(100, 100, 100);
plane3.addTriangle(new SimpleVector(-11.4f, lastHeightLeft * heightMultiplier / 3f, -1.02), 0.5f, 0.0f, new SimpleVector(-11.4f, newHeightLeft * heightMultiplier / 3f, 1.02), 0.5f, 1.0f, new SimpleVector(-6.6f, -0.939, -1.02), 1.0f, 0.0f);
plane3.addTriangle(new SimpleVector(-6.6f, -0.939, 1.02), 1.0f, 1.0f, new SimpleVector(-6.6f, -0.939, -1.02), 1.0f, 0.0f, new SimpleVector(-11.4f, newHeightLeft * heightMultiplier / 3f, 1.02), 0.5f, 1.0f);
plane3.addTriangle(new SimpleVector(6.6f, -0.939, -1.02), 0.0f, 0.0f, new SimpleVector(6.6f, -0.939, 1.02), 0.0f, 1.0f, new SimpleVector(11.4f, lastHeightRight * heightMultiplier / 3f, -1.02), 0.5f, 0.0f);
plane3.addTriangle(new SimpleVector(11.4f, newHeightRight * heightMultiplier / 3f, 1.02), 0.5f, 1.0f, new SimpleVector(11.4f, lastHeightRight * heightMultiplier / 3f, -1.02), 0.5f, 0.0f, new SimpleVector(6.6f, -0.939, 1.02), 0.0f, 1.0f);
plane3.setTexture("tex2");
plane3.build();
boolean merge = false;
if(merge){
Object3D mergeObj = Object3D.mergeObjects(plane1, plane2);
mergeObj = Object3D.mergeObjects(plane3, mergeObj);
world.addObject( mergeObj);
}else {
world.addObject(plane1);
world.addObject(plane2);
world.addObject(plane3);
Object3D mergeObj = Object3D.mergeObjects(plane1, plane2);
mergeObj = Object3D.mergeObjects(plane3, mergeObj);
world.addObject( mergeObj);
mergeObj.setSpecularLighting(false);
mergeObj.translate(0,0,3f);
}
}
@Override
public void onDrawFrame(GL10 gl10) {
frameBuffer.clear();
final float maxDistance = 150f;
camera.setPosition(-(0.5f * ((float) Math.abs(Math.cos(world.getFrameCounter() * 0.03f))) + 0.25f) * maxDistance, 30f, 0f);
camera.lookAt(new SimpleVector(0,0,0));
world.renderScene(frameBuffer);
world.draw(frameBuffer);
frameBuffer.display();
}
};
// Attach to some GLSurfaceView...
viewer.setRenderer(testRenderer);
Results: https://imgur.com/a/KffOw9m (left = merged object, right = not merged objects)
The first two images show the same but at a slightly different camera distance/angle, and you can see that the green tile on the left object is slightly darker than the in the second image.
In the last image, you can see some shading pattern on the red and green on the left object.
These do share coordinates however... maybe that nullifies the build() effect...
EDIT:
Okay... apparently it still happens when the coordinates are NOT shared...
So now I don't understand why build() didn't work...
Code snippet for non-sharing coordinates (replace these lines in the test case...):
Code: [Select]
plane2.addTriangle(new SimpleVector(-6.6, - 0.9, -1.02), 0.5f, 0.0f, new SimpleVector(-6.6, - 0.9, 1.02), 0.5f, 1.0f, new SimpleVector(-5.55, - 0.9, -1.02), 1.0f, 0.0f);
plane2.addTriangle(new SimpleVector(-5.55, - 0.9, 1.02), 1.0f, 1.0f, new SimpleVector(-5.55, - 0.9, -1.02), 1.0f, 0.0f, new SimpleVector(-6.6, - 0.9, 1.02), 0.5f, 1.0f);
plane2.addTriangle(new SimpleVector(5.55, - 0.9, -1.02), 0.0f, 0.0f, new SimpleVector(5.55, - 0.9, 1.02), 0.0f, 1.0f, new SimpleVector(6.6, - 0.9, -1.02), 0.5f, 0.0f);
plane2.addTriangle(new SimpleVector(6.6, - 0.9, 1.02), 0.5f, 1.0f, new SimpleVector(6.6, - 0.9, -1.02), 0.5f, 0.0f, new SimpleVector(5.55, - 0.9, 1.02), 0.0f, 1.0f);
plane2.setAdditionalColor(100, 100, 100);
plane2.compile(false, true);
plane2.strip();
plane2.build();
plane2.setTexture("tex1");
float heightMultiplier = 333f;
float lastHeightLeft = 0.03f;
float newHeightLeft = 0.024f;
float newHeightRight = 0.012f;
float lastHeightRight = 0.01f;
// base
plane3.setAdditionalColor(100, 100, 100);
plane3.addTriangle(new SimpleVector(-11.4f, lastHeightLeft * heightMultiplier / 3f, -1.02), 0.5f, 0.0f, new SimpleVector(-11.4f, newHeightLeft * heightMultiplier / 3f, 1.02), 0.5f, 1.0f, new SimpleVector(-6.6f, -0.941941941, -1.02), 1.0f, 0.0f);
plane3.addTriangle(new SimpleVector(-6.6f, -0.941941941, 1.02), 1.0f, 1.0f, new SimpleVector(-6.6f, -0.941941941, -1.02), 1.0f, 0.0f, new SimpleVector(-11.4f, newHeightLeft * heightMultiplier / 3f, 1.02), 0.5f, 1.0f);
plane3.addTriangle(new SimpleVector(6.6f, -0.941941941, -1.02), 0.0f, 0.0f, new SimpleVector(6.6f, -0.941941941, 1.02), 0.0f, 1.0f, new SimpleVector(11.4f, lastHeightRight * heightMultiplier / 3f, -1.02), 0.5f, 0.0f);
plane3.addTriangle(new SimpleVector(11.4f, newHeightRight * heightMultiplier / 3f, 1.02), 0.5f, 1.0f, new SimpleVector(11.4f, lastHeightRight * heightMultiplier / 3f, -1.02), 0.5f, 0.0f, new SimpleVector(6.6f, -0.941941941, 1.02), 0.0f, 1.0f);
plane3.setTexture("tex2");
plane3.build();
EDIT2: I forgot to set the additionalColor on the merged object... Just forget everything above...
Here is a test case without any additionalColor:
Code: [Select]
final GLSurfaceView.Renderer testRenderer = new GLSurfaceView.Renderer() {
private FrameBuffer frameBuffer;
private World world;
private Object3D master;
private Object3D plane1;
private Object3D plane2;
private Object3D plane3;
private Camera camera;
@Override
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
}
@Override
public void onSurfaceChanged(GL10 gl10, int w, int h) {
Config.nearPlane = 1f;
Config.glIgnoreNearPlane = false;
frameBuffer = new FrameBuffer(w, h);
world = new World();
world.setAmbientLight(0, 0, 0);
Light l1 = new Light(world);
l1.setPosition(new SimpleVector(0f, 6f, 0f));
camera = world.getCamera();
final Texture sphereTexture = new Texture(2, 2, new RGBColor(75, 0, 0));
final Texture overlayTexture = new Texture(2, 2, new RGBColor(0, 0, 75));
final Texture planeTexture = new Texture(2, 2, new RGBColor(0, 75, 0));
final TextureManager textureManager = TextureManager.getInstance();
textureManager.addTexture("tex0", sphereTexture);
textureManager.addTexture("tex1", overlayTexture);
textureManager.addTexture("tex2", planeTexture);
master = Object3D.createDummyObj();
plane1 = new Object3D(4);
plane2 = new Object3D(8);
plane3 = new Object3D(8);
plane1.addTriangle(new SimpleVector(-5.55, -0.941941941, -1.0), 0.0f, 0.0f, new SimpleVector(-5.55, -0.941941941, 1.0), 0.0f, 1.0f, new SimpleVector(5.55, -0.941941941, -1.0), 1.0f, 0.0f);
plane1.addTriangle(new SimpleVector(5.55, -0.941941941, 1.0), 1.0f, 1.0f, new SimpleVector(5.55, -0.941941941, -1.0), 1.0f, 0.0f, new SimpleVector(-5.55, -0.941941941, 1.0), 0.0f, 1.0f);
//roadMaster.setAdditionalColor(100, 100, 100);
//plane1.setAdditionalColor(100, 100, 100);
plane1.compile(false, true);
plane1.strip();
plane1.build();
plane1.setTexture("tex0");
plane2.addTriangle(new SimpleVector(-6.6, - 0.9, -1.02), 0.5f, 0.0f, new SimpleVector(-6.6, - 0.9, 1.02), 0.5f, 1.0f, new SimpleVector(-5.55, - 0.9, -1.02), 1.0f, 0.0f);
plane2.addTriangle(new SimpleVector(-5.55, - 0.9, 1.02), 1.0f, 1.0f, new SimpleVector(-5.55, - 0.9, -1.02), 1.0f, 0.0f, new SimpleVector(-6.6, - 0.9, 1.02), 0.5f, 1.0f);
plane2.addTriangle(new SimpleVector(5.55, - 0.9, -1.02), 0.0f, 0.0f, new SimpleVector(5.55, - 0.9, 1.02), 0.0f, 1.0f, new SimpleVector(6.6, - 0.9, -1.02), 0.5f, 0.0f);
plane2.addTriangle(new SimpleVector(6.6, - 0.9, 1.02), 0.5f, 1.0f, new SimpleVector(6.6, - 0.9, -1.02), 0.5f, 0.0f, new SimpleVector(5.55, - 0.9, 1.02), 0.0f, 1.0f);
//plane2.setAdditionalColor(100, 100, 100);
plane2.compile(false, true);
plane2.strip();
plane2.build();
plane2.setTexture("tex1");
float heightMultiplier = 333f;
float lastHeightLeft = 0.03f;
float newHeightLeft = 0.024f;
float newHeightRight = 0.012f;
float lastHeightRight = 0.01f;
// base
//plane3.setAdditionalColor(100, 100, 100);
plane3.addTriangle(new SimpleVector(-11.4f, lastHeightLeft * heightMultiplier / 3f, -1.02), 0.5f, 0.0f, new SimpleVector(-11.4f, newHeightLeft * heightMultiplier / 3f, 1.02), 0.5f, 1.0f, new SimpleVector(-6.6f, -0.941941941, -1.02), 1.0f, 0.0f);
plane3.addTriangle(new SimpleVector(-6.6f, -0.941941941, 1.02), 1.0f, 1.0f, new SimpleVector(-6.6f, -0.941941941, -1.02), 1.0f, 0.0f, new SimpleVector(-11.4f, newHeightLeft * heightMultiplier / 3f, 1.02), 0.5f, 1.0f);
plane3.addTriangle(new SimpleVector(6.6f, -0.941941941, -1.02), 0.0f, 0.0f, new SimpleVector(6.6f, -0.941941941, 1.02), 0.0f, 1.0f, new SimpleVector(11.4f, lastHeightRight * heightMultiplier / 3f, -1.02), 0.5f, 0.0f);
plane3.addTriangle(new SimpleVector(11.4f, newHeightRight * heightMultiplier / 3f, 1.02), 0.5f, 1.0f, new SimpleVector(11.4f, lastHeightRight * heightMultiplier / 3f, -1.02), 0.5f, 0.0f, new SimpleVector(6.6f, -0.941941941, 1.02), 0.0f, 1.0f);
plane3.setTexture("tex2");
plane3.build();
boolean merge = false;
if(merge){
Object3D mergeObj = Object3D.mergeObjects(plane1, plane2);
mergeObj = Object3D.mergeObjects(plane3, mergeObj);
//mergeObj.setAdditionalColor(100, 100, 100);
world.addObject( mergeObj);
}else {
world.addObject(plane1);
world.addObject(plane2);
world.addObject(plane3);
Object3D mergeObj = Object3D.mergeObjects(plane1, plane2);
mergeObj = Object3D.mergeObjects(plane3, mergeObj);
world.addObject( mergeObj);
//mergeObj.setAdditionalColor(100, 100, 100);
mergeObj.translate(0,0,3f);
plane1.translate(0,0,-3f);
plane2.translate(0,0,-3f);
plane3.translate(0,0,-3f);
}
}
@Override
public void onDrawFrame(GL10 gl10) {
frameBuffer.clear();
final float maxDistance = 150f;
camera.setPosition(-(0.5f * ((float) Math.abs(Math.cos(world.getFrameCounter() * 0.03f))) + 0.25f) * maxDistance, 30f, 0f);
camera.lookAt(new SimpleVector(0,0,0));
world.renderScene(frameBuffer);
world.draw(frameBuffer);
frameBuffer.display();
}
};
// Attach to some GLSurfaceView...
viewer.setRenderer(testRenderer);
EDIT3: An animated image for the last test case: https://imgur.com/a/wR8MqgG
I believe I get similar-ish results but it gets brighter for me randomly but I guess it's a similar idea
EDIT4: I have a slight feeling this issue is there because the merged Object3D is multi-textured..? I'm not entirely sure...
The issue seems to disappear if it has 1 or 2 different textures only (but when you add the third, the lighting seems to behave differently)