OpenGL ES 2.0 プログラミングガイド / magicien 

Open GL ES 2.0 プログラミングガイド ふと思い出してこの本を開いてみたところ、WebGLでのClipPlaneの実現方法が載っていた。

ES 1.1にはあったけど、2.0で無くなった機能をどう実装するか、という話が一通り載っていて、シェーダのプログラムもコピペしてそのまま使えるレベル。
そのうちの一つが、ユーザ定義クリップ面の話。

クリップ面の式を
Ax + By + Cz + D = 0
としたとき、
v_clipPlane = (A, B, C, D)
として次のシェーダを書けばOK。
( (A, B, C)はクリップ面に対する法線、Dは原点(0, 0)とクリップ面との距離になる。
 例えば、Y=0平面をクリップ面としたいなら、v_clipPlane=(0,1,0,0))

頂点シェーダ:
uniform vec4 v_clipPlane;
uniform mat4 matViewProjection;
attribute vec4 rm_Vertex;

varying float v_clipDist;

void main(void)
{
  v_clipDist = dot(rm_Vertex.xyz, u_clipPlane.xyz) + u_clipPlane.w;
  gl_Position = matViewProjection * rm_Vertex;
}

フラグメントシェーダ:
precision mediump float;
varying float v_clipDist;

void main(void)
{
  if(v_clipDist < 0.0)
    discard;

  gl_FragColor = vec4(0.5, 0.5, 1.0, 0.0);
}

頂点(rm_Vertex)毎にクリップ面との距離(v_clipDist)を計算しておく。
v_clipDist が 0 より小さい点はクリップ面の裏側にあることになるため、描画しない(discard)。
もっと難しい計算が必要だと思ったけど、恐ろしく簡単に実装できた。

2012/05/19(Sat) 22:44:29