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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据立方体_立方体纹理

發(fā)布時間:2025/3/11 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据立方体_立方体纹理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

立方體紋理就是包含6個2D紋理的紋理.6個紋理有序排列在立方體的6個面.其可以通過方向向量采樣立方體紋理上的紋素.

創(chuàng)建立方體貼圖跟創(chuàng)建2D貼圖一樣,但是綁定到GL_TEXTURE_CUBE_MAP上.

glGenTextures(1, &CubeMapID); glBindTexture(GL_TEXTURE_CUBE_MAP, CubeMapID);

立方體紋理右6個面,每個面都要調(diào)用一次glTexImage2D,因此共需要調(diào)用6次.每個面有特定的紋理目標(biāo).按照順序是這樣.

這些紋理目標(biāo)為枚舉型,按照順序他們的值是線性疊加的.因此編寫代碼的時候可以用for循環(huán)調(diào)用glTexImage2D,然后用循環(huán)次數(shù)作為這些紋理目標(biāo)的枚舉值.從GL_TEXTUREE_MAP_POSITIVE_X開始.

例如以i作為循環(huán)次數(shù)記錄.

glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);

立方體紋理也需要設(shè)置環(huán)繞模式與過濾模式.

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); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

一般的紋理是二維的因此僅需要設(shè)定ST的環(huán)繞模式即可.但是立方體紋理是三維的因此需要對R設(shè)置.可以簡單理解為z坐標(biāo).

天空盒

立方體紋理常用于天空盒.設(shè)置好紋理數(shù)據(jù)和VAO,VBO之后,編寫天空盒用的shader就可以了.

#version 330 core layout(location=0) in vec3 aPos;out vec3 TexCoords;uniform mat4 projection; uniform mat4 view;void main() {TexCoords=aPos;gl_Position = projection * view * vec4(aPos, 1.0); }

片元著色器獲取立方體紋理的紋素作為顏色輸出.

#version 330 core out vec4 FragColor; in vec3 TexCoords; uniform samplerCube skyBox; void main() {FragColor=texture(skyBox,TexCoords); }

在繪制天空和的時候需要開啟深度測試,以及關(guān)閉天空盒的深度寫入.因?yàn)橛行ο笈c相機(jī)的距離可能比天空盒面到相機(jī)的距離遠(yuǎn).因此這種情況下天空盒有可能將某些物體覆蓋了.并且需要注意需要先渲染天空盒再渲染其他物體.

int main() { glDepthMask(GL_FALSE); //繪制天空盒 //... glDepthMask(GL_TRUE); //繪制其他物體 }

如果按照以往的思路將MVP矩陣參數(shù)傳進(jìn)去將紋理坐標(biāo)設(shè)置好的話并不會得到一個良好的結(jié)果.

因?yàn)槲覀儾幌胩炜蘸懈鷪鼍爸衅渌矬w一樣.天空盒不應(yīng)受移動影響.僅受旋轉(zhuǎn)和縮放影響.因此需要去掉觀察矩陣的平移部分.即保留矩陣左上角部分.

view=glm::mat4(glm::mat3(view))

將這個view傳進(jìn)去shader可得到正確的顯示.

以上的做法是關(guān)閉深度寫入,讓天空盒不參與深度測試.讓每個像素都運(yùn)行一次天空盒的片元著色器.但其實(shí)將天空盒的深度值永遠(yuǎn)設(shè)置為1就可以獲得正確的效果了并且參與深度測試的話也不需要每個像素都調(diào)用天空盒的著色器.因?yàn)樵谀承?fù)雜的場景里面天空盒僅僅顯示一小部分.為此,我們需要將天空盒深度值永遠(yuǎn)設(shè)為1.

根據(jù)流水線,在頂點(diǎn)著色器運(yùn)行時投影矩陣會進(jìn)行透視除法,并最后處于標(biāo)準(zhǔn)化設(shè)備空間(NDC)中的.

因此若想經(jīng)過透視除法后的z值為1,則需要將z值定為w.

#version 330 core layout(location=0) in vec3 aPos;out vec3 TexCoords;uniform mat4 projection; uniform mat4 view;void main() {TexCoords=aPos;vec4 pos = projection * view * vec4(aPos, 1.0);gl_Position = pos.xyww; }

將z值定為w進(jìn)行透視除法后就變?yōu)?.

這時候還需要開啟深度測試并調(diào)用深度測試函數(shù)設(shè)置比較運(yùn)算符為GL_LEQUAL.

GL_LEQUAL為片元的深度值小于等于緩存的深度值時通過測試.因?yàn)槿绻{(diào)用默認(rèn)的GL_LESS的話基本上天空盒是不會通過測試的.這時候就不需要設(shè)置關(guān)閉深度寫入了.

glDepthFunc(GL_LEQUAL); //繪制天空盒 glDepthFunc(GL_LESS);

繪制完天空盒之后改回默認(rèn)的深度運(yùn)算操作符,以便其他物體進(jìn)行深度測試.

如果場景里面沒有需要透明度混合的物體的話則天空盒可以隨便放置于主循環(huán)的某一個位置進(jìn)行渲染.否則的話會出現(xiàn)這種情況.

2B因?yàn)椴恍枰该鞫然旌?因此可以獲得正常的渲染效果.但是草地于窗戶精靈體需要透明度混合因此會出現(xiàn)奇怪的效果.

這里我是先渲染場景的所有物體,最后才渲染天空盒的.因此這時候場景物體部分的深度值比1小,通過測試與默認(rèn)的顏色緩存的顏色進(jìn)行混合.接著天空盒與深度緩存進(jìn)行測試,因?yàn)樘炜蘸猩疃戎禐?,比場景里物體的深度值大,因此這部分片元會被拋棄.所以物體混合的顏色里面沒有天空盒紋理的顏色.

為此,最好在主循環(huán)剛開始的時候渲染天空盒.讓天空盒顏色代替默認(rèn)顏色緩存里的顏色.

所以,無論是對天空盒關(guān)閉深度寫入還是設(shè)置天空盒的深度值為1,都最好在主循環(huán)開始的時候渲染.

立方體紋理可以用于環(huán)境映射.常用有反射和折射.

首先是反射

反射很簡單.主要就是獲取向量R的方向然后通過R在立方體紋理中獲取紋素.

在頂點(diǎn)著色器獲取片元的位置以及法向量輸出到片元著色器.

#version 330 core layout (location=0) in vec3 aPos; layout (location=1) in vec3 aNormal;out vec3 fragPos; out vec3 Normal;uniform mat4 model; uniform mat4 view; uniform mat4 projection;void main() { Normal=mat3(transpose(inverse(view*model)))*aNormal;fragPos=vec3(view*model*vec4(aPos,1.0));gl_Position=projection*view*model*vec4(aPos,1.0); }

這里的法線用了法線矩陣消除縮放對物體法線的影響.片元位置放置在相機(jī)空間中,因?yàn)槲移糜趯⑦@些計(jì)算放在相機(jī)空間,這樣就不用在片元著色器計(jì)算觀察位置到片元位置了,直接可以用片元位置代替,因?yàn)樵谙鄼C(jī)空間中,攝像機(jī)的位置就是原點(diǎn).

根據(jù)上面的圖片,需要在片元著色器計(jì)算反射向量

.反射向量可以通過GLSL內(nèi)置函數(shù) 計(jì)算,也可以用反射向量的計(jì)算方式計(jì)算 .因?yàn)樵陧旤c(diǎn)著色器片元位置在相機(jī)空間下,所以向量 僅需要對片元位置歸一化即可.#version 330 core out vec4 FragColor; in vec3 Normal; in vec3 fragPos;uniform samplerCube skybox;void main() { //環(huán)境映射反射vec3 I=normalize(fragPos);vec3 R=reflect(I,normal);FragColor=vec4(texture(skybox,R).xyz,1.0); }

可以運(yùn)用反射貼圖使模型的僅某一部分進(jìn)行反射.通過引入反射貼圖并對反射貼圖進(jìn)行采樣獲得當(dāng)前網(wǎng)格的反射系數(shù),然后運(yùn)用插值對模型的反射貼圖與其他光照模型進(jìn)行綜合

struct Material {sampler2D texture_diffuse0;sampler2D texture_specular0;sampler2D texture_normal0;sampler2D texture_reflection0;float shininess;//影響鏡面高光的散射/半徑 };

在material就結(jié)構(gòu)體里面增加一個反射貼圖的聲明.接著求出反射系數(shù).

float reflectRate=(texture(material.texture_reflection0,TexCoords).r+texture(material.texture_reflection0,TexCoords).g+texture(material.texture_reflection0,TexCoords).b)/3;

不過反射貼圖一般顏色分量不是0就是1,所以也可以簡單點(diǎn)

float reflectRate=texture(material.texture_reflection0,TexCoords).r;

在總顏色輸出那里做一個插值就可以了.

void main() { vec3 normal=normalize(Normal);vec3 viewDir=normalize(-fragPos);//觀察空間下進(jìn)行vec3 Direction=CalcDirectionalLight(dirLight,normal,viewDir);vec3 Point = CalcPointLight(pointLight,normal,fragPos,viewDir);vec3 Spot=CalcSpotLight(spotLight,normal,fragPos,viewDir);//環(huán)境映射反射vec3 I=normalize(fragPos);vec3 R=reflect(I,normal);float reflectRate=texture(material.texture_reflection0,TexCoords).r;vec4 reflection=texture(skybox,R);FragColor=vec4(reflectRate*reflection.xyz+(1-reflectRate)*(Spot+Point+Direction),1.0); }

最終效果中可以看到身上比較閃閃的地方都有天空盒的映射,其中以眼部的鏡片效果最明顯.

折射

折射與反射的區(qū)別不大,就是將

函數(shù)改為 函數(shù),再加一個折射率常數(shù).

折射用到了斯涅耳定律,斯涅耳定律很簡單:

其中

, 表示兩種介質(zhì)的折射率, , 表示光線方向與法線的夾角.

介質(zhì)的折射率有一個固定的參數(shù).

但是!!!我們不需要自己計(jì)算斯涅爾定律,反射有內(nèi)建GLSL函數(shù).折射與反射的區(qū)別不大,就是將

函數(shù)改為 函數(shù),再加一個折射率常數(shù).將上述反射部分的片元著色器代碼修改下.

其中

,兩種折射率比例.然后作為 的第三個參數(shù)就行float ratio=1.0/1.33; vec3 I=normalize(fragPos); vec3 R=refract(I,normal,ratio);FragColor=vec4(texture(skybox,R).xyz,1.0);

當(dāng)然,

函數(shù)想要自己算也不是不行.楊超:cg refract函數(shù)?zhuanlan.zhihu.com

這里有一篇折射函數(shù)的推導(dǎo)過程.其中

.

按照這篇文章的推導(dǎo)即可得到正確折射向量.

vec3 refract(vec3 I,vec3 normal,float ratio) {vec3 OC=dot(-I,normal)*normal;vec3 CA=-I-OC;vec3 EB=-ratio*CA;float EB_length_2=EB.x*EB.x+EB.y*EB.y+EB.z+EB.z;vec3 OE=-sqrt(1-EB_length_2)*normal;return EB+OE; } 立方體貼圖 - LearnOpenGL CN?learnopengl-cn.github.io

總結(jié)

以上是生活随笔為你收集整理的数据立方体_立方体纹理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 亚洲精品一区二区三区在线 | 日本高清视频在线播放 | 久久99久久99精品免观看软件 | 劲爆欧美第一页 | 91成人在线观看国产 | 尤物视频免费在线观看 | 欧美一及片 | 久久免费在线观看 | 超碰免费av | 污片网站 | 亚洲淫欲 | 亚洲精品乱码久久久久久不卡 | 成都4电影免费高清 | 成人黄色电影在线 | 日韩专区在线播放 | 91成人免费电影 | 欧美极品少妇无套实战 | 中文字幕第一页亚洲 | 久久国产精品精品国产色婷婷 | 久久久久99精品成人片 | 精品在线视频免费观看 | 成人福利午夜 | 香蕉av在线播放 | 日韩看片 | 久久我不卡 | 中文字幕无码不卡免费视频 | 国产精品99久久久 | 成人7777 | 国产.com | 国产中文字幕在线 | 亚洲人久久 | 国产高清不卡一区 | 国产做爰xxxⅹ性视频国 | 手机看片日韩久久 | 玖玖视频 | 精品国产一级片 | 狂野欧美 | 999久久久精品视频 亚洲视频精品在线 | 日韩人妻精品无码一区二区三区 | 六月丁香啪啪 | 激情黄色av | 久久成人精品视频 | 成人a毛片久久免费播放 | 99久久精品一区二区 | 97人人澡 | 黄wwwww | 免费一区二区三区视频在线 | 国内福利视频 | 国内av网| 91色啪| 日韩三级在线观看 | 日韩免费在线观看视频 | 日韩综合网站 | 国产毛片欧美毛片久久久 | 国产日本一区二区三区 | 色涩网站 | 日韩av一 | 欧美日韩人妻精品一区二区 | 99视频在线观看视频 | 精品国产乱码一区二区 | 欧美福利视频一区 | 欧美激情亚洲综合 | 在线只有精品 | 国产日韩精品在线观看 | 国产欧美在线精品日韩 | 亚洲国产日韩在线观看 | 一级全黄色片 | 九一爱爱 | 深夜视频在线观看免费 | 亚洲最新在线视频 | 亚洲天堂av在线播放 | 精品一区二区三 | 欧美日韩在线播放 | 免费在线视频一区二区 | 韩国无码一区二区三区精品 | 亚洲伦理在线播放 | 国产日韩av一区二区 | 国产影视av | 亚洲国产永久 | 人妻精品一区二区在线 | 激情xxx | 欧美三级一区二区三区 | av手机免费在线观看 | 日韩伦理在线视频 | 日韩毛片在线视频 | 免费av免费观看 | 免费黄色在线看 | 久久久青 | 末路1997全集免费观看完整版 | 91精品福利在线 | 精品一区不卡 | 免费av免费看 | www亚洲视频 | 91禁国产网站 | 超碰caoprom| 欧美成综合 | 欧美一级片在线看 | 成人区人妻精品一区二区网站 | 精品成人在线观看 |