2016-04-05 7 views
0

ボリュームレンダリングアプリケーション(C#+ OpenTK)で作業しています。 ボリュームはレイキャスティングを使用してレンダリングされていますが、私はこのサイトで多くのインスピレーションを見つけました: http://graphicsrunner.blogspot.sk/2009/01/volume-rendering-101.html、私のアプリケーションはOpenGLで動作しますが、3Dテクスチャなどを使用する主なアイデアは同じです。 アプリケーションは正常に動作しますが、「ボリュームに流入」すると(境界ボックスの内側を意味する)、すべてが消えてしまい、これを防止したいと考えています。では、これを行う簡単な方法がいくつかありますか? →私は音量を流したり、音量を動かすことができます。ここでボリュームを流れるレイキャスティングを使用したボリュームレンダリング

は、フラグメントシェーダのコードです:

#version 330 

in vec3 EntryPoint; 
in vec4 ExitPointCoord; 

uniform sampler2D ExitPoints; 
uniform sampler3D VolumeTex; 
uniform sampler1D TransferFunc; 
uniform float  StepSize; 
uniform float  AlphaReduce; 
uniform vec2  ScreenSize; 
layout (location = 0) out vec4 FragColor; 

void main() 
{ 
//gl_FragCoord --> http://www.txutxi.com/?p=182 
vec3 exitPoint = texture(ExitPoints, gl_FragCoord.st/ScreenSize).xyz; 

//background need no raycasting 
if (EntryPoint == exitPoint) 
    discard; 

vec3 rayDirection = normalize(exitPoint - EntryPoint); 
vec4 currentPosition = vec4(EntryPoint, 0.0f); 
vec4 colorSum = vec4(.0f,.0f,.0f,.0f); 
vec4 color = vec4(0.0f,0.0f,0.0f,0.0f); 
vec4 value = vec4(0.0f); 

vec3 Step = rayDirection * StepSize; 
float stepLength= length(Step); 
float LengthSum = 0.0f; 
float Length = length(exitPoint - EntryPoint); 

for(int i=0; i < 16000; i++) 
{ 
    currentPosition.w = 0.0f; 
    value = texture(VolumeTex, currentPosition.xyz); 
    color = texture(TransferFunc, value.a); 

    //reduce the alpha to have a more transparent result 
    color.a *= AlphaReduce; 

    //Front to back blending 
    color.rgb *= color.a; 
    colorSum = (1.0f - colorSum.a) * color + colorSum; 

    //accumulate length 
    LengthSum += stepLength; 

    //break from the loop when alpha gets high enough 
    if(colorSum.a >= .95f) 
     break; 

    //advance the current position 
    currentPosition.xyz += Step; 

    //break if the ray is outside of the bounding box 
    if(LengthSum >= Length) 
     break; 
} 
FragColor = colorSum; 
} 

以下のコードはhttps://github.com/toolchainX/Volume_Rendering_Using_GLSL

ディスプレイ()関数に基づいていますことを

public void Display() 
    { 
     // the color of the vertex in the back face is also the location 
     // of the vertex 
     // save the back face to the user defined framebuffer bound 
     // with a 2D texture named `g_bfTexObj` 
     // draw the front face of the box 
     // in the rendering process, i.e. the ray marching process 
     // loading the volume `g_volTexObj` as well as the `g_bfTexObj` 
     // after vertex shader processing we got the color as well as the location of 
     // the vertex (in the object coordinates, before transformation). 
     // and the vertex assemblied into primitives before entering 
     // fragment shader processing stage. 
     // in fragment shader processing stage. we got `g_bfTexObj` 
     // (correspond to 'VolumeTex' in glsl)and `g_volTexObj`(correspond to 'ExitPoints') 
     // as well as the location of primitives. 

     // draw the back face of the box 
     GL.Enable(EnableCap.DepthTest); 

     //"vykreslim" front || back face objemu do framebuffru --> teda do 2D textury s ID bfTexID 
     //(pomocou backface.frag &.vert) 
     GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBufferID); 
     GL.Viewport(0, 0, width, height); 
     LinkShader(spMain.GetProgramHandle(), bfVertShader.GetShaderHandle(), bfFragShader.GetShaderHandle()); 
     spMain.UseProgram(); 
     //cull front face 
     Render(CullFaceMode.Front); 
     spMain.UseProgram(0); 
     //klasicky framebuffer --> "obrazovka" 
     GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); 

     GL.Viewport(0, 0, width, height); 
     LinkShader(spMain.GetProgramHandle(), rcVertShader.GetShaderHandle(), rcFragShader.GetShaderHandle()); 
     spMain.UseProgram(); 
     SetUniforms(); 
     Render(CullFaceMode.Back); 
     spMain.UseProgram(0); 

     GL.Disable(EnableCap.DepthTest); 
    } 

    private void DrawBox(CullFaceMode mode) 
    { 
     // --> Face culling allows non-visible triangles of closed surfaces to be culled before expensive Rasterization and Fragment Shader operations. 
     GL.Enable(EnableCap.CullFace); 
     GL.CullFace(mode); 
     GL.BindVertexArray(VAO); 
     GL.DrawElements(PrimitiveType.Triangles, 36, DrawElementsType.UnsignedInt, 0); 
     GL.BindVertexArray(0); 
     GL.Disable(EnableCap.CullFace); 
     spMain.UseProgram(0);//zapnuty bol v Render() ktora DrawBox zavolala 
    } 

    private void Render(CullFaceMode mode) 
    { 
     GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
     GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); 
     spMain.UseProgram(); 
     spMain.SetUniform("modelViewMatrix", Current); 
     spMain.SetUniform("projectionMatrix", projectionMatrix); 
     DrawBox(mode); 
    } 

問題がある(と思います)私はボリュームに向かって動いているので(私はカメラを動かさず、ボリュームをスケーリングするだけです)、スケールファクタが2.7を超えると、私はボリュームにあります。最終的な画像がレンダリングされるので、何も見ることができません。 >)ボリュームに

2.スケーリングしない -

1):私はスケールファクタに到達した場合= 2.7something :私は考えることができる 溶液(多分)は、そのようなことです何らかの長さ(おそらくスケールファクタに基づいて)のために、 RayDirectionに向かってEntryPointを移動するようシェーダを断片化するように言われました。

は今、私はこの "方法" を試してみました、それは働くことができるようです:

vec3 entryPoint = EntryPoint + some_value * rayDirection; 

some_valueは[0,1 [インターバルの間にクランプする必要が (または[0,1]?)しかし、多分それは問題でそれにさんに感謝していません:

if (EntryPoint == exitPoint) 
discard; 

だから今、多分(私の解決策はそれほど悪いわけではない場合)、私はこれに私の答えを変更することができます。 some_valueを計算する方法(ベースフラグメントシェーダーに送るスケールファクター)?

if(scale_factor < 2.7something) 
    work like before; 
else 
{ 
    compute some_value; //(I need help with this part) 
    change entry point; 
    work like before; 
} 

(私は英語のネイティブspeekerないんだけど、そうそこにテキスト内のいくつかの大きなミスをしていると、あなたが何かを理解していない場合は、ちょうど私が知っていると私はこれらのバグを修正しようとするでしょう)

ありがとうございます。

+0

効果的にあなたを助けるために、私たちはいくつかのコードを見る必要があります。 –

答えて

0

私は私の問題を解決しました。それは "ボリュームに囲まれている"錯覚にはなりませんが、今ではボリュームを流れて何も消えることはありません。 これが私の解決策のコードはシェーダを断片化するために追加されます。

vec3 entryPoint = vec3(0.0f); 

if(scaleCoeff >= 2.7f) 
{ 
    float tmp = min((scaleCoeff - 2.7f) * 0.1f, 1.0f); 
    entryPoint = EntryPoint + tmp * (exitPoint - EntryPoint); 
} 
else 
{ 
    entryPoint = EntryPoint; 
} 
// 

しかし、あなたが知っているか「ボリュームに囲まれている」効果を作るよりよい解決策を考えることができれば、あなたが許可すれば、私は喜んでいますよ私は知っている。

ありがとうございます。

関連する問題