ボリュームレンダリングアプリケーション(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ないんだけど、そうそこにテキスト内のいくつかの大きなミスをしていると、あなたが何かを理解していない場合は、ちょうど私が知っていると私はこれらのバグを修正しようとするでしょう)
ありがとうございます。
効果的にあなたを助けるために、私たちはいくつかのコードを見る必要があります。 –