Flicker artifacts in texture with tessellation - opengl

I encountered a problem when using tessellation.
Please refer to the link below
You may see some grey area after the rendering. If I rotate camera, they also changed (like a shinning effect.)
Could any one help me to figure out what is the reason? Thanks in advance.
Here is my code:
Vertex Shader:
in vec3 vertex_position;
in vec2 vertex_texcoord;
void main()
{
v_pos = vec3(vertex_position);
v_texcoord = vertex_texcoord;
}
TC shader:
layout(vertices = 3) out;
in vec3 v_pos[];
in vec2 v_texcoord[];
out vec3 tc_pos[];
out vec2 tc_texcoord[];
#define ID gl_InvocationID
#define TESS_LEVEL_INNER 3.0
#define TESS_LEVEL_OUTER 2.0
void main()
{
tc_pos[ID] = v_pos[ID];
tc_texcoord[ID] = v_texcoord[ID];
if (ID == 0)
{
gl_TessLevelInner[0] = TESS_LEVEL_INNER;
gl_TessLevelOuter[0] = TESS_LEVEL_OUTER;
gl_TessLevelOuter[1] = TESS_LEVEL_OUTER;
gl_TessLevelOuter[2] = TESS_LEVEL_OUTER;
}
}
Te shader:
layout(triangles, equal_spacing, cw) in;
in vec3 tc_pos[];
in vec2 tc_texcoord[];
out vec3 te_pos;
out vec2 te_texcoord;
void main()
{
vec3 p0 = gl_TessCoord.x * tc_pos[0];
vec3 p1 = gl_TessCoord.y * tc_pos[1];
vec3 p2 = gl_TessCoord.z * tc_pos[2];
vec2 t0 = gl_TessCoord.x * tc_texcoord[0];
vec2 t1 = gl_TessCoord.y * tc_texcoord[1];
vec2 t2 = gl_TessCoord.z * tc_texcoord[2];
te_pos = p0 + p1 + p2;
te_texcoord = t0 + t1 + t2;
vec4 p_t = vec4(te_pos-cam_pos.xyz,1.0) * cam_ori;
gl_Position = perspective_mat * p_t;
}
geometry shader:
layout (triangles) in;
layout (triangle_strip, max_vertices=3) out;
in vec3 te_pos[3];
in vec2 te_texcoord[3];
out vec2 g_texcoord;
void main()
{
gl_Position = gl_in[0].gl_Position;
g_texcoord = te_texcoord[0];
EmitVertex();
gl_Position = gl_in[1].gl_Position;
g_texcoord = te_texcoord[1];
EmitVertex();
gl_Position = gl_in[2].gl_Position;
g_texcoord = te_texcoord[2];
EmitVertex();
EndPrimitive();
}
Fragment:
in vec2 g_texcoord;
out vec4 frag_color;
void main()
{
frag_color = texture(tex_unit, g_texcoord);
}
Rendering Result

Related

Geometry shader odd issue

I want to use geometry shader to draw triangles of mesh, but encounter a really odd issue.
Result As follow: The wrong output.
The Right output.
The only diff between wrong and right in code, is when converting 3d position vector to 4d position vector. The right one did in vertex shader. The wrong one did in geometry shader.
Code as follow. Why this happend?
#version 330 core
layout (location = 0) in vec3 pos;
layout (location = 1) in vec3 normal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 project;
out vec3 normal_;
out vec4 pos_;
out vec3 pos_bug_;
out mat4 mvp_;
void main()
{
mvp_ = project * view * model;
normal_ = normal;
pos_ = vec4(pos, 1.0);
pos_bug_ = pos;
}
#version 330 core
layout (triangles) in;
layout (line_strip, max_vertices = 12) out;
uniform float length = 0.4f;
out vec4 color;
in mat4 mvp_[];
in vec3 normal_[];
in vec4 pos_[];
in vec3 pos_bug_[];
void GenNormal(int index) {
color = vec4(1, 1, 0, 1);
gl_Position = mvp_[0] * pos_[index];
EmitVertex();
gl_Position = mvp_[0] * pos_[index] + vec4(normal_[index], 0.0) * length;
EmitVertex();
EndPrimitive();
}
void GenTriangle(int index0, int index1) {
color = vec4(1, 1, 1, 1);
gl_Position = mvp_[0] * pos_[index0]; // Right
// gl_Position = mvp_[0] * vec4(pos_bug_[index0], 1.0); // Wrong
EmitVertex();
gl_Position = mvp_[0] * pos_[index1]; // Right
// gl_Position = mvp_[0] * vec4(pos_bug_[index1], 1.0); // Wrong
EmitVertex();
EndPrimitive();
}
void main()
{
GenNormal(0);
GenNormal(1);
GenNormal(2);
GenTriangle(0, 1);
GenTriangle(1, 2);
GenTriangle(0, 2);
}

How to flip Y-axis in GLSL shader before gl_FragColor = texture2D(*,*);

I need to flip my textures upside-down in shaders before applying perspective transformations. I modified vertTexCoord in vert.glsl, but I don't know where to use it in swap.glsl. The way to do it like
gl_FragColor = texture2D(texture, vertTexCoord );
does not work, because I also need the texture to be modified in perspective.
vert.glsl:
#define PROCESSING_COLOR_SHADER
uniform mat4 transform;
uniform mat4 texMatrix;
attribute vec4 vertex;
attribute vec4 color;
attribute vec2 texCoord;
varying vec4 vertColor;
varying vec4 vertTexCoord;
void main() {
gl_Position = transform * vertex;
vertColor = color;
vertTexCoord = texMatrix * vec4(texCoord, 1.0, 1.0);
}
swap.glsl:
#ifdef GL_ES
precision highp float;
#endif
// General parameters
uniform sampler2D from;
uniform sampler2D to;
uniform float progress;
uniform vec2 resolution;
uniform float reflection;
uniform float perspective;
uniform float depth;
varying vec4 vertColor;
varying vec4 vertTexCoord;
const vec4 black = vec4(0.0, 0.0, 0.0, 1.0);
const vec2 boundMin = vec2(0.0, 0.0);
const vec2 boundMax = vec2(1.0, 1.0);
bool inBounds (vec2 p) {
return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));
}
vec2 project (vec2 p) {
return p * vec2(1.0, -1.2) + vec2(0.0, -0.02);
}
vec4 bgColor (vec2 p, vec2 pfr, vec2 pto) {
vec4 c = black;
pfr = project(pfr);
if (inBounds(pfr)) {
c += mix(black, texture2D(from, pfr), reflection * mix(1.0, 0.0, pfr.y));
}
pto = project(pto);
if (inBounds(pto)) {
c += mix(black, texture2D(to, pto), reflection * mix(1.0, 0.0, pto.y));
}
return c;
}
void main() {
vec2 p = gl_FragCoord.xy / resolution.xy;
vec2 pfr, pto = vec2(-1.);
float size = mix(1.0, depth, progress);
float persp = perspective * progress;
pfr = (p + vec2(-0.0, -0.5)) * vec2(size/(1.0-perspective*progress), size/(1.0-size*persp*p.x)) + vec2(0.0, 0.5);
size = mix(1.0, depth, 1.-progress);
persp = perspective * (1.-progress);
pto = (p + vec2(-1.0, -0.5)) * vec2(size/(1.0-perspective*(1.0-progress)), size/(1.0-size*persp*(0.5-p.x))) + vec2(1.0, 0.5);
bool fromOver = progress < 0.5;
if (fromOver) {
if (inBounds(pfr)) {
gl_FragColor = texture2D(from, pfr);
}
else if (inBounds(pto)) {
gl_FragColor = texture2D(to, pto);
}
else {
gl_FragColor = bgColor(p, pfr, pto);
}
}
else {
if (inBounds(pto)) {
gl_FragColor = texture2D(to, pto);
}
else if (inBounds(pfr)) {
gl_FragColor = texture2D(from, pfr);
}
else {
gl_FragColor = bgColor(p, pfr, pto);
}
}
}
You sample the texture at
(u,v)
If you want to flip the Y-axis, just sample at
(u, 1.0f -v)
So your updated main will look like:
void main() {
gl_Position = transform * vertex;
vertColor = color;
newTCoord = texCoord;
newTCoord.y = 1.0 - newTCoord.y;
vertTexCoord = vec4(newTCoord, 1.0, 1.0);
}

GLSL geometry shader matrices

I have the following vertex shader:
#version 150 core
attribute vec4 vertex;
varying vec3 vert;
varying float zdepth;
uniform mat4 projMatrix;
uniform mat4 mvMatrix;
void main() {
vert = vertex.xyz;
zdepth = -(mvMatrix * vertex).z;
gl_Position = projMatrix * mvMatrix * vertex;
}
and geometry shader:
#version 150 core
uniform mat4 projMatrix;
uniform mat4 mvMatrix;
layout(lines_adjacency) in;
layout(triangle_strip, max_vertices = 4) out;
void main() {
vec4 p0 = gl_in[0].gl_Position;
vec4 p1 = gl_in[1].gl_Position;
vec4 p2 = gl_in[2].gl_Position;
vec4 p3 = gl_in[3].gl_Position;
vec4 v0 = normalize(p1-p0);
vec4 v1 = normalize(p2-p1);
vec4 v2 = normalize(p3-p2);
vec4 n11 = normalize(v1-v0);
vec4 n12 = -n11;
vec4 n21 = normalize(v2-v1);
vec4 n22 = -n21;
gl_Position = p1+n11*0.2;
EmitVertex();
gl_Position = p1+n12*0.2;
EmitVertex();
gl_Position = p2+n21*0.2;
EmitVertex();
gl_Position = p2+n22*0.2;
EmitVertex();
EndPrimitive();
}
The task of the geometry shader is to convert a line strip into triangle strip.
This is what I get for a line strip spiral:
I want to have the triangle strip normal always pointing in the viewer direction and get a even thickness. Of course it has to be less thick further away.
I need to rotate the n11,n12,n21,n22 so they are parallel to the view plane:
I would probably need to manipulate v0,v1,v2 with projMatrix and mvMatrix?
Thanks!
The projection matrix should not be applied to the vertex shader, I would do this all in view-space and then transform the final result into clip-space in the geometry shader. This avoids having to divide everything by W in the geometry shader.
You want to screen-align each of your triangles, which is very easy to do in a geometry shader (this is effectively billboarding). Pull the right/up vectors out of your ModelView matrix and then use those to calculate the offset in X and Y.
Geometry Shader Pseudo-code:
// Right = Column 0
vec3 right = vec3 (mvMatrix [0][0],
mvMatrix [1][0],
mvMatrix [2][0]);
// Up = Column 1
vec3 up = vec3 (mvMatrix [0][1],
mvMatrix [1][1],
mvMatrix [2][1]);
//
// Screen-align everything, and give a width of 0.4
//
gl_Position = projMatrix * ((p1+n11*0.2) - vec4 ((right + up) * 0.2, 0.0));
EmitVertex();
gl_Position = projMatrix * ((p1+n12*0.2) - vec4 ((right - up) * 0.2, 0.0));
EmitVertex();
gl_Position = projMatrix * ((p2+n21*0.2) + vec4 ((right - up) * 0.2, 0.0));
EmitVertex();
gl_Position = projMatrix * ((p2+n22*0.2) + vec4 ((right + up) * 0.2, 0.0));
EmitVertex ();
I don't get good results with this code. I guess it has something to do with the mvMatrix applied in the vertex shader and then using it again in right and up vectors.
I come up with a new code that works relatively well:
Vertex shader:
#version 150 core
attribute vec4 vertex;
varying vec3 vert;
uniform mat4 projMatrix;
uniform mat4 mvMatrix;
uniform vec3 camPos;
void main() {
vert = vertex.xyz;
gl_Position = vertex;
}
Geometry shader:
#version 150 core
uniform mat4 projMatrix;
uniform mat4 mvMatrix;
uniform vec3 camPos;
layout(lines_adjacency) in;
layout(triangle_strip, max_vertices = 6) out;
void main() {
vec4 p0 = gl_in[0].gl_Position;
vec4 p1 = gl_in[1].gl_Position;
vec4 p2 = gl_in[2].gl_Position;
vec4 p3 = gl_in[3].gl_Position;
vec3 forward1 = normalize(camPos - p1.xyz);
vec3 forward2 = normalize(camPos - p2.xyz);
vec3 v0 = normalize(vec3(p1-p0));
vec3 v1 = normalize(vec3(p2-p1));
vec3 v2 = normalize(vec3(p3-p2));
vec3 v0p1 = normalize(v0-(dot(v0,forward1))*forward1);
vec3 v1p1 = normalize(v1-(dot(v1,forward1))*forward1);
vec3 v1p2 = normalize(v1-(dot(v1,forward2))*forward2);
vec3 v2p2 = normalize(v2-(dot(v2,forward2))*forward2);
vec3 n0p1 = normalize(cross(v0p1,forward1));
vec3 n1p1 = normalize(cross(v1p1,forward1));
vec3 n1p2 = normalize(cross(v1p2,forward2));
vec3 n2p2 = normalize(cross(v2p2,forward2));
vec3 n11 = normalize(n0p1+n1p1);
vec3 n12 = -n11;
//if (n11[0]<0){
//n11 = n12;
//n12 = -n11;
// }
vec3 n21 = normalize(n1p2+n2p2);
vec3 n22 = -n21;
//if (n21[0]<0){
// n21 = n22;
//n22 = -n21;
// }
gl_Position = projMatrix * mvMatrix * vec4(p1.xyz+n11*0.2,1.0);
EmitVertex();
gl_Position = projMatrix * mvMatrix * vec4(p1.xyz+n12*0.2,1.0);
EmitVertex();
// EndPrimitive();
gl_Position = projMatrix * mvMatrix * vec4(p2.xyz+n21*0.2,1.0);
EmitVertex();
gl_Position = projMatrix * mvMatrix * vec4(p2.xyz+n22*0.2,1.0);
EmitVertex ();
EndPrimitive();
// gl_Position = projMatrix * mvMatrix * p1;
// EmitVertex();
// gl_Position = projMatrix * mvMatrix * p2;
// EmitVertex ();
// EndPrimitive();
}
I work without the matrixes applied. And I basiclly just included eye to point vector. So everything on screen seems turned to the eye.

GLSL Tessellation Displacement Mapping

in my recent project I am working with hardware side tessellation. The pipeline I want to implement should take a low poly mesh, tessellate it and apply a displacement map.
The Tessellation works fine and just as I expected it to look like. However, when I apply the displacement map in the tessellation evaluation shader I get an output which is somewhat random.
This is the output without displacement (I used the heightmap as a texture to verify whether my texCoords are accurate)
This is what I get when I enable my displacement (using the same texture for both coloring and displacement):
The shader code is as follows:
//VERTEX SHADER
#version 430
layout(location = 0) in vec4 vertex;
layout(location = 1) in vec4 normal;
layout(location = 2) in vec2 texCoord;
out vec3 vPosition;
out vec3 vNormal;
out vec2 vTexCoord;
void main() {
vPosition = vertex.xyz;
vNormal = normal.xyz;
vTexCoord = texCoord;
}
//TESS CONTROL
#version 430
layout(vertices = 3) out;
in vec3 vPosition[];
in vec3 vNormal[];
in vec2 vTexCoord[];
out vec3 tcPosition[];
out vec3 tcNormal[];
out vec2 tcTexCoord[];
uniform float innerTessLevel;
uniform float outerTessLevel;
void main(){
float inTess = innerTessLevel;
float outTess = outerTessLevel;
tcPosition[gl_InvocationID] = vPosition[gl_InvocationID];
tcNormal[gl_InvocationID] = vNormal[gl_InvocationID];
tcTexCoord[gl_InvocationID] = vTexCoord[gl_InvocationID];
if(gl_InvocationID == 0) {
gl_TessLevelInner[0] = inTess;
gl_TessLevelInner[1] = inTess;
gl_TessLevelOuter[0] = outTess;
gl_TessLevelOuter[1] = outTess;
gl_TessLevelOuter[2] = outTess;
gl_TessLevelOuter[3] = outTess;
}
}
//TESS EVAL
#version 430
layout(triangles, equal_spacing, ccw) in;
in vec3 tcPosition[];
in vec3 tcNormal[];
in vec2 tcTexCoord[];
out vec3 tePosition;
out vec2 teTexCoord;
uniform mat4 ModelViewProjection;
uniform mat4 ModelView;
uniform sampler2D texHeight;
void main(){
vec3 p0 = gl_TessCoord.x * tcPosition[0];
vec3 p1 = gl_TessCoord.y * tcPosition[1];
vec3 p2 = gl_TessCoord.z * tcPosition[2];
vec3 pos = p0 + p1 + p2;
vec3 n0 = gl_TessCoord.x * tcNormal[0];
vec3 n1 = gl_TessCoord.y * tcNormal[1];
vec3 n2 = gl_TessCoord.z * tcNormal[2];
vec3 normal = normalize(n0 + n1 + n2);
vec2 tc0 = gl_TessCoord.x * tcTexCoord[0];
vec2 tc1 = gl_TessCoord.y * tcTexCoord[1];
vec2 tc2 = gl_TessCoord.z * tcTexCoord[2];
teTexCoord = tc0 + tc1 + tc2;
float height = texture(texHeight, teTexCoord).x;
pos += normal * (height * 0.2f);
gl_Position = ModelViewProjection * vec4(pos, 1);
tePosition = vec3(ModelView * vec4(pos,1.0)).xyz;
}
//GEOMETRY
#version 430
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
uniform mat4 ModelView;
in vec3 tePosition[3];
in vec3 tePatchDistance[3];
in vec2 teTexCoord[3];
out vec3 gFacetNormal;
out vec2 gTexCoord;
void main() {
vec3 A = tePosition[2] - tePosition[0];
vec3 B = tePosition[1] - tePosition[0];
vec4 N = vec4( normalize(cross(A, B)) , 0.0);
gFacetNormal = N.xyz;
gTexCoord = teTexCoord[0];
gl_Position = gl_in[0].gl_Position; EmitVertex();
gTexCoord = teTexCoord[1];
gl_Position = gl_in[1].gl_Position; EmitVertex();
gTexCoord = teTexCoord[2];
gl_Position = gl_in[2].gl_Position; EmitVertex();
EndPrimitive();
}
//FRAGMENT
#version 430
layout(location = 0) out vec4 fragColor;
in vec3 gFacetNormal;
in vec2 gTexCoord;
uniform float lit;
uniform vec3 light;
uniform sampler2D texHeight;
void main() {
#ifndef ORANGE_PURPLE
vec3 color = gl_FrontFacing ? vec3(1.0,0.0,0.0) : vec3(0.0,0.0,1.0);
#else
vec3 color = gl_FrontFacing ? vec3(1.0,0.6,0.0) : vec3(0.6,0.0,1.0);
#endif
if (lit > 0.5) {
color = texture(texHeight, gTexCoord).xyz;
vec3 N = normalize(gFacetNormal);
vec3 L = light;
float df = abs(dot(N,L));
color = df * color;
fragColor = vec4(color,1.0);
}
else {
fragColor = vec4(color,1.0);
}
}
It would be nice if someone could help me on that one.
Thanks to #AndonM.Coleman I solved the matter
In fact: the output gFacetNormal is only defined for your first vertex in the geometry shader. Outputs have to be set after every EmitVertex (...) as-per the GLSL specification, or they will be undefined. Many implementations re-use the last value set, but you cannot rely on that behavior if you want this to work portably. You need to set gFacetNormal once before every EmitVertex. void EmitVertex () - "Emits the current values of output variables to the current output primitive. On return from this call, the values of output variables are undefined."
Stupid of me not to notice that, but here is the working code:
//VERTEX
#version 430
layout(location = 0) in vec4 vertex;
layout(location = 1) in vec4 normal;
layout(location = 2) in vec2 texCoord;
out vec3 vPosition;
out vec3 vNormal;
out vec2 vTexCoord;
void main() {
vPosition = vertex.xyz;
vNormal = normal.xyz;
vTexCoord = texCoord;
}
//TESSELLATION CONTROL
#version 430
layout(vertices = 3) out;
in vec3 vPosition[];
in vec3 vNormal[];
in vec2 vTexCoord[];
out vec3 tcPosition[];
out vec3 tcNormal[];
out vec2 tcTexCoord[];
uniform float innerTessLevel;
uniform float outerTessLevel;
void main(){
float inTess = innerTessLevel;
float outTess = outerTessLevel;
tcPosition[gl_InvocationID] = vPosition[gl_InvocationID];
tcNormal[gl_InvocationID] = vNormal[gl_InvocationID];
tcTexCoord[gl_InvocationID] = vTexCoord[gl_InvocationID];
if(gl_InvocationID == 0) {
gl_TessLevelInner[0] = inTess;
gl_TessLevelInner[1] = inTess;
gl_TessLevelOuter[0] = outTess;
gl_TessLevelOuter[1] = outTess;
gl_TessLevelOuter[2] = outTess;
gl_TessLevelOuter[3] = outTess;
}
}
//TESSELLATION EVALUATION
#version 430
layout(triangles, equal_spacing, ccw) in;
in vec3 tcPosition[];
in vec3 tcNormal[];
in vec2 tcTexCoord[];
out vec3 tePosition;
out vec2 teTexCoord;
out vec3 teNormal;
uniform mat4 ModelViewProjection;
uniform mat4 ModelView;
uniform sampler2D texHeight;
void main(){
vec3 p0 = gl_TessCoord.x * tcPosition[0];
vec3 p1 = gl_TessCoord.y * tcPosition[1];
vec3 p2 = gl_TessCoord.z * tcPosition[2];
vec3 pos = p0 + p1 + p2;
vec3 n0 = gl_TessCoord.x * tcNormal[0];
vec3 n1 = gl_TessCoord.y * tcNormal[1];
vec3 n2 = gl_TessCoord.z * tcNormal[2];
vec3 normal = normalize(n0 + n1 + n2);
vec2 tc0 = gl_TessCoord.x * tcTexCoord[0];
vec2 tc1 = gl_TessCoord.y * tcTexCoord[1];
vec2 tc2 = gl_TessCoord.z * tcTexCoord[2];
teTexCoord = tc0 + tc1 + tc2;
float height = texture(texHeight, teTexCoord).x;
pos += normal * (height * 0.5f);
gl_Position = ModelViewProjection * vec4(pos, 1);
teNormal = vec3(ModelView * vec4(normal,0.0)).xyz;
tePosition = vec3(ModelView * vec4(pos,1.0)).xyz;
}
//GEOMETRY
#version 430
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
uniform mat4 ModelView;
in vec3 tePosition[3];
in vec2 teTexCoord[3];
in vec3 teNormal[3];
out vec3 gFacetNormal;
out vec2 gTexCoord;
void main() {
gFacetNormal = teNormal[0];
gTexCoord = teTexCoord[0];
gl_Position = gl_in[0].gl_Position; EmitVertex();
gFacetNormal = teNormal[1];
gTexCoord = teTexCoord[1];
gl_Position = gl_in[1].gl_Position; EmitVertex();
gFacetNormal = teNormal[2];
gTexCoord = teTexCoord[2];
gl_Position = gl_in[2].gl_Position; EmitVertex();
EndPrimitive();
}
//FRAGMENT
#version 430
layout(location = 0) out vec4 fragColor;
in vec3 gFacetNormal;
in vec2 gTexCoord;
uniform float lit;
uniform vec3 light;
uniform sampler2D texHeight;
void main() {
#ifndef ORANGE_PURPLE
vec3 color = gl_FrontFacing ? vec3(1.0,0.0,0.0) : vec3(0.0,0.0,1.0);
#else
vec3 color = gl_FrontFacing ? vec3(1.0,0.6,0.0) : vec3(0.6,0.0,1.0);
#endif
if (lit > 0.5) {
color = texture(texHeight, gTexCoord).xyz;
vec3 N = normalize(gFacetNormal);
vec3 L = light;
float df = abs(dot(N,L));
color = df * color;
fragColor = vec4(color,1.0);
}
else {
fragColor = vec4(color,1.0);
}
}

Linking error at tessellation shaders in GLSL

I'm testing the triangle tessellation from the link http://prideout.net/blog/?p=48#shaders. All the shader are compiled correctly, but when I try to link the program using the command:
glLinkProgram(programID);
I got the following error:
Tessellation control info
(0): error C6029: No input primitive type
----------------------------------------
Tessellation evaluation info
(0): error c7005: No tessellation primitive mode specified
-----------------------------------------------------------
Geometry info
(0): error C6022: No input primitive type
(0): error C6029: No ouput primitive type
----------------------------------------
Not valid
It's so strange I declare output for TC Shader using command:
layout(vertices = 3) out;
And input layout for TE shader using command:
layout(triangles, equal_spacing, cw) in;
Why I still got this error?
I hope to see you answer about it.
I put my shaders in below:
Vertex shader:
#version 410 core
in vec4 Position;
out vec3 vPosition;
void main()
{
vPosition = Position.xyz;
}
TC shader:
#version 410 core
layout(vertices = 3) out;
in vec3 vPosition[];
out vec3 tcPosition[];
#define ID gl_InvocationID
void main()
{
float TessLevelInner = 3;
float TessLevelOuter = 2;
tcPosition[ID] = vPosition[ID];
if (ID == 0) {
gl_TessLevelInner[0] = TessLevelInner;
gl_TessLevelOuter[0] = TessLevelOuter;
gl_TessLevelOuter[1] = TessLevelOuter;
gl_TessLevelOuter[2] = TessLevelOuter;
}
}
TE Shader:
#version 410 core
//TessEval
layout(triangles, equal_spacing, cw) in;
in vec3 tcPosition[];
out vec3 tePosition;
out vec3 tePatchDistance;
uniform mat4 Projection;
uniform mat4 Modelview;
void main()
{
vec3 p0 = gl_TessCoord.x * tcPosition[0];
vec3 p1 = gl_TessCoord.y * tcPosition[1];
vec3 p2 = gl_TessCoord.z * tcPosition[2];
tePatchDistance = gl_TessCoord;
tePosition = normalize(p0 + p1 + p2);
gl_Position = Projection * Modelview * vec4(tePosition, 1);
}
Geometry shader:
#version 410 core
//geometry shader
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
in vec3 tePosition[3];
in vec3 tePatchDistance[3];
out vec3 gFacetNormal;
out vec3 gPatchDistance;
out vec3 gTriDistance;
uniform mat4 Modelview;
uniform mat3 NormalMatrix;
void main()
{
vec3 A = tePosition[2] - tePosition[0];
vec3 B = tePosition[1] - tePosition[0];
gFacetNormal = NormalMatrix * normalize(cross(A, B));
gPatchDistance = tePatchDistance[0];
gTriDistance = vec3(1, 0, 0);
gl_Position = gl_in[0].gl_Position; EmitVertex();
gPatchDistance = tePatchDistance[1];
gTriDistance = vec3(0, 1, 0);
gl_Position = gl_in[1].gl_Position; EmitVertex();
gPatchDistance = tePatchDistance[2];
gTriDistance = vec3(0, 0, 1);
gl_Position = gl_in[2].gl_Position; EmitVertex();
EndPrimitive();
}
Fragment Shader:
#version 410 core
//fragment shader
out vec4 FragColor;
in vec3 gFacetNormal;
in vec3 gTriDistance;
in vec3 gPatchDistance;
in float gPrimitive;
uniform vec3 LightPosition;
float amplify(float d, float scale, float offset)
{
d = scale * d + offset;
d = clamp(d, 0, 1);
d = 1 - exp2(-2*d*d);
return d;
}
void main()
{
vec3 AmbientMaterial = vec3(0.04f, 0.04f, 0.04f);
vec3 DiffuseMaterial = vec3(0, 0.75, 0.75);
vec3 LightPosition = vec3(0.25, 0.25, 1);
vec3 N = normalize(gFacetNormal);
vec3 L = LightPosition;
float df = abs(dot(N, L));
vec3 color = AmbientMaterial + df * DiffuseMaterial;
float d1 = min(min(gTriDistance.x, gTriDistance.y), gTriDistance.z);
float d2 = min(min(gPatchDistance.x, gPatchDistance.y), gPatchDistance.z);
color = amplify(d1, 40, -0.5) * amplify(d2, 60, -0.5) * color;
FragColor = vec4(color, 1.0);
}
FINALLY, this is the code I set up shader sources:
std::string filename = "shaders//terrain//terrain_TCShader.glsl"
FILE* fp = fopen(fileName.c_str(), "rt");
if (!fp)
return;
// Get all lines from a file
vector<string> sLines;
char sLine[255];
while (fgets(sLine, 255, fp))
sLines.push_back(sLine);
fclose(fp);
const char** sProgram = new const char*[sLines.size()];
for (int i = 0; i < sLines.size(); i++){
sProgram[i] = sLines[i].c_str();
}
//Also for GL_TESS_EVALUATION_SHADER, ..VERTEX, ...FRAGMENT
pShader[st] = glCreateShader(GL_TESS_CONTROL_SHADER);
glShaderSource(pShader[st], 1, (const GLchar**)sProgram, NULL);
glAttachShader(pProgram, pShader[st]);
glCompileShader(pShader[st]);
//==> I tried to check error here but it's ok, the compiler do not notify anything
After compile all the shader, I link the program
glLinkProgram(pProgram);
//And check error again:
glGetProgramiv(pProgram, GL_INFO_LOG_LENGTH,&infologLength);
if (infologLength > 0)
{
infoLog = (char *)malloc(infologLength);
glGetProgramInfoLog(pProgram, infologLength, &charsWritten, infoLog);
}
//I got the error here, as I described above.
I solved the problem. The error is in the code of loading shader.
glShaderSource(pShader[st], 1, (const GLchar**)sProgram, NULL);
I changed 1 to size of the char* array sProgram