I am trying to implement a texture cubic projection inside my WebGL shader, like in the picture below:
What I tried so far:
I am passing the bounding box of my object (the box in the middle of the picture) as follows:
uniform vec3 u_bbmin;
uniform vec3 u_bbmax;
... so the eight vertexes of my projection box are:
vec3 v1 = vec3(u_bbmin.x, u_bbmin.y, u_bbmin.z);
vec3 v2 = vec3(u_bbmax.x, u_bbmin.y, u_bbmin.z);
vec3 v3 = vec3(u_bbmin.x, u_bbmax.y, u_bbmin.z);
...other combinations
vec3 v8 = vec3(u_bbmax.x, u_bbmax.y, u_bbmax.z);
At the end, to sample from my texture I need a map in the form of:
varying vec3 v_modelPos;
...
uniform sampler2D s_texture;
vec2 tCoords = vec2(0.0);
tCoords.s = s(x,y,z)
tCoords.t = t(y,y,z)
vec4 color = texture2D(s_texture, tCoords);
I was able to implement spherical and cylindrical projections, but I am stuck now how to get this kind of cubic map, The texture shall stretch to the whole bounding box, aspect ratio doesn't matter.
Maybe I am missing some key points and I need some hints. How should the math for a cubic projection looks like?
The key-point here is: normals shall be in object-space. Please note that gman's answer is more elegant than mine, by using a matrix for the
uv
computation. I am using instead the bounding box coordinates, which are already passed to the vertex shader asuniform
for other general purposes.Moreover, I don't even need to distinguish all the six major axis, I just only need three sides projection, so this can be simplified down. Of course, the texture will be mirrored on the opposite faces.
Explanation:
modelPos
coordinates. Example: the texture can be rotated by 90 degrees by usingmodelPos.yx
instead ofmodelPos.xy
.modelPos
coordinates. Example: the texture can be mirrored on the Y-axis by usingvec2(sX, sY)
instead ofvec2(sX, -sY)
.Result:
EDIT:
It is worth to link here another answer from gman which contain additional information about this topic and also some cool optimization techniques to avoid conditionals inside GLSL shaders: How to implement textureCube using 6 sampler2D.
I honestly don't know if this is correct or not but ...
Looking up how cube mapping works there's a table in the OpenGL ES 2.0 spec
Using that I wrote this function
You pass in a matrix and it sets it up to move the correct X, Y, or Z to the X and Y columns (to convert to s and t). In other words you pass in normal and it returns s and t.
This would effectively give a unit cube projected on the positive side of the origin. Adding in another matrix we can move and scale that cube.
If you want it to fit the cube exactly then you need to set the scale, translation and orientation to match the cube.