|
|
Andrew Cocker wrote:
> Ideally, what I'd like to be able to do, is this:
>
> Wherever a specular highlight on an object occurs, if that highlight is
> above a certain brightness threshold, then place a lens flare there, with
> an equivalent brightness, size etc. Obviously this wouldn't work (or would
> be impractical) for objects with many specular highlights - where a
> surface normal is used for example, but on simpler objects it should work
> ok I think.
You can calculate the exact point of the highlight with planes and spheres
(and objects constructed of only these two things like meshs for example)
when there is no normal pertubation. With all other objects and pertubated
normals the highlights can be of any shape and you may have difficulty
where to place the lens flare even when doing by hand.
A highlight occurs where the light rays from the light source are directly
reflected into the camera (and the surface supports this). If you put some
objects at the place where the light source is and make the highlighting
object reflective you will see the reflection of that object where
previously the highlight was. Equivalently if you shoot a ball from the
camera to the point of hightlight it will hit the light source.
Calculating the highlight on a plane is easy: Just mirror the lightsource L
at the plane (-> L') and intersect the line camera-L' with the plane. Of
course there is only a highlight visible at the intersection point P if
nothing is between the camera and P and nothing between P and the
lightsource.
Following I will provide a solution for calculating the mid-point of
specular highlights on a sphere. First you can reduce the problem from 3D
to 2D: the camera, the light source, the sphere's midpoint and the
highlighting point lie all in the same plane. Therefore you can restrict
all calculations to this plane.
To make calculation easier I place the camera at position <a,0,0>, the
light source at position <px,py,0> and the sphere at the origin with radius
1. If you want a general solution you can always rotate, translate and
scale things so that they come to lie in that way.
Let n be the vector pointing from the origin to the highlighting point R,
q the vector <a,0,0> and p the vector <px,py,0>. Now we mirror q at the
tangent in R and get q'.
If n is the solution then the vectors n-q' and p-n have to be collinear:
l(n-q')=p-n
where l is a factor and l>=0.
I do not provide more mathematics of the solution here. If you know a bit
German you might have a look at
http://www.wr.inf.ethz.ch/education/nsr/exercises/ex12/ex.ps and
http://www.wr.inf.ethz.ch/education/nsr/exercises/ex12/sol.ps
where two ways of solving an equivilent problem are presented.
You can reduce the problem to a 4th-order polynom equation only having 'l'
as unknown:
a^2*(a^2-1) * l^4 + 2a(a-px) * l^3 +
(4a*px-a^2-(px^2-py^2)*(1+2a^2)) * l^2 + 2(px^2+py^2-a*px) * l +
(px^4+py^4+2px^2*py^2-px^2-py^2) == 0
Now one needs to find the roots of this polynom and with that you can
calculate n:
l-1
n = ------------------- * <a*l+px,py,0>
a^2*l^2-px^2-py^2
With that you find all possible points of highlights. However some of them
can be hidden by the sphere itself. For example if both camera and
lightsource are outside the sphere you will see at most one highlight. But
when the sphere is partly open or transparent you can see highlights in the
inner. You can use the trace() function to check if highlights are hidden
or not.
If both camera and lightsource are inside the sphere you will have up to 4
highligths. All of them are found as roots of the polynom above.
Calculation of n fails when |a|=||p|| (division zero by zero) but this
happens to be a special case where it is easy to calculate the highlights
differently.
I have written a macro which calculates the position of highlights in the
way mentioned above. However it uses a clumsy implementation of Newton's
algorithm to calculate the roots and does not always find the relevant ones.
(Shouldn't there be a standard macro for doing that?).
Macro is in p.t.s-f.
An alternative way to find the highlights is to do it the way a ray-tracer
does: It does not find the midpoints of them but can calculate how bright
the highlight is at some point. So you could for example use povray to
trace a picture of your scene where you have all textures replaced so that
everything is black except the highlights. Then you would have to find the
centers of the highlights showing up in the resulting picture and could
trace() at those points to find where to place the light flare.
- Micha
Post a reply to this message
|
|