置顶公告:【置顶】关于临时开启评论区所有功能的公告(2022.10.22) | 【置顶】关于本站Widget恢复使用的公告
  • 你好~!欢迎来到萌娘百科镜像站!如需查看或编辑,请联系本站管理员注册账号。
  • 本镜像站和其他萌娘百科的镜像站无关,请注意分别。

Module:Hct/ViewingConditions

猛汉♂百科,万男皆可猛的百科全书!转载请标注来源页面的网页链接,并声明引自猛汉百科。内容不可商用。
跳到导航 跳到搜索
Template-info.svg 模块文档  [创建] [刷新]
  1. --[[
  2. Copyright 2021 Google LLC
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ]]
  13. --[[
  14. This file has been modified. The original version is at
  15. https://github.com/material-foundation/material-color-utilities
  16. ]]
  17. local utils = require('Module:Hct/ColorUtils')
  18. local mathU = require('Module:Hct/MathUtils')
  19. --[[
  20. In traditional color spaces, a color can be identified solely by the observer's measurement of
  21. the color. Color appearance models such as CAM16 also use information about the environment where
  22. the color was observed, known as the viewing conditions.
  23. For example, white under the traditional assumption of a midday sun white point is accurately
  24. measured as a slightly chromatic blue by CAM16. (roughly, hue 203, chroma 3, lightness 100)
  25. This class caches intermediate values of the CAM16 conversion process that depend only on
  26. viewing conditions, enabling speed ups.
  27. ]]
  28. ViewingConditions = {}
  29. --[[
  30. Parameters are intermediate values of the CAM16 conversion process. Their names are shorthand
  31. for technical color science terminology, this class would not benefit from documenting them
  32. individually. A brief overview is available in the CAM16 specification, and a complete overview
  33. requires a color science textbook, such as Fairchild's Color Appearance Models.
  34. ]]
  35. -- private
  36. local function newViewingConditions(n, aw, nbb, ncb, c, nc, rgbD, fl, flRoot, z)
  37. return {
  38. n = n,
  39. aw = aw,
  40. nbb = nbb,
  41. ncb = ncb,
  42. c = c,
  43. nc = nc,
  44. rgbD = rgbD,
  45. fl = fl,
  46. flRoot = flRoot,
  47. z = z,
  48. };
  49. end
  50. --[[
  51. Create ViewingConditions from a simple, physically relevant, set of parameters.
  52. @param whitePoint White point, measured in the XYZ color space. default = D65, or sunny day
  53. afternoon
  54. @param adaptingLuminance The luminance of the adapting field. Informally, how bright it is in
  55. the room where the color is viewed. Can be calculated from lux by multiplying lux by
  56. 0.0586. default = 11.72, or 200 lux.
  57. @param backgroundLstar The lightness of the area surrounding the color. measured by L* in
  58. L*a*b*. default = 50.0
  59. @param surround A general description of the lighting surrounding the color. 0 is pitch dark,
  60. like watching a movie in a theater. 1.0 is a dimly light room, like watching TV at home at
  61. night. 2.0 means there is no difference between the lighting on the color and around it.
  62. default = 2.0
  63. @param discountingIlluminant Whether the eye accounts for the tint of the ambient lighting,
  64. such as knowing an apple is still red in green light. default = false, the eye does not
  65. perform this process on self-luminous objects like displays.
  66. ]]
  67. local function makeViewingConditions(whitePoint, adaptingLuminance, backgroundLstar, surround, discountingIlluminant)
  68. -- Transform white point XYZ to 'cone'/'rgb' responses
  69. local xyz = whitePoint;
  70. local rW = xyz[1] * 0.401288 + xyz[2] * 0.650173 + xyz[3] * -0.051461;
  71. local gW = xyz[1] * -0.250268 + xyz[2] * 1.204414 + xyz[3] * 0.045854;
  72. local bW = xyz[1] * -0.002079 + xyz[2] * 0.048952 + xyz[3] * 0.953127;
  73. local f = 0.8 + surround / 10.0;
  74. local c = f >= 0.9 and mathU.lerp(0.59, 0.69, ((f - 0.9) * 10.0))
  75. or mathU.lerp(0.525, 0.59, ((f - 0.8) * 10.0));
  76. local d = discountingIlluminant
  77. and 1.0
  78. or f * (1.0 - ((1.0 / 3.6) * math.exp((-adaptingLuminance - 42.0) / 92.0)));
  79. d = mathU.clampDouble(0.0, 1.0, d);
  80. local nc = f;
  81. local rgbD = {
  82. d * (100.0 / rW) + 1.0 - d,
  83. d * (100.0 / gW) + 1.0 - d,
  84. d * (100.0 / bW) + 1.0 - d,
  85. };
  86. local k = 1.0 / (5.0 * adaptingLuminance + 1.0);
  87. local k4 = k * k * k * k;
  88. local k4F = 1.0 - k4;
  89. local fl = (k4 * adaptingLuminance) + (0.1 * k4F * k4F * (mathU.cbrt(5.0 * adaptingLuminance)));
  90. local n = (utils.yFromLstar(backgroundLstar) / whitePoint[2]);
  91. local z = 1.48 + math.sqrt(n);
  92. local nbb = 0.725 / math.pow(n, 0.2);
  93. local ncb = nbb;
  94. local rgbAFactors = {
  95. math.pow(fl * rgbD[1] * rW / 100.0, 0.42),
  96. math.pow(fl * rgbD[2] * gW / 100.0, 0.42),
  97. math.pow(fl * rgbD[3] * bW / 100.0, 0.42),
  98. };
  99. local rgbA = {
  100. (400.0 * rgbAFactors[1]) / (rgbAFactors[1] + 27.13),
  101. (400.0 * rgbAFactors[2]) / (rgbAFactors[2] + 27.13),
  102. (400.0 * rgbAFactors[3]) / (rgbAFactors[3] + 27.13)
  103. };
  104. local aw = (2.0 * rgbA[1] + rgbA[2] + 0.05 * rgbA[3]) * nbb;
  105. return newViewingConditions(n, aw, nbb, ncb, c, nc, rgbD, fl, math.pow(fl, 0.25), z);
  106. end
  107. return makeViewingConditions(
  108. utils.whitePointD65(),
  109. (200.0 / math.pi * utils.yFromLstar(50.0) / 100.0),
  110. 50.0,
  111. 2.0,
  112. false
  113. );