日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Three.js的绘制流程(三)----地形

發(fā)布時間:2023/12/20 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Three.js的绘制流程(三)----地形 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨角獸企業(yè)重金招聘Python工程師標準>>>

最簡單的地形是單一的平面, 這個通過

var geo = new THREE.PlaneGeometry(2, 2, 256, 256) 幾何體構(gòu)建, 可以設定平面的切分塊的數(shù)量。

var pmesh = new THREE.Mesh(geo, material);

可以為平面提供紋理, 從而是地面看起來更真實一些,而紋理坐標在geo中已經(jīng)自動設定好了。 因此只需要寫材質(zhì)就可以了。

這里使用ShaderMaterial 用于材質(zhì)。

頂點shader:

varying vec2 vUV; //從定點shader 傳遞到 片段shader的紋理坐標

void main()

{

? ? ? vUV = uv; //uv 是默認存在的頂點屬性, 用于做紋理坐標

? ? ? gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1);// projectionMatrix 默認存在的投影矩陣 modelViewMatrix默認模型視圖矩陣 position定點坐標?
}

?

片段shader:

uniform sampler2D texture_grass;//紋理

varying vec2 vUV;

void main()

{

? ? ?gl_FragColor = texture2D(texture_grass, vUV);
}

材質(zhì)則是:

var mat = new THREE.ShaderMaterial({

? ? ?uniforms:{

? ? ? ? ? texture_grass:{type:'t', value:0, ?texture:TRHEE.ImageUtils.loadTexture("texture_grass.png")},//類型紋理, 紋理編號0, 加載圖片數(shù)據(jù)?

? ? },

? ? ?attributes:{},

? ? ?vertexShader:text,

? ? ?fragmentShader:text,

});

var pmesh = new THREE.Mesh(geo, mat);

?

這樣就得到一個添加了紋理的平面, 平面在x,y 平面上, 平面的正方向指向z正向, 可以調(diào)整平面x軸逆時針旋轉(zhuǎn)90度, 得到x,z 方向的平面。

?

現(xiàn)在我們期望能夠調(diào)整地面的高度, 采用的方式是鼠標點擊屏幕位置, 計算實際的地面的位置, 接著調(diào)整地面上該點附近的所有定點的高度。

調(diào)整高度有兩種方式, 一是調(diào)整geo幾何體中的vertices 中的y值, 或者在修改shader程序 增加一個頂點屬性, displacement 用于記錄所有頂點的高度,這樣只需要修改這一個數(shù)據(jù)就可以了,而不需要修改整個定點數(shù)組。

頂點shader調(diào)整:

attribute float displacement;

varying vec2 vUV;

void main()

{

? ? ? ?vUV = uv;

? ? ? ?gl_Position = projectionMatrix * modelViewMatrix * vec4(position.xy, ?displacement, 1);
}

材質(zhì)調(diào)整:

var mat = new THREE.ShaderMaterial({

? ? ? //其它部分相同

? ? ? ?attributes:{

? ? ?displacement:{type:'f', ?value:[]},

? ?}

});

需要根據(jù)平面頂點個數(shù) 來初始化displacement值為0

for(var i = 0; i < geo.vertices.length; i++)

? ? ? mat.attributes.displacement.value.push(0);

?

因為需要動態(tài)調(diào)整displacement的值 所以需要設定geo是動態(tài)更新的

geo.dynamic = true;

?

這樣現(xiàn)在仍只是看到一個平面;接下來需要設定鼠標點擊的時間處理函數(shù)。

var projector = new THREE.Projector(); //計算從屏幕坐標到 世界坐標的工具

?

renderer.domElement.onmousedown = function(e){

? ? ?var mx = e.offsetX;

? ? ?var my = e.offsetY;

? ? ?//計算相機近平面上的坐標

? ? ? mx = 2*mx/SCREEN_WIDTH-1;

? ? ?my = 1 - 2*my/SCREEN_HEIGHT;

? ? var vec = new THREE.Vector3(mx, my, 0);//只有 x y 坐標有意義

? ? ?var ray = project.pickingRay(vec, camera);//計算從相機發(fā)出的穿過近平面上mx my 點的射線

? ? var intersects = ray.intersectObject(pmesh); //計算射線和 平面的所有交點 0 或者 1個

? ? ?if(intersects.length > 0)

? ? {

? ? ? ? ? ? //存在交點

? ? ? ? ? ?updateDisplacement(intersects[0].point); //調(diào)整該點附近頂點的高度。

? ? }

}

?

function updateDisplacement(point)

{

//平面方位 -1, 1 ?-1, 1 x軸切分256份, WIDTH= 257, ?y軸切分256份 , HEIGHT=257

//計算交點附近 0.1為邊長的矩形框的上下左右范圍, 接著計算geo中相應的定點的行和列范圍。

//調(diào)整所有頂點的高度, 設定材質(zhì)中的 mat.attributes.displacement.needsUpdate = true; ?設定displacement需要更新

?

var radius = 0.05; var left = point.x-radius; var right = point.x+radius; var bottom = point.z-radius; var up = point.z + radius; var rowGrid = 2/(HEIGHT-1); var colGrid = 2/(WIDTH-1); var rowBegin = ~~Math.max((bottom+1)/rowGrid, 0); var rowEnd = ~~Math.min((up+1)/rowGrid, HEIGHT); var colBegin = ~~Math.max((left+1)/colGrid, 0); var colEnd = ~~Math.min((right+1)/colGrid, WIDTH); for(var i = rowBegin; i <= rowEnd; i++) { for(var j = colBegin; j <= colEnd; j++) { var num = ~~(i*WIDTH+j); //console.log(num); pmesh.displacement.value[num] += 0.05; //console.log("new", pmesh.displacement, pmesh.displacement.needsUpdate); } } pmesh.displacement.needsUpdate = true;


}

?

結(jié)束:

? ?通過設定幾何體可以動態(tài)更新, ?設定 材質(zhì)中的屬性需要更新, 則實現(xiàn)了調(diào)整displacement的目的。

轉(zhuǎn)載于:https://my.oschina.net/u/186074/blog/376765

總結(jié)

以上是生活随笔為你收集整理的Three.js的绘制流程(三)----地形的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。