Home Technical Talk

Performance question : multiples materials with custom AO

greentooth
Offline / Send Message
Froyok greentooth
I'm currently working on a small environment piece and I'm wondering if the way I work the mots optimized for achieving my result.

Here is my workflow :
1- I make tilling textures
2- I make some meshes using these textures and merge them together as a 1 big mesh
3- I make a lightmap UV (for UDK)
4- I also use this UV to generate an AO map for the global mesh.

The following part is in UDK :
1- I make a base materials with a multiply texture for the AO
2- Then I make a lot of material instance for changing the AO maps for each mesh

ao_udk_material.jpg


The thing is : my big mesh sometimes use like 4 of 6 different materials, but these materials are also on the other mesh (they are generic material used everywhere). The only difference is that they are different instanced materials for having the personalized AO map.


I'm wondering if on the performance side having these AO maps on the top with each time different materials could be a huge problem ?
But since the base texture is always the same everywhere in the level and I only use instanced materials to change the AO map, is it ok ?


What could be the best technique for optimizing this ? Especially in other engine. I guess what I do in UDK can't be reproduced in other engine...


edges_test.jpg

Replies

  • Eric Chadwick
    Options
    Offline / Send Message
    I don't know the precisely how Unreal manages instanced materials, but I do know the hardware usually wants each material to be delivered on its own.

    So if you have 6 instanced materials on one mesh, this is usually going to be sent to the card in separate chunks. Each chunk of triangles that shares the same material.

    Unreal might have some neat trickery that avoids this. Other engines might have this as well. Doubtful though. Usually the best bet is to make a single texture atlas, with those 6 bitmaps packed into it. I'm off to read up on UDK materials...
  • Eric Chadwick
    Options
    Offline / Send Message
    Yep, looks like it's as I thought.
    http://udn.epicgames.com/Three/InstancedMaterials.html#Static%20Parameters
    It seems each permutation of the instanced material is a different shader... so each time you replace that AO map, you're making a separate shader at runtime, which increases the draw calls for your model.

    The whole point of instanced materials seems to be to make it easier to edit content. Not specifically to improve performance. Though it can help with that too, by helping you manage how many different shaders you generate in the end.
  • Froyok
    Options
    Offline / Send Message
    Froyok greentooth
    I know that static parameters produce everytime a new shader (like the switch node) but I only use scalar and texture parameters in my materials.

    Also :
    An instance of a material can dynamically provide new values for these parameters with very little expense.

    I guess the best thing I can do is to make atlas texture.
    I'm thinking about 1 base material with an atlas + its AO maps.

    The thing is, I will probably try to preserver my UV range tiling, so I guess I will use the trick to only have one part of the atlas displayed. This mean I will need to use instancied materials for each part of the atlas...

    Herrr... Hard to see what is the best workflow... I will probably do some performance test.
  • Eric Chadwick
    Options
    Offline / Send Message
    Hopefully a UE3 pro will step in with some info. It sounds like maybe the non-static params are perf friendly, because maybe they don't have to send new shaders to the card, maybe they just tweak what's already there?

    D3lON.gif
  • Froyok
    Options
    Offline / Send Message
    Froyok greentooth
    Hopefully a UE3 pro will step in with some info. It sounds like maybe the non-static params are perf friendly, because maybe they don't have to send new shaders to the card, maybe they just tweak what's already there?
    That's what I'm understanding when I read the doc.
    But yeah a UE3 pro answer would be awesome ! :)

    D3lON.gif
    Haha !
  • JordanW
    Options
    Offline / Send Message
    JordanW polycounter lvl 19
    Anytime you make a new MIC you are creating a new Draw Call. So while the per pixel cost of multiplying AO on top of your mesh is negligible, you are creating some performance cost by having multiple materials. If these are huge meshes, like building size, and they only contain like 3-5 materials it probably won't be so bad.

    It also depends on your target platform, if it's mid-high PC, you probably don't have anything to worry about. In a true production environment we would just measure the cost and determine if it's worth it. There's no specific guideline because each scene/game has it's own performance characteristics.

    As a side note, Lightmass can bake AO for you in your lightmaps. This will avoid multiple draw calls AND render correctly. Your current implementation is an incorrect use of AO. AO should only be multiplied against indirect lighting. By manually multiplying it by the diffuse it's getting applied to direct and indirect lighting.
  • Froyok
    Options
    Offline / Send Message
    Froyok greentooth
    JordanW wrote: »
    Anytime you make a new MIC you are creating a new Draw Call. So while the per pixel cost of multiplying AO on top of your mesh is negligible, you are creating some performance cost by having multiple materials. If these are huge meshes, like building size, and they only contain like 3-5 materials it probably won't be so bad.

    It also depends on your target platform, if it's mid-high PC, you probably don't have anything to worry about. In a true production environment we would just measure the cost and determine if it's worth it. There's no specific guideline because each scene/game has it's own performance characteristics.

    Thank you for your input ! :)
    JordanW wrote: »
    As a side note, Lightmass can bake AO for you in your lightmaps. This will avoid multiple draw calls AND render correctly. Your current implementation is an incorrect use of AO. AO should only be multiplied against indirect lighting. By manually multiplying it by the diffuse it's getting applied to direct and indirect lighting.
    Well, I have already enabled the AO settings in lightmass but I guess I didn't feel the difference. Even if I know that my AO is incorrect, this add have a great impact on the visual (more depth on the mesh mostly).
  • Froyok
    Options
    Offline / Send Message
    Froyok greentooth
    JordanW wrote: »
    Anytime you make a new MIC you are creating a new Draw Call. So while the per pixel cost of multiplying AO on top of your mesh is negligible, you are creating some performance cost by having multiple materials. If these are huge meshes, like building size, and they only contain like 3-5 materials it probably won't be so bad.
    I jump on this today. I'm currently planning a new environments and I was grouping all the information I had about the performances in the UDK. I decided to do some tests by myself to be sure.

    And I meet a problem. This is probably me doing something wrong.


    I have made 2 meshes : the geometry is identical but one has only 1 material slot and the second has 3 slots. While I compare my scene with the simple mesh compared to the 3 slot mesh, it's logical to see my drawcall multiplied.

    I have 4 materials in my package :
    mat1 : gray/basic (used for the simple mesh)
    mat2 : blue color
    mat3 : orange color
    mat4 : instance material from blue -> green color

    My idea was first to compare a scene full with the 3 slots mesh and a scene with a copy of the mesh with the MIC. Of course there is no performance difference since it's always the same number of materials, the drawcalls are identical. But here is the thing : if I change some meshes in the scene with the other 3 slot mesh, the drawcall don't change. I was expecting to see them increasing since there should be 4 different materials in the scene.


    (Here follow my screenshot comparison. The total of meshes in the scene is always the same. Each screenshot is from a new scene, taken from out of the editor, in game mode.)

    1 mesh, 1 material (mat1)
    1355468998-udk_1mesh_1material.jpg


    1 mesh, 3 materials (mat1, mat2 & mat3)
    1355468992-udk_1mesh_3materials.jpg


    1 mesh, 3 materials (mat1, mat3 & mat4)
    1355468994-udk_1mesh_2mat_1mic.jpg


    2 meshes, 4 materials (mat1 to mat4)
    1355468993-udk_2meshes_3mat_1mic.jpg
  • JordanW
    Options
    Offline / Send Message
    JordanW polycounter lvl 19
    You should create a simpler test case, i'm losing you in what's different in shot 3 and 4. I think an easy way to think of draw calls is, if you have the same mesh throughout your scene its mesh count * # of mat IDs
  • Froyok
    Options
    Offline / Send Message
    Froyok greentooth
    Well :

    Screenshot 3
    : 1 mesh with material 1, 3 and 4 applied on it.

    Screenshot 4 : 2 meshes. They have the same topology and materials slot number but I have duplicated them inside my package to be sure they are different for the engine. The first mesh has the mat 1, 3 and 4 applied on it. The second mesh has mat 1, mat3 and mat4 applied on it.


    As you said before, MIC are considered as new materials, which mean new drawcalls. But comparing the performances on the scene in the two last screenshots, I see no changes.

    That's what I don't understand : if MIC make new drawcall, why my performances show that the engine counts only 3 materials instead of 4 (I'm not taking account of the character + ground material of course since they are in every screenshot) ?



    I made this heavy scene to see more easily the performance change.
  • JordanW
    Options
    Offline / Send Message
    JordanW polycounter lvl 19
    You have a mesh with 3 material slots, that's all that matters. If you have 3 material slots that's 3 drawcalls to render that mesh, no matter what materials are assigned.

    If you have 2 versions of the same mesh that have 3 matIDs each, it's 6 total draw calls no matter if they share materials or not.
  • Froyok
    Options
    Offline / Send Message
    Froyok greentooth
    JordanW wrote: »
    You have a mesh with 3 material slots, that's all that matters. If you have 3 material slots that's 3 drawcalls to render that mesh, no matter what materials are assigned.

    If you have 2 versions of the same mesh that have 3 matIDs each, it's 6 total draw calls no matter if they share materials or not.
    Ha, I see ! I was thinking in the wrong direction, I thought drawcall where made from shaders (that's stupid when you think back about it).

    So :
    JordanW wrote: »
    Anytime you make a new MIC you are creating a new Draw Call.
    This sentence is not actually correct ?
  • JordanW
    Options
    Offline / Send Message
    JordanW polycounter lvl 19
    I should have been more clear in that original sentence, I was connecting the two concepts together and i shouldn't have.
  • Froyok
    Options
    Offline / Send Message
    Froyok greentooth
    Ok, that's perfectly clear now ! Thanks a lot ! :)
Sign In or Register to comment.