[SOLVED] Shaders (s)

Hi

In the Stats view, I see the “Materials (s)” go high when I add more tiles into my game. Now, the materials are from a tilemap that is loaded from the asset manager:

Material mat = assets.loadMaterial("Materials/WangBlobLight.j3m"); //tileType.getTileSet()            
                    
mat.setTransparent(false);
        
geom.setMaterial(mat);
geom.setQueueBucket(RenderQueue.Bucket.Opaque);
this.updateWangBlobTile(geom, tileType);

and rotating the material:

public void updateWangBlobTile(Spatial s, TileType tileType) {
        Geometry geom;
        if (s instanceof Geometry) {
            geom = (Geometry) s;
        } else {
            geom = (Geometry) ((Node) s).getChild("MapTile"); //From ModelViewState
        }
        Material mat = geom.getMaterial();
        //Offset tile
        mat.setInt("numTilesOffsetX", clientMapState.getWangBlobTileNumber(tileType.getTileIndex()));

        //Rotate tile
        Quaternion rot = new Quaternion();
        float rotations = clientMapState.getWangBlobRotations(tileType.getTileIndex());
        float ninety_degrees_to_radians = FastMath.PI / 2;

        rot.fromAngleAxis(-ninety_degrees_to_radians * rotations, Vector3f.UNIT_Z);
        //Reset rotation
        geom.setLocalRotation(new Quaternion());
        //Set correct rotation
        geom.rotate(rot);

        //log.info("Coords: "+s.getLocalTranslation() +" rotated: "+geom.getLocalRotation());
    }

Should I be doing more caching of the material and re-using the same material (does that make a difference?)

My scene looks like this:

Every tile is is generated like the above. There’s one light source on the ship in the center.

Should I worry about the Materials (S) count here?

Any input is appreciated

Does numTilesOffsetX map to a define in your material definition?

If so then that would explain why each one gets a new shader at least.

I mean, I’m assuming when you say “Material(s)” that it’s really “Shader(s)” that you are concerned about.

Ah yes, correct. My mistake.

And reg. numTilesOffsetX, then yes. Here’s my material j3m:

Material WangBlobLight : MatDefs/StaticSprite/StaticSpriteLightShader.j3md {
 MaterialParameters {

    numTilesX : 15
    numTilesY : 1
    numTilesOffsetX : 0
    numTilesOffsetY : 0

    DiffuseMap : Flip Tilesets/wangblobs/File0002.png
    UseMaterialColors : true
    Specular : 1.0 1.0 1.0 1.0
    Diffuse : 1.0 1.0 1.0 1.0
    Shininess : 1.0
 }
AdditionalRenderState {
  Blend Alpha
  Wireframe Off
}
}

This would be where the define mappings are.

the numTilesOffsetX goes from 0 to 15 - do I need to cache the materials because of this or is there something else I should do ?

If it were me, and I was going to have more than a handful of sprites, I wouldn’t have mapped those values to defines in the first place.

Yes, here’s the defines section of that file:

    Defines {
        VERTEX_COLOR : UseVertexColor
        VERTEX_LIGHTING : VertexLighting            
        MATERIAL_COLORS : UseMaterialColors
        DIFFUSEMAP : DiffuseMap
        NORMALMAP : NormalMap
        SPECULARMAP : SpecularMap
        PARALLAXMAP : ParallaxMap
        NORMALMAP_PARALLAX : PackedNormalParallax
        STEEP_PARALLAX : SteepParallax
        ALPHAMAP : AlphaMap
        COLORRAMP : ColorRamp
        LIGHTMAP : LightMap
        SEPARATE_TEXCOORD : SeparateTexCoord
        DISCARD_ALPHA : AlphaDiscardThreshold
        USE_REFLECTION : EnvMap
        SPHERE_MAP : EnvMapAsSphereMap  
        NUM_BONES : NumberOfBones                        
        INSTANCING : UseInstancing
        NUMTILESX : numTilesX
        NUMTILESY : numTilesY
        NUMTILESOFFSETX : numTilesOffsetX
        NUMTILESOFFSETY : numTilesOffsetY
    }

and the MaterialParameters:

MaterialParameters {
...
        Boolean BackfaceShadows : false
        //---->>
        Int numTilesX
        Int numTilesY
        Int numTilesOffsetX
        Int numTilesOffsetY
        //Texture2D AniTexMap
        //<----
    }

How would you do it instead of the defines?

So for every different value of those Defines you will get a different “shader” because they are inserted directly into the source code. Which I guess is fine when 1000 sprites share the same tileset.

But when every “sprite” is somehow using different tileset parameters it would have been better to just have them as regular material parameters.

As it is now, those end up being #define lines inserted into the shader source. So every different combination of values is a different .vert/.frag file.

1 Like

I guess here I’m lost. I dont know the difference really. How can I move forward if I have to do it via material parameters?

Edit the .vert and .frag to use the material parameters instead of the #defined constants.

If your answer is: “I’m using someone else’s sprite library and I don’t know how to modify it.”

…then you should consider if you are using it appropriately and whether or not you really need what it’s offering.

At this point, I’m having to make more guesses than answers so that may be all of the information that I can provide. I don’t know why you have to set these constants differently for each tile, etc…

I do use the material parameters. Thanks to your comments, I went in and removed the defines and it works now.

Thank you

1 Like