Cg 程式設計/Unity/彎曲玻璃
外觀

本教程涵蓋折射對映及其與立方體貼圖的實現。
它是“反射表面”部分的變體,應該先閱讀。
在“反射表面”部分中,我們反射了視角射線,然後在反射方向的立方體貼圖中執行紋理查詢。在這裡,我們在彎曲的透明表面上折射視角射線,然後使用折射方向執行查詢。該效果將忽略光線再次離開透明物體時的第二次折射;然而,許多人幾乎沒有注意到差異,因為這種折射通常不是我們日常生活的一部分。
我們沒有使用reflect函式,而是使用refract函式;因此,片段著色器可能是
float4 frag(vertexOutput input) : COLOR
{
float refractiveIndex = 1.5;
float3 refractedDir = refract(normalize(input.viewDir),
normalize(input.normalDir), 1.0 / refractiveIndex);
return texCUBE(_Cube, refractedDir);
}
請注意,refract 接受第三個引數,即外部介質的折射率(例如,空氣的折射率為 1.0)除以物體的折射率(例如,某些型別的玻璃的折射率為 1.5)。還要注意,第一個引數必須是標準化的,而reflect則不需要。
使用經過調整的片段著色器,完整的著色器程式碼變為
Shader "Cg shader with refraction mapping" {
Properties {
_Cube("Reflection Map", Cube) = "" {}
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
// User-specified uniforms
uniform samplerCUBE _Cube;
struct vertexInput {
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float3 normalDir : TEXCOORD0;
float3 viewDir : TEXCOORD1;
};
vertexOutput vert(vertexInput input)
{
vertexOutput output;
float4x4 modelMatrix = unity_ObjectToWorld;
float4x4 modelMatrixInverse = unity_WorldToObject;
output.viewDir = mul(modelMatrix, input.vertex).xyz
- _WorldSpaceCameraPos;
output.normalDir = normalize(
mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
output.pos = UnityObjectToClipPos(input.vertex);
return output;
}
float4 frag(vertexOutput input) : COLOR
{
float refractiveIndex = 1.5;
float3 refractedDir = refract(normalize(input.viewDir),
normalize(input.normalDir), 1.0 / refractiveIndex);
return texCUBE(_Cube, refractedDir);
}
ENDCG
}
}
}
恭喜你。這是另一個教程的結尾。我們已經看到了
- 如何使用
refract指令將反射對映調整為折射對映。
如果你還想了解更多
- 關於反射對映和立方體貼圖,請閱讀“反射表面”部分。
- 關於
refract指令,你可以在Nivida 的 Cg 教程附錄 E 中查詢。
除非另有說明,否則此頁面上的所有示例原始碼均授予公共領域。