jerome Posted February 2, 2015 Share Posted February 2, 2015 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 ? Quote Link to comment Share on other sites More sharing options...
Temechon Posted February 2, 2015 Share Posted February 2, 2015 Hey, I think you need to create two materials, as texture are shared between materials. Quote Link to comment Share on other sites More sharing options...
jerome Posted February 2, 2015 Author Share Posted February 2, 2015 tinkiou Quote Link to comment Share on other sites More sharing options...
jahow Posted February 3, 2015 Share Posted February 3, 2015 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? Quote Link to comment Share on other sites More sharing options...
jerome Posted February 3, 2015 Author Share Posted February 3, 2015 Isn't this already possible with Sprites ?https://github.com/BabylonJS/Babylon.js/wiki/08-Sprites A SpriteManager has a texture and each sprite then may have its different offset on this texture, the position in the image, nope ? Quote Link to comment Share on other sites More sharing options...
jahow Posted February 3, 2015 Share Posted February 3, 2015 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! Quote Link to comment Share on other sites More sharing options...
Xeonzinc Posted February 3, 2015 Share Posted February 3, 2015 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? jerome 1 Quote Link to comment Share on other sites More sharing options...
jahow Posted February 3, 2015 Share Posted February 3, 2015 That sounds perfect: please share Quote Link to comment Share on other sites More sharing options...
jerome Posted February 3, 2015 Author Share Posted February 3, 2015 Yes, please show Quote Link to comment Share on other sites More sharing options...
Xeonzinc Posted February 3, 2015 Share Posted February 3, 2015 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;} Quote Link to comment Share on other sites More sharing options...
jahow Posted February 3, 2015 Share Posted February 3, 2015 Thanks, very interesting. If I understand correctly, the mesh.xn, mesh.yn, mesh.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? Quote Link to comment Share on other sites More sharing options...
Xeonzinc Posted February 3, 2015 Share Posted February 3, 2015 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.