FdageLights.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. // import { Matrix4 } from '../math/Matrix4.js';
  2. // import { Vector2 } from '../math/Vector2.js';
  3. /**
  4. *
  5. * @param {json} lightInfo
  6. * 比如:{
  7. "count": 3,
  8. "shadowCount": 3,
  9. "rotation": 217,
  10. "positions": [0.300016, 0.575976, 0.760422, 0, -0.431842, 0.294622, -0.852473, 0, -0.806823, 0.414129, -0.421348, 0],
  11. "directions": [0.300016, 0.575976, 0.760422, -0.431842, 0.294622, -0.852473, -0.806823, 0.414129, -0.421348],
  12. "colors": [5, 5, 5, 5.27104, 40, 24.3306, 85.7826, 79.3486, 44.3031],
  13. "parameters": [-1, 0, 0, -1, 0, 0, -1, 0, 0],
  14. "spot": [-1, 1, 0, -1, 1, 0, -1, 1, 0],
  15. "matrixWeights": [2, 2, 2]
  16. }
  17. * @param {json} camera
  18. */
  19. function FdageLights( lightInfo,camera ) {
  20. this.rotation = this.shadowCount = this.count = 0;
  21. this.positions = [];
  22. this.directions = [];
  23. this.matrixWeights = [];
  24. this.matrix = Matrix.identity();
  25. this.invMatrix = Matrix.identity();
  26. this.defaultmatrix = Matrix.identity();
  27. this.defaultviewmatrix = Matrix.identity();
  28. for (var key in lightInfo)
  29. this[key] = lightInfo[key];
  30. this.count = this.positions.length / 4;
  31. this.count = Math.min(6, this.count);
  32. this.shadowCount = Math.min(3, this.shadowCount);
  33. this.positions = new Float32Array(this.positions);
  34. this.positionBuffer = new Float32Array(this.positions);
  35. this.directions = new Float32Array(this.directions);
  36. this.directionBuffer = new Float32Array(this.directions);
  37. this.colors = new Float32Array(this.colors);
  38. this.colorsBuffer = new Float32Array(this.colors);
  39. this.modelViewBuffer = new Float32Array(16 * this.shadowCount);
  40. this.projectionBuffer = new Float32Array(16 * this.shadowCount);
  41. this.finalTransformBuffer = new Float32Array(16 * this.shadowCount);
  42. this.inverseTransformBuffer = new Float32Array(16 * this.shadowCount);
  43. this.shadowTexelPadProjections = new Float32Array(4 * this.shadowCount);
  44. this.shadowsNeedUpdate = new Uint8Array(this.shadowCount);
  45. for (var d = 0; d < this.shadowsNeedUpdate.length; ++d)
  46. {
  47. this.shadowsNeedUpdate[d] = 1;
  48. }
  49. Matrix.rotation(this.matrix, this.rotation, 1);
  50. Matrix.transpose(this.invMatrix, this.matrix);
  51. Matrix.copy(this.defaultmatrix, this.matrix);
  52. Matrix.copy(this.defaultviewmatrix, camera.viewMatrix);
  53. for (d = 0; d < this.count; ++d) {
  54. b = this.positions.subarray(4 * d, 4 * d + 4);
  55. var e = this.directions.subarray(3 * d, 3 * d + 3);
  56. 1 == this.matrixWeights[d] ? (Matrix.mul4(b, this.matrix, b[0], b[1], b[2], b[3]),
  57. Matrix.mulVec(e, this.matrix, e[0], e[1], e[2])) : 2 == this.matrixWeights[d] && (Matrix.mul4(b, camera.viewMatrix, b[0], b[1], b[2], b[3]),
  58. Matrix.mulVec(e, camera.viewMatrix, e[0], e[1], e[2]))
  59. }
  60. }
  61. FdageLights.prototype.getLightPos = function(a) {
  62. return this.positionBuffer.subarray(4 * a, 4 * a + 4)
  63. };
  64. FdageLights.prototype.setLightDistance = function(a, c) {
  65. 0 >= c && (c = 1E-5);
  66. this.parameters[3 * a + 2] = 1 / c
  67. };
  68. FdageLights.prototype.setLightSpotAngle = function(a, c) {
  69. 0 >= c && (c = 1E-6);
  70. this.spot[3 * a] = c;
  71. var b = Math.sin(3.1415926 / 180 * c / 2);
  72. this.spot[3 * a + 2] = 1 / (b * b) * this.spot[3 * a + 1]
  73. };
  74. FdageLights.prototype.setLightSpotSharpness = function(a, c) {
  75. this.spot[3 * a + 1] = c;
  76. this.setLightSpotAngle(this.spot[3 * a])
  77. }
  78. ;
  79. FdageLights.prototype.setLightPos = function(a, c) {
  80. this.positions[4 * a + 0] = c[0];
  81. this.positions[4 * a + 1] = c[1];
  82. this.positions[4 * a + 2] = c[2];
  83. var b = this.positions.subarray(4 * a, 4 * a + 4);
  84. 1 == this.matrixWeights[a] ? Matrix.mul4(b, this.defaultmatrix, c[0], c[1], c[2], b[3]) : 2 == this.matrixWeights[a] && Matrix.mul4(b, this.defaultviewmatrix, c[0], c[1], c[2], b[3])
  85. }
  86. ;
  87. FdageLights.prototype.setLightDir = function(a, c) {
  88. this.directions[3 * a + 0] = c[0];
  89. this.directions[3 * a + 1] = c[1];
  90. this.directions[3 * a + 2] = c[2];
  91. var b = this.directions.subarray(3 * a, 3 * a + 3);
  92. 1 == this.matrixWeights[a] ? Matrix.mulVec(b, this.defaultmatrix, c[0], c[1], c[2]) : 2 == this.matrixWeights[a] && Matrix.mulVec(b, this.defaultviewmatrix, c[0], c[1], c[2])
  93. }
  94. ;
  95. FdageLights.prototype.getLightColor = function(a) {
  96. return this.colors.subarray(3 * a, 3 * a + 3)
  97. }
  98. ;
  99. FdageLights.prototype.setLightColor = function(a, c) {
  100. this.colors[3 * a + 0] = c[0];
  101. this.colors[3 * a + 1] = c[1];
  102. this.colors[3 * a + 2] = c[2]
  103. }
  104. ;
  105. FdageLights.prototype.getLightDir = function(a) {
  106. return this.directionBuffer.subarray(3 * a, 3 * a + 3)
  107. }
  108. ;
  109. FdageLights.prototype.getColor = function(a) {
  110. a *= 3;
  111. return [this.colors[a], this.colors[a + 1], this.colors[a + 2]]
  112. }
  113. ;
  114. FdageLights.prototype.update = function(a, c) {
  115. var b = new Matrix.type(this.matrix);
  116. Matrix.rotation(this.matrix, this.rotation, 1);
  117. Matrix.transpose(this.invMatrix, this.matrix);
  118. for (var d = 0; d < this.count; ++d) {
  119. var e = this.positions.subarray(4 * d, 4 * d + 4)
  120. , f = this.directions.subarray(3 * d, 3 * d + 3)
  121. , g = this.getLightPos(d)
  122. , h = this.getLightDir(d);
  123. 1 == this.matrixWeights[d] ? (g[0] = e[0],
  124. g[1] = e[1],
  125. g[2] = e[2],
  126. g[3] = e[3],
  127. h[0] = f[0],
  128. h[1] = f[1],
  129. h[2] = f[2]) : 2 == this.matrixWeights[d] ? (Matrix.mul4(g, a.transform, e[0], e[1], e[2], e[3]),
  130. Matrix.mulVec(h, a.transform, f[0], f[1], f[2]),
  131. Matrix.mul4(g, this.matrix, g[0], g[1], g[2], g[3]),
  132. Matrix.mulVec(h, this.matrix, h[0], h[1], h[2])) : (Matrix.mul4(g, this.matrix, e[0], e[1], e[2], e[3]),
  133. Matrix.mulVec(h, this.matrix, f[0], f[1], f[2]));
  134. Vect.normalize(h, h)
  135. }
  136. for (var f = new Float32Array(this.finalTransformBuffer), g = Matrix.empty(), h = Matrix.empty(), k = Matrix.empty(), n = Vect.empty(), m = Vect.empty(), l = Vect.empty(), p = Vect.empty(), e = Vect.empty(), r = [], s = [], u = Matrix.create(0.5, 0, 0, 0.5, 0, 0.5, 0, 0.5, 0, 0, 0.5, 0.5, 0, 0, 0, 1), d = 0; d < this.count; ++d) {
  137. n = this.getLightPos(d);
  138. m = this.getLightDir(d);
  139. 0.99 < Math.abs(m[1]) ? Vect.set(l, 1, 0, 0) : Vect.set(l, 0, 1, 0);
  140. Vect.cross(p, l, m);
  141. Vect.normalize(p, p);
  142. Vect.cross(l, m, p);
  143. Vect.normalize(l, l);
  144. Matrix.set(g, p[0], p[1], p[2], -Vect.dot(p, n), l[0], l[1], l[2], -Vect.dot(l, n), m[0], m[1], m[2], -Vect.dot(m, n), 0, 0, 0, 1);
  145. for (n = 0; 8 > n; ++n)
  146. e[0] = n & 1 ? c.max[0] : c.min[0],
  147. e[1] = n & 2 ? c.max[1] : c.min[1],
  148. e[2] = n & 4 ? c.max[2] : c.min[2],
  149. Matrix.mulPoint(e, this.matrix, 1.005 * e[0], 1.005 * e[1], 1.005 * e[2]),
  150. Matrix.mulPoint(e, g, e[0], e[1], e[2]),
  151. 0 == n ? (r[0] = s[0] = e[0],
  152. r[1] = s[1] = e[1],
  153. r[2] = s[2] = e[2]) : (r[0] = Math.min(r[0], e[0]),
  154. r[1] = Math.min(r[1], e[1]),
  155. r[2] = Math.min(r[2], e[2]),
  156. s[0] = Math.max(s[0], e[0]),
  157. s[1] = Math.max(s[1], e[1]),
  158. s[2] = Math.max(s[2], e[2]));
  159. var n = -r[2]
  160. , m = -s[2]
  161. , q = this.spot[3 * d];
  162. 0 < q ? (n = Math.min(n, 1 / this.parameters[3 * d + 2]),
  163. m = Math.max(0.04 * n, m),
  164. Matrix.perspective(h, q, 1, m, n),
  165. d < this.shadowCount && (n = 2 * -Math.tan(0.00872664625 * q),
  166. this.shadowTexelPadProjections[4 * d + 0] = this.modelViewBuffer[16 * d + 2] * n,
  167. this.shadowTexelPadProjections[4 * d + 1] = this.modelViewBuffer[16 * d + 6] * n,
  168. this.shadowTexelPadProjections[4 * d + 2] = this.modelViewBuffer[16 * d + 10] * n,
  169. this.shadowTexelPadProjections[4 * d + 3] = this.modelViewBuffer[16 * d + 14] * n)) : (Matrix.ortho(h, r[0], s[0], r[1], s[1], m, n),
  170. d < this.shadowCount && (this.shadowTexelPadProjections[4 * d + 0] = this.shadowTexelPadProjections[4 * d + 1] = this.shadowTexelPadProjections[4 * d + 2] = 0,
  171. this.shadowTexelPadProjections[4 * d + 3] = Math.max(s[0] - r[0], s[1] - r[1])));
  172. Matrix.mul(k, h, g);
  173. Matrix.mul(k, u, k);
  174. Matrix.copyToBuffer(this.modelViewBuffer, 16 * d, g);
  175. Matrix.copyToBuffer(this.projectionBuffer, 16 * d, h);
  176. Matrix.copyToBuffer(this.finalTransformBuffer, 16 * d, k);
  177. Matrix.invert(k, k);
  178. Matrix.copyToBuffer(this.inverseTransformBuffer, 16 * d, k)
  179. }
  180. e = !1;
  181. for (d = 0; d < b.length; ++d)
  182. if (b[d] != this.matrix[d]) {
  183. e = !0;
  184. break
  185. }
  186. for (d = 0; d < this.shadowCount; d++)
  187. if (e && 1 == this.matrixWeights[d])
  188. this.shadowsNeedUpdate[d] = 1;
  189. else
  190. for (b = 16 * d; b < 16 * d + 16; ++b)
  191. if (f[b] != this.finalTransformBuffer[b]) {
  192. this.shadowsNeedUpdate[d] = 1;
  193. break
  194. }
  195. }
  196. ;
  197. FdageLights.prototype.flagUpdateAnimatedLighting = function() {
  198. for (var a = 0; a < this.shadowCount; a++)
  199. this.shadowsNeedUpdate[a] = 1
  200. }
  201. ;
  202. export { FdageLights };