1+ // scene/demo-specific variables go here
2+ let boxGeometry , boxMaterial ;
3+ let boxMeshes = [ ] ;
4+ let boxGeometries = [ ] ;
5+
6+ let totalNumberOfShapes = 0 ;
7+ let sphereTestPosition = new THREE . Vector3 ( ) ;
8+ let testPoint = new THREE . Vector3 ( 4 , 0.2 , 0 ) ;
9+ let spherePositions = [ ] ;
10+ let choose_mat = 0 ;
11+ let tempColor = new THREE . Color ( ) ;
12+ let shape = new THREE . Object3D ( ) ;
13+ let invMatrix = new THREE . Matrix4 ( ) ;
14+ let el ; // elements of the invMatrix
15+ let shapeBoundingBox_minCorner = new THREE . Vector3 ( ) ;
16+ let shapeBoundingBox_maxCorner = new THREE . Vector3 ( ) ;
17+ let shapeBoundingBox_centroid = new THREE . Vector3 ( ) ;
18+ let shape_array ;
19+ let shapeDataTexture ;
20+ let aabb_array ;
21+ let aabbDataTexture ;
22+ let totalWorklist ;
23+
24+
25+
26+ // called automatically from within initTHREEjs() function (located in InitCommon.js file)
27+ function initSceneData ( )
28+ {
29+ demoFragmentShaderFileName = 'RayTracing_InOneWeekend_Fragment.glsl' ;
30+
31+ // scene/demo-specific three.js objects setup goes here
32+ sceneIsDynamic = false ;
33+
34+ cameraFlightSpeed = 10 ;
35+
36+ // pixelRatio is resolution - range: 0.5(half resolution) to 1.0(full resolution)
37+ pixelRatio = mouseControl ? 1.0 : 0.75 ;
38+
39+ EPS_intersect = 0.01 ;
40+
41+ // set camera's field of view
42+ worldCamera . fov = 25 ;
43+ apertureSize = 0.001 ;
44+ focusDistance = 10.0 ;
45+ apertureChangeSpeed = 0.005 ;
46+ focusDistanceChangeSpeed = 0.05 ;
47+
48+ // position and orient camera
49+ cameraControlsObject . position . set ( 13 , 2 , 3 ) ;
50+ // look left
51+ cameraControlsYawObject . rotation . y = 1.35 ;
52+ // look slightly downward
53+ cameraControlsPitchObject . rotation . x = - 0.13 ;
54+
55+
56+
57+
58+ shape_array = new Float32Array ( 2048 * 2048 * 4 ) ;
59+ // 2048 = width of texture, 2048 = height of texture, 4 = r,g,b, and a components
60+
61+ aabb_array = new Float32Array ( 2048 * 2048 * 4 ) ;
62+ // 2048 = width of texture, 2048 = height of texture, 4 = r,g,b, and a components
63+
64+
65+ for ( let a = - 11 ; a < 11 ; a ++ )
66+ {
67+ for ( let b = - 11 ; b < 11 ; b ++ )
68+ {
69+ sphereTestPosition . set ( a + ( 0.9 * Math . random ( ) ) , 0.2 , b + ( 0.9 * Math . random ( ) ) ) ;
70+
71+ if ( sphereTestPosition . distanceTo ( testPoint ) > 1.0 )
72+ {
73+ spherePositions . push ( new THREE . Vector3 ( ) . copy ( sphereTestPosition ) ) ;
74+ totalNumberOfShapes ++ ;
75+ }
76+ }
77+ }
78+
79+ console . log ( "Shape count: " + totalNumberOfShapes ) ;
80+ totalWorklist = new Uint32Array ( totalNumberOfShapes ) ;
81+
82+ boxMaterial = new THREE . MeshBasicMaterial ( ) ;
83+ let ix32 = 0 ;
84+ let ix9 = 0 ;
85+
86+ for ( let i = 0 ; i < totalNumberOfShapes ; i ++ )
87+ {
88+ ix32 = i * 32 ;
89+ ix9 = i * 9 ;
90+
91+ shape . position . copy ( spherePositions [ i ] ) ;
92+ shape . rotation . set ( 0 , 0 , 0 ) ;
93+ shape . scale . set ( 0.2 , 0.2 , 0.2 ) ;
94+
95+ shape . updateMatrixWorld ( true ) ; // 'true' forces immediate matrix update
96+
97+ invMatrix . copy ( shape . matrixWorld ) . invert ( ) ;
98+ el = invMatrix . elements ;
99+
100+ //slot 0 Shape transform Matrix 4x4 (16 elements total)
101+ shape_array [ ix32 + 0 ] = el [ 0 ] ; // r or x // shape transform Matrix element[0]
102+ shape_array [ ix32 + 1 ] = el [ 1 ] ; // g or y // shape transform Matrix element[1]
103+ shape_array [ ix32 + 2 ] = el [ 2 ] ; // b or z // shape transform Matrix element[2]
104+ shape_array [ ix32 + 3 ] = el [ 3 ] ; // a or w // shape transform Matrix element[3]
105+
106+ //slot 1
107+ shape_array [ ix32 + 4 ] = el [ 4 ] ; // r or x // shape transform Matrix element[4]
108+ shape_array [ ix32 + 5 ] = el [ 5 ] ; // g or y // shape transform Matrix element[5]
109+ shape_array [ ix32 + 6 ] = el [ 6 ] ; // b or z // shape transform Matrix element[6]
110+ shape_array [ ix32 + 7 ] = el [ 7 ] ; // a or w // shape transform Matrix element[7]
111+
112+ //slot 2
113+ shape_array [ ix32 + 8 ] = el [ 8 ] ; // r or x // shape transform Matrix element[8]
114+ shape_array [ ix32 + 9 ] = el [ 9 ] ; // g or y // shape transform Matrix element[9]
115+ shape_array [ ix32 + 10 ] = el [ 10 ] ; // b or z // shape transform Matrix element[10]
116+ shape_array [ ix32 + 11 ] = el [ 11 ] ; // a or w // shape transform Matrix element[11]
117+
118+ //slot 3
119+ shape_array [ ix32 + 12 ] = el [ 12 ] ; // r or x // shape transform Matrix element[12]
120+ shape_array [ ix32 + 13 ] = el [ 13 ] ; // g or y // shape transform Matrix element[13]
121+ shape_array [ ix32 + 14 ] = el [ 14 ] ; // b or z // shape transform Matrix element[14]
122+ shape_array [ ix32 + 15 ] = el [ 15 ] ; // a or w // shape transform Matrix element[15]
123+
124+ //slot 4
125+ shape_array [ ix32 + 16 ] = 1 ; // r or x // shape type id# (0: box, 1: sphere, 2: cylinder, 3: cone, 4: paraboloid, etc)
126+ //shape_array[ix32 + 17] = 1; // g or y // material type id# (0: LIGHT, 1: DIFF, 2: REFR, 3: SPEC, 4: COAT, etc)
127+ shape_array [ ix32 + 18 ] = 0.0 ; // b or z // material Metalness - default: 0.0(no metal, a dielectric), 1.0 would be purely metal
128+ shape_array [ ix32 + 19 ] = 0.0 ; // a or w // material Roughness - default: 0.0(no roughness, totally smooth)
129+
130+ choose_mat = Math . random ( ) ;
131+ if ( choose_mat < 0.8 )
132+ {
133+ shape_array [ ix32 + 17 ] = 1 ; // diffuse
134+ tempColor . set ( Math . random ( ) * Math . random ( ) , Math . random ( ) * Math . random ( ) , Math . random ( ) * Math . random ( ) ) ;
135+
136+ } else if ( choose_mat < 0.95 )
137+ {
138+ shape_array [ ix32 + 17 ] = 3 ; // metal
139+ shape_array [ ix32 + 19 ] = Math . random ( ) * 0.5 ; // pick a random roughness between 0.0 and 0.5
140+ tempColor . set ( ( Math . random ( ) * 0.5 ) + 0.5 , ( Math . random ( ) * 0.5 ) + 0.5 , ( Math . random ( ) * 0.5 ) + 0.5 ) ;
141+
142+ } else
143+ {
144+ shape_array [ ix32 + 17 ] = 2 ; // glass
145+ tempColor . set ( 1 , 1 , 1 ) ;
146+ }
147+
148+ //slot 5
149+ shape_array [ ix32 + 20 ] = tempColor . r ; // r or x // material albedo color R (if LIGHT, this is also its emissive color R)
150+ shape_array [ ix32 + 21 ] = tempColor . g ; // g or y // material albedo color G (if LIGHT, this is also its emissive color G)
151+ shape_array [ ix32 + 22 ] = tempColor . b ; // b or z // material albedo color B (if LIGHT, this is also its emissive color B)
152+ shape_array [ ix32 + 23 ] = 1.0 ; // a or w // material Opacity (Alpha) - default: 1.0 (fully opaque), 0.0 is fully transparent
153+
154+ //slot 6
155+ shape_array [ ix32 + 24 ] = 1.0 ; // r or x // material Index of Refraction(IoR) - default: 1.0(air) (or 1.5(glass), 1.33(water), etc)
156+ shape_array [ ix32 + 25 ] = 0.0 ; // g or y // material ClearCoat Roughness - default: 0.0 (no roughness, totally smooth)
157+ shape_array [ ix32 + 26 ] = 1.5 ; // b or z // material ClearCoat IoR - default: 1.5(thick ClearCoat)
158+ shape_array [ ix32 + 27 ] = 0 ; // a or w // material data
159+
160+ //slot 7
161+ shape_array [ ix32 + 28 ] = 0 ; // r or x // material data
162+ shape_array [ ix32 + 29 ] = 0 ; // g or y // material data
163+ shape_array [ ix32 + 30 ] = 0 ; // b or z // material data
164+ shape_array [ ix32 + 31 ] = 0 ; // a or w // material data
165+
166+ // if this shape is a Box, use THREE.BoxGeometry as starting point for this shape's AABB
167+ //if (shape_array[ix32 + 16] == 0)
168+ boxGeometries [ i ] = new THREE . BoxGeometry ( 2 , 2 , 2 ) ;
169+ //else // else use THREE.SphereGeometry, as it produces a tighter-fitting AABB when shape is rotated
170+ // boxGeometries[i] = new THREE.SphereGeometry(1.4);
171+
172+ boxMeshes [ i ] = new THREE . Mesh ( boxGeometries [ i ] , boxMaterial ) ;
173+
174+ boxMeshes [ i ] . geometry . applyMatrix4 ( shape . matrixWorld ) ;
175+ boxMeshes [ i ] . geometry . computeBoundingBox ( ) ;
176+
177+ shapeBoundingBox_minCorner . copy ( boxMeshes [ i ] . geometry . boundingBox . min ) ;
178+ shapeBoundingBox_maxCorner . copy ( boxMeshes [ i ] . geometry . boundingBox . max ) ;
179+ boxMeshes [ i ] . geometry . boundingBox . getCenter ( shapeBoundingBox_centroid ) ;
180+
181+
182+ aabb_array [ ix9 + 0 ] = shapeBoundingBox_minCorner . x ;
183+ aabb_array [ ix9 + 1 ] = shapeBoundingBox_minCorner . y ;
184+ aabb_array [ ix9 + 2 ] = shapeBoundingBox_minCorner . z ;
185+ aabb_array [ ix9 + 3 ] = shapeBoundingBox_maxCorner . x ;
186+ aabb_array [ ix9 + 4 ] = shapeBoundingBox_maxCorner . y ;
187+ aabb_array [ ix9 + 5 ] = shapeBoundingBox_maxCorner . z ;
188+ aabb_array [ ix9 + 6 ] = shapeBoundingBox_centroid . x ;
189+ aabb_array [ ix9 + 7 ] = shapeBoundingBox_centroid . y ;
190+ aabb_array [ ix9 + 8 ] = shapeBoundingBox_centroid . z ;
191+
192+ totalWorklist [ i ] = i ;
193+ } // end for (let i = 0; i < totalNumberOfShapes; i++)
194+
195+
196+ for ( let i = 0 ; i < totalNumberOfShapes * 2 ; i ++ )
197+ buildnodes [ i ] = new BVH_Node ( ) ;
198+
199+ console . log ( "BvhGeneration..." ) ;
200+ console . time ( "BvhGeneration" ) ;
201+
202+ BVH_QuickBuild ( totalWorklist , aabb_array ) ;
203+
204+ console . timeEnd ( "BvhGeneration" ) ;
205+
206+
207+ shapeDataTexture = new THREE . DataTexture ( shape_array ,
208+ 2048 ,
209+ 2048 ,
210+ THREE . RGBAFormat ,
211+ THREE . FloatType ,
212+ THREE . Texture . DEFAULT_MAPPING ,
213+ THREE . ClampToEdgeWrapping ,
214+ THREE . ClampToEdgeWrapping ,
215+ THREE . NearestFilter ,
216+ THREE . NearestFilter ,
217+ 1 ,
218+ THREE . NoColorSpace ) ;
219+
220+ shapeDataTexture . flipY = false ;
221+ shapeDataTexture . generateMipmaps = false ;
222+ shapeDataTexture . needsUpdate = true ;
223+
224+ aabbDataTexture = new THREE . DataTexture ( aabb_array ,
225+ 2048 ,
226+ 2048 ,
227+ THREE . RGBAFormat ,
228+ THREE . FloatType ,
229+ THREE . Texture . DEFAULT_MAPPING ,
230+ THREE . ClampToEdgeWrapping ,
231+ THREE . ClampToEdgeWrapping ,
232+ THREE . NearestFilter ,
233+ THREE . NearestFilter ,
234+ 1 ,
235+ THREE . NoColorSpace ) ;
236+
237+ aabbDataTexture . flipY = false ;
238+ aabbDataTexture . generateMipmaps = false ;
239+ aabbDataTexture . needsUpdate = true ;
240+
241+
242+ // In addition to the default GUI on all demos, add any special GUI elements that this particular demo requires
243+
244+
245+ // scene/demo-specific uniforms go here
246+ pathTracingUniforms . tShape_DataTexture = { value : shapeDataTexture } ;
247+ pathTracingUniforms . tAABB_DataTexture = { value : aabbDataTexture } ;
248+
249+
250+ } // end function initSceneData()
251+
252+
253+
254+ // called automatically from within the animate() function (located in InitCommon.js file)
255+ function updateVariablesAndUniforms ( )
256+ {
257+ pathTracingUniforms . uFocusDistance . value = focusDistance ;
258+
259+ // INFO
260+ cameraInfoElement . innerHTML = "FOV: " + worldCamera . fov + " / Aperture: " + apertureSize . toFixed ( 3 ) + " / FocusDistance: " + focusDistance . toFixed ( 1 ) + "<br>" + "Samples: " + sampleCounter ;
261+
262+ } // end function updateVariablesAndUniforms()
263+
264+
265+
266+ init ( ) ; // init app and start animating
0 commit comments