Unity Shader学习(三)---纹理

纹理映射技术就是把一张图粘贴在模形的表面上

(一)用一张纹理来代替物体的漫反射颜色

 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Unity Shaders Book/Chapter 6/Blinn-Phong" {
    Properties {
        _Color ("Color Tint ",Color) = (1,1,1,1)
        _MainTex ("Main Tex",2D) = "white"{}//2D 是纹理属性
        _Specular ("Specular"Color) = (1111)
        _Gloss ("Gloss"Range(8.0256)) = 20
    }
    SubShader {
        Pass { 
            Tags { "LightMode"="ForwardBase" }
        
            CGPROGRAM
            
            #pragma vertex vert
            #pragma fragment frag
            
            #include "Lighting.cginc"
            
            fixed4 Color;
            sampler2D _MainTex;
            float4 _MainTex_ST;//纹理名_ST方式声明某个纹理的属性 _MainTex_ST.xy 存储的是缩放值,_MainTex_ST.zw存储的是偏移值

            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;
                // Transform the vertex from object space to projection space
                o.pos = UnityObjectToClipPos(v.vertex);
                
                // Transform the normal from object space to world space
                o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
                
                // Transform the vertex from object spacet to world space
                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                o.uv = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
                //或者用o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);进行纹理坐标变换
                return o;
            }
            
            fixed4 frag(v2f i) : SV_Target {
                // Get ambient term
                fixed3 albedo = tex2D(_MainTex,i.uv).rgb * _Color.rgb;
                //tex2D 用来对纹理进行采样,第一个参数_MainTex为纹理,i.uv为该点的纹素值,
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
                
                fixed3 worldNormal = normalize(i.worldNormal);
                fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
                
                // Compute diffuse term
                fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0dot(worldNormal, worldLightDir));
                
                // Get the view direction in world space
                fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
                // Get the half direction in world space
                fixed3 halfDir = normalize(worldLightDir + viewDir);
                // Compute specular term
                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0dot(worldNormal, halfDir)), _Gloss);
                
                return fixed4(ambient + diffuse + specular1.0);
            }
            
            ENDCG
        }
    } 
    FallBack "Specular"
}
纹理的类型:Texture, Normal map, Cubemap等

Alpha from Grayscale:设置透明通道的

Wrap Mode:可以设置为Repeat ,也可以设置为Tiling平铺

Filter Mode :滤波,Point Bilinear Trilinear三种,滤波效果一次提升,耗费也会变大

多级渐远纹理:提前用滤波技术得到很多小的图像,形成一个金字塔形,每一层都是对上一层采样的结果。当摄像机距离较远时,会使用小的纹理。这种技术会占用很多内存,以空间换取时间。

Advance类型的纹理,可以设置 Generate Mip Maps多级渐远纹理

导入的纹理可以是非正方形的,但是长宽的大小应该是2的幂,例如2,4,8等。如果非2的幂,会占用更多的内存空间,GPU读取纹理的速度也会下降。

Format决定了压缩的格式

(二)凹凸映射

凹凸映射目的是用一张纹理来修改模型表面的法线,为模型提供更多的细节。基本思想是通过改变表面法线,而不是使用纹理来改变光照方程中的颜色分量

实现凹凸映射有两种方法:

高度映射:利用高度纹理来模拟表面位移,得到一个修改后的法线值。

法线映射:使用一张法线纹理来直接存储表面法线,这种方法为法线映射。

1.高度纹理:用一张高度图来实现,主要是颜色不同,浅色表明向外凸起,深色为凹陷

2.法线纹理:法线纹理存储的就是表面的法线方向,由于法线的方向分量范围在[-1,1],而像素的分量范围在[0,1],需要做一个映射。

 pixel = (normal+1)/2 normal = pixel * 2 -1

模型空间中的表面法线存储在一张纹理中,为模型空间法线纹理。实际应用中常用模型顶点的切线空间来存储法线,称为切线空间的法线纹理。

(1)切线空间下光照模型

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Unity Shaders Book/Chapter 7/Normal Map In Tangent Space" {
    Properties {
        _Color ("Color Tint"Color) = (1111)
        _MainTex ("Main Tex"2D) = "white" {}
        _BumpMap ("Normal Map"2D) = "bump" {}//bump是Unity自带法线纹理,没有提供任何法线纹理时。表示对应了模型自带的法线纹理
        _BumpScale ("Bump Scale"Float) = 1.0//控制凹凸程度的
        _Specular ("Specular"Color) = (1111)
        _Gloss ("Gloss"Range(8.0256)) = 20
    }
    SubShader {
        Pass { 
            Tags { "LightMode"="ForwardBase" }
        
            CGPROGRAM
            
            #pragma vertex vert
            #pragma fragment frag
            
            #include "Lighting.cginc"
            
            fixed4 _Color;
            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _BumpMap;
            float4 _BumpMap_ST;
            float _BumpScale;
            fixed4 _Specular;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值