karoterra / aviutl-GLShaderKit

AviUtl 拡張編集スクリプトで GLSL を使用するための DLL
MIT License
9 stars 0 forks source link

テクスチャを複数使用しようとするとすべて最後にバインドしたテクスチャになる #9

Closed karoterra closed 1 month ago

karoterra commented 1 month ago

スクリプトの方では以下の様に

-- テクスチャ1
obj.copybuffer("obj", "image:multi-texture_1.png")
local data, w, h = obj.getpixeldata()
GLShaderKit.setTexture2D(0, data, w, h)
-- テクスチャ2
obj.copybuffer("obj", "image:multi-texture_2.png")
local data, w, h = obj.getpixeldata()
GLShaderKit.setTexture2D(1, data, w, h)
-- テクスチャ3
obj.copybuffer("obj", "image:multi-texture_3.png")
local data, w, h = obj.getpixeldata()
GLShaderKit.setTexture2D(2, data, w, h)

フラグメントシェーダーでは以下の様に

layout(binding = 0) uniform sampler2D texture0;
layout(binding = 1) uniform sampler2D texture1;
layout(binding = 2) uniform sampler2D texture2;

void main() {
  vec4 c0 = texture(texture0, TexCoord);
  vec4 c1 = texture(texture1, TexCoord);
  vec4 c2 = texture(texture2, TexCoord);
}

してみたところ、 c0, c1, c2 いずれもテクスチャ3になってしまった。 c0 はテクスチャ1、 c1 はテクスチ2、 c2 はテクスチャ3になるのが想定の挙動である。

karoterra commented 1 month ago

ソースコードを変更したり戻したりと試していたら、元のコードでも意図した挙動をしてしまった。 data, w, h = obj.getpixeldata() で画像データが出力されるdata 配列は毎回同じ配列が使いまわされているので、glTextureSubImage2D でGPUに画像をテクスチャとして転送する際、タイミングの問題で転送完了前に data を更新してしまっていたのかも? 再現が難しくて嫌ですわ。

対策案としては以下の通り。