Does GLSL remove unused variables? - opengl

For example, my vertex shader:
...
attribute vec2 uTexCoord;
uniform float a, b, c;
out vec2 texCoord;
...
void main() {
...
texCoord = uTexCoord * a * b * c;
...
}
And my fragment shader:
...
in vec2 texCoord;
uniform vec4 color;
layout(location = 0) out vec4 fragColor;
...
void main() {
...
fragColor = color;
}
Which variables will be considered unnecessary and will be deleted?
Or better to use #ifdef to exclude such code portions?

Related

In the visualization of fft using glsl, rewrite from glsl 120 to 150

I am trying to make fft texture using GLSL.
However, although it was created in the current version 150, thought that I wanted to rewrite it to version 120, it does not work well,
I will paste the source code below, so please let me know if you know what is the cause. I am delighted.
glsl150.vert
#version 150
uniform mat4 modelViewProjectionMatrix;
in vec4 position;
in vec2 texcoord;
out vec2 vTexCoord;
void main(){
vTexCoord = texcoord;
gl_Position = modelViewProjectionMatrix * position;
}
glsl150.frag
#version 150
uniform sampler2DRect tex;
uniform float rawFft[256];
in vec2 vTexCoord;
out vec4 outputColor;
void main(){
if (vTexCoord.y < 1.0) {
int i = int(vTexCoord.x);
outputColor.r = rawFft[i];
} else {
vec2 st = vTexCoord;
st.y -= 1.0;
outputColor.r = texture(tex, st).r;
}
outputColor.a = 1.0;
}
GLSL150 FFT Texture:
glsl120.vert
#version 120
#extension GL_ARB_texture_rectangle : enable
void main(){
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_Vertex;
}
glsl120.frag
#version 120
#extension GL_ARB_texture_rectangle : enable
uniform sampler2D tex;
uniform float rawFft[256];
vec4 outputColor;
void main(){
if (gl_TexCoord[0].y < 1.0) {
int i = int(gl_TexCoord[0].x);
outputColor.r = rawFft[i];
} else {
vec2 st = gl_TexCoord[0].st;
st.y -= 1.0;
outputColor.r = texture2D(tex, st).r;
}
outputColor.a = 1.0;
gl_FragColor = outputColor;
}
GLSL120 FFT Texture:
I want to make the result which is out in 150 work even with 120.
What is wrong?

GLSL shader issue

I created two shaders for my program to render simple objects.
Vertex shader source:
#version 400 core
layout (location = 1) in vec4 i_vertexCoords;
layout (location = 2) in vec3 i_textureCoords;
layout (location = 3) in vec3 i_normalCoords;
layout (location = 4) in int i_material;
uniform mat4 u_transform;
out VertexData {
vec3 textureCoords;
vec3 normalCoords;
int material;
} vs_out;
void main() {
vs_out.textureCoords = i_textureCoords;
vs_out.material = i_material;
gl_Position = u_transform * i_vertexCoords;
vs_out.normalCoords = gl_Position.xyz;
}
Fragment shader source:
#version 400 core
struct MaterialStruct {
int ambientTexutre;
int diffuseTexture;
int specularTexture;
int bumpTexture;
vec4 ambientColor;
vec4 diffuseColor;
vec4 specularColor;
float specularComponent;
float alpha;
int illuminationModel;
};
in VertexData {
vec3 textureCoords;
vec3 normalCoords;
int material;
} vs_out;
layout (std140) uniform MaterialsBlock {
MaterialStruct materials[8];
} u_materials;
uniform sampler2D u_samplers[16];
out vec4 fs_color;
void main() {
MaterialStruct m = u_materials.materials[vs_out.material];
fs_color = vec4(m.diffuseColor.rgb, m.diffuseColor.a * m.alpha);
}
Program created with this two shaders renders picture 2
When I change main() function contents to next:
void main() {
MaterialStruct m = u_materials.materials[vs_out.material];
fs_color = vec4(m.diffuseColor.rgb * (vs_out.normalCoords.z + 0.5), m.diffuseColor.a * m.alpha);
}
It renders picture 1, but materials still exists (if I'm trying to select material from u_materials.materials manually it works). Shader thinks what vs_out.material is constant and equals 0, but it isn't. Data is not changed (excluding transformation matrix)
Could someone explain the solution of this problem?
The GLSL 4.5 spec states in section 4.3.4 "Input Variables":
Fragment shader inputs that are signed or unsigned integers, integer vectors, or any double-precision
floating-point type must be qualified with the interpolation qualifier flat.
You can't use interpolation with those types, and actually, your code shouldn't compile on a strict implementation.

GLSL - Uniform error

I wrote shaders in #version 150. I have problem with uniforms. If I use any of light uniforms (vec4) my scene disappears.
Extraction of setting uniforms:
typedef struct { float x, y, z, w; } vec4;
//...
class MyClass {
GLuint _id;
vec4 light_diffuse;
};
//...
void MyClass::setUniforms {
//...
GLint location = glGetUniformLocation(_id, "in_light_diffuse");
//...
glUseProgram(_id);
//...
glUniform4fv(location, 1, (const GLfloat *)&light_diffuse);
//...
}
THIS WORKS:
#version 150
in vec4 in_vertex;
in vec3 in_normal;
in vec4 in_color;
uniform mat4 in_mvp_matrix;
uniform vec4 in_light_position;
uniform vec4 in_light_ambient;
uniform vec4 in_light_diffuse;
uniform vec4 in_light_specular;
out vec4 v_color;
void main() {
//vec4 a = in_light_position + in_light_ambient + in_light_diffuse + in_light_specular;
v_color = in_color;
gl_Position = in_mvp_matrix * in_vertex;
}
THIS DOESN'T WORK:
#version 150
in vec4 in_vertex;
in vec3 in_normal;
in vec4 in_color;
uniform mat4 in_mvp_matrix;
uniform vec4 in_light_position;
uniform vec4 in_light_ambient;
uniform vec4 in_light_diffuse;
uniform vec4 in_light_specular;
out vec4 v_color;
void main() {
vec4 a = in_light_position + in_light_ambient + in_light_diffuse + in_light_specular;
v_color = in_color;
gl_Position = in_mvp_matrix * in_vertex;
}
In first case I can see colorful objects, but in the second everything disappears. I don't even use these uniforms for calculation out_flag_color and result is empty screen.
It's simple. If I use one of them (no matter for what) it's empty.
Anybody help?
Solved. I was setting vec4 to uniform mat4 location.

GLSL : Considering not used variables

I wonder whether I should consider not used variables in glsl.
In next situation(which is just sample code for description).
If "trigger" is true, "position" and "normal" are not used in the fragment shader.
Then, are "position" and "normal" abandoned? or calculated by rasterizer?
Vertex shader :
layout(location = 0) in vec3 vertice;
layout(location = 1) in vec2 uv;
layout(location = 2) in vec3 normal;
out VertexData{
out vec3 position;
out vec2 uv;
out vec3 normal;
flat out bool trigger;
} VertexOut;
void main(){
gl_Position = vertice;
VertexOut.uv = uv;
if(uv.x > 0){
VertexOut.trigger = true;
else{
VertexOut.trigger = false;
VertexOut.position = vertice;
VertexOut.normal = normal;
}
}
Fragment shdaer :
in VertexData{
in vec3 position;
in vec2 uv;
in vec3 normal;
flat in bool trigger;
}VertexIn;
out vec4 color;
uniform sampler2D tex;
void main(){
if(VertexIn.trigger){
color = texture2D(tex, VertexIn.uv);
}
else{
vec4 result = texture2D(tex, VertexIn.uv);
/*
Lighting with position and normal...
*/
color = result;
}
}
Depends on hardware. On newer hardware smart compiler can avoid interpolating/fetching this values. Older hardware don't have this operations controllable by fragment shader, so it would be done anyway (interpolated from undefined value - which is still undefined).
Conditional operation isn't free though, especially if your fragment branches are highly divergent.

simple pass-through geometry shader with normal and color

I've written a very simple pass-through geometry shader. My input primitive is points and output primitive is also points. I also want to forward the color and normal from vertex shader to fragment shader through geometry shader. The shaders are compiled and linked flawlessly but the final color is very weird. I think there is something wrong with this forwarding. Can anyone point out the problem? Here are my shaders:
Vertex shader:
#version 330 compatibility
struct vData
{
vec3 normal;
vec4 color;
};
out vData vertex;
void main()
{
vertex.normal = gl_NormalMatrix * gl_Normal;
vertex.color = gl_Color;
gl_Position = ftransform();
}
Geometry shader:
#version 330
layout (points) in;
layout (points) out;
layout (max_vertices = 1) out;
struct vData
{
vec3 normal;
vec4 color;
};
in vData vertices[];
out vData frag;
void main()
{
int i;
for(i = 0;i < gl_in.length();i++)
{
frag.normal = vertices[i].normal;
frag.color = vertices[i].color;
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();
}
Fragment shader:
#version 330
struct vData
{
vec3 normal;
vec4 color;
};
in vData frag;
void main()
{
gl_FragColor = frag.color;
}
I figured this out! the in/out variables must have same name i.e. vertices[] in geometry shader should be vertex[]. That's it!
My refined and working code goes as follows:
Vertex shader:
#version 330 compatibility
out vData
{
vec3 normal;
vec4 color;
}vertex;
void main()
{
vertex.normal = normalize(gl_NormalMatrix * gl_Normal);
vertex.color = gl_Color;
gl_Position = ftransform();
}
Geometry shader:
#version 330
layout (points) in;
layout (points) out;
layout (max_vertices = 1) out;
in vData
{
vec3 normal;
vec4 color;
}vertices[];
out fData
{
vec3 normal;
vec4 color;
}frag;
void main()
{
int i;
for(i = 0;i < gl_in.length();i++)// gl_in.length() = 1 though!
{
frag.normal = vertices[i].normal;
frag.color = vertices[i].color;
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();
}
Fragment shader:
#version 330 compatibility
in fData
{
vec3 normal;
vec4 color;
};
void main()
{
gl_FragColor = frag.color;
}
Happy coding!