2

I am trying to implement a fluid surface simulation using the paper Fast Hydraulic Erosion Simulation and Visualization on GPU as a template to simulate water. However, I get artifacts like this:

Wave artifacts

The code for my update function is below, I have followed another post on this subject, but the change did not help.

    private void updateHeight (float dt, float dx){
    float dhL, dhR, dhF, dhB, DV;
    float totalFlux;
    float updateConstant;
    float fluxConstant = dt*GRAVITY/(2*VISCOUSCOEFFICEINT*dx);
    //Update Flux
    for (int y=1; y<=N-1; y++){
        for(int x=1;x<=N-1;x++){
            dhL = this.height[x][y] - this.height[x-1][y];
            dhR = this.height[x][y] - this.height[x+1][y];
            dhF = this.height[x][y] - this.height[x][y+1];
            dhB = this.height[x][y] - this.height[x][y-1];

            if (Mathf.Abs(dhL) < 0.0001f){
                dhL=0.0f;
            }
            if (Mathf.Abs(dhR) < 0.0001f){
                dhR=0;
            }
            if (Mathf.Abs(dhF) < 0.0001f){
                dhF=0;
            }
            if (Mathf.Abs(dhB) < 0.0001f){
                dhB=0;
            }

            this.tempFluxArray[x][y].fluxL = Mathf.Max(0.0f, this.fluxArray[x][y].fluxL + fluxConstant*dhL);
            this.tempFluxArray[x][y].fluxR = Mathf.Max(0.0f, this.fluxArray[x][y].fluxR + fluxConstant*dhR);
            this.tempFluxArray[x][y].fluxF = Mathf.Max(0.0f, this.fluxArray[x][y].fluxF + fluxConstant*dhF);
            this.tempFluxArray[x][y].fluxB = Mathf.Max(0.0f, this.fluxArray[x][y].fluxB + fluxConstant*dhB);

            totalFlux = this.tempFluxArray[x][y].fluxL + this.tempFluxArray[x][y].fluxR + this.tempFluxArray[x][y].fluxF + this.tempFluxArray[x][y].fluxB;

            if(totalFlux > 0){
                updateConstant = Mathf.Min(1.0f, this.height[x][y]* dx*dx/(totalFlux * dt));
                this.tempFluxArray[x][y].fluxL = updateConstant * this.tempFluxArray[x][y].fluxL;
                this.tempFluxArray[x][y].fluxR = updateConstant * this.tempFluxArray[x][y].fluxR;
                this.tempFluxArray[x][y].fluxF = updateConstant * this.tempFluxArray[x][y].fluxF;
                this.tempFluxArray[x][y].fluxB = updateConstant * this.tempFluxArray[x][y].fluxB;
            }
        }
    }
    swap();
    //Height Calculation
    for (int y=1; y<=N-1; y++){
        for(int x=1;x<=N-1;x++){
            DV = dt*(this.fluxArray[x-1][y].fluxR + this.fluxArray[x][y-1].fluxF + this.fluxArray[x+1][y].fluxL + this.fluxArray[x][y+1].fluxB - this.fluxArray[x][y].fluxL - this.fluxArray[x][y].fluxR - this.fluxArray[x][y].fluxF - this.fluxArray[x][y].fluxB);
            this.height[x][y] = this.height[x][y] + DV/(dx*dx);
            if(this.height[x][y] < 1){
                // Debug.Log(x);
                // Debug.Log(y);
            }
        }
    }
}

Could it be due to using this rather than ref? The way I interact with the water surface written below.

    private void waterdrop(int x, int y){
    float sqrD = 0.8f*0.8f;
    for (int j = 1; j < N; j++) {
        for (int i = 1; i < N; i++) {
            float sqrDToVert = (float)0.2f*(i - x)*(i-x) + 0.2f*(j - y)*(j-y);
            if (sqrDToVert <= sqrD){
                float distanceCompensator = 1 - (sqrDToVert/sqrD);
                this.fluxArray[i][j].fluxL = this.fluxArray[i][j].fluxL + (0.02f * distanceCompensator);
                this.fluxArray[i][j].fluxR = this.fluxArray[i][j].fluxR + (0.02f * distanceCompensator);
                this.fluxArray[i][j].fluxF = this.fluxArray[i][j].fluxF + (0.02f * distanceCompensator);
                this.fluxArray[i][j].fluxB = this.fluxArray[i][j].fluxB + (0.02f * distanceCompensator);
                //this.height[i][j] = this.height[i][j] - 1.0f * distanceCompensator;
                Debug.Log(this.height[i][j]);
            }
            //Debug.Log("x = "+i+"\n y = "+j+" height is "+this.height[i][j]);
        }
    }
}

Namely just changing the flux at some point at all direction.

Some solutions I have tried was to change the height but that didn't work or clamp on small changes only but it only built up. The boundary conditions are zero flux on all boarders and the height would be the same as the closest point.

Brandon Fung
  • 27
  • 1
  • 7

0 Answers0