What is PBR ?
Physically based rendering or PBR is a shading model in computer graphics that seeks to render graphics in a way that more accurately models the flow of light in the real world.
What does sort of lighting does jME use ?
jME supports more traditional unshaded, phong lighting models among others. This is how virtually all jME projects were built before PBR.
Does jME support PBR ?
Yes, jME supports PBR out of the box from ver 3.2.0 onwards. It was implemented by core developer, and unapologetically Frenchman, @nehon in 2014.
- Physically Based Rendering – Part one
- Physically Based Rendering – Part two
- Physically Based Rendering – Part three
From a practical standpoint, how does PBR work in jME?
There are a few main things needed to get PBR working in jME:
an EnvironmentalCamera: A 360 camera that can capture a cube map of a scene, and then generate the Prefiltered Environment cube Map and the Irradiance cube Map needed for PBR indirect lighting
a LightProbe: Holds environment map information used for indirect lighting in the Physically Based Rendering pipeline (the reflections).
a model with tangents and binormals.
What is HDR / HDRI ?
High-dynamic-range imaging (HDRI) is a high dynamic range (HDR) technique used in imaging and photography to reproduce a greater dynamic range of luminosity than is possible with standard digital imaging or photographic techniques.
So an HDR image often looks like a normal image on screen, but it holds a lot more information about the lighting at each pixel e.g. although a white piece of paper and an illuminated light bulb may appear to be the same colour, an HDRI will store the light bulb as much brighter than the piece of paper.
Where can I get HDR Images:
Good free sites :
What are Normals, Tangents, and Binormals, and why should I care ?
tl;dr: They are 3d vectors. You export normals with your model, and generate tangents and binormals in the engine for correct PBR behavior.
The normal is an imaginary line pointing straight “out” from a surface, think of a piece of paper sitting on a flat table, the normal will the point up towards the roof. This is needed internally for numerous important operations, such as lighting. The normals for a model are generated during the modeling step and must be exported with the model.
The tangent is an imaginary line that lies “on” a surface, it can be rotated to face 360°. The tangent is responsible for tasks such as aligning points on a surface. The following thought example does not exactly reflect what happening, but I find it helps: think of a piece of paper (a quad), sitting on a flat table, cut into 4 pieces (subdivided once), the normals for all 4 pieces are the same, straight up, the tangents are like rotating the pieces: if they are all pointing in different directions, we can get strange behavior in the renderer, so instead, we will often line up all the pieces by facing the top of each piece to align with the left edge of the table, or, setting all the tangents to be the same.
A tangent helps orient the texture in 3D space. It should essentially point in the ‘x axis’ of the texture in 3D space. Again, this is necessary because surfaces curve and/or triangles may be oriented in any direction relative to the square texture. The binormal is orthogonal to both the normal and the tangent and can generally be calculated from them.
The normal, tangent, and binormal represent the 3D axes of ‘texture space’… where the tangent is x (or u), the binormal is y (or v), and the normal is depth.
The bi-normal lies on the same imaginary surface as the tangent is pointed in the same direction as the tangent except it has been rotated by 90°.
For a more in-depth explanation, I recommend having a look at this SE question:
Generally, you will not have to worry about the how and why of tangents and bi-normals, inorder to get correct behavior in the PBR pipe-line, it is very important to generate tangents and binormals for any PBR Lit model.
Why isn’t normal, tangent and binormal information calculated in the shader ?
Since polygonal surfaces are only approximations of potentially curved surfaces, normals cannot generally be calculated from a triangle directly as there needs to be some understanding of the curvature of the surface. (Even a dumb straight average of the shared triangle normals is not enough.)
How do I generate Tangents and Bi-normals?
There are currently internal methods:
- The current industry standard, and preferred MikkTSpace Generator
- The older, now outdated TangentBinormalGenerator
Why does jME render my model differently to ______ (Blender, Substance Painter …) ?
Have a look at this thread.
Where do I get PBR materials ?
Much like the tradition Lighting model that uses a DiffuseMap and NormalMap among others, the PBRLighting model will also use a set of textures.
You can generate these yourself using:
- Blender[*ref needed]
- from a Diffuse image using software like
You can download a full set of PBR textures from sites such as
This entire thing smells a bit of black magic, what are you playing at here ?
Why isn’t my model rendering “correctly” ?
Here is a check list of debugging steps :
- Are you sure you know what ‘correct’ is? Double check documentation, write a simple test case, make sure it is jME doing something you don’t expect, not a lack of your understanding.
- Does your scene have an Environmental Camera?
- Have you generated a LightProbe and attached it to your scene?
3a. is this step finished (often it takes a few seconds to compute)
- is there any geometry blocking your environmental camera? eg is the camera’s position inside the mesh of a model if so, this could cause parts of the camera rendering to be occluded, and be black.
- Are you using PRBLighting material?
- Have you generated tangents and binormals for your models?
- If using textures, make sure they do not need to be flipped vertically?
assetmanager.loadTexture(new TextureKey("pathToFile.ext", true));
- Are you correctly using Roughness and Metallic, are their values between 0 and 1?
- are your faces pointing in the right direction, and not inverted ?
I have a different question, where do I get an answer?
Post it in here, or open a forum thread for it, we will try to keep this FAQ relevant.