Cesium 纹理贴图

本文探讨了在Cesium中遇到的纹理贴图问题,详细描述了如何使用纹理坐标(2,2)创建2X2纹理贴图时出现2X1效果的原因。分析发现,Cesium源码中的纹理压缩机制导致T纹理值被压缩,通过将`compressVertices`设置为`false`成功解决了问题。" 139197279,11033297,Hive小文件优化全攻略,"['Hive', '大数据', '数据仓库', 'Hadoop', 'SQL']

根据纹理坐标(2,2)实现2X2的纹理贴图,实现如下效果:

首次测试代码如下:

    const material = Material.fromType(Material.ImageType);
    material.uniforms.image = image;
    material.shaderSource=`
    uniform vec4 color_2;
    uniform vec2 repeat_1;
    uniform sampler2D image_0;
    czm_material czm_getMaterial(czm_materialInput materialInput)
    {
      czm_material material = czm_getDefaultMaterial(materialInput);
      vec2 st=materialInput.st;
      material.diffuse = czm_gammaCorrect(texture2D(image_0, fract(st))).rgb;
      material.alpha =  texture2D(image_0, fract(st)).a;
      return material;
    }
    `
    let positions = new Float64Array([
      0.0, 0.0, 0.0,
      5000.0, 0.0, 0.0,
      5000.0, 5000.0, 0.0,
      0.0, 5000.0, 0.0
    ]);
    /*纹理坐标*/
    let uv=[
      0.0, 0.0,
      2.0,0.0,
      2.0,2.0,
      0.0,2.0,
    ];
    /*发现线*/
    let normal=[
      0.0, 0.0,1.0,
      0.0, 0.0,1.0,
      0.0, 0.0,1.0,
      0.0, 0.0,1.0,
    ];
    let geometry = new Geometry({
      attributes : {
        position : new GeometryAttribute({
          componentDatatype : ComponentDatatype.DOUBLE,
          componentsPerAttribute : 3,
          values : positions
        }),
        st: new GeometryAttribute({
          componentDatatype: ComponentDatatype.FLOAT,//数据类型
          componentsPerAttribute:2,//定义几个为一组
          values: uv//坐标值
        }),
        normal:new GeometryAttribute({
          componentDatatype : ComponentDatatype.FLOAT,
          componentsPerAttribute : 3,
          values : normal
        })
      },
      indices : new Uint16Array([0, 1, 2,0,2,3]),
      primitiveType : PrimitiveType.TRIANGLES,
      boundingSphere : BoundingSphere.fromVertices(positions)
    });

    let rectangleInstance = new GeometryInstance({
      modelMatrix : Matrix4.multiplyByTranslation(Transforms.eastNorthUpToFixedFrame(
        this.position), new Cartesian3(0.0, 0.0, 100), new Matrix4()),
      geometry : geometry,
      id : 'rectangle',
    });
    let appr=new MaterialAppearance({
      material : material
    });
    let primitive=scene.primitives.add(new Primitive({
      asynchronous: false,
      geometryInstances : rectangleInstance,
      appearance : appr,
    }));

 实现效果变成2X1的效果图,而不是2X2的效果图

 出现这种效果原因:

在Cesium源码中Primitive源代码中查看:

 在如下这段代码中发现,执行了代码纹理压缩,而压缩纹理部分是S部分,而T部分是不压缩的,导致T纹理值为1,而S部分正常

function modifyForEncodedNormals(primitive, vertexShaderSource) {
  if (!primitive.compressVertices) {
    return vertexShaderSource;
  }

  var containsNormal =
    vertexShaderSource.search(/attribute\s+vec3\s+normal;/g) !== -1;
  var containsSt = vertexShaderSource.search(/attribute\s+vec2\s+st;/g) !== -1;
  if (!containsNormal && !containsSt) {
    return vertexShaderSource;
  }

  var containsTangent =
    vertexShaderSource.search(/attribute\s+vec3\s+tangent;/g) !== -1;
  var containsBitangent =
    vertexShaderSource.search(/attribute\s+vec3\s+bitangent;/g) !== -1;

  var numComponents = containsSt && containsNormal ? 2.0 : 1.0;
  numComponents += containsTangent || containsBitangent ? 1 : 0;

  var type = numComponents > 1 ? "vec" + numComponents : "float";

  var attributeName = "compressedAttributes";
  var attributeDecl = "attribute " + type + " " + attributeName + ";";

  var globalDecl = "";
  var decode = "";

  if (containsSt) {
    globalDecl += "vec2 st;\n";
    var stComponent = numComponents > 1 ? attributeName + ".x" : attributeName;
    decode +=
      "    st = czm_decompressTextureCoordinates(" + stComponent + ");\n";
  }

  if (containsNormal && containsTangent && containsBitangent) {
    globalDecl += "vec3 normal;\n" + "vec3 tangent;\n" + "vec3 bitangent;\n";
    decode +=
      "    czm_octDecode(" +
      attributeName +
      "." +
      (containsSt ? "yz" : "xy") +
      ", normal, tangent, bitangent);\n";
  } else {
    if (containsNormal) {
      globalDecl += "vec3 normal;\n";
      decode +=
        "    normal = czm_octDecode(" +
        attributeName +
        (numComponents > 1 ? "." + (containsSt ? "y" : "x") : "") +
        ");\n";
    }

    if (containsTangent) {
      globalDecl += "vec3 tangent;\n";
      decode +=
        "    tangent = czm_octDecode(" +
        attributeName +
        "." +
        (containsSt && containsNormal ? "z" : "y") +
        ");\n";
    }

    if (containsBitangent) {
      globalDecl += "vec3 bitangent;\n";
      decode +=
        "    bitangent = czm_octDecode(" +
        attributeName +
        "." +
        (containsSt && containsNormal ? "z" : "y") +
        ");\n";
    }
  }

  var modifiedVS = vertexShaderSource;
  modifiedVS = modifiedVS.replace(/attribute\s+vec3\s+normal;/g, "");
  modifiedVS = modifiedVS.replace(/attribute\s+vec2\s+st;/g, "");
  modifiedVS = modifiedVS.replace(/attribute\s+vec3\s+tangent;/g, "");
  modifiedVS = modifiedVS.replace(/attribute\s+vec3\s+bitangent;/g, "");
  modifiedVS = ShaderSource.replaceMain(modifiedVS, "czm_non_compressed_main");
  var compressedMain =
    "void main() \n" +
    "{ \n" +
    decode +
    "    czm_non_compressed_main(); \n" +
    "}";

  return [attributeDecl, globalDecl, modifiedVS, compressedMain].join("\n");
}

解决问题:

将compressVertices设置为false即可

let primitive=scene.primitives.add(new Primitive({
      asynchronous: false,
      geometryInstances : rectangleInstance,
      appearance : appr,
      compressVertices:false
}));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

生活真难

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值