Primitive篇(PrimitivePoint 點(diǎn))

我們有時候繪制對象時阿纤,需要自己靈活控制渲染對象的頂點(diǎn)和顏色(紋理)甚负,雖然cesium已經(jīng)給我們提供了很多現(xiàn)成的基礎(chǔ)圖元否淤,但還是不夠靈活,今天我們就從三維基礎(chǔ)繪制原理來學(xué)習(xí)下在cesium中沃饶,如何繪制基本圖元:點(diǎn)母廷、線、三角面片以及紋理貼圖糊肤。如果你熟悉三維渲染底層琴昆,那么對點(diǎn)、線馆揉、三角面片业舍、紋理這些概念一定非常了解,應(yīng)為它們是組成三維渲染對象的基礎(chǔ)把介。任何三維對象幾何屬性都是由復(fù)雜的點(diǎn)勤讽、線、三角面片這三種基本類型組成拗踢,然后加上紋理貼圖就有了逼真的外觀脚牍。那么今天我們就先來了解下如何用primitive接口繪制自定義點(diǎn)。

1 查看官方API

首先我們看primitive的官方api巢墅,可以看到primitive兩個重要對象:geometry和appearance:


image.png
1.1 查看geometry的官方api:
image.png

這里的PrimitiveType就是指定該幾何對象圖元類型是那種诸狭,一共有以下幾種:


image.png
1.2 查看appearance的官方api.

這里我們需要關(guān)注圖中標(biāo)出的三個屬性:
material:設(shè)置材質(zhì)
vertexShaderSource:設(shè)置頂點(diǎn)著色器代碼
fragmentShaderSource:設(shè)置片源著色器代碼。

image.png

2 繪制點(diǎn)

頂點(diǎn)著色器和片源著色器都是使用GLSL語言編寫君纫,接觸webgl的童鞋對此一定非常了解驯遇,我對此還沒入門,無法說出個所以然來蓄髓。
知道繪制primitive的要點(diǎn)后叉庐,下面就是具體實(shí)現(xiàn),直接上代碼:

var viewer = new Cesium.Viewer('cesiumContainer');

//封裝PrimitivePoints
var PrimitivePoints=(
    function () {
        var vertexShader;
        var fragmentShader;
        var geometry;
        var appearance;
        var viewer;
        function _(options) {
            viewer = options.viewer;
            vertexShader = getVS();
            fragmentShader = getFS();
            if (options.Cartesians && options.Cartesians.length >= 2) {
                var postionsTemp = [];
                var colorsTemp = [];
                var indicesTesm = [];
                if (options.Colors && options.Colors.length === options.Cartesians.length * 4) {
                    for (var i = 0; i < options.Cartesians.length; i++) {
                        postionsTemp.push(options.Cartesians[i].x);
                        postionsTemp.push(options.Cartesians[i].y);
                        postionsTemp.push(options.Cartesians[i].z);
                    }
                    colorsTemp = options.Colors;
                } else {
                    for (var i = 0; i < options.Cartesians.length; i++) {
                        postionsTemp.push(options.Cartesians[i].x);
                        postionsTemp.push(options.Cartesians[i].y);
                        postionsTemp.push(options.Cartesians[i].z);
                        //
                        colorsTemp.push(0.0);
                        colorsTemp.push(0.0);
                        colorsTemp.push(1.0);
                        colorsTemp.push(1.0);
                    }
                }

                //頂點(diǎn)索引(坐標(biāo)點(diǎn)下標(biāo)的連接順序)
                for (var i = 0; i < options.Cartesians.length; i++) {
                    indicesTesm.push(i);
                }
                this.positionArr = new Float64Array(postionsTemp);
                this.colorArr = new Float32Array(colorsTemp);
                this.indiceArr = new Uint16Array(indicesTesm);

            } else {
                var p1 = Cesium.Cartesian3.fromDegrees(0, 0, -10);
                var p2 = Cesium.Cartesian3.fromDegrees(0, 0.001, -10);
                this.positionArr = new Float64Array([
                    p1.x, p1.y, p1.z,
                    p2.x, p2.y, p2.z
                ]);
                this.colorArr = new Float32Array([
                         0.0, 0.0, 1.0, 1.0,
                         0.0, 0.0, 1.0, 1.0
                ]);
                this.indiceArr = new Uint16Array([0, 1]);
            }
           
            geometry = CreateGeometry(this.positionArr, this.colorArr, this.indiceArr);
            appearance = CreateAppearence(fragmentShader, vertexShader);

            this.primitive = viewer.scene.primitives.add(new Cesium.Primitive({
                geometryInstances: new Cesium.GeometryInstance({
                    geometry: geometry
                }),
                appearance: appearance,
                asynchronous: false
            }));
        }

        function CreateGeometry(positions, colors, indices) {
            return new Cesium.Geometry({
                attributes: {
                    position: new Cesium.GeometryAttribute({
                        componentDatatype: Cesium.ComponentDatatype.DOUBLE,
                        componentsPerAttribute: 3,
                        values: positions
                    }),
                    color: new Cesium.GeometryAttribute({
                        componentDatatype: Cesium.ComponentDatatype.FLOAT,
                        componentsPerAttribute: 4,
                        values: colors
                    })
                },
                indices: indices,
                primitiveType: Cesium.PrimitiveType.POINTS,
                boundingSphere: Cesium.BoundingSphere.fromVertices(positions)
            });
        }

        function CreateAppearence(fs, vs) {
            return new Cesium.Appearance({        
                renderState: {
                    blending: Cesium.BlendingState.PRE_MULTIPLIED_ALPHA_BLEND, 
                    depthTest: { enabled: true }, 
                    depthMask: true
                },
                fragmentShaderSource: fs,
                vertexShaderSource: vs
            });
        }

        function getVS() {
            return "attribute vec3 position3DHigh;\
            attribute vec3 position3DLow;\
            attribute vec4 color;\
            varying vec4 v_color;\
            attribute float batchId;\
            void main()\
            {\
                vec4 p = czm_computePosition();\
                v_color =color;\
                p = czm_modelViewProjectionRelativeToEye * p;\
                gl_Position = p;\
                gl_PointSize=8.0;\
            }\
            ";
        }
        function getFS() {
            return "varying vec4 v_color;\
            void main()\
            {\
                 float d = distance(gl_PointCoord, vec2(0.5,0.5));\
                 if(d < 0.5){\
                    gl_FragColor = v_color;\
                 }else{\
                    discard;\
                 }\
            }\
            ";
        }
       
        _.prototype.remove = function () {
            if (this.primitive != null) {
                viewer.scene.primitives.remove(this.primitive);
                this.primitive = null;
            }
        }
        _.prototype.updateCartesianPosition = function (cartesians) {
            if (this.primitive != null) {
                viewer.scene.primitives.remove(this.primitive);
                if (cartesians && cartesians.length < 2) { return; }
            
                var postionsTemp = [];
                var colorsTemp = [];
                var indicesTesm = [];
                for (var i = 0; i < cartesians.length; i++) {
                    postionsTemp.push(cartesians[i].x);
                    postionsTemp.push(cartesians[i].y);
                    postionsTemp.push(cartesians[i].z);
                     
                    colorsTemp.push(0.0);
                    colorsTemp.push(0.0);
                    colorsTemp.push(1.0);
                    colorsTemp.push(1.0);
                }
                for (var i = 0; i < cartesians.length; i++) {
                    indicesTesm.push(i);
                }
                this.positionArr = new Float64Array(postionsTemp);
                this.colorArr = new Float32Array(colorsTemp);
                this.indiceArr = new Uint16Array(indicesTesm);

                geometry = CreateGeometry(this.positionArr, this.colorArr, this.indiceArr);
                appearance = CreateAppearence(fragmentShader, vertexShader);

                this.primitive = viewer.scene.primitives.add(new Cesium.Primitive({
                    geometryInstances: new Cesium.GeometryInstance({
                        geometry: geometry
                    }),
                    appearance: appearance,
                    asynchronous: false
                }));
            } else { return;}
        }
        _.prototype.updateCartesianPositionColor = function (cartesians, colors) {
            if (colors.length === cartesians.length * 4) { } else { return; }
            if (this.primitive != null) {
                viewer.scene.primitives.remove(this.primitive);
                if (cartesians && cartesians.length < 2) { return; }
                
                var postionsTemp = [];
                var indicesTesm = [];
                
                for (var i = 0; i < cartesians.length; i++) {
                    postionsTemp.push(cartesians[i].x);
                    postionsTemp.push(cartesians[i].y);
                    postionsTemp.push(cartesians[i].z);
                }
                for (var i = 0; i < cartesians.length; i++) {
                    indicesTesm.push(i);
                }
                this.positionArr = new Float64Array(postionsTemp);
                this.colorArr = new Float32Array(colors);
                this.indiceArr = new Uint16Array(indicesTesm);

                geometry = CreateGeometry(this.positionArr, this.colorArr, this.indiceArr);
                appearance = CreateAppearence(fragmentShader, vertexShader);
                
                this.primitive = viewer.scene.primitives.add(new Cesium.Primitive({
                    geometryInstances: new Cesium.GeometryInstance({
                        geometry: geometry
                    }),
                    appearance: appearance,
                    asynchronous: false
                }));
            } else { return; }
        }
        return _;
    })();

//定義要顯示的點(diǎn)坐標(biāo)(經(jīng)緯度)
var positions = new Float64Array([
  110.2, 20.6,
  110.2, 21.9,
  111, 23
]);
var cartesian3Positions = Cesium.Cartesian3.fromDegreesArray(positions);

//定義要顯示的點(diǎn)的顏色(4個元素定義一個點(diǎn)的顏色(紅綠藍(lán)透明度))
var Colors = new Float64Array([
    1.0,0.0,0.0,1.0,
    0.0,1.0,0.0,1.0,
    0.0,0.0,1.0,1.0
]);

var p = new PrimitivePoints({
    viewer:viewer,
    Cartesians:cartesian3Positions,
    Colors:Colors
});
image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末会喝,一起剝皮案震驚了整個濱河市陡叠,隨后出現(xiàn)的幾起案子玩郊,更是在濱河造成了極大的恐慌,老刑警劉巖枉阵,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件译红,死亡現(xiàn)場離奇詭異,居然都是意外死亡兴溜,警方通過查閱死者的電腦和手機(jī)侦厚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拙徽,“玉大人刨沦,你說我怎么就攤上這事≌剩” “怎么了已卷?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長淳蔼。 經(jīng)常有香客問我,道長裁眯,這世上最難降的妖魔是什么鹉梨? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮穿稳,結(jié)果婚禮上存皂,老公的妹妹穿的比我還像新娘。我一直安慰自己逢艘,他們只是感情好旦袋,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著它改,像睡著了一般疤孕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上央拖,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天祭阀,我揣著相機(jī)與錄音,去河邊找鬼鲜戒。 笑死专控,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的遏餐。 我是一名探鬼主播伦腐,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼失都!你這毒婦竟也來了柏蘑?” 一聲冷哼從身側(cè)響起颖系,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎辩越,沒想到半個月后嘁扼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡黔攒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年趁啸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片督惰。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡不傅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赏胚,到底是詐尸還是另有隱情访娶,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布觉阅,位于F島的核電站崖疤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏典勇。R本人自食惡果不足惜劫哼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望割笙。 院中可真熱鬧权烧,春花似錦、人聲如沸伤溉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乱顾。三九已至板祝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間糯耍,已是汗流浹背扔字。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留温技,地道東北人革为。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像舵鳞,于是被迫代替她去往敵國和親震檩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容