29

WebGLシェーダー言語(GLSL)は、多次元ベクトル数学のための非常に強力なツールです。

JavaScript(Webブラウザーで実行)からのその力をプライベートな非3D計算に使用する可能性はありますか?データを取り込むことは可能ですが、シェーダーの計算が行われた後にJavaScriptにデータを取り出す方法はありますか?

実際の描画は必要ありません。ベクトルを計算するだけです。(JavaScriptで記述されたハードウェアアクセラレーション重力シミュレーターのアイデアをいじっています。)

ありがとう!


ニュース:Khronosは、JavaScriptでアクセス可能なバージョンのOpenCLとなるWebCLを開発しているようです。それはまさに私が探しているものですが、それは少し時間がかかります...

4

3 に答える 3

17

仕様を見る限り、WebGL はフレームバッファ オブジェクトとリードバック操作をサポートしています。データを変換してクライアント空間に戻すには、これで十分です。一連の操作は次のとおりです。

  1. 結果を保存するために必要なレンダー バッファを添付して FBO を作成します。縛る
  2. すべての入力データをテクスチャ (同じサイズ) にアップロードします。
  3. フラグメント部分内で計算を行う GLSL 処理シェーダーを作成し、テクスチャから入力を読み取り、出力を宛先レンダーバッファーに書き込みます。縛る
  4. クワッドを描きます。を介してレンダー バッファを読み戻しますglReadPixels
于 2011-03-24T13:24:19.017 に答える
6

ブラウザーでシェーダーからフロートを取得するのは実際には非常に簡単ですが、制約はピクセルごとに 1 つのフロートです。

4 つの int を 1 つの float に変換します (r: int, g: int, b: int, a: int) -> (rgba: float)。

ありがとうIEEE

float random(vec2 seed) { 
    return fract(cos(mod(123456780., 1024. * dot(seed / time, vec2(23.1406926327792690, 2.6651441426902251))))); 
}
float shift_right(float v, float amt) { 
    v = floor(v) + 0.5; return floor(v / exp2(amt)); 
}
float shift_left(float v, float amt) { 
    return floor(v * exp2(amt) + 0.5); 
}
float mask_last(float v, float bits) { 
    return mod(v, shift_left(1.0, bits)); 
}
float extract_bits(float num, float from, float to) { 
    from = floor(from + 0.5); to = floor(to + 0.5); 
    return mask_last(shift_right(num, from), to - from); 
}
vec4 encode_float(float val) { 
    if (val == 0.0) return vec4(0, 0, 0, 0); 
    float sign = val > 0.0 ? 0.0 : 1.0; 
    val = abs(val); 
    float exponent = floor(log2(val)); 
    float biased_exponent = exponent + 127.0; 
    float fraction = ((val / exp2(exponent)) - 1.0) * 8388608.0; 
    float t = biased_exponent / 2.0; 
    float last_bit_of_biased_exponent = fract(t) * 2.0; 
    float remaining_bits_of_biased_exponent = floor(t); 
    float byte4 = extract_bits(fraction, 0.0, 8.0) / 255.0; 
    float byte3 = extract_bits(fraction, 8.0, 16.0) / 255.0; 
    float byte2 = (last_bit_of_biased_exponent * 128.0 + extract_bits(fraction, 16.0, 23.0)) / 255.0; 
    float byte1 = (sign * 128.0 + remaining_bits_of_biased_exponent) / 255.0; 
    return vec4(byte4, byte3, byte2, byte1); 
}

使用法:

シェーダー:

outputcolor = encode_float(420.420f);

JavaScript:

// convert output to floats
output = new Float32Array(output.buffer);
于 2014-03-12T18:02:01.940 に答える
2

はい、実行可能です。Aaron Babcock による古いデモ (1.0 WebGL 仕様で動作させるには微調整が必​​要になる場合があります) があります

于 2011-03-24T14:19:00.107 に答える