Implements Screen Space Reflections in three.js

Overview

three.js Screen Space Reflections

Implements performant Screen Space Reflections in three.js.

Glossy Reflections

Clean Reflections

Example scene


Demos

react-three-fiber demos:

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

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 { SSRPass } from "screen-space-reflections"

const composer = new POSTPROCESSING.EffectComposer(renderer)

const ssrPass = new SSRPass(scene, camera, options?)
composer.addPass(ssrPass)

Options

Default values of the optional options parameter:

const options = {
	width: window.innerWidth,
	height: window.innerHeight,
	useBlur: true,
	blurKernelSize: POSTPROCESSING.KernelSize.SMALL,
	blurWidth: window.innerWidth,
	blurHeight: window.innerHeight,
	rayStep: 0.1,
	intensity: 1,
	power: 1,
	depthBlur: 0.1,
	enableJittering: false,
	jitter: 0.1,
	jitterSpread: 0.1,
	jitterRough: 0.1,
	roughnessFadeOut: 1,
	MAX_STEPS: 20,
	NUM_BINARY_SEARCH_STEPS: 5,
	maxDepthDifference: 3,
	maxDepth: 1,
	thickness: 10,
	ior: 1.45,
	stretchMissedRays: false,
	useMRT: true,
	useNormalMap: true,
	useRoughnessMap: true
}

Description:

  • width: width of the SSRPass

  • height: height of the SSRPass

  • useBlur: whether to blur the reflections and blend these blurred reflections depending on the roughness and depth of the reflection ray

  • blurKernelSize: the kernel size of the blur pass which is used to blur reflections; higher kernel sizes will result in blurrier reflections with more artifacts

  • blurWidth: the width of the blur pass

  • blurHeight: the height of the blur pass

  • 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

  • power: the power by which the reflections should be potentiated; higher values will give a more intense and vibrant look

  • depthBlur: how much deep reflections will be blurred (as reflections become blurrier the further away the object they are reflecting is)

  • enableJittering: 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

  • stretchMissedRays: 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

  • useMRT: 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

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

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

Features

  • Jittering and blurring reflections to approximate glossy 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
  • Blurring reflections using Kawase Blur Pass for better performance over a Gaussian Blur Pass

Tips

Getting the right look

SSR usually needs a lot of tweaking before it looks alright in a scene, so using a GUI where you can easily modify all values is highly recommended. The demo uses tweakpane as the GUI. If you want to use it, check out how it's initalized and used in the demo: https://github.com/0beqz/screen-space-reflections/blob/main/src/index.js.

Handling noise

To smooth out noise from jittering, set the blurKernelSize to 2 or 3 and increase depthBlur precisely while using rather low values for blurWidth and blurHeight. This will blur out reflections the "deeper" they are.

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:

Todos

  • Add Temporal Filtering to reduce noise

Credits

Resources

Comments
  • request: allow ssr for selected meshes

    request: allow ssr for selected meshes

    similar to outlines and bloom in postprocessing: https://github.com/pmndrs/postprocessing/blob/main/src/core/Selection.js this could allow us to mix and match, place it on certain regions and perhaps achieve a cleaner look while improving performance? in sketchfab they have something similar where ssr is usually being using on metallic surfaces.

    opened by drcmda 11
  • Cannot use import statement outside a module

    Cannot use import statement outside a module

    First off, incredible work here! We are using @react-postprocessing inside of a Jenkins build pipeline, and the following error just started showing up and breaking the build process. Looks like @react-postprocessing started including the SSRPass as part of their package.

    /node_modules/screen-space-reflections/ScreenSpaceReflections.js:25
    import { Pass, RenderPass, DepthPass, KernelSize, KawaseBlurPass } from 'postprocessing';
    
    SyntaxError: Cannot use import statement outside a module
    
    opened by benjaminmiles 9
  • ERESOLVE unable to resolve dependency tree

    ERESOLVE unable to resolve dependency tree

    Hi!

    When I try to install the package I get the following error:

    npm i screen-space-reflections -S                                                                                                                                                    ─╯
    npm ERR! code ERESOLVE
    npm ERR! ERESOLVE unable to resolve dependency tree
    npm ERR!
    npm ERR! While resolving: [email protected]
    npm ERR! Found: [email protected]
    npm ERR! node_modules/three
    npm ERR!   three@"^0.142.0" from the root project
    npm ERR!   peer three@">= 0.107.0 < 0.143.0" from [email protected]
    npm ERR!   node_modules/postprocessing
    npm ERR!     peer postprocessing@"^6.28.0" from [email protected]
    npm ERR!     node_modules/screen-space-reflections
    npm ERR!       screen-space-reflections@"*" from the root project
    npm ERR!
    npm ERR! Could not resolve dependency:
    npm ERR! peer three@"^0.141.0" from [email protected]
    npm ERR! node_modules/screen-space-reflections
    npm ERR!   screen-space-reflections@"*" from the root project
    npm ERR!
    npm ERR! Fix the upstream dependency conflict, or retry
    npm ERR! this command with --force, or --legacy-peer-deps
    npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
    npm ERR!
    npm ERR! See /home/xxx/.npm/eresolve-report.txt for a full report.
    
    npm ERR! A complete log of this run can be found in:
    npm ERR!     /home/xxx/.npm/_logs/2022-07-17T18_19_51_727Z-debug-0.log
    

    My project package.json looks like this:

    {
      "name": "front-end",
      "version": "0.0.1",
      "scripts": {
        "dev": "vite dev",
        "build": "vite build",
        "package": "svelte-kit package",
        "preview": "vite preview",
        "prepare": "svelte-kit sync",
        "test": "playwright test",
        "check": "svelte-check --tsconfig ./tsconfig.json",
        "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
        "lint": "prettier --check --plugin-search-dir=. . && eslint .",
        "format": "prettier --write --plugin-search-dir=. ."
      },
      "devDependencies": {
        "@playwright/test": "^1.22.2",
        "@sveltejs/adapter-auto": "next",
        "@sveltejs/kit": "next",
        "@types/cookie": "^0.5.1",
        "@typescript-eslint/eslint-plugin": "^5.27.0",
        "@typescript-eslint/parser": "^5.27.0",
        "autoprefixer": "^10.4.2",
        "eslint": "^8.16.0",
        "eslint-config-prettier": "^8.3.0",
        "eslint-plugin-svelte3": "^4.0.0",
        "postcss": "^8.4.14",
        "postcss-cssnext": "^3.1.1",
        "postcss-load-config": "^3.1.1",
        "postcss-nested": "^5.0.6",
        "prettier": "^2.6.2",
        "prettier-plugin-svelte": "^2.7.0",
        "svelte": "^3.46.0",
        "svelte-check": "^2.7.1",
        "svelte-preprocess": "^4.10.6",
        "tslib": "^2.3.1",
        "typescript": "^4.7.4",
        "vite": "^2.9.13"
      },
      "type": "module",
      "dependencies": {
        "@babylonjs/core": "^5.14.1",
        "@babylonjs/materials": "^5.14.1",
        "@fontsource/fira-mono": "^4.5.0",
        "@lukeed/uuid": "^2.0.0",
        "@three-ts/orbit-controls": "^1.4.7",
        "@types/three": "^0.141.0",
        "babylonjs": "^5.13.3",
        "babylonjs-loaders": "^5.13.3",
        "cookie": "^0.4.1",
        "gsap": "^3.10.4",
        "three": "^0.142.0",
        "three-gltf-loader": "^1.111.0",
        "three-orbitcontrols": "^2.110.3",
        "three-orbitcontrols-ts": "^0.1.2"
      }
    }
    
    

    Am I doing something wrong?

    I'd really like to try this out - it just looks too good!

    Thanks

    opened by sommerper 5
  • heavy flicker in some scenes

    heavy flicker in some scenes

    for example: https://codesandbox.io/s/threejs-journey-level-1-forked-84he6c?file=/src/App.js

    btw, wonderful, wonderful project! thank you so much for open sourcing this!

    opened by drcmda 5
  • Unable to load module

    Unable to load module

    With three in the latest version (0.142.0) if I try to use @react-three/postprocessing I get an error:

    Error: Cannot find module '/xxx/node_modules/three/examples/jsm/capabilities/WebGL'

    Which I could track back to this package, it seems that your require statement isn't valid anymore.

    Is there a way to fix this? thanks

    opened by federicovezzoli 2
  • rollup, vite, prettier, husky

    rollup, vite, prettier, husky

    i left out typescript for now to keep it simple.

    1. to run the example:

      cd example npm install (once) npm run dev

    2. any change in ../src/* will hot reload.

    3. any staged file will run through prettier automatically with your original settings, i just set the print-width to 120chr. that's where the 62 changed files come from, it fixed format since some where tabs, some spaces, etc.

    4. build supports both esm and cjs, both should be declared properly in package.json

    ps. the vercel deployment just needs to target /example now, it will be able to build and update it automatically on every change to the repo.

    opened by drcmda 2
  • Prevent infinite loop when disposing the EffectComposer

    Prevent infinite loop when disposing the EffectComposer

    IMHO the real problem is not here, it's there instead : https://github.com/pmndrs/postprocessing/blob/877cda9c93aa3ed6106062e0010674c1641a56a7/src/passes/Pass.js#L371-L388

    It blindly calls the dispose method on all props of a Pass, which leads to unpredictable side effects like what I experienced... Basically, when an EffectComposer is disposed, it will dispose it's passes, but the SSRPass will call the dispose method of it's composer prop, which will dispose it's passes again, ...infinite loop ♾️

    So I removed those props in your passes to avoid the problem. 🤷🏼‍♂️ (they were not used anyway)

    btw thanks for this project, it looks promising ! 🙂

    opened by wmcmurray 2
  • Black screen with VanillaJS build

    Black screen with VanillaJS build

    Apart from issue #16, I also tried running the library in VanillaJS (both with r141 and r143). The result is a black screen.

    First, I installed both libraries (space-screen-reflections and postprocessing) with npm. Then, I copied the corresponding javascript files into my js folder and linked them with the existing project. After adding the SSR effect pass and running it through the composer, I get a black screen and the following error: [.WebGL-0x1d8002a0d500] GL_INVALID_OPERATION: Active draw buffers with missing fragment shader outputs.

    Not sure if this is my inability of linking the code together or some deeper issue, but I would be grateful if you could give some pointers. Thanks!

    UPDATE: if I replace POSTPROCESSING.EffectComposer with regular EffectComposer, I get a red screen instead of a black one. (The error console looks the same as before, though). This looks similar to an issue already mentioned here.

    opened by lukacupic 1
  • WARNING: Multiple instances of Three.js being imported.

    WARNING: Multiple instances of Three.js being imported.

    i'm getting this console log WARNING: Multiple instances of Three.js being imported.

    these two should be peerDependencies, by depending on them the bundler will include two bundles for threejs.

    	"dependencies": {
    		"postprocessing": "^6.28.0",
    		"three": "^0.141.0"
    	},
    
    opened by drcmda 1
  • Selection is not working for me

    Selection is not working for me

    Hi, i'm having this issue. I set the selection of my pass, but ssr is applied in all scene. Maybe i'm writing something wrong:

    const sel = new POSTPROCESSING.Selection(ssrSelections)
    ssrEffect.selection.set(sel)
    

    Where ssrSelections is an array of meshes. Someone can help me, thank you!

    opened by GrikFreak 0
  • Can you provide more examples

    Can you provide more examples

    Can you provide more examples? I would like to learn how to use this library to develop more shocking effects, so far I can only see one example and it's cool, but if there are more examples I think I can better understand how to use it,thanks

    opened by aile1997 0
  • InstancedMesh

    InstancedMesh

    screen-space-reflections does not work well with InstancedMesh. Its like its not updating.

    My results (with instanced mesh) image

    Expectations (Without instanced mesh) image

    opened by Cevered 0
  • Noise in the background

    Noise in the background

    Hello !

    I've found a bug that I can't solve.

    When I use codesandbox.io, the SSR pass works fine like on this fork : https://codesandbox.io/s/envmap-ground-projection-forked-ie35kf

    But when I download it and run it locally, a white veil appears on top of the rendering and noise appears in the background like this screenshot image

    Have you any idea what could do this ?

    I use the same package.json than in the sandbox so with the same version for all packages.

    I got the problem with the vanilla THREEJS and react three fiber version.

    GPU is AMD Radeon RX 580.

    Otherwise this SSR is amazing, it runs smoothly in the web.

    Congratulations to everyone who worked on it.

    Have a good day !

    opened by Lipacinp 0
Owner
0bqz
web development. graphics. ui | ux
0bqz
Space Travelers' Hub - a web application that facilitates booking rockets and join selected space missions

This is a web application that facilitates booking rockets and join selected space missions. It is built for a company that offers both commercial and scientific space travel services. The application also works with real live data from the SpaceX API.

Mong'are 6 Mar 29, 2022
"Space-Travelers-Hub" is a website that allows users to book rockets and join selected space missions by using data from the SpaceX API.

Space-Travelers-Hub This project was bootstrapped with Create React App. Description "Space-Travelers-Hub" is a website that allows users to book rock

Tresor Sawasawa 4 Mar 13, 2022
A web application for a company that provides commercial and scientific space travel services. The application will allow users to book rockets and join selected space missions.

Space Travelers A web application for a company that provides commercial and scientific space travel services. The application will allow users to boo

Hector Torres 2 Apr 6, 2022
Welcome to Space Traveler's HUB, this web app allows the user to take a fictional tour across the space.

Welcome to Space Traveler's HUB, this web app allows the user to take a fictional tour across the space. The user can choose a rocket from our catalog interface, and reserve it. Also, the user can see recent special missions and join them. Finally, the user will be able to keep track of all your rockets and mission they are subscribed to. Build with React, Redux, React-router, and Railwindcss.

Mihreteab Misganaw 3 Jan 27, 2022
This web application provides commercial and scientific space travel services. The application allows users to book rockets and join selected space missions.

space-hub About Project "Space Traveler's Hub" is A web application that provides commercial and scientific space travelling services, We are working

Nicholas Emmanuel 7 Nov 2, 2022
This a web application for a company that provides commercial and scientific space travel services. The application will allow users to book rockets, dragons and join selected space missions.

Space Travelers' Hub In this project, we have worked with the real live data from the SpaceX API. Our task was to build a web application for a compan

Apuabi Titilope 4 Oct 31, 2022
In this project we built a web application that consumes an SpaceX API. It provides commercial and scientific space travel services that allows users to book rockets and join selected space missions.

Space Travelers' Hub In this project we built a web application that consumes an SpaceX API. It provides commercial and scientific space travel servic

Diego Yon 7 Sep 30, 2022
This web application provides commercial and scientific space travel services. The application allows users to book rockets and join selected space missions.

Space Traveler's Hub This web application provides commercial and scientific space travel services. The application allows users to book rockets and j

Michael Mesfin 6 Oct 4, 2022
three.js examples. if you are first in learning three.js , this will give you much help.

three-projected-material Three.js Material which lets you do Texture Projection on a 3d Model. Installation After having installed three.js, install i

null 22 Nov 2, 2022
Text Engraving & Extrusion demo based on Three.js is implemented with Typescript and webpack5. Used THREE-CSGMesh as the core tech to achieve engraving and extrusion results

Text Engraving & Extrusion Text Engraving & Extrusion demo is implemented using Three.js, with Typescript and webpack5. Used THREE-CSGMesh as the core

Jiahong Li 3 Oct 12, 2022
A starter next.js + solidity project that implements merkle trees

Create Merkle App By Backseats This is an example app that shows you how to use a Merkle tree for your allow list Includes a partial contract contract

null 6 Nov 6, 2022
A script that implements a GUI to make cheating on Blooket easier than ever.

BlooketUI What's BlooketUI? A script that implements a GUI to make cheating on Blooket easier than ever. How do i Use This? Copy the code of src.js by

null 66 Dec 24, 2022
Implements live reload functionality to Adobe extension development.

Adobe Live Reload Adobe Live Reload implements live reload functionality to Adobe extension development. Features Reload Adobe Extensions on file save

Duncan Lutz 4 Apr 24, 2022
Userland module that implements the module path mapping that Node.js does with "exports" in package.json

exports-map Userland module that implements the module path mapping that Node.js does with "exports" in package.json npm install exports-map Usage co

Mathias Buus 9 May 31, 2022
Project implements decorators for oak like Nest.js.

oak decorators Project implements decorators like implementation of Nest.js for Deno's web framework oak. Usage The following are the core files that

akihiro tanaka 5 Dec 5, 2022
A sample code that implements a simple Web app using AWS CDK v2

A sample code that implements a simple Web app using AWS CDK v2. This code will be introduced in a live coding session at AWS Summit Online Japan 2022 Developer Zone in 2022/5/25.

AWS Samples 29 Dec 5, 2022
Domvas implements the missing piece that connects the DOM and Canvas.

Domvas Overview Domvas implements the missing piece that connects the DOM and Canvas. It gives to the ability to take arbitrary DOM content and paint

Paul Bakaus 389 Dec 29, 2022