Shader variable parsing

I want to parse my height from the main to my shaders. Instead of the height= 10.0;
But it doesnt work.
Any ideas? What is wrong with my code

This is my vertex Shader

uniform mat4 g_WorldViewProjectionMatrix;
attribute vec3 inPosition;
varying float height;

void main(){
   height = 10.0;
  gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
}

My Fragment Shader

 varying float height;

 void main(){
    
  gl_FragColor.rgb = vec3(height/20.0 , 1.0 - height/20.0 ,0.0);

 }

My Main

    TerrainQuad terrain = new TerrainQuad("asdf", 256, 513, heightmap.getHeightMap());
    Material mat = new Material(assetManager, "Materials/newMat.j3md");
    terrain.setMaterial(mat);
    
    mat.setFloat("Height", height);
1 Like

The shader already contains the vertex position. You should look at other shaders such as the heightbasedterrain shader to see how it works.

Hint: it has a lot to do with inPosition.

I couldn find anything on the web about

What has inPosition to do with my height?

@M1ztl but i provided all code needed in:

height variable is there too. there are more posts than just one.

btw. anyway if you want pass any variable via code to shader, you need do it via materialDefinition

I tried it with your code an it still doesnt work.
What does the TransformWorldViewProjection even do?

From what you have posted, i guess that you are trying to pass a mat param? If that is the case, you need to add it to the j3md in the MaterialParameters block

MaterialParameters {
    ....
    Float Height
    ....
}

Then you need to retrieve it in the shader like this

uniform float m_Height;

void main(){
   ...
}

Note the use of the uniform keyword.

TransformWorldViewProjection transforms from the model space to the clip space.

Thx for your advice.
But i dont know what to do with the TransformWorldViewProjection/TransformWorld. Do i need to define them the j3md and in the shader?

I’ve tried it without the lines from @oxplay2 but i’m not getting a fade when setting the height manually. :confused:

They are functions from the Instancing.glsllib file.
Take a look at the shaders provided with the engine (eg Unshaded), you will see that there is an import for Instancing.glsllib.

Thx. The errors are gone but my color gradient still doesnt work, sadly.

He’s trying to set a color based on the vertex height, so there’s not need to pass any data to the shader because it already knows the position of the vertex. The inPosition variable contains this data. So you just need to set a color based on the height of the vertex.

As i see you dont even use my code, so how its supposed to work?

again i dont see you using code i provided like:

wPosition = TransformWorld(modelSpacePos).xyz;
height = wPosition.y;

also you always say “doesnt work” without any explaination.

We cant really read in mind, you need provide more information what you have done and what you exactly need… and what exactly dont work.

btw. also its not like i provide code and you expect it to just work when you dont even copy it fully. I help you with already done code that need to be put to default shaders to make it work. Its just an example of code ofc and can be modified to be even better. Anyway what i provided there is fully working if all is copy pasted in proper places in default shaders in JME 3.3 (3.2 should be fine too)

Well I am using your provided Code.

My mountains arent getting their color changed its all 1 color.
Could be something wrong with my Heightmap tho

AbstractHeightMap heightmap = new AbstractHeightMap() {
        @Override
        public boolean load() {
            int terrainSize = 256;
            size = terrainSize;
            // clean up data if needed.
            if (null != heightData) {
                unloadHeightMap();
            }
            heightData = new float[size * size];
            // transfer temporary buffer to final heightmap
            for (int i = 0; i < cords.size(); i++) {
                setHeightAtPoint(cords.get(i).getY(), cords.get(i).getX(), cords.get(i).getZ());
            }
            normalizeTerrain(1);
            return false;
        }

    };
    heightmap.load();

4 questions:

  • do heightmap is not a plain ? do it have mountains? (plain will ofc have one color)
  • can i also see fragment shader?
  • what initial height your terrain have? (i mean node of terrain)
  • what color is this “all 1 color”
  • Here’s my fragment shader:

  • This is my terrain:

    TerrainQuad terrain = new TerrainQuad("asdf", 256, 513, heightmap.getHeightMap());
    
  • It does have mountains

  • Its all green

if this is all green, i suspect your terrain is placed in world space much below (0,0,0) or heights are too low to make shader even see difference.

what you should check:

  • highest point of terrain in WorldSpace - its global rootNode space, not local
  • lowest point of terrain in WorldSpace
  • try make a very high mountain

simple test would be also placing a Box in rootNode in position (0.0.0) and see if its above terrain or on terrain. (because i suspect it will be much above terrain)

another simple test would be testing values like

height = wPosition.y + 10;

or

height = wPosition.y + 20;

or

height = wPosition.y + 50;

or others to see when it start making red. (because like i said your terrain seems to be not in (0,0,0) in world space.)

also you did not show values you pass as height to heightmap, if this values are like -100, then i belive it will be all green, because its very low height. Like i said in earlier topic, gl_fragColor line need to be “adjusted” to what you need.

I tried the box at 0,0,0 and it was in the middle of the terrain.
But when i try to make the mountains bigger they stay the same.

?

anyway did you tried this what i said above like “height = wPosition.y + 20;” ?

yes when + 20 it gets red

then try +10 or +5

looks like your mountain are little trully.

you can also try change line:

gl_FragColor.rgb = vec3(height/20.0 , 1.0 - height/20.0 ,0.0);

into

gl_FragColor.rgb = vec3(height/5.0 , 1.0 - height/5.0 ,0.0);

the 5.0 value is max height for red color here. you could make some variable you pass that check Maximum height of your terrain and pass as this value, it would be perfect.

so perfectly it would be:

gl_FragColor.rgb = vec3(height/maxHeight , 1.0 - height/maxHeight ,0.0);

where maxHeight will be max from values you pass to heightmap