unity shader reflect
改編自《cg教程--可編程實時圖形學權威指南》上的demo。
本文的目的不在於教你如何實現反射效果,而是在於讓你學會遷移cg、hlsl、glsl到unity中[unity shader 資料很少,但是前面哪幾種還是相對較多的 ]
反射向量計算公式 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{ //在UnityCG中有定義 可以參考appdata_base、appdata_tan、appdata_full
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文件的定義。
附unity shader 學習資料:http://en.wikibooks.org/wiki/Cg_Programming/Unity
本文的目的不在於教你如何實現反射效果,而是在於讓你學會遷移cg、hlsl、glsl到unity中[unity shader 資料很少,但是前面哪幾種還是相對較多的 ]
反射向量計算公式 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{ //在UnityCG中有定義 可以參考appdata_base、appdata_tan、appdata_full
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文件的定義。
附unity shader 學習資料:http://en.wikibooks.org/wiki/Cg_Programming/Unity
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.