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

pythreejs中如何将vec4向量数组作为uniform传入着色器

实现方法

Three.js(及其Python绑定如pythreejs)原生支持vec4类型的uniform数组,你只需要按照以下规则构造uniform值即可:


语法修正

首先你给出的材质代码有个小语法错误,myVectorSize=(dict(value=10),多了多余的左括号,修正为:

myVectorSize=dict(value=10)

两种传值方案

你可以任选以下两种方案之一给myVector赋值:

方案1:扁平化Float32数组(性能最优,适合大数组)

vec4数组可以直接序列化为长度为向量数量 * 4的Float32数组,每个vec4的4个分量按顺序连续存储即可。
示例代码:

import numpy as np
from pythreejs import ShaderMaterial, UniformsLib

# 声明需要传入的vec4数量,不得超过着色器中定义的数组长度(你的代码里是50)
vector_count = 10
# 构造示例数据:10个随机RGBA颜色的vec4,flatten为一维float32数组
my_vector_data = np.random.rand(vector_count, 4).astype(np.float32).flatten()

# 构造材质
fragment_shader = """
    uniform int myVectorSize;
    uniform vec4 myVector[50];

    void main() {
      // 示例:取第一个vec4作为片元输出颜色
      gl_FragColor = myVector[0];
    }
"""

material = ShaderMaterial(
    uniforms=dict(
        myVectorSize=dict(value=10),
        myVector=dict(value=my_vector_data),
        **UniformsLib['common']
    ),
    fragmentShader=fragment_shader,
)
方案2:vec4实例列表(写法直观,适合小数组)

你也可以直接传一个由Vector4实例组成的列表作为value,Three.js会自动处理序列化:

from pythreejs import Vector4

vector_count = 10
my_vector_data = []
for i in range(vector_count):
    # 构造每个vec4实例
    my_vector_data.append(Vector4(
        np.random.rand(), # r
        np.random.rand(), # g
        np.random.rand(), # b
        1.0 # a
    ))

注意事项

  • WebGL1环境下不支持动态长度的uniform数组,你需要在着色器中预先声明足够大的固定长度(如你的代码里的myVector[50]),实际传入的数组长度不得超过该声明值。
  • WebGL2环境下可以将着色器中的数组声明改为uniform vec4 myVector[];,支持动态传入任意长度的数组。
  • 后续需要更新数组内容时,直接修改myVector对应的value数组即可,无需重新赋值uniform对象,Three.js会自动检测数据变更。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 17:24:05