You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pyglet绑定ShaderPy着色器后图片渲染为黑块如何解决

故障根因

绑定自定义着色器后,OpenGL固定渲染管线的默认纹理、顶点处理逻辑会被完全替换。当前着色器没有对接Pyglet渲染精灵/图片时传入的顶点坐标、纹理坐标、纹理采样器参数,无法读取到图片的像素数据,所以只会渲染出无纹理的黑色矩形。

修复步骤
  • 调整着色器实现,匹配Pyglet默认的顶点属性传参规则:image.blit()、Sprite渲染时默认传入三组顶点属性,分别为位置坐标、纹理坐标、顶点颜色,顶点着色器必须正确接收这些属性并透传给片元着色器。
  • 片元着色器需声明2D纹理采样器,手动将采样器绑定到Pyglet默认使用的0号纹理单元,才能正确读取加载的图片像素。
  • 调整渲染顺序,将window.clear()清屏操作移到着色器绑定逻辑外,避免清屏重置纹理绑定状态。

可用参考实现

首先编写匹配Pyglet传参规则的着色器:

  1. 顶点着色器 shader.vs
#version 120
attribute vec2 a_position;
attribute vec2 a_texcoord;
attribute vec4 a_color;

varying vec2 v_texcoord;
varying vec4 v_color;

void main() {
    gl_Position = gl_ModelViewProjectionMatrix * vec4(a_position, 0.0, 1.0);
    v_texcoord = a_texcoord;
    v_color = a_color;
}
  1. 片元着色器 shader.fs
#version 120
varying vec2 v_texcoord;
varying vec4 v_color;
uniform sampler2D u_texture;

void main() {
    gl_FragColor = texture2D(u_texture, v_texcoord) * v_color;
}

修正后的Python运行代码:

import pyglet
from pyglet.gl import *
import shaderpy

# 加载图片资源
image = pyglet.image.load('image.png')

# 创建窗口
window = pyglet.window.Window(1280,720)
pyglet.gl.glClearColor(0.5,0,0,1)

# 初始化着色器,提前绑定纹理采样器到0号单元
shader = shaderpy.Shader([
    ('shader.vs', GL_VERTEX_SHADER), 
    ('shader.fs', GL_FRAGMENT_SHADER)
])
shader.bind()
shader.uniformi('u_texture', 0)
shader.unbind()

@window.event
def on_draw():
    window.clear()
    shader.bind()
    image.blit(0,0)
    shader.unbind()

pyglet.app.run()

如果你使用330及以上版本的核心模式GLSL,需要手动通过layout (location = x)语法指定顶点属性位置,自行传入投影矩阵uniform替代内置的gl_ModelViewProjectionMatrix,否则会出现坐标错乱、纹理读取失败的问题。ShaderPy本身不会自动适配Pyglet的渲染状态,所有固定管线的传参逻辑都需要手动在着色器中对接。

内容的提问来源于stack exchange,提问作者nela

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:39:43