《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

相关推荐
淡海水4 小时前
16-02-C#常用数据结构源码-附录B-源码索引速查
unity·c#·游戏引擎·il2cpp
速易达网络6 小时前
无人机远程操控仿真
游戏引擎·cocos2d
郝学胜-神的一滴6 小时前
游戏引擎原理与实践 02:揭开3A游戏背后的技术面纱
开发语言·计算机网络·程序人生·游戏·游戏引擎
警醒与鞭策14 小时前
【无标题】
android·unity·性能优化·游戏引擎·perforce
zhchyun200816 小时前
【Unity UI 进阶】仿 Element UI 打造企业级 Unity UI 组件库(10)
ui·unity·游戏引擎
地狱为王20 小时前
Unity使用NVIDIA的Audio2Face驱动口型
unity·游戏引擎
ebiobiz1 天前
STM32F4 Unity 单元测试与多次测试失败率统计详细步骤
stm32·unity·单元测试
一线灵1 天前
跨平台游戏引擎 Axmol-2.11.5 发布
游戏引擎·lua
淡海水1 天前
16-01-C#数据结构源码-附录A-术语表
unity·c#·游戏引擎·il2cpp
淡海水1 天前
16-03-C#数据结构源码-附录C-参考资源
unity·c#·游戏引擎·il2cpp