【发布时间】:2020-11-09 16:04:11
【问题描述】:
我设法使用以下片段着色器使用 OpenGL(OpenTK,因为我使用 C# 和 Winforms)创建了一个光线充足的场景:
#version 420 core
in vec3 FragPos;
in vec3 Normal;
in vec2 texCoord;
out vec4 FragColor;
uniform sampler2D texture0;
uniform sampler2D texture1;
struct Material {
sampler2D diffuse;
sampler2D specular;
float shininess;
};
struct Light {
vec3 position;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
uniform Material material;
uniform Light light;
uniform vec3 viewPos;
void main()
{
// Ambient
vec3 ambient = light.ambient * vec3(texture(material.diffuse, texCoord));
// Diffuse
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(vec3(light.position - FragPos));
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, texCoord));
// Specular
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
vec3 specular = light.specular * spec * vec3(texture(material.specular, texCoord));
vec3 result = ambient + diffuse + specular;
FragColor = vec4(result, 1.0);
}
不幸的是,这个解决方案似乎没有考虑纹理的 Alpha 通道。这导致了这样的场景:
计划是,左边的球体是云层。纹理包含一个 Alpha 通道,这应该会产生一个带有可见云的透明球体。不要混淆:当一切恢复正常时,云球将移回地球上方。
在实现环境光、漫反射光和镜面光之前,我使用了以下片段着色器:
#version 420 core
in vec2 texCoord;
out vec4 FragColor;
uniform sampler2D texture0;
uniform sampler2D texture1;
void main()
{
vec4 outputColor = mix(texture(texture0, texCoord), texture(texture1, texCoord), 0.2);
if(outputColor.a < 0.1)
discard;
FragColor = outputColor;
}
此着色器考虑了 Alpha 通道,它确实按预期工作。重要的是,云和地球是独立的球体对象。旧着色器中的 texture1 根本没有使用。所以唯一相关的纹理是纹理0。
所以“目标”应该是将 alpha 通道添加到新的着色器(带有照明的着色器)中。
抱歉,如果您觉得这个问题很愚蠢。我是 OpenGL 的新手,还在学习。 提前致谢!
【问题讨论】:
标签: c# winforms opengl glsl opentk