比較的最近の OpenGL ではシェーダー変数の attribute, varying などが廃止されて、in, out を使って記述することになっています。
そんな中、テセレーションのシェーダーコードを眺めていてふと思ったことがありました。
HLSLのように書けないだろうか
こんな風に TCS の入力・出力が書いてありました。
in VS_Out { vec3 WorldPos; vec3 Normal; } fromVS[]; struct TC_Output { vec3 Position; vec3 Normal; }; out TC_Output TC_Out[];
出力部分をみてみると構造体で指定されており、 HLSL のようでもあります。
そこで以下のようにコードを変えてみました・・・.
struct VS_Out { vec3 WorldPos; vec3 Normal; }; in struct VS_Out fromVS[];
これに対応するようにVSも編集しましたが、うまく動作せずでした。コンパイルやリンクがエラー無く通るので謎です。
うまく動作する方法
いくつか試行錯誤して通るコードに到達できました。
それが以下のコードです。
// 頂点シェーダー struct Vertex { vec3 WorldPos; vec3 Normal; }; out VSOut { struct Vertex Out; };
// TCS struct Vertex { vec3 WorldPos; vec3 Normal; }; in VSOut { struct Vertex Out; } fromVS[];
まとめ
結局構造体1つを out 指定という HLSL のような書き方はできませんでした。
interface ブロックの書き方が似ているため期待してしまっただけのようです。
また、interfaceブロックの中身はマッチングが行われるため、in/out で完全にあっていないと失敗しました。
構造体の名前から同じである必要がありました。
今回使用したコードは以前のテセレーションの関連コードです。
ブログの記事としてはこちらで使っていたものです。
GLSL の Interface Block はこちらのほうにも解説があります。
ちなみに今回の実験をしたのは Windows10 x64 で NVIDIA Geforce 650Ti でドライバは 375.57 でした。
ドライバのバージョンが違ったり、グラフィクスボードが違ったりすると同じ結果にはならないかもしれませんので、ご注意ください。