Home Reference Source Repository

js/SceneKit/SCNCamera.js

  1. 'use strict'
  2.  
  3. import NSObject from '../ObjectiveC/NSObject'
  4. //import SCNAnimatable from './SCNAnimatable'
  5. import SCNCameraProjectionDirection from './SCNCameraProjectionDirection'
  6. //import SCNTechniqueSupport from './SCNTechniqueSupport'
  7. import SCNMaterialProperty from './SCNMaterialProperty'
  8. import SCNMatrix4 from './SCNMatrix4'
  9.  
  10.  
  11. /**
  12. * A set of camera attributes that can be attached to a node to provide a point of view for displaying the scene.
  13. * @access public
  14. * @extends {NSObject}
  15. * @implements {SCNAnimatable}
  16. * @implements {SCNTechniqueSupport}
  17. * @see https://developer.apple.com/documentation/scenekit/scncamera
  18. */
  19. export default class SCNCamera extends NSObject {
  20. static get _propTypes() {
  21. return {
  22. name: 'string',
  23. zNear: 'float',
  24. zFar: 'float',
  25. yFov: 'float',
  26. xFov: 'float',
  27. fov: ['float', null], // TODO: implement
  28. automaticallyAdjustsZRange: 'boolean',
  29. usesOrthographicProjection: 'boolean',
  30. orthographicScale: 'float',
  31. projectionDirection: 'integer',
  32. categoryBitMask: 'integer',
  33. focalDistance: 'float',
  34. focalSize: 'float',
  35. focalBlurRadius: 'float',
  36. aperture: 'float',
  37. motionBlurIntensity: 'float',
  38. wantsHDR: 'boolean',
  39. exposureOffset: 'float',
  40. averageGray: 'float',
  41. whitePoint: 'float',
  42. minimumExposure: 'float',
  43. maximumExposure: 'float',
  44. wantsExposureAdaptation: 'boolean',
  45. exposureAdaptationDarkeningSpeedFactor: 'float',
  46. exposureAdaptationBrighteningSpeedFactor: 'float',
  47. exposureAdaptationDuration: ['float', null],
  48. exposureAdaptationHistogramRangeHighProbability: ['float', null],
  49. exposureAdaptationHistogramRangeLowProbability: ['float', null],
  50. exposureAdaptationMode: ['integer', null],
  51. contrast: 'float',
  52. saturation: 'float',
  53. //_colorGrading: 'SCNMaterialProperty',
  54. bloomIntensity: 'float',
  55. bloomThreshold: 'float',
  56. bloomBlurRadius: 'float',
  57. colorFringeIntensity: 'float',
  58. colorFringeStrength: 'float',
  59. vignettingIntensity: 'float',
  60. vignettingPower: 'float',
  61. //projectionTransform: 'SCNMatrix4'
  62. bladeCount: ['integer', 'apertureBladeCount'],
  63. fStop: 'float',
  64. focalBlurSampleCount: 'integer',
  65. focusDistance: 'float',
  66. screenSpaceAmbientOcclusionBias: 'float',
  67. screenSpaceAmbientOcclusionDepthThreshold: 'float',
  68. screenSpaceAmbientOcclusionIntensity: 'float',
  69. screenSpaceAmbientOcclusionNormalThreshold: 'float',
  70. screenSpaceAmbientOcclusionRadius: 'float',
  71. sensorSize: ['float', 'sensorHeight'], // TODO: check if it is correct
  72.  
  73. entityID: ['string', '_entityID'],
  74. screenSpaceAmbientOcclusionSampleCount: ['integer', null],
  75. screenSpaceAmbientOcclusionDownSample: ['integer', null],
  76. dofIntensity: ['float', null],
  77. fillMode: ['integer', null]
  78. }
  79. }
  80.  
  81. /**
  82. * constructor
  83. * @access public
  84. * @returns {void}
  85. */
  86. constructor() {
  87. super()
  88.  
  89. // Managing Camera Attributes
  90.  
  91. /**
  92. * A name associated with the camera object.
  93. * @type {?string}
  94. * @see https://developer.apple.com/documentation/scenekit/scncamera/1436623-name
  95. */
  96. this.name = null
  97.  
  98.  
  99. // Adjusting Camera Perspective
  100.  
  101. /**
  102. * The camera's near depth limit. Animatable.
  103. * @type {number}
  104. * @see https://developer.apple.com/documentation/scenekit/scncamera/1436592-znear
  105. */
  106. this.zNear = 1.0
  107.  
  108. /**
  109. * The camera’s far depth limit. Animatable.
  110. * @type {number}
  111. * @see https://developer.apple.com/documentation/scenekit/scncamera/1436596-zfar
  112. */
  113. this.zFar = 100.0
  114.  
  115. /**
  116. * The camera’s field of view, in degrees, on the vertical axis. Animatable.
  117. * @type {number}
  118. * @see https://developer.apple.com/documentation/scenekit/scncamera/1436598-yfov
  119. */
  120. this.yFov = 0
  121.  
  122. /**
  123. * The camera's field of view, in degrees, on the horizontal axis. Animatable.
  124. * @type {number}
  125. * @see https://developer.apple.com/documentation/scenekit/scncamera/1436608-xfov
  126. */
  127. this.xFov = 0
  128.  
  129. /**
  130. * A Boolean value that determines whether the camera automatically adjusts its zNear and zFar depth limits.
  131. * @type {boolean}
  132. * @see https://developer.apple.com/documentation/scenekit/scncamera/1436610-automaticallyadjustszrange
  133. */
  134. this.automaticallyAdjustsZRange = false
  135.  
  136.  
  137. // Managing the Camera Projection
  138.  
  139. /**
  140. * A Boolean value that determines whether the camera uses an orthographic projection.
  141. * @type {boolean}
  142. * @see https://developer.apple.com/documentation/scenekit/scncamera/1436621-usesorthographicprojection
  143. */
  144. this.usesOrthographicProjection = false
  145.  
  146. /**
  147. * Specifies the camera’s magnification factor when using an orthographic projection.
  148. * @type {number}
  149. * @see https://developer.apple.com/documentation/scenekit/scncamera/1436612-orthographicscale
  150. */
  151. this.orthographicScale = 1.0
  152.  
  153.  
  154. /**
  155. *
  156. * @type {SCNCameraProjectionDirection}
  157. * @see
  158. */
  159. this.projectionDirection = SCNCameraProjectionDirection.horizontal
  160.  
  161.  
  162. // Choosing Nodes to Be Visible to the Camera
  163.  
  164. /**
  165. * A mask that defines which categories this camera belongs to.
  166. * @type {number}
  167. * @see https://developer.apple.com/documentation/scenekit/scncamera/1436625-categorybitmask
  168. */
  169. this.categoryBitMask = -1
  170.  
  171.  
  172. // Adding Depth of Field and Blur Effects
  173.  
  174. /**
  175. * The distance from the camera at which objects appear in sharp focus. Animatable.
  176. * @type {number}
  177. * @see https://developer.apple.com/documentation/scenekit/scncamera/1436600-focaldistance
  178. */
  179. this.focalDistance = 10.0
  180.  
  181. /**
  182. * The width of the distance range at which objects appear in sharp focus. Animatable.
  183. * @type {number}
  184. * @see https://developer.apple.com/documentation/scenekit/scncamera/1436604-focalsize
  185. */
  186. this.focalSize = 0.0
  187.  
  188. /**
  189. * The maximum amount of blurring, in pixels, applied to areas outside the camera’s depth of field. Animatable.
  190. * @type {number}
  191. * @see https://developer.apple.com/documentation/scenekit/scncamera/1436606-focalblurradius
  192. */
  193. this.focalBlurRadius = 0.0
  194.  
  195. /**
  196. * A factor that determines the transition between in-focus and out-of-focus areas. Animatable.
  197. * @type {number}
  198. * @see https://developer.apple.com/documentation/scenekit/scncamera/1436594-aperture
  199. */
  200. this.aperture = 0.125
  201.  
  202. /**
  203. * A factor that determines the intensity of motion blur effects. Animatable.
  204. * @type {number}
  205. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644099-motionblurintensity
  206. */
  207. this.motionBlurIntensity = 0.0
  208.  
  209.  
  210. // Adding High Dynamic Range Effects
  211.  
  212. /**
  213. * A Boolean value that determines whether SceneKit applies High Dynamic Range (HDR) postprocessing effects to a scene.
  214. * @type {boolean}
  215. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644101-wantshdr
  216. */
  217. this.wantsHDR = false
  218.  
  219. /**
  220. * A logarithmic bias that adjusts the results of SceneKit’s tone mapping operation, brightening or darkening the visible scene.
  221. * @type {number}
  222. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644105-exposureoffset
  223. */
  224. this.exposureOffset = 0
  225.  
  226. /**
  227. * The luminance level to use as the midpoint of a tone mapping curve.
  228. * @type {number}
  229. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644097-averagegray
  230. */
  231. this.averageGray = 0.18
  232.  
  233. /**
  234. * The luminance level to use as the upper end of a tone mapping curve.
  235. * @type {number}
  236. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644110-whitepoint
  237. */
  238. this.whitePoint = 1.0
  239.  
  240. /**
  241. * The minimum exposure value to use in tone mapping.
  242. * @type {number}
  243. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644103-minimumexposure
  244. */
  245. this.minimumExposure = -15.0
  246.  
  247. /**
  248. * The minimum exposure value to use in tone mapping.
  249. * @type {number}
  250. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644120-maximumexposure
  251. */
  252. this.maximumExposure = 15.0
  253.  
  254.  
  255. // Adding Automatic HDR Exposure Adaptation
  256.  
  257. /**
  258. * A Boolean value that determines whether SceneKit automatically adjusts the exposure level.
  259. * @type {boolean}
  260. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644117-wantsexposureadaptation
  261. */
  262. this.wantsExposureAdaptation = false
  263.  
  264. /**
  265. * The relative duration of automatically animated exposure transitions from dark to bright areas.
  266. * @type {number}
  267. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644093-exposureadaptationbrighteningspe
  268. */
  269. this.exposureAdaptationBrighteningSpeedFactor = 0.4
  270.  
  271. /**
  272. * The relative duration of automatically animated exposure transitions from bright to dark areas.
  273. * @type {number}
  274. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644094-exposureadaptationdarkeningspeed
  275. */
  276. this.exposureAdaptationDarkeningSpeedFactor = 0.6
  277.  
  278.  
  279. // Adjusting Rendered Colors
  280.  
  281. /**
  282. * An adjustment factor to apply to the overall visual contrast of the rendered scene.
  283. * @type {number}
  284. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644112-contrast
  285. */
  286. this.contrast = 0.0
  287.  
  288. /**
  289. * An adjustment factor to apply to the overall color saturation of the rendered scene.
  290. * @type {number}
  291. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644100-saturation
  292. */
  293. this.saturation = 1.0
  294.  
  295. this._colorGrading = new SCNMaterialProperty()
  296.  
  297. // Adding Stylistic Visual Effects
  298.  
  299. /**
  300. * The magnitude of bloom effect to apply to highlights in the rendered scene. Animatable.
  301. * @type {number}
  302. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644104-bloomintensity
  303. */
  304. this.bloomIntensity = 0.0
  305.  
  306. /**
  307. * The brightness threshold at which to apply a bloom effect to highlights in the rendered scene. Animatable.
  308. * @type {number}
  309. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644098-bloomthreshold
  310. */
  311. this.bloomThreshold = 0.5
  312.  
  313. /**
  314. * The radius, in pixels, for the blurring portion of the bloom effect applied to highlights in the rendered scene. Animatable.
  315. * @type {number}
  316. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644096-bloomblurradius
  317. */
  318. this.bloomBlurRadius = 4.0
  319.  
  320. /**
  321. * The blend factor for fading the color fringing effect applied to the rendered scene.
  322. * @type {number}
  323. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644108-colorfringeintensity
  324. */
  325. this.colorFringeIntensity = 1.0
  326.  
  327. /**
  328. * The magnitude of color fringing effect to apply to the rendered scene.
  329. * @type {number}
  330. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644113-colorfringestrength
  331. */
  332. this.colorFringeStrength = 0.0
  333.  
  334. /**
  335. * The magnitude of vignette (darkening around edges) effect to apply to the rendered scene.
  336. * @type {number}
  337. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644106-vignettingintensity
  338. */
  339. this.vignettingIntensity = 1.0
  340.  
  341. /**
  342. * The amount of the rendered scene to darken with a vignette effect.
  343. * @type {number}
  344. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644118-vignettingpower
  345. */
  346. this.vignettingPower = 0.0
  347.  
  348.  
  349. // Instance Properties
  350.  
  351. /**
  352. *
  353. * @type {SCNMatrix4}
  354. * @see https://developer.apple.com/documentation/scenekit/scncamera/1690501-projectiontransform
  355. */
  356. this.projectionTransform = null
  357.  
  358. /**
  359. * @access private
  360. * @type {?string}
  361. */
  362. this._entityID = null
  363.  
  364.  
  365. /**
  366. *
  367. * @type {number}
  368. * @see https://developer.apple.com/documentation/scenekit/scncamera/2867484-aperturebladecount
  369. */
  370. this.apertureBladeCount = 0 // TODO: check the default value
  371.  
  372. /**
  373. *
  374. * @type {number}
  375. * @see https://developer.apple.com/documentation/scenekit/scncamera/2867490-fstop
  376. */
  377. this.fStop = 0.0 // TODO: check the default value
  378.  
  379. /**
  380. *
  381. * @type {number}
  382. * @see https://developer.apple.com/documentation/scenekit/scncamera/2867510-fieldofview
  383. */
  384. this.fieldOfView = 0.0 // TODO: check the default value
  385.  
  386. /**
  387. *
  388. * @type {number}
  389. * @see https://developer.apple.com/documentation/scenekit/scncamera/2872999-focalblursamplecount
  390. */
  391. this.focalBlurSampleCount = 0 // TODO: check the default value
  392.  
  393. /**
  394. *
  395. * @type {number}
  396. * @see
  397. */
  398. this.focalLength = 0.0 // TODO:
  399.  
  400. /**
  401. *
  402. * @type {number}
  403. * @see
  404. */
  405. this.focalDistance = 0.0 // TODO:
  406.  
  407. /**
  408. *
  409. * @type {number}
  410. * @see
  411. */
  412. this.screenSpaceAmbientOcclusionBias = 0.0 // TODO:
  413.  
  414. /**
  415. *
  416. * @type {number}
  417. * @see
  418. */
  419. this.screenSpaceAmbientOcclusionDepthThreshold = 0.0 // TODO:
  420.  
  421. /**
  422. *
  423. * @type {number}
  424. * @see
  425. */
  426. this.screenSpaceAmbientOcclusionIntensity = 0.0 // TODO:
  427.  
  428. /**
  429. *
  430. * @type {number}
  431. * @see
  432. */
  433. this.screenSpaceAmbientOcclusionNormalThreshold = 0.0 // TODO:
  434.  
  435. /**
  436. *
  437. * @type {number}
  438. * @see
  439. */
  440. this.screenSpaceAmbientOcclusionRadius = 0.0 // TODO:
  441.  
  442. /**
  443. *
  444. * @type {number}
  445. * @see
  446. */
  447. this.sensorHeight = 0.0 // TODO:
  448.  
  449. /**
  450. *
  451. * @type {boolean}
  452. * @see
  453. */
  454. this.wantsDepthOfField = false // TODO:
  455. }
  456.  
  457. // Creating a Camera
  458.  
  459. /**
  460. * Creates a camera from the specified Model I/O camera object.
  461. * @access public
  462. * @param {MDLCamera} mdlCamera - A Model I/O camera object.
  463. * @returns {void}
  464. * @desc The Model I/O framework provides universal support for import, export, description, and processing of several 3D asset file formats and related resources. (For details, see Model I/O.) The MDLCamera class is a generic description of a viewpoint on a scene, supporting a superset of the attributes described by the SCNCamera class.
  465. * @see https://developer.apple.com/documentation/scenekit/scncamera/1419839-init
  466. */
  467. init(mdlCamera) {
  468. }
  469.  
  470. // Adjusting Rendered Colors
  471. /**
  472. * A texture for applying color grading effects to the entire rendered scene.
  473. * @type {SCNMaterialProperty}
  474. * @desc The contents value for this material property must be a 3D color lookup table, or a 2D texture image that represents such a table arranged in a horizontal strip. A lookup table is a cube of color values: the red, green, and blue components of an input color map to the x, y, and z coordinates of a location in that cube, and at that location in the cube is a corresponding output color. You can provide data in this cubic format as a Metal texture with the type3D texture type.The 2D representation of a 3D color cube is an arrangement of slices: for example, a 16 x 16 x 16 color cube becomes a horizontal strip of 16 squares, each 16 x 16 pixels (that is, a 256 x 16 image). Each square contains a gradation of red and green components, and together the 16 squares form a gradation for the blue component. To provide a 2D representation of a color cube, set this material property’s contents value to an image.By using a color table, you can easily create custom color effects that apply to an entire rendered scene:Create a basic color table image such as Figure 1, where the color value for each R, G, and B coordinate in the cube is the corresponding RGB color.Figure 1 Basic color table imageUse an image editor to create the color effect you want using some other image—such as a screenshot of your game. Apply only effects that affect pixel colors without modifying pixel positions. (For example, you can use hue/saturation, color curves, or color matrix filters, but not blur or distort filters.)Figure 2 Creating a color grading effectApply the same color effect you created in step 2 to your basic color table image. You can even perform these steps together: paste the basic color table into your game screenshot, apply an effect to the combined picture, then crop the picture to just the modified color table. Figure 2 shows an example effect.Assign your customized color table image (such as the example in Figure 3) to this property. When rendering, SceneKit looks up the RGB values for each pixel in the rendered scene, and displays the corresponding color values from the color table.Figure 3 Custom color table image for color gradingBasic color table imageCreating a color grading effectCustom color table image for color grading
  475. * @see https://developer.apple.com/documentation/scenekit/scncamera/1644114-colorgrading
  476. */
  477. get colorGrading() {
  478. return this._colorGrading
  479. }
  480.  
  481. /**
  482. * @access private
  483. * @param {CGRect} viewRect -
  484. * @returns {void}
  485. */
  486. _updateProjectionTransform(viewRect) {
  487. const m = new SCNMatrix4()
  488. const left = viewRect.minX
  489. const right = viewRect.maxX
  490. const top = viewRect.maxY
  491. const bottom = viewRect.minY
  492. const aspect = viewRect.size.width / viewRect.size.height
  493.  
  494. if(this.usesOrthographicProjection){
  495. //this.orthographicScale
  496. m.m11 = 2 / (right - left)
  497. m.m12 = 0
  498. m.m13 = 0
  499. m.m14 = 0
  500. m.m21 = 0
  501. m.m22 = 2 / (top - bottom)
  502. m.m23 = 0
  503. m.m24 = 0
  504. m.m31 = 0
  505. m.m32 = 0
  506. m.m33 = -2 / (this.zFar - this.zNear)
  507. m.m34 = 0
  508. m.m41 = -(right + left) / (right - left)
  509. m.m42 = -(top + bottom) / (top - bottom)
  510. m.m43 = -(this.zFar + this.zNear) / (this.zFar - this.zNear)
  511. m.m44 = 1
  512. }else{
  513. // perspective
  514. //this.yFov
  515. //this.xFov
  516. //this.automaticallyAdjustsZRange
  517. let m11 = 1
  518. let m22 = 1
  519. if(this.yFov <= 0 && this.xFov <= 0){
  520. const cot = 1.0 / Math.tan(Math.PI / 6.0)
  521. m11 = cot / aspect
  522. m22 = cot
  523. }else if(this.yFov <= 0){
  524. const cot = 1.0 / Math.tan(this.xFov * Math.PI / 360.0)
  525. m11 = cot
  526. m22 = cot * aspect
  527. }else if(this.xFov <= 0){
  528. const cot = 1.0 / Math.tan(this.yFov * Math.PI / 360.0)
  529. m11 = cot / aspect
  530. m22 = cot
  531. }else{
  532. // FIXME: compare xFov to yFov
  533. const cot = 1.0 / Math.tan(this.yFov * Math.PI / 360.0)
  534. m11 = cot / aspect
  535. m22 = cot
  536. }
  537.  
  538. m.m11 = m11
  539. m.m12 = 0
  540. m.m13 = 0
  541. m.m14 = 0
  542. m.m21 = 0
  543. m.m22 = m22
  544. m.m23 = 0
  545. m.m24 = 0
  546. m.m31 = 0
  547. m.m32 = 0
  548. m.m33 = -(this.zFar + this.zNear) / (this.zFar - this.zNear)
  549. m.m34 = -1
  550. m.m41 = 0
  551. m.m42 = 0
  552. m.m43 = -2 * this.zFar * this.zNear / (this.zFar - this.zNear)
  553. m.m44 = 0
  554. }
  555. this.projectionTransform = m
  556. }
  557. }