马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
本帖最后由 birctreel 于 2023-11-28 10:49 编辑
下午好!我最近在学习shader功能,研究过程中有一些问题,想问问有没有大佬知道如何实现
目标:给游戏画面附上一层老电视那种RGB色相分离的CRT效果
进展:可以用Shader给单图附上Shader效果,但不知道怎么应用在整个Layer
详细研究过程:
在学习了章鱼大佬在知乎上的帖子和在论坛里关于shader的研究帖之后,我想到的方法是修改Shader,将其编辑为Transform,然后应用在Layer上。
https://zhuanlan.zhihu.com/p/348922729
https://zhuanlan.zhihu.com/p/349467983
学习的知乎帖
https://www.shadertoy.com/view/WdjfDy
https://www.shadertoy.com/view/wllBDM
以上是我参考的Shader站代码,下面是我据此修改的Renpy可使用的Shader代码:
[RenPy] 纯文本查看 复制代码 init python:
renpy.register_shader("shadertoy.test", variables="""
uniform float u_time;
uniform vec2 u_model_size;
uniform vec2 res0;
uniform sampler2D tex0;
uniform sampler2D tex1;
""",fragment_functions="""
vec2 curve(vec2 uv)
{
uv = (uv - 0.5) * 2.0;
uv *= 1.1;
uv.x *= 1.0 + pow((abs(uv.y) / 5.0), 2.0);
uv.y *= 1.0 + pow((abs(uv.x) / 4.0), 2.0);
uv = (uv / 2.0) + 0.5;
uv = uv *0.92 + 0.04;
return uv;
}
""",
vertex_300="""
//v_tex_coord = a_tex_coord;
""",
fragment_300="""
//Curve
vec2 uv = gl_FragCoord.xy / res0.xy;
uv = curve( uv );
vec3 col;
// Chromatic
col.r = texture2D(tex0,vec2(uv.x+0.003,(1-uv.y))).x;
col.g = texture2D(tex0,vec2(uv.x+0.000,(1-uv.y))).y;
col.b = texture2D(tex0,vec2(uv.x-0.003,(1-uv.y))).z;
col *= step(0.0, uv.x) * step(0.0, uv.y);
col *= 1.0 - step(1.0, uv.x) * 1.0 - step(1.0, uv.y);
col *= 0.5 + 0.5*16.0*uv.x*uv.y*(1.0-uv.x)*(1.0-uv.y);
col *= vec3(0.95,1.05,0.95);
//col *= 0.9+0.1*sin(10.0*u_time+uv.y*1000.0);
col *= 0.99+0.01*sin(500.0*u_time);
float comp = smoothstep( 0.2, 0.7, sin(u_time) );
gl_FragColor = vec4(col,1.0);
""")
init python:
renpy.register_shader("test44.softlight", variables="""
uniform sampler2D tex0;
uniform sampler2D tex1;
attribute vec2 a_tex_coord;
varying vec2 v_tex_coord;
""", vertex_300="""
v_tex_coord = a_tex_coord;
""", fragment_300="""
vec4 base = texture2D(tex0, v_tex_coord);
vec4 blend = texture2D(tex1, v_tex_coord);
vec4 ctemp = base * blend;
gl_FragColor = mix(base, ctemp+(base*(1-((1-base)*(1-blend))-ctemp)), 0.5);
""")
然后,再把这个注册好的Shader制作成Transform效果:
[RenPy] 纯文本查看 复制代码 transform shadercrt:
shader "shadertoy.test"
最后,可以应用于游戏的图片(scene or image)上:
[RenPy] 纯文本查看 复制代码 scene overlay at shadercrt
但是,这个Transform存在一些问题:
1.只能应用在图像上,并不能整体应用在图层或者整个游戏画面上
2.这个效果应用于立绘等有透明背景的图片上时,透明背景会变成纯黑,无法使用
在查阅renpy文档中,发现有layer应用整个transform的代码:
https://doc.renpy.cn/zh-CN/displaying_images.html#camerashow-layer
但如果我使用
[RenPy] 纯文本查看 复制代码 camera master at shadercrt
或者
[RenPy] 纯文本查看 复制代码 show layer master at shadercrt
都会报错:
[RenPy] 纯文本查看 复制代码 File "renpy/common/000window.rpy", line 114, in _window_auto_callback
_window_show(auto=True)
File "renpy/common/000window.rpy", line 69, in _window_show
renpy.with_statement(trans)
Exception: Shader ('renpy.geometry', 'renpy.solid', 'shadertoy.test') has not been given uniform tex0.
我想到的第二种方案是利用pygame调用shader。这里我找到了一个pygame写的应用shader的工程:
https://github.com/JingShing/ModernGL-Shader-with-pygame
我不太懂python和pygame,但研究了一下代码后发现,这个python代码中定义的画面效果是crt_shader.
那么我要怎样才能把这个pygame中的crt_shader应用在整个renpy游戏界面or图层上呢?
不知道有没有办法可以实现我想要的整体应用效果,如果真的不行,也只能死了这条心了……_(:3√ L)_
|