You are currently browsing the tag archive for the ‘texture’ tag.

As with all my script posts, I am assuming here that you already know the basics of how to create and edit prims and scripts.

I’ve already covered the rotation option for animating textures, in my post about creating a simple rippling water texture. In this post, however, I want to look at the other animation options, and give some examples. The only one I’m not going to cover is the scaling option, which works in a similar way to the rotation option, but which I have never found a real use for.

Let’s start with what most people think of in terms of texture animations, which is where the animation displays a series of ‘frames’. As a simple example, here is an alternative way of creating a rippling water effect, this time using an animation. To see this in action, rez a cube, and create a new script for it. Replace the contents of the script with the following:

default
{
 state_entry()
 {
  llSetTexture("349b2fec-0f7e-bd5f-5bcc-7090d27ae0fb", ALL_SIDES);
  llSetTextureAnim(ANIM_ON | LOOP, ALL_SIDES, 3, 3, 1, 9, 12.0);
 }
}

As with all the examples in this post, I am taking the textures from the asset server using their UUID, so they should be available to anyone. Of course, you don’t have to do it this way – you can apply animated textures to the prim in the normal way if you want (in which case you can remove the llSetTexture call in the above example).

The texture in this example is 128 x 128, and has the frames laid out in a 3 x 3 grid (the texture was created using the Gimp drawing package). It is actually rather smaller than is necessary, and hence not very high quality. A 256 x 256 version of the texture would be better quality, and would still load reasonably quickly.

Let’s look at each of the parameters of the llSetTextureAnim function.

The first parameter is a set of flags which are combined together using an OR (the ‘|’ symbol). In my example, only two options are included: ANIM_ON, which switches the animation on (no surprise there!) and the LOOP option, which tells the animation to return to the beginning and start again once it has reached the last frame. The alternative to LOOP is PING-PONG, which still keeps the animation running continuously, but when it reaches the last frame it then plays the frames in reverse until it gets back to the first frame, and so on.

If you don’t specify one or other of LOOP or PING-PONG the animation will play through just once and then stop (it will redisplay the first frame, though). We’ll see a possible use for this later.

The other possible flags for this parameter are SCALE, ROTATE, REVERSE, and SMOOTH. As I said above, I won’t be going in to SCALE and ROTATE in this post. REVERSE simply plays the animation backwards. I’ll come back to the SMOOTH option later.

The next two parameters tell the function how the frames are laid out in the texture. In my example, they are laid out in a 3 x 3 grid, so we set both values to 3. A common alternative would be to have the frames laid out horizontally in a long strip. If this sample texture had been done that way we would have had a strip 9 frames long, so these parameters would be 1, 9.

The next two parameters tell the function which frames to display, from the first frame to the last frame. You can use this if you only want to display part of the animation (possibly you might want to display different parts at different times). In this case we want to use all the frames.

The last parameter is the speed of the animation — the higher the number, the faster the animation. It is approximately (very approximately!) in frames per second, and values between 5 and 15 are usually appropriate, though of course this depends on your animation.

Now, what about that SMOOTH option? Well, this works in a rather different way. Instead of displaying individual frame, the SMOOTH option basically scrolls the entire texture sideways. Because of this, it is possible to use this to scroll a texture which isn’t animated (in other words, a texture which isn’t actually a series of frames).

As an example, let’s create a slowly drifting starfield. Rez a cube, and size it so that it is about 4 m wide and 2 m tall. Create a new script in it, and replace the script contents with the following:

default
{
 state_entry()
 {
  llSetTexture("43019701-cf5c-d484-3b35-3fb59fe895b4", ALL_SIDES);
  llSetTextureAnim(ANIM_ON | LOOP | SMOOTH, ALL_SIDES, 1, 2, 1, 1, 0.02);
 }
}

Notice that although the texture is not animated, we have specified a Y frame count of 2. This might seem rather odd, and needs some explanation. As soon as you apply llSetTextureAnim, the script will override whatever X and Y repeat values that you have specified, and instead will size the texture to match the X and Y frame count that you have specified, stretching it as necessary.

In order to make the texture fill the X direction without stretching, the Y frame-count has been specified as 2, making the script treat the texture as a two-frame animation. Because the start and end frames are both 1, it only displays one frame, which in this case works out as the top half of the texture, with the result that the texture is scaled correctly for us. This is not really an efficient way of doing things! Really, an animated texture needs to have the same X:Y ratio as the prim face that you are going to use it on.

Next, something more useful. Let’s see how to use texture animation with Second Life’s waterfall textures, and create a simple waterfall.

Start by rezzing a cube, and size it so that it is 2 m wide, 4 m tall, and 0.2 m deep. On the Texture tab, set the rotation to 90.0. This is because animations which use SMOOTH, as we are going to do, always slide along the X axis, so we need to rotate the texture to make our water flow vertically.

Create a new script in it, and replace the script contents with the following:

default
{
 state_entry()
 {
  llSetTexture("af8c86bd-c377-c331-7476-58abeb7af8fc", ALL_SIDES);
  llSetTextureAnim(ANIM_ON | LOOP | SMOOTH, ALL_SIDES, 1, 2, 1, 1, 0.5);
 }
}

By itself, this should look reasonably effective. We can make it better, though. Take a copy of this prim, shifting it so that it is a little bit in front of the original prim. Edit the script in this copy, and replace it with the following:

default
{
 state_entry()
 {
  llSetTexture("49649c94-f720-6d0f-2246-49cc1835284f", ALL_SIDES);
  llSetTextureAnim(ANIM_ON | LOOP | SMOOTH, ALL_SIDES, 1, 2, 1, 1, 0.25);
 }
}

This now gives us two waterfall animations, running at different speeds. The result is very effective.

Near the start of this post I mentioned that if you had neither LOOP nor PING-PONG in the animation flags the animation would run through just once. Here is an example of this. It is a ‘LOCKED’ sign which flashes once when somebody touches it.

Rez a new cube, and size it to be 1 m wide, 0.5 m tall, and 0.5 m deep. Create a new script in it, and replace the script contents with the following:

default
{
 state_entry()
 {
  llSetTexture("7392be5b-ce2f-eb64-6a45-a4544ec539a9", ALL_SIDES);
  llSetTextureAnim(ANIM_ON, ALL_SIDES, 1, 2, 1, 2, 5.0);
 }
 touch_start(integer total_number)
 {
  // Curiously, we have to switch the animation off first.
  llSetTextureAnim(0, ALL_SIDES, 1, 2, 1, 2, 0.0);
  // Now run the animation once.
  llSetTextureAnim(ANIM_ON, ALL_SIDES, 1, 2, 1, 2, 5.0);
 }
}

Finally, some useful (I hope!) notes:

Finding the prim face: You’ll notice that in the above scripts I have specified ALL_SIDES as the side to apply the texture and animation. A lot of the time you will want to put the texture and animation on one side only. The easiest way to find out the side number of a prim face is to use the Advanced (or Debug) menu.

To active or deactivate the menu, hold down CTRL+ALT+d on your keyboard. The Advanced menu should appear on the main Second Life menu.

Once this menu is showing, edit the prim you want to investigate. Click the ‘Select Texture’ option, and select the face you want to check. Then hold down CTRL+SHIFT+ALT+t on your keyboard. Details of the texture will appear in the bottom-left of your screen, including the face number.

Switching off animations: If you want to switch off the animation on a texture, simply pass zero as the flag. The other parameters are irrelevant:

llSetTextureAnim(0, ALL_SIDES, 1, 1, 1, 1, 0.0);

Texture Size: remember that a texture with multiple frames can easily be very large indeed, and Second Life still has to load the entire texture (no, it doesn’t load it frame by frame!). Creating an effective animation using a minimum number of frames is a skill in its own right.

The LSL Wiki has additional useful information: http://www.lslwiki.net/lslwiki/wakka.php?wakka=llSetTextureAnim

This is a simple but effective way to create a ‘draped cloth’ effect that can be used as the base texture of (for example) capes or curtains. I’m afraid that this one is specific to the Gimp graphics program, although possibly other programs will have similar features.

Start with an empty picture, at a large size such as 512 x 512, or even 1024 x 1024. I do this with all my textures. Starting large and scaling down usually works well, and sometimes actually improves things by removing or hiding small glitches, whereas it is well-nigh impossible to get good results by starting small and scaling up.

Find the Solid Noise option, under the Filters/Render/Clouds menu.

Set the options so that the X size is set to the maximum, or somewhere near it, and the Y size is set to the minimum, 0.0. You can try experimenting with different values, but you need to be aware that setting the Y size to anything other than the minimum can make it more difficult to create a seamless texture.

You should already see the drape effect.

If you want to increase or decrease the ‘depth’ of the effect, use the Brightness and Contrast — lowering the Contrast will make the effect shallower, increasing the depth (especially in conjunction with decreasing the Brightness) will make the effect deeper.

I would now colorise the texture. Select the Colorise option. Adjust the Hue slider to get the colour you want. Play with the other two sliders to tweak the result.

At this point, the drape will tile horizontally, but probably not vertically. There is a fairly easy way to fix this.

Start by selecting the top half of the image (you don’t have to be exact, but make sure that the top edge is at 0). Feather this fairly drastically, possibly to something like 50 pixels, then copy it. Paste it back in, flip it vertically, then move it down to the bottom, being careful not to move it horizontally.

If you find that the texture does not tile horizontally, you can apply a similar technique to the left and right sides of the texture.

The end result should be tileable. This technique of copying and pasting the top/bottom (and equally the left/right) halves of an image can often be used to make an image tileable if it has right/left or top/bottom symmetry.

Here is an example of the final result:

Drape texture

Sometimes it is useful to be able to change or apply textures through a script. Imagine, for example, a button or switch where you want to change the appearance when the user clicks on it.

There are a number of functions in the LSL library for dealing with textures. In this post I will cover the most basic of them. I’ll go into more details in subsequent posts.

Applying a Texture

Applying a texture to a prim is probably the simplest thing that can be done when scripting textures. You can use the llSetTexture function to do this, which simply needs the texture, and the side to apply the texture to. I’ll discuss prim sides a bit later, but for the example I’ll use the ALL_SIDES constant, which will apply the texture to all sides of the prim.

There are two different ways of specifying the texture. You can either use the name of the texture, or you can use the asset UUID of the texture.

To use the name, the texture must be included in the prim’s contents (just drag the texture from your inventory into the contents list of the prim).

Assume we have a texture called “test”. This script will apply the texture to all sides of the prim when the prim is touched:

default
{
    touch_start(int number)
    {
        llSetTexture("test", ALL_SIDES);
    }
}

Alternatively, we can specify the asset UUID. To find the UUID, right-click on the texture in your inventory, and select the Copy Asset UUID option. You can then paste the result into the script, like so:

default
{
    touch_start(int number)
    {
        llSetTexture("3c8f1c70-671a-4cb6-9f06-58b95c77e6a6", ALL_SIDES);
    }
}

The advantage with using the UUID is that the texture does not need to be in the prim’s inventory, it only needs to exist somewhere in SL’s asset server.

Note that the asset UUID in the above code is a real one, and will get you a “test card” pattern that you can use for testing offsets (see below).

Aside: What happens if you upload a texture into your inventory, get the UUID for it, then delete the texture? Will the texture vanish from Second Life altogether? No, it won’t. Once a texture is uploaded, it is permanently added to the asset server, and deleting it from your inventory has no effect on it — you simply won’t be able to refer to it by name any longer. It will still exist on the server, and you can still use the UUID to refer to it in a script.

Sides

Suppose you want to apply a texture to just one side of a prim. To do this you simply specify the side number:

llSetTexture(“test”, 1);

Ah, but how do you know which side has which number? That’s the tricky bit. Assume that you have just rezzed a cube, and haven’t rotated it in any way. The sides will be numbered as follows:

top: 0
side with lowest y: 1
side with highest x: 2
side with highest y: 3
side with lowest x: 4
bottom: 5

If you hollow the cube, side 5 is the inside (yes, all four interior sides count as a single side), and the bottom becomes side 6.

Working out the side numbers for a rotated cube, or for a more complex prim, gets rather more difficult, and can involve a lot of trial and error. A better way is to use the debug menu. If you don’t have the debug menu displayed, press CTRL+ALT+D to reveal it.

To get information about one side of a prim, tick the ‘Select Texture’ option in the build dialog, select the prim side that you want to know about, then press CTRL+SHIFT+ALT+T. Information about the prim side will be displayed, including the side number.

Scaling and Offsetting

Once a texture is applied, you can scale and offset it using the llScaleTexture and llOffsetTexture functions.

llScaleTexture(0.5, 2.0, ALL_SIDES);

llOffsetTexture(0.5, 0.0, ALL_SIDES);

The horizontal and vertical parameters taken by these functions are exactly the same as those on the texture tab of the build dialog, so you can use the build dialog to help find the appropriate values.

If you have already worked with textures you will know that a scaling of 1.0 x 1.0 will fit the texture to the size of the prim, whereas higher values will tile the texture, and lower values will only display part of the texture.

For example, a value of 0.25 will display one quarter of the texture, stretching it to fit the prim. Which quarter of the texture is actually displayed depends on the offset, and the way in which the offset works is not immediately obvious.

Basically, the offset is from the centre of the texture. An offset of 0.0 x 0.0 will therefore centre the texture. How other offset values affect the texture is easier to explain using an actual example.

Here is the testcard texture which I mentioned above, applied initially with an offset of 0.0 x 0.0:

Test Card example 1

If you change the horizontal offset to 0.25 you get this:

Test Card example 2

Try changing the horizontal scaling to 0.25, and the horizontal offset to 0.0. This produces the following, which is actually displaying the centre of the scaled texture, showing half of one band of colour, and half of the other.

Test Card example 3

To offset it so that we are centred in a band of colour, we need to use an offset of 1/8, or 0.125. Set the horizontal offset to this value, and we get a single band.

Test Card example 4

To centre each band in turn, use the following offsets:

-0.375
-0.125
0.125
0.375

Obviously, this only works when the horizontal scale is 0.25.

Using scaling and offsetting to select just one portion of a texture can help to make more efficient use of textures, especially if you have a prim which needs to sometimes change appearance — you can pack the different images into a single texture, and select the appropriate part of the texture using the scale and offset. The alternative method is to have multiple textures, but this means that when the texture is changed, there is a delay while the new texture is loaded. Using the scale and offset method, the texture is already fully loaded, and the prim changes appearance almost instantly.

I’ll cover this more in a later post.

Links

You will find a lot of useful information about the texture-handling functions on the LSL Wiki:

LSL Wiki

I’ve done a number of posts now about scripting, so maybe it’s time to move on to a new subject. I’m going to assume (as I did with scripting) that you are already familiar with the basics of texturing in Second Life, and also that you are probably familiar with a suitable graphics package for creating or adjusting textures.

Recently I’ve started experimenting with drop-shadows, and on reading Iris Ophelia’s article in New World Notes I see that I am not the only one. Drop- shadows are evidently the new thing!

But what is a drop-shadow, and why would you want one? An illustration is in order. Here is a snap-shot of one of the rooms of my SL home, Morgridge Mansion:

Morgridge Mansion without shadows

The key thing to note is that in real life there would be an element of shadowing beneath the objects (especially the chairs and the table). Let’s add this in Second Life:

Morgridge Mansion with shadows

Much better. A nice bit of added realism (to be honest, I’ve slightly overdone some of the shadowing, just to make it stand out for this illustration). You’ll notice that I’ve also added a shadow behind the portrait on the wall.

So…how is it done?

Well, I don’t know how other people do it, but I’ll explain how I achieved the effect.

The first thing you need is a shadow texture. For the Mansion I created two textures, one circular, and one square. I won’t give exact details on how to do this, because they depend on which graphics package you use (personally I use The Gimp, which is free, powerful). If you aren’t familiar with creating textures, I’ve included links to my own shadow textures, which you can feel free to copy and use — see the bottom of this post.

If you want to try creating your own shadow texture, these are the steps that I took. Translate them to suit your own graphics package:

I used a 128×128 graphic (shadows don’t need a high-resolution, so this size is perfectly adequate) with transparency. I then selected an area about 3/4 of the size of the entire graphic, feathered it to about 25 pixels (you can play about with this — it will determine how quickly your shadow ‘fades out’ towards the edges), and used a blend fill of black to dark gray to fill the area. The end result (in both square and circular versions):

(To be honest, I’m not happy with the square version, which has something of an ‘X’ effect to it. More work required, methinks.)

Ok, now we’ve got our texture, how do we apply this in Second Life?

Start with a new prim — cube for square shadows, cylinder for circular shadows. Resize the Z-scale to the minimum, 0.01, and adjust the X and Y scales until the prim is slightly larger than the object that you want to shadow (if you are adjusting the prim using the ‘grab handles’ rather than entering numbers into the dialog, you probably want to scale the X/Y size first, before minimising the Z scale).

You now need a completely transparent texture. There is a transparent texture in the default library, but unfortunately it is not completely transparent, and will leave you with an ugly white edge. I’d avoid it and use your own texture. If you don’t have a fully-transparent texture, I’ve included a link to mine at the bottom of this post.

Apply the texture. Then select the ‘Edit Texture’ option from the build dialog, and select the top surface of the prim. Apply the shadow texture to this surface.

Move the prim so that it is directly beneath the object that is to be shadowed.

On the Features tab of the build dialog, adjust the transparency. The higher the transparency, the more subtle the shadow. I’ve found that a value of between 40 and 60 seems to work best. Experiment.

Link the shadow prim to the main object, and you’re done.

And finally

The transparency of the shadow prim affects the darkness of the shadow, and the best value to use depends on where the object is located. It would be handy to give the owner of the object a way of adjusting this. Here’s a simple script that does just that. Drop this script into the shadow prim. Each time the owner clicks on it, the transparency will increase by 10 (fading the shadow). When the transparency reaches 100, the next click will return it to 0 (completely black):

// Default transparency value. Change to suit.
float transparency = 50.0;
// Amount to change transparency on each click.
float changeBy     = 10.0;
default
{
    touch_start(integer count)
    {
        // Only allow the owner to change the shadow.
        if (llDetectedKey(0) == llGetOwner())
        {
            // Adjust the transparency value.
            transparency = transparency + changeBy;
            if (transparency > 100.0)
            {
                transparency = 0.0;
            }
            // Apply the new value to the prim. llSetAlpha
            // works in reverse to the Transparency value
            // in the build dialog (!), so we'll subtract from
            // 100 to make them match.
            llSetAlpha(1.0 - (transparency / 100.0), ALL_SIDES);
        }
    }
    changed(integer change)
    {
        // Reset the script when the owner changes,
        // otherwise llGetOwner() might return the
        // wrong value.
        if (change & CHANGED_OWNER)
        {
            llResetScript();
        }
    }
}

Downloadable textures

Circular shadow texture

Square shadow texture

Fully-transparent texture

Here is a very simple way to create rippling water for a pond or swimming pool. It uses the water textures which are in the Second Life standard library, so you don’t have to spend money uploading any textures!

To make this work, create two prims. For the sake of this example, I’ll call them Water and Ripples, just to make it easier to identify which one I am talking about.

Make them both the same size, and flatten them as thin as possible — they are going to combine to form the water surface.

Place them so that the Ripples prim is just above the top of the Water prim.

In the Second Life texture library, find the Waterfalls folder. Texture the Water prim with the “Water – ripple layer 1” texture, and the Ripples prim with the “Water – ripple layer 2 texture”.

In the Water prim, create a new script, and replace the script contents with the following:

default
{
    state_entry()
    {
        llSetTextureAnim(ANIM_ON | LOOP | SMOOTH | ROTATE, ALL_SIDES,
                        1, 1, 1, 1, -0.025);
    }
}

This will slowly rotate the texture.

In the Ripples prim, create a new script, and replace the script contents with the following:

default
{
    state_entry()
    {
        llSetTextureAnim(ANIM_ON | LOOP | SMOOTH | ROTATE, ALL_SIDES,
                        1, 1, 1, 1, 0.025);
    }
}

This will slowly rotate the texture, but in the opposite direction to the texture of the Water prim.

The result, to my eyes at least, is a very convincing rippling water effect. You have to look at it very carefully to spot what is actually happening.