如何解决GLSL:如何将Alpha混合添加到带照明的片段着色器中
我设法使用以下片段着色器使用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,0.2);
if(outputColor.a < 0.1)
discard;
FragColor = outputColor;
}
此着色器考虑了alpha通道,并且确实按预期工作。重要的是,云和地球是分开的球体。完全不使用旧着色器中的texture1。因此,唯一相关的纹理是texture0。
因此,“目标”应该是将alpha通道添加到新的着色器(带有照明的着色器中)。
很抱歉,这个问题对您来说很愚蠢。我是OpenGL的新手,仍然在学习。 预先感谢!
解决方法
您必须mix
取决于云层的Alpha通道的纹理。假设“ texture1”是云层:
vec4 groundColor = texture(texture0,texCoord);
vec4 cloudColor = texture(texture1,texCoord);
vec4 outputColor = vec4(mix(grundColor.rgb,cloudColor.rgb,cloudColor.a),1.0);
FragColor = outputColor;
,
我自己找到了解决方案。这里是固定的着色器:
#version 420 core
in vec3 FragPos;
in vec3 Normal;
in vec2 texCoord;
out vec4 FragColor;
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
vec4 ambient = vec4(light.ambient,1.0) * texture(material.diffuse,texCoord);
// Diffuse
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(vec3(light.position - FragPos));
float diff = max(dot(norm,lightDir),0.0);
vec4 diffuse = vec4(light.diffuse,1.0) * diff * 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);
vec4 specular = vec4(light.specular,1.0) * spec * texture(material.specular,texCoord);
vec4 result = ambient + diffuse + specular;
if(result.a < 0.1)
discard;
FragColor = result;
}
如果您有更好的主意,我很乐意尝试:)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。