79828049

Date: 2025-11-23 18:52:02
Score: 0.5
Natty:
Report link

I was able to find my answer.

First of all instead of having my texture starting from the middle, I had it starting from a corner to make it easier to solve. Then I sent the mesh into the function findOffset() to calculate the offset I needed to add/remove in the shader.

function findOffset(mesh, material, options = {}) {
    const autoScale    = options.autoScale ?? false;   // scale texture to fit mesh
    const uniformScale = options.scale     ?? material.userData.ratio;     // manual scale multiplier
    if (!material.userData.shader) {
        console.warn("Shader not yet compiled. Call this AFTER first render.");
        return;
    }
    const shader = material.userData.shader;
    
    // Compute world-space bounding box
    const bbox = new THREE.Box3().setFromObject(mesh);
    const size = bbox.getSize(new THREE.Vector3());
    let min  = bbox.min;     // bottom-left-near corner (world-space!)
    min.x = min.x * uniformScale;
    min.y = min.y * uniformScale;
    min.z = min.z * uniformScale;
    
    // Compute offset for back sides
    const back = size.clone().multiplyScalar(uniformScale);
    
    // Pass to shader
    shader.uniforms.triplanarScaleX = { value: uniformScale };
    shader.uniforms.triplanarScaleY = { value: uniformScale };
    shader.uniforms.triplanarScaleZ = { value: uniformScale };
    shader.uniforms.triplanarOffset.value.copy(min);
    shader.uniforms.triplanarOffsetBack.value.copy(back);
    
    shader.uniforms.triplanarScaleX.value = uniformScale
    shader.uniforms.triplanarScaleY.value = uniformScale
    shader.uniforms.triplanarScaleZ.value = uniformScale
}

Finaly in the shader, I added the offset.

vec4 sampleTriplanarTexture(sampler2D tex, vec3 p, vec3 n, vec3 triplanarOffset, vec3 triplanarOffsetBack, float triplanarScaleX, float triplanarScaleY, float triplanarScaleZ) {
                    vec3 blend_weights = abs(n);
                    vec2 uvX;
                    vec2 uvY;
                    vec2 uvZ;
                    
                    vec4 colX;
                    vec4 colY;
                    vec4 colZ;
                    
                    vec3 N = normalize(n);
                    vec3 V = normalize(vViewPosition);
                    
                    // Decide dominant axis (stable per face)
                    vec3 w = abs(N);
                    bool faceX = w.x > w.y && w.x > w.z;
                    bool faceY = w.y > w.x && w.y > w.z;
                    bool faceZ = w.z > w.x && w.z > w.y;
                    
                    bool back = false;
                    if (faceZ && N.z < 0.0) { 
                        back = true;
                    }
                
                    if (faceX && N.x < 0.0) { 
                        back = true;
                    }
                
                    if (faceY && N.y < 0.0) {
                        back = true;
                    }
                    
                    // Identify cube face by normal
                    if (back == false) { // FRONT
                        blend_weights = normalize(max(vec3(0.001), blend_weights));
                        blend_weights /= (blend_weights.x + blend_weights.y + blend_weights.z);
                        
                        uvX = vec2( p.y * triplanarScaleY, p.z * triplanarScaleZ ) + triplanarOffset.yz;
                        uvY = vec2( p.x * triplanarScaleX, p.z * triplanarScaleZ ) + triplanarOffset.xz;
                        uvZ = vec2( p.x * triplanarScaleX, p.y * triplanarScaleY ) + triplanarOffset.xy;
                        
                        uvX.x = 1.0 - uvX.x;    // left/right border horizontal mirror
                        uvX.y = 1.0 - uvX.y;    // left/right border horizontal mirror
                        uvY.y = 1.0 - uvY.y;   // front border vertical flip
                        
                        colX = texture2D(tex, uvX);
                        colY = texture2D(tex, uvY);
                        colZ = texture2D(tex, uvZ);
                    }else{ //BACK
                        blend_weights = normalize(max(vec3(0.001), blend_weights));
                        blend_weights /= (blend_weights.x + blend_weights.y + blend_weights.z);
                        
                        uvX = vec2( p.y * triplanarScaleY, p.z * triplanarScaleZ ) + triplanarOffset.yz;
                        uvY = vec2( p.x * triplanarScaleX, p.z * triplanarScaleZ ) + triplanarOffset.xz;
                        uvZ = vec2( p.x * triplanarScaleX, p.y * triplanarScaleY ) + triplanarOffset.xy;                        
                        
                        uvX.y = 1.0 - uvX.y;   // left/right border horizontal mirror
                        uvZ.y = 1.0 - uvZ.y;   // front border vertical flip
                        
                        uvZ += vec2(0.0, triplanarOffsetBack.z); //back side offset
                        uvX += vec2(triplanarOffsetBack.z, 0.0); //font side offset
                        
                        colX = texture2D(tex, uvX);
                        colY = texture2D(tex, uvY);
                        colZ = texture2D(tex, uvZ);
                    }

                    return colX * blend_weights.x + colY * blend_weights.y + colZ * blend_weights.z;
                }

Which give the expected result:
Before

After

Reasons:
  • Blacklisted phrase (0.5): I need
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (1):
Posted by: Idea