《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

相关推荐
ThreePointsHeat18 小时前
Unity 关于打包WebGL + jslib录制RenderTexture画面
unity·c#·webgl
胡童嘉20 小时前
长沙烈焰鸟网络科技有限公司实习day13日记
功能测试·学习·职场和发展·游戏引擎·cocos2d
y***54881 天前
C++在游戏引擎中的开发
开发语言·c++·游戏引擎
BuHuaX1 天前
Unity_AssetBundle相关
unity·c#·游戏引擎·游戏策划
神码编程1 天前
【Unity】 HTFramework框架(六十八)StringEditor字符串复杂编辑器
unity·编辑器·游戏引擎·htframework
开发游戏的老王1 天前
UE5.6 C++项目升级UE5.7时用Rider加载项目失败的解决办法
ue5·游戏引擎·虚幻·虚幻引擎·rider·ue5.7·target.cs
TO_ZRG1 天前
Unity-iPhone、Unity-Framework target 如何选择、@rpath报错
unity·ios·iphone
平行云1 天前
World Labs & Paraverse:统一3D世界的创造与访问
3d·unity·ai·ue5·aigc·实时云渲染·云xr
jtymyxmz2 天前
《Unity Shader》7.2.3 实践 在切线空间下计算
unity·游戏引擎