MULTI SHADERS EXEMPLE

Download multi shaders exemple – Moussa Dembélé – www.mousman.com- mousman@hotmail.com

model made by Nergal83

Sorry, either Adobe flash is not installed or you do not have it enabled

There’s no textures,
but in this exemple three kind of shaders are used :
- one by default
- one for the tea cup sugars
- one for the coffe cup sugars.

We are going to see how.

The project can be found in the mutli_shaders directory.
The structure is the same.
Only one light and the object is moving this time.
Nothing new in World.as except the instanciation of CupsMesh.

CupsMesh.as

As usual the wavefront files are embeded :

[Embed(source="../lib/cups/cups.obj", mimeType="application/octet-stream")]
private var _objData:Class;

[Embed(source="../lib/cups/cups.mtl", mimeType="application/octet-stream")]
private var _mtlData:Class;

In setShaders() the three shaders are defined :

private function setShaders():void {
	// ShaderSets's container
	_shaderStore = new ShaderStore();

	// definition and declaration of the shaders to use
	var shader:MPhongShader = new MPhongShader();
	var writer:MVerticesBytesArrayWriter = new MVerticesBytesArrayWriter();
	// a ShaderSet object contains a IMShader and a IMBytesArrayWriter
	var shaderSet:ShaderSet = new ShaderSet(ShaderType.DEFAULT_SHADER, shader, writer);
	_shaderStore.add(shaderSet);

	shaderSet = new ShaderSet("simpleShader", new MSimpleShader(), writer);
	_shaderStore.add(shaderSet);			

	shaderSet = new ShaderSet("basicShader", new MBasicShader(), writer);
	_shaderStore.add(shaderSet);		
}

The first one (line 139) will be the default shader.
The second one (line 142) will be used for the tea cup sugars and the liquids. It is a simple shader that will interpolate the light without ‘special’ effects.
The last one (line 145) will be used for the coffe cup sugars. It is a basic shader that will apply the ambiant material color on the polygon groups.

A new function has been added : setSimpleConstants()
With the polygon groups on which the simple and basic shaders will be applied we only need the material ambiant color.
That’s what this function will do.

public function setSimpleConstants(mtlSet:MMtlSet):void {
	// fc3 , material ambiant color
	var color:Object = ColorUtil.hexArgb(mtlSet.ambiantColor);
	_context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT,  6, Vector.<Number>([Number(color.rouge) / 255, Number(color.vert) / 255, Number(color.bleu) / 255, 1]));
}

And now the drawTriangle() function :
Rembember that for each object an id is associated.
This is this id that is used to define which shader to take :

switch(object3Dset.id) {
	case "sugar1" :
	case "sugar2" :
		shaderSet = _shaderStore.getShaderById("basicShader");
		break;
	case "sugar3" :
	case "sugar4" :
	case "chocolate" :
	case "cofee" :
		shaderSet = _shaderStore.getShaderById("simpleShader");
	break;
	default :
		shaderSet = _shaderStore.getShaderById(ShaderType.DEFAULT_SHADER);
	break;
}

And also depending on this id we define the constants :

switch(object3Dset.id) {
	case "sugar1" :
	case "sugar2" :
	case "sugar3" :
	case "sugar4" :
	case "chocolate" :
	case "cofee" :							
		if(previousShaderSet != shaderSet)
			setSimpleConstants(mPolygonsGroup.mtlSet);
	break;
	default :
		if(previousShaderSet != shaderSet)
			setDefaultConstants(mPolygonsGroup.mtlSet);
	break;
}

Et voila…..

The complete drawTriangle() function :

public function drawTriangles():void {
	var shaderSet:ShaderSet;
	var previousShaderSet:ShaderSet;
	var buffer3D:VertexBuffer3D;
	var index3D:IndexBuffer3D;
	var object3Dset:MObject3D;
	var mPolygonsGroup:MPolygoneGroup3D;
	var polygonBufferSet:MPolygonGroupBuffers;

	// define the constantes wich are not dependant of objects or groups
	setFrameConstants();

	// loop through the objects
	var oSize:int = _mesh.mObjects.length;
	for (var i:int = 0; i < oSize; i++ ) {
		object3Dset =  _mesh.mObjects[i];
		//trace("drawing object " + object3Dset.id + " , " +object3Dset.id.length);
		// define the programs depending on groups
		previousShaderSet = shaderSet;
		switch(object3Dset.id) {
			case "sugar1" :
			case "sugar2" :
				shaderSet = _shaderStore.getShaderById("basicShader");
				break;
			case "sugar3" :
			case "sugar4" :
			case "chocolate" :
			case "cofee" :
				shaderSet = _shaderStore.getShaderById("simpleShader");
			break;
			default :
				shaderSet = _shaderStore.getShaderById(ShaderType.DEFAULT_SHADER);
			break;
		}
		if (previousShaderSet != shaderSet) {
			if(previousShaderSet) 
				previousShaderSet.shader.releaseActiveVertextBuffer(_context3D);
			_context3D.setProgram(shaderSet.program);	
		}
		// loop through the groups
		var pgSize:int = object3Dset.polygonsGroups.length;
		for (var j:int = 0; j < pgSize; j++ ) {
			mPolygonsGroup = object3Dset.polygonsGroups[j];
			//trace("drawing group " + mPolygonsGroup.id);

			// define the constantes depending on groups
			switch(object3Dset.id) {
				case "sugar1" :
				case "sugar2" :
				case "sugar3" :
				case "sugar4" :
				case "chocolate" :
				case "cofee" :							
					if(previousShaderSet != shaderSet)
						setSimpleConstants(mPolygonsGroup.mtlSet);
				break;
				default :
					if(previousShaderSet != shaderSet)
						setDefaultConstants(mPolygonsGroup.mtlSet);
				break;
			}

			// loop through the buffers
			var pbSize:int = mPolygonsGroup.polygonBufferSet.length;
			for (var k:int = 0; k < pbSize; k++ ) {
				polygonBufferSet = mPolygonsGroup.polygonBufferSet[k];
				buffer3D = polygonBufferSet.vertexBuffer;
				index3D = polygonBufferSet.indexBuffer;
				shaderSet.shader.setActiveVertextBuffer(_context3D, buffer3D);
				//trace("drawing triangles ");
				_context3D.drawTriangles(index3D, 0, -1);
			}
		}
	}
}

I hope you’ve appreciated this post.
It is your turn now !!

Any question, any comment, don’t hesitate…

gain time with parsing :binary file  export and import

 

 

Leave a Reply

  

  

  

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>