我正在尝试使用四个着色器:顶点着色器(VS),曲面细分控制着色器(TCS),曲面细分评估着色器(TES)和片段着色器(FS)。
但是,当我尝试加载这些着色器时,我得到:
这是最令人费解的,我已经花了几个小时试图解决它。但是,我看不到" gl_Vertex"在我的代码中的任何地方,所以我真的卡住了。我甚至不知道哪个着色器是问题。
这是我目前加载着色器的代码(它看起来很多,但它实际上只是重复代码而略有变化):
public static int loadShaderPair(String vertexShaderLocation, String fragmentShaderLocation, String tesShaderLocation, String tesscontrolShaderLocation) {
int shaderProgram = glCreateProgram();
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
int tesscontrolShader = glCreateShader(GL40.GL_TESS_CONTROL_SHADER);
int tesShader = glCreateShader(GL40.GL_TESS_EVALUATION_SHADER);
StringBuilder vertexShaderSource = new StringBuilder();
StringBuilder fragmentShaderSource = new StringBuilder();
StringBuilder tesShaderSource = new StringBuilder();
StringBuilder tesscontrolShaderSource = new StringBuilder();
BufferedReader tesShaderFileReader = null;
try {
tesShaderFileReader = new BufferedReader(new FileReader(tesShaderLocation));
String line;
while ((line = tesShaderFileReader.readLine()) != null) {
tesShaderSource.append(line).append('\n');
}
} catch (IOException e) {
e.printStackTrace();
return -1;
} finally {
if (tesShaderFileReader != null) {
try {
tesShaderFileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedReader tesscontrolShaderFileReader = null;
try {
tesscontrolShaderFileReader = new BufferedReader(new FileReader(tesscontrolShaderLocation));
String line;
while ((line = tesscontrolShaderFileReader.readLine()) != null) {
tesscontrolShaderSource.append(line).append('\n');
}
} catch (IOException e) {
e.printStackTrace();
return -1;
} finally {
if (tesscontrolShaderFileReader != null) {
try {
tesscontrolShaderFileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedReader vertexShaderFileReader = null;
try {
vertexShaderFileReader = new BufferedReader(new FileReader(vertexShaderLocation));
String line;
while ((line = vertexShaderFileReader.readLine()) != null) {
vertexShaderSource.append(line).append('\n');
}
} catch (IOException e) {
e.printStackTrace();
return -1;
} finally {
if (vertexShaderFileReader != null) {
try {
vertexShaderFileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedReader fragmentShaderFileReader = null;
try {
fragmentShaderFileReader = new BufferedReader(new FileReader(fragmentShaderLocation));
String line;
while ((line = fragmentShaderFileReader.readLine()) != null) {
fragmentShaderSource.append(line).append('\n');
}
} catch (IOException e) {
e.printStackTrace();
return -1;
} finally {
if (fragmentShaderFileReader != null) {
try {
fragmentShaderFileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
glShaderSource(vertexShader, vertexShaderSource);
glCompileShader(vertexShader);
if (glGetShaderi(vertexShader, GL_COMPILE_STATUS) == GL_FALSE) {
System.err.println("Vertex shader wasn't able to be compiled correctly. Error log:");
System.err.println(glGetShaderInfoLog(vertexShader, 1024));
return -1;
}
glShaderSource(tesscontrolShader, tesscontrolShaderSource);
glCompileShader(tesscontrolShader);
if (glGetShaderi(tesscontrolShader, GL_COMPILE_STATUS) == GL_FALSE) {
System.err.println("tesscontrol shader wasn't able to be compiled correctly. Error log:");
System.err.println(GL11.glGetString(GL11.glGetError()));
System.err.println(glGetShaderInfoLog(tesscontrolShader, 1024));
}
glShaderSource(fragmentShader, fragmentShaderSource);
glCompileShader(fragmentShader);
if (glGetShaderi(fragmentShader, GL_COMPILE_STATUS) == GL_FALSE) {
System.err.println("Fragment shader wasn't able to be compiled correctly. Error log:");
System.err.println(GL11.glGetString(GL11.glGetError()));
System.err.println(glGetShaderInfoLog(fragmentShader, 1024));
}
glShaderSource(tesShader, tesShaderSource);
glCompileShader(tesShader);
if (glGetShaderi(vertexShader, GL_COMPILE_STATUS) == GL_FALSE) {
System.err.println("Tessellation shader wasn't able to be compiled correctly. Error log:");
System.err.println(glGetShaderInfoLog(tesShader, 1024));
return -1;
}
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, tesShader);
glAttachShader(shaderProgram, tesscontrolShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
if (glGetProgrami(shaderProgram, GL_LINK_STATUS) == GL_FALSE) {
System.err.println("Shader program wasn't linked correctly.");
System.err.println(GL11.glGetString(GL11.glGetError()));
System.err.println(glGetProgramInfoLog(shaderProgram, 1024));
System.exit(1);
return -1;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glDeleteShader(tesShader);
glDeleteShader(tesscontrolShader);
return shaderProgram;
}
以下是我的着色器: VS:
layout (location = 0) in vec3 Position_VS_in;
layout (location = 1) in vec2 TexCoord_VS_in;
layout (location = 2) in vec3 Normal_VS_in;
uniform mat4 gWorld;
out vec3 WorldPos_CS_in;
out vec2 TexCoord_CS_in;
out vec3 Normal_CS_in;
void main()
{
WorldPos_CS_in = (gWorld * vec4(Position_VS_in, 1.0)).xyz;
TexCoord_CS_in = TexCoord_VS_in;
Normal_CS_in = (gWorld * vec4(Normal_VS_in, 0.0)).xyz;
gl_Position = ftransform();
}
TCS:
// define the number of CPs in the output patch
layout (vertices = 3) out;
uniform vec3 gEyeWorldPos;
// attributes of the input CPs
in vec3 WorldPos_CS_in[];
in vec2 TexCoord_CS_in[];
in vec3 Normal_CS_in[];
// attributes of the output CPs
out vec3 WorldPos_ES_in[];
out vec2 TexCoord_ES_in[];
out vec3 Normal_ES_in[];
float GetTessLevel(float Distance0, float Distance1)
{
float AvgDistance = (Distance0 + Distance1) / 2.0;
if (AvgDistance <= 2.0) {
return 10.0;
}
else if (AvgDistance <= 5.0) {
return 7.0;
}
else {
return 3.0;
}
}
void main()
{
// Set the control points of the output patch
TexCoord_ES_in[gl_InvocationID] = TexCoord_CS_in[gl_InvocationID];
Normal_ES_in[gl_InvocationID] = Normal_CS_in[gl_InvocationID];
WorldPos_ES_in[gl_InvocationID] = WorldPos_CS_in[gl_InvocationID];
// Calculate the distance from the camera to the three control points
float EyeToVertexDistance0 = distance(gEyeWorldPos, WorldPos_ES_in[0]);
float EyeToVertexDistance1 = distance(gEyeWorldPos, WorldPos_ES_in[1]);
float EyeToVertexDistance2 = distance(gEyeWorldPos, WorldPos_ES_in[2]);
// Calculate the tessellation levels
gl_TessLevelOuter[0] = GetTessLevel(EyeToVertexDistance1, EyeToVertexDistance2);
gl_TessLevelOuter[1] = GetTessLevel(EyeToVertexDistance2, EyeToVertexDistance0);
gl_TessLevelOuter[2] = GetTessLevel(EyeToVertexDistance0, EyeToVertexDistance1);
gl_TessLevelInner[0] = gl_TessLevelOuter[2];
}
TES:
layout(triangles, equal_spacing, ccw) in;
uniform mat4 gVP;
uniform sampler2D gDisplacementMap;
uniform float gDispFactor;
in vec3 WorldPos_ES_in[];
in vec2 TexCoord_ES_in[];
in vec3 Normal_ES_in[];
out vec3 WorldPos_FS_in;
out vec2 TexCoord_FS_in;
out vec3 Normal_FS_in;
vec2 interpolate2D(vec2 v0, vec2 v1, vec2 v2)
{
return vec2(gl_TessCoord.x) * v0 + vec2(gl_TessCoord.y) * v1 + vec2(gl_TessCoord.z) * v2;
}
vec3 interpolate3D(vec3 v0, vec3 v1, vec3 v2)
{
return vec3(gl_TessCoord.x) * v0 + vec3(gl_TessCoord.y) * v1 + vec3(gl_TessCoord.z) * v2;
}
void main()
{
// Interpolate the attributes of the output vertex using the barycentric coordinates
TexCoord_FS_in = interpolate2D(TexCoord_ES_in[0], TexCoord_ES_in[1], TexCoord_ES_in[2]);
Normal_FS_in = interpolate3D(Normal_ES_in[0], Normal_ES_in[1], Normal_ES_in[2]);
Normal_FS_in = normalize(Normal_FS_in);
WorldPos_FS_in = interpolate3D(WorldPos_ES_in[0], WorldPos_ES_in[1], WorldPos_ES_in[2]);
// Displace the vertex along the normal
float Displacement = texture(gDisplacementMap, TexCoord_FS_in.xy).x;
WorldPos_FS_in += Normal_FS_in * Displacement * gDispFactor;
gl_Position = gVP * vec4(WorldPos_FS_in, 1.0);
}
FS
varying vec4 position_in_view_space;
uniform sampler2D color_texture;
void main()
{
float dist = distance(position_in_view_space,
vec4(0.0, 0.0, 0.0, 1.0));
if (dist < 1000.0)
{
gl_FragColor = gl_Color;
// color near origin
}
else
{
gl_FragColor = gl_Color;
//kill;
//discard;
//gl_FragColor = vec4(0.3, 0.3, 0.3, 1.0);
// color far from origin
}
}
如果由于任何原因它有帮助,我的电脑支持最多(包括)OpenGL 4.0。
由于我无法弄清楚我是如何使用我不使用的一行代码,我希望你们中的一个能够诊断出这个问题。
答案 0 :(得分:2)
嗯,错误信息很清楚,原因是:
layout (location = 0) in vec3 Position_VS_in;
[...]
gl_Position = ftransform();
ftransform
是一个遗留函数,它使用遗留的bultin顶点位置属性gl_Vertex
根据传统的bultin矩阵制服转换顶点。
GL规范还要求通用顶点属性0为旧内置gl_Vertex
设置别名,因此您的属性索引0被阻止,您不能为此指定其他属性。
现在完全不清楚为什么在这里使用ftransform
。好像你根本不想要那样。但我无法确定这一点。但它肯定不会那样工作。在我看来,你根本不应该使用那些被弃用的东西。
更新1
请注意,ftransform
原则上等同于gl_ModelViewProjectionMatrix * gl_Vertex
,gl_ModelViewProjectionMatrix
是内置制服,代表您为P * MV
设置的矩阵的乘积GL_PROJECTION
GL_MODELVIEW
使用已弃用的GL矩阵堆栈,gl_Vertex
是使用glVertex...
/ glVertexPointer
/ glVertexAttribPointer(0,...)
设置的内置顶点位置属性。两者都可以由用户定义的属性/制服替换。
ftransform
的唯一转折是,对于相同的输入,它也保证获得与使用固定功能管道的渲染完全相同的结果。这对于多次传递算法很有用,其中一些传递需要使用着色器渲染,而其他算法使用固定功能管道。需要这样的函数,因为如果在没有着色器的情况下渲染时着色器不使用与GL实现完全相同的公式,则可能存在轻微的数值差异。