Shader山下(七)立方体反射【前编】

反射着色器可以获取外界的场景信息,并将它们反映到材质表面来模拟周围环境。

本文就要实现一个模拟反射的着色器,这里我们需要使用Cubemap来完成这个功能。

首先创建一个Cubemap:


然后编辑Cubemap:


这里建议先使用Unity自带的Default-Particle先看看效果。

接着我们开始编写shader:

Shader "Custom/Reflection/Base" {
	Properties {
		_MainTex ("Albedo (RGB)", 2D) = "white" {}
		_MainTint ("Main Tint", Color) = (1,1,1,1)
		_CubeMap ("CubeMap", CUBE) = "" {}
		_ReflAmount ("Reflection Amount", Range(0.01, 1)) = 0.5
	}
	SubShader {
		Tags { "RenderType"="Opaque"}
		LOD 200
		
		CGPROGRAM
		#pragma surface surf Lambert

		sampler2D _MainTex;
		fixed4 _MainTint;
		samplerCUBE _CubeMap;
		fixed _ReflAmount;

		struct Input {
			float2 uv_MainTex;
			float3 worldRefl;
		};

		void surf (Input IN, inout SurfaceOutput o) {
			fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _MainTint;
			o.Emission = texCUBE(_CubeMap, IN.worldRefl).rgb * _ReflAmount;
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}

		ENDCG
	}
	FallBack "Diffuse"
}
代码很简单。需要注意几个点:

1、Input里面增加了worldRefl变量,表示世界空间的反射向量。如图所示:

worldRefl = viewDir - 2.0 * normal * dot(viewDir, normal)

2、使用texCUBE获取worldRefl位置上的Cubemap上的色彩值,然后乘以系数传递给o.Emission(自发光)。

将shader和Cubemap应用到场景物体上就会获得这样的效果:


接着我们可以替换Cubemap上的图片,来感受反射的不同,例如把Right替换成:


就会获得:



接着我们为反射增加遮罩。

首先在Properties里添加:

		_ReflMask ("Reflection Mask", 2D) = "" {}
SubShader里添加:
sampler2D _ReflMask;
修改surf方法:

		void surf (Input IN, inout SurfaceOutput o) {
			fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _MainTint;
			fixed3 r = texCUBE(_CubeMap, IN.worldRefl).rgb;
			fixed4 m = tex2D (_ReflMask, IN.uv_MainTex);

			o.Emission = (r * m.r) * _ReflAmount;

			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}

修改很少,只是获取了mask里面的色彩值,与Cubemap上的色彩值相乘。

可以使用这张图片作为遮罩:


得到效果:



其他应用:

Shader山下(九)立方体反射【后编】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值