I am trying to create a simple passthrough "Geometry Shader" but for some reason its not linking. Debug info says its compiling fine.I don't know what I am doing wrong in this one? It is not the drivers or OS as I have linked and used geometry shader before, and they worked fine.
Vertex Shader code:
#version 450
in vec3 position;
uniform mat4 MVP;
out vec4 color;
void main()
{
gl_Position = MVP * vec4(position, 1.0);
color = vec4(0.5, 0.5, 0.0, 1.0);
}
Fragment Shader code:
#version 450
in vec4 fColor;
out vec4 fcolor;
void main() {
fcolor = fColor;
}
Geometry Shader Code:
#version 450
layout(lines) in;
layout(triangle_strip, max_vertices = 4) out;
in vec4 color;
out vec4 fColor;
void main()
{
fColor = color;
for(int i = 0; i <= gl_in.length(); i++)
{
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();
}
Debug output:
In Compile Shader from file: ../Curve.vert compile result:: 1 Shader
compile and attach success: In Compile Shader from file:
../Curve.geom compile result:: 1 Shader compile and attach success:
In Compile Shader from file: ../Curve.frag compile result:: 1 Shader
compile and attach success: Linking.. , Program handle found: 1 GL
Renderer : GeForce GTX 1660 Ti/PCIe/SSE2 GL Vendor :
NVIDIA Corporation GL Version : 4.6.0 NVIDIA 461.40 GL
Version No. : 4.6 GLSL Version : 4.60 NVIDIA
--------------- Debug message (131216): Program/shader state info: GLSL program 1 failed to link Source: API Type: Other Severity: low
Curve shader program not linked Curve shader program not validated Use
unsuccessful, returning? m_linked status: false Program handle: 1
Curve shader program handle: 1
The Geometry Shader transforms Primitives and is executed for each primitive. Therefore, the input of the Geometry Shader is an array the size of the vertex number of the primitives. e.g.:
in vec4 color[];
You have to emit a vertex for each vertex of the output primitive.
Related
I have a GLSL program that works on some machines, but fails to link on on one particular machine. I suspect a driver bug, but hope that someone will recognize something I'm doing as being poorly supported, and suggest an alternative.
If I omit the geometry shader, the vertex and fragment shaders link successfully.
The error log after the link error says:
Vertex shader(s) failed to link, fragment shader(s) failed to link, geometry shader(s) failed to link.
ERROR: error(#275) Symbol 'gl_AtiVertexData' is defined with 2 different types between two stages
ERROR: error(#275) Symbol 'gl_AtiVertexData' is defined with 2 different types between two stages
ERROR: error(#275) Symbol 'gl_AtiVertexData' is defined with 2 different types between two stages
My code does not contain the symbol gl_AtiVertexData, and Google finds no hits for it.
The GL_RENDERER string is "ATI Mobility Radeon HD 4670", GL_VERSION is "3.3.11672 Compatibility Profile Context", and GL_SHADING_LANGUAGE_VERSION is 3.30.
I've trimmed down my shader programs as much as possible, so that they no longer pretend to do anything useful, but still reproduce the problem.
Vertex shader:
#version 330
in vec4 quesaVertex;
out VertexData {
vec4 interpolatedColor;
};
void main()
{
gl_Position = quesaVertex;
interpolatedColor = vec4(1.0);
}
Geometry shader:
#version 330
layout (triangles) in;
layout (triangle_strip, max_vertices=3) out;
in VertexData {
vec4 interpolatedColor;
} gs_in[];
out VertexData {
vec4 interpolatedColor;
} gs_out;
void main() {
gl_Position = gl_in[0].gl_Position;
gs_out.interpolatedColor = gs_in[0].interpolatedColor;
EmitVertex();
gl_Position = gl_in[1].gl_Position;
gs_out.interpolatedColor = gs_in[1].interpolatedColor;
EmitVertex();
gl_Position = gl_in[2].gl_Position;
gs_out.interpolatedColor = gs_in[2].interpolatedColor;
EmitVertex();
EndPrimitive();
}
Fragment shader:
#version 330
in VertexData {
vec4 interpolatedColor;
};
out vec4 fragColor;
void main()
{
fragColor = interpolatedColor;
}
Later information:
When I tried renaming the interface block VertexData to IBlock, then the error message talked about a symbol gl_AtiIBlock instead of gl_AtiVertexData, so that symbol name was a red herring.
If I don't use interface blocks, then the program links correctly. That's a bother, because I'll need to write the vertex or fragment shader differently depending on whether there is a geometry shader between the vertex and fragment shaders, but maybe that's what I need to do.
I am trying to pass the vertex positions as a simple out vec3 pos from the vertex shader to the fragment shader in order to color vertices based on their position. Here is my vertex shader code:
#version 330 core
in vec3 position;
out vec3 pos;
uniform mat4 u_model;
void main(){
pos = position;
gl_Position = u_model * vec4(position, 1.0f);
}
Fragment shader:
#version 330 core
out vec4 color;
in vec4 pos;
void main(){
color = vec4(pos.x, 0.0f, 0.0f, 1.0f);
}
Now this only works when I run the program with the Nsight Graphics Debugger in Visual Studio 2019.
When I execute normally (x64, Debug) it seems to fall back to a default shader, which renders everything white. The vertex and fragment shader posted above stop working.
The type of the vertex shader output has to match exactly the type of the corresponding input in the next shader stage (fragment shader in this case).
See interface matching rules between shader stages.
In your case the type of the vertex shader output is vec3:
out vec3 pos;
but the type of the fragment shader input is vec4:
in vec4 pos;
Change the type of the fragment shader input to vec3, to solve the issue.
I don't know why this code works with Nsight Graphics Debugger in Visual Studio 2019. The bug is that it should not do so.
I want my renderer to be able to use tesselation shaders, but when it comes to run, the debugger says
%s
Link info
---------
error: "v_color" not declared as an output from the previous stage
and I do not know what does it exactly mean.
v_color is the fragment shader in vec4 which comes from the vertex shader and vertex shader gets this value from the vbo like this:
#version 420 core
layout (location = 1) in vec4 a_color
out vec4 v_color;
void main(void)
{
gl_Position = //something;
v_color = a_color;
}
#version 420 core
out vec4 color;
in vec4 v_color;
void main(void)
{
color = v_color;
}
and vertex shader gets a_color from vertex attrib pointer.
Why it returns error?
Each shader stage pass the output to the input of the next stage. The vertex shader is followed by the tessellation control shader, which is followed by the tessellation evaluation shader and finally the fragment shader (if there is no geometry shader).
If you have a tessellation shader and you want to pass an attribute from the vertex sahder to the fragment shader, then you have to pass the attribute through all shader stages:
e.g.:
Vertex shader:
#version 420 core
layout (location = 1) in vec4 a_color
out vec4 v_color;
void main(void)
{
v_color = a_color;
// .....
}
Tessellation control shader:
#version 420 core
layout(vertices=3) out;
in vec4 v_color[];
out vec4 tc_color[];
void main()
{
tc_color[gl_InvocationID] = v_color[gl_InvocationID];
// .....
}
Tessellation evaluation shader:
#version 420 core
layout(triangles) in;
in vec4 tc_color[];
out vec4 te_color;
void main()
{
te_color = tc_color[0] * gl_TessCoord.x +
tc_color[1] * gl_TessCoord.y +
tc_color[2] * gl_TessCoord.z;
// .....
}
Fragment shader:
#version 420 core
in vec4 te_color;
out vec4 color;
void main(void)
{
color = te_color;
}
I am using a book called Opengl SuperBible 6th edition. I am using JOGL 2.5.1 API. Everytihing was working fine, until I created geometry shader (exercise on page 37). When I try to pass color vector from geometry shader to fragment shader, the Java virtual machine crashes. I have also implemented GLSL error check at shader creation and it shows nothing. I really want to know what is the catch here. here is my code from vertex shader to fragment shader. Funny thing is the program crashes only when i send color from geometry shader to fragment shader. If i set color manualy in fragment shader the program works.
VERTEX SHADER:
#version 430 core
layout (location = 0) in vec4 offset;
layout (location = 1) in vec4 color;
out vec4 vs_color;
void main(void){
const vec4 vertices[3] = vec4[3](vec4( 0.25, -0.25, 0.5, 1.0),
vec4(-0.25, -0.25, 0.5, 1.0),
vec4( 0.25, 0.25, 0.5, 1.0));
gl_Position = vertices[gl_VertexID] + offset;
vs_color = color;
}
TESSELATION CONTROL SHADER:
#version 430 core
layout (vertices = 3) out;
in vec4 vs_color[];
out vec4 tsc_color[];
void main(void){
if (gl_InvocationID == 0){
gl_TessLevelInner[0] = 5.0;
gl_TessLevelOuter[0] = 5.0;
gl_TessLevelOuter[1] = 5.0;
gl_TessLevelOuter[2] = 5.0;
}
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
tsc_color[0] = vs_color[0];
}
TESSELATION EVALUATION SHADER:
#version 430 core
layout (triangles, equal_spacing, cw) in;
in vec4 tsc_color[];
out vec4 tse_color[];
void main(void){
gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position +
gl_TessCoord.y * gl_in[1].gl_Position +
gl_TessCoord.z * gl_in[2].gl_Position);
tse_color[0] = tsc_color[0];
}
GEOMETRY SHADER:
#version 430 core
layout (triangles) in;
layout (points, max_vertices = 3) out;
in vec4 tse_color[];
out vec4 geo_color;
void main(void){
int i;
for (i = 0; i < gl_in.length(); i++)
{
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}
geo_color = tse_color[0];
}
FRAGMENT SHADER:
#version 430 core
in vec4 geo_color;
out vec4 color;
void main(void){
//color = vec4(0.0f, 0.8f, 1.0f, 1.0f); for manual setting
color = geo_color;
}
THE ERROR THAT OCCURES:
glLinkProgram(<int> 0x6)GLDebugEvent[ id 0x7d1
type Error
severity High: dangerous undefined behavior
source GLSL or extension compiler
msg glLinkProgram failed to link a GLSL program with the following program info log: 'Vertex shader(s) failed to link, tessellation control shader(s) failed to link, tessellation evaluation shader(s) failed to link, geometry shader(s) failed to link, fragment shader(s) failed to link.
Vertex link error: INVALID_OPERATION.
ERROR: error(#275) Symbol "tse_color" is defined with 2 different types between two stages
tessellation control link error: INVALID_OPERATION.
ERROR: error(#275) Symbol "tse_color" is defined with 2 different types between two stages
tessellation evaluation link error: INVALID_OPERATION.
ERROR: error(#275) Symbol "tse_color" is defined with 2 different types between two stages
geometry link error: INVALID_OPERATION.
ERROR: error(#275) Symbol "tse_color" is defined with 2 different types between two stages
fragment link error: INVALID_OPERATION.
ERROR: error(#275) Symbol "tse_color" is defined with 2 different types between two stages
'
when 1401907851402
source 4.4 (Core profile, arb, debug, ES2 compat, ES3 compat, FBO, hardware) - 4.4.12874 Core Profile/Debug Context 14.100.0.0 - hash 0x14e08f00]
Tessellation Evaluation Shaders only output 1 vertex. I do not know why you have declared out vec4 tse_color[];, but that is a mistake.
// out vec4 tse_color[]; // WRONG
out vec4 tse_color; // * Fixed
[...]
// tse_color[0] = tsc_color[0]; // WRONG
tse_color = tsc_color[0]; // * Fixed
Finally, you are only outputting color to a single vertex for every invocation of your control shader, when you should be outputting multiple. To pass your per-vertex color through the control shader, you need the following:
tsc_color [gl_InvocationID] = vs_color [gl_InvocationID];
Now, here is where things get strange... you are only referencing the first color in your patch for each evaluated vertex. I think what you actually want is an input/output variable qualified with patch storage. That will allow you to create exactly 1 instance of the variable shared across all invocations, sort of like a provoking vertex only for tessellation.
Some info about my graphic card:
GL_RENDERER: Intel(R) G41 Express Chipset
OpenGL_VERSION: 2.1.0 - Build 8.15.10.1986
GLSL_VERSION: 1.20 - Intel Build 8.15.10.1986
Vertex shader 1:
#version 110
attribute vec3 vertexPosition_modelspace;
varying vec3 normal;
varying vec3 vertex;
void light(inout vec3 ver, out vec3 nor);
void main()
{
gl_Position = vec4(vertexPosition_modelspace, 1.0);
light(vertex, normal);
}
Vertex shader 2:
#version 110
void light(inout vec3 ver, out vec3 nor)
{
ver = vec3(0.0,1.0,0.0);
//vec3 v = -ver; // wrong line
nor = vec3(0.0,0.0,1.0);
//float f = dot(ver, nor); // wrong line
}
Fragment shader:
#version 110
varying vec3 normal;
varying vec3 vertex;
void main()
{
gl_FragColor = vec4(vertex, 1.0);
}
These shaders works well if the two lines are commented in second vertex shader. However, once one of them is enabled, we get a error. The error occur in opengl function glDrawArrays.
It seems that variable of out/inout can not used as right value.
I have run the same program on Intel HD Graphics 3000 which opengl's version is 3.1 and GLSL's version is 1.4, and the program works well. Is this a bug of Intel's driver or just wrong used by me?
Because intel g41 is an extremely weak gpu.
The only way through it is to upgrade your gpu.