opengl – What’s mistaken with the TBN map?


I am making an attempt to import 3D fashions into OpenGL utilizing Rust and GLFT fashions, the issue is that this perform used to work… Now it would not work in any respect!

It is working to load the 3D mannequin, with the feel within the right place, apparently with the normals and tangents additionally right… However after I apply the TBN matrix to the normals to use the traditional map… The render comes out like this:

I do not know easy methods to clarify it, however for some purpose the fitting a part of the mannequin (constructive X is right), however the left half (with unfavorable X) for some purpose the traditional.x and tangent.x values ​​are inverted! Which causes half of the mannequin to have seen strains of the transitions the place the traditional map can be…

enter image description hereenter image description here

Because of this, I spent about 3 days rewriting the code in search of the error in each approach… The issue is that even when I invert the traditional.x and tangent.x values ​​just for the unfavorable facet of X… This creates a brand new downside, as a result of I am unable to determine the place precisely the division between one facet and the opposite is, which creates some unusual issues like…

enter image description here

I assumed the issue was within the 3D mannequin, however in each 3D program I opened it, it was regular and the traditional map labored! So, what’s mistaken with my code?

fn CarregarGltf(tudo : &mut Vec, indice : &mut std::collections::HashMap, modelo : &str){
    let local_exe = std::env::current_dir().unwrap();
    let native = local_exe.show();
    let original_tamanho = tudo.len()/22;
    let (gltf, buffers, _) = gltf::import(format!("extras/{}.gltf",modelo)).unwrap();
    //println!("Desmontando... "{}":",modelo);
    for m in gltf.meshes(){
        for p in m.primitives(){
            let r = p.reader(|buffer| Some(&buffers[buffer.index()]));
            let mut indices = Vec::new();
            if let Some(gltf::mesh::util::ReadIndices::U16(gltf::accessor::Iter::Normal(iter))) = r.read_indices(){
                for v in iter{
                    indices.push(v);
                }
            }
            let mut posicao = Vec::new();
            if let Some(iter) = r.read_positions(){
                for v in iter{
                    posicao.push(v);
                }
            }
            let mut textura = Vec::new();
            if let Some(gltf::mesh::util::ReadTexCoords::F32(gltf::accessor::Iter::Normal(iter))) = r.read_tex_coords(0){
                for v in iter{
                    textura.push(v);
                }
            }
            let mut normais = Vec::new();
            if let Some(iter) = r.read_normals(){
                for v in iter{
                    normais.push(v);
                }
            }
            let mut tangentes = Vec::new();
            if let Some(iter) = r.read_tangents(){
                for v in iter{
                    tangentes.push(v);
                }
            }
            let mut ossosid = Vec::new();
            if let Some(gltf::mesh::util::ReadJoints::U8(gltf::accessor::Iter::Normal(iter))) = r.read_joints(0){
                for v in iter{
                    ossosid.push(v);
                }
            }
            if ossosid.len() == 0{
                println!("Cenário");
            }else{
                println!("Personagem");
            }
            let mut pesos = Vec::new();
            if let Some(gltf::mesh::util::ReadWeights::F32(gltf::accessor::Iter::Normal(iter))) = r.read_weights(0){
                for v in iter{
                    pesos.push(v);
                }
            }
            //println!("Indices : {}, {}", &indices.len()/3, &indices.len());
            for q in &indices{
                // posição
                tudo.push(posicao[*q as usize][0] as f32);
                tudo.push(posicao[*q as usize][1] as f32);
                tudo.push(posicao[*q as usize][2] as f32);
                // textura
                tudo.push(textura[*q as usize][0] as f32);
                tudo.push(textura[*q as usize][1] as f32);
                // Normais
                tudo.push(normais[*q as usize][0] as f32);
                tudo.push(normais[*q as usize][1] as f32);
                tudo.push(normais[*q as usize][2] as f32);
                // Tangentes
                tudo.push(tangentes[*q as usize][0] as f32);
                tudo.push(tangentes[*q as usize][1] as f32);
                tudo.push(tangentes[*q as usize][2] as f32);
                // ossosid e pesos
                if ossosid.len() != 0{
                    tudo.push(ossosid[*q as usize][0] as f32);
                    tudo.push(ossosid[*q as usize][1] as f32);
                    tudo.push(ossosid[*q as usize][2] as f32);
                    tudo.push(ossosid[*q as usize][3] as f32);
                    // pesos
                    let tmp = pesos[*q as usize][0] + pesos[*q as usize][1] + pesos[*q as usize][2] + pesos[*q as usize][3];
                    tudo.push(pesos[*q as usize][0]/tmp);
                    tudo.push(pesos[*q as usize][1]/tmp);
                    tudo.push(pesos[*q as usize][2]/tmp);
                    tudo.push(pesos[*q as usize][3]/tmp);
                }else{
                    tudo.push(0.0);tudo.push(0.0);tudo.push(0.0);tudo.push(0.0);
                    tudo.push(0.0);tudo.push(0.0);tudo.push(0.0);tudo.push(0.0);
                }
                // aoffset
                let rx = ((rand::thread_rng().gen_range(0..200000) as f32)/100.0)-1000.0;
                let rz = ((rand::thread_rng().gen_range(0..200000) as f32)/100.0)-1000.0;
                tudo.push(rx);
                tudo.push(0.0);
                tudo.push(rz);
            }
        }
    }
    indice.insert(modelo.to_string(),(original_tamanho as i32,(tudo.len()/22-original_tamanho) as i32));
    println!("Tudo do "{}" : {}, {}", modelo.to_string(), original_tamanho, tudo.len()/22-original_tamanho);
}

replace 1

I found that the error is by some means within the bitangent, I do not know easy methods to clarify it however after I use:

B = cross(NOR,T);

The error seems on the fitting facet of the mannequin.

Once I do the alternative:

B = cross(T,NOR);

The precise facet seems appropriately and the left facet seems incorrect.

How do I repair this? I attempted to change the X place, however it simply tousled the entire scene and though it appeared to repair the left and proper sides it created an error in the course of the mannequin!

enter image description here

I used this snippet within the code:

TBN = mat3(T,cross(NOR,T)*(-outpos1.x/abs(outpos1.x)),NOR);

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles