Jump to content

same textured material and different offsets


jerome
 Share

Recommended Posts

Hey, I was thinking: wouldn't it be possible to use a ShaderMaterial, and somehow change its uniforms depending on which mesh gets rendered? This way, one material could suit many different meshes and allow for variations on each one (shift in texture coords, color variations, etc.).

 

I know materials have an onBind event hook, but it doesn't give the mesh as a parameter so it wouldn't be possible to change uniforms here. Also the material won't get bound before each mesh render.

 

This would mean less Material objects created, but also (and more importantly) allow variations on instanced meshes, since these all share the same material.

 

Am I speaking crazy here?

Link to comment
Share on other sites

Here it is, mostly just a fudge from some of the other examples around here :)I've highlighted in red the key lines, which essentially just pass the number of sprites wide/high of the texture and then the sprite offset for x/y from the mesh to the shader.

 

Material js:

var custom_material = custom_material || {};(function () {    custom_material.ssheet = function (name, scene, texture) {        BABYLON.Material.call(this, name, scene);	this.ssheet = texture;        this.ssheet.uScale = 1.0;        this.ssheet.vScale = 1.0;  	this.ssheet.uOffset = 0;        this.ssheet.vOffset = 0;        this.ssheet.wrapU = BABYLON.Texture.MIRROR_ADDRESSMODE;        this.ssheet.wrapV = BABYLON.Texture.MIRROR_ADDRESSMODE;       		this.backFaceCulling = false;    };    custom_material.ssheet.prototype = Object.create(BABYLON.Material.prototype);    // Properties       custom_material.ssheet.prototype.needAlphaBlending = function () {        return true;    };    custom_material.ssheet.prototype.needAlphaTesting = function () {        return true;    };	    // Methods       custom_material.ssheet.prototype.isReady = function (mesh) {        var engine = this._scene.getEngine();        if (!this.ssheet.isReady)            return false;						        var defines = [];        if (this._scene.clipPlane) {            defines.push("#define CLIPPLANE");        }        var join = defines.join("\n");        if (this._cachedDefines != join) {            this._cachedDefines = join;            this._effect = engine.createEffect("./Shaders/Spritesheet/ssheet",                ["position", "normal", "uv"],                ["worldViewProjection", "world", "vSsheet"],                ["ssheetSampler"],                join);        }        if (!this._effect.isReady()) {            return false;        }        return true;    };    custom_material.ssheet.prototype.bind = function (world, mesh) {        this._effect.setMatrix("world", world);        this._effect.setMatrix("worldViewProjection", world.multiply(this._scene.getTransformMatrix()));                // Textures        if (this.ssheet) {            this._effect.setTexture("ssheetSampler", this.ssheet);        }  		this._effect.setFloat4("vSsheet",mesh.xn,mesh.yn,mesh.xoff,mesh.yoff);    };        custom_material.ssheet.prototype.dispose = function () {        if (this.ssheet) {            this.ssheet.dispose();        }     		        BABYLON.Material.dispose(this);    };})();

Vertex Shader:

#ifdef GL_ESprecision mediump float;#endif// Attributesattribute vec3 position;attribute vec2 uv;// Uniformsuniform mat4 worldViewProjection;// Normalvarying vec2 vUV;void main(void) {    gl_Position = worldViewProjection * vec4(position, 1.0);    vUV = uv;}

Fragment Shader:

#ifdef GL_ESprecision mediump float;#endif// Refsvarying vec2 vUV;uniform sampler2D ssheetSampler;uniform vec4 vSsheet;void main(void) {    // Cell selection    vec2 texCoords;		texCoords.x =( vUV.x /vSsheet.x) + vSsheet.z;	texCoords.y =( vUV.y /vSsheet.y) + vSsheet.w;    gl_FragColor = texture2D(ssheetSampler, texCoords).rgba;}
Link to comment
Share on other sites

Thanks, very interesting. If I understand correctly, the mesh.xnmesh.ynmesh.xoff and mesh.yoff properties control which part of the texture will be displayed on the mesh, and these properties can be changed on the fly.

 

It means one could similarly handle properties such as colorTint, opacity, etc. while still using instanced meshes. Is that right?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...