Issues with TexelFetch and "Scalar Swizzle" in GLSL - opengl

I have done some work with shaders before but I would consider myself relatively inexperienced with GLSL. I am trying to write a fluid solver that simulates smoke using a series of fragment shaders. Most of these involve taking discrete samples from the texture and then doing some operation onh them, so they all have similar compilation errors. Every pixel, and only each pixel, must be evaluated so I am using texelFetch as opposed to texture2D for my sampling. The following is an example of such a fragment shader:
uniform sampler2D velocity;
uniform sampler2D pressure;
uniform sampler2D solid;
uniform float numCellsX;
uniform float numCellsY;
void main(void) {
ivec2 pos = ivec2(gl_FragCoord.xy);
if (texelFetch(solid, pos.xy, 0).x > 0.0)
discard;
float c = texelFetch(pressure, pos.xy, 0).x;
float up = texelFetchOffset(pressure, pos.xy, 0, ivec2(0, 1)).x;
float down = texelFetchOffset(pressure, pos.xy, 0, ivec2(0, -1)).x;
float left = texelFetchOffset(pressure, pos.xy, 0, ivec2(-1, 0)).x;
float right = texelFetchOffset(pressure, pos.xy, 0, ivec2(1, 0)).x;
float upS = texelFetchOffset(solid, pos.xy, 0, ivec2(0, 1)).x;
float downS = texelFetchOffset(solid, pos.xy, 0, ivec2(0, -1)).x;
float leftS = texelFetchOffset(solid, pos.xy, 0, ivec2(-1, 0)).x;
float rightS = texelFetchOffset(solid, pos.xy, 0, ivec2(1, 0)).x;
if (upS > 0.0) up = c;
if (downS > 0.0) down = c;
if (leftS > 0.0) left = c;
if (rightS > 0.0) right = c;
gl_FragColor = texelFetch(velocity, pos.xy, 0) - vec2(0.5 * numCellsX * (right - left), 0.5 * numCellsY * (up - down));
}
And when I run this through glSlangValidator, I get the following errors:
ERROR: 0:14: 'texelFetch' : no matching overloaded function found
ERROR: 0:14: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:17: 'texelFetch' : no matching overloaded function found
ERROR: 0:17: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:18: 'texelFetchOffset' : no matching overloaded function found
ERROR: 0:18: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:19: 'texelFetchOffset' : no matching overloaded function found
ERROR: 0:19: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:20: 'texelFetchOffset' : no matching overloaded function found
ERROR: 0:20: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:21: 'texelFetchOffset' : no matching overloaded function found
ERROR: 0:21: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:23: 'texelFetchOffset' : no matching overloaded function found
ERROR: 0:23: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:24: 'texelFetchOffset' : no matching overloaded function found
ERROR: 0:24: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:25: 'texelFetchOffset' : no matching overloaded function found
ERROR: 0:25: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:26: 'texelFetchOffset' : no matching overloaded function found
ERROR: 0:26: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:33: 'texelFetch' : no matching overloaded function found
ERROR: 0:33: 'assign' : cannot convert from 'temp 2-component vector of float'
to 'fragColor mediump 4-component vector of float FragColor'
ERROR: 23 compilation errors. No code generated.
There is pretty much an error on almost every line and I have found very little information online about these things. Per the GLSL reference manual:
gvec4 texelFetch(gsampler2D sampler, ivec2 P, int lod);
I don't quite understand why it isn't accepting my texelFetch calls. I also don't know what scalar swizzle is (can't find this anywhere online) or why its an issue.

not supported with this profile: es
Perhaps you should compile it with the desktop version of GLSL, instead of GLSL ES (presumably 2.0). You should always use a #version declaration in your GLSL shaders.
Also, if you're using texelFetch, why are you still writing to deprecated outputs like gl_FragColor?
However:
cannot convert from 'temp 2-component vector of float'
That's true regardless of the version for this line:
texelFetch(velocity, pos.xy, 0) - vec2(0.5 * numCellsX * (right - left), 0.5 * numCellsY * (up - down))
texelFetch returns a 4-element vector. You cannot subtract a 2 element vector from a 4-element vector.

Related

Something is wrong with my GLSL shader for Minecraft

While i was making my shader for minecraft ive run into a problem
0(13) : error C0000: syntax error, unexpected ';', expecting '{' at token ";"
0(14) : error C0000: syntax error, unexpected ';', expecting '{' at token ";"
0(18) : error C1503: undefined variable "gbufferModelView"
0(18) : error C1503: undefined variable "gbufferProjection"
[16:24:00] [Client thread/ERROR] [net.optifine.shaders.SMCLog]: [Shaders] Error linking program: 20 (gbuffers_terrain
[16:24:00] [Client thread/INFO] [net.optifine.shaders.SMCLog]: [Shaders] Info log: gbuffers_terrain
Vertex info
0(13) : error C0000: syntax error, unexpected ';', expecting '{' at token ";"
0(14) : error C0000: syntax error, unexpected ';', expecting '{' at token ";"
0(18) : error C1503: undefined variable "gbufferModelView"
0(18) : error C1503: undefined variable "gbufferProjection"
(0) : error C2003: incompatible options for link
[16:24:00] [Client thread/ERROR] [net.optifine.shaders.SMCLog]: [Shaders] OpenGL error: 1282 (Invalid operation), program: gbuffers_terrain, at: useProgram
[16:24:00] [Client thread/INFO] [minecraft/GuiNewChat]: [CHAT] �eOpenGL Error�f: 1282 (Invalid operation)
[16:24:00] [Client thread/ERROR] [net.optifine.shaders.SMCLog]: [Shaders] [Shaders] Error: Invalid program "gbuffers_terrain"
[16:24:00] [Client thread/INFO] [minecraft/GuiNewChat]: [CHAT] [Shaders] Error: Invalid program "gbuffers_terrain"
[16:24:00] [Client thread/INFO] [net.optifine.shaders.SMCLog]: [Shaders] Shader info log: /shaders/gbuffers_block.fsh
0(13) : warning C7533: global variable gl_FragData is deprecated after version 120
Fragment info
#version 460
#define lightBlocks
#define intensity 1 //[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0]
#define BlocksOfLight 20 //[1 5 10 15 20 25 30 40 50 60 70 80 90 100 120 140 150 170 190 200]
layout(location = 0) in vec3 p;
int Num = 0;
//uniform sampler2D texture;
out vec4 color;
out vec4 texcoord;
out vec4 lmcoord;
uniform gbufferModelView;
uniform gbufferProjection;
void main() {
gl_Position = gbufferModelView * gbufferProjection * p;
color = vec4(1.0f,0.5f,1.0f,1.0f);
}
#version 120
uniform sampler2D texture;
uniform int worldTime;
float fac = 1.0f-abs(sin((worldTime/24000.0f)*3.14159f+3.14159f/4.0f));
in vec4 color;
in vec4 texcoord;
in vec4 lmcoord;
vec4 tex = texture2D(texture, texcoord.st);
vec3 colD = vec3(1.0f);
vec3 colN = vec3(0.0f,0.0f,0.5f);
vec3 light = (colD+(fac)*colN)/(fac+1.0f);
void main()
{
gl_FragColor = vec4(tex.r*color.r*(lmcoord.s+light.r),tex.g*color.g*(lmcoord.s+light.g),tex.b*color.b*(lmcoord.s+light.b),tex.a);
}
1st - Vertex 2nd - Fragment
Once, ive got wrong rendering of all blocks (all blocks in one single chunk somehow...), but then gbufferModelView and gbufferProjection stopped their work at all. Im on Minecraft 1.12.2

Recursion in GLSL prohibited?

I ran into this error when trying to write the following recursive call. I have seen a lot of demos of implementations of recursive Ray tracing in GLSL so I assumed that GLSL supported recursion.
Is this not the case?
OpenGL is returning a compile time error message:
Error: Function trace(vec3, vec3, vec3, int) has static recursion
This is my function definition:
vec3 trace(vec3 origin, vec3 direction, vec3 illum, int order)
{
float dist;
int s_index = getSphereIntersect(origin, direction, dist);
//if light hit
float light_dist = 200;
for(int k = 0; k < L_COUNT;k++)
if(s_intersects(l_center[k], l_radius[k],
origin, direction,
light_dist))
if(light_dist < dist )
return l_color[k]; //light is pure color
if (s_index != -1)
{
illum = s_color[s_index];
for(int j = 0; j < L_COUNT; j++)
{
float ambient = 0.68;
float diffuse = 0.5;
vec3 poi = view + (direction * dist);
vec3 li_disp = normalize( poi - l_center[j]);
vec3 poi_norm = s_normal(s_center[s_index], s_radius[s_index], poi);
float shade= dot(li_disp, normalize(poi_norm));
if(shade < 0) shade = 0;
illum = illum*l_color[j]*ambient + diffuse * shade;
//test shadow ray onto objects, if shadow then 0
if(order > 0)
illum = trace(poi+.0001*poi_norm, poi_norm, illum, order-1);
}
}
else
illum = vec3(0,0,0);
return illum;
}
I assumed that GLSL supported recursion
No. GLSL doesn't support or better said allow recursive function calls.
GLSL does not. The GLSL memory model does not allow for recursive function calls. This allows GLSL to execute on hardware that simply doesn't allow for recursion. It allows GLSL to function when there is no ability to write arbitrarily to memory, which is true of most shader hardware (though it is becoming less true with time).
So, no recursion in GLSL. Of any kind.
– OpenGL Wiki – Core Language (GLSL)
and
Recursion is not allowed, not even statically. Static recursion is present if the static function-call graph of
a program contains cycles. This includes all potential function calls through variables declared as
subroutine uniform (described below). It is a compile-time or link-time error if a single compilation unit
(shader) contains either static recursion or the potential for recursion through subroutine variables.
– GLSL 4.5 Specification, Page 115

DirectX HLSL shader implicit truncation of vector type error

Hi I'm getting an error in one my pixel shaders, implicit truncation of vector type.
Here is the code causing the error:
float3 colour = 0;
float3 ppColour = SceneTexture.Sample(PointSample, ppIn.UV);
float4 col = SceneTexture.Sample(PointSample, ppIn.UV);
float intensity = 0.0f;
float r = SceneTexture.Sample(PointSample, ppIn.UV).r;
float g = SceneTexture.Sample(PointSample, ppIn.UV).g;
float b = SceneTexture.Sample(PointSample, ppIn.UV).b;
float a = SceneTexture.Sample(PointSample, ppIn.UV).a;
intensity = r + g + b + a;
if (intensity > 5.0f)
{
for (int count = 0; count < 13; count++)
{
colour += SceneTexture.Sample(TrilinearSampler, ppIn.UV + PixelKernel[count] * BlurStrength) * BlurWeights[count];
}
return float4(colour, 1.0f);
}
return float4(ppColour, 1.0f);
If I comment out intensity = r + g + b + a; then the project compiles. Can anyone see what I'm doing wrong, thanks.
The reason you get this error is, that you are mulitplying/adding up float3's and float4's. You should 'cast' float3 to float4 with float4(float3, 1.0f) or float4.xyz (which makes it float3)
Inferring some of the 'extra' stuff that is required to actually compile the shader (uniforms, inputs, and making the code into an actual function), I get the following output when trying to compile it:
test.ps(16,9): warning X3206: implicit truncation of vector type
test.ps(29,11): warning X3206: implicit truncation of vector type
test.ps(29,11): error X4014: cannot have gradient operations inside loops with divergent flow control
As you can see, the truncations messages are just warnings, not errors, unless you are using /WX to compile. The issue with these warnings, is that you are assigning the result of a texture sample to a float3, but the return is actually a float4. You can either select the appropriate components with a swizzle, or, change the variable type. For example:
float4 ppColour = SceneTexture.Sample(PointSample, ppIn.UV);
The reason for the actual error, is that you cannot do sample interpolation in dynamic loops, or loops inside conditional statements. In this case, your loop is inside the if (intensity > 5.0) conditional. You have two options, either you can remove the conditional, or, you can use SampleLevel instead of Sample:
colour += SceneTexture.SampleLevel(TrilinearSampler, ppIn.UV + PixelKernel[count] * BlurStrength, 0) * BlurWeights[count];
Note: using SampleLevel like this will always sample the top mip-level.

HLSL error X3082

I have the following pixel shader function in HLSL:
float GammaCorrectA(float3 color, float alpha) {
float a = 1 - sqrt(1 - alpha);
float b = sqrt(alpha);
float t = (color.x + color.y + color.z) / 3;
return a * (1 - t) + b^t;
}
This is being called thusly:
float screen = GammaCorrectA(strokeColor, alpha);
strokeColor and alpha are both floats.
This is resulting in the following error on the 'return' line:
error X3082: int or unsigned int type required.
I am compiling with Shader Model 4 Level 9_3, with optimizations disabled and debugging information enabled.
I can't seem to find this error documented on MSDN, or anywhere.
Broadly, can anybody point me to where this error is documented? I would like to understand what's going on here. More specifically, can anybody spot my error?
Instead of b^t use the HLSL pow function:
return a * (1 - t) + pow(b, t);

How to make this code work on Mesa3d?

This GLSL code compile and run warningless in ATI's OpenGL:
void main()
{
vec4 tmp = gl_ModelViewMatrix * gl_Vertex;
tmp.xyz = tmp.xyz / (1 - tmp.w);
tmp.w = 1;
gl_Position = gl_ProjectionMatrix * tmp;
gl_FrontColor = gl_Color;
}
Why does it fail with mesa? How to decrypt that error message and make it Mesa's implementation compliant?
Compilation log:
0:1(88): error: Could not implicitly convert operands to arithmetic operator
0:1(89): error: Operands to arithmetic operators must be numeric
0:1(97): error: type mismatch
Try changing your 1s to 1.0s.