2014-10-27 25 views
6

tôi có:Khối lượng render trong WebGL

  1. một mảng 3D có chứa một tập dữ liệu 3d được hiển thị
  2. một ma trận 4x4 trong đó xác định khoảng cách/rộng/định hướng của khối lượng được hiển thị
  3. một opacity hàm truyền
  4. một chức năng chuyển màu

tôi muốn sử dụng ThreeJS để làm khối lượng render (MIP, RayCasting, vv) của dữ liệu này. Có một số trình đổ bóng/trình diễn có sẵn không?

Tôi có nên làm việc trực tiếp ở cấp độ bóng hoặc trong javascript không?

Bất kỳ mẫu gợi ý/code sẽ được rất nhiều đánh giá cao, nhất

+1

Có là khối diễu hành Ví dụ: http://threejs.org/examples/#webgl_marchingcubes –

+1

mrdoob cũng liên kết một ví dụ ông đã làm trong năm 2012 trong một vấn đề gihub: https://github.com/mrdoob/three.js/issues/1821 – Atrahasis

Trả lời

1

Có một số trình đổ bóng/trình diễn có sẵn không?

Leandro R Barbagallo đã viết an in-depth blog post về hiển thị khối lượng trong WebGL.

+0

Liên kết bị hỏng (thậm chí là Lưu trữ.org) – Kroltan

+0

@Kroltan Hmm, liên kết Archive.org hoạt động cho tôi –

+1

@Kroltan Ngoài ra, đây là repo GitHub của anh ấy: https://github.com/lebarba/WebGLVolumeRendering –

1

WAVE Client Renderer là thư viện dựa trên Three.js để hiển thị khối lượng thông qua Truyền đúc.

Tăng tốc GPU Khối lượng Ray Casting thường được triển khai hiển thị nhiều đường.

Đoạn đầu tiên của trình đổ bóng rất đơn giản. Nó vẽ đến tọa độ kết cấu (tại tọa độ đối tượng) của vị trí các tia của chúng chạm vào mặt sau của khối lập phương.

Bạn có thể tìm thấy ví dụ về trình đổ bóng GLSL, với các dấu nháy ejs bên dưới.

firstPass.frag

precision mediump int; 

precision mediump float; 



varying vec4 backColor; 



void main(void) 

{ 

    gl_FragColor = backColor; 

} 

firstPass.vert

precision mediump int; 

precision mediump float; 



attribute vec4 vertColor; 



varying vec4 backColor; 

varying vec4 pos; 



void main(void) 

{ 

    backColor = vertColor; 



    pos = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 

    gl_Position = pos; 

} 

Các đường chuyền thứ hai thực hiện một mẫu thực tế của dữ liệu và trực quan của hình ảnh cuối cùng.

secondPass.vert

precision mediump int; 

precision mediump float; 



attribute vec4 vertColor; 



varying vec4 backColor; 

varying vec4 pos; 



void main(void) 

{ 

    backColor = vertColor; 



    pos = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 

    gl_Position = pos; 

} 

secondPass.frag

#ifdef GL_FRAGMENT_PRECISION_HIGH 

// highp is supported 

precision highp int; 

precision highp float; 

#else 

// high is not supported 

precision mediump int; 

precision mediump float; 

#endif 



varying vec4 frontColor; 

varying vec4 pos; 



uniform sampler2D uBackCoord; 

uniform sampler2D uTransferFunction; 

uniform sampler2D uSliceMaps[<%= maxTexturesNumber %>]; 



uniform float uNumberOfSlices; 

uniform float uMinGrayVal; 

uniform float uMaxGrayVal; 

uniform float uOpacityVal; 

uniform float uColorVal; 

uniform float uAbsorptionModeIndex; 

uniform float uSlicesOverX; 

uniform float uSlicesOverY; 

uniform float uSteps; 

// uniform int uAvailable_textures_number; 



//Acts like a texture3D using Z slices and trilinear filtering. 

float getVolumeValue(vec3 volpos) 

{ 

    float s1Original, s2Original, s1, s2; 

    float dx1, dy1; 

    // float dx2, dy2; 

    // float value; 



    vec2 texpos1,texpos2; 



    float slicesPerSprite = uSlicesOverX * uSlicesOverY; 



    s1Original = floor(volpos.z*uNumberOfSlices); 

    // s2Original = min(s1Original + 1.0, uNumberOfSlices); 



    int tex1Index = int(floor(s1Original/slicesPerSprite)); 

    // int tex2Index = int(floor(s2Original/slicesPerSprite)); 



    s1 = mod(s1Original, slicesPerSprite); 

    // s2 = mod(s2Original, slicesPerSprite); 



    dx1 = fract(s1/uSlicesOverX); 

    dy1 = floor(s1/uSlicesOverY)/uSlicesOverY; 



    // dx2 = fract(s2/uSlicesOverX); 

    // dy2 = floor(s2/uSlicesOverY)/uSlicesOverY; 



    texpos1.x = dx1+(volpos.x/uSlicesOverX); 

    texpos1.y = dy1+(volpos.y/uSlicesOverY); 



    // texpos2.x = dx2+(volpos.x/uSlicesOverX); 

    // texpos2.y = dy2+(volpos.y/uSlicesOverY); 



    float value1 = 0.0, value2 = 0.0; 

    // bool value1Set = false, value2Set = false; 



    // int numberOfSlicemaps = int(ceil(uNumberOfSlices/(uSlicesOverX * uSlicesOverY))); 



    <% for(var i=0; i < maxTexturesNumber; i++) { %> 

     if(tex1Index == <%=i%>) 

     { 

      value1 = texture2D(uSliceMaps[<%=i%>],texpos1).x; 

     } 



     <% if(i < maxTexturesNumber-1) { %> 

      else 

     <% } %> 

    <% } %> 



    return value1; 



    // for (int x = 0; x < gl_MaxTextureImageUnits-2; x++) 

    // { 

    //  if(x == numberOfSlicemaps) 

    //  { 

    //   break; 

    //  } 



    //  if(x == tex1Index) { 

    //   value1 = texture2D(uSliceMaps[x],texpos1).x; 

    //   value1Set = true; 

    //  } 



    //  if(x == tex2Index) { 

    //   value2 = texture2D(uSliceMaps[x],texpos2).x; 

    //   value2Set = true; 

    //  } 



    //  if(value1Set && value2Set) { 

    //   break; 

    //  } 



    // } 



    // return mix(value1, value2, fract(volpos.z*uNumberOfSlices)); 



} 



void main(void) 

{ 

vec2 texC = ((pos.xy/pos.w) + 1.0)/2.0; 



vec4 backColor = texture2D(uBackCoord,texC); 



vec3 dir = backColor.rgb - frontColor.rgb; 

//dir /= length(dir); 



vec4 vpos = frontColor; 



//  vec3 Step = dir/uSteps; 

vec3 Step = dir/uSteps; 



vec4 accum = vec4(0, 0, 0, 0); 

vec4 sample = vec4(0.0, 0.0, 0.0, 0.0); 

vec4 colorValue = vec4(0, 0, 0, 0); 

float biggest_gray_value = 0.0; 



float opacityFactor = uOpacityVal; 

float lightFactor = uColorVal; 



// const 4095 - just example of big number 

// It because expression i > uSteps impossible 

for(float i = 0.0; i < 4095.0; i+=1.0) 

{ 

// It because expression i > uSteps impossible 

    if(i == uSteps) { 

     break; 

    } 



    float gray_val = getVolumeValue(vpos.xyz); 



    if(gray_val < uMinGrayVal || gray_val > uMaxGrayVal) { 

     colorValue = vec4(0.0); 

    } else { 

     if(biggest_gray_value < gray_val) { 

      biggest_gray_value = gray_val; 

     } 



     if(uAbsorptionModeIndex == 0.0) 

     { 

      vec2 tf_pos; 

      tf_pos.x = (gray_val - uMinGrayVal)/(uMaxGrayVal - uMinGrayVal); 

      tf_pos.y = 0.5; 



      colorValue = texture2D(uTransferFunction,tf_pos); 

      //colorValue = vec4(tf_pos.x, tf_pos.x, tf_pos.x, 1.0); 



      sample.a = colorValue.a * opacityFactor; 

      sample.rgb = colorValue.rgb * uColorVal; 

      accum += sample; 



      if(accum.a>=1.0) 

       break; 



     } 



     if(uAbsorptionModeIndex == 1.0) 

     { 

      vec2 tf_pos; 

      tf_pos.x = (gray_val - uMinGrayVal)/(uMaxGrayVal - uMinGrayVal); 

      tf_pos.y = 0.5; 



      colorValue = texture2D(uTransferFunction,tf_pos); 

      //colorValue = vec4(tf_pos.x, tf_pos.x, tf_pos.x, 1.0); 



      sample.a = colorValue.a * opacityFactor * (1.0/uSteps); 

      sample.rgb = (1.0 - accum.a) * colorValue.rgb * sample.a * lightFactor; 

      accum += sample; 



      if(accum.a>=1.0) 

       break; 



     } 



     if(uAbsorptionModeIndex == 2.0) 

     { 

      vec2 tf_pos; 

      tf_pos.x = (biggest_gray_value - uMinGrayVal)/(uMaxGrayVal - uMinGrayVal); 

      tf_pos.y = 0.5; 



      colorValue = texture2D(uTransferFunction,tf_pos); 

      //colorValue = vec4(tf_pos.x, tf_pos.x, tf_pos.x, 1.0); 

      sample.a = colorValue.a * opacityFactor; 

      sample.rgb = colorValue.rgb * uColorVal; 



      accum = sample; 



     } 



    } 



    //advance the current position 

    vpos.xyz += Step; 



    //break if the position is greater than <1, 1, 1> 

    if(vpos.x > 1.0 || vpos.y > 1.0 || vpos.z > 1.0 || vpos.x < 0.0 || vpos.y < 0.0 || vpos.z < 0.0) 

    { 

     break; 

    } 



} 



gl_FragColor = accum; 



} 
+0

bây giờ có tốt hơn không? –

Các vấn đề liên quan