shader篇-纹理-渐变纹理

本文介绍如何使用渐变纹理来控制漫反射光照结构,这是在卡通渲染中常用的技术。文章提供了详细的Shader代码实现,并解释了配置参数及顶点、片元着色器的工作原理。

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

shader篇-纹理-渐变纹理


简介

==

纹理的一开始的作用是用以定义物体的颜色,但后面发现纹理可以存储任何表面属性。比如说,使用渐变纹理来控制漫反射光照的结构。在很多卡通风格的渲染中都使用了该技术。

代码实现

配置

Properties {
        _Color ("Color Tint", 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;

    //利用内置函数计算平铺和偏移后的纹理坐标
    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(worldLightDir + viewDir);
    fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)), _Gloss);

    return fixed4(ambient + diffuse + specular, 1.0);
}

_RampTex实际上是一个一维纹理,因此纹理坐标的u和v方向我们都使用了halfLambert

注意

渐变纹理的wrap mode应设为clamp模式,防止对纹理采样由于浮动数精度造成一些问题。

最终效果

这里写图片描述
渐变纹理
这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值