Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

screen-space-reflections

Package Overview
Dependencies
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

screen-space-reflections

Screen Space Reflections implementation in three.js

  • 2.0.8
  • npm
  • Socket score

Version published
Maintainers
1
Created
Source

three.js Screen Space Reflections

Implements performant Screen Space Reflections in three.js.





Demos

react-three-fiber demos:

Usage

If you are using react-three-fiber, you can also use the SSR component from react-postprocessing. Check out the react-three-fiber demos to see how it's used there.

Basic usage:

Install the package first:

npm i screen-space-reflections

Then add it to your code like so:

import { SSREffect } from "screen-space-reflections"

const composer = new POSTPROCESSING.EffectComposer(renderer)

const ssrEffect = new SSREffect(scene, camera, options?)

const ssrPass = new POSTPROCESSING.EffectPass(camera, ssrEffect)

composer.addPass(ssrPass)

Options

Default values of the optional "options" parameter
const options = {
	temporalResolve: true,
	temporalResolveMix: 0.9,
	temporalResolveCorrectionMix: 1,
	maxSamples: 256,
	resolutionScale: 1,
	width: typeof window !== "undefined" ? window.innerWidth : 2000,
	height: typeof window !== "undefined" ? window.innerHeight : 1000,
	ENABLE_BLUR: false,
	blurMix: 0.5,
	blurKernelSize: 8,
	blurSharpness: 0.5,
	rayStep: 0.1,
	intensity: 1,
	maxRoughness: 0.1,
	ENABLE_JITTERING: false,
	jitter: 0.1,
	jitterSpread: 0.1,
	jitterRough: 0,
	roughnessFadeOut: 1,
	rayFadeOut: 0,
	MAX_STEPS: 20,
	NUM_BINARY_SEARCH_STEPS: 5,
	maxDepthDifference: 3,
	maxDepth: 1,
	thickness: 10,
	ior: 1.45,
	DITHERING: false,
	STRETCH_MISSED_RAYS: true,
	USE_MRT: true,
	USE_NORMALMAP: true,
	USE_ROUGHNESSMAP: true
}
Description of the properties
  • width: width of the SSREffect

  • height: height of the SSREffect

  • temporalResolve: whether you want to use Temporal Resolving to re-use reflections from the last frames; this will reduce noise tremendously but may result in "smearing"

  • temporalResolveMix: a value between 0 and 1 to set how much the last frame's reflections should be blended in; higher values will result in less noisy reflections when moving the camera but a more smeary look

  • temporalResolveCorrectionMix: a value between 0 and 1 to set how much the reprojected reflection should be corrected; higher values will reduce smearing but will result in less flickering at reflection edges

  • maxSamples: the maximum number of samples for reflections; settings it to 0 means unlimited samples; setting it to a value like 6 can help make camera movements less disruptive when calculating reflections

  • ENABLE_BLUR: whether to blur the reflections and blend these blurred reflections with the raw ones depending on the blurMix value

  • blurMix: how much the blurred reflections should be mixed with the raw reflections

  • blurSharpness: the sharpness of the Bilateral Filter used to blur reflections

  • blurKernelSize: the kernel size of the Bilateral Blur Filter; higher kernel sizes will result in blurrier reflections with more artifacts

  • rayStep: how much the reflection ray should travel in each of its iteration; higher values will give deeper reflections but with more artifacts

  • intensity: the intensity of the reflections

  • maxRoughness: the maximum roughness a texel can have to have reflections calculated for it

  • ENABLE_JITTERING: whether jittering is enabled; jittering will randomly jitter the reflections resulting in a more noisy but overall more realistic look, enabling jittering can be expensive depending on the view angle

  • jitter: how intense jittering should be

  • jitterSpread: how much the jittered rays should be spread; higher values will give a rougher look regarding the reflections but are more expensive to compute with

  • jitterRough: how intense jittering should be in relation to a material's roughness

  • MAX_STEPS: the number of steps a reflection ray can maximally do to find an object it intersected (and thus reflects)

  • NUM_BINARY_SEARCH_STEPS: once we had our ray intersect something, we need to find the exact point in space it intersected and thus it reflects; this can be done through binary search with the given number of maximum steps

  • maxDepthDifference: the maximum depth difference between a ray and the particular depth at its screen position after refining with binary search; lower values will result in better performance

  • maxDepth: the maximum depth for which reflections will be calculated

  • thickness: the maximum depth difference between a ray and the particular depth at its screen position before refining with binary search; lower values will result in better performance

  • ior: Index of Refraction, used for calculating fresnel; reflections tend to be more intense the steeper the angle between them and the viewer is, the ior parameter set how much the intensity varies

  • DITHERING: Improves performance but reduces quality by only alternately calculating reflections for every second pixel each frame; only works well if resolutionScale is 1

  • STRETCH_MISSED_RAYS: if there should still be reflections for rays for which a reflecting point couldn't be found; enabling this will result in stretched looking reflections which can look good or bad depending on the angle

  • USE_MRT: WebGL2 only - whether to use multiple render targets when rendering the G-buffers (normals, depth and roughness); using them can improve performance as they will render all information to multiple buffers for each fragment in one run; this setting can't be changed during run-time

  • USE_ROUGHNESSMAP: if roughness maps should be taken account of when calculating reflections

  • USE_NORMALMAP: if normal maps should be taken account of when calculating reflections

Since the right options for an SSR effect depend a lot on the scene, it can happen that you don't seem to have an effect at all in your scene when you use the SSR effect for the first time in it without any configuration. This can have multiple causes such as rayStep being way too low for your scene for example. So to find out which SSR options are right for your scene, you should use a GUI to find the right values easily. The example already comes with a simple one-file GUI SSRDebugGUI.js that you can use in your project like so:

  • First install the npm package of the module used for the GUI:
npm i tweakpane
  • then just copy the SSRDebugGUI.js to your project and initialize it like so in your scene:
import { SSRDebugGUI } from "./SSRDebugGUI"

const gui = new SSRDebugGUI(ssrEffect, options)

That's it, you should now have the GUI you can see in the example scene. The options parameter is optional for the SSRDebugGUI and will default to the default options if no options parameter is given.


Run Locally

If you'd like to test this project and run it locally, run these commands:

git clone https://github.com/0beqz/screen-space-reflections
cd screen-space-reflections/example
npm i --force
npm run dev

Features

  • Temporal Reprojection to re-use the last frame and thus reduce noise
  • Jittering and blurring reflections to approximate rough reflections
  • Using three.js' WebGLMultipleRenderTarget (WebGL2 only) to improve performance when rendering scene normals, depth and roughness
  • Early out cases to compute only possible reflections and boost performance
  • Using an edge-preserving bilateral blur filter to keep details while blurring noise

What's new in v2

  • Introduced Temporal Reprojection to reduce noise for the reflections when moving the camera by reprojecting the last frame's reflections into the current one
  • Implemented accumulative sampling by saving and re-using the last frame's reflections to accumulate especially jittered reflections over frames
  • Made all SSR-related options (e.g. thickness, ior, rayStep,...) reactive so that you now just need to set ssrEffect.rayStep = value for example to update values
  • Fixed jittering so that it's actually correct from all angles (it used to be less intense the higher you were looking down at a reflection)
  • Removed Kawase Blur in favor of Bilateral Blur to preserve edges and keep details as the blur method of the SSR effect
  • Changed the SSR implementation from a pass to an effect to improve performance
  • Optimizations regarding computation of required buffers and reflections

Tips

Expand to view tips ### Getting rid of artifacts

If you are getting artifacts, for example:

Then try the following:

  • increase thickness
  • increase maxDepthDifference
  • increase maxDepth or set it directly to 1
  • decrease rayStep and increase MAX_STEPS if reflections are cutting off now
  • increase NUM_BINARY_SEARCH_STEPS

Keep in mind that increasing these values will have an impact on performance.

Hiding missing reflections

Since SSR only works with screen-space information, there'll be artifacts when there's no scene information for a reflection ray. This usually happens when another objects occludes a reflecting object behind it.
To make missing reflections less apparent, use an env-map that can then be used as a fallback when there is no reflection. Ideally use a box-projected env-map.

Here are two implementations for three.js and react-three-fiber:

Getting updated reflections for animated materials

By default, the SSR effect won't really update reflections if the camera is not moving and no mesh in the view is moving. However, it will check if a mesh's material's map is a VideoTexture and will keep its reflections updated each frame. If your material is not using a VideoTexture but is still animated (e.g. it's a custom animated shader material), then you can get updated reflections for it by setting mesh.material.userData.needsUpdatedReflections = true. This will make the SSR effect recalculate its reflections each frame.

Server Side Rendering and window being undefined

If you are using Server Side Rendering and don't have access to the window object then the SSR effect won't be able to set the correct width and height for its passes. So once you have access to the window object, set the correct width and height of the SSR effect using:

ssrEffect.setSize(window.innerWidth, window.innerHeight)

Todos

  • Reprojection: support skinned meshes
  • Proper upsampling to still get quality reflections when using half-res buffers

Credits

Resources

Screen Space Reflections in general

Temporal Reprojection

Keywords

FAQs

Package last updated on 26 Jul 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc