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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

CSharpGL(43)环境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction)...

發(fā)布時間:2025/7/25 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CSharpGL(43)环境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction)... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

CSharpGL(43)環(huán)境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction)

開始

如圖所示,本文圍繞GLSL里的samplerCube記錄天空盒(Skybox)、反射(reflection)、折射(refraction)的實現(xiàn)。

下載

CSharpGL已在GitHub開源,歡迎對OpenGL有興趣的同學加入(https://github.com/bitzhuwei/CSharpGL)

天空盒(Skybox)

samplerCube

想在三維場景里渲染出天空和大地,可以利用一個巨大的立方體,把6個連接的圖片分別貼在立方體的6個面上。

?

這樣的立方體就是所謂的天空盒(Skybox)。

OpenGL提供了一個GL_TEXTURE_CUBE_MAP類型的紋理,其本身就是一個立方體,自帶6個紋理面。它對應的GLSL里的類型就是samplerCube。SamplerCube正適合做天空盒。

?

SkyboxNode

渲染天空盒,實際上就是渲染一個巨大的立方體,并且用samplerCube為其上色。

其vertex shader如下:

1 #version 330 core 2 3 layout(location = 0) in vec3 inPosition;// 頂點位置 4 5 uniform mat4 mvpMatrix; 6 7 out vec3 texCoord;// 立方體紋理在此頂點處的坐標值 8 9 void main() 10 { 11 vec4 position = mvpMatrix * vec4(inPosition, 1.0); 12 gl_Position = position.xyww;// 保證天空盒的深度始終為最深 13 texCoord = inPosition;// 立方體紋理的特殊情況 14 }

注意,這里的gl_Position = position.xyww;,是為了保證天空盒的深度始終為最深。這樣就不會遮擋住場景里的其他物體。再注意,texCoord = inPosition;這句,就要求我們的天空盒模型必須是中心在坐標原點的立方體,這樣才能保證inPosition在數(shù)值上等于此頂點的紋理坐標值

其fragment shader如下:

1 #version 330 core 2 3 uniform samplerCube skybox; 4 5 in vec3 texCoord; 6 7 out vec4 color; 8 9 void main() 10 { 11 color = texture(skybox, texCoord); 12 }

極其簡單,就是從skybox紋理中取出對應位置的顏色,寫入Framebuffer。

如果把鏡頭拉遠,你會看到所謂的天空盒是這樣的:一個剔除了正面的立方體?

?

反射(Reflection)

利用samplerCube,可以實現(xiàn)一個反射效果——根據(jù)反射原理,把天空盒的紋理貼到模型上,看上去的感覺是,模型像鏡子一樣反射了周圍的東西。此即為環(huán)境映射的一種。

?

GLSL自帶了反射函數(shù)reflect(,);

實現(xiàn)反射的vertex shader如下:

1 #version 330 core 2 3 layout (location = 0) in vec3 inPosition; 4 layout (location = 1) in vec3 inNormal; 5 6 uniform mat4 projection; 7 uniform mat4 view; 8 uniform mat4 model; 9 10 out vec3 passNormal; 11 out vec3 passPosition; 12 13 void main() 14 { 15 gl_Position = projection * view * model * vec4(inPosition, 1.0); 16 17 passNormal = mat3(transpose(inverse(model))) * inNormal; 18 passPosition = vec3(model * vec4(inPosition, 1.0)); 19 }

此vertex shader做了3件事:1.給gl_Position賦值。2.傳遞world space里的法線passNormal。3.傳遞world space里的位置passPosition。

下面根據(jù)反射原理為模型上色(fragment shader):

1 #version 330 core 2 3 uniform vec3 cameraPos; 4 uniform samplerCube skybox; 5 6 in vec3 passNormal; 7 in vec3 passPosition; 8 9 out vec4 FragColor; 10 11 void main() 12 { 13 vec3 I = normalize(passPosition - cameraPos); 14 vec3 R = reflect(I, normalize(passNormal)); 15 FragColor = vec4(texture(skybox, R).rgb, 1.0); 16 }

這里利用reflect函數(shù)找到反射方向(即紋理坐標),從而找到目標顏色。

?

折射(Refraction)

?

折射與反射類似,也是一種環(huán)境映射方式。其vertex shader與反射相同,fragment shader也只有一點點不同:利用GLSL內(nèi)置的refract()函數(shù)找到折射方向。

1 #version 330 core 2 3 uniform vec3 cameraPos; 4 uniform samplerCube skybox; 5 6 in vec3 passNormal; 7 in vec3 passPosition; 8 9 out vec4 FragColor; 10 11 void main() 12 { 13 float ratio = 1.00 / 1.52; 14 vec3 I = normalize(passPosition - cameraPos); 15 vec3 R = refract(I, normalize(passNormal), ratio); 16 FragColor = vec4(texture(skybox, R).rgb, 1); 17 }

注意,這里有個ratio是指兩種透明物體的折射率。1.52是玻璃對空氣的折射率。再注意,這里我們只計算了一個面的折射,然而本文的模型有光線的進入和穿出兩次折射。不過一般這樣也沒關系,最終效果還是不錯的。

總結(jié)

沒什么可總結(jié)的。

?

轉(zhuǎn)載于:https://www.cnblogs.com/bitzhuwei/p/CSharpGL-43-environment-mapping-skybox-reflection-refraction.html

總結(jié)

以上是生活随笔為你收集整理的CSharpGL(43)环境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction)...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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