Dynamic 2D Shadows Optimization

Started by
3 comments, last by -XM- 11 years, 1 month ago

Hi guys, I've implemented this shadow sample into my engine: http://www.catalinzima.com/2013/01/dynamic-2d-shadows-for-windows-phone-7/ Everything was working fine until I ran my game on the Xbox 360.... I get 30 FPS when my game runs at 1920 x 1080, but if I run it at 1280 x 720 or below it runs at 60 FPS. If you run the stand alone sample the same thing happens.

I don't know exactly why the resolution makes a difference, but I did some further profiling and found that this call gets called for every hull:

game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleStrip, shadowVertices, 0, shadowVertexCount * 2 - 2);

When I draw just one hull my FPS goes back up to 60, so for the last week or so I've been trying to add all of the verts and indices to a list and then make this call one time after iterating through the hulls. The problem is that after doing this the shadows are drawing really whacky... I'm not sure where I'm going wrong, this should be a simple fix but it seems I'm overlooking something small that is screwing me up.

Any help would be appreciated! I attached the modified sample to this post.

My changes are in ConvexHull's DrawShadows:


            int currentIndex = startingIndex;
            int svCount = 0;
            while (svCount != shadowVertexCount * 2)
            {
                shadowHullIndices.Add(currentIndex + shadowHullVertices.Count); //Added this
                Vector3 vertexPos = vertices[currentIndex].Position + new Vector3(position, 0);

                //one vertex on the hull
                shadowVertices[svCount] = new VertexPositionColor();
                shadowVertices[svCount].Color = Color.Transparent;
                shadowVertices[svCount].Position = vertexPos;

                //one extruded by the light direction
                shadowVertices[svCount + 1] = new VertexPositionColor();
                shadowVertices[svCount + 1].Color = Color.Transparent;
                Vector3 L2P = vertexPos - new Vector3(lightSource.Position, 0);
                L2P.Normalize();
                shadowVertices[svCount + 1].Position = new Vector3(lightSource.Position, 0) + L2P * 9000;

                svCount += 2;
                currentIndex = (currentIndex + 1) % primitiveCount;
            }


            drawingEffect.World = Matrix.Identity;
            drawingEffect.CurrentTechnique.Passes[0].Apply();

            for (int i = 0; i < shadowVertexCount * 2 - 2; i++) //Added this
                shadowHullVertices.Add(shadowVertices[i]);
//Original call:
//game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleStrip, shadowVertices, 0, shadowVertexCount * 2 - 2); 

and in Game1's DrawLightmap:


                foreach (ConvexHull ch in objects)
                {
                    //draw shadow
                    ch.DrawShadows(light, shadowHullVertices, shadowHullIndices); //Added. For now, pass the lists in and add the appropriate verts and indices.
                }

                //Added this:
                GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(PrimitiveType.TriangleList, shadowHullVertices.ToArray(), 0, shadowHullVertices.Count, shadowHullIndices.ToArray(), 0, shadowHullIndices.Count / 3);



Advertisement

So it's hard to tell from the code provided, but generally speaking if your frame rate goes down when you increase resolution, you're most likely fill-rate bound. Try cutting stuff out of your pixel shader and see if you can get a better framerate. It's just a guess though.

Good luck!

Perception is when one imagination clashes with another

Coalescing all your draw calls into one can help save you CPU time. If that's your bottle neck, that can increase your framerate. (Rouhgly how many "hulls" do you have?).

Like the other poster said though, you may be fill-rate bound (or possibly texture fetch bound). So you need to reduce your resolution, or find some way to draw less (or speed up your pixel shader)..

1920 x 1080 can be a lot for the Xbox. I don't think any AAA title runs at that resolution - they're usually 720p or less.

Also the jump from 30 FPS to 60 FPS is because you have vsync on. The difference might actually be very small (like 59 FPS to 61 FPS). If you're doing perf measurements, you should set IsFixedTimeStep to false, and SynchronizeWithVerticalRetrace on the GraphicsDeviceManager to false (in your game's constructor).

Also as a side post. The hardware scaler for the Xbox from 720p to 1080p is nearly identical to actual 1080p. Most people can't tell the difference.

Perception is when one imagination clashes with another

The max number of hulls I ever draw is about 15.... but I think you guys are right, I just needed to lower my resolution. I didn't understand that most AAA games cheat the 1080p on consoles... I did some research and the only example I saw of a game truly running at 1920 x 1080 was Virtua Tennis 3 (not sure if that's really true). I guess I shouldn't assume so much from the back of the boxes...

Thanks for sending me in the right direction guys!

This topic is closed to new replies.

Advertisement