UnityShader---高级纹理(反射、折射、菲涅尔反射、镜子\玻璃效果)(内置渲染管线)---11

反射:代码里有阴影和衰减计算

Shader "Unlit/17"
{
    Properties
    {
        _Color("Color",Color)=(1,1,1,1)
        _ReflectColor("ReflectColor",Color)=(1,1,1,1)
        _ReflectAmount("ReflectAmount",Range(0,1))=0.5
        _CubeMap("CubeMap",Cube)="cube"{}
    }
        SubShader
    {
        Tags { "RenderType" = "Opaque" }
        LOD 100

        Pass
        {
            Tags{"LightMode" = "ForwardBase"}
            Cull Off

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag            

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"

            fixed4 _Color;
            fixed4 _ReflectColor;
            fixed _ReflectAmount;
            samplerCUBE _CubeMap;

            struct a2v
            {
                float4 vertex : POSITION;
                float3 normal:NORMAL;
            };

            struct v2f
            {
                float4 pos:SV_POSITION;
                float3 worldPos:TEXCOORD0;
                float3 worldNormal:TEXCOORD1;
                float3 worldLight:TEXCOORD2;
                float3 worldView:TEXCOORD3;
                float3 worldReflect:TEXCOORD4;
                SHADOW_COORDS(5)
            };            

            v2f vert (a2v v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);   
                
                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
               
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                
                o.worldLight = UnityWorldSpaceLightDir(o.worldPos);

                o.worldView = UnityWorldSpaceViewDir(o.worldPos);

                o.worldReflect = reflect(-o.worldView,o.worldNormal);

                TRANSFER_SHADOW(o);

                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                fixed3 worldNormal = normalize(i.worldNormal);
                fixed3 worldLight = normalize(i.worldLight);
                fixed3 worldView = normalize(i.worldView);

                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;

                fixed3 diffuse = _LightColor0.rgb * _Color.rgb * saturate(dot(worldNormal,worldLight));
                
                fixed3 reflection = texCUBE(_CubeMap,i.worldReflect).rgb * _ReflectColor.rgb;

                UNITY_LIGHT_ATTENUATION(atten,i,i.worldPos);

                fixed3 color = ambient + lerp(diffuse, reflection, _ReflectAmount) * atten;

                return fixed4(color ,1.0);
            }
            ENDCG
        }
    }
}

折射:

Shader "Unlit/18"
{
    Properties
    {
        _Color("Color",Color)=(1,1,1,1)
        _RefractColor("RefractColor",Color)=(1,1,1,1)
        _RefractAmount("RefractAmount",Range(0,1))=0.5
        _RefractRatio("Ratio",Range(0,1))=0.5
        _Cubemap("RefractionMap",Cube)="cube"{}
    }
        SubShader
    {
        Tags { "RenderType" = "Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag           

            #include "UnityCG.cginc"
            #include "AutoLight.cginc"
            #include "Lighting.cginc"

            fixed4 _Color;
            fixed4 _RefractColor;
            fixed _RefractAmount;
            fixed _RefractRatio;
            samplerCUBE _Cubemap;

            struct a2v
            {
                float4 vertex : POSITION;
                float3 normal:NORMAL;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                float3 worldPos:TEXCOORD0;
                float3 worldNormal:TEXCOORD1;
                float3 worldLight:TEXCOORD2;
                float3 worldView:TEXCOORD3;
                float3 worldRefract:TEXCOORD4;
                SHADOW_COORDS(5)
            };

            v2f vert (a2v v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);

                o.worldPos = mul(unity_ObjectToWorld,v.vertex);

                o.worldNormal = UnityObjectToWorldNormal(v.normal);

                o.worldLight = UnityWorldSpaceLightDir(o.worldPos);

                o.worldView = UnityWorldSpaceViewDir(o.worldPos);

                o.worldRefract = refract(-normalize(o.worldView),normalize(o.worldNormal),_RefractRatio);

                TRANSFER_SHADOW(o);

                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                fixed3 worldNormal = normalize(i.worldNormal);
                fixed3 worldLight = normalize(i.worldLight);
                fixed3 worldView = normalize(i.worldView);

                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
                
                fixed3 diffuse = _LightColor0.rgb * _Color.rgb * saturate(dot(worldNormal,worldLight));

                fixed3 refraction = texCUBE(_Cubemap,i.worldRefract) * _RefractColor.rgb;

                UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);

                fixed3 color = ambient + lerp(diffuse,refraction,_RefractAmount) * atten;

                return fixed4(color,1.0);
            }
            ENDCG
        }
    }
}

菲尼尔反射:

Shader "Unlit/19"
{
	Properties
	{
	   _Color("Color",Color) = (1,1,1,1)
	   _FresnelScale("FresnelScale",Range(0,1)) = 0.5
	   _Cubemap("CubeMap",Cube) = "_Skybox"{}
	}
		SubShader
	{
		Tags { "RenderType" = "Opaque" }
		LOD 100
		
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag           

			#include "UnityCG.cginc"
			#include "Lighting.cginc"
			#include "AutoLight.cginc"

			fixed4 _Color;
			fixed _FresnelScale;
			samplerCUBE _Cubemap;

			struct a2v
			{
				float4 vertex : POSITION;
				float3 normal:NORMAL;
			};

			struct v2f
			{
				float4 pos : SV_POSITION;
				float3 worldPos:TEXCOORD0;
				float3 worldNormal:TEXCOORD1;
				float3 worldLight:TEXCOORD2;
				float3 worldView:TEXCOORD3;
				float3 worldReflect:TEXCOORD4;
				UNITY_SHADOW_COORDS(5)
			};

			v2f vert(a2v v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);

				o.worldPos = mul(unity_ObjectToWorld, v.vertex);

				o.worldNormal = UnityObjectToWorldNormal(v.normal);

				o.worldLight = UnityWorldSpaceLightDir(o.worldPos);

				o.worldView = UnityWorldSpaceViewDir(o.worldPos);

				o.worldReflect = reflect(-o.worldView, o.worldNormal);

				TRANSFER_SHADOW(o);

				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				fixed3 worldNormal = normalize(i.worldNormal);

				fixed3 worldLight = normalize(i.worldLight);

				fixed3 worldView = normalize(i.worldView);

				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;

				fixed3 diffuse = _LightColor0.rgb * _Color.rgb * saturate(dot(worldNormal,worldLight));

				fixed3 reflection = texCUBE(_Cubemap,i.worldReflect).rgb;

				//_FresnelSacle=0时,菲涅尔反射,_FresnelScale=1时,完全反射
				float fresnel = _FresnelScale + (1 - _FresnelScale) * pow(1 - dot(worldNormal, worldView),5);

				UNITY_LIGHT_ATTENUATION(atten,i,i.worldPos);

				fixed3 color = ambient + lerp( diffuse , reflection ,saturate( fresnel ) ) * atten;

				return fixed4(color,1.0);
			}
			ENDCG
		}
	}
}

镜子效果:

Shader "Unlit/20"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag          

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);  

                //反转X坐标即可
                o.uv.x = 1 - o.uv.x;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {             
                return = tex2D(_MainTex, i.uv);     
            }
            ENDCG
        }
    }
}

玻璃效果:

Shader "Unlit/21"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _BumpMap("Normal Map",2D)="bump"{}
        _CubeMap("Cube Map",Cube)="_Skybox"{}
        _Distortion("Distortion",Range(0,100))=10
        _RefractAmount("Refract Amount",Range(0,1))=1
    }
    SubShader
    {
        Tags{"Queue"="Transparent" "RenderType"="Opaque"}

        GrabPass{"_RefractionTex"}

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

            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _BumpMap;
            float4 _BumpMap_ST;
            samplerCUBE _CubeMap;
            float _Distortion;
            fixed _RefractAmount;

            sampler2D _RefractionTex;
            float4 _RefractionTex_TexelSize;


            struct a2v
            {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
                float3 normal:NORMAL;
                float4 tangent:TANGENT;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                float4 uv : TEXCOORD0;     
                float4 screenPos:TEXCOORD1;
                float4 T2W1:TEXCOORD2;
                float4 T2W2:TEXCOORD3;
                float4 T2W3:TEXCOORD4;
            };            

            v2f vert (a2v v)
            {
                v2f o;

                o.pos = UnityObjectToClipPos(v.vertex);

                //屏幕坐标
                o.screenPos = ComputeGrabScreenPos(o.pos);

                //uv
                o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex);   
                o.uv.zw = TRANSFORM_TEX(v.texcoord, _BumpMap);

                float3 worldPos = mul(unity_ObjectToWorld,v.vertex);

                //求切线空间到世界空间的变换矩阵
                fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
                fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
                fixed3 worldBinormal = cross(worldNormal,worldTangent) * v.tangent.w;

                o.T2W1 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);
                o.T2W2 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);
                o.T2W3 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);

                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                float3 worldPos = float3(i.T2W1.w,i.T2W2.w,i.T2W3.w);
                fixed3 worldView = normalize(UnityWorldSpaceViewDir(worldPos));

                //获取切线空间法线
                fixed3 bump = UnpackNormal(tex2D(_BumpMap,i.uv.zw));

                //偏移:法线 * 扰动 * 纹素
                float2 offset = bump.xy * _Distortion * _RefractionTex_TexelSize.xy;

                //屏幕坐标+偏移
                i.screenPos.xy = offset + i.screenPos.xy;

                //折射
                fixed3 refraction = tex2D(_RefractionTex,i.screenPos.xy/i.screenPos.w).rgb;

                //反射:需先求反射方向,便于立方体贴图采样,反射方向需要法线方向和视角方向
                //法线
                fixed3 worldNormal = normalize(half3(dot(i.T2W1.xyz,bump),dot(i.T2W2.xyz,bump),dot(i.T2W3.xyz,bump)));
                //反射方向
                float3 reflectDir = reflect(-worldView,worldNormal);

                //主纹理贴图
                fixed3 texColor = tex2D(_MainTex,i.uv.xy).rgb;

                //求得反射= 反射颜色 * 主纹理颜色
                fixed3 reflection = texCUBE(_CubeMap, reflectDir) * texColor;

                //反射和折射混合
                fixed3 color = reflection * (1 - _RefractAmount) + refraction * _RefractAmount;

                return fixed4(color,1.0);
            }
            ENDCG
        }
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值