В шейдерах почти ничего не смыслю, потому попробовал реализовать эту технику в StrumpyShaderEditor. Вышло что-то похожее на HDR, но есть определенные проблемы (например, белая окантовка по краям). Хотелось бы услышать ваши мнения. Надеюсь на помощь знающих людей)
Шейдер:
Синтаксис:
Используется glsl
Shader "ReflectionRimHDR"
{
Properties
{
_MainColor("_MainColor", Color) = (1,0,0,1)
_CubeMap("_CubeMap", Cube) = "" {}
_RangeHDR("_RangeHDR", Range(1.005,1.2) ) = 1.005
_NormalMap("_NormalMap", 2D) = "normal" {}
_RimPower("_RimPower", Range(0.1,3) ) = 1.8
_RimColor("_RimColor", Color) = (0.0597015,0.2503912,1,1)
_SpecPower("_SpecPower", Range(0.1,1) ) = 0.9
_MySpecColor("_MySpecColor", Color) = (1,1,1,1)
}
SubShader
{
Tags
{
"Queue"="Geometry"
"IgnoreProjector"="False"
"RenderType"="Opaque"
}
Cull Back
ZWrite On
ZTest LEqual
ColorMask RGBA
Blend One Zero
Fog{
}
CGPROGRAM
#pragma surface surf BlinnPhongEditor vertex:vert
#pragma exclude_renderers xbox360
#pragma target 3.0
float4 _MainColor;
samplerCUBE _CubeMap;
float _RangeHDR;
sampler2D _NormalMap;
float _RimPower;
float4 _RimColor;
float _SpecPower;
float4 _MySpecColor;
struct EditorSurfaceOutput {
half3 Albedo;
half3 Normal;
half3 Emission;
half3 Gloss;
half Specular;
half Alpha;
};
inline half4 LightingBlinnPhongEditor_PrePass (EditorSurfaceOutput s, half4 light)
{
half3 spec = light.a * s.Gloss;
half4 c;
c.rgb = (s.Albedo * light.rgb + light.rgb * spec);
c.a = s.Alpha + Luminance(spec);
return c;
}
inline half4 LightingBlinnPhongEditor (EditorSurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
{
viewDir = normalize(viewDir);
half3 h = normalize (lightDir + viewDir);
half diff = max (0, dot (s.Normal, lightDir));
float nh = max (0, dot (s.Normal, h));
float3 spec = pow (nh, s.Specular*128.0) * s.Gloss;
half4 res;
res.rgb = _LightColor0.rgb * (diff * atten * 2.0);
res.w = spec * Luminance (_LightColor0.rgb);
return LightingBlinnPhongEditor_PrePass( s, res );
}
struct Input {
float3 simpleWorldRefl;
float3 viewDir;
float2 uv_NormalMap;
};
void vert (inout appdata_full v, out Input o) {
float4 VertexOutputMaster0_0_NoInput = float4(0,0,0,0);
float4 VertexOutputMaster0_1_NoInput = float4(0,0,0,0);
float4 VertexOutputMaster0_2_NoInput = float4(0,0,0,0);
float4 VertexOutputMaster0_3_NoInput = float4(0,0,0,0);
o.simpleWorldRefl = -reflect( normalize(WorldSpaceViewDir(v.vertex)), normalize(mul((float3x3)_Object2World, SCALED_NORMAL)));
}
void surf (Input IN, inout EditorSurfaceOutput o) {
o.Albedo = 0.0;
o.Normal = float3(0.0,0.0,1.0);
o.Emission = 0.0;
o.Gloss = 0.0;
o.Specular = 0.0;
o.Alpha = 1.0;
float4 TexCUBE0=texCUBE(_CubeMap,float4( IN.simpleWorldRefl, 1.0));
float4 Mask1=float4(0.0,0.0,0.0,TexCUBE0.w);
float4 Mask0=float4(TexCUBE0.x,TexCUBE0.y,TexCUBE0.z,0.0);
float4 Multiply1=float4( 255) * Mask0;
float4 Subtract0=Multiply1 - float4( 128);
float4 Pow1=pow(_RangeHDR.xxxx,Subtract0);
float4 Add1=Mask1 + Pow1;
float4 Tex2DNormal0=UnpackNormal( tex2D(_NormalMap,(IN.uv_NormalMap.xyxy).xy) );
float4 Fresnel0=float4( 1.0 - dot( normalize( float4(IN.viewDir, 1.0).xyz), normalize( Tex2DNormal0.xyz ) ) );
float4 Pow0=pow(Fresnel0,_RimPower.xxxx);
float4 Multiply2=Add1 * Pow0;
float4 Add0=_MainColor + Multiply2;
float4 Multiply0=_RimColor * Pow0;
float4 Master0_5_NoInput = float4(1,1,1,1);
float4 Master0_6_NoInput = float4(1,1,1,1);
o.Albedo = Add0;
o.Normal = Tex2DNormal0;
o.Emission = Multiply0;
o.Specular = _SpecPower.xxxx;
o.Gloss = _MySpecColor;
o.Alpha = 1.0;
}
ENDCG
}
Fallback "Diffuse"
}
{
Properties
{
_MainColor("_MainColor", Color) = (1,0,0,1)
_CubeMap("_CubeMap", Cube) = "" {}
_RangeHDR("_RangeHDR", Range(1.005,1.2) ) = 1.005
_NormalMap("_NormalMap", 2D) = "normal" {}
_RimPower("_RimPower", Range(0.1,3) ) = 1.8
_RimColor("_RimColor", Color) = (0.0597015,0.2503912,1,1)
_SpecPower("_SpecPower", Range(0.1,1) ) = 0.9
_MySpecColor("_MySpecColor", Color) = (1,1,1,1)
}
SubShader
{
Tags
{
"Queue"="Geometry"
"IgnoreProjector"="False"
"RenderType"="Opaque"
}
Cull Back
ZWrite On
ZTest LEqual
ColorMask RGBA
Blend One Zero
Fog{
}
CGPROGRAM
#pragma surface surf BlinnPhongEditor vertex:vert
#pragma exclude_renderers xbox360
#pragma target 3.0
float4 _MainColor;
samplerCUBE _CubeMap;
float _RangeHDR;
sampler2D _NormalMap;
float _RimPower;
float4 _RimColor;
float _SpecPower;
float4 _MySpecColor;
struct EditorSurfaceOutput {
half3 Albedo;
half3 Normal;
half3 Emission;
half3 Gloss;
half Specular;
half Alpha;
};
inline half4 LightingBlinnPhongEditor_PrePass (EditorSurfaceOutput s, half4 light)
{
half3 spec = light.a * s.Gloss;
half4 c;
c.rgb = (s.Albedo * light.rgb + light.rgb * spec);
c.a = s.Alpha + Luminance(spec);
return c;
}
inline half4 LightingBlinnPhongEditor (EditorSurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
{
viewDir = normalize(viewDir);
half3 h = normalize (lightDir + viewDir);
half diff = max (0, dot (s.Normal, lightDir));
float nh = max (0, dot (s.Normal, h));
float3 spec = pow (nh, s.Specular*128.0) * s.Gloss;
half4 res;
res.rgb = _LightColor0.rgb * (diff * atten * 2.0);
res.w = spec * Luminance (_LightColor0.rgb);
return LightingBlinnPhongEditor_PrePass( s, res );
}
struct Input {
float3 simpleWorldRefl;
float3 viewDir;
float2 uv_NormalMap;
};
void vert (inout appdata_full v, out Input o) {
float4 VertexOutputMaster0_0_NoInput = float4(0,0,0,0);
float4 VertexOutputMaster0_1_NoInput = float4(0,0,0,0);
float4 VertexOutputMaster0_2_NoInput = float4(0,0,0,0);
float4 VertexOutputMaster0_3_NoInput = float4(0,0,0,0);
o.simpleWorldRefl = -reflect( normalize(WorldSpaceViewDir(v.vertex)), normalize(mul((float3x3)_Object2World, SCALED_NORMAL)));
}
void surf (Input IN, inout EditorSurfaceOutput o) {
o.Albedo = 0.0;
o.Normal = float3(0.0,0.0,1.0);
o.Emission = 0.0;
o.Gloss = 0.0;
o.Specular = 0.0;
o.Alpha = 1.0;
float4 TexCUBE0=texCUBE(_CubeMap,float4( IN.simpleWorldRefl, 1.0));
float4 Mask1=float4(0.0,0.0,0.0,TexCUBE0.w);
float4 Mask0=float4(TexCUBE0.x,TexCUBE0.y,TexCUBE0.z,0.0);
float4 Multiply1=float4( 255) * Mask0;
float4 Subtract0=Multiply1 - float4( 128);
float4 Pow1=pow(_RangeHDR.xxxx,Subtract0);
float4 Add1=Mask1 + Pow1;
float4 Tex2DNormal0=UnpackNormal( tex2D(_NormalMap,(IN.uv_NormalMap.xyxy).xy) );
float4 Fresnel0=float4( 1.0 - dot( normalize( float4(IN.viewDir, 1.0).xyz), normalize( Tex2DNormal0.xyz ) ) );
float4 Pow0=pow(Fresnel0,_RimPower.xxxx);
float4 Multiply2=Add1 * Pow0;
float4 Add0=_MainColor + Multiply2;
float4 Multiply0=_RimColor * Pow0;
float4 Master0_5_NoInput = float4(1,1,1,1);
float4 Master0_6_NoInput = float4(1,1,1,1);
o.Albedo = Add0;
o.Normal = Tex2DNormal0;
o.Emission = Multiply0;
o.Specular = _SpecPower.xxxx;
o.Gloss = _MySpecColor;
o.Alpha = 1.0;
}
ENDCG
}
Fallback "Diffuse"
}