Revision bb4755e2
Added by Leszek Koltunski over 4 years ago
src/main/java/org/distorted/library/effect/EffectName.java | ||
---|---|---|
72 | 72 |
CONTRAST ( EffectType.FRAGMENT, new float[] {1.0f} , 1, 3, 3 , FragmentEffectContrast.class ), |
73 | 73 |
SMOOTH_CONTRAST ( EffectType.FRAGMENT, new float[] {1.0f} , 1, 3, 3 , FragmentEffectContrast.class ), |
74 | 74 |
|
75 |
BLUR ( EffectType.POSTPROCESS,new float[] {0.0f} , 1, 0, 0 , PostprocessEffectBlur.class ),
|
|
76 |
GLOW ( EffectType.POSTPROCESS,new float[] {0.0f} , 5, 0, 0 , PostprocessEffectGlow.class );
|
|
75 |
BLUR ( EffectType.POSTPROCESS,new float[] {0.0f} , 2, 0, 0 , PostprocessEffectBlur.class ),
|
|
76 |
GLOW ( EffectType.POSTPROCESS,new float[] {0.0f} , 6, 0, 0 , PostprocessEffectGlow.class );
|
|
77 | 77 |
|
78 | 78 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
79 | 79 |
|
src/main/java/org/distorted/library/effect/PostprocessEffect.java | ||
---|---|---|
39 | 39 |
/** |
40 | 40 |
* 5: 5 per-effect interpolated values. |
41 | 41 |
*/ |
42 |
public static final int NUM_UNIFORMS = 5;
|
|
42 |
public static final int NUM_UNIFORMS = 6;
|
|
43 | 43 |
|
44 | 44 |
static final int POS_DATA_SIZE= 2; |
45 | 45 |
static final int TEX_DATA_SIZE= 2; |
src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java | ||
---|---|---|
24 | 24 |
import org.distorted.library.main.DistortedFramebuffer; |
25 | 25 |
import org.distorted.library.main.InternalRenderState; |
26 | 26 |
import org.distorted.library.program.DistortedProgram; |
27 |
import org.distorted.library.type.Data1D;
|
|
27 |
import org.distorted.library.type.Data2D;
|
|
28 | 28 |
|
29 | 29 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
30 | 30 |
/** |
... | ... | |
32 | 32 |
*/ |
33 | 33 |
public class PostprocessEffectBlur extends PostprocessEffect |
34 | 34 |
{ |
35 |
private static final int MAX_HALO = 50;
|
|
35 |
private static final int MAX_RADIUS = 50;
|
|
36 | 36 |
|
37 |
private Data1D mBlurRadius;
|
|
37 |
private Data2D mBlurHaloAndRadius;
|
|
38 | 38 |
|
39 | 39 |
private static final float[] GAUSSIAN = // G(0.00), G(0.03), G(0.06), ..., G(3.00), 0 |
40 | 40 |
{ // where G(x)= (1/(sqrt(2*PI))) * e^(-(x^2)/2). The last 0 terminates. |
... | ... | |
56 | 56 |
// i.e. k(i)=floor((i+3)/2). (the 'i' in k(i) means 'blur taking into account the present pixel and 'i' pixels |
57 | 57 |
// in all 4 directions) |
58 | 58 |
// We need room for MAX_BLUR of them, and sum(i=0...N, floor((i+3)/2)) = N + floor(N*N/4) |
59 |
private static float[] weightsCache = new float[MAX_HALO + MAX_HALO*MAX_HALO/4];
|
|
60 |
private static float[] offsetsCache = new float[MAX_HALO + MAX_HALO*MAX_HALO/4];
|
|
61 |
private static float[] mWeights = new float[MAX_HALO];
|
|
62 |
private static float[] mOffsets = new float[MAX_HALO];
|
|
59 |
private static float[] weightsCache = new float[MAX_RADIUS + MAX_RADIUS*MAX_RADIUS/4];
|
|
60 |
private static float[] offsetsCache = new float[MAX_RADIUS + MAX_RADIUS*MAX_RADIUS/4];
|
|
61 |
private static float[] mWeights = new float[MAX_RADIUS];
|
|
62 |
private static float[] mOffsets = new float[MAX_RADIUS];
|
|
63 | 63 |
|
64 | 64 |
private static DistortedProgram mProgram1, mProgram2; |
65 | 65 |
private static int mIndex1, mIndex2; |
... | ... | |
133 | 133 |
*/ |
134 | 134 |
public boolean compute(float[] uniforms, int index, long currentDuration, long step ) |
135 | 135 |
{ |
136 |
return mBlurRadius.get(uniforms,index,currentDuration,step); |
|
136 |
return mBlurHaloAndRadius.get(uniforms,index,currentDuration,step);
|
|
137 | 137 |
} |
138 | 138 |
|
139 | 139 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
181 | 181 |
float offsetCorrW = corrW/w; |
182 | 182 |
float offsetCorrH = corrH/h; |
183 | 183 |
|
184 |
int radius = (int)(uniforms[index]*mQualityScale); |
|
185 |
if( radius>=MAX_HALO ) radius = MAX_HALO-1;
|
|
184 |
int radius = (int)(uniforms[index+1]*mQualityScale);
|
|
185 |
if( radius>=MAX_RADIUS ) radius = MAX_RADIUS-1;
|
|
186 | 186 |
computeGaussianKernel(radius); |
187 | 187 |
|
188 | 188 |
int offset = radius + radius*radius/4; |
... | ... | |
259 | 259 |
|
260 | 260 |
final String blurFragment1 = |
261 | 261 |
|
262 |
"#define MAX_BLUR "+MAX_HALO+ "\n"+
|
|
262 |
"#define MAX_BLUR "+MAX_RADIUS+ "\n"+
|
|
263 | 263 |
"precision lowp float; \n"+ |
264 | 264 |
"in vec2 v_TexCoord; \n"+ |
265 | 265 |
"out vec4 fragColor; \n"+ |
... | ... | |
281 | 281 |
|
282 | 282 |
final String blurFragment2 = |
283 | 283 |
|
284 |
"#define MAX_BLUR "+MAX_HALO+ "\n"+
|
|
284 |
"#define MAX_BLUR "+MAX_RADIUS+ "\n"+
|
|
285 | 285 |
"precision lowp float; \n"+ |
286 | 286 |
"in vec2 v_TexCoord; \n"+ |
287 | 287 |
"out vec4 fragColor; \n"+ |
... | ... | |
309 | 309 |
/** |
310 | 310 |
* Blur the Framebuffer. |
311 | 311 |
* |
312 |
* @param blurRadius The 'strength' of the effect, in pixels. 0 = no blur, 10 = when blurring a given pixel, |
|
313 |
* take into account 10 pixels in each direction. |
|
312 |
* @param blurHaloAndRadius First float: the halo. |
|
313 |
* How far beyond the object does the effect stretch to? Unit: Percentage |
|
314 |
* of the size of the original object, i.e. Halo=0 --> no halo around, this |
|
315 |
* would mean sharp edges around the object; Halo=100 --> halo of the size |
|
316 |
* of the object itself around (in case of blur, this would be - in vast |
|
317 |
* majority of cases except an object rendered very closely to the near plane- |
|
318 |
* an overkill). |
|
319 |
* Second float: the radius. |
|
320 |
* The 'strength' if the blur of the edges, in pixels. 0 = no blur, 10 = |
|
321 |
* blur of roughly 10 pixels around the whole halo. |
|
322 |
|
|
314 | 323 |
*/ |
315 |
public PostprocessEffectBlur(Data1D blurRadius)
|
|
324 |
public PostprocessEffectBlur(Data2D blurHaloAndRadius)
|
|
316 | 325 |
{ |
317 | 326 |
super(EffectName.BLUR); |
318 |
mBlurRadius = blurRadius;
|
|
327 |
mBlurHaloAndRadius = blurHaloAndRadius;
|
|
319 | 328 |
} |
320 | 329 |
} |
src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java | ||
---|---|---|
24 | 24 |
import org.distorted.library.main.DistortedFramebuffer; |
25 | 25 |
import org.distorted.library.main.InternalRenderState; |
26 | 26 |
import org.distorted.library.program.DistortedProgram; |
27 |
import org.distorted.library.type.Data1D;
|
|
27 |
import org.distorted.library.type.Data2D;
|
|
28 | 28 |
import org.distorted.library.type.Data4D; |
29 | 29 |
|
30 | 30 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
33 | 33 |
*/ |
34 | 34 |
public class PostprocessEffectGlow extends PostprocessEffect |
35 | 35 |
{ |
36 |
private static final int MAX_HALO = 50;
|
|
36 |
private static final int MAX_RADIUS = 50;
|
|
37 | 37 |
|
38 |
private Data1D mGlowRadius;
|
|
38 |
private Data2D mGlowHaloAndRadius;
|
|
39 | 39 |
private Data4D mColor; |
40 | 40 |
|
41 | 41 |
private static final float[] GAUSSIAN = // G(0.00), G(0.03), G(0.06), ..., G(3.00), 0 |
... | ... | |
58 | 58 |
// i.e. k(i)=floor((i+3)/2). (the 'i' in k(i) means 'blur taking into account the present pixel and 'i' pixels |
59 | 59 |
// in all 4 directions) |
60 | 60 |
// We need room for MAX_BLUR of them, and sum(i=0...N, floor((i+3)/2)) = N + floor(N*N/4) |
61 |
private static float[] weightsCache = new float[MAX_HALO + MAX_HALO*MAX_HALO/4];
|
|
62 |
private static float[] offsetsCache = new float[MAX_HALO + MAX_HALO*MAX_HALO/4];
|
|
63 |
private static float[] mWeights = new float[MAX_HALO];
|
|
64 |
private static float[] mOffsets = new float[MAX_HALO];
|
|
61 |
private static float[] weightsCache = new float[MAX_RADIUS + MAX_RADIUS*MAX_RADIUS/4];
|
|
62 |
private static float[] offsetsCache = new float[MAX_RADIUS + MAX_RADIUS*MAX_RADIUS/4];
|
|
63 |
private static float[] mWeights = new float[MAX_RADIUS];
|
|
64 |
private static float[] mOffsets = new float[MAX_RADIUS];
|
|
65 | 65 |
|
66 | 66 |
private static DistortedProgram mProgram1, mProgram2; |
67 | 67 |
private static int mIndex1, mIndex2; |
... | ... | |
135 | 135 |
*/ |
136 | 136 |
public boolean compute(float[] uniforms, int index, long currentDuration, long step ) |
137 | 137 |
{ |
138 |
mColor.get(uniforms,index+1,currentDuration,step);
|
|
139 |
return mGlowRadius.get(uniforms,index,currentDuration,step); |
|
138 |
mColor.get(uniforms,index+2,currentDuration,step);
|
|
139 |
return mGlowHaloAndRadius.get(uniforms,index,currentDuration,step);
|
|
140 | 140 |
} |
141 | 141 |
|
142 | 142 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
184 | 184 |
float offsetCorrW = corrW/w; |
185 | 185 |
float offsetCorrH = corrH/h; |
186 | 186 |
|
187 |
int radius = (int)(uniforms[index]*mQualityScale); |
|
188 |
if( radius>=MAX_HALO ) radius = MAX_HALO-1;
|
|
187 |
int radius = (int)(uniforms[index+1]*mQualityScale);
|
|
188 |
if( radius>=MAX_RADIUS ) radius = MAX_RADIUS-1;
|
|
189 | 189 |
computeGaussianKernel(radius); |
190 | 190 |
|
191 | 191 |
int offset = radius + radius*radius/4; |
... | ... | |
262 | 262 |
|
263 | 263 |
final String glowFragment1 = |
264 | 264 |
|
265 |
"#define MAX_BLUR "+MAX_HALO+ "\n"+
|
|
265 |
"#define MAX_BLUR "+MAX_RADIUS+ "\n"+
|
|
266 | 266 |
"precision lowp float; \n"+ |
267 | 267 |
"in vec2 v_TexCoord; \n"+ |
268 | 268 |
"out vec4 fragColor; \n"+ |
... | ... | |
284 | 284 |
|
285 | 285 |
final String glowFragment2 = |
286 | 286 |
|
287 |
"#define MAX_BLUR "+MAX_HALO+ "\n"+
|
|
287 |
"#define MAX_BLUR "+MAX_RADIUS+ "\n"+
|
|
288 | 288 |
"precision lowp float; \n"+ |
289 | 289 |
"in vec2 v_TexCoord; \n"+ |
290 | 290 |
"out vec4 fragColor; \n"+ |
... | ... | |
309 | 309 |
} |
310 | 310 |
|
311 | 311 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
312 |
|
|
313 | 312 |
/** |
314 | 313 |
* Make the object glow with a specific color and a halo of specific radius. |
315 | 314 |
* |
316 |
* @param glowRadius The 'strength' if the effect, in pixels. 0 = no halo, 10 = halo of roughly 10 pixels |
|
317 |
* around the whole object. |
|
318 |
* @param color RGBA of the color with which to draw the glow; example: (1.0f,0.0f,0.0f,0.5f) - half transparent red. |
|
315 |
* @param glowHaloAndRadius First float: the halo. |
|
316 |
* How far beyond the object does the effect stretch to? Unit: Percentage |
|
317 |
* of the size of the original object, i.e. Halo=0 --> no halo around, this |
|
318 |
* would mean sharp edges around the object; Halo=100 --> halo of the size |
|
319 |
* of the object itself around. |
|
320 |
* Second float: the radius. |
|
321 |
* The 'strength' if the blur of the edges, in pixels. 0 = no blur, 10 = |
|
322 |
* blur of roughly 10 pixels around the whole halo. |
|
323 |
* @param color RGBA of the color with which to draw the glow; example: (1.0f,0.0f,0.0f,0.5f) - |
|
324 |
* half transparent red. |
|
319 | 325 |
*/ |
320 |
public PostprocessEffectGlow(Data1D glowRadius, Data4D color)
|
|
326 |
public PostprocessEffectGlow(Data2D glowHaloAndRadius, Data4D color)
|
|
321 | 327 |
{ |
322 | 328 |
super(EffectName.GLOW); |
323 |
mGlowRadius = glowRadius; |
|
324 |
mColor = color; |
|
329 |
|
|
330 |
mGlowHaloAndRadius = glowHaloAndRadius; |
|
331 |
mColor = color; |
|
325 | 332 |
} |
326 | 333 |
} |
src/main/java/org/distorted/library/effectqueue/EffectQueuePostprocess.java | ||
---|---|---|
83 | 83 |
// first zero out the 'alpha' because BLUR effect will not overwrite this (it is a 1D effect) |
84 | 84 |
// and if previously there was a GLOW effect here then mA would be non-zero and we don't want |
85 | 85 |
// that (see preprocess()) |
86 |
mUniforms[NUM_UNIFORMS*i+4]=0.0f;
|
|
86 |
mUniforms[NUM_UNIFORMS*i+5]=0.0f;
|
|
87 | 87 |
|
88 | 88 |
if( mEffects[i].compute(mUniforms, NUM_UNIFORMS*i, mCurrentDuration[i], step) ) |
89 | 89 |
{ |
... | ... | |
97 | 97 |
// TODO (now only really works in case of 1 effect!) |
98 | 98 |
if( mNumEffects>0 ) |
99 | 99 |
{ |
100 |
mR = mUniforms[1];
|
|
101 |
mG = mUniforms[2];
|
|
102 |
mB = mUniforms[3];
|
|
103 |
mA = mUniforms[4];
|
|
100 |
mR = mUniforms[2];
|
|
101 |
mG = mUniforms[3];
|
|
102 |
mB = mUniforms[4];
|
|
103 |
mA = mUniforms[5];
|
|
104 | 104 |
} |
105 | 105 |
|
106 | 106 |
mTime = currTime; |
Also available in: Unified diff
Change the Postprocessing effects: separate the radius and the halo.
Reason: we needed a way to specify the size of the halo around a postprocessed object; before it was automatically (and not very correctly) computed from the radius - before we knew the size of the object's bounding box, so this automatic computation was possible. Now we're removing the MashBase.getBounding(0 API, so the size of the halo has to be explicitly given by the user. This way is more correct anyway and gives the user more control (as the Multiblur app proves!)
Warning: here for the first time I can see that the 2 Examples (PostprocessingTree and MovingGlow) sometimes would not appear (black screen). Maybe this commit introduces such a bug - investigate.