I've fleshed out a loop to dynamically generate texture sizes for each different view I have in a browser-based visualization using shaders. I know the minimum number of pixels I need in order to pass my values to the shaders; however I need to scale them up to a power of 2 size, and then make sure their x and y dimensions are also powers of two with a 1:1, 2:1, or 1:2 ratio. Right now my loop is infinite, and I suppose I will need to continue to increase the overall power of 2 pixel count until I reach a size that satisfies one of my ratios.
My question is: Is there a more efficient or direct way to achieve what I'm trying to do here?
var motifMinBufferSize = 80000;
var bufferSize; // the total number of texels that will be in the computation buffers (must be a power of two)
var dimensions;
function initValues() {
bufferSize = setBufferSize();
dimensions = setPositionsTextureSize();
}
function setBufferSize() {
var buffer = motifMinBufferSize;
// fill out the buffers to a power of two - necessary for the computation textures in the shaders
var powCount = 1;
var powOf2 = 2;
while ( buffer > powOf2 ) {
powOf2 *= 2;
powCount++;
}
while ( buffer < powOf2 ) {
buffer += 1;
}
}
function setPositionsTextureSize() {
var dimensions = {
texWidth : null,
texHeight : null
};
var foundDimensions = false;
var powOf2 = 2;
while (foundDimensions === false) {
var candidateWidth = bufferSize/powOf2;
if ( candidateWidth === powOf2 || candidateWidth/2 === powOf2 || candidateWidth*2 === powOf2 ) {
dimensions.texWidth = candidateWidth;
dimensions.textHeight = powOf2;
foundDimensions = true;
} else {
powOf2 *= 2;
}
}
return dimensions;
}
Your buffer must contain 2^n elements since both the width and height of the buffer are powers of two. The smallest n that satisfies the requirement of holding
at least motifMinBufferSize
elements is calculated using logarithms: n = Math.ceil(Math.log2(motifMinBufferSize))
.
Let's say height of the buffer is 2^h and the width of the buffer is 2^w. We know that w and h can differ by at most one (due to the restrictions on the ratio of the buffer dimensions). We also know that 2^n = 2^w * 2^h which means n = w + h. Since w and h differ by at most 1, they are both basically half of n. Therefore we can get:
function getBufferDimensions(minBufferSize) {
var n = Math.ceil(Math.log2(minBufferSize));
var w = Math.ceil(n / 2);
var h = n - w;
return {
width: Math.pow(2, w),
height: Math.pow(2, h),
};
}