Rick Posted March 25, 2013 Share Posted March 25, 2013 I have a base model. I have 6 base materials that fit this model. I need to randomly create any of these variations at random times (so no way of knowing how many I'd need ahead of time). What would be the most efficient way to do this? Because of model instancing I can't just load the base model and apply different materials to it because it switches the models to the most current material. Having 6 different model files of the same model to get around the instancing issue is wasteful and on mobile I can't imagine is the way to go. Any ideas? [EDIT] What I'm doing now is I placed the base model in the scene (as a precache model so model instancing happens but my understanding is Model:Load() where the second parameter is Asset.Unmanaged means I get instancing of the model data, but a new material? I then created 6 csg models and put the 6 materials on them as a precache to the materials so when I call Material:Load() it should be instances of the already loaded materials right? With this I'm getting about 20 fps on my desktop. :/ I notice also it's like the scene takes 30 seconds to really load or finish doing whatever it's doing even though it shows and screen and runs. I get 30 some seconds of choppy 20 FPS before MOST times it gets to 60 and then stays. Every so often it won't get to 60 and stays in the 20's. This is very strange. Quote Link to comment Share on other sites More sharing options...
YouGroove Posted March 25, 2013 Share Posted March 25, 2013 Rick : Are your tests on PC or directly tested on mobile ? Because of model instancing I can't just load the base model and apply different materials to it because it switches the models to the most current material. Why not loading a model where no material is assigned and just assign material by code ? (you would have all 6 materials pre loaded) I notice also it's like the scene takes 30 seconds to really load or finish doing whatever it's doing even though it shows and screen and runs. It's like "Darkness game it puts lot of time to start, i think a future optimisation could be done in LE3 : like having one file zip per section made behind the scene. You add a model to your project a zip file "Models.zip" would be modified behind the scene, and loading the game, LE3 would load all zip files of the project (models.zip, script.zip etc ...) I then created 6 csg models and put the 6 materials on them as a precache to the materials so when I call Material:Load() it should be instances of the already loaded materials right? Are you sure about model instancing ? that it works that way ? What is your game type ? tower defense ? to need a big amount of models with different textures ? How works the game if you just create models and materials as needed at run time ? [color=#000000][font=arial, tahoma, helvetica, sans-serif]I get 30 some seconds of choppy 20 FPS before MOST times it gets to 60 and then stays. Every so often it won't get to 60 and stays in the 20's[/font][/color] Do you use NavMesh functions ? it's a thread running in background. Finally can't you change design of your game to make it work better ? Quote Stop toying and make games Link to comment Share on other sites More sharing options...
Rick Posted March 25, 2013 Author Share Posted March 25, 2013 Why not loading a model where no material is assigned and just assign material by code ? (you would have all 6 materials pre loaded) Using just LoadModel() without the second param will make an instance of it and they all share the material. Using it with Asset.Unmanaged I'm guessing is what's causing the slowdown. This is why I think a shader that allows us to have multiple textures on 1 image file and offset which one we want would be the best fit in this siutation. Maybe I just have to make 1 of each as preloading and make prefabs :/ Hope that doesn't kill the memory usage on mobile. Quote Link to comment Share on other sites More sharing options...
YouGroove Posted March 25, 2013 Share Posted March 25, 2013 This is why I think a shader that allows us to have multiple textures on 1 image file and offset which one we want would be the best fit in this siutation. Without that super shader : For example if your Goblin would have 256*256 texture UV, what you could do is have one 1024*1024 texture that would contain four assembled 256*256 textures in fact , and just use some UV shift to change texture of the model at runtime I don't know if LE 3 have simple UV commands functions ? Keep us to date with how you've done and what works better, i'm interested Quote Stop toying and make games Link to comment Share on other sites More sharing options...
shadmar Posted March 25, 2013 Share Posted March 25, 2013 This is why I think a shader that allows us to have multiple textures on 1 image file and offset which one we want would be the best fit in this siutation. You can already do this I think, wouldn't this just be plain uvmapping? 1 Quote HP Omen - 16GB - i7 - Nvidia GTX 1060 6GB Link to comment Share on other sites More sharing options...
Rick Posted March 25, 2013 Author Share Posted March 25, 2013 Niosp (I think) did something like this in LE2. It worked great. I'm not a shader guy so I have no idea how this would be done but I know it can be done and has before. Quote Link to comment Share on other sites More sharing options...
shadmar Posted March 25, 2013 Share Posted March 25, 2013 @Rick Ok.. change shader you want to use (ex : Dynamic\diffuse.shader) : Find : uniform vec4 lighting_ambient; Add below : uniform vec3 tileselect; Find : outcolor *= texture2D(texture0,ex_texcoords0); Replace it so it reads : outcolor *= texture2D(texture0,vec2(ex_texcoords0.x*tileselect.z+tileselect.z*tileselect.x,ex_texcoords0.y*tileselect.z+tileselect.z*tileselect.y)); That's it for the shader part. In your application, you need to do this for a 3x3 texture in psuedo : surface = entity:GetSurface() material = surface:GetMaterial() shader = material:GetShader() shader:SetVec3("tileselect",tile_x,tile_y,1.0/3.0) --1.0/4.0 if you use a 4x4 texture and so on... tile_x and tile_y is typical 0,0 --> 2,2 for a 3x3 texture. Let me know how it works out. Quote HP Omen - 16GB - i7 - Nvidia GTX 1060 6GB Link to comment Share on other sites More sharing options...
shadmar Posted March 25, 2013 Share Posted March 25, 2013 should work for mobile also, just follow the convention like using uniform highp instead of uniform.. Quote HP Omen - 16GB - i7 - Nvidia GTX 1060 6GB Link to comment Share on other sites More sharing options...
Rick Posted March 25, 2013 Author Share Posted March 25, 2013 hmm, couldn't get this to work. So you tested this and it worked for you? Here is what I did. 1) Opened diffuse+normal.shader and made the changes you have above 2) Made a tga file that was 1024x1024 and put in 3 of my 256x256 textures on this starting in top left corner and going right 3) Imported this texture into LE3 4) Generated normal map via LE3 menu option 5) Made dynamic material from texture and normal. The bg color of my 1024x1024 texture is white, so what I noticed visually on the material is that it was ALL white with the normal bumps in the shape of the actual texture, but again, the color was all white so something wrong at this point. 6) I do the code stuff you have but again it's all white because something is clearly wrong with the material. No clue why it's just all white (the bg of the texture) and doesn't show at all the 3 textures I have inside of it. If I take your code change out I see the 3 textures and the remaining white but then of course I don't get the functionality that you are trying to provide. Not sure what's up with the all white :/ Quote Link to comment Share on other sites More sharing options...
shadmar Posted March 26, 2013 Share Posted March 26, 2013 I only tested the shader by hardcoding the tileselect value directly, hence the pseudo for the app code. I will try to make a quick lua example for it. Oh to support normalmaps you need to change the texture2D for the normalmap too. Quote HP Omen - 16GB - i7 - Nvidia GTX 1060 6GB Link to comment Share on other sites More sharing options...
YouGroove Posted March 26, 2013 Share Posted March 26, 2013 Shadmar : I'm also interested for Android on that code. Could you post some working example on "Assets" -> "Scripts" of Leadwerks site ? (Important new functionnalities should be here for all users to community) Quote Stop toying and make games Link to comment Share on other sites More sharing options...
Rick Posted March 26, 2013 Author Share Posted March 26, 2013 @shadmar Yeah, I notice if I hardcode tileselect in the shader it works (or does the correct offset when the material is first created) but you can never change it in code then since the hardcode overwrites the code change each time. Need some way to get around that. Could probably do some check to init to 0,0 and set a flag and if flag is set (the first time it goes into main(), we don't init anymore). Not sure how you can do that in a shader though. Are you able to give a var a value when you declare it, otherwise not sure how you would init it once only, or tell that a variable hasn't been given a value yet? If I try to init on the declaration line I get (Pixel Shader: Line 10: Initialization of uniform variables requires #version 120 or later). What version are we working with? Quote Link to comment Share on other sites More sharing options...
shadmar Posted March 26, 2013 Share Posted March 26, 2013 It's a uniform, that means it should be sendt from the application. All uniforms are inputs to a shader from an application. don't initialize it (might not work on mobile then) I'm at work so I can't test app code until later. ps! I might forgot to mention, but shader:SetVec3() should be ran at every loop. Also write out some debug info on these so you know you actually found correct material and shader: (make sure material isn't returning NULL) surface = entity:GetSurface() material = surface:GetMaterial() shader = material:GetShader() Here is a nice example on how to debug material : http://www.leadwerks...etmaterial-r127 Quote HP Omen - 16GB - i7 - Nvidia GTX 1060 6GB Link to comment Share on other sites More sharing options...
Rick Posted March 26, 2013 Author Share Posted March 26, 2013 ps! I might forgot to mention, but shader:SetVec3() should be ran at every loop. I just noticed that I created an int uniform that in the shader would change the tileset uniform (because for some reason the Vec3 isn't working) and when I created 2 models with the same shader in the App:Start() I always got the last one I set. Getting closer 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.