Fastest settings for Sprites (2D and UI) - c#

what are the fastest settings here:
https://docs.unity3d.com/Manual/TextureTypes.html#Sprite for Sprites (2D and UI)?
With fastest I mean, what are the settings that cost less power for cpu / gpu / ram / whatever.
the sprites i have are 32x32, if that is important.

TL;DR - Most these settings have little to no impact on performance more on quality or content/layout. Your performance is going to come more from how you structure your project.
Texture Type - In this case it is fixed to Sprite (2D and UI)
Texture Shape - Obviously locked to 2D.
Sprite Mode - This depends on whether or not you're using a sprite map. Meaning keeping multiple sprites (or components of a sprite) together in one image. You'd either have this set to on or off based on what the image contains for content. It depends on exactly what you're trying to do here, but sprite maps can be used efficiently for animation if needed. They can be used to break down components of a sprite such as eyes, arms, legs and etc. then an overlay can be used to animate the sprite. It can also be used as a way of storing multiple sprites in one image, though I don't think you're after this.
Packing Tag - Can be used with sprites to identify the sprite's packing/batch group. Sprite packing is something you want to investigate.
Unity - Sprite Packer
Pixels Per Unit - Is kind of the only other place in which you may care about as it affects the physics engine. This setting again depends on your project, but in your case leaving the default setting is probably best, but 32 would probably be fine. I don't think it will have much of an impact.
Mesh Type - Due to the fact the image is 32x32 you're forcing the full rect option here.
Extrude Edges - Has little to no bearing on performance.
Pivot - Has little to no bearing on performance. Unless there are certain algorithms in your scripts that must be run where a particular coordinate system/layout matter. Highly, unlikely to have an impact on performance, more of an impact on your algorithms layout.
sRGB - Can affect how the shader will handle the image, but again due to image content your pretty much forced to choose one or the other.
Alpha Source - Leave this set to "None" unless it is needed.
Alpha Is Transparency - Shouldn't matter due to the Alpha Source
Generate Mip Maps - This shouldn't matter due to the resolution of your images, but if you were to have larger images you'd want to enable this. The images would take more storage space. However, the quality would be a necessity more than likely when the large images become tiny. Mip Maps provide varying sizes of your image. They would help increase rendering performance by allowing the engine to use the appropriately sized image for the task, thereby reducing stress on the GPU and CPU. Typically, they're used for Level of Detail (LOD).
Wikipedia - Mipmap
Filter Mode - Are you doing transformations? Point is the most efficient I believe here.
Ansio Level - Forced to 1 for sprites
Max Size - Has little to no impact on performance, but will have an impact on storage size. Set this to the largest size that the image can be.
Compression - Compression can help or hinder performance based on platform. "Low Quality Compression has an effect on mobile platforms, but not on desktop platforms)." Unity - Textures
Performance Tips
Use smaller sprites
While this article is for 3D it may have some snippets that help you out.
Unity - (3D) Optimizing graphics rendering in Unity games
Only draw what you need to draw when you need to draw it.
Disable game components that don't need to be enabled.
Keep UI components to a minimum if using the default Unity UI.
Debug your game and see how many draw cycles are being done.
Batch your draws where possible. Look into sprite packing.
Performance is going to be very specific to your specific project.

Related

Pix-elated Drawing and 3D representations

I am writing a program to imitate Natural Physics. I want to know whether there is a better way to draw an object other than overriding the OnDraw method, and FillRectangle(x,y,1,1) for each pixel.
Is there a way to do a similar action using DirectX or OpenGL? Because to my knowledge the Graphics does not utilize the video card of ones computer (please correct me if I am wrong).
Saying this I would like some thoughts in relation to creating a 3D environment using mathematical calculations to work out the relative quadrant sizes so that objects appear to be farther away then in reality (as a monitor is only 2D), or closer.
Yes. Drawing pixel by pixel with FillRectangle will be very inefficient and slow things down a huge amount. As you say, you should use a graphics rendering system such as DirectX or OpenGL. The choice of which is up to you. If you do a simple search on the web you will find many tutorials on how to get started with 3d graphics.
OpenGL focuses on "Draw me this object in space", and it will take care of rendering it, taking advantage of your graphics card if possible. You do not worry about the pixels, you specify dimensions, camera angles, shaders etc.
You can draw pixels with OpenGL, but that is not the 'correct' way to draw 3d graphics with it.
EDIT in response to Vasa's questions:
I believe OpenGL does what's best based on your graphics card capabilities and drivers. In general OpenGL isn't going to be your best option for drawing direct pixels. BUT remember that
Pixels are different sizes on different machines. Are you expecting to just live with this? Or live with a big display on low-res screens and a tiny one on high-res screens? There may be multiplications involved. If you use literal pixels then once you start multiplying for different screens you are going to get artefacts and inaccuracies.
You want a direct mapping of X to pixels. OpenGL uses float values. They aren't integer 1 to 1 mappings, but they do use a direct proportion. If you choose a scale then OpenGL is not going to suddenly start distorting ratios.
The important thing is proportions not absolute pixels. Although I accept that it's possible for your case to be different.
See this for 2d drawing:
http://basic4gl.wikispaces.com/2D+Drawing+in+OpenGL

Scalable video game graphics

I'm looking to make a relatively simple game using solely graphics primitives (Arcs, Lines, Polygons, etc.).
I started doing this in C# by drawing to a Panel, but right now I'm hung up on how all the scaling works in terms of keeping the proportions the same when changing resolutions. Does anyone have any advice and / or tips on how to do something like this?
There are two options:
1 - Scale everything so that it is sized at a certain percentage of the screen/window. For example, if you want your object to be 1/4 of the screen, then it's width is ScreenWidth/4 and height is ScreenHeight/4. The problem with this technique is that a screen's aspect ratio may make things short and fat or tall and wide. Usually this is addressed by determining one dimension and then using the screen's aspect ratio to determine the other dimension. Ie, Width=Height*AspectRatio.
2 - Make everything the same physical dimension. For example, you may want an object to appear exactly 1" by 1". You can use the screen's resolution (dots per inch) to scale your drawings accordingly. The problem with this is that while it may work well for 'average' sized screens, images may be too small on large screens or too large on small screens.
Most games use technique #1 (with compensation made for the aspect ratio). AR was not always a big deal, but now with widescreen monitors being so popular, it's almost required.
Also, like Richard said, WinForms is not great for games (except minesweeper!), but probably okay for teaching yourself.
Not really a helpful answer but, don't use WinForms!!
If you want a good gaming platform, use DirectX, or XNA Game Studio.
You can do this using GDI+, and transforms. For details on using Matrix to do transforms, see this article on CodeProject.
That being said, this is much, much simpler using WPF's drawing options. In addition to being a retained mode model, which is much simpler when doing simple graphics (ie: move an object instead of constantly redrawing), it has some other nice benefits. The main benefit is that everything in WPF is done using floating point values, and is completely scalable, with no extra real effort. For details on this, see Shapes and Basic Drawing with WPF, which includes both drawing and transforming of shapes.

Drawing 2D Sprite (Bitmap) TIles Efficiently

I'm writing a 2d tile-based engine. Currently, my drawing routine uses the C# Drawing library to redraw every visible tile every time the screen refreshes. I got scrolling and zooming to work, and everything looks the way I want it to. But the routine is slow. Now I'm trying to improve it. I've a couple of questions:
First, I think redrawing the tiles at every refresh is unnecessary (since they never change). Right now I'm trying to change the algorithm so that it writes the whole map to a single bitmap at initialization, and then cuts the correct portion of the bitmap when it's time to draw. Do you think this is the right way to go?
(I also considered leaving the image in the background and just scrolling over it. But then I decided that I don't want to draw stuff that's outside of the field-of-view. However, perhaps that is cheaper than cutting/pasting? A memory vs time issue?)
Second, as far as I understand the C# Drawing routines do not use the full power of the GPU. I think I should try to do the drawing in OpenGL (or DirectX, but I prefer the former, since it is multiplatform). Will that help? Do you know any tiling (or general pixel-drawing) tutorial for OpenGL? A book reference could also help.
I also don't do multi-threading at the moment (in fact I only have a vague idea of what that is). Should I try to multi-thread the drawer? Or would OpenGL make multi-threading for graphics redundant?
Thanks.
What application framework are you planning to use? Techniques for efficient drawing are very different between WinForms (Win32) and WPF.
You are correct that .NET drawing routines do not take full advantage of the GPU. Using DirectX or OpenGL, one immediate optimization would be to preload all of your image tiles (or at least, all of the tiles you need for the immediate view area plus a little more) into GPU memory using image lists or display lists. You would then draw the tiles on a surface by index - draw tile N at x,y. This is usually much faster than drawing on a GPU surface using bitmaps stored in main system memory, since the bitmap pixels have to be copied to the GPU for each tile drawn and that uses up a lot of time. Drawing by index also uses a lot less GPU memory whenever you can use the same image tile in multiple places in the output.
OpenGL vs DirectX is your choice, but IMO DirectX has been evolving at a faster rate providing more hardware accelerated functions than OpenGL. OpenGL drivers on Windows also have a reputation for being neglected by hardware vendors. Their primary focus is on their DirectX drivers.
Give some thought to whether you really need OpenGL or DirectX for your 2D tile application. Requiring OpenGL or DirectX will reduce the number of machines, particularly older machines, that can run your app. OpenGL and DirectX may be overkill. You can do a lot with plain old GDI if you're smart about it.
Stay away from multithreading until you have a really good reason to go there and you have some experience with threading. Multithreading offers the reward of some performance boosts for some computing situations, but also brings with it new headaches and new performance problems. Make sure the benefit is significant before you sign up for all these new headaches.
In general, moving pixels around on the screen is usually not a good match for multithreading. You've got only one display device (in most cases) so hitting it with multiple threads trying to change pixels at the same time doesn't work well. To borrow an expression from project management: If a woman can create a baby in 9 months, can you use 9 women to create 1 baby in 1 month? ;>
Work on identifying parts of your system that do not need to access the same resources or devices. Those are better candidates for running in parallel threads than blitting tiles to the screen.
The best optimization is to discover work that does not need to be done - reducing the number of times tiles are redrawn for example, or changing to an indexed model so the tiles can be drawn from GPU memory instead of system memory.
If you want to use OpenGL your best bet for 2d would be SDL.
Using OpenGL with C# will never be that portable simply due to the fact it would use .NET wrappers.
XNA is a great tool for writing games in C#, it should provide a lot more speed and flexibility then SDL does (especially the .net port) plus more features (however more bulk).
For your cutting or scrolling question, the best route would be scrolling.
Memory is much less of an issue than CPU when you're drawing using GDI+ (what System.Drawing uses). You could always split the map up into sections and scroll those then load when necessary if it's that big.
I'm not familiar with OpenGL, but I've written a tile based engine in ManagedDX (later ported to XNA). ManagedDX is depricated, but there's the SlimDX project which is still under active development.
With DX, you can load each individual tile into a Texture. (Using Texture.FromFile() or Texture.FromStream() for example), and have a single Sprite instance draw them. This performs pretty well. I group the textures in a simple class with a Point or Vector2 for their locations, set them only when the location changes rather than every time the draw method is called. I cache tiles in memory only for the immediate screen and one or two tiles beyond, there's no need for more than that as the file IO is quick enough to fetch new tiles as it's scrolled.
struct Tile
{
public Point Location;
public Texture Texture;
}
Device device;
Sprite sprite;
List<Tile> tiles = new List<Tile>();
.ctor() {
this.device = new Device(...)
this.sprite = new Sprite(this.device);
}
void Draw() {
this.device.Clear(ClearFlags.Target, Color.CornflowerBlue, 1.0f, 0);
this.device.BeginScene();
this.sprite.Begin(SpriteFlags.AlphaBlend);
foreach (Tile tile in this.tiles) {
this.sprite.Draw2D(tile.Texture,
new Point(0, 0), 0.0f, tile.Location, Color.White);
}
this.sprite.End();
this.device.EndScene();
this.device.Present();
}

Whats the most efficient method for transitioning between two images (Like Mac wallpaper change)

I'm working on a wallpaper application. Wallpapers are changed every few minutes as specified by the user.
The feature I want is to fade in a new image while fading out the old image. Anyone who has a mac may see the behavior I want if they change their wallpaper every X minutes.
My current thoughts on how I would approach this is to take both images and lay one over the other and vary the opacity. Start the old image at 90% and the new image at 10%. I would then decrease the old image by 10% until it is 0%, while increasing the new image by 10% until 90%. I would then set the wallpaper to the new image.
To make it look like a smooth transition I would create the transition wallpapers before starting the process instead of doing it in real-time.
My question is, is there a more effective way to do this?
I can think of some optimizations such as saving the transition images with a lower quality.
Any ideas on approaches that would make this more efficient than I described?
Sounds like an issue of trade-off.
It depends on the emphasis:
Speed of rendering
Use of resources
Speed of rendering is going to be an issue of how long the process of the blending images is going to take to render to a screen-drawable image. If the blending process takes too long (as transparency effects may take a long time compared to regular opaque drawing operations) then pre-rendering the transition may be a good approach.
Of course, pre-rendering means that there will be multiple images either in memory or disk storage which will have to be held onto. This will mean that more resources will be required for temporary storage of the transition effect. If resources are scarce, then doing the transition on-the-fly may be more desirable. Additionally, if the images are on the disk, there is going to be a performance hit due to the slower I/O speed of data outside of the main memory.
On the issue of "saving the transition images with a lower quality" -- what do you mean by "lower quality"? Do you mean compressing the image? Or, do you mean having smaller image? I can see some pros and cons for each method.
Compress the image
Pros: Per image, the amount of memory consumed will be lower. This would require less disk space, or space on the memory.
Cons: Decompression of the image is going to take processing. The decompressed image is going to take additional space in the memory before being drawn to the screen. If lossy compression like JPEG is used, compression artifacts may be visible.
Use a smaller image
Pros: Again, per image, the amount of memory used will be lower.
Cons: The process of stretching the image to the screen size will take some processing power. Again, additional memory will be needed to produce the stretched image.
Finally, there's one point to consider -- Is rendering the transition in real-time really not going to be fast enough?
It may actually turn out that rendering doesn't take too long, and this may all turn out to be premature optimization.
It might be worth a shot to make a prototype without any optimizations, and see if it would really be necessary to pre-render the transition. Profile each step of the process to see what is taking time.
If the performance of on-the-fly rendering is unsatisfactory, weigh the positives and negatives of each approach of pre-rendering, and pick the one that seems to work best.
Pre-rendering each blended frame of the transition will take up a lot of disk space (and potentially bandwidth). It would be better to simply load the two images and use the graphics card to do the blending in real time. If you have to use something like openGL directly, you will probably be able to just create two rectangles, set the images as the textures, and vary the alpha values. Most systems have simpler 2d apis that would let you do this very easily. (eg. CoreAnimation on OS X, which will automatically vary the transparency over time and make full use of hardware acceleration.)
On the fly rendering should be quick enough if handled by the graphics card, especially if it's the same texture with a different opacity (a lot of graphics rendering time is often loading textures to the card, ever wondered what game loading screens were actually doing?)

Moving from Wiimote to camera?

I've been doing some Johnny Chung Lee-style Wiimote programming, and am running into problems with the Wiimote's relatively narrow field-of-view and limit of four points. I've bought a Creative Live! camera with an 85-degree field of view and a high resolution.
My prototype application is written in C#, and I'd like to stay there.
So, my question: I'd like to find a C#.Net camera / vision library that lets me track points - probably LEDs - in the camera's field of view. In the future, I'd like to move to R/G/B point tracking so as to allow more points to be tracked and distinguished more easily. Any suggestions?
You could check out the Emgu.CV library which is a .NET (C#) wrapper for OpenCV. OpenCV is considered by many, including myself, to be the best (free) computer vision library.
Check out AForge.Net.. It seems to be a powerful library.
With a normal camera, the task of identifying and tracking leds is quite more challanging, because of all the other objects which are visibile.
I suggest that you try to maximize the contrast by reducing the exposure (thus turning of auto-exposure), if that's possible in the driver: you should aim for a value where your leds have still an high intensity in the image (>200) while not being overexposed (<255). You should then be able to threshold your image correctly and get higher quality results.
If the image is still too cluttered to be analyzed easily and efficiently, you may use infrared leds, remove the IR-block filter on the camera (if your camera has it), and maybe add an "Infrared Pass / Visible Light blocking" filter: you should then have bright spots only where the leds are, but you will not bee able to use color. There may be issues with the image quality though.
When tracking things like lights, especially if they are a special color, I recommend you apply a blur filter to the footage first. This blends out colors nicely, a while less accurate, will use less CPU and there's less threshold adjustments you have to do.

Categories