Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 解析THREE.json json网格格式法线错误_Javascript_Three.js_Webgl_Deferred Rendering - Fatal编程技术网

Javascript 解析THREE.json json网格格式法线错误

Javascript 解析THREE.json json网格格式法线错误,javascript,three.js,webgl,deferred-rendering,Javascript,Three.js,Webgl,Deferred Rendering,编辑:Demo finally online:使用下拉菜单切换到环面模型以查看问题的实况。注意:需要Webgl MRT扩展 我在WebGL中开发自己的延迟渲染引擎已经有一段时间了,现在我已经有了一个使用GBuffer和MRT扩展的工作原型,可以非常令人满意地渲染一些茶壶。这是从零开始开发的,主要是为了让我在不使用任何框架的情况下正确地学习WebGL,并理解延迟渲染。对于任何感兴趣的人-源代码位于github上: 我已经厌倦了只看茶壶,并尝试为三个JSON格式的模型实现一个加载器。我已经移植(复制

编辑:Demo finally online:使用下拉菜单切换到环面模型以查看问题的实况。注意:需要Webgl MRT扩展

我在WebGL中开发自己的延迟渲染引擎已经有一段时间了,现在我已经有了一个使用GBuffer和MRT扩展的工作原型,可以非常令人满意地渲染一些茶壶。这是从零开始开发的,主要是为了让我在不使用任何框架的情况下正确地学习WebGL,并理解延迟渲染。对于任何感兴趣的人-源代码位于github上:

我已经厌倦了只看茶壶,并尝试为三个JSON格式的模型实现一个加载器。我已经移植(复制)了加载程序的主要部分,我可以让网格显示正确的顶点和索引缓冲区,这很好,但法线总是扭曲的。我选择只支持带有顶点UV和顶点法线以及单个材质的索引几何体(最终这应该是基于PBR的),因此我忽略了JSON中的任何其他内容,只将我支持的内容直接写入Float32Array(等等)。下面是我的导入代码,加上我看到的奇怪法线的截图

  parseThreeJSModel: (data) =>

    isBitSet = (value, position) ->
      return value & ( 1 << position )

    vertices = data.vertices
    uvs = data.uvs
    indices = []
    normals = data.normals

    vertexNormals = []
    vertexUvs = []
    vertexPositions = []

    @vertexPositionBuffer = new DFIR.Buffer( new Float32Array( data.vertices ), 3, gl.STATIC_DRAW )
    @vertexTextureCoordBuffer = new DFIR.Buffer( new Float32Array( data.uvs[0] ), 2, gl.STATIC_DRAW )

    numUvLayers = data.uvs.length
    faces = data.faces

    zLength = faces.length
    offset = 0

    while offset < zLength
      type = faces[offset++]
      isQuad              = isBitSet( type, 0 )
      hasMaterial         = isBitSet( type, 1 )
      hasFaceVertexUv     = isBitSet( type, 3 )
      hasFaceNormal       = isBitSet( type, 4 )
      hasFaceVertexNormal = isBitSet( type, 5 )
      hasFaceColor       = isBitSet( type, 6 )
      hasFaceVertexColor  = isBitSet( type, 7 )

      if isQuad
        indices.push faces[ offset ]
        indices.push faces[ offset + 1 ]
        indices.push faces[ offset + 3 ]
        indices.push faces[ offset + 1 ]
        indices.push faces[ offset + 2 ]
        indices.push faces[ offset + 3 ]
        offset += 4

        if hasMaterial
          offset++

        if hasFaceVertexUv
          for i in [0 ... numUvLayers] by 1
            uvLayer = data.uvs[i]
            for j in [0 ... 4] by 1
              uvIndex = faces[offset++]
              u = uvLayer[ uvIndex * 2 ]
              v = uvLayer[ uvIndex * 2 + 1 ]

              if j isnt 2 
                vertexUvs.push u
                vertexUvs.push v
              if j isnt 0
                vertexUvs.push u
                vertexUvs.push v

        if hasFaceNormal
          offset++

        if hasFaceVertexNormal
          for i in [0 ... 4] by 1
              normalIndex = faces[ offset++ ] * 3
              normal = [ normalIndex++, normalIndex++, normalIndex ] 
              if i isnt 2
                vertexNormals.push normals[normal[0]]
                vertexNormals.push normals[normal[1]]
                vertexNormals.push normals[normal[2]]
              if i isnt 0
                vertexNormals.push normals[normal[0]]
                vertexNormals.push normals[normal[1]]
                vertexNormals.push normals[normal[2]]

        if hasFaceColor
          offset++

        if hasFaceVertexColor
          offset += 4
      else
        indices.push faces[offset++]
        indices.push faces[offset++]
        indices.push faces[offset++]

        if hasMaterial
          offset++
        if hasFaceVertexUv
          for i in [0 ... numUvLayers] by 1
            uvLayer = data.uvs[i]
            for j in [0 ... 3] by 1
              uvIndex = faces[offset++]
              u = uvLayer[ uvIndex * 2 ]
              v = uvLayer[ uvIndex * 2 + 1 ]
              if j isnt 2 
                vertexUvs.push u
                vertexUvs.push v
              if j isnt 0
                vertexUvs.push u
                vertexUvs.push v

        if hasFaceNormal
          offset++

        if hasFaceVertexNormal
          for i in [0 ... 3] by 1
            normalIndex = faces[ offset++ ] * 3

            vertexNormals.push normals[normalIndex++]
            vertexNormals.push normals[normalIndex++]
            vertexNormals.push normals[normalIndex]

        if hasFaceColor
          offset++

        if hasFaceVertexColor
          offset +=3

    @vertexNormalBuffer = new DFIR.Buffer( new Float32Array( vertexNormals ), 3, gl.STATIC_DRAW )
    @vertexIndexBuffer = new DFIR.Buffer( new Uint16Array( indices ), 1, gl.STATIC_DRAW, gl.ELEMENT_ARRAY_BUFFER )
    @loaded=true
jsmodel:(数据)=>
isBitSet=(值,位置)->

返回值&(1它不是问题的直接解决方案,但可能会有所帮助

如果您有像上面示例中的框一样的基本形状,您也可以同时使用
THREE.FlatShading
和跳过设置法线。在某些情况下可能更容易:

var material = new THREE.???Material({ shading: THREE.FlatShading });

不确定您在Three.Face3到缓冲区之间的转换是否正确。这是我自己的Three Json解析器,我使用它从blender加载动画蒙皮网格,这可能会对您有所帮助。同样,只支持部分功能。它返回索引缓冲区,以便与
.drawElements
而不是
.drawArray一起使用s

function parsePackedArrayHelper(outArray, index, dataArray, componentSize){
    for (var c = 0; c<componentSize; c++){
        outArray.push(dataArray[index*componentSize + c]);
    }
}

function parseThreeJson(geometry){
    if (isString(geometry)){
        geometry = JSON.parse(geometry);
    }

    var faces = geometry["faces"];
    faces = convertQuadToTrig(faces); // can use the triangulate modifer in blender to skip this 
    // and others data etc... 

    var seenVertices = new Map();
    var currentIndex = 0;
    var maxIndex = 0;

    var c = 0; // current index into the .faces array
    while (c < faces.length){
        var bitInfo = faces[c];
        var hasMaterials = (bitInfo &(1<<1)) !== 0;
        var hasVertexUvs = (bitInfo &(1<<3)) !== 0;
        var hasVertexNormals = (bitInfo &(1<<5)) !== 0;
        var faceIndex = c+1;

        c += (
            4 + //1 for the bitflag and 3 for vertex positions
            (hasMaterials? 1: 0) +
            (hasVertexUvs? 3: 0) +
            (hasVertexNormals ? 3: 0)
        );

        for (var v = 0;v<3;v++){
            var s = 0; 
            var vertIndex = faces[faceIndex+v];
            var uvIndex = -1;
            var normalIndex = -1;
            var materialIndex = -1;
            if (hasMaterials){
                s += 1;
                materialIndex = faces[faceIndex+3];
            }
            if (hasVertexUvs){
                s += 3;
                uvIndex = faces[faceIndex+s+v];
            }
            if (hasVertexNormals){
                s += 3;
                normalIndex = faces[faceIndex+s+v];
            }

            var hash = ""+vertIndex+","+uvIndex+","+normalIndex;
            if (seenVertices.has(hash)){
                indices[currentIndex++] = seenVertices.get(hash);
            } else {
                seenVertices.set(hash, maxIndex);
                indices[currentIndex++] = maxIndex++;
                parsePackedArrayHelper(verticesOut, vertIndex, verticesData, 3);
                if (boneInfluences > 1){
                    // skinning data skipped
                }
                if (hasVertexUvs){
                    parsePackedArrayHelper(uvsOut, uvIndex, uvsData[0], 2);

                    // flip uv vertically; may or may not be needed
                    var lastV = uvsOut[uvsOut.length-1];
                    uvsOut[uvsOut.length-1] = 1.0 - lastV;

                }
                if (hasVertexNormals){
                    parsePackedArrayHelper(normalsOut, normalIndex, normalsData, 3);
                }

                if (hasMaterials){
                    materialIndexOut.push(materialIndex);
                }
            }
        }
    }
}
函数parsePackedArrayHelper(outArray、index、dataArray、componentSize){

对于(var c=0;cHave您是否首先确认问题在于json网格导入器,而不是您的g缓冲区或世界法线的渲染?您是否在blender中使用平滑或平面着色?我非常确定问题不在于我的gbuffer实现,正如我所说,我可以使用webgl教程网站和很好(我会试着在问题上附上一个截图).至于法线,我只是直接从混合器中导出默认立方体,因此法线应该是平坦的,而不是平滑的。我也尝试过导出suzanne,结果类似,网格和索引都很好,法线到处都是。感谢这一点-看起来很像我需要的,尽管我认为我真正需要的是e parsePackedArrayHelper()方法-你介意发布吗?谢谢!哦,抱歉-顶部没有看到!我会尝试一下,但我一定没有很好地解释它,因为我把索引缓冲区弄得一团糟(也就是说,法线看起来确实好一点)。将继续尝试,谢谢!谢谢-我实际上并没有使用three.js,事实上,这是我自己的引擎。我只是尝试使用three.js模型格式,而不是编写自己的,这在当时似乎是个好主意!@bharling解决您的问题有什么运气吗?还没有,不幸的是-我目前正在研究引擎的其他方面(并且忽略了它只能加载茶壶的事实:),它们现在看起来很漂亮。)现在考虑尝试使用.obj加载程序,这里有一些普通的webgl示例