Sunday, July 12, 2009

texture sprites in second life

seasoned web hands will probably be familiar with the concept of CSS Sprites. the idea behind sprites is that with modern networks tuned for downloading large images, why not improve the performance of a web site by smashing all your visual elements in one image (JPG, GIF, PNG, whatever.) and then use the position features of CSS2 to display just a bit of that big image in a visual element. here's a visual to help grok it:

this image contains 12 distinct visual elements, arrows, circles, checkmarks, etc. (i nabbed these images from the wikimedia commons where they are released under a GPL license, more info at the gnome-look website.) note the box around one of the elements? that's there to remind you that you probably only want to display a portion of this image at any given time. the elements are stuffed into a single image for download to your browser to take advantage of the performance boost you may get by downloading single images instead of multiple individual images.

users of second life might have seen textures seem to not rez properly or rez half way and hang before completing download. there are several reasons why this might occur, some errors, others ramifications of the way progressive downloads on SL textures are handled. progressive downloads are intended to give users a context for the virtual world in as short a time as possible. in other words, it was thought that a world where all/most the textures are filled in but fuzzy and gradually got less fuzzy was better than a grey or transparent world where you had to wait forever to render the whole, non-fuzzy scene.

but this policy is problematic for some objects in the virtual world. objects like signs intended to display arbitrary text will sometimes rez the images representing different letters on a different schedule. this gives a weird appearance where some letters are clearly defined while others are fuzzy. for my money, this is a touch unsettling.

you can avoid this with the use of "texture sprites". SL builders are probably familiar with the fact that textures have a "repeats per face" and "offset" options. you can use these options to create the SL equivalent of CSS sprites. that is, you can apply a large image that contains multiple visual elements and use the repeats per face and offset parameters on a primitive face to only show the visual element you want to see. the benefits here are that all the visual elements will be in the same state of "rezzedness".

here's an example. i rezzed a cube with the dimensions <0.01,0.1,0.1> and applied the blank texture. i then put the following script in it:

// Copyright (c) 2009, Meadhbh Hamrick
// All rights reserved.
// 
// Redistribution and use in source and binary forms,
// with or without modification, are permitted provided
// that the following conditions are met:
// 
// * Redistributions of source code must retain the
//   above copyright notice, this list of conditions and
//   the following disclaimer.
// * Redistributions in binary form must reproduce the
//   above copyright notice, this list of conditions and
//   the following disclaimer in the documentation
//   and/or other materials provided with the
//   distribution.
// * Neither the name of the Project Meadhbh nor the
//   names of its contributors may be used to endorse
//   or promote productsderived from this software
//   without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY MEADHBH HAMRICK
// ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL MEADHBH HAMRICK BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

integer face;

stroke_face ( ) {
    vector offset;
    if ( 0 == face ) {
        offset = <0.0,0.333,0.0>;
    } else if ( 1 == face ) {
        offset = <0.0,0.111,0.0>;
    } else if ( 2 == face ) {
        offset = <0.0,-0.111,0.0>;
    } else {
        offset = <0.0,-.333,0.0>;
    }

    llSetPrimitiveParams( [ PRIM_TEXTURE, 2, "4b2b744a-7203-dcc7-3d8e-db8aa195f103", <1.0,0.111,0.0>, offset, 0  ] );
}

default
{
    state_entry()
    {
        face = 0;
        stroke_face();
    }

    touch_start(integer total_number)
    {
        face = face + 1;
        if( face > 3 ) { 
            face = 0;
        }
        stroke_face();
    }
}

people allergic to copy and paste can download the script from project meadhbh at sprite_test.lsl

the texture "4b2b744a-7203-dcc7-3d8e-db8aa195f103" was generated by combining several small images with the css sprite generator from project fondue. a copy of the png the texture was generated from is available at texturesprite.png. and in the interest of full disclosure, i should mention that the images from which this texture was generated were downloaded from the wikimedia commons site, were apparently made by John Erling Blad and released under a GNU Free Documentation License. Ergo, the PNG linked to above and the "4b2b744a-7203-dcc7-3d8e-db8aa195f103" texture should both be considered to be released under the same license.

1 comment:

Meadhbh Siobhan said...

aha! turns out someone else discovered this as well... http://bit.ly/q36rR