Обращение к Texel в ThreeJS DataTexture - PullRequest
0 голосов
/ 01 октября 2019

Я ищу, чтобы вычислить ссылки texel для THREE.DataTexture в Javascript для использования во фрагментном шейдере. Мне удалось вычислить координаты точек в пространстве экрана и передать их шейдеру в едином массиве с плавающей точкой значений x и y, а затем ссылаться на эти точки по индексам в моем шейдере. Теперь я хочу отрисовать слишком много точек, чтобы передать координаты в равномерном массиве с плавающей точкой, поэтому я хотел бы использовать DataTexture и записать координаты в значения RG текселей RGBA.

Ссылка на этот вопрос Я использую следующий метод:

var tDataWidth = points.length;
var tData = new Uint8Array( Math.pow(tDataWidth, 2) );

var texelSize = 1.0 / tDataWidth;
var texelOffset = new THREE.Vector2(0.5 * texelSize, 0.5 * texelSize);

for(var i = 0; i < points.length; i++){

    //convert data to 0-1, then to 0-255
    //inverse is to divide by 255 then multiply by width, height respectively

    tData[i * 4] = Math.round(255 * (points[i].x / window.innerWidth));
    tData[i * 4 + 1] = Math.round(255 * ((window.innerHeight - points[i].y) / window.innerHeight));
    tData[i * 4 + 2] = 0;
    tData[i * 4 + 3] = 0;

    //calculate UV texel coordinates here
    //Correct after edit
    var u = ((i % tDataWidth) / tDataWidth) + texelOffset;
    var v = (Math.floor(i / tDataWidth) + texelOffset);
    var vUV = new THREE.Vector2(u, v);
    //this function inserts the reference to the texel at the index into the shader
    //referenced in the frag shader:
    //cvec = texture2D(tData, index);
    shaderInsert += ShaderInsert(vUV, screenPos.x, window.innerHeight - screenPos.y);

}
var dTexture = new THREE.DataTexture( sdfUItData, tDataWidth, tDataWidth, THREE.RGBAFormat, THREE.UnsignedByteType );
//I think this is necessary
dTexture.magFilter = THREE.NearestFilter;
dTexture.needsUpdate = true;

//update uniforms of shader to get this DataTexture
renderer.getUniforms("circles")["tData"].value = dTexture;

//return string insert of circle
//I'm editing the shader through javascript then recompiling it
//There's more to it in the calling function, but this is the relevant part I think

    ...

ShaderInsert(index){
     var circle = "\n\tvIndex = vec2(" + String(index.x) + ", " + String(index.y) + ");\n";
     circle += "\tcvec = texture2D(tData, vIndex);\n";
     circle += "\tcpos = vec2( (cvec.r / 255.0) * resolution.x, (cvec.y / 255.0) * resolution.y);\n";
     circle += "\tc = circleDist(translate(p, cpos), 7.0);\n";
     circle += "\tm = merge(m, c);";
     return(circle);    
}

Любая помощь, где я иду не так? Прямо сейчас вывод находится в левом нижнем углу, так что, насколько я могу судить, (0, window.innerHeight). Спасибо!

1 Ответ

0 голосов
/ 04 октября 2019

Так что ответ на самом деле прост. В фрагментном шейдере значения rgba равны 0,0 - 1,0, поэтому нет необходимости делить на 255. Как я делал в фрагментном шейдере.

Я также хотел бы сказать, что обнаружил расширение Spector.js Chromeкоторый позволяет просматривать все вызовы и буферы webgl. Довольно круто!

enter image description here

Если кто-то хочет узнать больше о том, как функции рисования работают во фрагментном шейдере, все это в этом удивительном шейдере, который я сделалне пишите:

https://www.shadertoy.com/view/4dfXDn

<3 </p>

...