改編自《cg教程--可編程實時圖形學權威指南》上的demo。
反射向量計算公式 R=I-2N(N*I) 備注N*I是點乘 I入射光線,N法向量
函數實現:
float3 reflect(float3 I,float3 N)
{
return I-2.0*N*dot(N,I);
}
Shader "CG shader Reflect"{ Properties { environmentMap("Environment Map", Cube) = "" {} reflectivity("reflectivity1", float) =1 //反射系數 影響反射強度 decalMap("decalMap", 2D) = "white" {} } SubShader{ Pass{ CGPROGRAM #pragma vertex vert //頂點編程入口 #pragma fragment frag //片段編程入口 #include "UnityCG.cginc" //注意引入 struct VertInput{ float4 position:POSITION; float2 texCoordw:TEXCOORD0; float3 normal1:NORMAL; }; struct VertOutput{ float4 oPosition:SV_POSITION; float2 oTexCoord:TEXCOORD0; float3 R:TEXCOORD1; }; // uniform 類型的參數 需要在Properties uniform samplerCUBE environmentMap; uniform float reflectivity; uniform sampler2D decalMap; VertOutput vert(VertInput input) { VertOutput o; o.oPosition=mul(UNITY_MATRIX_MVP,input.position);//UNITY_MATRIX_MVP變量, 就是對應圖形中的模型視圖投影矩陣(ModelViewProj),unity中規定 必須這么寫 o.oTexCoord=input.texCoordw; float3 positionW=mul(_Object2World,input.position).xyz;//_Object2World 模型矩陣,把本地坐標轉到世界坐標 float3 N=mul((float3x3)_Object2World,input.normal1); N=normalize(N); float3 I=positionW-_WorldSpaceCameraPos;//計算入射光線,需要在世界坐標系中計算。_WorldSpaceCameraPos視點(相機)在世界坐標的位置 o.R=reflect(I,N);//計算反射光線 reflect系統自帶函數 return o; } float4 frag(VertOutput output):COLOR { float4 reflectionColor=texCUBE(environmentMap,output.R); float4 decalColor=tex2D(decalMap,output.oTexCoord); float4 color1=lerp(decalColor,reflectionColor,reflectivity); return color1; } ENDCG } } }
上例代碼出現的_Object2World,_WorldSpaceCameraPos 莫名奇妙的參數,來自UnityCG.cginc文件,在對cg、hlsl、glsl進行移植的時候,特殊參數需要參考UnityCG.cginc文件的定義。
實現效果:
初學階段,不妥之處望大家指教。