Skip to content

0beqz/three-billboard-reflection

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Billboard Reflection

Implements performant reflections for simple planes in three.js.

The name derives from billboards for which this technique can ideally be used as seen in the Unreal Engine 3: Samaritan Demo. The benefit of this technique is that any mesh with any orientation can reflect these planes correctly.

Installation

The build (UMD and module version) is located in the /dist directory.

Usage

import BillboardReflection from "./BillboardReflection"

let billboardReflection = new BillboardReflection()

billboardReflection.create(billboardMesh)
billboardReflection.create(otherBillboardMesh, options)

mesh.material.onBeforeCompile = shader => billboardReflection.enableReflection(shader)

This will make mesh reflect billboardMesh and otherBillboardMesh.

Options

Options for BillboardReflection.create(mesh, options)

Default values:

{
    rayFalloff: 0,
    color: undefined, // will use reflecting mesh's color if undefined
    opacity: undefined, // will use reflecting mesh's opacity if undefined
    visible: undefined // will use reflecting mesh's visibility if undefined
}

Description:

  • rayFalloff: how much the ray falls off by distance, higher values will make it fade out faster
  • color: multiplies the reflection color with the given color, if it is undefined, the mesh's material color will be used
  • opacity: the opacity of the reflection, if it is undefined, the mesh's material opacity will be used
  • visible: whether the reflection is visible, if it is undefined, the mesh's visibility (namely its visible property and its material's visible property) will be used

Options for BillboardReflection.enableReflection(shader, options)

Default values:

{
    roughnessMapBlur: true,
    roughnessMapBlurIntensity: 0.85,

    roughness: undefined, // will use reflecting mesh's roughness if undefined
    envMapIntensity: undefined // will use reflecting mesh's envMapIntensity if undefined
}

Description:

  • roughnessMapBlur: whether to blur reflections using low-res mipmaps (see Limitations section for more information)
  • roughnessMapBlurIntensity: if roughnessMapBlur is enabled, how much a material should be blurred for higher roughness values, higher values will blur a reflection more but will result in more artifacts
  • roughness: overwrite roughness value for a reflection, if it's undefined, the material's roughness value will be used
  • envMapIntensity: overwrite envMapIntensity value for a reflection, if it's undefined, the material's envMapIntensity value will be used

Reflection for just a texture and matrix

If your reflecting objects are not meshes (e.g. all billboards are batched into a single mesh) then you can use a texture and a matrix to create reflections for each billboard:

let position = new Vector3(1, 0, 0)
let rotation = new Quaternion().setFromEuler(new Euler(0, 1, 0))
let scale = new Vector3(1, 1, 1)

let matrix = new Matrix4().compose(position, rotation, scale)

billboardReflection.createFromTextureAndMatrix(texture, matrix)

This will give the same reflection as a mesh at the given position with the given rotation and scale.

Limitations

There are limitations regarding roughness and occlusion due to performance reasons.

Roughness

Proper roughness support is missing so reflections aren't blurred on rough surfaces but fade out. If there's a roughness map then blur is achieved through using low-res mipmaps of a billboard texture for rough spots which gives acceptable results when there aren't too many rough spots. This does not work for video textures as these don't have mipmaps.

If your material has a roughness map but you don't want to use blur, then you can have it toggled off like so:

material.onBeforeCompile = shader => billboardReflection.enableReflection(shader, { roughnessMapBlur: false })

This will now only make the reflection fade out for higher roughness values.

Occlusion

There's no occlusion check for reflections so they can be visible behind other meshes. This can be counteracted by giving these meshes reflections too or increasing the reflection's fallOff value.

References

Papers and articles

Slides

Credits

Algorithm

Demo Scene

About

Performant plane reflections in three.js r139

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published