bug: shader doesn't get rendered and doesn't display any error
ElmarWueest opened this issue · 6 comments
Hello
My shader get not rendered. The Fps counter is running and no error gets displayed, but only the VS background color is rendered.
I'm developing a shader for a Phone background. This shader is programmed to run on the "shader editor" app: appstore. The shader runs without any problems on this app.(undefine "on_vs" for use on the app.)
My guess for the cause of this problem: I use arrays in my shader.
my shader:
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define on_vs
#ifdef on_vs
vec2 resolution = iResolution.xy;
float time = iGlobalTime;
vec2 offset = iMouse.xy / iResolution.xy * vec2(-1.0, -1.0);
#else
uniform vec2 resolution;
uniform float time;
uniform vec2 offset;
#endif
void cswap(inout vec3[8] points, inout float[8] pdistance, int i){
if(pdistance[i]>pdistance[i+1]){
float tempf = pdistance[i];
pdistance[i] = pdistance[i+1];
pdistance[i+1] = tempf;
vec3 tempv3 = points[i];
points[i] = points[i+1];
points[i+1] = tempv3;
}
}
void sort(inout vec3[8] points, inout float[8] pdistance){
cswap(points,pdistance,0);
cswap(points,pdistance,2);
cswap(points,pdistance,4);
cswap(points,pdistance,6);
cswap(points,pdistance,1);
cswap(points,pdistance,3);
cswap(points,pdistance,5);
cswap(points,pdistance,2);
cswap(points,pdistance,4);
cswap(points,pdistance,3);
cswap(points,pdistance,2);
cswap(points,pdistance,4);
cswap(points,pdistance,1);
cswap(points,pdistance,3);
cswap(points,pdistance,5);
cswap(points,pdistance,0);
cswap(points,pdistance,2);
cswap(points,pdistance,4);
cswap(points,pdistance,6);
}
void FAST32_hash_3D( vec3 gridcell,
out vec4 lowz_hash_0,
out vec4 lowz_hash_1,
out vec4 lowz_hash_2,
out vec4 highz_hash_0,
out vec4 highz_hash_1,
out vec4 highz_hash_2 ) // generates 3 random numbers for each of the 8 cell corners
{
// gridcell is assumed to be an integer coordinate
// TODO: these constants need tweaked to find the best possible noise.
// probably requires some kind of brute force computational searching or something....
const vec2 OFFSET = vec2( 50.0, 161.0 );
const float DOMAIN = 69.0;
const vec3 SOMELARGEFLOATS = vec3( 635.298681, 682.357502, 668.926525 );
const vec3 ZINC = vec3( 48.500388, 65.294118, 63.934599 );
// truncate the domain
gridcell.xyz = gridcell.xyz - floor(gridcell.xyz * ( 1.0 / DOMAIN )) * DOMAIN;
vec3 gridcell_inc1 = step( gridcell, vec3( DOMAIN - 1.5, DOMAIN - 1.5, DOMAIN - 1.5 ) ) * ( gridcell + 1.0 );
// calculate the noise
vec4 P = vec4( gridcell.xy, gridcell_inc1.xy ) + OFFSET.xyxy;
P *= P;
P = P.xzxz * P.yyww;
vec3 lowz_mod = vec3( 1.0 / ( SOMELARGEFLOATS.xyz + gridcell.zzz * ZINC.xyz ) );
vec3 highz_mod = vec3( 1.0 / ( SOMELARGEFLOATS.xyz + gridcell_inc1.zzz * ZINC.xyz ) );
lowz_hash_0 = fract( P * lowz_mod.xxxx );
highz_hash_0 = fract( P * highz_mod.xxxx );
lowz_hash_1 = fract( P * lowz_mod.yyyy );
highz_hash_1 = fract( P * highz_mod.yyyy );
lowz_hash_2 = fract( P * lowz_mod.zzzz );
highz_hash_2 = fract( P * highz_mod.zzzz );
}
// convert a 0.0->1.0 sample to a -1.0->1.0 sample weighted towards the extremes
vec4 Cellular_weight_samples( vec4 samples )
{
samples = samples * 2.0 - 1.0;
//return (1.0 - samples * samples) * sign(samples); // square
return (samples * samples * samples) - sign(samples); // cubic (even more variance)
}
//
// Cellular Noise 3D
// Based off Stefan Gustavson's work at http://www.itn.liu.se/~stegu/GLSL-cellular
// http://briansharpe.files.wordpress.com/2011/12/cellularsample.jpg
//
// Speed up by using 2x2x2 search window instead of 3x3x3
// produces range of 0.0->1.0
//
float Cellular3D(vec3 P)
{
// establish our grid cell and unit position
vec3 Pi = floor(P);
vec3 Pf = P - Pi;
// calculate the hash.
// ( various hashing methods listed in order of speed )
vec4 hash_x0, hash_y0, hash_z0, hash_x1, hash_y1, hash_z1;
FAST32_hash_3D( Pi, hash_x0, hash_y0, hash_z0, hash_x1, hash_y1, hash_z1 );
// generate the 8 random points
// restrict the random point offset to eliminate artifacts
// we'll improve the variance of the noise by pushing the points to the extremes of the jitter window
const float JITTER_WINDOW = 0.23; // 0.166666666 will guarentee no artifacts. It is the intersection on x of graphs f(x)=( (0.5 + (0.5-x))^2 + 2*((0.5-x)^2) ) and f(x)=( 2 * (( 0.5 + x )^2) + x * x )
hash_x0 = Cellular_weight_samples( hash_x0 ) * JITTER_WINDOW + vec4(0.0, 1.0, 0.0, 1.0);
hash_y0 = Cellular_weight_samples( hash_y0 ) * JITTER_WINDOW + vec4(0.0, 0.0, 1.0, 1.0);
hash_x1 = Cellular_weight_samples( hash_x1 ) * JITTER_WINDOW + vec4(0.0, 1.0, 0.0, 1.0);
hash_y1 = Cellular_weight_samples( hash_y1 ) * JITTER_WINDOW + vec4(0.0, 0.0, 1.0, 1.0);
hash_z0 = Cellular_weight_samples( hash_z0 ) * JITTER_WINDOW + vec4(0.0, 0.0, 0.0, 0.0);
hash_z1 = Cellular_weight_samples( hash_z1 ) * JITTER_WINDOW + vec4(1.0, 1.0, 1.0, 1.0);
// return the closest squared distance
vec4 dx1 = Pf.xxxx - hash_x0;
vec4 dy1 = Pf.yyyy - hash_y0;
vec4 dz1 = Pf.zzzz - hash_z0;
vec4 dx2 = Pf.xxxx - hash_x1;
vec4 dy2 = Pf.yyyy - hash_y1;
vec4 dz2 = Pf.zzzz - hash_z1;
vec4 d1 = dx1 * dx1 + dy1 * dy1 + dz1 * dz1;
vec4 d2 = dx2 * dx2 + dy2 * dy2 + dz2 * dz2;
vec3 points[8];
points[0] = vec3(dx1.x,dy1.x,dz1.x);
points[1] = vec3(dx1.y,dy1.y,dz1.y);
points[2] = vec3(dx1.z,dy1.z,dz1.z);
points[3] = vec3(dx1.w,dy1.w,dz1.w);
points[4] = vec3(dx2.x,dy2.x,dz2.x);
points[5] = vec3(dx2.y,dy2.y,dz2.y);
points[6] = vec3(dx2.z,dy2.z,dz2.z);
points[7] = vec3(dx2.w,dy2.w,dz2.w);
float pdistance[8];
pdistance[0] = d1.x;
pdistance[1] = d1.y;
pdistance[2] = d1.z;
pdistance[3] = d1.w;
pdistance[4] = d2.x;
pdistance[5] = d2.y;
pdistance[6] = d2.z;
pdistance[7] = d2.w;
sort(points, pdistance);
vec3 minv = vec3(pdistance[0],pdistance[1],pdistance[2]);
float delta = (abs(minv.x - minv.y) + abs(minv.x - minv.z) + abs(minv.y - minv.z))/3.0;
float temp = ((minv.y / minv.x)/3.0) * -1.0 + 1.0;
float distance_to_middle = (minv.x + minv.y) / 2.0;
float c_to_mid = (distance_to_middle - minv.x);
c_to_mid /= distance_to_middle;
c_to_mid = c_to_mid * -1.0 + 1.0;
return smoothstep(0.93,1.0,c_to_mid);
return minv.x;
}
float CellFast(vec3 p, vec3 offset, float frequency, float amplitude)
{
float h = Cellular3D((p + offset) * frequency);
h *= amplitude;
return h;
}
vec2 rotate(vec2 pos, float angle){
float a = atan(pos.x/pos.y);
float l = sqrt(pos.x * pos.x + pos.y * pos.y);
a += angle;
pos.x = l*cos(a);
pos.y = l*sin(a);
return pos;
}
void main(void) {
float max_res = max(resolution.x,resolution.y);
vec2 uv = gl_FragCoord.xy /max_res;
vec2 soffset = offset * 0.7;
vec3 pos = vec3(uv + soffset,time/200.0);
pos.yz = rotate(pos.yz, 0.1);
float heigth = CellFast(pos, vec3(1.0,1.0,1.0), 8.0, 1.0);
gl_FragColor = vec4(heigth, heigth, heigth, 1.0);
}
Do you see compiler errors? For me it mentions:
WARNING: 0:129: '=' : global variable initializers should be constant expressions (uniforms and globals are allowed in global initializers for legacy compatibility)
WARNING: 0:130: '=' : global variable initializers should be constant expressions (uniforms and globals are allowed in global initializers for legacy compatibility)
WARNING: 0:131: '=' : global variable initializers should be constant expressions (uniforms and globals are allowed in global initializers for legacy compatibility)
Line 19: '[]' : Index expression must be constant
Line 19: '[]' : Index expression must be constant
Line 20: '[]' : Index expression must be constant
Line 21: '[]' : Index expression must be constant
Line 21: '[]' : Index expression must be constant
Line 22: '[]' : Index expression must be constant
Line 24: '[]' : Index expression must be constant
Line 25: '[]' : Index expression must be constant
Line 25: '[]' : Index expression must be constant
Line 26: '[]' : Index expression must be constant
The warnings can possibly be ignored, but the non-constant index expression won't ever compile on WebGL 1.0. I have a pull-request in the pipeline that enables partial WebGL 2.0 support if available. That maybe supports this, but I'm not sure myself. I'll check my dev-build when I get home.
Please let us know also if your output looks like this or if it is missing the error output:
Sorry, I just noticed I missed in your issue that you don't see the errors. Om what platform are you running VSC?
Yesterday I restarted VSC multiple times but no error got printed. Strangely, today all errors get printed as on your picture. Bug fixed, but I looking forward to hear more about WebGL 2.0 support.
The errors are removed in WebGL 2.0 but what was previously a warning has been promoted to an error :P
With a couple modifications to the shader I got it to run, not sure if that is how it should look:
Note I'm using the SHADER_TOY define to check if this is running in the extension, we have that "built-in". And to avoid the warning I hacked your variables to be defines instead, I also needed to change the parameter name of CellFast for that to work:
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define on_vs
#ifdef SHADER_TOY
#define resolution (iResolution.xy)
#define time (iGlobalTime)
#define offset (iMouse.xy / iResolution.xy * vec2(-1.0, -1.0))
#elif defined(on_vs)
vec2 resolution = iResolution.xy;
float time = iGlobalTime;
vec2 offset = iMouse.xy / iResolution.xy * vec2(-1.0, -1.0);
#else
uniform vec2 resolution;
uniform float time;
uniform vec2 offset;
#endif
void cswap(inout vec3[8] points, inout float[8] pdistance, int i){
if(pdistance[i]>pdistance[i+1]){
float tempf = pdistance[i];
pdistance[i] = pdistance[i+1];
pdistance[i+1] = tempf;
vec3 tempv3 = points[i];
points[i] = points[i+1];
points[i+1] = tempv3;
}
}
void sort(inout vec3[8] points, inout float[8] pdistance){
cswap(points,pdistance,0);
cswap(points,pdistance,2);
cswap(points,pdistance,4);
cswap(points,pdistance,6);
cswap(points,pdistance,1);
cswap(points,pdistance,3);
cswap(points,pdistance,5);
cswap(points,pdistance,2);
cswap(points,pdistance,4);
cswap(points,pdistance,3);
cswap(points,pdistance,2);
cswap(points,pdistance,4);
cswap(points,pdistance,1);
cswap(points,pdistance,3);
cswap(points,pdistance,5);
cswap(points,pdistance,0);
cswap(points,pdistance,2);
cswap(points,pdistance,4);
cswap(points,pdistance,6);
}
void FAST32_hash_3D( vec3 gridcell,
out vec4 lowz_hash_0,
out vec4 lowz_hash_1,
out vec4 lowz_hash_2,
out vec4 highz_hash_0,
out vec4 highz_hash_1,
out vec4 highz_hash_2 ) // generates 3 random numbers for each of the 8 cell corners
{
// gridcell is assumed to be an integer coordinate
// TODO: these constants need tweaked to find the best possible noise.
// probably requires some kind of brute force computational searching or something....
const vec2 OFFSET = vec2( 50.0, 161.0 );
const float DOMAIN = 69.0;
const vec3 SOMELARGEFLOATS = vec3( 635.298681, 682.357502, 668.926525 );
const vec3 ZINC = vec3( 48.500388, 65.294118, 63.934599 );
// truncate the domain
gridcell.xyz = gridcell.xyz - floor(gridcell.xyz * ( 1.0 / DOMAIN )) * DOMAIN;
vec3 gridcell_inc1 = step( gridcell, vec3( DOMAIN - 1.5, DOMAIN - 1.5, DOMAIN - 1.5 ) ) * ( gridcell + 1.0 );
// calculate the noise
vec4 P = vec4( gridcell.xy, gridcell_inc1.xy ) + OFFSET.xyxy;
P *= P;
P = P.xzxz * P.yyww;
vec3 lowz_mod = vec3( 1.0 / ( SOMELARGEFLOATS.xyz + gridcell.zzz * ZINC.xyz ) );
vec3 highz_mod = vec3( 1.0 / ( SOMELARGEFLOATS.xyz + gridcell_inc1.zzz * ZINC.xyz ) );
lowz_hash_0 = fract( P * lowz_mod.xxxx );
highz_hash_0 = fract( P * highz_mod.xxxx );
lowz_hash_1 = fract( P * lowz_mod.yyyy );
highz_hash_1 = fract( P * highz_mod.yyyy );
lowz_hash_2 = fract( P * lowz_mod.zzzz );
highz_hash_2 = fract( P * highz_mod.zzzz );
}
// convert a 0.0->1.0 sample to a -1.0->1.0 sample weighted towards the extremes
vec4 Cellular_weight_samples( vec4 samples )
{
samples = samples * 2.0 - 1.0;
//return (1.0 - samples * samples) * sign(samples); // square
return (samples * samples * samples) - sign(samples); // cubic (even more variance)
}
//
// Cellular Noise 3D
// Based off Stefan Gustavson's work at http://www.itn.liu.se/~stegu/GLSL-cellular
// http://briansharpe.files.wordpress.com/2011/12/cellularsample.jpg
//
// Speed up by using 2x2x2 search window instead of 3x3x3
// produces range of 0.0->1.0
//
float Cellular3D(vec3 P)
{
// establish our grid cell and unit position
vec3 Pi = floor(P);
vec3 Pf = P - Pi;
// calculate the hash.
// ( various hashing methods listed in order of speed )
vec4 hash_x0, hash_y0, hash_z0, hash_x1, hash_y1, hash_z1;
FAST32_hash_3D( Pi, hash_x0, hash_y0, hash_z0, hash_x1, hash_y1, hash_z1 );
// generate the 8 random points
// restrict the random point offset to eliminate artifacts
// we'll improve the variance of the noise by pushing the points to the extremes of the jitter window
const float JITTER_WINDOW = 0.23; // 0.166666666 will guarentee no artifacts. It is the intersection on x of graphs f(x)=( (0.5 + (0.5-x))^2 + 2*((0.5-x)^2) ) and f(x)=( 2 * (( 0.5 + x )^2) + x * x )
hash_x0 = Cellular_weight_samples( hash_x0 ) * JITTER_WINDOW + vec4(0.0, 1.0, 0.0, 1.0);
hash_y0 = Cellular_weight_samples( hash_y0 ) * JITTER_WINDOW + vec4(0.0, 0.0, 1.0, 1.0);
hash_x1 = Cellular_weight_samples( hash_x1 ) * JITTER_WINDOW + vec4(0.0, 1.0, 0.0, 1.0);
hash_y1 = Cellular_weight_samples( hash_y1 ) * JITTER_WINDOW + vec4(0.0, 0.0, 1.0, 1.0);
hash_z0 = Cellular_weight_samples( hash_z0 ) * JITTER_WINDOW + vec4(0.0, 0.0, 0.0, 0.0);
hash_z1 = Cellular_weight_samples( hash_z1 ) * JITTER_WINDOW + vec4(1.0, 1.0, 1.0, 1.0);
// return the closest squared distance
vec4 dx1 = Pf.xxxx - hash_x0;
vec4 dy1 = Pf.yyyy - hash_y0;
vec4 dz1 = Pf.zzzz - hash_z0;
vec4 dx2 = Pf.xxxx - hash_x1;
vec4 dy2 = Pf.yyyy - hash_y1;
vec4 dz2 = Pf.zzzz - hash_z1;
vec4 d1 = dx1 * dx1 + dy1 * dy1 + dz1 * dz1;
vec4 d2 = dx2 * dx2 + dy2 * dy2 + dz2 * dz2;
vec3 points[8];
points[0] = vec3(dx1.x,dy1.x,dz1.x);
points[1] = vec3(dx1.y,dy1.y,dz1.y);
points[2] = vec3(dx1.z,dy1.z,dz1.z);
points[3] = vec3(dx1.w,dy1.w,dz1.w);
points[4] = vec3(dx2.x,dy2.x,dz2.x);
points[5] = vec3(dx2.y,dy2.y,dz2.y);
points[6] = vec3(dx2.z,dy2.z,dz2.z);
points[7] = vec3(dx2.w,dy2.w,dz2.w);
float pdistance[8];
pdistance[0] = d1.x;
pdistance[1] = d1.y;
pdistance[2] = d1.z;
pdistance[3] = d1.w;
pdistance[4] = d2.x;
pdistance[5] = d2.y;
pdistance[6] = d2.z;
pdistance[7] = d2.w;
sort(points, pdistance);
vec3 minv = vec3(pdistance[0],pdistance[1],pdistance[2]);
float delta = (abs(minv.x - minv.y) + abs(minv.x - minv.z) + abs(minv.y - minv.z))/3.0;
float temp = ((minv.y / minv.x)/3.0) * -1.0 + 1.0;
float distance_to_middle = (minv.x + minv.y) / 2.0;
float c_to_mid = (distance_to_middle - minv.x);
c_to_mid /= distance_to_middle;
c_to_mid = c_to_mid * -1.0 + 1.0;
return smoothstep(0.93,1.0,c_to_mid);
return minv.x;
}
float CellFast(vec3 p, vec3 soffset, float frequency, float amplitude)
{
float h = Cellular3D((p + soffset) * frequency);
h *= amplitude;
return h;
}
vec2 rotate(vec2 pos, float angle){
float a = atan(pos.x/pos.y);
float l = sqrt(pos.x * pos.x + pos.y * pos.y);
a += angle;
pos.x = l*cos(a);
pos.y = l*sin(a);
return pos;
}
void main(void) {
float max_res = max(resolution.x,resolution.y);
vec2 uv = gl_FragCoord.xy /max_res;
vec2 soffset = offset * 0.7;
vec3 pos = vec3(uv + soffset,time/200.0);
pos.yz = rotate(pos.yz, 0.1);
float heigth = CellFast(pos, vec3(1.0,1.0,1.0), 8.0, 1.0);
gl_FragColor = vec4(heigth, heigth, heigth, 1.0);
}
When the pull-request is through you can happily fix this in a nicer way if your GPU supports WebGL 2.0
For me everything is solved.
Thank you alot for your support and development of the shadertoy extension for VSC.
It's a great tool!!
Nice, I'm happy you like it :)
If you have any suggestions on how to make the extension better don't hesitate to let us know.