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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.