A tutorial introducing how to implement custom materials from scratch using textures.
In the previous tutorial, we saw some of the important basics on building materials from scratch by building a flat coloured material. Basic indeed, and not very interesting. To improve on that, we’ll make a small step in the right direction by introducing textures, which in turn exposes a bit more of the material framework’s requirements.
We can start out exactly the same as last time’s TrivialColorMaterial and TrivialColorPass, naming them TrivialTextureMaterial and TrivialTexturePass, respectively. We’ll highlight the differences necessary to use textures.
No color getter/setter is needed this time, and since we don’t have any more constant data to send to the fragment shader, there’s no need to create a Vector.<Number> for that either.
As far as the vertex shader is concerned, only one thing changes. Since we’ll need to map a texture on our objects, we need to provide some UV coordinates per vertex and pass them on to the fragment shader where the texture will be sampled.
We’re still using vertex attribute stream 0 for the position, so we’ll use stream 1 for the UV coordinates. We simply pass them on to varying register v0, so the fragment shader can access it, which simply needs to sample the texture we set at texture stream 0.
While last time we could just skip implementing this step, when using textures this is necessary. Stage3D won’t let us keep textures bound to texture stream slots if they’re not used by the fragment shader. This means that if we’d render an object with our current TrivialTextureMethod followed by a render of an object with TrivialColorMethod, the texture would still be bound in slot 0 resulting in an error. The same is the case for vertex attributes streams, so the UV coordinates assigned to stream 1 need to be unassigned.
“Hold on!”, I hear you say, “We’ve been using vertex stream 0 last time and didn’t need to disable that!” True enough, but since we’re always using the vertex position, we’ll always have something assigned to stream 0 anyway, so disabling it is unnecessary (and it made the previous example a bit simpler).
This will allow the material framework to disable streams automatically as needed, and you won’t have to overrride the deactivate method.
The accompanying example code shows how the material can be used, in conjunction with the old TrivialColorMaterial in order to make sure the render state is cleared correctly.
These first two tutorials already provided most of the info you need to start tinkering around with writing your own custom shaders. However, there’s still some upcoming tutorials to show how to access lights.