Unity Shader------Specular(高光反射)计算
程序员文章站
2024-03-23 08:27:16
...
高光反射公式:
Specular= 直射光颜色 * pow(max(dot(当前点的反射光方向,当前点到摄像机的方向),0),高光反射参数)
逐顶点高光反射:
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Custom/Shader03"{
Properties{
_Color("_Color",Color) = (1,1,1,1) //物体本身的颜色
_SpecularColor("_SpecularColor",Color)=(1,1,1,1) //高光的颜色
_Gloss("Gloss",Range(8,200)) = 10 //控制高光光圈大小
}
SubShader{
Pass{
//定义LightMode以得到unity的内置光照变量
Tags{"LightMode" = "ForwardBase"}
CGPROGRAM
//unity内置文件引入,要使用unity的内置变量
#include "Lighting.cginc"
#pragma vertex vert
#pragma fragment frag
fixed4 _Color;
half _Gloss;
fixed4 _SpecularColor;
struct a2v {
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f {
float4 position : SV_POSITION;
fixed3 color : COLOR;
};
v2f vert(a2v v) {
v2f f;
//UNITY_MATRIX_MVP 坐标从模型空间转剪裁空间
f.position = UnityObjectToClipPos(v.vertex);
//法线的单位向量:_World2Object 把一个方向从世界空间转模型空间
fixed3 normalDir = normalize(mul(v.normal, (float3x3) unity_WorldToObject));
//光的单位向量:对于每个顶点来说,平行光位置就是光的方向 _WorldSpaceLightPos0 取得平行光的位置
fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
//取得漫反射颜色
fixed3 diffuse = _LightColor0.rgb * max(dot(normalDir, lightDir), 0) * _Color.rgb;
//反射光方向
fixed3 reflectDir = normalize(reflect(-lightDir, normalDir));
//当前点到摄像机的方向
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(v.vertex, unity_WorldToObject).xyz);
//高光反射
fixed3 specular = _LightColor0.rgb * pow(max(dot(reflectDir, viewDir), 0), _Gloss) *_SpecularColor;
//环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
//颜色叠加
f.color = diffuse + specular + ambient;
return f;
}
fixed4 frag(v2f f) : SV_Target{
return fixed4(f.color,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
逐像素高光反射:
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Custom/Shader03"{
Properties{
_Color("_Color",Color) = (1,1,1,1) //物体本身的颜色
_SpecularColor("_SpecularColor",Color)=(1,1,1,1) //高光的颜色
_Gloss("Gloss",Range(8,200)) = 10 //控制高光光圈大小
}
SubShader{
Pass{
//定义LightMode以得到unity的内置光照变量
Tags{"LightMode" = "ForwardBase"}
CGPROGRAM
//unity内置文件引入,要使用unity的内置变量
#include "Lighting.cginc"
#pragma vertex vert
#pragma fragment frag
fixed4 _Color;
half _Gloss;
fixed4 _SpecularColor;
struct a2v {
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f {
float4 position : SV_POSITION;
float3 worldNormal : TEXCOOED0;
float3 worldVertex : TEXCOOED1;
};
v2f vert(a2v v) {
v2f f;
//UNITY_MATRIX_MVP 坐标从模型空间转剪裁空间
f.position = UnityObjectToClipPos(v.vertex);
f.worldNormal = mul(v.normal, (float3x3) unity_WorldToObject);
f.worldVertex = mul(v.vertex, unity_WorldToObject).xyz;
return f;
}
fixed4 frag(v2f f) : SV_Target{
//法线的单位向量:_World2Object 把一个方向从世界空间转模型空间
fixed3 normalDir = normalize(f.worldNormal);
//光的单位向量:对于每个顶点来说,平行光位置就是光的方向 _WorldSpaceLightPos0 取得平行光的位置
fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
//取得漫反射颜色
fixed3 diffuse = _LightColor0.rgb * max(dot(normalDir, lightDir), 0) * _Color.rgb;
//反射光方向
fixed3 reflectDir = normalize(reflect(-lightDir, normalDir));
//当前点到摄像机的方向
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - f.worldVertex);
//高光反射
fixed3 specular = _LightColor0.rgb * pow(max(dot(reflectDir, viewDir), 0), _Gloss) *_SpecularColor;
//环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
//颜色叠加
fixed3 tempColor = diffuse + specular + ambient;
return fixed4(tempColor,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
对比:
上一篇: Hadoop之命令操作
下一篇: Java游戏之简单版雷霆战机