今天我们用学过的Shader知识实现一个简单的玻璃材质。
首先,玻璃是半透明的
玻璃最主要的特点就是它是透明的,不同的玻璃有不同的不透明度,水杯的透明度比较低,而装药品的棕色玻璃瓶不透明度就比较高。当然,玻璃也有一定的颜色。利用透明,我们可以这样实现玻璃材质:
Shader "Custom/GlassShader" {
Properties {
_MainTint("Main Color", Color) = (1, 1, 1, 1)
_AlphaVal("Alpha", Range(0, 1)) = 0.1
}
SubShader {
Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType"="Transparent" }
LOD 200
CGPROGRAM
#pragma surface surf BlinnPhong alpha
fixed4 _MainTint;
float _AlphaVal;
struct Input {
float3 viewDir;
};
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = _MainTint.rgb;
o.Alpha = _AlphaVal;
}
ENDCG
}
FallBack "Diffuse"
}
此时的效果是这样的,可以看到透明效果,但是它看上去更像两块粗糙的透明的塑料片。
给玻璃增加反射效果
为了表现这是光滑的玻璃而非塑料,我们增加反射属性,利用天空盒实现简单的反射效果,此时的代码是这样的:
Shader "Custom/GlassShader" {
Properties {
_MainTint("Main Color", Color) = (1, 1, 1, 1)
_AlphaVal("Alpha", Range(0, 1)) = 0.1
_CubeMap("Sky Box", CUBE) = ""{}
_ReflPower("Reflect Power", Range(0, 1)) = 1
}
SubShader {
Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType"="Transparent" }
LOD 200
CGPROGRAM
#pragma surface surf BlinnPhong alpha
fixed4 _MainTint;
float _AlphaVal;
samplerCUBE _CubeMap;
float _ReflPower;
struct Input {
float3 worldRefl;
float3 viewDir;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 s = texCUBE(_CubeMap, IN.worldRefl);
o.Albedo = _MainTint.rgb;
o.Emission = s.rgb * _ReflPower;
o.Alpha = _AlphaVal;
}
ENDCG
}
FallBack "Diffuse"
}这时候玻璃就有了反射效果,尤其是当我们从不同角度看的时候,会看到玻璃反射了场景中的景象,当然这其实是假的,那来自我们指定的天空盒。
给玻璃增加菲涅尔效果
曾经说到过菲涅尔菲先生的效果非常不错,可以根据视角控制反射的强弱。我们的玻璃当然也可以应用这种效果:
Shader "Custom/GlassShader" {
Properties {
_MainTint("Main Color", Color) = (1, 1, 1, 1)
_AlphaVal("Alpha", Range(0, 1)) = 0.1
_CubeMap("Sky Box", CUBE) = ""{}
_ReflPower("Reflect Power", Range(0, 1)) = 1
_FresnelPower("Fresnel Power", Range(0.1, 5)) = 2
}
SubShader {
Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType"="Transparent" }
LOD 200
CGPROGRAM
#pragma surface surf BlinnPhong alpha
fixed4 _MainTint;
float _AlphaVal;
samplerCUBE _CubeMap;
float _ReflPower;
float _FresnelPower;
struct Input {
float3 worldRefl;
float3 viewDir;
};
void surf (Input IN, inout SurfaceOutput o) {
float rim = 1.0 - max(0, dot(o.Normal, normalize(IN.viewDir)));
rim = pow(rim, _FresnelPower);
half4 s = texCUBE(_CubeMap, IN.worldRefl);
o.Albedo = _MainTint.rgb;
o.Emission = s.rgb * _ReflPower * rim;
o.Alpha = _AlphaVal;
}
ENDCG
}
FallBack "Diffuse"
}下面上本次的最终效果图:
结束语
掌握了一些基本的Shader知识以后,剩下的就是继续深入研究和利用已有的知识实现想要的效果,Shader是灵活的,我们完全可以根据自己的想法去实现想要材质。就算有人觉得效果不好,也可以悄悄告诉他:“这是艺术…”。
版权声明:本文为dbtxdxy原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。