我正在为Javascript中的THREE.DataTexture计算纹理元素引用,以用于片段着色器。我已经成功地计算了点的屏幕空间坐标,并将它们传递到x和y值的统一浮点数组中的着色器中,然后在着色器中通过索引引用了这些点。我现在想渲染太多的点,以致无法在统一的float数组中传递坐标,因此我想使用DataTexture并将坐标写入RGBA像素的RG值。
Referencing this question我正在使用以下方法:
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)。谢谢!
所以答案实际上很简单。在片段着色器中,rgba值为0.0-1.0,因此不需要像在片段着色器中所做的那样除以255。
我也想说,我发现了Spector.js Chrome扩展程序,该扩展程序允许查看所有webgl调用和缓冲区。太酷了!
[如果有人想了解更多有关片段着色器中绘图功能的工作方式,这些全都在我没有写过的出色着色器中:
https://www.shadertoy.com/view/4dfXDn
<3