2015-05-14 121 views
2

我们一直在尝试在WebGL中渲染3D云域时进行大量工作。我们迄今采用的方法概述为here - 每个射线的开始位置是体积立方体前面的当前位置,并且结束位置是根据前一遍计算的,该前一遍将xyx vales编码为背面质地。从体积中渲染体积

当摄像机位于音量范围内时,我们该如何扩展此功能?我们是否需要立即创建更小的体积立方体?我们能否改变着色器从摄像头开始行进,而不是从正面进入,然后投影到立方体的背面?

我们不确定从哪里开始!

在此先感谢

回答

0

只渲染一次。

在那个过程中,你只渲染背面。摄像机位置需要从世界坐标转换为3轴坐标系统,它们与您渲染的音量盒的大小一致。您的目标是创建一个4x4矩阵,其中所有列向量都是vec4(...,0),这些向量的x,y,z由x,y,z轴方向与卷盒长度定义。如果该框与x轴平行,则该矢量是(1,0,0)。如果它被拉伸到(2,0,0),那么它就是它自己的x轴,它将成为矩阵中第0列的列向量。用y和z轴和它们的长度这样做。矩阵中的最后一个列向量就是这个矩阵的位置,这个矩阵就是vec4(tx,ty,tz,1),然后这个矩阵定义了一个坐标系,然后用它来把摄影机的位置转换成统一的(0,0,0 ) - (1,1,1)框的体积。

创建该卷的反矩阵矩阵,并将凸轮从右侧乘以vec4(campos,1)到invVolMatrix。将生成的vec3作为UNIFORM发送到着色器。

只渲染背景(0,0,0)到(1,1,1)坐标在它们各自的volBox角上 - 就像你已经做过的那样。现在,你有你的着色器

  1. 均匀坎波斯
  2. 背面voltex协调
  3. 你知道你的volbox与对角线局部坐标系的单位立方体从(0,0,0)(1 ,1,1)

在着色器做:

varying vec3 vLocalUnitTexCoord; // backface interpolated coordinate 
uniform vec3 LOCAL_CAM_POS;  // localised camPos 

struct AABB { 
    vec3 min; // (0,0,0) 
    vec3 max; // (1,1,1) 
}; 

struct Ray { 
    vec3 origin; vec3 dir; 
}; 

float getUnitAABBEntry(in Ray r) { 
    AABB b; 
    b.min = vec3(0); 
    b.max = vec3(1); 

    // compute clipping for box.min and box.max corner 
    vec3 rInvDir = vec3(1.0)/r.dir; 
    vec3 tMinima = (b.min - r.origin) * rInvDir; 
    vec3 tMaxima = (b.max - r.origin) * rInvDir; 

    // sort for nearest corner 
    vec3 tEntries = min(tMinima, tMaxima); 

    // find first real entry value of 3 t-distance values in vec3 container 
    vec2 tMaxEntryCandidates = max(vec2(tEntries.st), vec2(tEntries.pp)); 
    float tMaxEntry = max(tMaxEntryCandidates.s, tMaxEntryCandidates.t); 
} 

vec3 getCloserPos(in vec3 camera, in vec3 frontFaceIntersection, in float t) { 
    float useFrontCoord = 0.5 + 0.5 * sign(t); 
    vec3 startPos = mix(camera, frontFaceIntersection, useFrontCoord); 
    return startPos; 
} 

vec4 main(void) 
{ 
    Ray r; 
    r.origin = LOCAL_CAM_POS; 
    r.dir = normalize(vLocalUnitTexCoord - LOCAL_CAM_POS); 

    float t = getUnitAABBEntry(r); 
    vec3 frontFaceLocalUnitTexCoord = r.origin + r.dir * t; 
    vec3 startPos = getCloserPos(LOCAL_CAM_POS, frontFaceLocalUnitTexCoord, t); 

    // loop for integration follows here 
    vec3 start = startpos; 
    vec3 end = vLocalUnitTexCoord; 
    ...for loop..etc... 
} 

编码愉快!