上記で説明したように、レイトレーシングを使用して 3D シーンを 2D プレーンにレンダリングしたいと考えています。最終的にはボリューム レンダリングに使用したいと考えていますが、ここでの基本に苦労しています。ビュープレーンがカメラに接続された (もちろんカメラの前にある) three.js シーンがあります。
セットアップ:
次に (シェーダーで) 平面の各ポイント (250x250) を通してカメラから光線を放ちます。平面の後ろには 41x41x41 のボリューム (本質的に立方体) があります。光線が立方体を通過する場合、光線が交差したビュー プレーン内のポイントは赤くレンダリングされ、それ以外の場合、ポイントは黒になります。残念ながら、これは立方体を正面から見た場合にのみ機能します。例は次のとおりです: http://ec2-54-244-155-66.us-west-2.compute.amazonaws.com/example.html
立方体をさまざまな角度から見ようとすると (マウスでカメラを動かすことができます)、希望どおりにビュー プレーンに立方体がレンダリングされませんが、側面にいくつかの奇妙なピクセルがある正方形が表示されます..
これがレイトレーシングのコードです。
頂点シェーダー:
bool inside(vec3 posVec){
bool value = false;
if(posVec.x <0.0 ||posVec.x > 41.0 ){
value = false;
}
else if(posVec.y <0.0 ||posVec.y > 41.0 ){
value = false;
}
else if(posVec.z <0.0 ||posVec.z > 41.0 ){
value = false;
}
else{
value = true;
}
return value;
}
float getDensity(vec3 PointPos){
float stepsize = 1.0;
float emptyStep = 15.0;
vec3 leap;
bool hit = false;
float density = 0.000;
// Ray direction from the camera through the current point in the Plane
vec3 dir = PointPos- camera;
vec3 RayDirection = normalize(dir);
vec3 start = PointPos;
for(int i = 0; i<STEPS; i++){
vec3 alteredPosition = start;
alteredPosition.x += 20.5;
alteredPosition.y += 20.5;
alteredPosition.z += 20.5;
bool insideTest = inside(alteredPosition);
if(insideTest){
// advance from the start position
start = start + RayDirection * stepsize;
hit = true;
}else{
leap = start + RayDirection * emptyStep;
bool tooFar = inside(leap);
if(tooFar){
start = start + RayDirection * stepsize;
}else{
start = leap;
}
}
}
if(hit){
density = 1.000;
}
return density;
}
void main() {
PointIntensity = getDensity(position);
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * mvPosition;
}
フラグメント シェーダー:
varying float PointIntensity;
void main() {
//Rays that have traversed the volume (cube) should leave a red point on the viewplane, Rays that just went through empty space a black point
gl_FragColor= vec4(PointIntensity, 0.0, 0.0, 1.0);
}
完全なコード: http://pastebin.com/4YmWL0u1
同じコードで実行中: http://ec2-54-244-155-66.us-west-2.compute.amazonaws.com/example.html
ここで私が間違っていたことについて誰かが何かヒントを持っていれば、とてもうれしいです
編集:
Mark Lundin が提案した変更を加えて例を更新しましたが、残念ながら、カメラを動かしたときにまだ赤い四角しか表示されません (側面に奇妙なピクセルはありません)。
mat4 uInvMVProjMatrix = modelViewMatrix *inverseProjectionMatrix;
inverseProjectionMatrix は Three.js のカメラ プロパティ ProjectionMatrixInverse であり、ユニフォームとしてシェーダーに渡されます。次に、UV 座標を使用して、ビュープレーン内のすべてのポイントに対して unproject 関数が呼び出されます。
新しいコードは次のとおりです。
ここで実行しています:
http://ec2-54-244-155-66.us-west-2.compute.amazonaws.com/example.html
カメラが実際に移動していることを確認するには、x、y、z を押して現在のカメラの x、y、z 座標を取得します。