2017-02-08 8 views
1

Я использую этот код, чтобы рисовать треугольники цезия:Цезий примитивы (треугольники) затенения

var mypositions = Cesium.Cartesian3.fromDegreesArrayHeights(triangles); 

// unroll 'mypositions' into a flat array here 
var numPositions = mypositions.length; 

var pos = new Float64Array(numPositions * 3); 
var normals = new Float32Array(numPositions * 3); 
for (var i = 0; i < numPositions; ++i) { 
    pos[i * 3] = mypositions[i].x; 
    pos[i * 3 + 1] = mypositions[i].y; 
    pos[i * 3 + 2] = mypositions[i].z; 
    normals[i * 3] = 0.0; 
    normals[i * 3 + 1] = 0; 
    normals[i * 3 + 2] = 1.0; 
} 

console.log(normals) 
var geometry = new Cesium.Geometry({ 
vertexFormat : Cesium.VertexFormat.ALL, 
    attributes: { 
    position: new Cesium.GeometryAttribute({ 
     componentDatatype: Cesium.ComponentDatatype.DOUBLE, // not FLOAT 
     componentsPerAttribute: 3, 
     values: pos 
    }), 
    normal: new Cesium.GeometryAttribute({ 
     componentDatatype: Cesium.ComponentDatatype.FLOAT, 
     componentsPerAttribute: 3, 
     values: normals 
    }) 

    }, 

    // Don't need the following line if no vertices are shared. 
// indices: new Uint32Array([0, 1, 2, 3, 4, 5]), 
    primitiveType: Cesium.PrimitiveType.TRIANGLES, 
    boundingSphere: Cesium.BoundingSphere.fromVertices(pos) 
}); 

var myInstance = new Cesium.GeometryInstance({ 
    geometry: geometry, 
    attributes: { 
    color: new Cesium.ColorGeometryInstanceAttribute(0.0039215697906911, 
      0.7333329916000366, 
      0, 
      1) 
    }, 
    show: new Cesium.ShowGeometryInstanceAttribute(true) 
}); 

var TIN = viewer.scene.primitives.add(new Cesium.Primitive({ 
    geometryInstances: [myInstance], 
    asynchronous: false, 
    appearance: new Cesium.PerInstanceColorAppearance({ 
    closed: true, 
    translucent: false, 
    flat: false 
    //, 
    //vertexShaderSource: "", 
    //fragmentShaderSource: "" 

    }) 
    })); 

Это то, что я получаю: enter image description here

Я хотел бы включить затенение, поэтому результат должен быть как показано на рисунке ниже: enter image description here

Я попытался написать Vertex и Fragment GLSL shader, но безуспешно. Я не знаком с GLSL, и я получаю компиляционную ошибку. Есть ли другой способ создания такого затенения?

Спасибо!

ответ

2

Независимо от того, что вы не разместили свои шейдеры GLSL или не получили на работу, ваша проблема (после того, как вы в конечном итоге выясните материал GLSL) заключается в том, что вы устанавливаете все нормали для обозначения в + Z вместо того, чтобы быть нормальным для каждого треугольника, как второй скриншот ваших шоу.

var normals = new Float32Array(numPositions * 3); 
for (var i = 0; i < numPositions; ++i) { 
    pos[i * 3] = mypositions[i].x; 
    pos[i * 3 + 1] = mypositions[i].y; 
    pos[i * 3 + 2] = mypositions[i].z; 
    normals[i * 3] = 0.0; 
    normals[i * 3 + 1] = 0; 
    normals[i * 3 + 2] = 1.0; 
} 

Что вам нужно сделать, вместо того, чтобы это установить позиции, а затем для нормалей, действуют на наборы из 3 вершин (треугольник), а не отдельных вершин. Таким образом, вы можете рассчитать нормальную поверхность. Это один из многих объяснений того, как сделать это:

https://math.stackexchange.com/questions/305642/how-to-find-surface-normal-of-a-triangle

Я не знаком с цезием, но я бы себе не было бы какой-то «по умолчанию» шейдер, сделал основное освещение. Если нет, то основой для простого освещения, как это называется Lambertian reflectance. Ваш вершинный шейдер выводит цвет, который вычисляется как dot(N, L), где N - нормали вашей вершины, а L - вектор от этой вершины к вашему источнику света (или просто отрицательный от направления вашего света, если это направленная/окружающая среда/солнце/и т.п свет). Фрагмент-шейдер просто удалит этот цвет.

+0

Спасибо! Это хорошее наблюдение. Сначала исправит нормали. – VNenad

+1

Вы были правы, это была проблема нормалей. Теперь я получаю хорошую визуализацию с основным оттенком. Нормали могут быть рассчитаны с использованием: 'Cesium.GeometryPipeline.computeNormal (geometry);' с включенными индексами. – VNenad