微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

GLSL:如何将Alpha混合添加到带照明的片段着色器中

如何解决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通道。结果是这样的场景:

enter image description here

计划是,左球是云层。纹理包含一个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 举报,一经查实,本站将立刻删除。