gromiczek - 8 months ago 42

Javascript Question

I've fleshed out a loop to dynamically generates texture sizes for each different view I have in a browser-based visualization using shaders. I know the minimum number of pixels I need 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 pixel count until I reach a size that satisfies my ratio.

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;

}

Answer Source

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),
};
}
```