I'm new to all of this, first of all. I have a pentagon shape, which
is of course made up of three triangles. I've generated them by hand,
and used a TriangleFanArray, but I get the same result when using a
PointLight or SpotLight - you can see the borders of the triangles.
It's like the lights think each triangle is different enough to not
light it the same. The effect is really apparent if I set the
ColoringAttributes to SHADE_FLAT. Why would this be? It looks fine
with a DirectionalLight, by the way.
Is there something I can do with the material or appearance to fix
this?
> I have a pentagon shape, which is of course made up of three
> triangles. I've generated them by hand, and used a
> TriangleFanArray, but I get the same result when using a
> PointLight or SpotLight - you can see the borders of the
> triangles. It's like the lights think each triangle is
> different enough to not light it the same.
You're probably seeing Mach banding.
This is a fundamental limitation of Gouraud shading which just
linearly interpolates color intensities across the triangle
vertices. The human visual system is very good at detecting
2nd-order discontinuities across shading gradients, which will
occur at the boundaries of your triangles with Gouraud shading.
> The effect is really apparent if I set the ColoringAttributes
> to SHADE_FLAT. Why would this be? It looks fine with a
> DirectionalLight, by the way.
With directional lighting the light source is at infinity, so all
the normals of your flat surface are at the same angle to the
light source and will be lit the same. With point and spot
sources each normal will be at a slightly different angle with
respect to the positional light source and will receive a
different shade value when lit. These differences are made much
more apparent with flat shading.
> Is there something I can do with the material or appearance to
> fix this?
Ideally you would use Phong shading, which interpolates dot
products for each pixel across a triangle instead of just color
intensities. This is available with modern pixel shader GPUs. I
think Java 3D 1.4 supports that stuff.
You can simulate Phong shading to an arbitrary degree by dividing
your surface up into smaller triangles. When each triangle is
about the size of a pixel you'll have perfect shading for
positional light sources, but you'll of course run slower and use
lots more memory.
You might also be able to minimize the mach banding with Gouraud
shading by turning down or completely eliminating the specular
coefficients of the surface. Specular lighting involves
exponentiation of the dot products at the triangle vertices and
will exaggerate the tesselated nature of the surface.
The easiest workaround is to just use directional lighting. It's
easier for the GPU to compute as well and you'll have better
performance.
-- Mark Hood
Ed - 10 Oct 2005 01:35 GMT
Thank you, you've explained it very well, and mentioning Phong shading
was something good for me follow up on and research.
I understand now exactly what's going on, by splitting a pentagon into
3 triangles, the shading on the thin triangles doesn't match the
larger ones, which makes perfect sense given their thinness and the
way they lie with the large one.
I was playing arounda bit more with directional lighting and
adjusting the colors here and there to get an effect that's more
likeable - I didn't like directional at first because it seemed when a
side directly faced that way, it turned pure white...but I've figured
out how to fix that now :)
Thanks again!
Ed