简单的玻璃材质效果——UnityShader学习笔记


自言自语

最近一直工作比较忙,但也没有放弃shader学习,今天又从同事那里GET到了一个效果,比较简单,但是效果还不错。性价比应该还不错。笔记下来,以后可以拿来用用。 不过自己计算的改动就是没啥道理。所以要论证理论正确性可能是没有的。不过我是美术,好看就完事儿了。

一、效果

在这里插入图片描述
在这里插入图片描述

二、Shader(Builltin)

Shader "TNShaderPractise/GlassBottle"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "black" {}
        _MainTex2 ("Texture2", 2D) = "black" {}
        _MaskTex ("_MaskTex", 2D) = "black" {}
		_MatCap01Pow("_MatCap01Pow",Float)=1
		_refract("_refract",Float) =1
		[HDR]_refacColor("_refacColor",Color)=(0,0,0,1)
    }
    SubShader
    {
        Tags { "RenderType"="Transparent"  "Queue" = "Transparent"}

        Pass
        {
			Blend SrcAlpha OneMinusSrcAlpha
            Cull Off
            ZWrite Off
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct a2v
            {
                float4 vertex : POSITION;
				half3 normal : NORMAL;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
				half3 normalWS : TEXCOORD1;		
                float4 pos : SV_POSITION;
				float4 posWS : TEXCOORD2;
				float4 vPOS : TEXCOORD3;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;	   
			sampler2D _MainTex2;
            float4 _MainTex2_ST;  
			sampler2D _MaskTex;
            float4 _MaskTex_ST;

			float _MatCap01Pow;
			float _refract;
			float4 _refacColor;


            v2f vert (a2v v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
				o.posWS = mul(unity_ObjectToWorld,v.vertex);
				o.normalWS = UnityObjectToWorldNormal(v.normal);
                o.uv = v.texcoord;
				o.vPOS = o.posWS - v.vertex;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
				half3 viewDir = normalize(UnityWorldSpaceViewDir(i.posWS));
				half3 normalVS = normalize(mul(UNITY_MATRIX_V,i.normalWS));
				//改进版matCapUV
				float3 posVS = normalize(mul(UNITY_MATRIX_V,i.posWS));
				normalVS = cross(posVS,normalVS);
				normalVS.y = - normalVS.y;

				

				half thickMask = tex2D (_MaskTex,i.uv).g;
				half NdotV = abs(dot(i.normalWS,viewDir));
				half fresnel = smoothstep(1,0,NdotV);
				fresnel = fresnel+thickMask;

				float uvOffset = fresnel*_refract;

				float2 matCapUV = normalVS.yx*0.5+0.5;
				float2 matCapUV2 = uvOffset+matCapUV;
				
				half4 matCap01 = tex2D(_MainTex,matCapUV)*_MatCap01Pow;


				half4 matCap02 = tex2D(_MainTex2,matCapUV2);

				matCap02 = lerp (_refacColor*0.5,_refacColor*matCap02,clamp(0,1,uvOffset));
				float alpha = saturate(max(matCap01.r,fresnel*fresnel));

				half4 col = matCap01+ matCap02;

                return float4(col.rgb,alpha);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

三、修改版来了

效果

在这里插入图片描述

Shader

Shader "TNShaderPractise/GlassBottle"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "black" {}
        _MainTex2 ("Texture2", 2D) = "black" {}
        _MaskTex ("_MaskTex", 2D) = "black" {}
		_MatCap01Pow("_MatCap01Pow",Float)=1
		_refract("_refract",Float) =1
		[HDR]_refacColor("_refacColor",Color)=(0,0,0,1)
        _DecalTex ("DecalTex",2D) = "black"{} 
        [HDR]_DecalColor("DecalColor",Color)=(1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Transparent"  "Queue" = "Transparent"}

        Pass
        {
			Blend SrcAlpha OneMinusSrcAlpha
            Cull Front
            ZWrite Off
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct a2v
            {
                float4 vertex : POSITION;
				half3 normal : NORMAL;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
				half3 normalWS : TEXCOORD1;		
                float4 pos : SV_POSITION;
				float4 posWS : TEXCOORD2;
				float4 vPOS : TEXCOORD3;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;	   
			sampler2D _MainTex2;
            float4 _MainTex2_ST;  
			sampler2D _MaskTex;
            float4 _MaskTex_ST;    
            sampler2D _DecalTex;
            float4 _DecalTex_ST;
            float4 _DecalColor;

			float _MatCap01Pow;
			float _refract;
			float4 _refacColor;


            v2f vert (a2v v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
				o.posWS = mul(unity_ObjectToWorld,v.vertex);
				o.normalWS = UnityObjectToWorldNormal(v.normal);
                o.uv = v.texcoord;
				o.vPOS = o.posWS - v.vertex;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
				half3 viewDir = normalize(UnityWorldSpaceViewDir(i.posWS));
				half3 normalVS = normalize(mul(UNITY_MATRIX_V,i.normalWS));
				//改进版matCapUV
				float3 posVS = normalize(mul(UNITY_MATRIX_V,i.posWS));
				normalVS = cross(posVS,normalVS);
				normalVS.y = - normalVS.y;

				

				half thickMask = tex2D (_MaskTex,i.uv*_MaskTex_ST.xy+_MaskTex_ST.zw).g;
				half NdotV = abs(dot(i.normalWS,viewDir));
				half fresnel = smoothstep(1,0,NdotV);
				fresnel = fresnel+thickMask;

				float uvOffset = fresnel*_refract;

				float2 matCapUV = normalVS.yx*0.5+0.5;
				float2 matCapUV2 = uvOffset+matCapUV;
				
				half4 matCap01 = tex2D(_MainTex,matCapUV)*_MatCap01Pow;
				half4 matCap02 = tex2D(_MainTex2,matCapUV2);

                half4 Decal = tex2D(_DecalTex,i.uv*_DecalTex_ST.xy+_DecalTex_ST.zw)*_DecalColor;

				matCap02 = lerp (_refacColor*0.5,_refacColor*matCap02,clamp(0,1,uvOffset));


				float alpha = saturate(max(matCap01.r,fresnel*fresnel));
                float alphaDecal = smoothstep(0,0.1,Decal.r);

				half4 col = matCap01+ matCap02;
                col = lerp(col,Decal,alphaDecal);
                
                float finalAlpha =  lerp(alpha,alphaDecal,alphaDecal);

                return float4(col.rgb,finalAlpha);
            }
            ENDCG
        }
        Pass
        {
			Blend SrcAlpha OneMinusSrcAlpha
            Cull Back
            ZWrite Off
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct a2v
            {
                float4 vertex : POSITION;
				half3 normal : NORMAL;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
				half3 normalWS : TEXCOORD1;		
                float4 pos : SV_POSITION;
				float4 posWS : TEXCOORD2;
				float4 vPOS : TEXCOORD3;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;	   
			sampler2D _MainTex2;
            float4 _MainTex2_ST;  
			sampler2D _MaskTex;
            float4 _MaskTex_ST;    
            sampler2D _DecalTex;
            float4 _DecalTex_ST;
            float4 _DecalColor;

			float _MatCap01Pow;
			float _refract;
			float4 _refacColor;


            v2f vert (a2v v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
				o.posWS = mul(unity_ObjectToWorld,v.vertex);
				o.normalWS = UnityObjectToWorldNormal(v.normal);
                o.uv = v.texcoord;
				o.vPOS = o.posWS - v.vertex;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
				half3 viewDir = normalize(UnityWorldSpaceViewDir(i.posWS));
				half3 normalVS = normalize(mul(UNITY_MATRIX_V,i.normalWS));
				//改进版matCapUV
				float3 posVS = normalize(mul(UNITY_MATRIX_V,i.posWS));
				normalVS = cross(posVS,normalVS);
				normalVS.y = - normalVS.y;

				

				half thickMask = tex2D (_MaskTex,i.uv*_MaskTex_ST.xy+_MaskTex_ST.zw).g;
				half NdotV = abs(dot(i.normalWS,viewDir));
				half fresnel = smoothstep(1,0,NdotV);
				fresnel = fresnel+thickMask;

				float uvOffset = fresnel*_refract;

				float2 matCapUV = normalVS.yx*0.5+0.5;
				float2 matCapUV2 = uvOffset+matCapUV;
				
				half4 matCap01 = tex2D(_MainTex,matCapUV)*_MatCap01Pow;
				half4 matCap02 = tex2D(_MainTex2,matCapUV2);

                half4 Decal = tex2D(_DecalTex,i.uv*_DecalTex_ST.xy+_DecalTex_ST.zw)*_DecalColor;
                //志诚大佬纠正我透明度取值的问题 提出用灰度计算不会影响后边的颜色计算
                half DecalAlpha = Decal.r*0.2125+Decal.g*0.7154+Decal.b*0.0721;

				matCap02 = lerp (_refacColor*0.5,_refacColor*matCap02,clamp(0,1,uvOffset));

				float alpha = max(matCap01.r,fresnel*fresnel);
                float alphaDecal = smoothstep(0,0.08,DecalAlpha);

				half4 col = matCap01+ matCap02;
                col = lerp(col,Decal,alphaDecal);
                
                float finalAlpha =  lerp(alpha,alphaDecal,alphaDecal);

                return float4(col.rgb,finalAlpha);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

总结

继续加油

  • 9
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值