您的位置:首页 > 移动开发 > Unity3D

Unity shader: Bank BRDF

2015-08-15 15:56 393 查看
Back BRDF是一种 模拟 金属表面 的 各向异性 光泽的经验模型,具体公式参照 GPU 编程与CG 语言之阳春白雪下里巴人 中120页的公式(10-14)

Shader "Custom/Bank-BRDF" {
Properties {
_AmbiColor ("Main Color", Color) = (1, 1, 1, 1)
_Ak ("Ambient Coef", float) = 1
_DiffColor ("Diff Color", Color) = (1, 1, 1, 1)
_Dk ("Diff Coef", float) = 1
_SpecColor ("Spec Color", Color) = (1, 1, 1, 1)
_Sk ("Sk", float) = 1
_Sp ("Sp", Range(0, 5)) = 1
}

SubShader {
Pass {
CGPROGRAM
#include "UnityCG.cginc"
#pragma vertex vert
#pragma fragment frag

float4 _AmbiColor;
float _Ak;
float4 _DiffColor;
float _Dk;
float4 _SpecColor;
float _Sk;
float _Sp;

struct v2f {
float4 pos : POSITION;
float3 normal : TEXCOORD0;
float3 light : TEXCOORD1;
float3 view : TEXCOORD2;
float3 targent : TEXCOORD3;
};

v2f vert(appdata_base v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.normal = v.normal;
o.light = ObjSpaceLightDir(v.vertex);
o.view = ObjSpaceViewDir(v.vertex);
o.targent = cross(v.normal, o.view);

return o;
}

float4 frag(v2f i) : COLOR {
float3 l = normalize(i.light);
float3 t = normalize(i.targent);
float3 v = normalize(i.view);
float3 n = normalize(i.normal);

float lt = dot(l, t);
float vt = dot(v, t);
float nl = dot(n, l);
float nv = dot(n, v);

float4 ambi = _AmbiColor * _Ak;
float4 diff = _Dk * _DiffColor * saturate(nl);

if (nl <= 0 || nv <= 0)
return ambi + diff;

float p = sqrt(1 - lt * lt) * sqrt(1 - vt * vt) - lt * vt;
float f = _Sk * pow(p, _Sp);
float spec = f * _SpecColor * saturate(dot(l, n));

return ambi + diff + spec;
}
ENDCG
}
}
FallBack "Diffuse"
}


效果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: