Libgdx fbo background transparency - android

I draw things on an FBO in libgdx. Than I just want to draw that fbo WITH TRANSPARENT background to my screen. But that is allways BLACK.
Is it possible to use a transparent background on the spriteBatch?
Tried a lot of things, but it looks like I cannot dop this simple task.
I created a custom shader and:
vec4 orig = texture2D(u_texture, tc);
if (orig.a==0.0) discard;
ths FBO create code:
fbo = new FrameBuffer(Format.RGB565, width, height, hasDepth);
than:
public void begin() {
fbo.begin();
Gdx.gl.glClearColor(1.0f, 0.0f, 0.0f, 0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
}
public void render() {
renderIt();
}
private void renderIt() {
spriteBatch.begin();
spriteBatch.setShader(shader);
spriteBatch.draw(fboRegion, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
spriteBatch.end();
}
public void end() {
Gdx.gl.glDisable(GLES20.GL_BLEND);
fbo.end();
}
It looks like the shader cannot determinate the FBO's alpha values. why? I just need to clear the alpha=0.0 pixels out.
So in my shader the background cut out:
if (orig.r==1.0) discard;
this is WORKING
if (orig.a==0.0) discard;
if (orig.a<0.2) discard;
if (orig.a<0.9) discard;
THIS IS NOT
my shader looks like this
void main() {
vec4 sum = vec4(0.0);
vec2 tc = v_texCoord0;
//the amount to blur, i.e. how far off center to sample from
//1.0 -> blur by one pixel
//2.0 -> blur by two pixels, etc.
float blur = radius/resolution;
//the direction of our blur
//(1.0, 0.0) -> x-axis blur
//(0.0, 1.0) -> y-axis blur
float hstep = dir.x;
float vstep = dir.y;
sum += texture2D(u_texture, vec2(tc.x - 4.0*blur*hstep, tc.y - 4.0*blur*vstep)) * 0.0162162162;
sum += texture2D(u_texture, vec2(tc.x - 3.0*blur*hstep, tc.y - 3.0*blur*vstep)) * 0.0540540541;
sum += texture2D(u_texture, vec2(tc.x - 2.0*blur*hstep, tc.y - 2.0*blur*vstep)) * 0.1216216216;
sum += texture2D(u_texture, vec2(tc.x - 1.0*blur*hstep, tc.y - 1.0*blur*vstep)) * 0.1945945946;
sum += texture2D(u_texture, vec2(tc.x, tc.y)) * 0.2270270270;
sum += texture2D(u_texture, vec2(tc.x + 1.0*blur*hstep, tc.y + 1.0*blur*vstep)) * 0.1945945946;
sum += texture2D(u_texture, vec2(tc.x + 2.0*blur*hstep, tc.y + 2.0*blur*vstep)) * 0.1216216216;
sum += texture2D(u_texture, vec2(tc.x + 3.0*blur*hstep, tc.y + 3.0*blur*vstep)) * 0.0540540541;
sum += texture2D(u_texture, vec2(tc.x + 4.0*blur*hstep, tc.y + 4.0*blur*vstep)) * 0.0162162162;
vec4 all = v_color * vec4(sum.rgb, 1.0);
if (all.a < 0.9) discard;
else gl_FragColor = all;
}

RGB565 format does not have an alpha channel. If you need transparency use a format like ARGB8888

LOL I was a fckin idiote.
vec4 all = v_color * vec4(sum.rgb, 1.0);
if (all.a < 0.9) discard;
else gl_FragColor = all;
this is the BAD shader (its alpha is allways 1.0)
this is the worked one:
vec4 all = sum;
if (all.a < 0.5) discard;
else
gl_FragColor = all;

Related

How to make smoother borders using Fragment shader in OpenGL?

I have been trying to draw border of an Image with transparent background using OpenGL in Android. I am using Fragment Shader & Vertex Shader. (From the GPUImage Library)
Below I have added Fig. A & Fig B.
Fig A.
Fig B.
I have achieved Fig A. With the customised Fragment Shader. But Unable to make the border smoother as in Fig B. I am attaching the Shader code that I have used (to achieve rough border). Can someone here help me on how to make the border smoother?
Here is my Vertex Shader :
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
varying vec2 textureCoordinate;
void main()
{
gl_Position = position;
textureCoordinate = inputTextureCoordinate.xy;
}
Here is my Fragment Shader :
I have calculated 8 pixels around the current pixel. If any one pixel of those 8 is opaque(having alpha greater than 0.4), It it drawn as a border color.
precision mediump float;
uniform sampler2D inputImageTexture;
varying vec2 textureCoordinate;
uniform lowp float thickness;
uniform lowp vec4 color;
void main() {
float x = textureCoordinate.x;
float y = textureCoordinate.y;
vec4 current = texture2D(inputImageTexture, vec2(x,y));
if ( current.a != 1.0 ) {
float offset = thickness * 0.5;
vec4 top = texture2D(inputImageTexture, vec2(x, y - offset));
vec4 topRight = texture2D(inputImageTexture, vec2(x + offset,y - offset));
vec4 topLeft = texture2D(inputImageTexture, vec2(x - offset, y - offset));
vec4 right = texture2D(inputImageTexture, vec2(x + offset, y ));
vec4 bottom = texture2D(inputImageTexture, vec2(x , y + offset));
vec4 bottomLeft = texture2D(inputImageTexture, vec2(x - offset, y + offset));
vec4 bottomRight = texture2D(inputImageTexture, vec2(x + offset, y + offset));
vec4 left = texture2D(inputImageTexture, vec2(x - offset, y ));
if ( top.a > 0.4 || bottom.a > 0.4 || left.a > 0.4 || right.a > 0.4 || topLeft.a > 0.4 || topRight.a > 0.4 || bottomLeft.a > 0.4 || bottomRight.a > 0.4 ) {
if (current.a != 0.0) {
current = mix(color , current , current.a);
} else {
current = color;
}
}
}
gl_FragColor = current;
}
You were almost on the right track.
The main algorithm is:
Blur the image.
Use pixels with opacity above a certain threshold as outline.
The main problem is the blur step. It needs to be a large and smooth blur to get the smooth outline you want. For blurring, we can use convolution filter Kernel. And to achieve a large blur, we should use a large kernel. And I suggest using the Gaussian Blur distribution, as it is very well known and used.
The Overview of he Algorithm is:
For each fragment, we sample many locations around it. The samples are made in an N by N grid. We average them together using weights that follow a 2D Gaussian Distribution.
This results in a blurred image.
With the blurred image, we paint the fragments that have alpha greater than a threshold with our outline color. And, of course, any opaque pixels in the original image should also appear in the result.
On a sidenote, your solution is almost a blur with a 3 x 3 kernel (you sample locations around the fragment in a 3 by 3 grid). However, a 3 x 3 kernel won't give you the amount of blur you need. You need more samples (e.g. 11 x 11). Also, the weights closer to the center should have a greater impact on the result. Thus, uniform weights won't work very well.
Oh, and one more important thing:
One single shader to acomplish this is NOT the fastest way to implement this. Usually, this would be acomplished with 2 separate renders. The first one would render the image as usual and the second render would blur and add the outline. I assumed that you want to do this with 1 single render.
The following is a vertex and fragment shader that accomplish this:
Vertex Shader
varying vec2 vecUV;
varying vec3 vecPos;
varying vec3 vecNormal;
void main() {
vecUV = uv * 3.0 - 1.0;
vecPos = (modelViewMatrix * vec4(position, 1.0)).xyz;
vecNormal = (modelViewMatrix * vec4(normal, 0.0)).xyz;
gl_Position = projectionMatrix * vec4(vecPos, 1.0);
}
Fragment Shader
precision highp float;
varying vec2 vecUV;
varying vec3 vecPos;
varying vec3 vecNormal;
uniform sampler2D inputImageTexture;
float normalProbabilityDensityFunction(in float x, in float sigma)
{
return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma;
}
vec4 gaussianBlur()
{
// The gaussian operator size
// The higher this number, the better quality the outline will be
// But this number is expensive! O(n2)
const int matrixSize = 11;
// How far apart (in UV coordinates) are each cell in the Gaussian Blur
// Increase this for larger outlines!
vec2 offset = vec2(0.005, 0.005);
const int kernelSize = (matrixSize-1)/2;
float kernel[matrixSize];
// Create the 1-D kernel using a sigma
float sigma = 7.0;
for (int j = 0; j <= kernelSize; ++j)
{
kernel[kernelSize+j] = kernel[kernelSize-j] = normalProbabilityDensityFunction(float(j), sigma);
}
// Generate the normalization factor
float normalizationFactor = 0.0;
for (int j = 0; j < matrixSize; ++j)
{
normalizationFactor += kernel[j];
}
normalizationFactor = normalizationFactor * normalizationFactor;
// Apply the kernel to the fragment
vec4 outputColor = vec4(0.0);
for (int i=-kernelSize; i <= kernelSize; ++i)
{
for (int j=-kernelSize; j <= kernelSize; ++j)
{
float kernelValue = kernel[kernelSize+j]*kernel[kernelSize+i];
vec2 sampleLocation = vecUV.xy + vec2(float(i)*offset.x,float(j)*offset.y);
vec4 sample = texture2D(inputImageTexture, sampleLocation);
outputColor += kernelValue * sample;
}
}
// Divide by the normalization factor, so the weights sum to 1
outputColor = outputColor/(normalizationFactor*normalizationFactor);
return outputColor;
}
void main()
{
// After blurring, what alpha threshold should we define as outline?
float alphaTreshold = 0.3;
// How smooth the edges of the outline it should have?
float outlineSmoothness = 0.1;
// The outline color
vec4 outlineColor = vec4(1.0, 1.0, 1.0, 1.0);
// Sample the original image and generate a blurred version using a gaussian blur
vec4 originalImage = texture2D(inputImageTexture, vecUV);
vec4 blurredImage = gaussianBlur();
float alpha = smoothstep(alphaTreshold - outlineSmoothness, alphaTreshold + outlineSmoothness, blurredImage.a);
vec4 outlineFragmentColor = mix(vec4(0.0), outlineColor, alpha);
gl_FragColor = mix(outlineFragmentColor, originalImage, originalImage.a);
}
This is the result I got:
And for the same image as yours, with matrixSize = 33, alphaTreshold = 0.05
And to try to get crispier results we can tweak the parameters. Here is an example with matrixSize = 111, alphaTreshold = 0.05, offset = vec2(0.002, 0.002), alphaTreshold = 0.01, outlineSmoothness = 0.00. Note that increasing matrixSize will heavily impact performance, which is a limitation of rendering this outline with only one shader pass.
I tested the shader on this site. Hopefully you will be able to adapt it to your solution.
Regarding references, I have used quite a lot of this shadertoy example as basis for the code I wrote for this answer.
In my filters, the smoothness is achieved by a simple boxblur on the border.. You have decided that alpha > 0.4 is a border. The value of alpha between 0-0.4 in surrounding pixels gives an edge. Just blur this edge with a 3x3 window to get the smooth edge.
if ( current.a != 1.0 ) {
// other processing
if (current.a > 0.4) {
if ( (top.a < 0.4 || bottom.a < 0.4 || left.a < 0.4 || right.a < 0.4
|| topLeft.a < 0.4 || topRight.a < 0.4 || bottomLeft.a < 0.4 || bottomRight.a < 0.4 )
{
// Implement 3x3 box blur here
}
}
}
You need to tweak which edge pixels you blur. The basic issue is that it drops from an opaque to a transparent pixel - what you need is a gradual transition.
Another options is quick anti-aliasing. From my comment below - Scale up 200% and then scale down 50% to original method. Use nearest neighbour scaling. This technique is used for smooth edges on text sometimes.

How to mask a fragment shader

I want to implement backround blurring for selfie camera.
I have a blurring fragment shader
precision mediump float;
uniform sampler2D uSampler;
uniform float uBlur;
uniform float uRadius;
varying vec2 vTextureCoord;
void main() {
vec3 sum = vec3(0);
if (uBlur > 0.0) {
for (float i = -uBlur; i < uBlur; i++) {
for (float j = -uBlur; j < uBlur; j++) {
sum += texture2D(uSampler, vTextureCoord + vec2(i, j) * (uRadius / uBlur)).rgb / pow(uBlur * 2.0, 2.0);
}
}
} else {
sum = texture2D(uSampler, vTextureCoord).rgb;
}
gl_FragColor = vec4(sum, 1.0);
}
Also I have an array which indicates where I need to put blurring effect.
My idea is to pass the array somehow to the fragment shader and skip coordinates that should not be blurred.
Is there any way to do that or is there any other way I should follow?
UPD0:
Mask is generated dynamically several times per second. The mask data contained by com.google.mlkit.vision.segmentation.SegmentationMask class - It has ByteBuffer with width and heigh inside.
I tried to generate a bitmap with
Bitmap.createBitmap(maskColorsFromByteBuffer(mask), maskWidth, maskHeight, Config.ARGB_8888)
and
private int[] maskColorsFromByteBuffer(ByteBuffer byteBuffer) {
#ColorInt int[] colors = new int[maskWidth * maskHeight];
for (int i = 0; i < maskWidth * maskHeight; i++) {
float backgroundLikelihood = 1 - byteBuffer.getFloat();
if (backgroundLikelihood > 0.9) {
colors[i] = Color.argb(128, 51, 112, 69);
} else if (backgroundLikelihood > 0.2) {
// Linear interpolation to make sure when backgroundLikelihood is 0.2, the alpha is 0 and
// when backgroundLikelihood is 0.9, the alpha is 128.
// +0.5 to round the float value to the nearest int.
int alpha = (int) (182.9 * backgroundLikelihood - 36.6 + 0.5);
colors[i] = Color.argb(alpha, 51, 112, 69);
}
}
return colors;
}
After generating the bitmap I tried to draw it with ImageObjectFilterRender - as far as I see that class generating texture from the bitmap.

GLSL performance issue in fragment shader on vec4 add

I have a fairly simple fragment shader used to handle a situation with multiple lights (code below trimmed down for clarity, only two lights shown).
The broad idea is to sum the various lighting contributions for each fragment, and it work fine, however I have found that it is unstably so on my hardware (Android HTX Desire X).
Measuring FPS, it becomes apparent that there is a single vec4 addition line which is causing the FPS to drop by 10.
What could be causing this performance hit on such an apparently simple operation?
void main (void)
{
vec4 v = u_ViewModelMatrix * vec4(v_Vertex, 1.0);
vec3 nv = normalize(-v.xyz);
vec3 normalVector = normalize((u_ViewModelTransposeMatrix * vec4(normalize(v_Normal), 0.0)).xyz);
vec4 finalColour = vec4(0.0, 0.0, 0.0, 1.0);
// LIGHT 0
lightPosition = vec4(u_LightData[2], u_LightData[3], u_LightData[4], 1);
lightColour = vec4(u_LightData[5], u_LightData[6], u_LightData[7], 1.0) * u_LightData[0];
lightVector = normalize((u_ViewMatrix * lightPosition).xyz - v.xyz);
halfwayVector = normalize(lightVector + nv);
facing = dot(normalVector, lightVector);
if (facing >= 0.0) {
finalColour = finalColour + diffuseColour * facing * lightColour;
}
// LIGHT 1
lightPosition = vec4(u_LightData[LIGHTS_FLOATS_PER_LIGHT*1+2],
u_LightData[LIGHTS_FLOATS_PER_LIGHT*1+3],
u_LightData[LIGHTS_FLOATS_PER_LIGHT*1+4],
1);
lightColour = vec4(u_LightData[LIGHTS_FLOATS_PER_LIGHT*1+5],
u_LightData[LIGHTS_FLOATS_PER_LIGHT*1+6],
u_LightData[LIGHTS_FLOATS_PER_LIGHT*1+7],
1.0) * u_LightData[LIGHTS_FLOATS_PER_LIGHT*1];
lightVector = normalize((u_ViewMatrix * lightPosition).xyz - v.xyz);
halfwayVector = normalize(lightVector + nv);
facing = dot(normalVector, lightVector);
if (facing >= 0.01) {
vec4 qwe = diffuseColour * facing * lightColour;
// HERE .............
finalColour = finalColour + qwe; // takes 10 fps
// HERE ^^^^^^^^^^^^^
}
gl_FragColor = finalColour;
}
Branching causes this. Avoid using ifs and for loops.
Replace
if (facing >= 0.0) {
finalColour = finalColour + diffuseColour * facing * lightColour;
}
with
finalColour += max(0.0, facing) * diffuseColour * lightColour;
and
if (facing >= 0.01) {
vec4 qwe = diffuseColour * facing * lightColour;
// HERE .............
finalColour = finalColour + qwe; // takes 10 fps
// HERE ^^^^^^^^^^^^^
}
with
finalColour += step(0.01, facing) * facing * diffuseColour * lightColour;
Don't worry if you will be calculating some values even when you don't need it. Since shaders are executed in parallel you can't get much faster than the slowest instance.
Also you should move as many things as possible to the vertex shader since it'll be executed just once for every vertex vs for every pixel in the fragment shader; basically you calculate everything that (tri)interpolates well in vertex shader and pass it as varyings:
Position and color of the lights
Vectors L, V and H (in this example at least)

Android OpenGLES 2.0 2D Rendering

After two days of bashing my head and trying to figure this stuff out I have been woefully unsuccessful, hopefully someone can point me in the right direction.
I am trying to make a tile based game in GLES 2.0, but I cant get anything to show up the way I want. Basically I have an array of vertices that make up pairs of triangles that would form a square grid. I want to use GLES20.glDrawArrays() to draw subsections of this grid at a time.
I have figured out how to "view" from a different perspective using a combination of Matrix.orthoM() and Matrix.setLookAtM() but for the life of me I can figure out how to have my triangles not fill the entire screen.
I really need some guidance on setting up a projection so that if the triangle is defined as (0,0,0) (0,20,0) (20,0,0) it shows up on the screen as 20 pixels wide and 20 pixels tall, translated by my current view.
Here is what I have currently, but it just fills my entire screen with green. If someone could show me the correct way to manipulate the scene so that it fills the camera, or the camera only shows like 20 triangles wide by 10 triangle high that would make my week.
When the surface changes:
GLES20.glViewport(0, 0, ScreenX, ScreenY);
float ratio = ScreenX / ScreenY;
Matrix.orthoM(_ProjMatrix, 0,
-ratio,
ratio,
-1, 1,
3, 7);
Matrix.setLookAtM(_VMatrix, 0,
60, 60, 7,
60, 60, 0,
0, 1, 0);
Beginning drawing:
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
Matrix.multiplyMM(_MVPMatrix, 0, _ProjMatrix, 0, _VMatrix, 0);
if (_activeMap != null)
_activeMap.draw(0, 0, (int)ScreenX, (int)ScreenY, _MVPMatrix);
The draw function:
public void draw(int x, int y, int width, int height, float[] MVPMatrix)
{
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUseProgram(_pHandle);
GLES20.glUniformMatrix4fv(_uMVPMatrixHandle, 1, false, MVPMatrix, 0);
int minRow, minCol, maxRow, maxCol;
minRow = (int) (y / Engine.TileSize);
minCol = (int) (x / Engine.TileSize);
maxRow = (int) (minRow + (height / Engine.TileSize));
maxCol = (int) (minCol + (width / Engine.TileSize));
minRow = (minRow < 0) ? 0 : minRow;
minCol = (minCol < 0) ? 0 : minCol;
maxRow = (maxRow > _rows) ? (int)_rows : maxRow;
maxCol = (maxCol > _cols) ? (int)_cols : maxCol;
for (int r = minRow; r < maxRow - 1; r++)
for (int d = 0; d < _vBuffers.length; d++)
{
_vBuffers[d].position(0);
GLES20.glVertexAttribPointer(_vAttHandle, 3, GLES20.GL_FLOAT,
false,
0, _vBuffers[d]);
GLES20.glEnableVertexAttribArray(_vAttHandle);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES,
(int) (r * 6 * _cols),
(maxCol - minCol) * 6);
}
}
Shader script:
private static final String _VERT_SHADER =
"uniform mat4 uMVPMatrix; \n"
+ "attribute vec4 vPosition; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = uMVPMatrix * vPosition; \n"
+ "} \n";
private static final String _FRAG_SHADER =
"precision mediump float; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = vec4 (0.63671875, 0.76953125, 0.22265625, 1.0); \n"
+ "} \n";
For a tile based game a simple translate would be far more appropriate, setLookAt is just overkill.
I hope it may help you. Check this link for OpenGL programming.
OpenGL Programming Guide
Go to Chapter 3.Viewing here you can find information about projection.

Fragment shader with multiple floating operations slow on Xoom (tegra2)

I am trying to make "burning star" impression on android game I have been developing with little help of noise function (simplex noise in this case). Unfortunately I cant use 3d textures as they are in gles extension and android packages doesn't have them included.
Only option left for me is therefore calculating noise function in fragment shader. Code provided below runs smoothly or acceptably (20-60fps) on HTC Desire Z andLG optimus one. With same program on Motorola XOOM (which have tegra2 chipset) however I get fraction(1-3) of fps even when displaying only small part of object.
Thing we tried so far:
meddling with precision(lowp-higp), both in first line directive and specifying for each occurrence of float/vec separately
commenting parts of noise function - it seem that there isn't any particular bottleneck, its combination of all things together
googling problems related to tegra, floating point in shaders etc
This is stripped down part of code needed for reproduction of this behavior. Note that on XOOM there are some artifacts which we believe is caused by 16bit floating operations in tegra.
precision mediump float;
#define pi 3.141592653589793238462643383279
//
// Description : Array and textureless GLSL 2D/3D/4D simplex
// noise functions.
// Author : Ian McEwan, Ashima Arts.
// Maintainer : ijm
// Lastmod : 20110822 (ijm)
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
// Distributed under the MIT License. See LICENSE file.
// https://github.com/ashima/webgl-noise
//
vec3 mod289(vec3 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec4 mod289(vec4 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec4 permute(vec4 x) {
return mod289(((x*34.0)+1.0)*x);
}
vec4 taylorInvSqrt(vec4 r)
{
return 1.79284291400159 - 0.85373472095314 * r;
}
float snoise(vec3 v)
{
const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
// First corner
vec3 i = floor(v + dot(v, C.yyy) );
vec3 x0 = v - i + dot(i, C.xxx) ;
// Other corners
vec3 g = step(x0.yzx, x0.xyz);
vec3 l = 1.0 - g;
vec3 i1 = min( g.xyz, l.zxy );
vec3 i2 = max( g.xyz, l.zxy );
// x0 = x0 - 0.0 + 0.0 * C.xxx;
// x1 = x0 - i1 + 1.0 * C.xxx;
// x2 = x0 - i2 + 2.0 * C.xxx;
// x3 = x0 - 1.0 + 3.0 * C.xxx;
vec3 x1 = x0 - i1 + C.xxx;
vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
// Permutations
i = mod289(i);
vec4 p = permute( permute( permute(
i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
+ i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
+ i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
// Gradients: 7x7 points over a square, mapped onto an octahedron.
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
float n_ = 0.142857142857; // 1.0/7.0
vec3 ns = n_ * D.wyz - D.xzx;
vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
vec4 x_ = floor(j * ns.z);
vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
vec4 x = x_ *ns.x + ns.yyyy;
vec4 y = y_ *ns.x + ns.yyyy;
vec4 h = 1.0 - abs(x) - abs(y);
vec4 b0 = vec4( x.xy, y.xy );
vec4 b1 = vec4( x.zw, y.zw );
//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
vec4 s0 = floor(b0)*2.0 + 1.0;
vec4 s1 = floor(b1)*2.0 + 1.0;
vec4 sh = -step(h, vec4(0.0));
vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
vec3 p0 = vec3(a0.xy,h.x);
vec3 p1 = vec3(a0.zw,h.y);
vec3 p2 = vec3(a1.xy,h.z);
vec3 p3 = vec3(a1.zw,h.w);
//Normalise gradients
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
// Mix final noise value
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
m = m * m;
return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
dot(p2,x2), dot(p3,x3) ) );
}
uniform vec3 color1;
uniform vec3 color2;
uniform float t;
varying vec3 vTextureCoord;
void main()
{
float t = 0.5; //mod(t, 3.0);
float x = (vTextureCoord.x)*2.0;
float y = -(vTextureCoord.y)*2.0;
float r = sqrt(x * x + y * y);
gl_FragColor = vec4(0.0,0.0,0.0,0.0);
if(r<= 1.0){
float n = snoise( vec3(vec2(x,y), Mr_T*3.3 ) );
gl_FragColor = vec4( mix(color1,color2, abs(n) ) ,1.0);
}
}
I was facing the same problem for tegra2 a while ago. Read 1.3 : http://www.opengl.org/wiki/GLSL_:_common_mistakes. and feel the pain. In my case fps went up twice but it still sucked.

Categories

Resources