I am developing OpenGLES app for Android and using Perlin noise from Stefan Gustavson. It's animated 2D noise so I use 3D Perlin with time variable as third dimension. And it was all looking good on my Samsung Galaxy Young (API 10), but when I tested it with ASUS MEMO tablet (API 17) I got this glitchy thing with even elipses and square-like areas:-
What could cause such differences between various devices?
Fragment shader code:
precision mediump float;
varying vec2 screenPosition;
uniform vec4 colorFilter;
uniform float time;
vec4 permute(vec4 x)
{
return mod(((x*34.0)+1.0)*x, 289.0);
}
vec4 taylorInvSqrt(vec4 r)
{
return 1.79284291400159 - 0.85373472095314 * r;
}
vec3 fade(vec3 t) {
return t*t*t*(t*(t*6.0-15.0)+10.0);
}
float noise(vec3 P)
{
vec3 Pi0 = floor(P); // Integer part for indexing
vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1
Pi0 = mod(Pi0, 289.0);
Pi1 = mod(Pi1, 289.0);
vec3 Pf0 = fract(P); // Fractional part for interpolation
vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0
vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
vec4 iy = vec4(Pi0.yy, Pi1.yy);
vec4 iz0 = Pi0.zzzz;
vec4 iz1 = Pi1.zzzz;
vec4 ixy = permute(permute(ix) + iy);
vec4 ixy0 = permute(ixy + iz0);
vec4 ixy1 = permute(ixy + iz1);
vec4 gx0 = ixy0 / 7.0;
vec4 gy0 = fract(floor(gx0) / 7.0) - 0.5;
gx0 = fract(gx0);
vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);
vec4 sz0 = step(gz0, vec4(0.0));
gx0 -= sz0 * (step(0.0, gx0) - 0.5);
gy0 -= sz0 * (step(0.0, gy0) - 0.5);
vec4 gx1 = ixy1 / 7.0;
vec4 gy1 = fract(floor(gx1) / 7.0) - 0.5;
gx1 = fract(gx1);
vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);
vec4 sz1 = step(gz1, vec4(0.0));
gx1 -= sz1 * (step(0.0, gx1) - 0.5);
gy1 -= sz1 * (step(0.0, gy1) - 0.5);
vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);
vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);
vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);
vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);
vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);
vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);
vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);
vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);
vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
g000 *= norm0.x;
g010 *= norm0.y;
g100 *= norm0.z;
g110 *= norm0.w;
vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
g001 *= norm1.x;
g011 *= norm1.y;
g101 *= norm1.z;
g111 *= norm1.w;
float n000 = dot(g000, Pf0);
float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));
float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));
float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));
float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));
float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));
float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));
float n111 = dot(g111, Pf1);
vec3 fade_xyz = fade(Pf0);
vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);
vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);
float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);
return 2.2 * n_xyz;
}
void main() {
float valuer = (noise(vec3(screenPosition.x*4.0, screenPosition.y*3.0, time)));
float val1 = 0.25*(sign(valuer+0.2)-sign(valuer-0.2));
float val2 = 0.125*(sign(valuer+0.4)-sign(valuer-0.4));
outputColor = colorFilter*(val1+val2+0.25);
}
Most likely the Samsung Galaxy Young is executing the math at highp, and the ASUS MEMO tablet is executing at mediump.
OpenGLES devices are not required to support highp in fragment shaders, but the above code looks very much like it will be required.
Is that even a full fragment shader? I thought GLES fragment shaders required you to specify a default precision or required you to specify precision on a per-variable basis. I see neither, so perhaps there is some information omitted.
Related
I have an OpenGL app with a simple shader that run well on an emulator device in Android Studio with API 30 but on my own hardware device (API 30) it doesn't.
The problem is in the fragment shader. This is the code:
#version 100
precision highp float;
struct DirLight {
int on;
vec3 direction;
vec3 ambientColor;
vec3 diffuseColor;
vec3 specularColor;
float specularExponent;
sampler2D shadowMap;
mat4 shadowVPMatrix;
int shadowEnabled;
};
struct PointLight {
int on;
vec3 position;
float constant;
float linear;
float quadratic;
vec3 ambientColor;
vec3 diffuseColor;
vec3 specularColor;
float specularExponent;
sampler2D shadowMap;
mat4 shadowVPMatrix;
int shadowEnabled;
};
#define MAX_NUM_POINT_LIGHTS 8
uniform DirLight uDirLight;
uniform PointLight uPointLights[MAX_NUM_POINT_LIGHTS];
uniform int uNumPointLights;
uniform vec3 uViewPos;
uniform sampler2D uTexture;
uniform int uIsTextured;
varying vec4 vColor;
varying vec4 vPosition;
varying vec3 vNormal;
varying vec2 vTexCoords;
const vec4 bitShifts = vec4(1.0 / (256.0*256.0*256.0), 1.0 / (256.0*256.0), 1.0 / 256.0, 1.0);
vec4 getColor(){
if (uIsTextured != 0){
return texture2D(uTexture,vTexCoords);
}
return vColor;
}
float unpack(vec4 color){
return dot(color, bitShifts);
}
// return 0.0 if in shadow.
// return 1.0 if not in shadow.
float calcShadow(sampler2D shadowMap, vec4 positionFromLight, int shadowEnabled){
if (shadowEnabled == 0){
return 1.0;
}
vec3 positionFromLight3 = positionFromLight.xyz / positionFromLight.w;
positionFromLight3 = (positionFromLight3 + 1.0) / 2.0;
float closestFragmentZ = unpack(texture2D(shadowMap, positionFromLight3.xy));
float currentFragmentZ = positionFromLight3.z;
return float(closestFragmentZ > currentFragmentZ);
}
float diffuseLighting(vec3 normal, vec3 lightDir){
return max(dot(normal, lightDir), 0.0);
}
float specularLighting(vec3 normal, vec3 lightDir, vec3 viewDir, float specularExponent){
vec3 reflectDir = reflect(-lightDir, normal);
return pow(max(dot(viewDir, reflectDir), 0.0), specularExponent);
}
vec4 calcDirLight(vec3 normal, vec3 viewDir){
vec3 lightDir = normalize(-uDirLight.direction);
float diff = diffuseLighting(normal, lightDir);
float spec = specularLighting(normal, lightDir, viewDir, uDirLight.specularExponent);
vec4 color = getColor();
vec4 ambient = vec4(uDirLight.ambientColor, 1.0) * color;
vec4 diffuse = vec4(uDirLight.diffuseColor * diff, 1.0) * color;
vec4 specular = vec4(uDirLight.specularColor * spec, 1.0) * vec4(0.5,0.5,0.5,1.0);
return ambient + (diffuse + specular) * calcShadow(uDirLight.shadowMap, uDirLight.shadowVPMatrix * vPosition, uDirLight.shadowEnabled);
}
float calcAttenuation(PointLight pointLight, float distance){
return 1.0 / (pointLight.constant + pointLight.linear * distance + pointLight.quadratic * (distance * distance));
}
vec4 calcPointLight(PointLight pointLight, vec3 normal, vec3 viewDir){
vec3 d = pointLight.position - vec3(vPosition);
vec3 lightDir = normalize(d);
float diff = diffuseLighting(normal, lightDir);
float spec = specularLighting(normal, lightDir, viewDir, pointLight.specularExponent);
float distance = length(d);
float attenuation = calcAttenuation(pointLight,distance);
vec4 color = getColor();
vec4 ambient = vec4(pointLight.ambientColor, 1.0) * color;
vec4 diffuse = vec4(pointLight.diffuseColor * diff, 1.0) * color;
vec4 specular = vec4(pointLight.specularColor * spec, 1.0) * vec4(0.5,0.5,0.5,1.0);
ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;
return ambient + (diffuse + specular) * calcShadow(pointLight.shadowMap, pointLight.shadowVPMatrix * vPosition, pointLight.shadowEnabled);
}
void main() {
vec3 normal = normalize(vNormal);
vec3 viewDir = normalize(uViewPos - vec3(vPosition));
vec4 result = vec4(0.0);
if (uDirLight.on == 1){
result = calcDirLight(normal, viewDir);
}
for (int i = 0; i < uNumPointLights; i++){
if (uPointLights[i].on == 1){
result += calcPointLight(uPointLights[i], normal, viewDir);
}
}
gl_FragColor = result;
}
When I run the app on my device logcat shows the following lines
2021-06-24 17:49:14.032 2061-2096/com.outofbound.rhinoengine I/AdrenoGLES-0: Build Config : S P 10.0.7 AArch64
2021-06-24 17:49:14.032 2061-2096/com.outofbound.rhinoengine I/AdrenoGLES-0: Driver Path : /vendor/lib64/egl/libGLESv2_adreno.so
2021-06-24 17:49:14.036 2061-2096/com.outofbound.rhinoengine I/AdrenoGLES-0: PFP: 0x016ee190, ME: 0x00000000
2021-06-24 17:49:14.040 2061-2061/com.outofbound.rhinoengine D/SurfaceView: UPDATE null, mIsCastMode = false
2021-06-24 17:49:14.074 2061-2102/com.outofbound.rhinoengine I/AdrenoGLES-0: ERROR: 0:101: 'viewDir' : undeclared identifier
ERROR: 0:101: 'specularLighting' : no matching overloaded function found
ERROR: 2 compilation errors. No code generated.
2021-06-24 17:49:14.075 2061-2102/com.outofbound.rhinoengine I/AdrenoGLES-0: ERROR: 0:101: 'viewDir' : undeclared identifier
ERROR: 0:101: 'specularLighting' : no matching overloaded function found
ERROR: 2 compilation errors. No code generated.
2021-06-24 17:49:15.316 2061-2085/com.outofbound.rhinoengine W/System: A resource failed to call close.
BUT if I simply rename viewDir to v in main() function
void main() {
vec3 normal = normalize(vNormal);
vec3 v = normalize(uViewPos - vec3(vPosition));
vec4 result = vec4(0.0);
if (uDirLight.on == 1){
result = calcDirLight(normal, v);
}
for (int i = 0; i < uNumPointLights; i++){
if (uPointLights[i].on == 1){
result += calcPointLight(uPointLights[i], normal, v);
}
}
gl_FragColor = result;
}
the error above disappears but the app still doesn't work showing a black screen.
Any tips?
It looks to me that the viewDir issue is a driver bug where it's messed up trying to inline your code.
However, you should be aware that is not a simple shader by OpenGLES 2 standards. As Dpk implied, you cannot assume high precision is available in OpenGLES2.
Additionally, you cannot assume that there's anywhere near enough uniform space for your shader. Try using glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxFragmentUniforms); to see how many uniforms are supported. Devices are allowed to go as low as 16 vec4s, but your shader uses 100s.
I'd suggest you consider switching to OpenGLES 3 or 3.1 if you don't want to worry about some of the tight limits of GLES2. If you persist with OpenGLES2 then maybe cut the shader right back to literally nothing (just return a colour) and gradually build up the functionality.
Also, make sure you are checking for errors on shader compilation and linking and all OpenGLES calls, it can save a lot of time.
try
//#version 100
//precision highp float;
precision mediump float;
and try this
opengles20 may not support INT in param see doc
float on;
//if (uDirLight.on == 1){
if (uDirLight.on == 1.0){
I think the error is related to the array of uniform uniform PointLight uPointLights[MAX_NUM_POINT_LIGHTS];. So I solved using one point light
uniform PointLight uPointLight;.
Anyway I'll try if defining multiple uniform PointLight uPointLightN; with 0 <= N < MAX_NUM_POINT_LIGHTS it still works.
So I have 2 shaders that I want to combine. ie, the output of shader 1 (Edge Detection) should be the input of shader 2 (Blur).
Both shaders work perfectly standalone. However, I do not know how to combine them, because the output of shader 1 is a vec4, and shader 2 needs to use texture coordinate and sampler2D.
Shader 1 (Edge Detection)
precision highp float;
varying vec3 n;
varying vec2 uv;
uniform sampler2D tex;
precision mediump float;
void main() {
/*
* Edge Detection
*/
vec3 irgb = texture2D(tex, uv).rgb;
float ResS = 720.;
float ResT = 720.;
vec2 stp0 = vec2(1./ResS, 0.);
vec2 st0p = vec2(0., 1./ResT);
vec2 stpp = vec2(1./ResS, 1./ResT);
vec2 stpm = vec2(1./ResS, -1./ResT);
const vec3 W = vec3(0.2125, 0.7154, 0.0721);
float i00 = dot(texture2D(tex, uv).rgb, W);
float im1m1 = dot(texture2D(tex, uv-stpp).rgb, W);
float ip1p1 = dot(texture2D(tex, uv+stpp).rgb, W);
float im1p1 = dot(texture2D(tex, uv-stpm).rgb, W);
float ip1m1 = dot(texture2D(tex, uv+stpm).rgb, W);
float im10 = dot(texture2D(tex, uv-stp0).rgb, W);
float ip10 = dot(texture2D(tex, uv+stp0).rgb, W);
float i0m1 = dot(texture2D(tex, uv-st0p).rgb, W);
float i0p1 = dot(texture2D(tex, uv+st0p).rgb, W);
float h = -1.*im1p1 - 2.*i0p1 - 1.*ip1p1 + 1.*im1m1 + 2.*i0m1 + 1.*ip1m1;
float v = -1.*im1m1 - 2.*im10 - 1.*im1p1 + 1.*ip1m1 + 2.*ip10 + 1.*ip1p1;
float mag = length(vec2(h, v));
vec3 target = vec3(mag, mag, mag);
vec4 nonWhiteToBlack = vec4(mix(irgb, target, 1.0),1.);
if (nonWhiteToBlack.r < 0.2 && nonWhiteToBlack.g < 0.2 && nonWhiteToBlack.b < 0.2) {
nonWhiteToBlack = vec4(0,0,0,1);
}
gl_FragColor = vec4(nonWhiteToBlack);
}
Shader 2 (Blur)
/*
* blur
*/
vec3 irgb = texture2D(tex, uv).rgb;
float ResS = 720.;
float ResT = 720.;
vec2 stp0 = vec2(1./ResS, 0.);
vec2 st0p = vec2(0., 1./ResT);
vec2 stpp = vec2(1./ResS, 1./ResT);
vec2 stpm = vec2(1./ResS, -1./ResT);
vec3 i00 = texture2D(tex, uv).rgb;
vec3 im1m1 = texture2D(tex, uv-stpp).rgb;
vec3 ip1p1 = texture2D(tex, uv+stpp).rgb;
vec3 im1p1 = texture2D(tex, uv-stpm).rgb;
vec3 ip1m1 = texture2D(tex, uv+stpm).rgb;
vec3 im10 = texture2D(tex, uv-stp0).rgb;
vec3 ip10 = texture2D(tex, uv+stp0).rgb;
vec3 i0m1 = texture2D(tex, uv-st0p).rgb;
vec3 i0p1 = texture2D(tex, uv+st0p).rgb;
vec3 target = vec3(0., 0., 0.);
target += 1.*(im1m1+ip1m1+ip1p1+im1p1);
target += 2.*(im10+ip10+i0p1);
target += 4.*(i00);
target /= 16.;
gl_FragColor = vec4(target, 1.);
Any Help Would Be Appreciated
The following is the GLSL Fragment Shader code I'm concerned about:
#extension GL_OES_EGL_image_external : require
precision lowp float;
varying highp vec2 v_TexCoordinate;
uniform samplerExternalOES u_Texture;
uniform float uParamValue1; // hue
uniform float uParamValue2; // hue of replacing color
const float delta = 0.1;
vec3 rgb2hsv(vec3 c)
{
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);
vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx);
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
vec3 hsv2rgb(vec3 c)
{
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
void main()
{
vec3 texel = texture2D(u_Texture, v_TexCoordinate).rgb;
vec3 texelHsv = rgb2hsv(texel);
if(!(abs(texelHsv.x - uParamValue1) < delta))
{
texel = vec3(dot(vec3(0.299, 0.587, 0.114), texel));
//texel = vec3(texture2D(inputImageTexture2, vec2(texel.r, .16666)).r);
}
else
{
texelHsv.x = uParamValue2;
texel = hsv2rgb(texelHsv);
}
gl_FragColor = vec4(texel, 1.0);
}
The value of uParamValue1 and uParamValue2 is changed via two seekbars.
When I checked the uniform locations of uParamValue1 and uParamValue2, they returned valid uniforms on both my Galaxy S6 and Xiaomi Mi 3W, 1 and 2 respectively.
However, when I move the slider that corresponds to uParamValue1, the shader doesn't seem to respond to the changes in Xiaomi Mi 3W, whereas in the Galaxy S6, it works fine.
Why is this, and how can I prevent it from happening?
I try to implement warp shader (black hole). It works great on desktop, but it looks wrong on mobile devices. The problem is in its size. When I increase the size of black hole the warped edges disappear. If it has very small size it looks as I want. I am using LibGDX.
How it should look like (Desktop):
How it looks on mobile device with the same size:
When I decrease the size the warped edges appears:
Vertex shader:
attribute vec2 a_position;
void main()
{
gl_Position = vec4(a_position.xy, 0.0, 1.0);
}
Fragment shader:
#ifdef GL_ES
precision mediump float;
#endif
uniform sampler2D u_texture;
uniform vec2 u_res;
uniform float u_size;
// Gravitational field at
// position pos, given a black hole
// of mass m at position center
// (ignoring G constant)
vec2 Fgrav(float m, vec2 center, vec2 pos)
{
vec2 dir = center - pos;
float distance = length(dir);
dir /= distance;
return dir * (m / (distance*distance));
}
void main(void)
{
vec2 texCoord = gl_FragCoord.xy / u_res.xy;
vec4 sceneColor;
vec2 blackHoleCenters = vec2(u_res.xy*.5);
vec2 netGrav = Fgrav( (50. - u_size) * 500., blackHoleCenters, gl_FragCoord.xy);
float netGravMag = length(netGrav);
if(netGravMag < 1.0)
{
texCoord = (gl_FragCoord.xy + netGrav*((50. - u_size) * 15.0))/u_res.xy;
}
else texCoord.xy=vec2(.5,.5);
sceneColor = texture2D(u_texture, texCoord);
gl_FragColor = sceneColor;
}
How to fix this issue? Thanks.
UPDATE:
That's how I get u_size parameter:
public float getDistance(Camera cam){
return (float) Math.sqrt(Math.pow(cam.position.x, 2) + Math.pow(cam.position.y, 2) + Math.pow(cam.position.z, 2));
}
public void render(Camera cam, Mesh quad) {
program.begin();
program.setUniformf(u_size, getDistance(cam));
...
Initializing of camera:
cam = new PerspectiveCamera(64, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
cam.position.set(0f, 0.0f, 30.0f);
cam.lookAt(0,0.0f,0);
cam.near = 0.1f;
cam.far = 450f;
cam.update();
So, the initial value of u_size is 30.
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.