Skip to content

HDR support - environment and image based lighting. #72

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = {
loader: "awesome-typescript-loader",
},
{
test: /\.(glb|mtl|png|jpe?g|gif)$/,
test: /\.(glb|mtl|png|jpe?g|gif|hdr|exr)$/,
use: [
{
loader: "file-loader",
Expand Down
1,765 changes: 853 additions & 912 deletions package-lock.json

Large diffs are not rendered by default.

34 changes: 17 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,33 +47,33 @@
"lodash.debounce": "^4.0.8",
"moment": "^2.24.0",
"react-full-screen": "^0.2.4",
"styled-components": "^4.3.2"
"styled-components": "^4.4.1"
},
"devDependencies": {
"@babel/core": "^7.4.5",
"@babel/plugin-proposal-class-properties": "^7.4.4",
"@babel/preset-env": "^7.4.5",
"@babel/preset-react": "^7.0.0",
"@babel/preset-typescript": "^7.3.3",
"@babel/core": "^7.7.2",
"@babel/plugin-proposal-class-properties": "^7.7.0",
"@babel/preset-env": "^7.7.1",
"@babel/preset-react": "^7.7.0",
"@babel/preset-typescript": "^7.7.2",
"@material-ui/core": "^3.9.3",
"@material-ui/lab": "^3.0.0-alpha.30",
"@types/lodash.debounce": "^4.0.6",
"@types/node": "^12.0.0",
"@types/react": "^16.8.13",
"@types/styled-components": "^4.1.18",
"@types/node": "^12.12.7",
"@types/react": "^16.9.11",
"@types/styled-components": "^4.4.0",
"babel-loader": "^8.0.6",
"babel-plugin-dynamic-import-webpack": "^1.1.0",
"file-loader": "^3.0.1",
"fs-extra": "^7.0.1",
"lodash.camelcase": "^4.3.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"rimraf": "^2.6.3",
"react": "^16.11.0",
"react-dom": "^16.11.0",
"rimraf": "^2.7.1",
"three": "^0.108.0",
"tslint": "^5.16.0",
"tslint-react": "^4.0.0",
"typescript": "^3.4.3",
"webpack": "^4.32.2",
"webpack-cli": "^3.3.1"
"tslint": "^5.20.1",
"tslint-react": "^4.1.0",
"typescript": "^3.7.2",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10"
}
}
6 changes: 4 additions & 2 deletions src/builders/GameBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LoadingManager } from "three"
import { LoadingManager, WebGLRenderer } from "three"

import CameraManager from "../managers/CameraManager"
import DataManager from "../managers/DataManager"
Expand Down Expand Up @@ -28,14 +28,16 @@ const defaultGameBuilder = async ({
const isOrangeTeam = colors[index]
return { name, isOrangeTeam }
})
const sceneManager = await defaultSceneBuilder(players, loadingManager)
const renderer = new WebGLRenderer({ antialias: true })
const sceneManager = await defaultSceneBuilder(players, renderer, loadingManager)
defaultAnimationBuilder(replayData, sceneManager.players, sceneManager.ball)
DataManager.init({ replayData, replayMetadata })
CameraManager.init()
KeyManager.init()

return GameManager.init({
clock,
renderer
})
}

Expand Down
12 changes: 11 additions & 1 deletion src/builders/SceneBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { LoadingManager, Scene } from "three"
import { LoadingManager, Scene, WebGLRenderer, Mesh, MeshStandardMaterial } from "three"

import GameFieldAssets from "../loaders/scenes/GameFieldAssets"
import SceneManager from "../managers/SceneManager"
import { buildBall } from "./ball/buildBall"
import { buildPlayfield } from "./field/buildPlayfield"
import { buildCarGroup } from "./player/buildCarGroup"
import { addLighting } from "./scene/addLighting"
import { addEnvironment } from "./scene/addEnvironment"

interface Player {
name: string
Expand All @@ -20,6 +21,7 @@ interface Player {
*/
const defaultSceneBuilder = async (
playerInfo: Player[],
renderer: WebGLRenderer,
loadingManager?: LoadingManager
): Promise<SceneManager> => {
const scene = new Scene()
Expand All @@ -29,13 +31,21 @@ const defaultSceneBuilder = async (
}
await GameFieldAssets.load()

const envMap = addEnvironment(scene, renderer)
addLighting(scene)
const field = buildPlayfield(scene)
const players = playerInfo.map(({ name, isOrangeTeam }) =>
buildCarGroup(scene, { playerName: name, isOrangeTeam })
)
const ball = buildBall(scene)

// TODO ?
scene.traverse( child => {
if ( (<Mesh> child).isMesh ) {
(<MeshStandardMaterial> (<Mesh> child).material).envMap = envMap
}
})

return SceneManager.init({
scene,
ball,
Expand Down
29 changes: 29 additions & 0 deletions src/builders/scene/addEnvironment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Scene, WebGLRenderer } from "three"

import { PMREMGenerator } from "three/examples/jsm/pmrem/PMREMGenerator"
import { PMREMCubeUVPacker } from "three/examples/jsm/pmrem/PMREMCubeUVPacker"
import { EquirectangularToCubeGenerator } from "three/examples/jsm/loaders/EquirectangularToCubeGenerator"
import GameFieldAssets from "../../loaders/scenes/GameFieldAssets"

export const addEnvironment = (scene: Scene, renderer: WebGLRenderer) => {
const { environment } = GameFieldAssets.getAssets()

const cubeGenerator = new EquirectangularToCubeGenerator( environment, { resolution: 2048 } );
cubeGenerator.update( renderer );

// @ts-ignore
const pmremGenerator = new PMREMGenerator( cubeGenerator.renderTarget.texture );
pmremGenerator.update( renderer );

const pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );

// @ts-ignore
scene.background = cubeGenerator.renderTarget;

pmremGenerator.dispose();
pmremCubeUVPacker.dispose();

const envMap = pmremCubeUVPacker.CubeUVRenderTarget.texture;
return envMap
}
8 changes: 4 additions & 4 deletions src/builders/scene/addLighting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { AmbientLight, DirectionalLight, HemisphereLight, Scene } from "three"

export const addLighting = (scene: Scene) => {
// Ambient light provides uniform lighting to all objects in the scene
const ambientLight = new AmbientLight(0xffffff, 0.2)
scene.add(ambientLight)
// const ambientLight = new AmbientLight(0xffffff, 0.2)
// scene.add(ambientLight)

// Hemisphere light gives the cars their shine and color
const hemisphereLight = new HemisphereLight(0xffffbb, 0xffffff, 0.5)
scene.add(hemisphereLight)
// const hemisphereLight = new HemisphereLight(0xffffbb, 0xffffff, 0.5)
// scene.add(hemisphereLight)

// The directional light is purely responsible for casting shadows
const dirLight = new DirectionalLight(0xffffff, 1.5)
Expand Down
24 changes: 24 additions & 0 deletions src/loaders/operators/loadEXR.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { LoadingManager, DataTexture, FloatType } from "three"
import { EXRLoader } from "three/examples/jsm/loaders/EXRLoader"

export const loadEXR = (path: string, loadingManager?: LoadingManager) => {
return new Promise(
(
resolve: (exrTexture: DataTexture) => void,
reject: (err: Error | ErrorEvent) => void
) => {
const exrLoader = new EXRLoader(loadingManager)
exrLoader.setDataType( FloatType )
exrLoader.load(
path,
(exrTexture: DataTexture) => {
resolve(exrTexture)
},
undefined,
(error: Error | ErrorEvent) => {
reject(error)
}
)
}
)
}
24 changes: 24 additions & 0 deletions src/loaders/operators/loadRGBE.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { LoadingManager, DataTexture, UnsignedByteType } from "three"
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader"

export const loadRGBE = (path: string, loadingManager?: LoadingManager) => {
return new Promise(
(
resolve: (rgbeTexture: DataTexture) => void,
reject: (err: Error | ErrorEvent) => void
) => {
const rgbeLoader = new RGBELoader(loadingManager)
rgbeLoader.setDataType( UnsignedByteType )
rgbeLoader.load(
path,
(rgbeTexture: DataTexture) => {
resolve(rgbeTexture)
},
undefined,
(error: Error | ErrorEvent) => {
reject(error)
}
)
}
)
}
8 changes: 6 additions & 2 deletions src/loaders/scenes/GameFieldAssets.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Group, LoadingManager, Object3D } from "three"
import { Group, LoadingManager, Object3D, DataTexture } from "three"

import { loadBall } from "../storage/loadBall"
import { loadBlueCar, loadOrangeCar, loadWheel } from "../storage/loadCar"
import { loadField } from "../storage/loadField"
import { loadEnvironment } from "../storage/loadEnvironment"

interface AvailableAssets {
ball: Object3D
Expand All @@ -11,6 +12,7 @@ interface AvailableAssets {
orangeCar: Group
blueCar: Group
wheel: Object3D
environment: DataTexture
}

class GameFieldAssets {
Expand All @@ -29,13 +31,15 @@ class GameFieldAssets {
loadOrangeCar(lm),
loadBlueCar(lm),
loadWheel(lm),
]).then(([ball, field, orangeCar, blueCar, wheel]) => {
loadEnvironment(lm)
]).then(([ball, field, orangeCar, blueCar, wheel, environment]) => {
this.assets = {
ball,
field,
orangeCar,
blueCar,
wheel,
environment
}
})
}
Expand Down
15 changes: 15 additions & 0 deletions src/loaders/storage/loadEnvironment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { LoadingManager, DataTexture } from "three"

import { loadRGBE } from "../operators/loadRGBE"
// import { loadEXR } from "../operators/loadEXR"
import { storageMemoize } from "./storageMemoize"

export const loadEnvironment = (loadingManager?: LoadingManager) =>
storageMemoize(async () => {
const { default: hdr } = await import(
// @ts-ignore
/* webpackChunkName: "Environment" */ "../../assets/models/textures/Environment/Environment.hdr"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has this made it into SharedAssets yet?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I haven't finished final render yet, current environment texture is a testrender I made.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is okay to put the test render in. It is honestly high quality enough for temporary use.

@Abbondanzo is there a way to flag the render under beta?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a way to flag the render under beta?

Not entirely, but we can flag the version number in package.json as 0.7.0b or something of that nature. Publishing only happens once we cut releases in this repo

)
const environmentTexture = await loadRGBE(hdr, loadingManager)
return environmentTexture as DataTexture
}, "ENVIRONMENT")
9 changes: 5 additions & 4 deletions src/managers/GameManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,16 @@ import KeyManager from "./KeyManager"
import SceneManager from "./SceneManager"

interface GameManagerOptions {
clock: FPSClock
clock: FPSClock,
renderer: WebGLRenderer
}

export class GameManager {
clock: FPSClock
private readonly renderer: WebGLRenderer
renderer: WebGLRenderer

private constructor({ clock }: GameManagerOptions) {
this.renderer = new WebGLRenderer({ antialias: true })
private constructor({ clock, renderer }: GameManagerOptions) {
this.renderer = renderer
this.renderer.shadowMap.enabled = true
this.animate = this.animate.bind(this)
this.render = this.render.bind(this)
Expand Down
4 changes: 4 additions & 0 deletions src/types/exr.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module "*.exr" {
const value: string
export default value
}
4 changes: 4 additions & 0 deletions src/types/hdr.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module "*.hdr" {
const value: string
export default value
}
2 changes: 1 addition & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ module.exports = {
},
},
{
test: /\.(glb|mtl)$/,
test: /\.(glb|mtl|hdr|exr)$/,
use: [
{
loader: "file-loader",
Expand Down