A (very) SimpleGrassControl

@vvishmaster

If you could provide me with the materials and shaders needed to make this sway with the wind, and everything work. I would appreciate that.

The material definition as well as all the needed shaders are in the TheForester plugin available from the update centre. Atleast they were at the time of posting.
I included the library here just in case http://rapidshare.com/share/7E778B0E835B4AB0C24250C58CBB99B1

Make sure you include that library in your project.

As for the texture unfortunately i don’t have access to the texture i made in the picture at the moment but any grass texture with an alpha channel will do.

Google “grass sprite png” or make your own in GIMP or photoshop.

Hope that helps :slight_smile: .

1 Like

@vvishmaster when I create a terrain and add the control to it, nothing happens.

I know that the problem is that the isgrasslayer() method, it doesn’t know which is the color red on the alphamap. But I don’t know how to provide the alphamap. It is supposed to be included in the terrain when the terrain is created.

When I set isgrasslayer() to always true, the grass shows up, but as you would expect it is in the wrong layer which makes the grass look funky.

How am I supposed to provide your class with the rbg alpha map? It is not reading any rbg alphamap.

Edit:

I added this one line to force the standard terrain alpha-mapping. This line makes the grass show up, which makes things fine. But the grass if as tall as my character, but I can fix that, though.

[java]
candidateGrassPatchLocation.set(x+grassPatchRandomOffset.x, terrain.getHeight(new Vector2f(x+grassPatchRandomOffset.x,z+grassPatchRandomOffset.y)), z+grassPatchRandomOffset.y);

terrain.getMaterial().setTextureParam(“AlphaMap”, VarType.Texture2D, assetManager.loadTexture(“Textures/red.png”)); //(at)pixelapp: I added this single line.

if(isGrassLayer(candidateGrassPatchLocation))
[/java]

I guess I can work it out from here. But I would be great if you tell me what am I supposed to be doing as per the first paragraph of this post.

Edit:

I found the answer.

The way the JMonkey Terrain Editor paints the red on the alpha-map texture is a different format/layer from what GIMP or other image processing apps do/read. So for your grass class to read the image you should make sure the red on the alpha-map is readable by conventional image processing apps, otherwise all the SimpleGrassControl class sees is a transparent texture.

1 Like

Look at those flowers!

As @vvishmaster said, I didn’t have to modify the code posted above.

[These are not the final game assets for the game, please disregard blurry textures and pointy 3D models].

2 Likes

Its looking good! I’m glad you managed to get it working :slight_smile:

Hi @vvishmaster, here is your shader at work:

I did not use your control because I already have height maps I wanted to reuse for seedability with my terrain in a whole, but I found your work very good!

1 Like

Can anyone help me? I don’t see the grass when I run. thanks…
Provide sample code, it would be great help…
gluckos at alice .it

Hi, could you show us your code please? It will be much simpler to help you if you did.

@.Ben. said: Hi, could you show us your code please? It will be much simpler to help you if you did.
Thanks for the reply!! https://www.dropbox.com/s/wbcjxtsr564783u/Screenshot%202014-10-22%2021.58.38.png?dl=0
MaterialDef My MaterialDef {

    MaterialParameters {

        //Fading parameters (don't set these manually).
        Float FadeEnd
        Float FadeRange
        Boolean FadeEnabled
    

        //Is the grass mesh a distant impostor?
        Boolean IsImpostor
        
        //Is the grass swaying or not?
        Boolean Swaying
        //The wind vector (determines direction and amplitude of the swaying function).
        Vector2 Wind
        //The swaying frequency
        Float SwayFrequency

        //The texture
        Texture2D ColorMap
        //The perlin noise for stipple fading.
        Texture2D AlphaNoiseMap
    }

    Technique {
        VertexShader GLSL120:   Resources/Grass.vert
        FragmentShader GLSL120: Resources/Grass.frag

        WorldParameters {
            WorldViewProjectionMatrix
            WorldMatrix
            CameraPosition
            Time
        }

        Defines {
            SWAYING : Swaying
            FADE_ENABLED : FadeEnabled
            IS_IMPOSTOR : IsImpostor
        }
    }

}
@GluckOs said: Thanks for the reply!! https://www.dropbox.com/s/wbcjxtsr564783u/Screenshot%202014-10-22%2021.58.38.png?dl=0

The error on the screenshot talks about the VertexLighting parameter which I do have in my J3MD file, why isn’t yours showing it? Did you strip variables down? Try and leave the shader file exactly like it was because in Grass.vert it is making calculations based on if the VertexLighting variable is true or false. Now it’s UNDEFINED which throws the exception.

Use this J3MD file instead, which contains all the appropriate definitions:


MaterialDef Grass {

    MaterialParameters {
        
        //Fading parameters (don't set these manually).
        Float FadeEnd
        Float FadeRange
        Boolean FadeEnabled
        
        //Is the grass swaying or not?
        Boolean Swaying
        //The wind vector (determines direction and amplitude of the swaying function).
        Vector2 Wind
        //Combined vector for various fading data.
        //x = The swaying frequency
        //y = The swaying variation (how the offset varies between patches)
        //z = Maximum swaying distance (grass beyond this distance does not move).
        Vector3 SwayData

        //Use lighting
        Boolean VertexLighting

        //Use vertex colors (requires a colormap provided to the grassloader).
        Boolean VertexColors

        //Use grass self-shadowing.
        Boolean SelfShadowing

        //The texture
        Texture2D ColorMap
        //The perlin noise for stipple fading.
        Texture2D AlphaNoiseMap

        //When texture alpha is below this value, the pixel is discarded
        Float AlphaThreshold

        Float opacity
        
        //Used internally.
        Int NumLights
    }

    Technique {

        LightMode SinglePass

        VertexShader GLSL100:   Shaders/Grass/Grass.vert
        FragmentShader GLSL100: Shaders/Grass/Grass.frag

        WorldParameters {
            WorldViewProjectionMatrix
            WorldMatrix
            ModelViewMatrix
            ProjectionMatrix
            ViewMatrix
            ModelViewProjectionMatrix
            WorldViewMatrix
            CameraPosition
            Time
        }

        Defines {
            SWAYING : Swaying
            FADE_ENABLED : FadeEnabled
            VERTEX_LIGHTING : VertexLighting
            VERTEX_COLORS : VertexColors
            SELF_SHADOWING : SelfShadowing
            NUM_LIGHTS : NumLights
        }
    }

    Technique PreShadow {

        VertexShader GLSL100 :   MatDefs/BillboardPreShadow/BillboardPreShadow.vert
        FragmentShader GLSL100 : MatDefs/BillboardPreShadow/BillboardPreShadow.frag

        WorldParameters {
            WorldViewProjectionMatrix
            WorldViewMatrix
            ProjectionMatrix
        }

        Defines {
            DIFFUSEMAP_ALPHA : DiffuseMap
        }

        RenderState {
            FaceCull Off
            DepthTest On
            DepthWrite On
            PolyOffset 5 0
            ColorWrite Off
        }
    }

    Technique PreNormalPass {

        VertexShader GLSL100 :   Common/MatDefs/SSAO/normal.vert
        FragmentShader GLSL100 : Common/MatDefs/SSAO/normal.frag

        WorldParameters {
            WorldViewProjectionMatrix
            WorldViewMatrix
            NormalMatrix
        }

        Defines {
            SWAYING : Swaying
            FADE_ENABLED : FadeEnabled
        }

        RenderState {

        }

    }

}
1 Like

thanks…
I do not have the following files:

MatDefs/BillboardPreShadow/BillboardPreShadow.vert
MatDefs/BillboardPreShadow/BillboardPreShadow.frag
Common/MatDefs/SSAO/normal.vert
Common/MatDefs/SSAO/normal.frag

where can I find them?

Thanks again, I hope I can run the code…

You have them, because the /MatDefs/ [EDIT: MatDefs does NOT come with the libraries, sorry my mistake] and /Common/ directories come with the JME3 librairies. It’s already in the compiler path and it should work as is without you creating any of those files, at least here it works out of the box, as is.

Common comes from JME. MatDefs is local (assets/MatDefs)… and I don’t recognize the BillboardPreShadow as any standard JME thing.

Oh sh*t, yes! I’m sorry, put these instead, those come with JME3 as I intended… I just forgot I duplicated those a long time ago and assumed they were the original ones, so put this instead and it will work:

Common/MatDefs/Shadow/PreShadow.vert
Common/MatDefs/Shadow/PreShadow.frag

@.Ben. said: Oh sh*t, yes! I'm sorry, put these instead, those come with JME3 as I intended... I just forgot I duplicated those a long time ago and assumed they were the original ones, so put this instead and it will work:

Common/MatDefs/Shadow/PreShadow.vert
Common/MatDefs/Shadow/PreShadow.frag

still does not appear on the grass terrain …
GrassBase.j3md

MaterialDef Grass {
 
    MaterialParameters {
        
        //Fading parameters (don't set these manually).
        Float FadeEnd
        Float FadeRange
        Boolean FadeEnabled
        
        //Is the grass swaying or not?
        Boolean Swaying
        //The wind vector (determines direction and amplitude of the swaying function).
        Vector2 Wind
        //Combined vector for various fading data.
        //x = The swaying frequency
        //y = The swaying variation (how the offset varies between patches)
        //z = Maximum swaying distance (grass beyond this distance does not move).
        Vector3 SwayData
 
        //Use lighting
        Boolean VertexLighting
 
        //Use vertex colors (requires a colormap provided to the grassloader).
        Boolean VertexColors
 
        //Use grass self-shadowing.
        Boolean SelfShadowing
 
        //The texture
        Texture2D ColorMap
        //The perlin noise for stipple fading.
        Texture2D AlphaNoiseMap
 
        //When texture alpha is below this value, the pixel is discarded
        Float AlphaThreshold
 
        Float opacity
        
        //Used internally.
        Int NumLights
    }
 
    Technique {
 
        LightMode SinglePass
 
        VertexShader GLSL100:   Resources/Grass.vert  //my file
        FragmentShader GLSL100: Resources/Grass.frag  // my file
 
        WorldParameters {
            WorldViewProjectionMatrix
            WorldMatrix
            ModelViewMatrix
            ProjectionMatrix
            ViewMatrix
            ModelViewProjectionMatrix
            WorldViewMatrix
            CameraPosition
            Time
        }
 
        Defines {
            SWAYING : Swaying
            FADE_ENABLED : FadeEnabled
            VERTEX_LIGHTING : VertexLighting
            VERTEX_COLORS : VertexColors
            SELF_SHADOWING : SelfShadowing
            NUM_LIGHTS : NumLights
        }
    }
 
    Technique PreShadow {
 
        VertexShader GLSL100 :   Common/MatDefs/Shadow/PreShadow.vert  //jme3 library
        FragmentShader GLSL100 : Common/MatDefs/Shadow/PreShadow.frag  //jme3 library
 
        WorldParameters {
            WorldViewProjectionMatrix
            WorldViewMatrix
            ProjectionMatrix
        }
 
        Defines {
            DIFFUSEMAP_ALPHA : DiffuseMap
        }
 
        RenderState {
            FaceCull Off
            DepthTest On
            DepthWrite On
            PolyOffset 5 0
            ColorWrite Off
        }
    }
 
    Technique PreNormalPass {
 
        VertexShader GLSL100 :   Common/MatDefs/SSAO/normal.vert  //jme3 library
        FragmentShader GLSL100 : Common/MatDefs/SSAO/normal.frag  //jme3 library
 
        WorldParameters {
            WorldViewProjectionMatrix
            WorldViewMatrix
            NormalMatrix
        }
 
        Defines {
            SWAYING : Swaying
            FADE_ENABLED : FadeEnabled
        }
 
        RenderState {
 
        }
 
    }
 
}
 

I used class control in this topic …

and the main write this:

  Node map = (Node)assetManager.loadModel("Models/terrain.j3o");
        map.addControl(new SimpleGrassControl(assetManager,“Textures/FlowerA_D.png”)); 
       
        rootNode.attachChild(map);

It would be very convenient for me to have working code.
Thanks again for your patience!

At that point, I don’t know. Maybe the author can answer better. Are you sure you put the “FlowerA_D.png” file in the assets/Textures folder? I mean, at this point, are you seeing an exception thrown message or is the app running without crashing?

@.Ben. said: At that point, I don't know. Maybe the author can answer better. Are you sure you put the "FlowerA_D.png" file in the assets/Textures folder? I mean, at this point, are you seeing an exception thrown message or is the app running without crashing?

Thanks for the reply… App running without crashing but does not appear any grass on the ground…
FlowerA_D.png in the directory asset/Textures https://www.dropbox.com/s/ig4jc6vr1nr00fe/Screenshot%202014-10-23%2014.10.15.png?dl=0
app while running Dropbox - Screenshot 2014-10-23 14.11.46.png - Simplify your life

OK good, then you must be close to making it work, I guess. Can you dropbox a ZIP of your project? I’ll test it and find why it doesn’t work.

@.Ben. said: OK good, then you must be close to making it work, I guess. Can you dropbox a ZIP of your project? I'll test it and find why it doesn't work.
https://dl.dropboxusercontent.com/u/51602590/GrassControl.zip

thanks again

Hi, the flowers are underneath the terrain. Try to go under the terrain, you will see them.

EDIT: OK, change your line 147 to account for the terrain scaling, note that this is a rough number, you might want to programmatically get this real value or something, because getHeight() might not take the scaling into account. Maybe it’s because you made your terrain, scaled it and saved it to a j3o object file, the scaling might not be possible to get precisely through the code, but I don’t know about this, just a guess. Anyhow, here’s what I got just by modifying line 147, see the “* 5.1f”:

candidateGrassPatchLocation.set(x+grassPatchRandomOffset.x, terrain.getHeight(new Vector2f(x+grassPatchRandomOffset.x,z+grassPatchRandomOffset.y)) * 5.1f, z+grassPatchRandomOffset.y);

1 Like