PBR Terrain & Converter Utility


#1

I’ve finished working on a basic PBRTerrainShader and I’ve open sourced the repository for anyone who would like to use it.

Currently Includes:

  • Basic PBR Terrain shader for 3.2
  • Basic PBR Terrain shader for 3.3 (supports light probe blending and AmbienLight)
  • Utility to convert a Phong terrain material to PBR (useful for terrains created with external terrain editors)

WIP Features / Coming Soon:

  • Advanced PBR Terrain shader (utilizing a texture array)
  • Utility for packing Metallic/Roughness/Ao map all in one texture
  • Utility for saving and reusing texture arrays

The ‘readme’ file describes how to use the Converter Utility if you need to convert an existing terrain.
And the repository also contains a working test case if you choose to generate your terrain from code (thanks @Ali_RS for making the test case and helping with testing)

Also thanks to @b00n for your original PBR terrain shader that I based this off of
And thanks to @nehon for creating and sharing the original PBR Shader, bringing JME3 into a new era of graphical quality - and especially for how much I have learned about shaders from analyzing and extending your work with the PBR shaders :slightly_smiling_face:

Please let me know if you have any issues or questions using the shader or converter utility.

The test case should look like this:


#2

Cool, thanks so much for your contribution Ryan :slightly_smiling_face:


#3

just noted unused:

float hour = 0; (because now we got ambient)

just to let know :slight_smile: for sure im interested in it, but without some features from Afflicted.


#4

After properly tested by folks and reviewed and final cleanups and being approved by core developers, we might finally be able to include the shader into JME core as a standard PBR terrain material.


#5

ok, but i see there Things like:

where for example is

float getAdjustedPlaguedVar(float plaguedVar){

the JME version should be more “universal”, or maybe i dont understand what is this plaguedVar, but if im not wrong, its strict related to @yaRnMcDonuts game itself :slight_smile:

im not quite sure what are:

livelinessValue
plaguedValue
noiseHash (i belive its some noise, but for now im not sure what noise)

edit:

im not against this vars, but why not make them like “universal overlays” above everything else


#6

Yes, I know about those variables which are specific to Ryan game, of course, they should not get included in the standard one aimed for the core.
I mean there is yet a lot of things to be discussed about it. So no hurry.


#7

Also anyway @yaRnMcDonuts need to change license of it, because it cant be used as new BSD as it is now with license file inside. Strict law related. (“All rights reserved.”)


#8

I will most likely clean up all of the extra (and unused in 3.3) vars for daylight and indoor lighting when 3.3 is moved to stable, but until then I will probably leave support for both so that i can have day/night cycles in 3.2 still

Yeah it should be okay to remove these from the final version if it gets merged into the engine. But for nowm they shouldn’t affect your code as long as they are not defined.

I set that up a long time ago, and actually copy/pasted many things with the license and gradle files from another repository I was referncing, but I’ll remove that licensing. I’m still somewhat of a noob with using Gitbhub :stuck_out_tongue:


#9

Im testing your shaders.

Normals looks fine even in blend areas.

i fully dont understand this line:

  normal += norm * 0.9;

why there is:

mat3 tbnMat;

used only in:

plaguedNormal = normalize(tbnMat * plaguedNormal);

?

also one i dont understand why:

normal = normalize(normal * vec3(2.0) - vec3(1.0));

instead of JME PBR one that is:

normal = normalize((normal.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0)));

?

BTW:

could you also implement normal intensity change:

  normal.z /= 10;
  normal = normalize(normal);

where 10 will be param.

it works here:

  normal += norm * 0.9;

  normal = normalize(normal * vec3(2.0) - vec3(1.0));

  normal.z /= 10;
  normal = normalize(normal);

#10

Whenever I was working on it, I was also confused as to why I could not copy this code exactly from the standard PBR shader. But finally I had to just base it off of “what looks right” when the scene is rendered

So rather than basing my code directly on the original shader, I ended up trying many things with the Terrain’s tangents and normals until I finally got the PBR Terrain to appear in the scene the same way as a standard quad with the normal PBR Shader.

Whenever I have some time I’ll test this out and ensure it works as intended when applied to a terrain. Although for a terrain, there would have to be an option to change the intensity on a per-texture basis.


#11

Whenever I have some time I’ll test this out and ensure it works as intended when applied to a terrain. Although for a terrain, there would have to be an option to change the intensity on a per-texture basis.

yes, per texture, it would be again a lot params :slight_smile:

it should blend some intensity param based on texture params.

So rather than basing my code directly on the original shader, I ended up trying many things with the Terrain’s tangents and normals until I finally got the PBR Terrain to appear in the scene the same way as a standard quad with the normal PBR Shader.

hmm, would be great to have same as PBR, then it would be easy to “update based on PBR changes” in future. Also probably more issues were solved there.


#12

also, there seems to be not so important issue in normals, just for 90 degree terrain:


#13

Thankfully it should not be much of an issue when updating both files to new versions (atleast it was not for me when I was also developing a 3.3 version as well), as most updates to the PBR shader will only effect the lower half of both shaders (the liighting caclulations) wheras the top part of both PBR shaders (the texture reads) is already drastically different between the normal PBR shader and the terrain shader


#14

That’s odd, did you double check that you turned tri-planar mapping on? it looks like the albedo texture is also stretched out as well - I haven’t noticed any distortion in my scenes but I will double check


#15

hmmm…

the only thing i did was:

    mat_terrain.setBoolean("useTriPlanarMapping", true);

and i got no normals?

sorry, it more look like everything broke rather just normals.

do i need enable something more?


#16

When using tri-planar mapping, you also need to adjust the scales for all of your textures.

So you need to divide all of your textures’ scales by the size of your terrain, if I remember correctly.

So on a terrain of size 512, a scale of 4.0 is equal to a scale of 0.007797271 in tri-planar mode.

If you make a terrain in the terrain editor, then it will automatically divide/multiply your scales when you toggle tri-planar mode, but you need to do that manually when you make terrains with code.


#17

better now, but im still not sure if normals on 90 degree terrain are ok.

i tried each of

public Vector3f lightDir = new Vector3f(5.9236743f, -7.27054665f, 5.896916f);
public Vector3f lightDir = new Vector3f(5.9236743f, -7.27054665f, -5.896916f);
public Vector3f lightDir = new Vector3f(-4.9236743f, -3.27054665f, 5.896916f);
public Vector3f lightDir = new Vector3f(-4.9236743f, -4.27054665f, -5.896916f);

but always i see very low visible, or invisible normals on same side of mountain. idk why.

maybe its still just light, im not sure


#18

They look correct from certain angles - although the issue with normal mapping on all models is that it depends on the lighting angle

If you want to exaggerate the normal map for testing purposes, try settings a low roughness value and a high metallic value. Normal maps are much, much more apparent on PBR models that are very shiney.

If you have a model with high roughness and a low metallic value, then you will notice more depth from the roughness map than the normal map.


#19

I think you still have to normalise a mixed normal. I’m not sure that’s the actual issue, just noticed you never mentioned that step.


#20

just to show shader on multidimensional model:

all textures have same normalmap, for some reason left arm/hand have almost no normals.

same on front view, same arm/hand

maybe im just nervous about this normals. overall effect is ok, just not sure why its not same on both sides, since it use same texture scale and same normalmaps, just different albedos