Unity Shader入门教程(六) :渐变纹理

此博客承接上篇教程,介绍渐变纹理的实现方法。需准备一张渐变图,并将纹理的Wrap Mode设为Clamp模式,因Repeat模式在高光区会因浮点精度问题产生黑点。还给出了渐变纹理的shader代码及单句注释。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在了解了上篇教程后,实现渐变纹理就比较简单了。我们需要准备一张渐变图即可。渐变图的参考如下:

需要注意的是,需要将该纹理的Wrap Mode设置为Clamp模式。这是因为在使用Repeat模式时在高光区域会产生一些黑点,如下

这是由于浮点精度造成的,当我们使用fixed2(halfLambert,halfLambert)对渐变纹理进行纹理采样时,虽然理论上的值在[0,1],但可能会有1.00001的值出现。如果使用repeat模式,此时会舍弃整数部分,只保留小数部分,得到的就为0.00001,对应了渐变图中最左边的颜色,此时呈现黑色。

接下来渐变纹理的shader如下,单句代码的注释也写在代码中了。

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

Shader "Custom/RampTexture"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
		_RampTex("Ramp Tex", 2D) = "white"{}
		_Specular("Specular", Color) = (1, 1, 1, 1)
		_Gloss("Gloss", Range(8.0, 256)) = 20
	}
	SubShader
	{
		Pass
		{
			Tags{"LightMode" = "ForwardBase"}

			CGPROGRAM

			#pragma vertex vert
			#pragma fragment frag
			#include "Lighting.cginc"

			fixed4 _Color;
			sampler2D _RampTex;
			float4 _RampTex_ST;
			fixed4 _Specular;
			float _Gloss;

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

			struct v2f {
				float4 pos : SV_POSITION;
				float3 worldNormal : TEXCOORD0;
				float3 worldPos : TEXCOORD1;
				float2 uv : TEXCOORD2;
			};

			v2f vert(a2v v) {
				v2f o;

				o.pos = UnityObjectToClipPos(v.vertex);
				//计算世界空间下的法线方向
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				//转世界坐标
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
				//unity内置宏,计算平铺和偏移后的纹理坐标
				o.uv = TRANSFORM_TEX(v.texcoord, _RampTex);

				return o;
			}

			fixed4 frag(v2f i) : SV_Target{
				//将世界空间下的法线向量单位化
				fixed3 worldNormal = normalize(i.worldNormal);
				//获取世界空间下的光照方向
				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));

				//获取环境光
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
				//半兰伯特模型,并用此模型对渐变纹理进行纹理采样(半兰伯特模型在教程三中有讲)
				fixed halfLambert = 0.5 * dot(worldNormal, worldLightDir) + 0.5;
				fixed3 diffuseColor = tex2D(_RampTex, fixed2(halfLambert, halfLambert)).rgb * _Color.rgb;

				//漫反射计算
				fixed3 diffuse = _LightColor0.rgb * diffuseColor;
				//镜面反射计算公式
				fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
				fixed3 halfDir = normalize(viewDir + worldLightDir);
				fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)), _Gloss);

				return fixed4(ambient + diffuse + specular, 1.0);
			}
			ENDCG
		}
	}
    FallBack "Specular"
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值