I am working with a height texture that is retrieved from a server. It encodes the overall height value per pixel within the RGB
channels. To get a height value per pixel, the R
channel is multiplied by 65536.0, G
with 256.0 , then height = R + G + B
.
Due to this splitting, R
and G
have discontinuities (see the image of the G
channel below with the 100% white vs. 100% black areas) which they need since the other part (R or B) takes over. That's why I can't linearly filter the texture. I'd like, however, to linearly filter the B
channel as it contains the highest frequencies/smallest height deviations – in order to get a smooth surface.
Is it possible to split up the texture internally (e.g., within the shader but I don't mind where this happens), so that only its B
channel is linearly filtered while the R, B
channels are left at nearest neighbour? Before all components are added together again? If so, how can this be done in an efficient manner?
WebGL texture filtering applies to the whole texture, not each individual channel. But what you could do is clone the texture, and sample them separately in the shader.
var texture2 = texture1.clone();
texture1.magFilter = THREE.NearestFilter;
texture2.magFilter = THREE.LinearFilter; // This is the default
Then in your shader:
vec2 sampleRG = texture2D(texture1, vUv).rg;
float sampleB = texture2D(texture2, vUv).b;
It's a little bit of extra overhead, but nothing your GPU can't handle.
Note, I've always seen each channel's value range from 0 to 255, not 256. Are you sure you don't want to multiply by 255 instead?