1
1
import {
2
2
AgXToneMapping ,
3
- PerspectiveCamera ,
4
- Scene ,
5
3
Box3 ,
6
- Mesh ,
7
- CylinderGeometry ,
8
- MeshPhysicalMaterial ,
4
+ Scene ,
5
+ Vector3 ,
9
6
WebGLRenderer ,
10
- EquirectangularReflectionMapping ,
11
- Color ,
12
7
} from 'three' ;
13
- import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js' ;
14
8
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' ;
15
9
import { WebGLPathTracer } from '../src/index.js' ;
16
- import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js' ;
17
- import { MeshoptDecoder } from 'three/examples/jsm/libs/meshopt_decoder.module.js' ;
18
10
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js' ;
19
11
import { LoaderElement } from './utils/LoaderElement.js' ;
20
12
import { getScaledSettings } from './utils/getScaledSettings.js' ;
13
+ import { MaterialOrbSceneLoader } from './utils/MaterialOrbLoader.js' ;
14
+ import { RectAreaLightUniformsLib } from 'three/examples/jsm/lights/RectAreaLightUniformsLib.js' ;
21
15
22
- const MODEL_URL = 'https://raw.githubusercontent.com/gkjohnson/3d-demo-data/main/models/material-balls/material_ball_v2.glb' ;
23
- const ENV_URL = 'https://raw.githubusercontent.com/gkjohnson/3d-demo-data/master/hdri/autoshop_01_1k.hdr' ;
24
16
const DB_URL = 'https://api.physicallybased.info/materials' ;
25
17
const CREDITS = 'Materials courtesy of "physicallybased.info"' ;
26
18
@@ -41,6 +33,8 @@ init();
41
33
42
34
async function init ( ) {
43
35
36
+ RectAreaLightUniformsLib . init ( ) ;
37
+
44
38
loader = new LoaderElement ( ) ;
45
39
loader . attach ( document . body ) ;
46
40
@@ -49,84 +43,39 @@ async function init() {
49
43
// renderer
50
44
renderer = new WebGLRenderer ( { antialias : true } ) ;
51
45
renderer . toneMapping = AgXToneMapping ;
46
+ renderer . toneMappingExposure = 0.02 ;
52
47
document . body . appendChild ( renderer . domElement ) ;
53
48
54
49
// path tracer
55
50
pathTracer = new WebGLPathTracer ( renderer ) ;
56
51
pathTracer . multipleImportanceSampling = params . multipleImportanceSampling ;
57
52
pathTracer . tiles . set ( params . tiles , params . tiles ) ;
53
+ pathTracer . textureSize . set ( 2048 , 2048 ) ;
58
54
pathTracer . filterGlossyFactor = 0.5 ;
59
55
60
- // camera
61
- const aspect = window . innerWidth / window . innerHeight ;
62
- camera = new PerspectiveCamera ( 75 , aspect , 0.025 , 500 ) ;
63
- camera . position . set ( - 4 , 2 , 3 ) ;
64
-
65
- // controls
66
- controls = new OrbitControls ( camera , renderer . domElement ) ;
67
- controls . addEventListener ( 'change' , ( ) => pathTracer . updateCamera ( ) ) ;
68
-
69
56
// scene
70
57
scene = new Scene ( ) ;
71
58
72
59
// load assets
73
- const [ envTexture , gltf , dbJson ] = await Promise . all ( [
74
- new RGBELoader ( ) . loadAsync ( ENV_URL ) ,
75
- new GLTFLoader ( ) . setMeshoptDecoder ( MeshoptDecoder ) . loadAsync ( MODEL_URL ) ,
60
+ const [ orb , dbJson ] = await Promise . all ( [
61
+ new MaterialOrbSceneLoader ( ) . loadAsync ( ) ,
76
62
fetch ( DB_URL ) . then ( res => res . json ( ) ) ,
77
63
] ) ;
78
64
79
- // background
80
- envTexture . mapping = EquirectangularReflectionMapping ;
81
- scene . background = envTexture ;
82
- scene . environment = envTexture ;
83
-
84
65
// scene initialization
85
- gltf . scene . scale . setScalar ( 0.01 ) ;
86
- gltf . scene . updateMatrixWorld ( ) ;
87
- scene . add ( gltf . scene ) ;
88
-
89
- const box = new Box3 ( ) ;
90
- box . setFromObject ( gltf . scene ) ;
91
-
92
- const floor = new Mesh (
93
- new CylinderGeometry ( 3 , 3 , 0.05 , 200 ) ,
94
- new MeshPhysicalMaterial ( { color : 0xffffff , roughness : 0 , metalness : 0.25 } ) ,
95
- ) ;
96
- floor . geometry = floor . geometry . toNonIndexed ( ) ;
97
- floor . geometry . clearGroups ( ) ;
98
- floor . position . y = box . min . y - 0.03 ;
99
- scene . add ( floor ) ;
100
-
101
- shellMaterial = new MeshPhysicalMaterial ( ) ;
102
- const coreMaterial = new MeshPhysicalMaterial ( { color : new Color ( 0.5 , 0.5 , 0.5 ) } ) ;
103
- gltf . scene . traverse ( c => {
104
-
105
- // the vertex normals on the material ball are off...
106
- // TODO: precompute the vertex normals so they are correct on load
107
- if ( c . geometry ) {
66
+ scene . add ( orb . scene ) ;
67
+ camera = orb . camera ;
68
+ shellMaterial = orb . material ;
108
69
109
- c . geometry . computeVertexNormals ( ) ;
70
+ scene . attach ( camera ) ;
71
+ camera . removeFromParent ( ) ;
72
+ camera . updateMatrixWorld ( ) ;
110
73
111
- }
112
-
113
- if ( c . name === 'Sphere_1' ) {
114
-
115
- c . material = coreMaterial ;
116
-
117
- } else {
118
-
119
- c . material = shellMaterial ;
120
-
121
- }
122
-
123
- if ( c . name === 'subsphere_1' ) {
124
-
125
- c . material = coreMaterial ;
126
-
127
- }
128
-
129
- } ) ;
74
+ const fwd = new Vector3 ( 0 , 0 , - 1 ) . transformDirection ( camera . matrixWorld ) . normalize ( ) ;
75
+ controls = new OrbitControls ( camera , renderer . domElement ) ;
76
+ controls . addEventListener ( 'change' , ( ) => pathTracer . updateCamera ( ) ) ;
77
+ controls . target . copy ( camera . position ) . addScaledVector ( fwd , 25 ) ;
78
+ controls . update ( ) ;
130
79
131
80
// database set up
132
81
database = { } ;
@@ -201,7 +150,7 @@ function applyMaterialInfo( info, material ) {
201
150
if ( material . transmission ) {
202
151
203
152
if ( info . color ) material . attenuationColor . setRGB ( ...info . color ) ;
204
- material . attenuationDistance = 200 / info . density ;
153
+ material . attenuationDistance = 1000 / info . density ;
205
154
206
155
} else {
207
156
@@ -228,6 +177,7 @@ function animate() {
228
177
229
178
requestAnimationFrame ( animate ) ;
230
179
pathTracer . renderSample ( ) ;
180
+ // renderer.render( scene, camera );
231
181
loader . setSamples ( pathTracer . samples , pathTracer . isCompiling ) ;
232
182
233
183
}
0 commit comments