《Unity Shader》7.3 渐变纹理

( 1)在Unity中新建一个场景。在本书资源中,该场景名为Scene_7_3。在Unity 5.2中,默认情况下场景将包含一个摄像机和一个平行光,并且使用了内置的天空盒子。在Window ->Lighting -> Skybox中去掉场景中的天空盒子。

点击 Window-rendering-lighting,点击 environment,点击 skybox material

(2)新建一个材质。在本书资源中,该材质名为RampTextureMat。

(3)新建一个Unity Shader。在本书资源中,该Unity Shader名为Chapter7-RampTexture。把新的Unity Shader赋给第2步中创建的材质。

(4)向场景中拖曳一个Suzanne模型,并把第2步中的材质赋给该模型。

读者可以在开源网站github(https://github.com/candycat1992/Unity_Shaders_Book)上下载本书的源代码。

点击 Assets/Models/Materials,找到对应模型

https://github.com/candycat1992/Unity_Shaders_Book/blob/master/Assets/Models/suzanne.obj

下载下来

找到文件后直接拖到 项目的Assets 里

再从 Assets 拖一个到Scene 里

点开suzanne,选择 default

5)保存场景。

打开新建的Chapter7-RampTexture,删除所有已有代码,并进行如下修改。

(1)首先,我们需要为这个Shader起一个名字:

(2)我们在Properties语义块中声明一个纹理属性来存储渐变纹理:

(3)然后,我们在SubShader语义块中定义了一个Pass语义块,并在Pass的第一行指明了该Pass的光照模式:

(4)然后,我们使用CGPROGRAM和ENDCG来包围住CG代码片,以定义最重要的顶点着色器和片元着色器代码。我们使用#pragma指令来告诉Unity,我们定义的顶点着色器和片元着色器叫什么名字。在本例中,它们的名字分别是vert和frag:

(5)为了使用Unity内置的一些变量,如_LightColor0,还需要包含进Unity的内置文件Lighting.cginc:

(6)随后,我们需要定义和Properties中各个属性类型相匹配的变量:

(7)定义顶点着色器的输入和输出结构体:

(8)定义顶点着色器:

(9)接下来是关键的片元着色器:

(10)最后,我们为该Unity Shader设置合适的Fallback:

java 复制代码
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/Chapter7-RampTexture"
{
    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); //TRANSFORM_TEX宏来计算经过平铺和偏移后的纹理坐标。
                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;
                //  Use  the  texture  to  sample  the  diffuse  color
                fixed  halfLambert   =  0.5 * dot(worldNormal,  worldLightDir)  +  0.5; //法线方向和光照方向的点积做一次0.5倍的缩放以及一个0.5大小的偏移来计算半兰伯特部分halfLambert,映射到了[0,1]之间
                fixed3   diffuseColor   =   tex2D(_RampTex,   fixed2(halfLambert,   halfLambert)).rgb * _Color.rgb;  //使用halfLambert来构建一个纹理坐标,并用这个纹理坐标对渐变纹理_RampTex进行采样
                //_RampTex实际就是一个一维纹理(它在纵轴方向上颜色不变),因此纹理坐标的u和v方向我们都使用了halfLambert
                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);
            }
            ENDCG
        }
    }

    Fallback "Specular"
}

保存后返回场景。我们在本书资源中提供了多种渐变纹理,如Ramp_Texture0.psd和Ramp_Texture1.psd等。读者可以尝试把不同的渐变纹理拖曳到材质面板查看效果。

https://github.com/candycat1992/Unity_Shaders_Book/blob/master/Assets/Textures/Chapter7/Ramp_Texture0.psd

https://github.com/candycat1992/Unity_Shaders_Book/blob/master/Assets/Textures/Chapter7/Ramp_Texture1.psd

下载对应的 texture,把 mat 赋予对应 tecture

相关推荐
真鬼12314 小时前
【Unity 6】Unity6快捷下载,快速下载
unity·游戏引擎
会潜水的小火龙15 小时前
unity打包apk报错Failure to initialize问题解决方法
unity·游戏引擎
平行云17 小时前
实时云渲染平台数据通道,支持3D应用文件上传下载分享无缝交互
linux·unity·云原生·ue5·gpu算力·实时云渲染·像素流送
Sator119 小时前
unity仅用粒子系统实现拖尾
unity·游戏引擎
游乐码19 小时前
Unity基础(五)四元数相关
unity·游戏引擎
想做后端的前端20 小时前
Unity热更新 - HybridCLR & YooAsset
unity·游戏引擎
鹿野素材屋20 小时前
Unity预加载:减少游戏中首次加载资源时的卡顿
windows·游戏·unity
RPGMZ20 小时前
RPGMZ游戏引擎事件技巧大全
javascript·游戏引擎·事件·rpgmz·rpgmakermz
天若有情67321 小时前
Superpowers 游戏引擎核心应用场景与落地指南
游戏引擎·superpowers
winlife_21 小时前
嵌入式 MCP server vs 外挂桥接进程:引擎编辑器自动化的架构取舍
架构·自动化·编辑器·游戏引擎·架构设计·mcp·编辑器自动化