﻿ 利用着色器迭代求解离散泊松方程 - 鸿网互联

# 利用着色器迭代求解离散泊松方程

d2z(x,y)/dx2 +d2z(x,y)/dy2 =f(x,y)

d2z(i,j)/dx2 +d2z(i,j)/dy2 = z(i-1,j)+z(i,j-1)+z(i+1,j)+z(i,j+1)-4z(i,j)

z(i,j)=1/4(z(i-1,j)+z(i,j-1)+z(i+1,j)+z(i,j+1)+f(i,j))

zn+1(i,j)=1/4(zn(i-1,j)+zn(i,j-1)+zn(i+1,j)+zn(i,j+1)+f(i,j))

```  1 #version 400
2 #extension GL_ARB_texture_rectangle : enable
3
4
5 //original image which will not be changed
6 uniform sampler2DRect inputImg;
7
8 //red as dirichlet boundary,blue as neumann boundary
9 uniform sampler2DRect constraintImg;
10
11 uniform sampler2DRect tmpImg;
12
13 uniform vec2 size;
14
15
16 void main()
17 {
18     vec2 coord = gl_FragCoord.xy;
19     vec4 inputColor=texture2DRect(inputImg, coord);
20     vec4 tmpColor = texture2DRect(tmpImg, coord);
21     vec4 constraintColor= texture2DRect(constraintImg, coord);
22
23     if(inputColor.w<0.01)//input 4channel as mask
24     {
25         //outside mask,should be zero
26         gl_FragColor = vec4(0,0,0,1);
27     }
28     else if(constraintColor.x>0.99)//red
29     {
30         //dirichlet boundary,remain the original color
31         gl_FragColor = inputColor;
32     }
33     else if(constraintColor.x<0.01 && constraintColor.y>0.01)//green
34     {
35         if(constraintColor.y>0.99)
36             gl_FragColor = inputColor;
37         else
38         {
39             vec4 f = vec4(constraintColor.w,constraintColor.w,constraintColor.w,constraintColor.w);
40             vec4 a = texture2DRect(tmpImg, coord + vec2(-1, 0));
41             vec4 b = texture2DRect(tmpImg, coord + vec2(1, 0));
42             vec4 c = texture2DRect(tmpImg, coord + vec2(0, -1));
43             vec4 d = texture2DRect(tmpImg, coord + vec2(0, 1));
44             vec4 res= 0.25*(a+b+c+d+f);
45             res=(1 - constraintColor.y) * res + constraintColor.y * inputColor;
46             gl_FragColor = res;
47         }
48     }
49     else if(constraintColor.x<0.01 && constraintColor.z>0.99)//blue
50     {
51         //neumann boundary,derivative is zero,should be inside mask
52         //so we decide to use the average color of its inside region neighbors as the approximation
53         int count=0;
54         vec4 res = vec4(0,0,0,0);
55         vec4 ma = texture2DRect(inputImg, coord+vec2(-1,0));
56         if(ma.w>=0.9)//inside mask region
57         {
58             vec4 a = texture2DRect(tmpImg, coord+vec2(-1,0));
59             res+=a;
60             count+=1;
61
62         }
63
64         vec4 mb = texture2DRect(inputImg, coord+vec2(1,0));
65         if(mb.w>=0.9)
66         {
67             vec4 b = texture2DRect(tmpImg, coord + vec2(1, 0));
68             res+=b;
69             count+=1;
70         }
71
72         vec4 mc = texture2DRect(inputImg, coord+vec2(0,-1));
73         if(mc.w>=0.9)
74         {
75             vec4 c = texture2DRect(tmpImg, coord + vec2(0, -1));
76             res+=c;
77             count+=1;
78         }
79
80         vec4 md = texture2DRect(inputImg, coord+vec2(0,1));
81         if(md.w>=0.9)
82         {
83             vec4 d = texture2DRect(tmpImg, coord + vec2(0, 1));
84             res+=d;
85             count+=1;
86         }
87
88         if(count>0)
89             res/=count;
90
91         gl_FragColor=res;
92     }
93     else
94     {
95         //inside poisson,jacobi iteration
96         vec4 f = vec4(constraintColor.w,constraintColor.w,constraintColor.w,constraintColor.w);
97         vec4 a = texture2DRect(tmpImg, coord + vec2(-1, 0));
98         vec4 b = texture2DRect(tmpImg, coord + vec2(1, 0));
99         vec4 c = texture2DRect(tmpImg, coord + vec2(0, -1));
100         vec4 d = texture2DRect(tmpImg, coord + vec2(0, 1));
101         vec4 res = 0.25*(a+b+c+d+f);
102
103         gl_FragColor=res;
104     }
105
106 }```

<