Revision 4aa38649
Added by Leszek Koltunski almost 6 years ago
src/main/java/org/distorted/library/effect/VertexEffectDeform.java | ||
---|---|---|
110 | 110 |
{ |
111 | 111 |
addEffect( EffectName.DEFORM, |
112 | 112 |
|
113 |
"const vec2 ONE = vec2(1.0,1.0); \n"
|
|
113 |
"const vec3 ONE = vec3(1.0,1.0,1.0); \n"
|
|
114 | 114 |
+ "const float A = 0.5; \n" |
115 | 115 |
+ "const float B = 0.2; \n" |
116 | 116 |
+ "const float C = 5.0; \n" |
117 | 117 |
|
118 |
+ "vec2 center = vUniforms[effect+1].yz; \n"
|
|
119 |
+ "vec2 ps = center-v.xy; \n"
|
|
120 |
+ "vec2 aPS = abs(ps); \n"
|
|
121 |
+ "vec2 maxps = u_objD.xy + abs(center); \n"
|
|
118 |
+ "vec3 center = vUniforms[effect+1].yzw; \n"
|
|
119 |
+ "vec3 ps = center-v.xyz; \n"
|
|
120 |
+ "vec3 aPS = abs(ps); \n"
|
|
121 |
+ "vec3 maxps = u_objD + abs(center); \n"
|
|
122 | 122 |
+ "float d = degree_region(vUniforms[effect+2],ps); \n" |
123 | 123 |
+ "vec3 force = vUniforms[effect].xyz * d; \n" |
124 |
+ "vec2 aForce = abs(force.xy); \n"
|
|
125 |
+ "float denom = dot(ps+(1.0-d)*force.xy,ps); \n"
|
|
124 |
+ "vec3 aForce = abs(force); \n"
|
|
125 |
+ "float denom = dot(ps+(1.0-d)*force,ps); \n" |
|
126 | 126 |
+ "float one_over_denom = 1.0/(denom-0.001*(sign(denom)-1.0)); \n" |
127 |
+ "vec2 Aw = A*maxps; \n"
|
|
128 |
+ "vec2 quot = ps / maxps; \n"
|
|
127 |
+ "vec3 Aw = A*maxps; \n"
|
|
128 |
+ "vec3 quot = ps / maxps; \n"
|
|
129 | 129 |
+ "quot = quot*quot; \n" // ( (x/W)^2 , (y/H)^2 ) where x,y are distances from V to center |
130 | 130 |
|
131 | 131 |
+ "float denomV = 1.0 / (aForce.y + Aw.x); \n" |
132 | 132 |
+ "float denomH = 1.0 / (aForce.x + Aw.y); \n" |
133 | 133 |
|
134 |
+ "vec2 vertCorr= ONE - aPS / ( aForce+C*aPS + (ONE-sign(aForce)) ); \n" // avoid division by 0 when force and PS both are 0
|
|
134 |
+ "vec3 vertCorr= ONE - aPS / ( aForce+C*aPS + (ONE-sign(aForce)) ); \n" // avoid division by 0 when force and PS both are 0
|
|
135 | 135 |
|
136 | 136 |
+ "float mvXvert = -B * ps.x * aForce.y * (1.0-quot.y) * denomV; \n" // impact the vertical component of the force vector has on horizontal movement |
137 | 137 |
+ "float mvYhorz = -B * ps.y * aForce.x * (1.0-quot.x) * denomH; \n" // impact the horizontal component of the force vector has on vertical movement |
... | ... | |
144 | 144 |
+ "v.z += force.z*d*d*(3.0*d*d -8.0*d +6.0); \n" // thick bubble |
145 | 145 |
+ "float b = -(12.0*force.z*d*(1.0-d)*(1.0-d)*(1.0-d))*one_over_denom; \n" |
146 | 146 |
|
147 |
+ "n.xy += n.z*b*ps;" |
|
147 |
+ "n.xy += n.z*b*ps.xy;"
|
|
148 | 148 |
); |
149 | 149 |
} |
150 | 150 |
|
... | ... | |
178 | 178 |
super(EffectName.DEFORM); |
179 | 179 |
mVector = vector; |
180 | 180 |
mCenter = center; |
181 |
mRegion = new Static4D(0,0,Float.MAX_VALUE, Float.MAX_VALUE);
|
|
181 |
mRegion = new Static4D(0,0,0, Float.MAX_VALUE);
|
|
182 | 182 |
} |
183 | 183 |
} |
src/main/java/org/distorted/library/effect/VertexEffectDistort.java | ||
---|---|---|
112 | 112 |
{ |
113 | 113 |
addEffect(EffectName.DISTORT, |
114 | 114 |
|
115 |
"vec2 center = vUniforms[effect+1].yz; \n"
|
|
116 |
+ "vec2 ps = center-v.xy; \n"
|
|
115 |
"vec3 center = vUniforms[effect+1].yzw; \n"
|
|
116 |
+ "vec3 ps = center-v.xyz; \n"
|
|
117 | 117 |
+ "vec3 force = vUniforms[effect].xyz; \n" |
118 | 118 |
+ "float d = degree(vUniforms[effect+2],center,ps); \n" |
119 |
+ "float denom = dot(ps+(1.0-d)*force.xy,ps); \n"
|
|
119 |
+ "float denom = dot(ps+(1.0-d)*force,ps); \n" |
|
120 | 120 |
+ "float one_over_denom = 1.0/(denom-0.001*(sign(denom)-1.0)); \n" // = denom==0 ? 1000:1/denom; |
121 | 121 |
|
122 | 122 |
//v.z += force.z*d; // cone |
... | ... | |
129 | 129 |
+ "float b = -(12.0*force.z*d*(1.0-d)*(1.0-d)*(1.0-d))*one_over_denom; \n" // |
130 | 130 |
|
131 | 131 |
+ "v.xy += d*force.xy; \n" |
132 |
+ "n.xy += n.z*b*ps;" |
|
132 |
+ "n.xy += n.z*b*ps.xy;"
|
|
133 | 133 |
); |
134 | 134 |
} |
135 | 135 |
|
... | ... | |
161 | 161 |
super(EffectName.DISTORT); |
162 | 162 |
mVector = vector; |
163 | 163 |
mCenter = center; |
164 |
mRegion = new Static4D(0,0,Float.MAX_VALUE, Float.MAX_VALUE);
|
|
164 |
mRegion = new Static4D(0,0,0, Float.MAX_VALUE);
|
|
165 | 165 |
} |
166 | 166 |
} |
167 | 167 |
|
src/main/java/org/distorted/library/effect/VertexEffectPinch.java | ||
---|---|---|
69 | 69 |
{ |
70 | 70 |
addEffect(EffectName.PINCH, |
71 | 71 |
|
72 |
"vec2 center = vUniforms[effect+1].yz; \n"
|
|
73 |
+ "vec2 ps = center-v.xy; \n"
|
|
72 |
"vec3 center = vUniforms[effect+1].yzw; \n"
|
|
73 |
+ "vec3 ps = center-v.xyz; \n"
|
|
74 | 74 |
+ "float h = vUniforms[effect].x; \n" |
75 | 75 |
+ "float t = degree(vUniforms[effect+2],center,ps) * (1.0-h)/max(1.0,h); \n" |
76 | 76 |
+ "float angle = vUniforms[effect].y; \n" |
77 | 77 |
+ "vec2 dir = vec2(sin(angle),-cos(angle)); \n" |
78 |
+ "v.xy += t*dot(ps,dir)*dir;" |
|
78 |
+ "v.xy += t*dot(ps.xy,dir)*dir;"
|
|
79 | 79 |
); |
80 | 80 |
} |
81 | 81 |
|
... | ... | |
109 | 109 |
super(EffectName.PINCH); |
110 | 110 |
mPinch = pinch; |
111 | 111 |
mCenter = center; |
112 |
mRegion = new Static4D(0,0,Float.MAX_VALUE, Float.MAX_VALUE);
|
|
112 |
mRegion = new Static4D(0,0,0, Float.MAX_VALUE);
|
|
113 | 113 |
} |
114 | 114 |
} |
src/main/java/org/distorted/library/effect/VertexEffectSink.java | ||
---|---|---|
65 | 65 |
{ |
66 | 66 |
addEffect(EffectName.SINK, |
67 | 67 |
|
68 |
"vec2 center = vUniforms[effect+1].yz; \n"
|
|
69 |
+ "vec2 ps = center-v.xy; \n"
|
|
68 |
"vec3 center = vUniforms[effect+1].yzw; \n"
|
|
69 |
+ "vec3 ps = center-v.xyz; \n"
|
|
70 | 70 |
+ "float h = vUniforms[effect].x; \n" |
71 | 71 |
+ "float t = degree(vUniforms[effect+2],center,ps) * (1.0-h)/max(1.0,h); \n" |
72 | 72 |
|
73 |
+ "v.xy += t*ps;" |
|
73 |
+ "v.xy += t*ps.xy;"
|
|
74 | 74 |
); |
75 | 75 |
} |
76 | 76 |
|
... | ... | |
104 | 104 |
super(EffectName.SINK); |
105 | 105 |
mSink = sink; |
106 | 106 |
mCenter = center; |
107 |
mRegion = new Static4D(0,0,Float.MAX_VALUE, Float.MAX_VALUE);
|
|
107 |
mRegion = new Static4D(0,0,0, Float.MAX_VALUE);
|
|
108 | 108 |
} |
109 | 109 |
} |
src/main/java/org/distorted/library/effect/VertexEffectSwirl.java | ||
---|---|---|
66 | 66 |
{ |
67 | 67 |
addEffect(EffectName.SWIRL, |
68 | 68 |
|
69 |
"vec2 center = vUniforms[effect+1].yz; \n"
|
|
70 |
+ "vec2 PS = center-v.xy; \n"
|
|
69 |
"vec3 center = vUniforms[effect+1].yzw; \n"
|
|
70 |
+ "vec3 PS = center-v.xyz; \n"
|
|
71 | 71 |
+ "vec4 SO = vUniforms[effect+2]; \n" |
72 | 72 |
+ "float d1_circle = degree_region(SO,PS); \n" |
73 | 73 |
+ "float d1_bitmap = degree_bitmap(center,PS); \n" |
... | ... | |
76 | 76 |
+ "float sinA = sin(alpha); \n" |
77 | 77 |
+ "float cosA = cos(alpha); \n" |
78 | 78 |
|
79 |
+ "vec2 PS2 = vec2( PS.x*cosA+PS.y*sinA,-PS.x*sinA+PS.y*cosA ); \n" // vector PS rotated by A radians clockwise around center.
|
|
80 |
+ "vec4 SG = (1.0-d1_circle)*SO; \n" // coordinates of the dilated circle P is going to get rotated around |
|
81 |
+ "float d2 = max(0.0,degree(SG,center,PS2)); \n" // make it a max(0,deg) because otherwise when center=left edge of the |
|
82 |
// bitmap some points end up with d2<0 and they disappear off view. |
|
83 |
+ "v.xy += min(d1_circle,d1_bitmap)*(PS - PS2/(1.0-d2)); \n" // if d2=1 (i.e P=center) we should have P unchanged. How to do it?
|
|
79 |
+ "vec3 PS2 = vec3( PS.x*cosA+PS.y*sinA,-PS.x*sinA+PS.y*cosA, PS.z ); \n" // vector PS rotated by A radians clockwise around center.
|
|
80 |
+ "vec4 SG = (1.0-d1_circle)*SO; \n" // coordinates of the dilated circle P is going to get rotated around
|
|
81 |
+ "float d2 = max(0.0,degree(SG,center,PS2)); \n" // make it a max(0,deg) because otherwise when center=left edge of the
|
|
82 |
// bitmap some points end up with d2<0 and they disappear off view.
|
|
83 |
+ "v.xy += min(d1_circle,d1_bitmap)*(PS.xy - PS2.xy/(1.0-d2)); \n" // if d2=1 (i.e P=center) we should have P unchanged. How to do it?
|
|
84 | 84 |
); |
85 | 85 |
} |
86 | 86 |
|
... | ... | |
112 | 112 |
super(EffectName.SWIRL); |
113 | 113 |
mSwirl = swirl; |
114 | 114 |
mCenter = center; |
115 |
mRegion = new Static4D(0,0,Float.MAX_VALUE, Float.MAX_VALUE);
|
|
115 |
mRegion = new Static4D(0,0,0, Float.MAX_VALUE);
|
|
116 | 116 |
} |
117 | 117 |
} |
118 | 118 |
|
src/main/java/org/distorted/library/effect/VertexEffectWave.java | ||
---|---|---|
127 | 127 |
{ |
128 | 128 |
addEffect(EffectName.WAVE, |
129 | 129 |
|
130 |
"vec2 center = vUniforms[effect+1].yz; \n"
|
|
130 |
"vec3 center = vUniforms[effect+1].yzw; \n"
|
|
131 | 131 |
+ "float amplitude = vUniforms[effect ].x; \n" |
132 | 132 |
+ "float length = vUniforms[effect ].y; \n" |
133 | 133 |
|
134 |
+ "vec2 ps = center - v.xy; \n"
|
|
134 |
+ "vec3 ps = center - v.xyz; \n"
|
|
135 | 135 |
+ "float deg = amplitude*degree_region(vUniforms[effect+2],ps); \n" |
136 | 136 |
|
137 | 137 |
+ "if( deg != 0.0 && length != 0.0 ) \n" |
... | ... | |
170 | 170 |
|
171 | 171 |
+ "vec3 normal = cross(sx,sy); \n" |
172 | 172 |
|
173 |
+ "if( normal.z<=0.0 ) \n" // Why this bizarre shit rather than the straightforward
|
|
173 |
+ "if( normal.z<=0.0 ) \n" // Why this bizarre thing rather than the straightforward
|
|
174 | 174 |
+ "{ \n" // |
175 | 175 |
+ "normal.x= 0.0; \n" // if( normal.z>0.0 ) |
176 | 176 |
+ "normal.y= 0.0; \n" // { |
... | ... | |
179 | 179 |
// n.z = (n.z*normal.z); |
180 | 180 |
// } |
181 | 181 |
+ "n.x = (n.x*normal.z + n.z*normal.x); \n" // |
182 |
+ "n.y = (n.y*normal.z + n.z*normal.y); \n" // ? Because if we do the above, my shitty Nexus4 crashes
|
|
182 |
+ "n.y = (n.y*normal.z + n.z*normal.y); \n" // ? Because if we do the above, my Nexus4 crashes |
|
183 | 183 |
+ "n.z = (n.z*normal.z); \n" // during shader compilation! |
184 | 184 |
+ "} \n" |
185 | 185 |
+ "}" |
... | ... | |
235 | 235 |
super(EffectName.WAVE); |
236 | 236 |
mWave = wave; |
237 | 237 |
mCenter = center; |
238 |
mRegion = new Static4D(0,0,Float.MAX_VALUE, Float.MAX_VALUE);
|
|
238 |
mRegion = new Static4D(0,0,0, Float.MAX_VALUE);
|
|
239 | 239 |
} |
240 | 240 |
} |
src/main/java/org/distorted/library/main/DistortedScreen.java | ||
---|---|---|
38 | 38 |
public class DistortedScreen extends DistortedFramebuffer |
39 | 39 |
{ |
40 | 40 |
///// DEBUGGING ONLY ///////////////////////// |
41 |
private boolean mShowFPS; |
|
42 |
|
|
43 | 41 |
private static final int NUM_FRAMES = 100; |
42 |
private static final int FPS_W = 120; |
|
43 |
private static final int FPS_H = 70; |
|
44 |
|
|
45 |
private boolean mShowFPS; |
|
44 | 46 |
|
45 | 47 |
private MeshQuad fpsMesh; |
46 | 48 |
private DistortedTexture fpsTexture; |
... | ... | |
48 | 50 |
private Canvas fpsCanvas; |
49 | 51 |
private Bitmap fpsBitmap; |
50 | 52 |
private Paint mPaint; |
51 |
private int fpsH, fpsW; |
|
52 | 53 |
private String fpsString; |
53 | 54 |
private long lastTime=0; |
54 | 55 |
private long[] durations; |
... | ... | |
100 | 101 |
fpsString = "" + ((int)(10000.0f*NUM_FRAMES/durations[NUM_FRAMES]))/10.0f; |
101 | 102 |
|
102 | 103 |
mPaint.setColor(0xffffffff); |
103 |
fpsCanvas.drawRect(0, 0, fpsW, fpsH, mPaint);
|
|
104 |
fpsCanvas.drawRect(0, 0, FPS_W, FPS_H, mPaint);
|
|
104 | 105 |
mPaint.setColor(0xff000000); |
105 |
fpsCanvas.drawText(fpsString, fpsW/2, 0.75f*fpsH, mPaint);
|
|
106 |
fpsCanvas.drawText(fpsString, FPS_W/2, 0.75f*FPS_H, mPaint);
|
|
106 | 107 |
fpsTexture.setTexture(fpsBitmap); |
107 | 108 |
|
108 | 109 |
lastTime = time; |
... | ... | |
129 | 130 |
|
130 | 131 |
if( mShowFPS && fpsTexture.setAsInput()) |
131 | 132 |
{ |
132 |
fpsEffects.drawPriv(fpsW / 2.0f, fpsH / 2.0f, fpsMesh, this, time);
|
|
133 |
fpsEffects.drawPriv(FPS_W / 2.0f, FPS_H / 2.0f, fpsMesh, this, time);
|
|
133 | 134 |
} |
134 | 135 |
|
135 | 136 |
if( ++mCurRenderedFBO>=Distorted.FBO_QUEUE_SIZE ) |
... | ... | |
155 | 156 |
if( !mShowFPS ) |
156 | 157 |
{ |
157 | 158 |
mShowFPS = true; |
158 |
|
|
159 |
fpsW = 120; |
|
160 |
fpsH = 70; |
|
161 |
|
|
162 | 159 |
fpsString = ""; |
163 |
fpsBitmap = Bitmap.createBitmap(fpsW, fpsH, Bitmap.Config.ARGB_8888);
|
|
160 |
fpsBitmap = Bitmap.createBitmap(FPS_W, FPS_H, Bitmap.Config.ARGB_8888);
|
|
164 | 161 |
fpsMesh = new MeshQuad(); |
165 |
fpsTexture = new DistortedTexture(fpsW, fpsH);
|
|
162 |
fpsTexture = new DistortedTexture(FPS_W, FPS_H);
|
|
166 | 163 |
fpsTexture.setTexture(fpsBitmap); |
167 | 164 |
fpsCanvas = new Canvas(fpsBitmap); |
168 | 165 |
fpsEffects = new DistortedEffects(); |
... | ... | |
171 | 168 |
mPaint = new Paint(); |
172 | 169 |
mPaint.setAntiAlias(true); |
173 | 170 |
mPaint.setTextAlign(Paint.Align.CENTER); |
174 |
mPaint.setTextSize(0.7f * fpsH);
|
|
171 |
mPaint.setTextSize(0.7f * FPS_H);
|
|
175 | 172 |
|
176 | 173 |
durations = new long[NUM_FRAMES + 1]; |
177 | 174 |
currDuration = 0; |
src/main/res/raw/main_vertex_shader.glsl | ||
---|---|---|
43 | 43 |
uniform int vName[NUM_VERTEX]; // their names. |
44 | 44 |
uniform vec4 vUniforms[3*NUM_VERTEX];// i-th effect is 3 consecutive vec4's: [3*i], [3*i+1], [3*i+2]. |
45 | 45 |
// The first vec4 is the Interpolated values, |
46 |
// next is half cache half Center, the third - the Region.
|
|
46 |
// second vec4: first float - cache, next 3: Center, the third - the Region.
|
|
47 | 47 |
|
48 | 48 |
////////////////////////////////////////////////////////////////////////////////////////////// |
49 | 49 |
// HELPER FUNCTIONS |
... | ... | |
62 | 62 |
////////////////////////////////////////////////////////////////////////////////////////////// |
63 | 63 |
// return degree of the point as defined by the bitmap rectangle |
64 | 64 |
|
65 |
float degree_bitmap(in vec2 S, in vec2 PS)
|
|
65 |
float degree_bitmap(in vec3 S, in vec3 PS)
|
|
66 | 66 |
{ |
67 |
vec2 A = sign(PS)*u_objD.xy + S;
|
|
67 |
vec3 A = sign(PS)*u_objD + S;
|
|
68 | 68 |
|
69 |
vec2 signA = sign(A); //
|
|
70 |
vec2 signA_SQ = signA*signA; // div = PS/A if A!=0, 0 otherwise.
|
|
71 |
vec2 div = signA_SQ*PS/(A-(vec2(1,1)-signA_SQ));//
|
|
69 |
vec3 signA = sign(A); //
|
|
70 |
vec3 signA_SQ = signA*signA; // div = PS/A if A!=0, 0 otherwise.
|
|
71 |
vec3 div = signA_SQ*PS/(A-(vec3(1.0,1.0,1.0)-signA_SQ)); //
|
|
72 | 72 |
|
73 | 73 |
return 1.0-max(div.x,div.y); |
74 | 74 |
} |
... | ... | |
94 | 94 |
// where a = PS*PO/|PS| but we are really looking for d = |PX|/(|PX|+|PS|) = 1/(1+ (|PS|/|PX|) ) and |
95 | 95 |
// |PX|/|PS| = -b + sqrt(b^2 + (OX^2-PO^2)/PS^2) where b=PS*PO/|PS|^2 which can be computed with only one sqrt. |
96 | 96 |
|
97 |
float degree_region(in vec4 region, in vec2 PS)
|
|
97 |
float degree_region(in vec4 region, in vec3 PS)
|
|
98 | 98 |
{ |
99 |
vec2 PO = PS + region.xy;
|
|
100 |
float D = region.z*region.z-dot(PO,PO); // D = |OX|^2 - |PO|^2
|
|
99 |
vec3 PO = PS + region.xyz;
|
|
100 |
float D = region.w*region.w-dot(PO,PO); // D = |OX|^2 - |PO|^2
|
|
101 | 101 |
|
102 | 102 |
if( D<=0.0 ) return 0.0; |
103 | 103 |
|
... | ... | |
119 | 119 |
////////////////////////////////////////////////////////////////////////////////////////////// |
120 | 120 |
// return min(degree_bitmap,degree_region). Just like degree_region, currently only supports circles. |
121 | 121 |
|
122 |
float degree(in vec4 region, in vec2 S, in vec2 PS)
|
|
122 |
float degree(in vec4 region, in vec3 S, in vec3 PS)
|
|
123 | 123 |
{ |
124 |
vec2 PO = PS + region.xy;
|
|
125 |
float D = region.z*region.z-dot(PO,PO); // D = |OX|^2 - |PO|^2
|
|
124 |
vec3 PO = PS + region.xyz;
|
|
125 |
float D = region.w*region.w-dot(PO,PO); // D = |OX|^2 - |PO|^2
|
|
126 | 126 |
|
127 | 127 |
if( D<=0.0 ) return 0.0; |
128 | 128 |
|
129 |
vec2 A = sign(PS)*u_objD.xy + S;
|
|
130 |
vec2 signA = sign(A);
|
|
131 |
vec2 signA_SQ = signA*signA;
|
|
132 |
vec2 div = signA_SQ*PS/(A-(vec2(1,1)-signA_SQ));
|
|
129 |
vec3 A = sign(PS)*u_objD.xyz + S;
|
|
130 |
vec3 signA = sign(A);
|
|
131 |
vec3 signA_SQ = signA*signA;
|
|
132 |
vec3 div = signA_SQ*PS/(A-(vec3(1.0,1.0,1.0)-signA_SQ));
|
|
133 | 133 |
float E = 1.0-max(div.x,div.y); |
134 | 134 |
|
135 | 135 |
float ps_sq = dot(PS,PS); |
Also available in: Unified diff
Redefine the Vertex Region from (x,y,r,unused) to (x,y,z,r). This takes into account the 'Z', which makes it possible to warp only one side of a 3D Mesh like Sphere.
Also corresponding changes in applications.