Godot - Shader - 透明边缘

原理

  • 如果当前像素点为非透明,则输出像素点上的内容。
  • 如果当前像素点透明,且相邻像素不透明,则输出屏幕上的内容。

代码

背景图片先进行

  • 背景图
    • 缓存背景图到SCREEN_TEXTURE中
  • 执行抠边代码
shader_type canvas_item;
void fragment(){
    COLOR=textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0);
}

再执行抠边代码

shader_type canvas_item;
render_mode blend_mix;

uniform vec3 modulate_color = vec3(1.0, 1.0, 1.0);
uniform float modulate_alpha = 1.0;

uniform bool outline_diagonals = false; //true to extend the outline to diagonal pixels

void fragment(){
    vec4 col = texture(TEXTURE, UV); //original color
    
    if (col.a == 0.0) //might be part of where the outline should be
    {
        bool isOutline = false;
        
        if (texture(TEXTURE, UV + vec2(0.0, TEXTURE_PIXEL_SIZE.y)).a    != 0.0 ||
            texture(TEXTURE, UV + vec2(0.0, -TEXTURE_PIXEL_SIZE.y)).a   != 0.0 ||
            texture(TEXTURE, UV + vec2(TEXTURE_PIXEL_SIZE.x, 0.0)).a    != 0.0 ||
            texture(TEXTURE, UV + vec2(-TEXTURE_PIXEL_SIZE.x, 0.0)).a   != 0.0){
            isOutline = true;
        }
        if (outline_diagonals){
            if (texture(TEXTURE, UV + vec2(-TEXTURE_PIXEL_SIZE.x, TEXTURE_PIXEL_SIZE.y)).a    != 0.0 ||
                texture(TEXTURE, UV + vec2(-TEXTURE_PIXEL_SIZE.x, -TEXTURE_PIXEL_SIZE.y)).a   != 0.0 ||
                texture(TEXTURE, UV + vec2(TEXTURE_PIXEL_SIZE.x, TEXTURE_PIXEL_SIZE.y)).a     != 0.0 ||
                texture(TEXTURE, UV + vec2(TEXTURE_PIXEL_SIZE.x, -TEXTURE_PIXEL_SIZE.y)).a    != 0.0){
                isOutline = true;
            }
        }
        if (isOutline){
            col = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0).rgba; //set to background screen texture
        }   
    }else{ //part of the original image
        col = col*vec4(modulate_color, modulate_alpha) //modulate by a given amount if any
    }
    
    COLOR = col;
}

源码:

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容