GLSL

GLSLの関数の引数で指定するout修飾子とinout修飾子の違いについて

GLSLの関数で参照渡しをするときに、以下のように引数にoutinoutといった修飾子を指定すると思います。

void func(out output) {
   ...
}

outinoutの違いを今までわかっていなかったのですが、以下のページに書いてあったので備忘録としてまとめておきます。
https://www.khronos.org/opengl/wiki/Core_Language_(GLSL)

まずinoutですが、こちらin修飾子と同じように関数の呼び出し時に実引数の値を引数にコピーします。例えば、以下のようなフラグメントシェーダーの場合、colorは最終的に(1.0, 1.0, 0.0)となり、黄色でレンダリングされます。

fragment_shader
void testInout(inout color) {
  color += vec3(0.0, 1.0, 0.0);
}

vod main() {
  vec3 color = vec3(1.0, 0.0, 0.0);
  testInout(color);
  gl_FragColor = vec4(color, 1.0);
}

一方でoutでは関数の呼び出し時に値のコピーをおこないません。そのため値は未定義(値がなにか不明)の状態になります。以下のようなフラグメントシェーダーでは最終的なcolorの値は予測できなくなります。実際に実行してみるとノイズのようなものが出力されることを確認できました。
http://glslsandbox.com/e#46725.0

fragment_shader
void testOut(out color) {
  color += vec3(0.0, 1.0, 0.0);
}

vod main() {
  vec3 color = vec3(1.0, 0.0, 0.0);
  testOut(color);
  gl_FragColor = vec4(color, 1.0);
}