Попытка реализовать в юнити алгоритм Орен-Наяр. Вот что получилось:
Помогите разобраться
Шейдер:
Синтаксис:
Используется glsl
Shader "MyShaders/Oren-Nayar" {
Properties {
_Color("Main Color", Color) = (1,1,1,1)
_SpecColor("Specular Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB)", 2D) = "white" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
_Shininess("Shininess", Range(0.001, 1)) = 0.1
_Roughness("Roughness", Range(0, 1)) = 0.3
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf OrenNayarBlinn
#pragma target 3.0
half _Roughness;
half4 LightingOrenNayarBlinn (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) {
half diff = max(dot(s.Normal, lightDir), 0.0);
half nh = max (0, dot (s.Normal, normalize(lightDir + viewDir)));
half spec = pow(nh, s.Specular * 128);
half rs = _Roughness * _Roughness;
half a = 1 - 0.5 * rs / (rs + 0.33);
half b = 0.45 * rs / (rs + 0.09);
half nl = dot(s.Normal, lightDir);
half nv = dot(s.Normal, viewDir);
half3 lProj = normalize(lightDir - s.Normal * nl);
half3 vProj = normalize(viewDir - s.Normal * nv);
half cx = max(dot(lProj, vProj), 0);
half cosAlpha = nl > nv ? nl : nv;
half cosBeta = nl > nv ? nv : nl;
half dx = sqrt((1 - cosAlpha * cosAlpha) * (1 - cosBeta * cosBeta)) / cosBeta;
half4 c;
c.rgb = ((s.Albedo * max(0, nl) * diff * _LightColor0.rgb * (a + b * cx * dx)) + (_LightColor0.rgb * spec * _SpecColor.rgb)) * atten;
c.a = 1.0;
return c;
}
half _Shininess;
half4 _Color;
sampler2D _MainTex;
sampler2D _BumpMap;
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb * _Color.rgb;
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
o.Specular = _Shininess;
o.Alpha = c.a * _Color.a;
}
ENDCG
}
FallBack "Diffuse"
}
Properties {
_Color("Main Color", Color) = (1,1,1,1)
_SpecColor("Specular Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB)", 2D) = "white" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
_Shininess("Shininess", Range(0.001, 1)) = 0.1
_Roughness("Roughness", Range(0, 1)) = 0.3
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf OrenNayarBlinn
#pragma target 3.0
half _Roughness;
half4 LightingOrenNayarBlinn (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) {
half diff = max(dot(s.Normal, lightDir), 0.0);
half nh = max (0, dot (s.Normal, normalize(lightDir + viewDir)));
half spec = pow(nh, s.Specular * 128);
half rs = _Roughness * _Roughness;
half a = 1 - 0.5 * rs / (rs + 0.33);
half b = 0.45 * rs / (rs + 0.09);
half nl = dot(s.Normal, lightDir);
half nv = dot(s.Normal, viewDir);
half3 lProj = normalize(lightDir - s.Normal * nl);
half3 vProj = normalize(viewDir - s.Normal * nv);
half cx = max(dot(lProj, vProj), 0);
half cosAlpha = nl > nv ? nl : nv;
half cosBeta = nl > nv ? nv : nl;
half dx = sqrt((1 - cosAlpha * cosAlpha) * (1 - cosBeta * cosBeta)) / cosBeta;
half4 c;
c.rgb = ((s.Albedo * max(0, nl) * diff * _LightColor0.rgb * (a + b * cx * dx)) + (_LightColor0.rgb * spec * _SpecColor.rgb)) * atten;
c.a = 1.0;
return c;
}
half _Shininess;
half4 _Color;
sampler2D _MainTex;
sampler2D _BumpMap;
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb * _Color.rgb;
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
o.Specular = _Shininess;
o.Alpha = c.a * _Color.a;
}
ENDCG
}
FallBack "Diffuse"
}
Источник http://steps3d.narod.ru/tutorials/lighting-tutorial.html