I'm about at my wit's end. I was trying the double-polar thing, but arctan() is giving me fits. Gonna try to rotate a vector using a rotation matrix. Problem is, my matrix work is way rusty. Matter of fact, I don't really do matrices as matrices exactly.
In order to avoid confusion between the (x,y,z) that is the axis you're rotating around and the (x,y,z) that is the vector you're rotating, I'd do this in two parts:
In the first part, (x,y,z) is the axis you're rotating around:
OMG this is just screwed. The code is working fine, but the route I'm taking is screwed. Every time I think I have it, something is rotated by 90 degrees at the 180 mark and I have to bang my head some more.
I'll get there eventually. Long way first, then the shortcuts.
Kepp in mind that if you're rotating by any multiple of pi/2, about half your equation will drop out because cos(pi/2) = 0, sin(pi) = 0, cos(3*pi/2) = 0, etc.
For example, with theta = pi in the equations above you end up with
code:
a11 = 1 + (1-1)x^2
a12 = (1-1)xy - (0)z
...
or
code:
a11 = 1
a12 = 0
...
.
-- not necessarily stoned... just beautiful.
DocOzone
Maniac (V) Lord Mad Scientist Sovereign of all the lands Ozone and just beyond that little green line over there...
From: Cardiff By The Sea, California Insane since: Mar 1994
posted 01-07-2007 21:12
Hah hah! I read the first couple lines, and followed the link - my first thought was "Yowza! Where's Slime?" Back to the thread, and of course, *there* is slime! Hi Slime, Hi WJ! Hope you guys are having a good new year. =)
New year is going alright, but could definitely use a vacation.
Well, I've gotten decent at rotating. I've got all the pieces and they seem to be working fine individually. However, I'm missing a little something when it comes to putting it all together. Driving me absolutley nuts. Maybe in a few days I'll put together a super pack and see if any of y'all can help me crack this.
Hi Doc =) Haven't seen you around much... though I haven't been around much myself. (Someone needs to do something about the slowness of this forum, I rarely get past the first page anymore.) Are you around the LA area? I'm living out here now so maybe I could drop by your shop sometime, if you're still doing that.
WJ, if you give some specifics maybe I could help.
Alright, Slime and the rest of you vector-heads. Gonna toss this out there. Text right now, maybe some specific resources later.
Back when I was more into 3d, I had some tricks for baking custom normal maps and then taking them in Photoshop for more post work. My own home brew of techniques for adding faux lighting, highlights, reflection layers, and other things. Gave up 3d for awhile. Then got sucked into Second Life. Over on the SL forums, the subject of normals came up. So, I'm trying to resurrect my old 2d/3d techniques for the SL crowd. Maybe even toss in a few new tricks.
The normal maps that I'm baking are full 3d in local space (screenish). By full 3d, I mean that the vectors go all the way around instead of half way around like in pure screen space.
R == 0=left, 255=right
G == 0=top, 255=bottom
B == 0=away, 255=towards
I'm grabbing these values in Photoshop and turning them into a unit vector. When you look at these maps in Photoshop, V(0,0,1) is facing. And V(0,0,-1) is the backside of the model. And V(-1,0,0) is to the left. And so on.
Using that system right there is already pretty good. In Photoshop, I can set one vector as a faux lightsource, and then get theta between that vector and V. That theta can then be used for faux lighting.
So far so good.
The next step is to add a bump map. Using Sobel, not to hard to turn a greyscale bump into a vector.
If I add G and V, everything is fine for when facing. However, everything is backwards on the backside. For V(0,0,1) + G, they add fine. For V(0,0,-1) + G, everything is rotated 180 degrees.
This is because I'm adding vectors from a sphere and vectors from a plane. That is, the plane needs to be wrapped to the sphere, so to speak. The G vector needs to be spherified or brought to beer, or normalized, or whatever you want to call it.
Enter a few more vectors.
B(x,y,z)
This the the base vector that G has to be rotated to. For my custom normal maps, this would be B(0,0,1).
U(x,y,z)
This is the vector to rotate about. The way I see this problem in my head, this vector is the perpendicular between V and B.
- Get V and G and make sure B is set properly.
- Get U, which is the perpendicular between V and B.
- Get theta between B and V.
- Rotate G around U using theta (-theta).
That is where I'm at and how I'm trying to accomplish my task.
There is either something wrong with my thinking, or something stupid in the code. I keep running into a rotation problem in the final result.
I've been running this through my head for weeks now and I can't see what is wrong. I can rotate like a madman with a Hit-or-Miss Stick, but nothing proper.
If you want to go the extra mile and grab Filter Meister, I'll post some sample maps and the code that is driving me nuts.
I'm with you until "The next step is to add a bump map." I'm not 100% sure how you want to combine a bump map (which, as you explain, is basically a hemispherical normal map) with a fully spherical normal map. Can you explain that better?
I don't understand the purpose or meaning of your vector B, which you say is always (0,0,1).
Is the following what you're trying to do?
Take the starting normal V, and apply G to it "from its point of view." So, if V is (0,-1,0), and G is (0,1,0), the result is (0,0,1). In this case, G represented a 90 degree rotation upwards. If G is (0,0,1), it represents no rotation and the result remains unchanged from V. One way of thinking about this is to take a picture of G from straight above (positive Z direction), then move our camera to look straight down along V, superimpose the picture we took, and take the resulting vector.
If that's what you're trying to do, then it has the problem that you need to decide how to rotate the camera around V before superimposing the picture. If you decide that the camera's "up" should always point towards (0,0,1), then you'll get problems (seams) around places where V = (0,0,-1)*. Perhaps the best way to decide which direction the camera's "up" is depends on the way that the texture is mapped to the final 3D model at each given point. In fact, that may be what you want.
In any case, I suspect the easiest solution to this is going to boil down to matrix math and a rotation will be overkill.
* I believe your current solution, rotating G around towards V from (0,0,1), will have similar problems, because for different V's around (0,0,-1) the rotations are going to go around wildly different axes. Are the majority of your problems on parts of the model whose normals are around (0,0,-1)?
Actually, after thinking about your problem more, I'm pretty sure this is what you're trying to do (and I was touching on this in my previous post):
You have a nicely normal mapped 3D model. The normals are in 3D space, so you don't have to transform them to be tangent to the polygons: you just use the normals directly. Here's a bump map, which you've UV-mapped onto the model. If you view the bump map on the model, the white spots are places you want to pop "up" more than usual.
Every pixel on the bump map can be turned into a normal G, as you've described. This normal, if it were transformed into tangent space on the polygons, would be a good normal map. However, instead of just transforming it into tangent space on the polygons, you want to transform it into tangent space on the *original* normal map, thus combining the two normal maps.
The best way to do this is probably to (1) first transform it into tangent space on the polygons, and then (2) transform it from there into the direction of the original normal map.
(1) can be done only by using the UV coordinates of the polygon in question. You want to find which direction in 3D space on the polygon is "up" (0,1) on the texture, and which direction is "right" (1,0) on the texture. We'll work out the math for this if I'm correct about what you're going for. Once you have these "up" and "right" directions, and you have "out" as the triangle's normal, you can get the transformation of G into 3D space as G' = G.x * right + G.y * up + G.z * out.
(2) can be done, as you were doing, by a rotation from the triangle's normal towards the original normal map's value of V. Find U which is perpendicular to the triangle's normal and V, as well as the angle between them, and rotate G' around it by that angle.
This is basically the "camera" approach I described above, but by starting in the triangle's tangent space we avoid the "pole" problem at (0,0,-1) because we've moved the pole to the opposite of the triangle's normal, and V is never close to that.
Sounds very much like you understand what I'm trying to do.
I'm going to try a slightly different approach. Try to do it 'backwards', so to speak. If I don't give an update in a few days, my head probably exploded with frustration.