色、ムズ〜〜〜〜

本記事は、先日開催されたKyoto.js 19のために用意したLT資料に加筆したものです。

kyotojs.connpass.com


こんにちは、天城です。 最近はWebGLで動画編集アプリを開発しており、Webでの色の扱いについて日々苦しんでおります。 この記事では、僕が最近知った色関連の小ネタを共有します。

目次

話題1: mix-blend-modeにaddがない

www.youtube.com

そもそもBlendingって何?

  • Webにおける色の合成は Compositing and Blending というSpecで定義されている
  • BlendingとCompositingは別概念である
    • Blending: 2つの色を混ぜること (multiply, darker… etc)
    • Compositing: 前景色と背景色を合成すること (source-over, xor… etc)

Webでは基本的にsource-over compositingしか使われない

  • source-over: 前景色が背景色の上に表示される
    • DOM要素が、z-index順に塗り重ねられていくイメージ
  • source-overにおけるBlendingとCompositingは、以下のように計算される:
  • alpha 50%の要素を2つ重ねたとき、出力のalphaは

  αo = αs + αb \, x \, (1 - αs) \\
      = 0.5 + 0.5 \, x \, (1 - 0.5) \\
      = 0.5 + 0.25 \\
      = 0.75

となり、0.75になる

Canvasではsource-over以外のCompositingが使える

  • Canvasでは globalCompositingOperation で Compositing を指定できる
  • Canvasでは、globalCompositingOperationを lighter にすることで加算合成ができた
    • 全然 “lighter” では無いが……
      • 実際Specにも「Porter-Duffにおける plus のことだよ」と書いてある
      • つまり、plus-lighter というネーミングは、この lighterplus を併記したもの……?

PDF Reference

  • Adobe製品(Photoshop, AE etc)で使われてるBlending Functionは、PDF Referenceで定義されている
  • 他社の画像/映像/デザイン系アプリも、基本的にAdobeのBlending Functionsを真似ているっぽい
  • Adobe公式のPDFのドキュメントだが……

一方その頃WebGLは……

話題2: Display P3

CSS Color 4でDisplay P3が使えるようになった

CSS Color Module Level 4

なにそれ?

Display P3

つまり?

  • 色域 (= 色空間 = Color Space) の一つ
  • Appleが策定した
  • Display P3はDCI-P3という規格から派生した
  • DCI-P3との違い
    • white pointが D65 (≒ 6500K) (DCI-P3だと~6300 K)
    • ガンマが2.2 (DCI-P3だと2.6)

つまり???????????????

  • 表示できる色が増える
    • Display P3での rgb(1, 0, 0) は、sRGBの rgb(1, 0, 0) よりも赤い
    • 256色より1677万色(厳密には16777216色)のほうが良いよね、というのとは違う話

CSS Color 4

https://www.w3.org/TR/css-color-4/

  • Candidate Recommendation Draft 状態 (勧告準備?)
  • Color 3が勧告されたのは2011年
    • 昔だね

In particular, it allows specifying colors in other color spaces than sRGB; previously, the more saturated colors outside the sRGB gamut could not be used in CSS even if the display device supported them.

  • sRGB 以外の色域も扱えるようにしようね、というのが主なテーマっぽい

CSS Color 4 で導入された記法

color() 関数

色空間を指定して色を定義できる

linear-gradient(to right in hsl) とか

詳しくはChromeの開発ブログとかtakanoripさんの記事に全部書いてある

余談: CSS Color 5ではICCプロファイルを読めるようになるらしい……?

media queryでディスプレイのカラープロファイルを判定する

デモ: https://codepen.io/fand/pen/poxYYrR

  • sRGBのディスプレイで表示:

  • MacBook Proのディスプレイで表示:

  • 「sRGBの場合のみ表示する」ということはできない……?

    • (color-gamut: srgb) and (not(color-gamut)) だとダメだった
    • 誰か教えて!

CanvasでDisplay P3を使うには

let canvas = document.getElementById("canvas");
let context = canvas.getContext("2d", { colorSpace: "display-p3" });

  • 右の赤のほうが赤い
    • ディスプレイの輝度を下げるとわかりやすいです
  • ImageDataの色を取得するときも色域を指定できる
    • imageData = context.getImageData(0, 0, 1, 1, { colorSpace: "display-p3" });

WebGLでDisplay P3を使うには

const canvas = document.querySelector('#canvas');
const context = canvas.getContext("webgl");
context.drawingBufferColorSpace = "display-p3";

// これは動かないので注意
canvas.getContext("webgl", { colorSpace: "display-p3" });

demo: https://codesandbox.io/s/webgl-display-p3-test-xs8zcp

  • ディスプレイがDisplay P3に対応しているとき、WebGLからDisplay P3空間の色を出力できる

  • テクスチャとして使う画像のカラープロファイルは考慮されないので注意

スクリーンショット撮るときの注意

  • macOSスクリーンショットを撮ると、出力画像のカラープロファイルは撮影したディスプレイのカラープロファイルになる
    • Finderで画像ファイルを右クリック→ Get Info でカラープロファイルをチェックできる
    • sRGBのディスプレイで撮影したスクリーンショットの場合
    • Display P3のディスプレイで撮影したスクリーンショットの場合
  • WebGLでsRGB出力した画面のスクショを他のアプリと比較して「おかしいな〜〜〜〜〜〜〜」と悩んでいた
    • 1行目のスクショと2行目のスクショで色味が違うのがわかりますか?
    • ディスプレイのカラープロファイルをsRGBに変更すると正しい色味になった (3行目)
  • なんかいい方法を教えてくれ……
    • ColorSync Utilityで解決したりもできるらしい?????