Skip to main content
gamedev.net
🔒 Locked

sphere mapping

Started by DXMan 14 replies 3.1k views
Original Post
DXMan
DXMan
I've been messing around with spherical environment mapping and I've run into two problems: 1) When applying spherical envmapping to a mostly flat object (such as water) using the Vertex Shader manually (an effect file *.fx), the "reflection" is badly distorted when the camera is facing 90deg forward LookAtPt(0.0f, 0.0f, 1.0f). Does anybody know how to get rid of this? 2) When applying spherical envmapping to a mostly flat object using DX7-style texture stage state changes, no "reflection" shows up on the object at all! Does anyone know how to fix this?
Zipster
Zipster
When you say "looking forward," do you mean looking straight at the flat surface, or at a 90° angle to the surface? It could be something you're forgetting in your shader effect? Did you take a look at the SphereMap examples provided with the SDK?

Also, what texture states and changes are you making?

[Edited by - Zipster on June 27, 2004 4:33:29 PM]
DXMan
DXMan
Yes, I have looked at the examples provided in the SDK. The "SphereMap" sample is what I based my shader on. It's kind of hard to explain what I mean by "looking forward". If the camera is facing toward Zpos (x and y positions don't seem to matter) the texture looks like a bunch of squiggly lines running in the same direction of the camera (Zpos). I don't know how to get rid of this distortion?!?

When using DX7-style state/stage changes, I use:

m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);

// Use camera-space normals
m_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);

// Use texture scale matrix to map normal coordinates to 0..1 range
m_pd3dDevice->SetTransform(D3DTRANSFORMSTATE_TEXTURE0, &m_matTexScale);


Do you know what I'm doing wrong??
Zipster
Zipster
That all appears to be correct. What is your texture transformation matrix? Did you remember to set your texture before rendering? The following code works for me in managed DirectX:
Matrix texScaleMat = Matrix.Identity;texScaleMat.M11 = 0.5f;texScaleMat.M22 = -0.5f;texScaleMat.M41 = 0.5f;texScaleMat.M42 = 0.5f;device.TextureState[0].ColorArgument0 = TextureArgument.TextureColor;device.TextureState[0].ColorOperation = TextureOperation.SelectArg1;device.TextureState[0].TextureCoordinateIndex = (int)TextureCoordinateIndex.CameraSpaceNormal;device.TextureState[0].TextureTransform = TextureTransform.Count2;device.SamplerState[0].AddressU = TextureAddress.Clamp;device.SamplerState[0].AddressV = TextureAddress.Clamp;device.SetTexture(0, sphereMapTexture);device.Transform.Texture0 = texScaleMat;// The standard teapot meshdevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, shinyTeapot.LocalMesh.NumberVertices, 0, shinyTeapot.LocalMesh.NumberFaces);

There's almost a direct correspondence to the unmanaged C++ counterparts - you'd use SetTextureStageState for most of it.

This isn't as good as the shader version however, since this only takes into the account the raw vertex normal when calculating texture coordinates, while the shader version (referring to the effect used in the SphereMap example) transforms each normal into view-projection space, which allows the texture filter to make it look more realistic on meshes with lower normal resolution (i.e less vertexes), as well as eliminate a lot of the fish-lens appearance that results. For example, if you were to render a cube using the texture stage state method, since all the normals per side are the same, each corner maps to an equal texture coordinate and you get a single mapped texel per side (i.e solid color), which is horrible. A view-projection transformation would mean each corner maps to a different, more appropriate coordinate that gives better results once filtered. The shader version also requires wrap texture addressing for the V coordinate - my best guess because texture-space V and world-space Y are inverted compared to each other, so you get denormalized texture coordinates (1..2 or -1..0), however someone more experienced can clarify that!

EDIT: Is it possible for you to get a screenshot of this artifact you describe? A picture is worth a thousand words after all :)
DXMan
DXMan
Thanks for your help so far!!

Yes, I've got screenshots of this. If you could give me a way to send them to you so you could look them over I would be happy to do so, Zipster!!
Zipster
Zipster
This is as good an address as any :)
DXMan
DXMan
I've e-mailed you the screenshots, Zipster.
Let me know if you get them.

Thanks again!!
Zipster
Zipster
I'll reproduce the screenshots here for everyone:
Correct


Incorrect


Some questions. What object is receiving the sphere map? Your skybox? Just what exactly are we looking at here :)

Second, what does your sphere map texture look like?
DXMan
DXMan
Thanks for your reply, Zipster!
To answer your first question, we are looking at a sample from my game engine that I have been hard at work on since Christmas 2003. There is a spaceship flying over a water "level" with several islands. I am using a sphere with reversed normals for the skybox and the water is the object being spheremapped. Notice in the "correct" screenshot that the water seems to "reflect" the skybox. In the incorrect image notice how the water looks like a bunch of distorted lines running parallel with the camera when it should look pretty much identical to the "correct" image. Also the camera in the "incorrect" screenshot is facing 90 degrees to the left of that in the "correct" screenshot.

I'll send you a copy of what my sphere map looks like to the same address that I sent the original screenshots to.

Thanks again for your help, Zipster!
Zipster
Zipster
Do you notice any gradual changes in the reflection as you rotate the ship from the "correct" orientation to the "incorrect" orientation? Or does it just snap to the distortion when you reach the "incorrect" orientation?

Also, how much of the ShaderMap example did you base your shader code off of?
DXMan
DXMan
When I rotate the ship from "correct" orientation to "incorrect" orientation there doesn't appear to be a gradual shift into distortion. It snaps into distortion. It almost appears like the distortion is in the map itself because you can see the distortion if you're not looking directly in the "incorrect" direction, as long as the "incorrect" orientation is in the viewspace. I'll send you a screenshot of this if you like.

Oh, and my shader is pretty much line for line the same as the example in the SDK. I guess you could say I "ripped it off". ;-)

Does this same problem occur when you do spherical envmapping on a semiflat surface??

Thanks for your support so far.
Zipster
Zipster
I've done some experiments with flat surfaces using the SphereMap example, and I can't replicated the distortion. It might have to do with your sphere map texture not "truly" being a sphere map :) Take a look at the one the example uses to see what I mean (in the SDK media folder).

If it happens when the orientation is in a view space, then depending on your field-of-view it could have something to do with a certain set of view vectors that it doesn't like. But I'm not sure about that.
DXMan
DXMan
Sorry for the long delay in response, I've been busy. :-)

You see, the wierd thing is, is when I use the spheremap from the SDK example the exact same thing happens!! Could you explain in more depth how the "view vectors" might cause this distortion?? Do you know of anything else that might cause this?? Could you maybe send me an example program (with source) that you've done that shows your flat surface sphere mapping?? Maybe its something I'm overlooking...

Thanks for your support so far.
Zipster
Zipster
All I did was take the SphereMap example, change the mesh from a teapot to a cube (for the flat faces), and recompile.

However, I did notice some distortion when viewing the cube from the opposite angle it was supposed to be viewed at. I'll get back on that one.
Zipster
Zipster
After doing some extended testing, I've come to the conclusion that what you're experiencing are natural consequences of using sphere mapping. Go here for a more in-depth discussion.

I recommend you switch to cube mapping instead.
DXMan
DXMan
Thanks for your help, Zipster.
I guess I'll have to use cube mapping... :-)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.