Sign in to follow this  
jerome

same textured material and different offsets

Recommended Posts

Hi,

 

I have got two different meshes.

I want them to use the same textured material but each one with a different texture offset.

 

Is there a way to do this ?

 

Or do I need to create a different material for each mesh ?

Share this post


Link to post
Share on other sites

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?

Share this post


Link to post
Share on other sites

That is a very good point. I'll look into it and see if there is something there that I can replicate.

 

The idea would be to have some sort of '3D' sprites, instanced meshes with more that just position/rotation/scale variables!

Share this post


Link to post
Share on other sites

I already have a material like this for meshes as I found sprites too limiting, essentially it allows the use of a texture as a sprite sheet for a mesh (changing offsets base on parameters attached to the mesh), but you only need one material.

 

I can post the key parts this evening if its of use?

Share this post


Link to post
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;}

Share this post


Link to post
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?

Share this post


Link to post
Share on other sites

Yes, that's the key bit really.

 

The only aspect i haven't tried out is sending large amounts of dynamic data to the shader (probably some form of array) as I'm currently limited to putting data into multiple vec4's,  although I think it must be possible.

Share this post


Link to post
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...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.