3D Dynamic Reflection in Windows Phone 7


Some classic ways of simulating Full Dynamic Reflection in Computer Graphics are Spherical Reflection (very low quality with lots of gaps but extremely fast), Dual Paraboloid Reflection Mapping (not so slow but not so beautiful) and Dynamic Cube Mapping (Slow but awesome quality).
In this post i will present a way to implement the Dynamic Cub Mapping Reflection in WP7 using only the built-in shaders provided by XNA.

The technic itself is very simple, we just need to set a cube map as a render target and render the scene in the point of the view of the camera. (this presented idea also works on PC and Xbox without change, but there are more clever ways to achieve the same results in these plataforms).
The only big problem is that XNA and Directx (xna runs in the top of it) uses different “hands” orientation.
DirectX uses a left-handed coordinate system and XNA uses a right-handed coordinate system with:

  • Forward is +Z, backward is -Z. Forward points towards the observer.
  • Right is +X, left is -X. Right points to the right-side of the screen.
  • Up is +Y, down is -Y. Up points to the top of the screen.

Microsoft hided all these differences behind the scenes (almost always we dont even know that it exists), but when rendering to cube map targets we need to be aware and more … we need to perform the conversion by hand …

To render the scene we also need to create a special camera as shown in the code below:

public void RenderSceneToTextureCube(RenderTargetCube renderTargetCube, Color backGroundColor, IWorld world, ref Vector3 objPos, GameTime gt,bool drawComponentsPreDraw = true,bool useCuller = false
            , List objListException = null, float nearPlane = 1, float farPlane = 1000
            )
        {
            Matrix proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver2, 1, nearPlane, farPlane);
            proj.M33 *= -1;
            proj.M34 *= -1;
            Matrix viewMatrix = new Matrix();
            // Render our cube map, once for each cube face( 6 times ).
            for (int i = 0; i < 6; i++)
            {
                // render the scene to all cubemap faces
                CubeMapFace cubeMapFace = (CubeMapFace)i;

                switch (cubeMapFace)
                {
                    case CubeMapFace.NegativeX:
                        {
                            viewMatrix = Matrix.CreateLookAt(objPos, objPos -  Vector3.Left, Vector3.Up);
                            break;
                        }
                    case CubeMapFace.NegativeY:
                        {
                            viewMatrix = Matrix.CreateLookAt(objPos, objPos - Vector3.Down,-Vector3.Forward);
                            break;
                        }
                    case CubeMapFace.NegativeZ:
                        {
                            viewMatrix = Matrix.CreateLookAt(objPos, objPos + Vector3.Backward, Vector3.Up);
                            break;
                        }
                    case CubeMapFace.PositiveX:
                        {
                            viewMatrix = Matrix.CreateLookAt(objPos, objPos - Vector3.Right, Vector3.Up);
                            break;
                        }
                    case CubeMapFace.PositiveY:
                        {
                            viewMatrix = Matrix.CreateLookAt(objPos, objPos - Vector3.Up, -Vector3.Backward);
                            break;
                        }
                    case CubeMapFace.PositiveZ:
                        {
                            viewMatrix = Matrix.CreateLookAt(objPos, objPos + Vector3.Forward, Vector3.Up);
                            break;
                        }
                }                
                
                // Set the cubemap render target, using the selected face
                SetCubeRenderTarget(renderTargetCube, cubeMapFace);
                Clear(backGroundColor);
                RenderSceneWithBasicMaterial(world, gt, objListException, ref viewMatrix, ref proj, drawComponentsPreDraw, useCuller);
                RestorePreviousRenderTarget();                
            }
                        
        }

The function RenderSceneWithBasicMaterial() just render all the scene objects with the most basic built-in shader. (other variables names are easily understandable, adjust it to your application) (there are some dumb Vector operations like -Vector3.Backward, fix it =P )

With the cube render target created and populated, we just need to pass it to the built in Environment Shader.
I wont put the code here cause it is straightforward.

Remember that you need to call this function (RenderSceneToTextureCube()) in all the frames and it is pretty slow, so be carefull !
Some things to speedup the process are:

  • Create a small Cube Render Target. (Cubemap render target creation code not shown)
  • Render objects in low resolution without effects
  • Do not render everything in all the frames (do magics like rendering only one face of the cubemap each frame ... )

The end result is very cool, but the price paid to render it is huge.
Obs: this obvious works on PC and Xbox also =P

  1. #1 by warisan on 24 de março de 2017 - 7:45 pm

    I need complete and detailed requirements, policies and procedures, anyone help me please? = ).

  2. #2 by http://www.yosemitesoap.com/how-to-find-cheap-car-insurance-for-17-year-old-boy.html on 24 de março de 2017 - 7:58 pm

    I hate my life but at least this makes it bearable.

  3. #3 by chronic pain pain on 24 de março de 2017 - 8:06 pm

    You ave made some decent points there. I looked on the web to find out more about the issue and found most people will go along with your views on this website.

  4. #4 by hoverboard for sale on 24 de março de 2017 - 8:11 pm

    878207 44656replica watches are amazing reproduction of original authentic swiss luxury time pieces. 940573

  5. #5 by http://www.wrighthousecalls.com/national-casualty-insurance-company-claims-phone-number.html on 24 de março de 2017 - 8:24 pm

    As Zebbo up in the Ozarks opined….”if the idea that homosexuals, lesbians like poets, are born—not made- then they must be the “offsprings” of homosexuals and/or lesbians.”Zebbo has been known to adjucate matters between sexual partners who disagree as to which one of them plays the “male” part and which one plays the “female” part during their sexual encounters.A wise man that Zebbo!.

  6. #6 by http://www.whatsyouroldbrooklyn.com/car-rental-insurance-coverage-tips.html on 24 de março de 2017 - 8:30 pm

    That book Emotional Vampires is such a good look at different personalities. It really made me see how these people were behaving whether it was on a subconscious level or not.In the end, we need to learn how to avoid emotionally draining people.

  7. #7 by http://www.studioy.us/online-taxi-insurance-quotes.html on 24 de março de 2017 - 8:38 pm

    Economies are in dire straits, but I can count on this!

  8. #8 by http://www.yosemitesoap.com/progressive-insurance-iselin-nj.html on 24 de março de 2017 - 9:06 pm

    What you do, you do well. The MSM don’t mention riots in Denmark in the UK, or anything else about Denmark for that matter. The only thing we can know about Denmark is “country of origin” on packs of bacon, and Lurpak Danish butter.Your first hand contributors from elsewhere give us an insight we would not get otherwise.

1 493 494 495
(não será publicado)