Sharing Textures between Starling and Away3D

In a previous post Recipe for a Mixed App with Starling and Away3D I discussed how to get started with creating a mixed app with both 2D and 3D layers. Here I will talk about how manage and share resources in the mixed app.postcard

Sharing Resources and Textures

So now we have code that places display object on both 3D and 2D layers. As commonly done is a starling app, there is a resource manager that loads and creates graphical assets, like images and sprite sheets. This works just fine for the starling side, but the 3D side takes different types as textures and requires materials assigned to them. Does that mean we should have a different set of assets for 3D?

Well, with some minimal adjustments, we should be able to use the same assets on the 3D side.

The first thing to notice, is that even though the different layers are created individually, they all share one render context. In other words, any Stage3D resource that is made available to one layer is automatically available to all.

Coming from the Starling side, I already have plenty of code to deal with textures and images.The common element in both is the raw Stage3d texture, TextureBase.   Starling texture is actually a wrapper for  TextureBase and contains one in the ‘base’ property. The SharedTexture class below does the trick of putting them all together, so it can be used by Away3D.

import away3d.textures.Texture2DBase;
import flash.display3D.textures.TextureBase;
import starling.textures.Texture;
 
// SharedTexture class
public class SharedTexture extends Texture2DBase 
{
	private var refTexture:Texture;
 
	public function SharedTexture(tex:Texture) 
	{
		super();
		refTexture = tex;
	}
 
	override protected function uploadContent(texture:TextureBase):void
	{
		// Leave empty
	}
 
	override protected function createTexture(context:Context3D):TextureBase
	{
		var baseTex:TextureBase = refTexture.base;
		return baseTex;
	}
}

To use it, instantiate with an existing starling texture and then pass it as the texture in the construnctor:

var tex:Texture = Texture.fromBitmap(....); // Get a starling texture
var sharedTex:SharedTexture = new SharedTexture(tex);
var mat:TextureMaterial= new TextureMaterial(sharedTex); // pass it to a material

flatMap

Sharing Sprite Sheets

What if we want to use existing sprite sheets as texture materials in the 3D scene?

I find that in reality, most of the textures I use come from sprite sheets. Starling internally refers to them as sub textures, and they contain  the information needed to extract the texture from the sheet.

In order for us to use Starling sprite sheets (or texture atlases), we can use this wrapper class for an Away3D sprite sheet that can be used on meshes. The  AwaySheet class wraps a  TextureAtlas and creates a shared material using  the SharedTexture class that was described earlier.

Get the source for the AwaySheet class here.

Once created, the away sheet would contain a texture material that can be accessed via the its sharedMaterial property.

	var sheet:AwaySheet = new AwaySheet(myAtlas); // warap existing atlas
	..
	// create a plane and assign the sheet material to it
	var plane:Mesh = new Mesh(new PlaneGeometry(500, 500), sheet.sharedMaterial);
	sheet.setupUV(plane, "sample1"); // Map it to a specific sub-texture in the sheet

The last step that is needed is to map the mesh to the sub-texture. This is done with the setupUV() function in the sheet, supplying it with the name for the texture in the sheet. This is equivalent to calling getTexture(“sample1”) on a starling TextureAtlas.

Note that you would end up using the same sheet material for multiple meshes, when each is using a different texture in the sheet – same as you would in starling. This approach would help reducing draw calls and state changes, because a single material is used for all those different textures.

Another advantage: this class can be modified to play animations, and essentially creating an animated material. That can be easily achieved by subsequent calls to sheet.setupUV() to advance the animation frame.
As opposed to Away3D’s own  SpriteSheetAnimator, it actually uses standard sheets that are used by Starling, and is much simpler to setup and use.

 

One thought on “Sharing Textures between Starling and Away3D

Comments are closed.