OpenGLでは、オブジェクトを通常どおりに描画してから、元のオブジェクトが描画されないようにステンシルバッファーを使用して、ワイヤーフレームとして再度描画することで、オブジェクトの輪郭を描くことができます。ただし、これにより、1つの単色のアウトラインが作成されます。
この画像では、クリーチャーの輪郭のピクセルは、輪郭を描くクリーチャーから離れるほど透明になっているように見えます。OpenGLで同様の効果を得るにはどうすればよいですか?
答えに遅れましたが、同じことを達成しようとしていて、使用しているソリューションを共有したいと思いました。
同様の効果は、それほど複雑ではないシェーダーを使用した1回の描画操作で実現できます。
フラグメントシェーダーでは、稲妻とテクスチャに基づいてフラグメントの色を計算し、ハイライトされていない色「colorA」を取得します。
2番目の色は、アウトラインの色「colorB」です。
フラグメントをカメラベクトルに取得し、正規化してから、このベクトルとフラグメントの正規化の内積を取得する必要があります。
フラグメントからカメラへのベクトルは、アイスペースでのフラグメントの位置の逆です。
その場合、フラグメントの色は次のようになります。
float CameraFacingPercentage = dot(v_fragmentToCamera, v_Normal);
gl_FragColor = ColorA * CameraFacingPercentage + ColorB * (1 - FacingCameraPercentage);
これは基本的な考え方ですが、アウトラインの色を多かれ少なかれ設定するためにいろいろと試してみる必要があります。また、モデルの凹面部分も強調表示されますが、質問に投稿された画像にも当てはまります。
彼らはこれにワイヤーフレームを使用しませんでした。シェーダーに大きく関連していて、これが必要だと思います。
dotprod(view、normal)を使用してGLSLシェーダーでエッジを検出する
http://en.wikibooks.org/wiki/GLSL_Programming/Unity/Toon_Shading#Outlines
私が見る限り、画面への影響は短く、コミックのアウトラインのように、多くの「エッジ」効果は純粋なエッジではありません。ほとんどの場合、パスは1つで、オブジェクトを通常どおりにレンダリングしてから、ジオメトリ(テクスチャなし)とGLSLシェーダーのみを含むパスがあります。フラグメントシェーダーでは、法線が取得され、その法線は、オブジェクトに色を付けるカメラベクトルに垂直になります。次に、完全な垂線に近い領域を含めることにより、効果が滑らかになります。
正確な計算を調べる必要がありますが、カメラのベクトルと法線の内積をとると、「垂直性」の量が得られると思います。次に、expのような関数を実行して、1にバイアスをかけることができます。
したがって(それが正しいことを保証することなく):
exp(dot(vec3(0, 0, 1), normal));
(注:すべてが画面スペースにあります。)