Lighting big faces / cutting into mini-faces

hi guys,
here is the problem: I’ve a big plane and a small pointlight near it. How to make the plane look good? Because it consists of only 2 triangles, these 2 reflect the light more or less, making a bright one and a dark one, damn ugly. As far as I know, the only way to get best shading is to cut this big plane into small pieces (more triangles) so that each face can reflect it’s part of light. (I already tried to apply NICEST shading to the plane but the problem remains the same)

This brings a new problem:
Given points A, B, C and some sort of size limit, how to make a good big triangle face consisting of many small triangles (depending on the size limit)?
This looks like a damn hard mathematic problem, as well as a hard to program stuff!
Can anyone help me?

If there are any good alternatives, i take them!
… i’ve maybe missed some util class to help doing such things …

I suppose you want a generic algorithm for splitting up a single triangle into many triangles?

Take a vector between each point in your original triangle (A,B,C) and find the centre point (half the vector).

Form four triangles:

  1. A,AB,AC (where AB and AC are centre points)
  2. B,AB,BC
  3. C,AC,BC
  4. AB,AC,BC

Repeat til your triangle is sufficently broken.

Kev

Yes, you can either divide your plane into smaller triangles or, if you ligthing is static and uses mostly diffuse materials, you can render your lighting into a texture and combine it with the texture on your plane, drawing the plane as unlit geometry. The latter technique is called lightmapping and is used in many games but the problem is that lightmaps, and multitexturing in general, are hard to export/import from 3D-modeling apps to Java3D.

I don’t know of any apps for doing automatic division of your plane into smaller triangles that makes it look good with the lighting. I did that manually in Maya for my last project by just subdividing and occasionally manually splitting individual polygons until I got acceptable results.

There may also be some way to get better results by using new shader tricks, but those aren’t available in Java3D.

You can try to use some kind of per-pixel lightning.

Disable normal lighting for this triangle. Compute normal versus direction to light for each vertex and put it into color. Then do DOT3 with constant (it gets a bit tricky here, you need to look at object/light/view coordinates). This should give you brightness for each pixel, which you can later use to multiply with texture to get final image.

Basically, you are doing normal normal/light calculation here - but for each pixel, not just for vertex. You can also look at it as a kind of dot3 bump mapping, just with flat bumpmap.

Sorry for not being more specific about coordinate space - I do not have time to exactly check which should be used at which stage.

Please also note that you will get only diffuse light with such approach - specular highlight requires a bit more complicated function, not available in java3d AFAIK.

thanks for the interesting replies, however, it is still not adequate.
The first proposition (kevglass) should be largely optimized because it’s result goes worse as the triangle gets “thin”. For a triangle: (0,0,0),(0,1,0),(100,0,0), the subdivisions would also be many long thin triangles, causing bad lighting anyway and far too many triangles. Despite of this, it’s a very good solution as long as the triangle has side sizes of same range.
And, besides of this, it’s easy to explain/understand, but hard to do!

The second one don’t apply since the light is moving along the plane.

The third and last one is a little too complicated for me and i doubt it’s a very efficient way to do it.

Damn, isn’t there another simple way to have it well lit!?

I can’t think of a simple way, but if it is that much of a problem you might want to implement Kev’s solution if the triangle is within a certain length/height ratio and maybe break it up in a zig-zag pattern (like a child’s picture of crocodile teeth) if it is a long thin triangle.

Another slightly simpler solution might be…

Triangle (A,B,C)

Find the vector between points B and C, find the halfway point (e.g. B + half of the vector).

Form two new triangles:

A,B,Half way Point
A,C,Half way Point

This would just split each traingle through the middle.

Extensions to give nicer results might be:

  • Split based on find the middle of the longest side
  • Don’t split if the area of the triangle becomes less than a tolerance value (seach on google for area of triangle formula).

Kev

If dynamic geometry is possible, then maybe middle point of triangle could be place in closest place to light. This way, you would get nicer interpolation of diffuse light, with some kind of spot light approximation (but more triangle-shaped than circular).

As for my previous proposal, it should be absolutely acceptable with any GPU which implements DOT3 in hardware. As for the coding - I doubt it will take more than page of code, and you can reuse it for also for other objects/bumpmapping.

thanks guys,
i will do some background search on abies pixel lighting proposal cause i know nothing about it, nor have precise idea how it should be implemented. If it turns out not to be ok, for any matter, i’ll try kev’s second proposal… aie aie aie, this will take a lot of time!!