Pergunta

Resumo

Estou tentando aplicar um mapa de deslocamento (mapa de altura) a um objeto bastante simples (plano hexagonal) e estou tendo alguns resultados inesperados.Estou usando tons de cinza e, como tal, tive a impressão de que meu mapa de altura deveria afetar apenas os valores Z da minha malha.No entanto, o mapa de deslocamento que criei estica a malha pelos planos X e Y.Além disso, parece não usar o mapeamento UV que criei e ao qual todas as outras texturas foram aplicadas com sucesso.

Modelo e Mapa UV

Aqui estão imagens de referência da minha malha hexagonal e seu mapa UV correspondente no Blender.

Hexagonal Model and UV Map

Texturas Difusas e Deslocadas

Estas são as texturas de mapa difuso e de deslocamento que estou aplicando à minha malha por meio do Three.JS.

Hexagonal Diffuse and Displacement Textures

Renderizações

Quando renderizo o plano sem um mapa de deslocamento, você pode ver que o plano hexagonal permanece dentro das linhas.No entanto, quando adiciono o mapa de deslocamento, ele afeta claramente as posições X e Y dos vértices, em vez de afetar apenas Z, expandindo o plano bem sobre as linhas.

Hexagonal Plane Renders -- With & Without Displacement Map

Código

Aqui está o código Three.js relevante:

    // Textures
    var diffuseTexture = THREE.ImageUtils.loadTexture('diffuse.png', null, loaded);
    var displacementTexture = THREE.ImageUtils.loadTexture('displacement.png', null, loaded);

    // Terrain Uniform
    var terrainShader = THREE.ShaderTerrain["terrain"];
    var uniformsTerrain = THREE.UniformsUtils.clone(terrainShader.uniforms);

  //uniformsTerrain["tNormal"].value = null;
  //uniformsTerrain["uNormalScale"].value = 1;

    uniformsTerrain["tDisplacement"].value = displacementTexture;
    uniformsTerrain["uDisplacementScale"].value = 1;

    uniformsTerrain[ "tDiffuse1" ].value = diffuseTexture;
  //uniformsTerrain[ "tDetail" ].value = null;
    uniformsTerrain[ "enableDiffuse1" ].value = true;
  //uniformsTerrain[ "enableDiffuse2" ].value = true;
  //uniformsTerrain[ "enableSpecular" ].value = true;

  //uniformsTerrain[ "uDiffuseColor" ].value.setHex(0xcccccc);
  //uniformsTerrain[ "uSpecularColor" ].value.setHex(0xff0000);
  //uniformsTerrain[ "uAmbientColor" ].value.setHex(0x0000cc);

  //uniformsTerrain[ "uShininess" ].value = 3;
  //uniformsTerrain[ "uRepeatOverlay" ].value.set(6, 6);

    // Terrain Material
    var material = new THREE.ShaderMaterial({
        uniforms:uniformsTerrain,
        vertexShader:terrainShader.vertexShader,
        fragmentShader:terrainShader.fragmentShader,
        lights:true,
        fog:true
    });

    // Load Tile
    var loader = new THREE.JSONLoader();
    loader.load('models/hextile.js', function(g) {
      //g.computeFaceNormals();
      //g.computeVertexNormals();
        g.computeTangents();
        g.materials[0] = material;

        tile = new THREE.Mesh(g, new THREE.MeshFaceMaterial());
        scene.add(tile);
    });

Hipótese

Atualmente estou lidando com três possibilidades de por que isso pode estar dando errado:

  1. O mapa UV não se aplica ao meu mapa de deslocamento.
  2. Fiz o mapa de deslocamento incorretamente.
  3. Perdi uma etapa crucial no processo que bloquearia o deslocamento apenas para Z.

E, claro, a opção secreta nº 4, que não é nenhuma das opções acima e eu apenas realmente não tenho ideia do que estou fazendo.Ou qualquer mistura dos acima mencionados.

Exemplo ao vivo

Você pode ver um exemplo ao vivo aqui.

Se alguém com mais conhecimento no assunto pudesse me orientar ficaria muito grato!

Editar 1:Como sugestão, comentei computeFaceNormals() e computeVertexNormals().Embora tenha feito uma ligeira melhoria, a malha ainda está distorcida.

Foi útil?

Solução

No material do seu terreno, defina wireframe = true, e você poderá ver o que está acontecendo.

Seu código e texturas estão basicamente bons.O problema ocorre quando você calcula normais de vértice na função de retorno de chamada do carregador.

As normais do vértice calculadas para o anel externo da sua geometria apontam um pouco para fora.Isto é mais provável porque em computeVertexNormals() eles são calculados pela média das normais de face de cada face vizinha, e as normais de face dos "lados" do seu modelo (a parte preta) são calculadas em média no cálculo normal do vértice para os vértices que compõem o anel externo do "cap ".

Como resultado, o anel externo da “tampa” se expande para fora sob o mapa de deslocamento.

EDITAR:Com certeza, direto do seu modelo, os vértices normais do anel externo apontam para fora.As normais dos vértices dos anéis internos são todas paralelas.Talvez o Blender esteja usando a mesma lógica para gerar normais de vértices que computeVertexNormals() faz.

vertex normals

Outras dicas

O problema é como o seu objeto é construído porque o deslocamento ocorre ao longo do vetor normal.

o código está aqui.

https://github.com/mrdoob/três.js/blob/master/examples/js/ShaderTerrain.js#L348-350

"vec3 dv = texture2D( tDisplacement, uvBase ).xyz;",

Isso pega o vetor RGB da textura de deslocamento.

"float df = uDisplacementScale * dv.x + uDisplacementBias;",

isso leva apenas o valor vermelho do vetor porque uDisplacementScale é normalmente 1,0 e uDisplacementBias é 0,0.

"vec3 displacedPosition = normal * df + position;",

Isso desloca a posição ao longo do vetor normal.

então para resolver você atualiza os normais ou o shader.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top