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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Environment Mapping

發(fā)布時(shí)間:2023/12/16 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Environment Mapping 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Environment Mapping

Texture cubes的另一種應(yīng)用是environment mapping。Environment mapping也稱為reflection mapping,用于近似模擬reflective surfaces(反光表面),比如汽車上的鍍了一層金屬物的保險(xiǎn)杠。
Environment mapping的處理過程比skybox稍微復(fù)雜一些,因?yàn)樾枰?jì)算光線與表面的反射向量。反射向量主要由view direction(限入射角向量)和表面的法向量計(jì)算得到。具體的公式如下:
R = I – 2 * N * (I ? N)
其中,I表示入射向量,N指表面的法向量。列表8.2列出了一種environment mapping effect的代碼。
列表8.2 EnvironmentMapping.fx
#include "include\\Common.fxh"/************* Resources *************/cbuffer CBufferPerFrame {float4 AmbientColor : AMBIENT <string UIName = "Ambient Light";string UIWidget = "Color";> = {1.0f, 1.0f, 1.0f, 0.0f};float4 EnvColor : COLOR <string UIName = "Environment Color";string UIWidget = "Color";> = {1.0f, 1.0f, 1.0f, 1.0f };float3 CameraPosition : CAMERAPOSITION < string UIWidget="None"; >; }cbuffer CBufferPerObject {float4x4 WorldViewProjection : WORLDVIEWPROJECTION < string UIWidget="None"; >;float4x4 World : WORLD < string UIWidget="None"; >;float ReflectionAmount <string UIName = "Reflection Amount";string UIWidget = "slider";float UIMin = 0.0;float UIMax = 1.0;float UIStep = 0.05;> = {0.5f}; }Texture2D ColorTexture <string ResourceName = "default_color.dds";string UIName = "Color Texture";string ResourceType = "2D"; >;TextureCube EnvironmentMap <string UIName = "Environment Map";string ResourceType = "3D"; >;SamplerState TrilinearSampler {Filter = MIN_MAG_MIP_LINEAR; };RasterizerState DisableCulling {CullMode = NONE; };/************* Data Structures *************/struct VS_INPUT {float4 ObjectPosition : POSITION;float3 Normal : NORMAL;float2 TextureCoordinate : TEXCOORD; };struct VS_OUTPUT {float4 Position : SV_Position;float2 TextureCoordinate : TEXCOORD0; float3 ReflectionVector : TEXCOORD1; };/************* Vertex Shader *************/VS_OUTPUT vertex_shader(VS_INPUT IN) {VS_OUTPUT OUT = (VS_OUTPUT)0;OUT.Position = mul(IN.ObjectPosition, WorldViewProjection);OUT.TextureCoordinate = get_corrected_texture_coordinate(IN.TextureCoordinate);float3 worldPosition = mul(IN.ObjectPosition, World).xyz;float3 incident = normalize(worldPosition - CameraPosition);float3 normal = normalize(mul(float4(IN.Normal, 0), World).xyz);// Reflection Vector for cube map: R = I - 2*N * (I.N)OUT.ReflectionVector = reflect(incident, normal);return OUT; }/************* Pixel Shader *************/float4 pixel_shader(VS_OUTPUT IN) : SV_Target {float4 OUT = (float4)0;float4 color = ColorTexture.Sample(TrilinearSampler, IN.TextureCoordinate);float3 ambient = get_vector_color_contribution(AmbientColor, color.rgb); float3 environment = EnvironmentMap.Sample(TrilinearSampler, IN.ReflectionVector).rgb;float3 reflection = get_vector_color_contribution(EnvColor, environment);OUT.rgb = lerp(ambient, reflection, ReflectionAmount);OUT.a = color.a;return OUT; }/************* Techniques *************/technique10 main10 {pass p0{SetVertexShader(CompileShader(vs_4_0, vertex_shader()));SetGeometryShader(NULL);SetPixelShader(CompileShader(ps_4_0, pixel_shader()));SetRasterizerState(DisableCulling);} }

Environment Mapping Preamble

在這個(gè)effect代碼中,CBufferPerFrame模塊中包含了表示ambient color和environment color的成員。這是一個(gè)全局的AmbientColor變量,以及一個(gè)用于指定多個(gè)environment-mapped objects的獨(dú)立的color/intensity變量值。對(duì)于美術(shù)人員來說這只是多一種選擇。用于表示directional lighting,specular,point light或者spotlights的成員全部從CBufferPerFrame中移除了,重點(diǎn)是用于表示environment mapping的成員。但是,實(shí)際上前面所有的光照模型都可以與environment mapping一起使用。
CBufferPerFrame中還包含一個(gè)CameraPosition成員,用于計(jì)算入射(觀察)向量。
CBufferPerObject中新增了一個(gè)成員ReflectionAmout。該變量用于在ambient和reflection color之間進(jìn)行插值運(yùn)算。
在environment mapping effect中提供了兩個(gè)textures。其中ColorTexture是一個(gè)普通的2D紋理,用于采樣表面的顏色。EnvironmentMap是一個(gè)TextureCube類型的3D紋理,包含了反光環(huán)境的數(shù)據(jù)。
最后,看一下VS_OUTPUT結(jié)構(gòu)體中的ReflectionVector成員。在vertex shader計(jì)算該向量值,并用于texture cube的采樣。其中的2D TextureCoordinate成員則是用于color texture的采樣。

Environment Mapping Vertex Shader

與以前一樣,vertex shader首先執(zhí)行常用的步驟,把vertex變換到homogeneous space,再給color map的紋理坐標(biāo)賦值。然后變換vertex到world space中,用于計(jì)算入射向量。接著在把表面的法向量變換到world space并進(jìn)行規(guī)范化后,使用HLSL的內(nèi)置函數(shù)reflect()計(jì)算反射向量。該函數(shù)的運(yùn)算方法與注釋中列出的數(shù)學(xué)公式一樣,由于HLSL中提供了該函數(shù),最好是直接使用內(nèi)置函數(shù)。

Environment Mapping Pixel Shader

Pixel shader首先對(duì)color texture進(jìn)行采樣并計(jì)算ambient。然后采樣environment map texture,并使用EvnColor變量的顏色和強(qiáng)度對(duì)environment值進(jìn)行調(diào)制。最后調(diào)用HLSL的內(nèi)置函數(shù)lerp()對(duì)ambient和reflection進(jìn)行插值得到最終的輸出顏色。使用下面公式進(jìn)行線性插值:
Value = x * (1 – s) + (y*s)
其中,s是一個(gè)介于0.0和1.0之間的值,表示最終計(jì)算結(jié)果中x占有的比例以及y占用的比例。因此,對(duì)于environment mapping effect,代入該公式得:

其中ReflectionAmout變量類似于一個(gè)滑塊,用于定義reflection和nonreflection顏色所占的百分比。如果ReflectionAmout值設(shè)為1.0,object的顏色就像鏡面一樣,反射所有關(guān)聯(lián)的texture cube顏色。相反,如果該值設(shè)為0.0,object就不會(huì)反射環(huán)境紋理。

Environment Mapping Output

圖8.6顯示了在一個(gè)sphere上使用environment mapping effect的輸出結(jié)果,其中ambient為純白色和full-intensity(強(qiáng)度值為1.0)。在該effect中,使用checkerboard texture作為color map,使用圖8.1中的texture cube作為environment map。左圖中,reflection amount值為1.0;右圖中reflection amount值為0.5。
圖8.6 EnvironmentMapping.fx applied to a sphere with pure-white, full-intensity
ambient and environment light values, and reflection amounts of 1.0 (left) and 0.5 (right).
(Skybox texture by Emil Persson.)

Dynamic Environment Mapping

到目前為止,已經(jīng)討論了靜態(tài)的environment maps,以及不會(huì)改變(或者說不會(huì)頻繁改變)的texture cubes。靜態(tài)的environment maps也能提供有趣的細(xì)節(jié)和較好性能,但如果仔細(xì)觀察,會(huì)發(fā)現(xiàn)environment map與實(shí)際的場景并不完全相符。很多游戲使用完全不相關(guān)的cube maps,只存在理論上的顏色相似性。如果camera不能足夠靠近一個(gè)反射表面,或者反射表面的形狀使得反射畫面足夠扭曲,就沒有人能夠發(fā)現(xiàn)反射的畫面與實(shí)際場景不符。但是,如果camera可以在一個(gè)反射面上放大,觀察就有可能看到實(shí)現(xiàn)環(huán)境和reflected map之間的不一致。例如,在一個(gè)“global” environment map中通常不包含相距很近的objects。
一種解決方案是根據(jù)觀察者從一區(qū)域移動(dòng)到另一個(gè)區(qū)域時(shí)相應(yīng)的改變environment map,使得每個(gè)區(qū)域具有不同的主題。對(duì)于同一個(gè)區(qū)域,也可以根據(jù)一天中某個(gè)時(shí)刻或天氣情況改變environment map。但是最終的解決方案是在場景中從場景本身生成動(dòng)態(tài)的environment maps。這種方案的實(shí)現(xiàn)步驟為,把camera放在一個(gè)object所處的位置,并設(shè)置camera的FOV為90-degree(包括水平和垂直方向);然后在每一幀中指向每一個(gè)坐標(biāo)軸渲染場景,共渲染6次,并把這6次的輸出圖片組合成一個(gè)texture cube。使用這種方法,需要捕獲reflected environment 場景中的每一個(gè)object。但是,要在可交互的幀率下執(zhí)行這些運(yùn)算,計(jì)算成本是非常大的。可以考慮只針對(duì)場景中關(guān)鍵的objects創(chuàng)建動(dòng)態(tài)的texture cubes。另外,還可以使用較低的分辨率渲染這種cube maps,或者在總幀率一小部分渲染。

總結(jié)

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

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