OpenGL几何着色器传递纹理坐标
Posted
技术标签:
【中文标题】OpenGL几何着色器传递纹理坐标【英文标题】:OpenGL geometry shader passing texture coordinates 【发布时间】:2019-11-05 13:23:26 【问题描述】:我在通过几何着色器正确传递纹理坐标时遇到问题。当我的片段着色器结束时,我的纹理坐标变得一团糟。 这是顶点着色器:
#version 330 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 texCoord;
out VS_OUT
vec3 v_Normal;
vec2 v_TexCoord;
vec3 v_FragPos;
vs_out;
uniform mat4 u_Model;
uniform mat4 u_View;
uniform mat4 u_Projection;
void main()
gl_Position = u_Projection * u_View * u_Model * vec4(position, 1.0);
vs_out.v_Normal = normalize(mat3(transpose(inverse(u_Model))) * normal);
vs_out.v_TexCoord = texCoord;
vs_out.v_FragPos = vec3(u_Model * vec4(position, 1.0));
几何着色器:
#version 330 core
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
in VS_OUT
vec3 v_Normal;
vec2 v_TexCoord;
vec3 v_FragPos;
gs_in[];
out GS_OUT
vec3 v_Normal;
vec2 v_TexCoord;
vec3 v_FragPos;
gs_out;
uniform float u_Time;
vec4 explode(vec4 position, vec3 normal)
float magnitude = 2.0;
vec3 direction = normal * ((sin(u_Time) + 1.0) / 2.0) * magnitude;
return position + vec4(direction, 0.0);
vec3 GetNormal()
vec3 a = vec3(gl_in[0].gl_Position) - vec3(gl_in[1].gl_Position);
vec3 b = vec3(gl_in[2].gl_Position) - vec3(gl_in[1].gl_Position);
return normalize(cross(a, b));
void main()
vec3 normal = GetNormal();
gl_Position = explode(gl_in[0].gl_Position, normal);
gs_out.v_Normal = gs_in[0].v_Normal;
gs_out.v_TexCoord = gs_in[0].v_TexCoord;
gs_out.v_FragPos = vec3(explode(vec4(gs_in[0].v_FragPos, 1.0), normal));
EmitVertex();
gl_Position = explode(gl_in[1].gl_Position, normal);
gs_out.v_Normal = gs_in[1].v_Normal;
gs_out.v_TexCoord = gs_in[1].v_TexCoord;
gs_out.v_FragPos = vec3(explode(vec4(gs_in[1].v_FragPos, 1.0), normal));
EmitVertex();
gl_Position = explode(gl_in[2].gl_Position, normal);
gs_out.v_Normal = gs_in[1].v_Normal;
gs_out.v_TexCoord = gs_in[1].v_TexCoord;
gs_out.v_FragPos = vec3(explode(vec4(gs_in[1].v_FragPos, 1.0), normal));
EmitVertex();
EndPrimitive();
片段着色器:
#version 330 core
struct Material
sampler2D ambient;
sampler2D diffuse;
sampler2D specular;
sampler2D emissive;
float shininess;
;
struct DirectionalLight
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
;
struct PointLight
vec3 position;
vec3 ambient;
vec3 diffuse;
vec3 specular;
float constant;
float linear;
float quadratic;
;
struct SpotLight
vec3 position;
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
float constant;
float linear;
float quadratic;
float cutOff;
float outerCutOff;
;
out vec4 color;
in GS_OUT
vec3 v_Normal;
vec2 v_TexCoord;
vec3 v_FragPos;
fs_in;
#define NR_POINT_LIGHTS 1
uniform Material u_Material;
uniform DirectionalLight u_DirectionalLight;
uniform PointLight u_PointLights[NR_POINT_LIGHTS];
uniform SpotLight u_SpotLight;
uniform vec3 u_ViewPos;
uniform samplerCube skybox;
vec3 calculateDirectionalLight(DirectionalLight light, Material material, vec2 texCoord, vec3 normal, vec3 viewDirection);
vec3 calculatePointLight(PointLight light, Material material, vec2 texCoord, vec3 normal, vec3 fragPos, vec3 viewDirection);
vec3 calculateSpotLight(SpotLight light, Material material, vec2 texCoord, vec3 normal, vec3 fragPos, vec3 viewDirection);
void main()
vec3 lightColor = vec3(0.0);
vec3 normal = normalize(fs_in.v_Normal);
vec3 viewDirection = normalize(u_ViewPos - fs_in.v_FragPos);
lightColor += calculateDirectionalLight(u_DirectionalLight, u_Material, fs_in.v_TexCoord, normal, viewDirection);
for (int i = 0; i < NR_POINT_LIGHTS; i++)
lightColor += calculatePointLight(u_PointLights[i], u_Material, fs_in.v_TexCoord, normal, fs_in.v_FragPos, viewDirection);
lightColor += calculateSpotLight(u_SpotLight, u_Material, fs_in.v_TexCoord, normal, fs_in.v_FragPos, viewDirection);
lightColor += texture(u_Material.ambient, fs_in.v_TexCoord).rgb * texture(skybox, reflect(-viewDirection, normal)).rgb;
color = vec4(lightColor, 1.0);
vec3 calculateDirectionalLight(DirectionalLight light, Material material, vec2 texCoord, vec3 normal, vec3 viewDirection)
vec3 ambient = light.ambient * vec3(texture(material.diffuse, texCoord));
vec3 lightDirection = normalize(-light.direction);
vec3 diffuse = light.diffuse * vec3(texture(material.diffuse, texCoord)) * max(dot(lightDirection, normal), 0.0);
vec3 reflectDirection = reflect(-lightDirection, normal);
vec3 specular = light.specular * vec3(texture(material.specular, texCoord)) * pow(max(dot(viewDirection, reflectDirection), 0.0), material.shininess);
// vec3 emmisive = texture(material.emmisive, texCoord).rgb;
return vec3(ambient + diffuse + specular);
vec3 calculatePointLight(PointLight light, Material material, vec2 texCoord, vec3 normal, vec3 fragPos, vec3 viewDirection)
vec3 ambient = light.ambient * vec3(texture(material.diffuse, texCoord));
vec3 lightDirection = normalize(light.position - fragPos);
vec3 diffuse = light.diffuse * vec3(texture(material.diffuse, texCoord)) * max(dot(lightDirection, normal), 0.0);
vec3 reflectDirection = reflect(-lightDirection, normal);
vec3 specular = light.specular * vec3(texture(material.specular, texCoord)) * pow(max(dot(viewDirection, reflectDirection), 0.0), material.shininess);
float distance = length(light.position - fragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance +
light.quadratic * (distance * distance));
ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;
// vec3 emmisive = texture(material.emmisive, texCoord).rgb;
return vec3(ambient + diffuse + specular);
vec3 calculateSpotLight(SpotLight light, Material material, vec2 texCoord, vec3 normal, vec3 fragPos, vec3 viewDirection)
vec3 lightDirection = normalize(light.position - fragPos);
float theta = dot(lightDirection, normalize(-light.direction));
float epsilon = light.cutOff - light.outerCutOff;
float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
vec3 ambient = light.ambient * vec3(texture(material.diffuse, texCoord));
vec3 diffuse = light.diffuse * vec3(texture(material.diffuse, texCoord)) * max(dot(lightDirection, normal), 0.0);
vec3 reflectDirection = reflect(-lightDirection, normal);
vec3 specular = light.specular * vec3(texture(material.specular, texCoord)) * pow(max(dot(viewDirection, reflectDirection), 0.0), material.shininess);
// vec3 emmisive = texture(material.emmisive, texCoord).rgb;
float distance = length(light.position - fragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance +
light.quadratic * (distance * distance));
ambient *= intensity * attenuation;
diffuse *= intensity * attenuation;
specular *= intensity * attenuation;
return vec3(ambient + diffuse + specular);
在我添加几何着色器并通过它传递插值顶点属性之前:
通过几何着色器传递不同的属性后:
任何想法我错过了什么?
【问题讨论】:
【参考方案1】:gl_Position = explode(gl_in[2].gl_Position, normal);
gs_out.v_Normal = gs_in[1].v_Normal;
gs_out.v_TexCoord = gs_in[1].v_TexCoord;
看起来像是复制粘贴错误,您可能打算在此处放置 2 而不是 1。
【讨论】:
是的,你是对的,解决了这个问题,花了我一个小时挠头......谢谢:)以上是关于OpenGL几何着色器传递纹理坐标的主要内容,如果未能解决你的问题,请参考以下文章