/home/lindsay/xeolabs/xeogl-next/xeogl/src/materials/phongMaterial.js
API Docs for:

File: /home/lindsay/xeolabs/xeogl-next/xeogl/src/materials/phongMaterial.js

  1. /**
  2. A **PhongMaterial** is a {{#crossLink "Material"}}{{/crossLink}} that defines the surface appearance of
  3. attached {{#crossLink "Mesh"}}Meshes{{/crossLink}} using
  4. the classic <a href="https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model">Blinn-Phong</a> lighting model.
  5.  
  6. ## Examples
  7.  
  8. | <a href="../../examples/#materials_phong_textures"><img src="../../assets/images/screenshots/PhongMaterial/textures.png"></img></a> | <a href="../../examples/#materials_phong_textures_video"><img src="../../assets/images/screenshots/PhongMaterial/videoTexture.png"></img></a> | <a href="../../examples/#materials_phong_fresnel"><img src="../../assets/images/screenshots/PhongMaterial/fresnel.png"></img></a> |
  9. |:------:|:----:|:-----:|:-----:|
  10. |[Phong textures](../../examples/#materials_phong_textures)|[Video texture](../../examples/#materials_phong_textures_video)| [Fresnels](../../examples/#materials_phong_fresnel)|
  11.  
  12. ## Overview
  13.  
  14. * Used for rendering non-realistic objects such as "helpers", wireframe objects, labels etc.
  15. * Use the physically-based {{#crossLink "MetallicMaterial"}}{{/crossLink}} or {{#crossLink "SpecularMaterial"}}{{/crossLink}} when more realism is required.
  16.  
  17. The following table summarizes PhongMaterial properties:
  18.  
  19. | Property | Type | Range | Default Value | Space | Description |
  20. |:--------:|:----:|:-----:|:-------------:|:-----:|:-----------:|
  21. | {{#crossLink "PhongMaterial/ambient:property"}}{{/crossLink}} | Array | [0, 1] for all components | [1,1,1,1] | linear | The RGB components of the ambient light reflected by the material. |
  22. | {{#crossLink "PhongMaterial/diffuse:property"}}{{/crossLink}} | Array | [0, 1] for all components | [1,1,1,1] | linear | The RGB components of the diffuse light reflected by the material. |
  23. | {{#crossLink "PhongMaterial/specular:property"}}{{/crossLink}} | Array | [0, 1] for all components | [1,1,1,1] | linear | The RGB components of the specular light reflected by the material. |
  24. | {{#crossLink "PhongMaterial/emissive:property"}}{{/crossLink}} | Array | [0, 1] for all components | [0,0,0] | linear | The RGB components of the light emitted by the material. |
  25. | {{#crossLink "PhongMaterial/alpha:property"}}{{/crossLink}} | Number | [0, 1] | 1 | linear | The transparency of the material surface (0 fully transparent, 1 fully opaque). |
  26. | {{#crossLink "PhongMaterial/shininess:property"}}{{/crossLink}} | Number | [0, 128] | 80 | linear | Determines the size and sharpness of specular highlights. |
  27. | {{#crossLink "PhongMaterial/reflectivity:property"}}{{/crossLink}} | Number | [0, 1] | 1 | linear | Determines the amount of reflectivity. |
  28. | {{#crossLink "PhongMaterial/diffuseMap:property"}}{{/crossLink}} | {{#crossLink "Texture"}}{{/crossLink}} | | null | sRGB | Texture RGB components multiplying by {{#crossLink "PhongMaterial/diffuse:property"}}{{/crossLink}}. If the fourth component (A) is present, it multiplies by {{#crossLink "PhongMaterial/alpha:property"}}{{/crossLink}}. |
  29. | {{#crossLink "PhongMaterial/specularMap:property"}}{{/crossLink}} | {{#crossLink "Texture"}}{{/crossLink}} | | null | sRGB | Texture RGB components multiplying by {{#crossLink "PhongMaterial/specular:property"}}{{/crossLink}}. If the fourth component (A) is present, it multiplies by {{#crossLink "PhongMaterial/alpha:property"}}{{/crossLink}}. |
  30. | {{#crossLink "PhongMaterial/emissiveMap:property"}}{{/crossLink}} | {{#crossLink "Texture"}}{{/crossLink}} | | null | linear | Texture with RGB components multiplying by {{#crossLink "PhongMaterial/emissive:property"}}{{/crossLink}}. |
  31. | {{#crossLink "PhongMaterial/alphaMap:property"}}{{/crossLink}} | {{#crossLink "Texture"}}{{/crossLink}} | | null | linear | Texture with first component multiplying by {{#crossLink "PhongMaterial/alpha:property"}}{{/crossLink}}. |
  32. | {{#crossLink "PhongMaterial/occlusionMap:property"}}{{/crossLink}} | {{#crossLink "Texture"}}{{/crossLink}} | | null | linear | Ambient occlusion texture multiplying by {{#crossLink "PhongMaterial/ambient:property"}}{{/crossLink}}, {{#crossLink "PhongMaterial/diffuse:property"}}{{/crossLink}} and {{#crossLink "PhongMaterial/specular:property"}}{{/crossLink}}. |
  33. | {{#crossLink "PhongMaterial/normalMap:property"}}{{/crossLink}} | {{#crossLink "Texture"}}{{/crossLink}} | | null | linear | Tangent-space normal map. |
  34. | {{#crossLink "PhongMaterial/diffuseFresnel:property"}}{{/crossLink}} | {{#crossLink "Fresnel"}}{{/crossLink}} | | null | | Fresnel term applied to {{#crossLink "PhongMaterial/diffuse:property"}}{{/crossLink}}. |
  35. | {{#crossLink "PhongMaterial/specularFresnel:property"}}{{/crossLink}} | {{#crossLink "Fresnel"}}{{/crossLink}} | | null | | Fresnel term applied to {{#crossLink "PhongMaterial/specular:property"}}{{/crossLink}}. |
  36. | {{#crossLink "PhongMaterial/emissiveFresnel:property"}}{{/crossLink}} | {{#crossLink "Fresnel"}}{{/crossLink}} | | null | | Fresnel term applied to {{#crossLink "PhongMaterial/emissive:property"}}{{/crossLink}}. |
  37. | {{#crossLink "PhongMaterial/reflectivityFresnel:property"}}{{/crossLink}} | {{#crossLink "Fresnel"}}{{/crossLink}} | | null | | Fresnel term applied to {{#crossLink "PhongMaterial/reflectivity:property"}}{{/crossLink}}. |
  38. | {{#crossLink "PhongMaterial/alphaFresnel:property"}}{{/crossLink}} | {{#crossLink "Fresnel"}}{{/crossLink}} | | null | | Fresnel term applied to {{#crossLink "PhongMaterial/alpha:property"}}{{/crossLink}}. |
  39. | {{#crossLink "PhongMaterial/lineWidth:property"}}{{/crossLink}} | Number | [0..100] | 1 | | Line width in pixels. |
  40. | {{#crossLink "PhongMaterial/pointSize:property"}}{{/crossLink}} | Number | [0..100] | 1 | | Point size in pixels. |
  41. | {{#crossLink "PhongMaterial/alphaMode:property"}}{{/crossLink}} | String | "opaque", "blend", "mask" | "blend" | | Alpha blend mode. |
  42. | {{#crossLink "PhongMaterial/alphaCutoff:property"}}{{/crossLink}} | Number | [0..1] | 0.5 | | Alpha cutoff value. |
  43. | {{#crossLink "PhongMaterial/backfaces:property"}}{{/crossLink}} | Boolean | | false | | Whether to render {{#crossLink "Geometry"}}Geometry{{/crossLink}} backfaces. |
  44. | {{#crossLink "PhongMaterial/frontface:property"}}{{/crossLink}} | String | "ccw", "cw" | "ccw" | | The winding order for {{#crossLink "Geometry"}}Geometry{{/crossLink}} frontfaces - "cw" for clockwise, or "ccw" for counter-clockwise. |
  45.  
  46. ## Usage
  47.  
  48. In this example we have a Mesh with
  49.  
  50. * a {{#crossLink "Lights"}}{{/crossLink}} containing an {{#crossLink "AmbientLight"}}{{/crossLink}} and a {{#crossLink "DirLight"}}{{/crossLink}},
  51. * a {{#crossLink "PhongMaterial"}}{{/crossLink}} which applies a {{#crossLink "Texture"}}{{/crossLink}} as a diffuse map and a specular {{#crossLink "Fresnel"}}{{/crossLink}}, and
  52. * a {{#crossLink "TorusGeometry"}}{{/crossLink}}.
  53.  
  54. ```` javascript
  55. var torus = new xeogl.Mesh({
  56.  
  57. lights: new xeogl.Lights({
  58. lights: [
  59. new xeogl.AmbientLight({
  60. color: [0.7, 0.7, 0.7]
  61. }),
  62. new xeogl.DirLight({
  63. dir: [-1, -1, -1],
  64. color: [0.5, 0.7, 0.5],
  65. intensity: [1.0, 1.0, 1.0],
  66. space: "view"
  67. })
  68. ]
  69. }),
  70.  
  71. material: new xeogl.PhongMaterial({
  72. ambient: [0.3, 0.3, 0.3],
  73. diffuse: [0.5, 0.5, 0.0], // Ignored, since we have assigned a Texture to diffuseMap, below
  74. diffuseMap: new xeogl.Texture({
  75. src: "diffuseMap.jpg"
  76. }),
  77. specular: [1, 1, 1],
  78. specularFresnel: new xeogl.Fresnel({
  79. leftColor: [1.0, 1.0, 1.0],
  80. rightColor: [0.0, 0.0, 0.0],
  81. power: 4
  82. }),
  83. shininess: 80, // Default
  84. alpha: 1.0 // Default
  85. }),
  86.  
  87. geometry: new xeogl.TorusGeometry()
  88. });
  89. ````
  90.  
  91. ## Transparency
  92.  
  93. ### Alpha Blending
  94.  
  95. Let's make our torus transparent. We'll update its PhongMaterial's {{#crossLink "PhongMaterial/alpha:property"}}{{/crossLink}}
  96. and {{#crossLink "PhongMaterial/alphaMode:property"}}{{/crossLink}}, causing it to blend 50% with the background:
  97.  
  98. ````javascript
  99. torus.material.alpha = 0.5;
  100. torus.material.alphaMode = "blend";
  101. ````
  102. *TODO: Screenshot*
  103.  
  104. ### Alpha Masking
  105.  
  106. Now let's make holes in our torus instead. We'll give its PhongMaterial an {{#crossLink "PhongMaterial/alphaMap:property"}}{{/crossLink}}
  107. and configure {{#crossLink "PhongMaterial/alpha:property"}}{{/crossLink}}, {{#crossLink "PhongMaterial/alphaMode:property"}}{{/crossLink}},
  108. and {{#crossLink "PhongMaterial/alphaCutoff:property"}}{{/crossLink}} to treat it as an alpha mask:
  109.  
  110. ````javascript
  111. torus.material.alphaMap = new xeogl.Texture({
  112. src: "textures/diffuse/crossGridColorMap.jpg"
  113. });
  114.  
  115. torus.material.alpha = 1.0;
  116. torus.material.alphaMode = "mask";
  117. torus.material.alphaCutoff = 0.2;
  118. ````
  119. *TODO: Screenshot*
  120.  
  121.  
  122. @class PhongMaterial
  123. @module xeogl
  124. @submodule materials
  125. @constructor
  126. @extends Material
  127. @param [owner] {Component} Owner component. When destroyed, the owner will destroy this component as well. Creates this component within the default {{#crossLink "Scene"}}{{/crossLink}} when omitted.
  128. @param [cfg] {*} The PhongMaterial configuration
  129. @param [cfg.id] {String} Optional ID, unique among all components in the parent {{#crossLink "Scene"}}Scene{{/crossLink}}, generated automatically when omitted.
  130. @param [cfg.meta=null] {String:Object} Metadata to attach to this PhongMaterial.
  131. @param [cfg.ambient=[1.0, 1.0, 1.0 ]] {Array of Number} PhongMaterial ambient color.
  132. @param [cfg.diffuse=[ 1.0, 1.0, 1.0 ]] {Array of Number} PhongMaterial diffuse color.
  133. @param [cfg.specular=[ 1.0, 1.0, 1.0 ]] {Array of Number} PhongMaterial specular color.
  134. @param [cfg.emissive=[ 0.0, 0.0, 0.0 ]] {Array of Number} PhongMaterial emissive color.
  135. @param [cfg.alpha=1] {Number} Scalar in range 0-1 that controls alpha, where 0 is completely transparent and 1 is completely opaque.
  136. @param [cfg.shininess=80] {Number} Scalar in range 0-128 that determines the size and sharpness of specular highlights.
  137. @param [cfg.reflectivity=1] {Number} Scalar in range 0-1 that controls how much {{#crossLink "CubeMap"}}CubeMap{{/crossLink}} is reflected.
  138. @param [cfg.lineWidth=1] {Number} Scalar that controls the width of lines for {{#crossLink "Geometry"}}{{/crossLink}} with {{#crossLink "Geometry/primitive:property"}}{{/crossLink}} set to "lines".
  139. @param [cfg.pointSize=1] {Number} Scalar that controls the size of points for {{#crossLink "Geometry"}}{{/crossLink}} with {{#crossLink "Geometry/primitive:property"}}{{/crossLink}} set to "points".
  140. @param [cfg.ambientMap=null] {Texture} A ambient map {{#crossLink "Texture"}}Texture{{/crossLink}}, which will multiply by the diffuse property. Must be within the same {{#crossLink "Scene"}}Scene{{/crossLink}} as this PhongMaterial.
  141. @param [cfg.diffuseMap=null] {Texture} A diffuse map {{#crossLink "Texture"}}Texture{{/crossLink}}, which will override the effect of the diffuse property. Must be within the same {{#crossLink "Scene"}}Scene{{/crossLink}} as this PhongMaterial.
  142. @param [cfg.specularMap=null] {Texture} A specular map {{#crossLink "Texture"}}Texture{{/crossLink}}, which will override the effect of the specular property. Must be within the same {{#crossLink "Scene"}}Scene{{/crossLink}} as this PhongMaterial.
  143. @param [cfg.emissiveMap=undefined] {Texture} An emissive map {{#crossLink "Texture"}}Texture{{/crossLink}}, which will override the effect of the emissive property. Must be within the same {{#crossLink "Scene"}}Scene{{/crossLink}} as this PhongMaterial.
  144. @param [cfg.normalMap=undefined] {Texture} A normal map {{#crossLink "Texture"}}Texture{{/crossLink}}. Must be within the same {{#crossLink "Scene"}}Scene{{/crossLink}} as this PhongMaterial.
  145. @param [cfg.alphaMap=undefined] {Texture} An alpha map {{#crossLink "Texture"}}Texture{{/crossLink}}, which will override the effect of the alpha property. Must be within the same {{#crossLink "Scene"}}Scene{{/crossLink}} as this PhongMaterial.
  146. @param [cfg.reflectivityMap=undefined] {Texture} A reflectivity control map {{#crossLink "Texture"}}Texture{{/crossLink}}, which will override the effect of the reflectivity property. Must be within the same {{#crossLink "Scene"}}Scene{{/crossLink}} as this PhongMaterial.
  147. @param [cfg.occlusionMap=null] {Texture} An occlusion map {{#crossLink "Texture"}}Texture{{/crossLink}}. Must be within the same {{#crossLink "Scene"}}Scene{{/crossLink}} as this PhongMaterial.
  148. @param [cfg.diffuseFresnel=undefined] {Fresnel} A diffuse {{#crossLink "Fresnel"}}Fresnel{{/crossLink}}. Must be within the same {{#crossLink "Scene"}}Scene{{/crossLink}} as this PhongMaterial.
  149. @param [cfg.specularFresnel=undefined] {Fresnel} A specular {{#crossLink "Fresnel"}}Fresnel{{/crossLink}}. Must be within the same {{#crossLink "Scene"}}Scene{{/crossLink}} as this PhongMaterial.
  150. @param [cfg.emissiveFresnel=undefined] {Fresnel} An emissive {{#crossLink "Fresnel"}}Fresnel{{/crossLink}}. Must be within the same {{#crossLink "Scene"}}Scene{{/crossLink}} as this PhongMaterial.
  151. @param [cfg.alphaFresnel=undefined] {Fresnel} An alpha {{#crossLink "Fresnel"}}Fresnel{{/crossLink}}. Must be within the same {{#crossLink "Scene"}}Scene{{/crossLink}} as this PhongMaterial.
  152. @param [cfg.reflectivityFresnel=undefined] {Fresnel} A reflectivity {{#crossLink "Fresnel"}}Fresnel{{/crossLink}}. Must be within the same {{#crossLink "Scene"}}Scene{{/crossLink}} as this PhongMaterial.
  153. @param [cfg.alphaMode="opaque"] {String} The alpha blend mode - accepted values are "opaque", "blend" and "mask".
  154. See the {{#crossLink "PhongMaterial/alphaMode:property"}}{{/crossLink}} property for more info.
  155. @param [cfg.alphaCutoff=0.5] {Number} The alpha cutoff value. See the {{#crossLink "PhongMaterial/alphaCutoff:property"}}{{/crossLink}} property for more info.
  156. @param [cfg.backfaces=false] {Boolean} Whether to render {{#crossLink "Geometry"}}Geometry{{/crossLink}} backfaces.
  157. @param [cfg.frontface="ccw"] {Boolean} The winding order for {{#crossLink "Geometry"}}Geometry{{/crossLink}} front faces - "cw" for clockwise, or "ccw" for counter-clockwise.
  158. */
  159. import {core} from "./../core.js";
  160. import {Material} from './material.js';
  161. import {State} from '../renderer/state.js';
  162. import {math} from '../math/math.js';
  163. import {componentClasses} from "./../componentClasses.js";
  164.  
  165. const type = "xeogl.PhongMaterial";
  166. const alphaModes = {"opaque": 0, "mask": 1, "blend": 2};
  167. const alphaModeNames = ["opaque", "mask", "blend"];
  168.  
  169. class PhongMaterial extends Material {
  170.  
  171. /**
  172. JavaScript class name for this Component.
  173.  
  174. For example: "xeogl.AmbientLight", "xeogl.MetallicMaterial" etc.
  175.  
  176. @property type
  177. @type String
  178. @final
  179. */
  180. get type() {
  181. return type;
  182. }
  183.  
  184. init(cfg) {
  185.  
  186. super.init(cfg);
  187.  
  188. this._state = new State({
  189. type: "PhongMaterial",
  190. ambient: math.vec3([1.0, 1.0, 1.0]),
  191. diffuse: math.vec3([1.0, 1.0, 1.0]),
  192. specular: math.vec3([1.0, 1.0, 1.0]),
  193. emissive: math.vec3([0.0, 0.0, 0.0]),
  194. alpha: null,
  195. shininess: null,
  196. reflectivity: null,
  197. alphaMode: null,
  198. alphaCutoff: null,
  199. lineWidth: null,
  200. pointSize: null,
  201. backfaces: null,
  202. frontface: null, // Boolean for speed; true == "ccw", false == "cw"
  203. hash: null
  204. });
  205.  
  206. this.ambient = cfg.ambient;
  207. this.diffuse = cfg.diffuse;
  208. this.specular = cfg.specular;
  209. this.emissive = cfg.emissive;
  210. this.alpha = cfg.alpha;
  211. this.shininess = cfg.shininess;
  212. this.reflectivity = cfg.reflectivity;
  213. this.lineWidth = cfg.lineWidth;
  214. this.pointSize = cfg.pointSize;
  215.  
  216. if (cfg.ambientMap) {
  217. this._ambientMap = this._checkComponent("xeogl.Texture", cfg.ambientMap);
  218. }
  219. if (cfg.diffuseMap) {
  220. this._diffuseMap = this._checkComponent("xeogl.Texture", cfg.diffuseMap);
  221. }
  222. if (cfg.specularMap) {
  223. this._specularMap = this._checkComponent("xeogl.Texture", cfg.specularMap);
  224. }
  225. if (cfg.emissiveMap) {
  226. this._emissiveMap = this._checkComponent("xeogl.Texture", cfg.emissiveMap);
  227. }
  228. if (cfg.alphaMap) {
  229. this._alphaMap = this._checkComponent("xeogl.Texture", cfg.alphaMap);
  230. }
  231. if (cfg.reflectivityMap) {
  232. this._reflectivityMap = this._checkComponent("xeogl.Texture", cfg.reflectivityMap);
  233. }
  234. if (cfg.normalMap) {
  235. this._normalMap = this._checkComponent("xeogl.Texture", cfg.normalMap);
  236. }
  237. if (cfg.occlusionMap) {
  238. this._occlusionMap = this._checkComponent("xeogl.Texture", cfg.occlusionMap);
  239. }
  240. if (cfg.diffuseFresnel) {
  241. this._diffuseFresnel = this._checkComponent("xeogl.Fresnel", cfg.diffuseFresnel);
  242. }
  243. if (cfg.specularFresnel) {
  244. this._specularFresnel = this._checkComponent("xeogl.Fresnel", cfg.specularFresnel);
  245. }
  246. if (cfg.emissiveFresnel) {
  247. this._emissiveFresnel = this._checkComponent("xeogl.Fresnel", cfg.emissiveFresnel);
  248. }
  249. if (cfg.alphaFresnel) {
  250. this._alphaFresnel = this._checkComponent("xeogl.Fresnel", cfg.alphaFresnel);
  251. }
  252. if (cfg.reflectivityFresnel) {
  253. this._reflectivityFresnel = this._checkComponent("xeogl.Fresnel", cfg.reflectivityFresnel);
  254. }
  255.  
  256. this.alphaMode = cfg.alphaMode;
  257. this.alphaCutoff = cfg.alphaCutoff;
  258. this.backfaces = cfg.backfaces;
  259. this.frontface = cfg.frontface;
  260.  
  261. this._makeHash();
  262. }
  263.  
  264. _makeHash() {
  265. const state = this._state;
  266. const hash = ["/p"]; // 'P' for Phong
  267. if (this._normalMap) {
  268. hash.push("/nm");
  269. if (this._normalMap.hasMatrix) {
  270. hash.push("/mat");
  271. }
  272. }
  273. if (this._ambientMap) {
  274. hash.push("/am");
  275. if (this._ambientMap.hasMatrix) {
  276. hash.push("/mat");
  277. }
  278. hash.push("/" + this._ambientMap.encoding);
  279. }
  280. if (this._diffuseMap) {
  281. hash.push("/dm");
  282. if (this._diffuseMap.hasMatrix) {
  283. hash.push("/mat");
  284. }
  285. hash.push("/" + this._diffuseMap.encoding);
  286. }
  287. if (this._specularMap) {
  288. hash.push("/sm");
  289. if (this._specularMap.hasMatrix) {
  290. hash.push("/mat");
  291. }
  292. }
  293. if (this._emissiveMap) {
  294. hash.push("/em");
  295. if (this._emissiveMap.hasMatrix) {
  296. hash.push("/mat");
  297. }
  298. hash.push("/" + this._emissiveMap.encoding);
  299. }
  300. if (this._alphaMap) {
  301. hash.push("/opm");
  302. if (this._alphaMap.hasMatrix) {
  303. hash.push("/mat");
  304. }
  305. }
  306. if (this._reflectivityMap) {
  307. hash.push("/rm");
  308. if (this._reflectivityMap.hasMatrix) {
  309. hash.push("/mat");
  310. }
  311. }
  312. if (this._occlusionMap) {
  313. hash.push("/ocm");
  314. if (this._occlusionMap.hasMatrix) {
  315. hash.push("/mat");
  316. }
  317. }
  318. if (this._diffuseFresnel) {
  319. hash.push("/df");
  320. }
  321. if (this._specularFresnel) {
  322. hash.push("/sf");
  323. }
  324. if (this._emissiveFresnel) {
  325. hash.push("/ef");
  326. }
  327. if (this._alphaFresnel) {
  328. hash.push("/of");
  329. }
  330. if (this._reflectivityFresnel) {
  331. hash.push("/rf");
  332. }
  333. hash.push(";");
  334. state.hash = hash.join("");
  335. }
  336.  
  337. /**
  338. The PhongMaterial's ambient color.
  339.  
  340. @property ambient
  341. @default [0.3, 0.3, 0.3]
  342. @type Float32Array
  343. */
  344. set ambient(value) {
  345. let ambient = this._state.ambient;
  346. if (!ambient) {
  347. ambient = this._state.ambient = new Float32Array(3);
  348. } else if (value && ambient[0] === value[0] && ambient[1] === value[1] && ambient[2] === value[2]) {
  349. return;
  350. }
  351. if (value) {
  352. ambient[0] = value[0];
  353. ambient[1] = value[1];
  354. ambient[2] = value[2];
  355. } else {
  356. ambient[0] = .2;
  357. ambient[1] = .2;
  358. ambient[2] = .2;
  359. }
  360. this._renderer.imageDirty();
  361. }
  362.  
  363. get ambient() {
  364. return this._state.ambient;
  365. }
  366.  
  367. /**
  368. The PhongMaterial's diffuse color.
  369.  
  370. Multiplies by {{#crossLink "PhongMaterial/diffuseMap:property"}}{{/crossLink}}.
  371.  
  372. @property diffuse
  373. @default [1.0, 1.0, 1.0]
  374. @type Float32Array
  375. */
  376. set diffuse(value) {
  377. let diffuse = this._state.diffuse;
  378. if (!diffuse) {
  379. diffuse = this._state.diffuse = new Float32Array(3);
  380. } else if (value && diffuse[0] === value[0] && diffuse[1] === value[1] && diffuse[2] === value[2]) {
  381. return;
  382. }
  383. if (value) {
  384. diffuse[0] = value[0];
  385. diffuse[1] = value[1];
  386. diffuse[2] = value[2];
  387. } else {
  388. diffuse[0] = 1;
  389. diffuse[1] = 1;
  390. diffuse[2] = 1;
  391. }
  392. this._renderer.imageDirty();
  393. }
  394.  
  395. get diffuse() {
  396. return this._state.diffuse;
  397. }
  398.  
  399. /**
  400. The material's specular color.
  401.  
  402. Multiplies by {{#crossLink "PhongMaterial/specularMap:property"}}{{/crossLink}}.
  403.  
  404. @property specular
  405. @default [1.0, 1.0, 1.0]
  406. @type Float32Array
  407. */
  408. set specular(value) {
  409. let specular = this._state.specular;
  410. if (!specular) {
  411. specular = this._state.specular = new Float32Array(3);
  412. } else if (value && specular[0] === value[0] && specular[1] === value[1] && specular[2] === value[2]) {
  413. return;
  414. }
  415. if (value) {
  416. specular[0] = value[0];
  417. specular[1] = value[1];
  418. specular[2] = value[2];
  419. } else {
  420. specular[0] = 1;
  421. specular[1] = 1;
  422. specular[2] = 1;
  423. }
  424. this._renderer.imageDirty();
  425. }
  426.  
  427. get specular() {
  428. return this._state.specular;
  429. }
  430.  
  431. /**
  432. The PhongMaterial's emissive color.
  433.  
  434. Multiplies by {{#crossLink "PhongMaterial/emissiveMap:property"}}{{/crossLink}}.
  435.  
  436. @property emissive
  437. @default [0.0, 0.0, 0.0]
  438. @type Float32Array
  439. */
  440. set emissive(value) {
  441. let emissive = this._state.emissive;
  442. if (!emissive) {
  443. emissive = this._state.emissive = new Float32Array(3);
  444. } else if (value && emissive[0] === value[0] && emissive[1] === value[1] && emissive[2] === value[2]) {
  445. return;
  446. }
  447. if (value) {
  448. emissive[0] = value[0];
  449. emissive[1] = value[1];
  450. emissive[2] = value[2];
  451. } else {
  452. emissive[0] = 0;
  453. emissive[1] = 0;
  454. emissive[2] = 0;
  455. }
  456. this._renderer.imageDirty();
  457. }
  458.  
  459. get emissive() {
  460. return this._state.emissive;
  461. }
  462.  
  463. /**
  464. Factor in the range [0..1] indicating how transparent the PhongMaterial is.
  465.  
  466. A value of 0.0 indicates fully transparent, 1.0 is fully opaque.
  467.  
  468. Multiplies by {{#crossLink "PhongMaterial/alphaMap:property"}}{{/crossLink}}.
  469.  
  470. @property alpha
  471. @default 1.0
  472. @type Number
  473. */
  474. set alpha(value) {
  475. value = (value !== undefined && value !== null) ? value : 1.0;
  476. if (this._state.alpha === value) {
  477. return;
  478. }
  479. this._state.alpha = value;
  480. this._renderer.imageDirty();
  481. }
  482.  
  483. get alpha() {
  484. return this._state.alpha;
  485. }
  486.  
  487. /**
  488. A factor in range [0..128] that determines the size and sharpness of the specular highlights create by this PhongMaterial.
  489.  
  490. Larger values produce smaller, sharper highlights. A value of 0.0 gives very large highlights that are almost never
  491. desirable. Try values close to 10 for a larger, fuzzier highlight and values of 100 or more for a small, sharp
  492. highlight.
  493.  
  494. @property shininess
  495. @default 80.0
  496. @type Number
  497. */
  498. set shininess(value) {
  499. this._state.shininess = value !== undefined ? value : 80;
  500. this._renderer.imageDirty();
  501. }
  502.  
  503. get shininess() {
  504. return this._state.shininess;
  505. }
  506.  
  507. /**
  508. The PhongMaterial's line width.
  509.  
  510. @property lineWidth
  511. @default 1.0
  512. @type Number
  513. */
  514. set lineWidth(value) {
  515. this._state.lineWidth = value || 1.0;
  516. this._renderer.imageDirty();
  517. }
  518.  
  519. get lineWidth() {
  520. return this._state.lineWidth;
  521. }
  522.  
  523. /**
  524. The PhongMaterial's point size.
  525.  
  526. @property pointSize
  527. @default 1.0
  528. @type Number
  529. */
  530. set pointSize(value) {
  531. this._state.pointSize = value || 1.0;
  532. this._renderer.imageDirty();
  533. }
  534.  
  535. get pointSize() {
  536. return this._state.pointSize;
  537. }
  538.  
  539. /**
  540. Scalar in range 0-1 that controls how much {{#crossLink "CubeMap"}}CubeMap{{/crossLink}} is reflected by this PhongMaterial.
  541.  
  542. The surface will be non-reflective when this is 0, and completely mirror-like when it is 1.0.
  543.  
  544. Multiplies by {{#crossLink "PhongMaterial/reflectivityMap:property"}}{{/crossLink}}.
  545.  
  546. @property reflectivity
  547. @default 1.0
  548. @type Number
  549. */
  550. set reflectivity(value) {
  551. this._state.reflectivity = value !== undefined ? value : 1.0;
  552. this._renderer.imageDirty();
  553. }
  554.  
  555. get reflectivity() {
  556. return this._state.reflectivity;
  557. }
  558.  
  559. /**
  560. Normal map.
  561.  
  562. @property normalMap
  563. @default undefined
  564. @type {Texture}
  565. @final
  566. */
  567. get normalMap() {
  568. return this._normalMap;
  569. }
  570.  
  571. /**
  572. Ambient map.
  573.  
  574. Multiplies by {{#crossLink "PhongMaterial/ambient:property"}}{{/crossLink}}.
  575.  
  576. @property ambientMap
  577. @default undefined
  578. @type {Texture}
  579. @final
  580. */
  581. get ambientMap() {
  582. return this._ambientMap;
  583. }
  584.  
  585. /**
  586. Diffuse map.
  587.  
  588. Multiplies by {{#crossLink "PhongMaterial/diffuse:property"}}{{/crossLink}}.
  589.  
  590. @property diffuseMap
  591. @default undefined
  592. @type {Texture}
  593. @final
  594. */
  595. get diffuseMap() {
  596. return this._diffuseMap;
  597. }
  598.  
  599. /**
  600. Specular map.
  601.  
  602. Multiplies by {{#crossLink "PhongMaterial/specular:property"}}{{/crossLink}}.
  603.  
  604. @property specularMap
  605. @default undefined
  606. @type {Texture}
  607. @final
  608. */
  609.  
  610. get specularMap() {
  611. return this._specularMap;
  612. }
  613.  
  614. /**
  615. Emissive map.
  616.  
  617. Multiplies by {{#crossLink "PhongMaterial/emissive:property"}}{{/crossLink}}.
  618.  
  619. @property emissiveMap
  620. @default undefined
  621. @type {Texture}
  622. @final
  623. */
  624. get emissiveMap() {
  625. return this._emissiveMap;
  626. }
  627.  
  628. /**
  629. Alpha map.
  630.  
  631. Multiplies by {{#crossLink "PhongMaterial/alpha:property"}}{{/crossLink}}.
  632.  
  633. @property alphaMap
  634. @default undefined
  635. @type {Texture}
  636. @final
  637. */
  638. get alphaMap() {
  639. return this._alphaMap;
  640. }
  641.  
  642. /**
  643. Reflectivity map.
  644.  
  645. Multiplies by {{#crossLink "PhongMaterial/reflectivity:property"}}{{/crossLink}}.
  646.  
  647. @property reflectivityMap
  648. @default undefined
  649. @type {Texture}
  650. @final
  651. */
  652. get reflectivityMap() {
  653. return this._reflectivityMap;
  654. }
  655.  
  656. /**
  657.  
  658. Occlusion map.
  659.  
  660. @property occlusionMap
  661. @default undefined
  662. @type {Texture}
  663. @final
  664. */
  665. get occlusionMap() {
  666. return this._occlusionMap;
  667. }
  668.  
  669. /**
  670. Diffuse Fresnel.
  671.  
  672. Applies to {{#crossLink "PhongMaterial/diffuseFresnel:property"}}{{/crossLink}}.
  673.  
  674. @property diffuseFresnel
  675. @default undefined
  676. @type {Fresnel}
  677. @final
  678. */
  679. get diffuseFresnel() {
  680. return this._diffuseFresnel;
  681. }
  682.  
  683. /**
  684. Specular Fresnel.
  685.  
  686. Applies to {{#crossLink "PhongMaterial/specular:property"}}{{/crossLink}}.
  687.  
  688. @property specularFresnel
  689. @default undefined
  690. @type {Fresnel}
  691. @final
  692. */
  693. get specularFresnel() {
  694. return this._specularFresnel;
  695. }
  696.  
  697. /**
  698. Emissive Fresnel.
  699.  
  700. Applies to {{#crossLink "PhongMaterial/emissive:property"}}{{/crossLink}}.
  701.  
  702. @property emissiveFresnel
  703. @default undefined
  704. @type {Fresnel}
  705. @final
  706. */
  707. get emissiveFresnel() {
  708. return this._emissiveFresnel;
  709. }
  710.  
  711. /**
  712. Alpha Fresnel.
  713.  
  714. Applies to {{#crossLink "PhongMaterial/alpha:property"}}{{/crossLink}}.
  715.  
  716. @property alphaFresnel
  717. @default undefined
  718. @type {Fresnel}
  719. @final
  720. */
  721. get alphaFresnel() {
  722. return this._alphaFresnel;
  723. }
  724.  
  725. /**
  726. Reflectivity Fresnel.
  727.  
  728. Applies to {{#crossLink "PhongMaterial/reflectivity:property"}}{{/crossLink}}.
  729.  
  730. @property reflectivityFresnel
  731. @default undefined
  732. @type {Fresnel}
  733. @final
  734. */
  735. get reflectivityFresnel() {
  736. return this._reflectivityFresnel;
  737. }
  738.  
  739. /**
  740. The alpha rendering mode.
  741.  
  742. This governs how alpha is treated. Alpha is the combined result of the
  743. {{#crossLink "PhongMaterial/alpha:property"}}{{/crossLink}} and
  744. {{#crossLink "PhongMaterial/alphaMap:property"}}{{/crossLink}} properties.
  745.  
  746. * "opaque" - The alpha value is ignored and the rendered output is fully opaque.
  747. * "mask" - The rendered output is either fully opaque or fully transparent depending on the alpha value and the specified alpha cutoff value.
  748. * "blend" - The alpha value is used to composite the source and destination areas. The rendered output is combined with the background using the normal painting operation (i.e. the Porter and Duff over operator).
  749.  
  750. @property alphaMode
  751. @default "opaque"
  752. @type {String}
  753. */
  754.  
  755. set alphaMode(alphaMode) {
  756. alphaMode = alphaMode || "opaque";
  757. let value = alphaModes[alphaMode];
  758. if (value === undefined) {
  759. this.error("Unsupported value for 'alphaMode': " + alphaMode + " - defaulting to 'opaque'");
  760. value = "opaque";
  761. }
  762. if (this._state.alphaMode === value) {
  763. return;
  764. }
  765. this._state.alphaMode = value;
  766. this._renderer.imageDirty();
  767. }
  768.  
  769. get alphaMode() {
  770. return alphaModeNames[this._state.alphaMode];
  771. }
  772.  
  773. /**
  774. The alpha cutoff value.
  775.  
  776. Specifies the cutoff threshold when {{#crossLink "PhongMaterial/alphaMode:property"}}{{/crossLink}}
  777. equals "mask". If the alpha is greater than or equal to this value then it is rendered as fully
  778. opaque, otherwise, it is rendered as fully transparent. A value greater than 1.0 will render the entire
  779. material as fully transparent. This value is ignored for other modes.
  780.  
  781. Alpha is the combined result of the
  782. {{#crossLink "PhongMaterial/alpha:property"}}{{/crossLink}} and
  783. {{#crossLink "PhongMaterial/alphaMap:property"}}{{/crossLink}} properties.
  784.  
  785. @property alphaCutoff
  786. @default 0.5
  787. @type {Number}
  788. */
  789. set alphaCutoff(alphaCutoff) {
  790. if (alphaCutoff === null || alphaCutoff === undefined) {
  791. alphaCutoff = 0.5;
  792. }
  793. if (this._state.alphaCutoff === alphaCutoff) {
  794. return;
  795. }
  796. this._state.alphaCutoff = alphaCutoff;
  797. }
  798.  
  799. get alphaCutoff() {
  800. return this._state.alphaCutoff;
  801. }
  802.  
  803. /**
  804. Whether backfaces are visible on attached {{#crossLink "Mesh"}}Meshes{{/crossLink}}.
  805.  
  806. The backfaces will belong to {{#crossLink "Geometry"}}{{/crossLink}} compoents that are also attached to
  807. the {{#crossLink "Mesh"}}Meshes{{/crossLink}}.
  808.  
  809. @property backfaces
  810. @default false
  811. @type Boolean
  812. */
  813. set backfaces(value) {
  814. value = !!value;
  815. if (this._state.backfaces === value) {
  816. return;
  817. }
  818. this._state.backfaces = value;
  819. this._renderer.imageDirty();
  820. }
  821.  
  822. get backfaces() {
  823. return this._state.backfaces;
  824. }
  825.  
  826. /**
  827. Indicates the winding direction of front faces on attached {{#crossLink "Mesh"}}Meshes{{/crossLink}}.
  828.  
  829. The faces will belong to {{#crossLink "Geometry"}}{{/crossLink}} components that are also attached to
  830. the {{#crossLink "Mesh"}}Meshes{{/crossLink}}.
  831.  
  832. @property frontface
  833. @default "ccw"
  834. @type String
  835. */
  836. set frontface(value) {
  837. value = value !== "cw";
  838. if (this._state.frontface === value) {
  839. return;
  840. }
  841. this._state.frontface = value;
  842. this._renderer.imageDirty();
  843. }
  844.  
  845. get frontface() {
  846. return this._state.frontface ? "ccw" : "cw";
  847. }
  848.  
  849. destroy() {
  850. super.destroy();
  851. this._state.destroy();
  852. }
  853. }
  854.  
  855. componentClasses[type] = PhongMaterial;
  856.  
  857. export{PhongMaterial};