Use GLSL-Unit to compile fragment shader - glsl

I want to use GLSL-Unit to just minify a fragment shader. But if I do run this command:
sunbox$ glsl-compiler --input=/Users/sunbox/Sites/bessa-app/xyz.fshader
I'm getting these error messages:
/usr/local/bin/glsl-compiler: line 1: syntax error near unexpected token `b'
/usr/local/bin/glsl-compiler: line 1: `var COMPILED=true,goog=goog||{};goog.global=this;goog.DEBUG=true;goog.LOCALE="en";goog.provide=function(b){if(!COMPILED){if(goog.isProvided_(b))throw Error('Namespace "'+b+'" already declared.');delete goog.implicitNamespaces_[b];for(var f=b;f=f.substring(0,f.lastIndexOf("."));){if(goog.getObjectByName(f))break;goog.implicitNamespaces_[f]=true}}goog.exportPath_(b)};'
So, how do I simply minify a fragment shader?

I finally got it working. :D
For everyone who's interested, you need this file:
http://code.google.com/p/glsl-unit/source/browse/bin/template_glsl_compiler.js
... and NodeJS installed. Then add a simple comment in your shader file:
//! FRAGMENT
precision lowp float;
uniform sampler2D image;
varying vec2 src_position;
void main() {
gl_FragColor = texture2D(image, src_position);
}
... and annoyingly you have to use the .glsl file extension! :(
Now you can run this command:
sunbox$ node /Volumes/template_glsl_compiler.js --input=/Volumes/test.glsl --variable_renaming=INTERNAL --output=/Volumes/test.fshader.min
And that's it. Compiled output will be:
//! VERTEX
//! FRAGMENT
precision lowp float;uniform sampler2D image;varying vec2 a;void main(){gl_FragColor=texture2D(image,a);}
Really nice! :)

Related

when do i need GL_EXT_nonuniform_qualifier?

I want to compile the following code into SPIR-V
#version 450 core
#define BATCH_ID (PushConstants.Indices.x >> 16)
#define MATERIAL_ID (PushConstants.Indices.x & 0xFFFF)
layout (push_constant) uniform constants {
ivec2 Indices;
} PushConstants;
layout (constant_id = 1) const int MATERIAL_SIZE = 32;
in Vertex_Fragment {
layout(location = 0) vec4 VertexColor;
layout(location = 1) vec2 TexCoord;
} inData;
struct ParameterFrequence_3 {
int ColorMap;
};
layout (set = 3, binding = 0, std140) uniform ParameterFrequence_3 {
ParameterFrequence_3[MATERIAL_SIZE] data;
} Frequence_3;
layout (location = 0) out vec4 out_Color;
layout (set = 2, binding = 0) uniform sampler2D[] Sampler2DResources;
void main(void) {
vec4 color = vec4(1.0);
color *= texture(Sampler2DResources[Frequence_3.data[MATERIAL_ID].ColorMap], inData.TexCoord);
color *= inData.VertexColor;
out_Color = color;
}
(The code is generated by a program I am developing which is why the code might look a little strange, but it should make the problem clear)
When trying to do so, I am told
error: 'variable index' : required extension not requested: GL_EXT_nonuniform_qualifier
(for the third last line where the texture lookup also happens)
After I followed a lot of discussion around how dynamically uniform is specified and that the shading language spec basically says the scope is specified by the API while neither OpenGL nor Vulkan really do so (maybe that changed), I am confused why i get that error.
Initially I wanted to use instanced vertex attributes for the indices, those however are not dynamically uniform which is what I thought the PushConstants would be.
So when PushConstants are constant during the draw call (which is the max scope for dynamically uniform requirement), how can the above shader end up in any dynamically non-uniform state?
Edit: Does it have to do with the fact that the buffer backing the storage for the "ColorMap" could be aliased by another buffer via which the content might be modified during the invocation? Or is there a way to tell the compiler this is a "restricted" storage so it knows it is constant?
Thanks
It is 3 am in the morning over here, I should just go to sleep.
Chances anyone end up having the same problem are small, but I'd still rather answer it myself than delete it:
I simply had to add a SpecializationConstant to set the size of the sampler2D array, now it works without requiring any extension.
Good night

What is the syntax for 'pixel_interlock_ordered' in GLSL?

I'm trying out the ARB_fragment_shader_interlock extension in OpenGL 4.5 and am failing to get the shader to compile when trying to use pixel_interlock_ordered.
#version 430
#extension GL_ARB_shading_language_420pack : require
#extension GL_ARB_shader_image_load_store : require
#extension GL_ARB_fragment_shader_interlock : require
layout(location = 0, rg8, pixel_interlock_ordered) uniform image2D image1;
void main()
{
beginInvocationInterlockARB();
ivec2 coords = ivec2(gl_FragCoord.xy);
vec4 pixel = imageLoad(image1, coords);
pixel.g = pixel.g + 0.01;
if (pixel.g > 0.5)
pixel.r = pixel.r + 0.01;
else
pixel.r = pixel.r + 0.02;
imageStore(image1, coords, pixel);
endInvocationInterlockARB();
}
The following shader fails compilation with:
0(6) : error C7600: no value specified for layout qualifier 'pixel_interlock_ordered'
Which is the same error you would get for any random name instead of pixel_interlock_ordered. I guess the syntax is different somehow, but the spec (https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_fragment_shader_interlock.txt) refer to it as a "layout qualifier".
Googling "pixel_interlock_ordered" comes up short with just links to the official specs, so I can't find an example. What is the correct syntax?
Layout qualifiers in GLSL are a bit weird. They usually apply to declarations, but some of them effectively apply to the shader as a whole. Such qualifiers are basically shader-specific options you set from within the shader.
The interlock qualifiers are those kinds of qualifiers. You're not saying that this variable will be accessed via interlocking, because that's not what interlocking means. It means that the execution of the interlock-bound code will have a certain property, relative to executing interlock-bound code on other invocations of the same shader. The qualifier specifies the details of the execution restriction.
Qualifiers that apply to the shader as a whole are grammatically specified as qualifiers on in or out (most such qualifiers use in, but a few use out):
layout(pixel_interlock_ordered) in;

QOpenGLShader - version directive must be first statement and may not be repeated

I'am building an OpenGL-application using Qt 5.11.2. When adding a tessellation shader the following error occurs:
QOpenGLShader::compile(Tessellation Control): 0(2) : error C0204: version directive must be first statement and may not be repeated
*** Problematic Tessellation Control shader source code ***
#define lowp
#define mediump
#define highp
#line 1
´╗┐#version 400
#line 1
layout (vertices = 4) out;
I'm working on Windows 10 with Geforce GTX 1050/PCIe/SSE2 GPU.
I've found similar reports, but none of the answers worked for me: unable to compile GLSL shaders on Qt 5.3 after Nvidia driver update
Serious rendering issues with OpenGL 4.1 and Qt 5
The shader looks like this:
#version 400
layout (vertices = 4) out;
uniform float animationFrame;
in vec3 v_vertex[];
out vec3 tc_vertex[];
void main()
{...}
To add the shader I use the following code:
addShader(QOpenGLShader::Vertex, "data/cube.vert", *m_program);
addShader(QOpenGLShader::Fragment, "data/cube.frag", *m_program);
addShader(QOpenGLShader::TessellationControl, "data/cube.tcs", *m_program);
addShader(QOpenGLShader::TessellationEvaluation, "data/cube.tes", *m_program);
addShader(QOpenGLShader::Geometry, "data/cube.geom", *m_program);
Obviously the first lines inserted by Qt produce the error. Any ideas how to fix this problem?
I have the same problem, my errors shows like this:
QOpenGLShader::compile(Fragment): 0(2) : error C0204: version directive must be first statement and may not be repeated
*** Problematic Fragment shader source code ***
#ifdef GL_KHR_blend_equation_advanced
#extension GL_ARB_fragment_coord_conventions : enable
#extension GL_KHR_blend_equation_advanced : enable
#endif
#define lowp
#define mediump
#define highp
#line 1
???#version 330 core
out vec4 FragColor;
void main(void)
{
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
***
as you can see, there are ??? in the messages, while you have ´╗┐
when I changed from "utf-8 with BOM" to "utf-8", it works~
I have the error like this:
???#version 330 core
I use visual code to change the file encoding from "utf-8 with BOM" to "utf-8". Then it works.
I guess the answer is "version directive must be first statement and may not be repeated"
So, put your version directive to the first line - before all defines and the same.
Just checked it - that is it.
When I put directive "#version 330 core" in the fourth line of code - the same error "version directive must be first statement and may not be repeated" occured;
So the right way is to put this directive to the first line as it should be:
1 #version 330 core
2 in highp vec3 vert;
3 in highp vec3 vertNormal;
Where 1,2,3 - line's numbers.

Fragment Shader IN variable causes nothing to appear

I'm trying to send a variable from my vertex shader to my fragment shader, but when I include a specific the in variable in an if statement, it causes nothing to show up. Removing the if statement causes everything to appear and work normally. What's weird is that if statement isn't actually doing anything and that no errors are being generated by the fragment shader.
I have several other variables I'm sending from my vertex shader to my fragment shader but this one specifically is the only one causing issues. I know type is being set correct because I'm using it for something else that's working correctly.
vertex shader
#version 150
in float type;
out int roofBool;
void main(void)
{
textureXY = texcoords;
roofBool = 0;
if(type == 2){
roofBool = 1;
}
}
fragment shader
#version 150
in int roofBool;
// The output. Always a color
out vec4 fragColor;
void main()
{
int a = 0;
if(roofBool == 1){ //removing this causes everything to work
a = 2;
}
}
int variables cannot be interpolated by the GL. You must declare both the output and the corresponding input with the flat qualifier`.
From the behavior you described, it seems like you are not properly checking the compile and link status of your shaders/programs, and don't seem to retrieve the compiler/linker info log. You would vert likely have gotten a useful error message if you did.

Invalid value GLSL?

After letting my opengl program run for a while and viewing the scene from different angles I am getting an OpenGL "invalid value" error in my shader program. This is literally my program:
Vertex
#version 420
in vec4 Position;
uniform mat4 modelViewProjection;
void main()
{
in vec4 Position;
uniform mat4 modelViewProjection;
}
Fragment
#version 420
out vec4 fragment;
void main()
{
fragment = vec4(1,0,0,1);
}
This error occurs right after the function call to tell OpenGL to use my shader program. What could the cause of this be? It happens regardless of the object I call it on. How can I get more information on what is going on? The error occurs almost randomly for a series of frames, but then works again after a while, fails again after a bit, ect.
If it helps, here is what my program linking looks like:
...
myShader = glCreateProgram();
CreateShader(myShader,GL_VERTEX_SHADER, "shaders/prog.vert");
CreateShader(myShader,GL_FRAGMENT_SHADER, "shaders/prog.frag");
glLinkProgram(myShader);
PrintProgramLog(myShader);
...
void CreateShader(int prog, const GLenum type, const char* file)
{
int shad = glCreateShader(type);
char* source = ReadText(file);
glShaderSource(shad,1,(const char**)&source,NULL);
free(source);
glCompileShader(shad);
PrintShaderLog(shad,file);
glAttachShader(prog,shad);
}
This is what I'm using to get the error:
void ErrCheck(const char* where)
{
int err = glGetError();
if (err) fprintf(stderr,"ERROR: %s [%s]\n",gluErrorString(err),where);
}
And here is what is being printed out at me:
ERROR: invalid value [drawThing]
It happens after I call to use the program:
glUseProgram(_knightShaders[0]);
ErrCheck("drawThing");
or glGetUniformLocation:
glGetUniformLocation(myShader, "modelViewProjection");
ErrCheck("drawThing2");
So I fixed the problem. What I had above wasn't the whole truth, what I actually had was
myShader[0] = glCreateProgram();
myShader was an array of 4 GLuint(s), each int being a different shader program (although at this point they were all copies of the shader program I posted above). The problem was fixed when I stopped using an array and instead used:
GLuint myShader0;
GLuint myShader1;
GLuint myShader2;
GLuint myShader3;
Why this fixed the problem makes no sense to me, it's also pretty annyoing because rather than being able to index the shader mode I want, such as:
int mode = ... (code the determine what shader to use here)
glUseProgram(myShader[mode]);
I have to instead use conditionals:
int mode = ... (code the determine what shader to use here)
if (mode == 0) glUseProgram(myShader0);
else if (mode == 1) glUseProgram(myShader1);
else if (mode == 2) glUseProgram(myShader2);
else glUseProgram(myShader3);
If anyone of you know why this fixes the problem, I would very much appreciate the knowledge!