找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 243|回复: 2

[教程] 【变换组件】边缘渐变

[复制链接]
发表于 2026-4-24 15:04:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 Maz马 于 2026-4-24 15:06 编辑

用于美化fixed,viewport类容器效果的transform

                               
登录/注册后可看大图


变换组件
    鼠标视差
    3D 倾斜
    边缘渐变

最开始是希望能够传一张mask纹理图来自动遮罩的
可以不规则遮罩也不用写死逻辑

尝试失败之后选择用3D倾斜的思路,用shader直接作用在组件和子组件上

控制像素透明度,兼容rp的alpha预乘
但是写死了逻辑只能控制四边
[RenPy] 纯文本查看 复制代码
init python:
    renpy.register_shader("FixedMask",
        variables="""
            uniform sampler2D tex0;
            uniform float u_FMask_s;        // 
            uniform float u_FMask_f;        // 
            uniform float u_FMask_w;        // 
            varying vec2 v_tex_coord;
        """,
        fragment_300="""
            vec4 color = texture2D(tex0, v_tex_coord);
            float x = v_tex_coord.x;
            float y = v_tex_coord.y;
            float alpha = 1.0;
            float t;
            
            // 将 f 转换为实际渐变范围 (最大到中心点 0.5)
            float f_actual = u_FMask_f * 0.5;
            
            // 根据方向计算 alpha
            if (u_FMask_s == 1.0) {  // 仅顶部
                if (y < f_actual) {
                    t = y / f_actual;
                    alpha = smoothstep(0.0, 1.0, pow(t, u_FMask_w));
                }
            }
            else if (u_FMask_s == 2.0) {  // 仅底部
                if (y > 1.0 - f_actual) {
                    t = (1.0 - y) / f_actual;
                    alpha = smoothstep(0.0, 1.0, pow(t, u_FMask_w));
                }
            }
            else if (u_FMask_s == 3.0) {  // 仅左侧
                if (x < f_actual) {
                    t = x / f_actual;
                    alpha = smoothstep(0.0, 1.0, pow(t, u_FMask_w));
                }
            }
            else if (u_FMask_s == 4.0) {  // 仅右侧
                if (x > 1.0 - f_actual) {
                    t = (1.0 - x) / f_actual;
                    alpha = smoothstep(0.0, 1.0, pow(t, u_FMask_w));
                }
            }
            else if (u_FMask_s == 5.0) {  // 上下
                if (y < f_actual) {
                    t = y / f_actual;
                    alpha = min(alpha, smoothstep(0.0, 1.0, pow(t, u_FMask_w)));
                }
                if (y > 1.0 - f_actual) {
                    t = (1.0 - y) / f_actual;
                    alpha = min(alpha, smoothstep(0.0, 1.0, pow(t, u_FMask_w)));
                }
            }
            else if (u_FMask_s == 6.0) {  // 左右
                if (x < f_actual) {
                    t = x / f_actual;
                    alpha = min(alpha, smoothstep(0.0, 1.0, pow(t, u_FMask_w)));
                }
                if (x > 1.0 - f_actual) {
                    t = (1.0 - x) / f_actual;
                    alpha = min(alpha, smoothstep(0.0, 1.0, pow(t, u_FMask_w)));
                }
            }
            else if (u_FMask_s == 7.0) {  // 四边
                if (y < f_actual) {
                    t = y / f_actual;
                    alpha = min(alpha, smoothstep(0.0, 1.0, pow(t, u_FMask_w)));
                }
                if (y > 1.0 - f_actual) {
                    t = (1.0 - y) / f_actual;
                    alpha = min(alpha, smoothstep(0.0, 1.0, pow(t, u_FMask_w)));
                }
                if (x < f_actual) {
                    t = x / f_actual;
                    alpha = min(alpha, smoothstep(0.0, 1.0, pow(t, u_FMask_w)));
                }
                if (x > 1.0 - f_actual) {
                    t = (1.0 - x) / f_actual;
                    alpha = min(alpha, smoothstep(0.0, 1.0, pow(t, u_FMask_w)));
                }
            }
            
            // 预乘 alpha
            color.rgb *= alpha;
            color.a = alpha;
            
            gl_FragColor = color;
        """)

transform MDX_fmask(s=5.0,f=0.3,w=2.0):
    mesh True
    shader "FixedMask"
    u_FMask_s s      # side 1=上, 2=下, 3=左, 4=右, 5=上下, 6=左右, 7=四边
    u_FMask_f f      # fade 渐变范围 0.0~1.0
    u_FMask_w w      # warp 曲线陡峭度 =1线性, >1陡峭

#测试

screen abc():
    fixed:
        align(0.5,0.5)
        xysize(445,900)
        at MDX_fmask
        frame:
            vbox:
                text _("{size=68}画廊{/size}"):
                    outlines [ (1, "#f00", 0, 0 ) ]
                textbutton "text" action NullAction()
                viewport:
                    vbox:
                        for i in range(10):
                            text "1"


#点击头像 查看我写的更多屎
粉身碎骨浑不怕,要留答辩在人间





发表于 2026-4-25 21:27:59 | 显示全部楼层
根据马老师的设计思路,改了一个代码简化版本的:
[RenPy] 纯文本查看 复制代码
init python:
    # 边缘虚化:按左、右、上、下四个方向的距离,边缘逐渐透明。
    renpy.register_shader("CursedOctopus.edge_virtualization",
        variables="""
            uniform sampler2D tex0;
            uniform float u_edge_left;
            uniform float u_edge_right;
            uniform float u_edge_top;
            uniform float u_edge_bottom;
            uniform float u_edge_softness;
            attribute vec2 a_tex_coord;
            varying vec2 v_tex_coord;
        """,
        vertex_300="""
            v_tex_coord = a_tex_coord;
        """,
        fragment_300="""
            vec2 uv = v_tex_coord.xy;
            vec4 color = texture2D(tex0, uv);

            float left = clamp(u_edge_left, 0.0, 0.5);
            float right = clamp(u_edge_right, 0.0, 0.5);
            float top = clamp(u_edge_top, 0.0, 0.5);
            float bottom = clamp(u_edge_bottom, 0.0, 0.5);

            float alpha = 1.0;
            float left_alpha =  left > 0.0 ? smoothstep(0.0, left, uv.x) : 1.0;
            float right_alpha =  right > 0.0 ? smoothstep(0.0, right, 1.0 - uv.x) : 1.0;
            float top_alpha =  top > 0.0 ? smoothstep(0.0, top, uv.y) : 1.0;
            float bottom_alpha =  bottom > 0.0 ? smoothstep(0.0, bottom, 1.0 - uv.y) : 1.0;
            alpha *= pow(left_alpha * right_alpha * top_alpha * bottom_alpha, u_edge_softness);

            gl_FragColor = color * alpha;
        """
    )


transform edge_virtualization(left=0.0, right=0.0, top=0.0, bottom=0.0, softness=1.0):
    mesh True
    shader "CursedOctopus.edge_virtualization"
    u_edge_left left
    u_edge_right right
    u_edge_top top
    u_edge_bottom bottom
    u_edge_softness softness
回复 支持 1 抱歉 0

使用道具 举报

 楼主| 发表于 2026-5-2 20:28:21 | 显示全部楼层
被诅咒的章鱼 发表于 2026-4-25 21:27
根据马老师的设计思路,改了一个代码简化版本的:

当时写的没想那么多,抄一抄先
回复 支持 抱歉

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|RenPy中文空间 ( 苏ICP备17067825号 )

GMT+8, 2026-5-18 02:28 , Processed in 0.024548 second(s), 9 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表