Commit 13767682 authored by Matthias Betz's avatar Matthias Betz
Browse files

Extract fake-shading math into pure ShadeColor

parent 3087a8d7
package de.hft.stuttgart.citydoctor2.gui.gl;
import de.hft.stuttgart.citydoctor2.math.UnitVector3d;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
import javafx.scene.paint.Color;
/**
* Computes the surface-differentiation shade used by the legacy renderer: brightness derived from the
* angle between the polygon normal and a fixed axis. Not physical lighting; only makes adjacent faces
* distinguishable. Ported from {@code TriangulatedGeometry.calculateMaterial}.
*/
public final class ShadeColor {
private static final UnitVector3d AXIS = new Vector3d(19, 0.8, 1.5).normalize();
private ShadeColor() {}
public static Color shade(Vector3d normal, Color base) {
double cos = normal.dot(AXIS);
// clamp to acos domain; raw dot can drift slightly outside [-1,1] for near-parallel normals
cos = Math.max(-1.0, Math.min(1.0, cos));
double brightness = Math.acos(cos) / Math.PI * 0.6 + 0.3; // -> [0.3, 0.9]
return base.deriveColor(0, 1.0, brightness, 1.0);
}
}
package de.hft.stuttgart.citydoctor2.gui.gl;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
import javafx.scene.paint.Color;
import org.junit.Test;
public class ShadeColorTest {
@Test
public void brightnessStaysWithinExpectedBand() {
// Shade brightness is acos(normal.AXIS)/PI * 0.6 + 0.3 -> always within [0.3, 0.9].
Vector3d[] normals = {
new Vector3d(1, 0, 0), new Vector3d(0, 1, 0), new Vector3d(0, 0, 1),
new Vector3d(-1, 0, 0), new Vector3d(0.3, -0.7, 0.5)
};
for (Vector3d n : normals) {
Color c = ShadeColor.shade(n.normalize(), Color.WHITE);
assertTrue("brightness >= 0.3", c.getBrightness() >= 0.3 - 1e-6);
assertTrue("brightness <= 0.9", c.getBrightness() <= 0.9 + 1e-6);
}
}
@Test
public void matchesLegacyFormulaForKnownNormal() {
Vector3d axis = new Vector3d(19, 0.8, 1.5).normalize();
Vector3d normal = new Vector3d(0, 0, 1).normalize();
double cos = Math.max(-1.0, Math.min(1.0, normal.dot(axis)));
double shade = Math.acos(cos) / Math.PI * 0.6 + 0.3;
Color expected = Color.WHITE.deriveColor(0, 1.0, shade, 1.0);
Color actual = ShadeColor.shade(normal, Color.WHITE);
assertEquals(expected.getRed(), actual.getRed(), 1e-9);
assertEquals(expected.getGreen(), actual.getGreen(), 1e-9);
assertEquals(expected.getBlue(), actual.getBlue(), 1e-9);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment