使用three.js著色器創(chuàng)建地球

使用three.js著色器創(chuàng)建地球首先要知道一下幾個點

1.著色器的介紹

Webgl繪制圖形是基于著色器(shader)的繪圖機制赏廓,著色器提供了靈活且強大的繪制二維或三維圖形的方法彰触,所有Webgl程序必須使用它娇澎。

著色器語言類似于c語言铛纬,當我們寫webgl程序時跳昼,著色器語言以字符串的形式嵌入在javascript語言中碌廓。

2.ShaderMaterial介紹

three.js中的ShaderMaterial可以讓我們自己定制著色器机蔗,直接操作像素闰非。我們只需要理解著色器的基本原理膘格。

使用自定義著色器渲染的材質(zhì)。著色器是用GLSL編寫的在GPU 上運行的小程序 财松。如果需要瘪贱,您可能需要使用自定義著色器:實現(xiàn)不包含在任何內(nèi)置材質(zhì)中的效果將許多對象組合成一個BufferGeometry以提高性能

3.Vertex Shader介紹

作用于每個頂點,通常是處理從世界空間到裁剪空間(屏幕坐標)的坐標轉(zhuǎn)換辆毡,后面緊接的是光柵化菜秦。

4.Fragment Shader介紹

作用于每個屏幕上的片元(這里可近似理解為像素),通常是計算顏色舶掖。

下面是代碼

<!DOCTYPE html>

<html>

<head>

? <meta charset="utf-8">

? <title>My first three.js app</title>

? <style>

? ? body {

? ? ? margin: 0;

? ? }

? </style>

</head>

<body>

? <script src="https://cdn.bootcdn.net/ajax/libs/three.js/r128/three.js"></script>

? <script src="d:/3D/node_modules/@three-ts/orbit-controls/dist/index"></script>

? <script type="module">

? ? const clock = new THREE.Clock();

? ? const scene = new THREE.Scene();

? ? const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

? ? const renderer = new THREE.WebGLRenderer({

? ? ? antialias: true

? ? });

? ? renderer.setPixelRatio(window.devicePixelRatio);

? ? renderer.setSize(window.innerWidth, window.innerHeight);

? ? document.body.appendChild(renderer.domElement);

? ? let AeroSphere = {

? ? ? uniforms: {

? ? ? ? globeTexture: {

? ? ? ? ? value: new THREE.TextureLoader().load('./global.jpg'),

? ? ? ? },

? ? ? ? time: {

? ? ? ? ? value: 0,

? ? ? ? },

? ? ? },

? ? ? vertexShader: [

? ? ? ? 'varying vec2 vUv;',

? ? ? ? 'varying vec3 vertexNormal;',

? ? ? ? 'void main(){',

? ? ? ? 'vUv = uv;',

? ? ? ? 'vertexNormal = normalize(normalMatrix * normal);', //將法線轉(zhuǎn)換到視圖坐標系中

? ? ? ? 'gl_Position ?= projectionMatrix * modelViewMatrix * vec4(position, 1);',// 計算頂點著色器中頂點的位置

? ? ? ? '}',

? ? ? ].join('\n'),

? ? ? fragmentShader: [

? ? ? ? 'uniform sampler2D globeTexture;',

? ? ? ? 'varying vec2 vUv;',

? ? ? ? 'varying vec3 vertexNormal;',

? ? ? ? 'void main(){',

? ? ? ? 'float intensity = 1.05 -dot(vertexNormal,vec3(0.0,0.0,1.0));',

? ? ? ? 'vec3 atmosphere = vec3(0.3 , 0.6 , 1.0) * pow(intensity,1.5);',

? ? ? ? ' gl_FragColor = vec4(atmosphere + texture2D(globeTexture,vUv).xyz,1.0);',

? ? ? ? '}',

? ? ? ].join('\n'),

? ? };

? ? let Atmosphere = {

? ? ? uniforms: {

? ? ? ? time: {

? ? ? ? ? value: 0,

? ? ? ? },

? ? ? },

? ? ? vertexShader: [

? ? ? ? 'varying vec3 vertexNormal;',

? ? ? ? 'varying vec2 depthUv;',

? ? ? ? 'void main(){',

? ? ? ? 'vertexNormal = normalize(normalMatrix * normal);', //將法線轉(zhuǎn)換到視圖坐標系中

? ? ? ? 'gl_Position ?= projectionMatrix * modelViewMatrix * vec4(position, 1.0);',// 計算頂點著色器中頂點的位置

? ? ? ? 'depthUv = gl_Position.xy/1.0 + 0.5;',

? ? ? ? '}',

? ? ? ].join('\n'),

? ? ? fragmentShader: [

? ? ? ? 'varying vec3 vertexNormal;',

? ? ? ? 'varying vec2 depthUv;',

? ? ? ? 'uniform float time;',

? ? ? ? 'void main(){',

? ? ? ? 'float step = abs(time - depthUv.x);',

? ? ? ? 'if(step < 0.02){',

? ? ? ? 'float d = ?(1.0 - step * 50.0);',

? ? ? ? '}',

? ? ? ? 'float intensity = pow(0.5 - dot(vertexNormal, vec3(0.3 ,1 , 1)) ,0.5);',

? ? ? ? ' gl_FragColor = vec4(0.3, 0.6 , 1.0 ?, 1.0) * intensity;',

? ? ? ? '}',

? ? ? ].join('\n'),

? ? };

? ? const sphere = new THREE.Mesh(new THREE.SphereGeometry(5, 50, 50), new THREE.ShaderMaterial({

? ? ? vertexShader: AeroSphere.vertexShader,

? ? ? fragmentShader: AeroSphere.fragmentShader,

? ? ? uniforms: AeroSphere.uniforms,

? ? }))

? ? const atmosphere = new THREE.Mesh(new THREE.SphereGeometry(5, 50, 50), new THREE.ShaderMaterial({

? ? ? vertexShader: Atmosphere.vertexShader,

? ? ? fragmentShader: Atmosphere.fragmentShader,

? ? ? uniforms: Atmosphere.uniforms,

? ? ? blending: THREE.AdditiveBlending,

? ? ? side: THREE.BackSide

? ? }))

? ? atmosphere.scale.set(1.05, 1.05, 1.05)

? ? scene.add(sphere)

? ? scene.add(atmosphere)

? ? camera.position.z = 12

? ? const animate = function () {

? ? ? requestAnimationFrame(animate);

? ? ? renderer.render(scene, camera);

? ? ? sphere.rotation.y += 0.005

? ? ? const delta = clock.getDelta();

? ? ? const time = (clock.getElapsedTime() / 5) % 1;

? ? ? if (AeroSphere.uniforms) {

? ? ? ? Atmosphere.uniforms.time.value = time;

? ? ? }

? ? };

? ? animate();

? </script>

</body>

</html>

以上為個人拙見不喜勿噴,謝謝觀看

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末球昨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子眨攘,更是在濱河造成了極大的恐慌主慰,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件期犬,死亡現(xiàn)場離奇詭異河哑,居然都是意外死亡,警方通過查閱死者的電腦和手機龟虎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門璃谨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鲤妥,你說我怎么就攤上這事佳吞。” “怎么了棉安?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵底扳,是天一觀的道長。 經(jīng)常有香客問我贡耽,道長衷模,這世上最難降的妖魔是什么鹊汛? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮阱冶,結果婚禮上刁憋,老公的妹妹穿的比我還像新娘。我一直安慰自己木蹬,他們只是感情好至耻,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著镊叁,像睡著了一般尘颓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上晦譬,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天疤苹,我揣著相機與錄音,去河邊找鬼敛腌。 笑死痰催,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的迎瞧。 我是一名探鬼主播夸溶,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼凶硅!你這毒婦竟也來了缝裁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤足绅,失蹤者是張志新(化名)和其女友劉穎捷绑,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體氢妈,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡粹污,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了首量。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片壮吩。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖加缘,靈堂內(nèi)的尸體忽然破棺而出鸭叙,到底是詐尸還是另有隱情,我是刑警寧澤拣宏,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布沈贝,位于F島的核電站,受9級特大地震影響勋乾,放射性物質(zhì)發(fā)生泄漏宋下。R本人自食惡果不足惜嗡善,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望学歧。 院中可真熱鬧滤奈,春花似錦、人聲如沸撩满。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伺帘。三九已至,卻和暖如春忌锯,著一層夾襖步出監(jiān)牢的瞬間伪嫁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工偶垮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留张咳,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓似舵,卻偏偏與公主長得像脚猾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子砚哗,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

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