OpenGL學習筆記 天空盒(反射,折射)

2021-10-23 09:30:55 字數 2336 閱讀 1165

先展示乙個效果圖

多個紋理組合起來對映到一張紋理上的一種紋理型別:立方體貼圖(cube map)。

簡單來說,立方體貼圖就是乙個包含了6個2d紋理的紋理,每個2d紋理都組成了立方體的乙個面:乙個有紋理的立方體。你可能會奇怪,這樣乙個立方體有什麼用途呢?為什麼要把6張紋理合併到一張紋理中,而不是直接使用6個單獨的紋理呢?立方體貼圖有乙個非常有用的特性,它可以通過乙個方向向量來進行索引/取樣。假設我們有乙個1x1x1的單位立方體,方向向量的原點位於它的中心。使用乙個橘黃色的方向向量來從立方體貼圖上取樣乙個紋理值會像是這樣:

立方體貼圖建立

unsigned int textureid;

glgentextures(1, &textureid);

//gl_texture_cube_map 注意引數

glbindtexture(gl_texture_cube_map, textureid);

//和opengl的很多列舉(enum)一樣,它們背後的int值是線性遞增的,所以如果我們有乙個紋理位置的陣列或者vector,我們就可以從gl_texture_cube_map_positive_x開始遍歷它們,在每個迭代中對列舉值加1,遍歷了整個紋理目標:

int width, height, nrchannels;

unsigned char *data;

for(unsigned int i = 0; i < textures_faces.size(); i++)

同樣也需要設定環繞方式

gltexparameteri(gl_texture_cube_map, gl_texture_mag_filter, gl_linear);

gltexparameteri(gl_texture_cube_map, gl_texture_min_filter, gl_linear);

gltexparameteri(gl_texture_cube_map, gl_texture_wrap_s, gl_clamp_to_edge);

gltexparameteri(gl_texture_cube_map, gl_texture_wrap_t, gl_clamp_to_edge);

gltexparameteri(gl_texture_cube_map, gl_texture_wrap_r, gl_clamp_to_edge);

天空盒的乙個特點就是無限的空間。

目前我們是首先渲染天空盒,之後再渲染場景中的其它物體。這樣子能夠工作,但不是非常高效。如果我們先渲染天空盒,我們就會對螢幕上的每乙個畫素執行一遍片段著色器,即便只有一小部分的天空盒最終是可見的。可以使用提前深度測試(early depth testing)輕鬆丟棄掉的片段能夠節省我們很多寶貴的頻寬。

所以,我們將會最後渲染天空盒,以獲得輕微的效能提公升。這樣子的話,深度緩衝就會填充滿所有物體的深度值了,我們只需要在提前深度測試通過的地方渲染天空盒的片段就可以了,很大程度上減少了片段著色器的呼叫。問題是,天空盒只是乙個1x1x1的立方體,它很可能會不通過大部分的深度測試,導致渲染失敗。不用深度測試來進行渲染不是解決方案,因為天空盒將會複寫場景中的其它物體。我們需要欺騙深度緩衝,讓它認為天空盒有著最大的深度值1.0,只要它前面有乙個物體,深度測試就會失敗。

在座標系統小節中我們說過,透視除法是在頂點著色器執行之後執行的,將gl_position的xyz座標除以w分量。我們又從深度測試小節中知道,相除結果的z分量等於頂點的深度值。使用這些資訊,我們可以將輸出位置的z分量等於它的w分量,讓z分量永遠等於1.0,這樣子的話,當透視除法執行之後,z分量會變為w / w = 1.0。

void main()

主要說下反射和折射。

可以看到,反射只需要渲染反射後的向量所「擊中」的片段的顏色。**如下(片段著色器)

#version 330 core

out vec4 fragcolor;

in vec3 normal;

in vec3 position;

uniform vec3 camerapos;

uniform samplercube skybox;

void main()

opengl 天空盒 ThingJS玩轉天空盒技術

在計算機的三維世界中,三維天空的繪製肯定不可能像現實生活中的天空一樣,一望無際綿延無盡 thingjs的天空盒技術是認真的。引用地圖元件指令碼之後地球相機引數就改變,需要校正天空盒。為什麼偏偏是天空盒呢?這就得問一下,天空盒的原理是什麼?opengl中天空盒的思想就是繪製乙個大的立方體,然後將觀察者...

QT與OpenGL結合實現天空盒

之前搗鼓過一段時間opengl,用的是glad加上glfw庫,由於在windows下c 開發用qt較多,所以把qt和opengl結合,因此進行了嘗試。首先qt5.8.0下有自帶的opengl控制項opengl widget,將這個控制項提公升為乙個自己寫的類myopenglbox繼承於qopengl...

關於OpenGL的天空盒的理解

參考 owed by 春夜喜雨 關於天空盒 空間概念上 可以理解為乙個盒子,內壁貼著貼圖,我們位於盒子內,盒子離我們無窮遠。我們抬頭向四面看,最遠處是這個盒子的內壁,由於我們始終位於盒子內,所以我們不會看到盒子以外的部分。opengl實現上 通常是 天空盒採用6張可以連線縫合的天空,貼圖到乙個立方體...