找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1189|回复: 5

[经验] Renpy Shader分享,持续更新(吧)

[复制链接]
发表于 2024-1-12 14:00:11 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 birctreel 于 2024-2-23 19:52 编辑

改了 能用 但不一定那么有用……的一些shader分享,大多是画面效果类
基本上都是看到shadertoy站上很有趣的shader,一时兴起改了改,最后发现我的项目用不上的代码。放在那里也很可惜不如分享出来,说不定大家能用得上
Shader license 参考这里:https://www.shadertoy.com/terms
使用时请注意哈!


1.水彩效果
源代码:https://www.shadertoy.com/view/slcSRM
效果参考shadertoy站,(因为个人需求原因)去掉了白边、减弱了提亮效果,纯粹的水彩特效,因为是动态的,比其他水彩效果看起来有趣
(最后因为发现本来美术风格就是水彩用不上这玩意儿啊!!!而作罢)
[RenPy] 纯文本查看 复制代码
    renpy.register_shader("shader.watercolor",
    variables="""
        uniform float u_time;
        uniform vec2 u_model_size;
        uniform vec2 res0;
        uniform sampler2D tex0;
        attribute vec2 a_tex_coord;
        varying vec2 v_tex_coord;
        uniform vec4 u_color
    """,
    fragment_functions="""
        #define M_PI 3.14159265358979323846
        vec2 hash( vec2 p ) // replace this by something better
        {
            p = vec2( dot(p,vec2(127.1,311.7)), dot(p,vec2(269.5,183.3)) );
            return -1.0 + 2.0*fract(sin(p)*43758.5453123);
        }

        float noise( in vec2 p )
        {
            const float K1 = 0.366025404; // (sqrt(3)-1)/2;
            const float K2 = 0.211324865; // (3-sqrt(3))/6;

            vec2  i = floor( p + (p.x+p.y)*K1 );
            vec2  a = p - i + (i.x+i.y)*K2;
            float m = step(a.y,a.x); 
            vec2  o = vec2(m,1.0-m);
            vec2  b = a - o + K2;
            vec2  c = a - 1.0 + 2.0*K2;
            vec3  h = max( 0.5-vec3(dot(a,a), dot(b,b), dot(c,c) ), 0.0 );
            vec3  n = h*h*h*h*vec3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0)));
            return dot( n, vec3(70.0) );
        }


        float simp(vec2 uv) {
            uv *= 5.0;
            mat2 m = mat2( 1.6,  1.2, -1.2,  1.6 );
            float f = 0.5000*noise( uv ); uv = m*uv;
            f += 0.2500*noise( uv ); uv = m*uv;
            f += 0.1250*noise( uv ); uv = m*uv;
            f += 0.0625*noise( uv ); uv = m*uv;
            f = 0.2 + 0.8*f;
            return f;
        }


        vec4 bumpFromDepth(vec2 uv, vec2 resolution, float scale) {
        vec2 step = 1. / resolution;
            
        float height = simp(uv);
            
        vec2 dxy = height - vec2(
            simp(uv + vec2(step.x, 0.)), 
            simp(uv + vec2(0., step.y))
        );
            
        return vec4(normalize(vec3(dxy * scale / step, 1.)), height);
        }




        float sdRoundedBox( in vec2 p, in vec2 b, in vec4 r )
        {
            r.xy = (p.x>0.0)?r.xy : r.zw;
            r.x  = (p.y>0.0)?r.x  : r.y;
            vec2 q = abs(p)-b+r.x;
            return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - r.x;
        }
    """,
    vertex_100="""
            v_tex_coord = a_tex_coord;
    """,
        
    fragment_300="""
        // Normalized pixel coordinates (from 0 to 1)
        vec2 uv = v_tex_coord;
        vec4 offset = bumpFromDepth(uv + vec2(floor(u_time*4.0)/4.0), res0.xy, .05)/80.0;
        

        // Output to screen
                    //texture(iChannel0, uv + offset.xy)*0.4;
        
                    
        gl_FragColor = (texture2D(tex0, uv + offset.xy)*0.4) + (texture2D(tex0, uv)*0.6);
        gl_FragColor += length(bumpFromDepth(uv, res0.xy, .1))*0.05;

    """)




2.描边效果
源代码:https://www.shadertoy.com/view/DtBBWd
超好用的描边!!!!想要修改描边粗细,就修改【line_thickness】这个参数,原帖默认是10,我这里改成3,效果已经很不错了。
注意描边粗细数值不能太大,因为这个描边逻辑实际上是把你的原图在背景的四个方向多粘了几遍,导致如果描边数值过大,描的边会出现重影
*因为我没有修改描边粗细的需求所以没有把这个变量放出来,如果你需要随时调整线宽,就在开头声明一个新变量赋到line_thickness上就行

我这里改了shader代码,便于使用shader的时候可以随时调整描边颜色,即你修改u_color这个参数后面跟的那个四位向量数值就行
不过注意glsl的颜色写法和renpy不同,这个四位向量数值为(RR/255,GG/255,BB/255,透明度),你需要把16进制颜色转换成RRGGBB之后再除255,变成小数才行。
比如我这个描边的颜色实际是16进制颜色#C69949
(这个用上了,非常好用,你甚至可以用它改描边颜色做按钮悬浮动效)

[RenPy] 纯文本查看 复制代码
    renpy.register_shader("shader.outline",
    variables="""
        uniform float u_time;
        uniform vec2 u_model_size;
        uniform vec2 res0;
        uniform sampler2D tex0;
        attribute vec2 a_tex_coord;
        varying vec2 v_tex_coord;
        uniform vec4 u_color
    """,
    fragment_functions="""
    """,
    vertex_100="""
            v_tex_coord = a_tex_coord;
    """,
        
    fragment_300="""
        vec2 uv = v_tex_coord;

        vec2 texture_PIXEL_SIZE = vec2(0.0005, 0.0005);
        float line_thickness = 3;
        
        vec2 size = texture_PIXEL_SIZE * line_thickness;
        
        float outline = texture2D(tex0, uv + vec2(-size.x, 0)).a;
        outline += texture2D(tex0, uv + vec2(0, size.y)).a;
        outline += texture2D(tex0, uv + vec2(size.x, 0)).a;
        outline += texture2D(tex0, uv + vec2(0, -size.y)).a;
        outline += texture2D(tex0, uv + vec2(-size.x, size.y)).a;
        outline += texture2D(tex0, uv + vec2(size.x, size.y)).a;
        outline += texture2D(tex0, uv + vec2(-size.x, -size.y)).a;
        outline += texture2D(tex0, uv + vec2(size.x, -size.y)).a;
        outline = min(outline, 1.0);
        
        vec4 color = texture2D(tex0, uv);
        vec4 COLOR = mix(color, u_color, outline - color.a);
        
        gl_FragColor = COLOR;
    """)

#用的时候就写XXX at outline就行

transform outline():
    mesh True#这里表示描边仅用在外轮廓上,防止你层叠图它每一层都给你描一次边
    shader 'shader.outline'
    u_color (0.831,0.792,0.808,1)#这里修改描边颜色





3.又快又好的高斯模糊
试了一下之后发现果然又快又好
源码:https://www.shadertoy.com/view/Xltfzj

顺便定义了transform gsblur,使用的时候 就 at gsblur(rad值)就行,rad是你的模糊半径,建议不要大于10,不然虽然很快但是不那么好了……(汗)
[RenPy] 纯文本查看 复制代码
    renpy.register_shader("shader.gsblur",
    variables="""
        uniform float u_radius;
        uniform vec2 u_model_size;
        uniform vec2 res0;
        uniform sampler2D tex0;
        attribute vec2 a_tex_coord;
        varying vec2 v_tex_coord;
    """,
    fragment_functions="""
    """,
    vertex_100="""
            v_tex_coord = a_tex_coord;
    """,
        
    fragment_300="""
        float Pi = 6.28318530718; // Pi*2
        // GAUSSIAN BLUR SETTINGS {{{
        float Directions = 16.0; // BLUR DIRECTIONS (Default 16.0 - More is better but slower)
        float Quality = 6.0; // BLUR QUALITY (Default 4.0 - More is better but slower)
        float Size = u_radius; // BLUR SIZE (Radius)
        // GAUSSIAN BLUR SETTINGS }}}
    
        vec2 Radius = Size/res0.xy;
        
        // Normalized pixel coordinates (from 0 to 1)
        vec2 uv = v_tex_coord;
        // Pixel colour
        vec4 Color = texture2D(tex0, uv);
        
        // Blur calculations
        for( float d=0.0; d<Pi; d+=Pi/Directions)
        {
            for(float i=1.0/Quality; i<=1.0; i+=1.0/Quality)
            {
                Color += texture2D(tex0, uv+vec2(cos(d),sin(d))*Radius*i);                
            }
        }
        
        // Output to screen
        Color /= Quality * Directions - 15.0;
        gl_FragColor =  Color;
    """)



先发几个库存的
之后如果还做了其他shader就更新在这个帖子下面

 楼主| 发表于 2024-1-12 15:06:16 | 显示全部楼层
自用的色差shader,模仿老电视之类的那种效果
源代码是这个
https://www.shadertoy.com/view/WdjfDy
但已然魔改得看不出痕迹……(草)

去掉了条纹和闪烁,不然视觉效果看起来会很累

[RenPy] 纯文本查看 复制代码
init python hide:
    renpy.register_shader("shader.rgbtv",
    variables="""
        uniform float u_time;
        uniform vec2 u_model_size;
        uniform vec2 res0;
        uniform sampler2D tex0;
        attribute vec2 a_tex_coord;
        varying vec2 v_tex_coord;

    """,
    fragment_functions="""

    vec2 crt_coords(vec2 uv, float bend)
    {
        uv -= 0.5;
        //uv *= 2.;
        uv.x *= 1. + pow(abs(uv.y)/bend, 5.);
        uv.y *= 1. + pow(abs(uv.x)/bend, 5.);
        
        //uv /= 2.5;
        return uv + .5;
    }
    float rand(vec2 co){
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
    }

    float rand(float c){
        return rand(vec2(c,1.0));
    }
    
    """,
    vertex_100="""
            v_tex_coord = a_tex_coord;
    """,
        
    fragment_300="""
        float t = float(int(u_time * 15));
        vec2 crt_uv = crt_coords(v_tex_coord, 4.);
        vec4 col;
        col.r = texture2D(tex0, crt_uv + vec2(0.0015, 0)).r;
        col.g = texture2D(tex0, crt_uv).g;
        col.b = texture2D(tex0, crt_uv + vec2(0., -0.0015)).b;
        col.a = texture2D(tex0, crt_uv).a;
        gl_FragColor = col;
    """)

transform crt(child):
    mesh True
    gl_pixel_perfect True
    Model().shader("shader.rgbtv").child(child, fit=True)




回复 支持 0 抱歉 1

使用道具 举报

 楼主| 发表于 2024-1-16 17:59:56 | 显示全部楼层
本帖最后由 birctreel 于 2024-1-16 18:06 编辑

一个barrel模糊色差效果,和上面那个挺类似的
https://www.shadertoy.com/view/XssGz8
去掉了点击效果和页面上展示的其他东西
[RenPy] 纯文本查看 复制代码
    renpy.register_shader("shader.barrel",

    variables="""

        uniform float u_time;
        uniform vec2 u_model_size;
        uniform vec2 res0;
        uniform sampler2D tex0;
        attribute vec2 a_tex_coord;
        varying vec2 v_tex_coord;
    """,
    fragment_functions="""

        float remap01( float t, float a, float b ) {
            return clamp( (t - a) / (b - a), 0.0, 1.0 );
        }
        vec2 remap01( vec2 t, vec2 a, vec2 b ) {
            return clamp( (t - a) / (b - a), 0.0, 1.0 );
        }

        float rand(vec2 co){
        return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
        }

        float rand(float c){
            return rand(vec2(c,1.0));
        }
    
        //note: input [0;1]
        vec3 spectrum_offset_rgb( float t )
        {
            //note: optimisation from [url=https://twitter.com/Stubbesaurus/status/818847844790575104]https://twitter.com/Stubbesaurus/status/818847844790575104[/url]
            float t0 = 2.0 * t - 1.5;//这里用来调整模糊和色差的程度
            vec3 ret = clamp( vec3( -t0, 1.0-abs(t0), t0), 0.0, 1.0);

            
            return ret;

        }

        const float gamma = 2.2;
        vec3 lin2srgb( vec3 c )
        {
            return pow( c, vec3(gamma) );
        }
        vec3 srgb2lin( vec3 c )
        {
            return pow( c, vec3(1.0/gamma));
        }


        vec3 yCgCo2rgb(vec3 ycc)
        {
            float R = ycc.x - ycc.y + ycc.z;
            float G = ycc.x + ycc.y;
            float B = ycc.x - ycc.y - ycc.z;
            return vec3(R,G,B);
        }


        vec3 yuv2rgb( vec3 yuv )
        {
            vec3 rgb;
            rgb.r = yuv.x + yuv.z * 1.13983;
            rgb.g = yuv.x + dot( vec2(-0.39465, -0.58060), yuv.yz );
            rgb.b = yuv.x + yuv.y * 2.03211;
            return rgb;
        }


        // ====

        //note: from [url=https://www.shadertoy.com/view/XslGz8]https://www.shadertoy.com/view/XslGz8[/url]
        vec2 radialdistort(vec2 coord, vec2 amt)
        {
            vec2 cc = coord - 0.5;
            return coord + 2.0 * cc * amt;
        }


        //note: from [url=https://www.shadertoy.com/view/MlSXR3]https://www.shadertoy.com/view/MlSXR3[/url]
        vec2 brownConradyDistortion(vec2 uv, float dist)
        {
            uv = uv * 2.0 - 1.0;
            // positive values of K1 give barrel distortion, negative give pincushion
            float barrelDistortion1 = 0.1 * dist; // K1 in text books
            float barrelDistortion2 = -0.025 * dist; // K2 in text books

            float r2 = dot(uv,uv);
            uv *= 1.0 + barrelDistortion1 * r2 + barrelDistortion2 * r2 * r2;
            //uv *= 1.0 + barrelDistortion1 * r2;
            
            // tangential distortion (due to off center lens elements)
            // is not modeled in this function, but if it was, the terms would go here
            return uv * 0.5 + 0.5;
        }

        vec2 distort( vec2 uv, float t, vec2 min_distort, vec2 max_distort )
        {
            vec2 dist = mix( min_distort, max_distort, t );
            //return radialdistort( uv, 2.0 * dist );//这个弧面程度似乎小一点
            return brownConradyDistortion( uv, 75.0 * dist.x );//这个弧面程度大一点
        }

        // ====

        vec3 spectrum_offset( float t )
        {
            return spectrum_offset_rgb( t );

        }

        // ====

        /*
        float nrand( vec2 n )
        {
            return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);
        }
        */

        float rand(vec3 co){ return rand(co.xy+rand(co.z)); }
    """,
    vertex_100="""
            v_tex_coord = a_tex_coord;
    """,
        
    fragment_300="""
        vec2 uv = v_tex_coord;
        
        const float MAX_DIST_PX = 12.0;
        float max_distort_px = MAX_DIST_PX * (1.0-.5/res0.x);
        vec2 max_distort = vec2(max_distort_px) / res0.xy;
        vec2 min_distort = 0.5 * max_distort;

        
        const int num_iter = 7;
        const float stepsiz = 1.0 / (float(num_iter)-1.0);
        float t = stepsiz;
        //vec2 oversiz = vec2(1.0);
        vec2 oversiz = distort( vec2(1.0), 1.0, min_distort, max_distort );
        uv = remap01( uv, 1-oversiz,oversiz);
        vec3 sumcol = vec3(0.0);
        vec3 sumw = vec3(0.0);
        for ( int i=0; i<num_iter; ++i )
        {
            vec3 w = spectrum_offset( t );
            sumw += w;
            //vec2 uvd = distort(uv, t, min_distort, max_distort ); //TODO: move out of loop
            sumcol += w * srgb2lin(texture2D(tex0, uv ).rgb );
            t += stepsiz;
        }
        sumcol.rgb /= sumw;

        vec3 outcol = sumcol.rgb;
        outcol = lin2srgb( outcol );

        gl_FragColor = col;
    """)
回复 支持 抱歉

使用道具 举报

 楼主| 发表于 2024-2-7 14:55:33 | 显示全部楼层
https://www.shadertoy.com/view/XssGDN
一个晕眩效果,相当实用!
调整scale和speed两个参数来自定义自己想要的晕眩程度


[RenPy] 纯文本查看 复制代码
    renpy.register_shader("shader.dizzy",
    variables="""
        uniform float u_time;
        uniform vec2 u_model_size;
        uniform vec2 res0;
        uniform sampler2D tex0;
        attribute vec2 a_tex_coord;
        varying vec2 v_tex_coord;
        uniform vec4 u_color
    """,
    fragment_functions="""
        const float scale = 0.02;
        vec2 getOffset(float time, vec2 uv)
        {
        float a = 1.0 + 0.5 * sin(time + uv.x * 10.0);
        float b = 1.0 + 0.5 * cos(time + uv.y * 10.0);
            
        return scale * vec2(a + sin(b), b + cos(a));
        }
    """,
    vertex_100="""
            v_tex_coord = a_tex_coord;
    """,
        
    fragment_300="""
        //const float scale = 0.02;
        float speed = 5.0;

        vec2 uv = v_tex_coord;
        float time= speed * u_time;
        float prevTime= speed * (u_time-1.0);

        // current offset
        vec2 offset= getOffset(time, uv);	

        // offset at prev frame
        vec2 prevOffset= getOffset(prevTime, uv);	

        // motion vector from previous to current frame
        vec2 delta= offset - prevOffset;

        uv += offset;

        vec4 color= vec4(0.0, 0.0, 0.0, 0.0);

        // some iterations of unweighted blur
        const int steps= 20;
        float factor= 1.0 / float(steps);

        for (int i=0; i<steps; i++)
        {
            color += texture2D(tex0, uv);
            uv += delta * factor;
        }

        vec4 whoaColor = color;
        float whoa = 0.1 + 0.01 * (1.0 + cos(10.0 * sin(time)));

        gl_FragColor = (whoa * whoaColor) * color * factor;
    """)


回复 支持 抱歉

使用道具 举报

发表于 2024-4-5 21:09:49 | 显示全部楼层
请问大佬,你说你不懂Shader,那你是如何知道怎么修改至Renpy可用的呢?
回复 支持 抱歉

使用道具 举报

 楼主| 发表于 2024-6-28 15:59:52 | 显示全部楼层
gogomyt 发表于 2024-4-5 21:09
请问大佬,你说你不懂Shader,那你是如何知道怎么修改至Renpy可用的呢?

基本是试出来的,先不管三七二十一写上去运行看看,报错的话就根据报错信息来调整
回复 支持 抱歉

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-21 19:39 , Processed in 0.121708 second(s), 27 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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