WEBGL流体模拟

时间:2017-06-28 01:12:28

标签: webgl fluid

我正在尝试使用http://meatfighter.com/fluiddynamics/GPU_Gems_Chapter_38.pdf作为资源,使用WebGL进行流体模拟。我已经实现了所有功能,但我觉得有很多东西没有正常工作。我增加了边界,但似乎它们没有效果,这使我怀疑压力和平流有多大作用。我显示了发散,我在移动物体的位置以及速度到达边缘(边界)的地方变得非常小,但是我得到的压力是完全空的。我使用扩散着色器计算压力,如链接资源中所述。

我知道我发布的代码由于它的性质而有点混乱。如果有帮助,我可以提供任何图片/链接到模拟。

- 编辑 -

经过一番调查后,我认为问题与我的平流功能有关。或者至少是一个问题。我不确定如何解决它。

我所遵循的一般流程不是发布我的所有代码,而是: 平流速度 扩散速度 加速度 计算分歧 计算压力 减去渐变

用于扩散速度和计算压力我只进行了10次迭代,因为我的所有计算机都可以处理我的实现(我会优化一旦我开始工作),但我觉得计算压力和减去梯度没有任何影响。

这是我正在使用的着色器:

//advection
uniform vec2 res;//The width and height of our screen
uniform sampler2D velocity;//input velocity
uniform sampler2D quantity;//quantity to advect


void main() {
        vec2 pixel = gl_FragCoord.xy / res.xy;

        float i0, j0, i1, j1;
        float x, y, s0, s1, t0, t1, dxt0, dyt0;
        float dt = 1.0/60.0;
        float Nx = res.x -1.0;
        float Ny = res.y -1.0;
        float i = pixel.x;
        float j = pixel.y;

        dxt0 = dt  ;
        dyt0 = dt  ;
        x = gl_FragCoord.x - dxt0 * (texture2D(velocity, pixel).x );
        y = gl_FragCoord.y - dyt0 * (texture2D(velocity, pixel).y );

        i0=x-0.5; 
        i1=x+0.5;

        j0=y-0.5; 
        j1=y+0.5;


        s1 = x-i0; 
        s0 = 1.0-s1; 
        t1 = y-j0; 
        t0 = 1.0-t1;


        float p1 =  (t0 * texture2D(quantity, vec2(i0,j0)/res.xy).r);
        float p2 =  (t1 * texture2D(quantity, vec2(i0,j1)/res.xy).r);
        float p3 =  (t0 * texture2D(quantity, vec2(i1,j0)/res.xy).r);
        float p4 =  (t1 * texture2D(quantity, vec2(i1,j1)/res.xy).r);
        float total1 = s0 * (p1 + p2);
        float total2 = s1 * (p3 + p4);
        gl_FragColor.r = total1 + total2;

        p1 =  (t0 * texture2D(quantity, vec2(i0,j0)/res.xy).g);
        p2 =  (t1 * texture2D(quantity, vec2(i0,j1)/res.xy).g);
        p3 =  (t0 * texture2D(quantity, vec2(i1,j0)/res.xy).g);
        p4 =  (t1 * texture2D(quantity, vec2(i1,j1)/res.xy).g);
        total1 = s0 * (p1 + p2);
        total2 = s1 * (p3 + p4);
        gl_FragColor.g = total1 + total2;

}

//diffusion shader starts here

uniform vec2 res;//The width and height of our screen
uniform sampler2D x;//Our input texture
uniform sampler2D b;
uniform float alpha;
uniform float rBeta;


void main() {
    float xPixel = 1.0/res.x;
    float yPixel = 1.0/res.y;
    vec2 pixel = gl_FragCoord.xy / res.xy;
    gl_FragColor = texture2D( b, pixel );

    vec4 leftColor = texture2D(x,vec2(pixel.x-xPixel,pixel.y));
    vec4 rightColor = texture2D(x,vec2(pixel.x+xPixel,pixel.y));
    vec4 upColor = texture2D(x,vec2(pixel.x,pixel.y-yPixel));

    vec4 downColor = texture2D(x,vec2(pixel.x,pixel.y+yPixel));




    gl_FragColor.r = (gl_FragColor.r * alpha +leftColor.r   + rightColor.r + upColor.r + downColor.r) * rBeta;

    gl_FragColor.g = (gl_FragColor.g * alpha +leftColor.g   + rightColor.g + upColor.g + downColor.g)* rBeta;


    gl_FragColor.b = (gl_FragColor.b * alpha +leftColor.b   + rightColor.b + upColor.b + downColor.b)* rBeta;


}



//gradient
uniform vec2 res;//The width and height of our screen
uniform sampler2D velocity;//Our input velocity
uniform sampler2D pressure;//Our input pressure

void main() {
    float xPixel = 1.0/res.x;
    float yPixel = 1.0/res.y;
    vec2 pixel = gl_FragCoord.xy / res.xy;

    vec4 leftColor  = texture2D(pressure, vec2(pixel.x-xPixel,pixel.y));
    vec4 rightColor = texture2D(pressure, vec2(pixel.x+xPixel,pixel.y));
    vec4 upColor    = texture2D(pressure, vec2(pixel.x,pixel.y-yPixel));
    vec4 downColor  = texture2D(pressure, vec2(pixel.x,pixel.y+yPixel));




    vec2 gradient = xPixel/2.0 * vec2((rightColor.x - leftColor.x), (upColor.y - downColor.y));
    //Diffuse equation
    gl_FragColor = texture2D(velocity, pixel) ;
    gl_FragColor.xy -= gradient;



}



uniform vec2 res;//The width and height of our screen
uniform sampler2D velocity;//Our input texture


void main() {
    float xPixel = 1.0/res.x;
    float yPixel = 1.0/res.y;
    vec2 pixel = gl_FragCoord.xy / res.xy;

    vec4 leftColor  = texture2D(velocity, vec2(pixel.x-xPixel,pixel.y));
    vec4 rightColor = texture2D(velocity, vec2(pixel.x+xPixel,pixel.y));
    vec4 upColor    = texture2D(velocity, vec2(pixel.x,pixel.y-yPixel));
    vec4 downColor  = texture2D(velocity, vec2(pixel.x,pixel.y+yPixel));




    float div = xPixel/2.0 * ((rightColor.x - leftColor.x) + (upColor.y - downColor.y));
    //Diffuse equation
    gl_FragColor = vec4(div);



}

0 个答案:

没有答案