【Unity Shader】Surface Shader 和纹理相关的用法

用法篇

  • Standard Surface Shader
    • 该 Shader 的输出主要是为表面光照提供一些初始值用于计算,可以在官网下载内置着色器文件,然后搜索一些相关结构体的组成,比如 SurfaceOutputStandard 等
    • 一篇关于这个的文章
  • Packed Arrays
    • // 填充部分
      o.Alpha = _Color.a;
      o.Albedo = _Color.rgb;
      o.Albedo.rg = _Color.rg;
      
      // 单个值赋给整个 Array
      o.Albedo = 0;
      
      // 矩阵相关
      float4x4 matrix;
      // 单个值
      float first = matrix._m00;
      float last = matrix._m33;
      // 多个值
      float4 diagonal = matrix._m00_m11_m22_m33;
      // 行
      float4 firstRow = matrix[0]; <=> float4 firstRow = matrix._m00_m01_m02_m03;
  • Texture Mapping and UV
    • 我们将 2D 纹理包裹到 3D 模型上面,称为纹理映射
    • 映射的时候需要知道当前顶点对应的纹理和 UV 值用于采样对应的颜色
    • 	Properties {
      		_Color ("Color", Color) = (1,1,1,1)
      		_MainTex ("Albedo (RGB)", 2D) = "white" {}
      	}
      
      	sampler2D _MainTex;
      
      	struct Input {
      		float2 uv_MainTex;
      	};
      
      	fixed4 _Color;
      
      	void surf (Input IN, inout SurfaceOutputStandard o) {
      		fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
      		o.Albedo = c.rgb;
      		o.Alpha = c.a;
      	}

  • Texture Normal and Normal Intensity

    • 可以用于产生视觉偏差,让平面产生明暗效果,原因是使用的光照模型计算光照时与法线夹角变化引起结果变化

    • Shader "CookBook/shader_normal" {
          Properties{
              _Color("Color", Color) = (1,1,1,1)
              _NormalTex("Nomral Map", 2D) = "bump" {}
              _NormalMapIntensity("Normal intensity", Range(0, 3)) = 1
          }
          SubShader{
              Tags{ "RenderType" = "Opaque" }
              LOD 200
      
              CGPROGRAM
              #pragma surface surf Standard fullforwardshadows
              #pragma target 3.0
      
              sampler2D _NormalTex;
              fixed _NormalMapIntensity;
      
              struct Input {
                  float2 uv_NormalTex;
              };
      
              fixed4 _Color;
      
              void surf(Input IN, inout SurfaceOutputStandard o) {
                  fixed3 normalMap = UnpackNormal(tex2D(_NormalTex, IN.uv_NormalTex));
                  normalMap.x *= _NormalMapIntensity;
                  normalMap.y *= _NormalMapIntensity;
      
                  o.Normal = normalize(normalMap);
                  o.Albedo = _Color;
              }
              ENDCG
          }
          FallBack "Diffuse"
      }
  • Texture Scale

    • 上面说了可以利用 UV 值进行采样,在纹理 Inspector 面板中,Wrap Mode 修改为 Repeat 后,纹理会重复填充,这时候我们可以利用 UV 拉伸来做一些不停移动的效果

    • 可以用于瀑布,水流,岩浆等

    • Properties {
          _Color ("Color", Color) = (1,1,1,1)
      	_MainTex ("Albedo (RGB)", 2D) = "white" {}
          _ScrollXSpeed ("X Scroll Speed", Range(0, 10)) = 2
          _ScrollYSpeed ("Y Scroll Speed", Range(0, 10)) = 2
      }
      
      	sampler2D _MainTex;
      
      	struct Input {
      		float2 uv_MainTex;
      	};
      
      	fixed4 _Color;
          fixed _ScrollXSpeed;
          fixed _ScrollYSpeed;
      
      	void surf (Input IN, inout SurfaceOutputStandard o) {
              fixed2 scrolledUV = IN.uv_MainTex;
      
              fixed xScrollValue = _ScrollXSpeed * _Time;
              fixed yScrollValue = _ScrollYSpeed * _Time;
      
              scrolledUV += fixed2(xScrollValue, yScrollValue);
      
      		fixed4 c = tex2D (_MainTex, scrolledUV) * _Color;
      		o.Albedo = c.rgb;
      		o.Alpha = c.a;
      	}
      }
      

  • Texture Transparent

    • 透明度混合,可以用于一些镂空的物品,如窗户等,里面有个 alpha:fade 可以看看 一篇关于这个的文章

    • Shader "CookBook/shader_transparent" {
      	Properties {
      		_Color ("Color", Color) = (1,1,1,1)
      		_MainTex ("Albedo (RGB)", 2D) = "white" {}
      	}
      	SubShader {
      		Tags { 
                  "Queue" = "Transparent"
                  "IgnoreProjector" = "True"
                  "RenderType"="Transparent" 
              }
      		LOD 200
      
      		CGPROGRAM
      		#pragma surface surf Standard alpha:fade
      		#pragma target 3.0
      
      		sampler2D _MainTex;
      
      		struct Input {
      			float2 uv_MainTex;
      		};
      
      		fixed4 _Color;
      
      		void surf (Input IN, inout SurfaceOutputStandard o) {
      			fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
      			o.Albedo = c.rgb;
      			o.Alpha = c.a;
      		}
      		ENDCG
      	}
      	FallBack "Diffuse"
      }
      

    • 透明物体,可以用于 3D 投影效果,灵魂等,主要是一个视线与法线夹角的边沿判断

      • Shader "CookBook/shader_holographics" {
            Properties{
                _Color("Color", Color) = (1,1,1,1)
                _MainTex("Albedo (RGB)", 2D) = "white" {}
                _DotProduct("Rim Effect", Range(-1,1)) = 0.25
            }
        
            SubShader{
                Tags{
                    "Queue" = "Transparent"
                    "IgnoreProjector" = "True"
                    "RenderType" = "Transparent"
                }
                LOD 200
        
                CGPROGRAM
                #pragma surface surf Lambert alpha:fade
                #pragma target 3.0
        
                sampler2D _MainTex;
                float _DotProduct;
        
                struct Input {
                    float2 uv_MainTex;
                    float3 worldNormal;
                    float3 viewDir;
                };
        
                fixed4 _Color;
        
                void surf(Input IN, inout SurfaceOutput o) {
                    fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
                    float border = 1 - abs(dot(IN.viewDir, IN.worldNormal));
                    float alpha = (border * (1 - _DotProduct) + _DotProduct);
        
                    o.Albedo = c.rgb;
                    o.Alpha = c.a * alpha;;
                }
                ENDCG
            }
            FallBack "Diffuse"
        }
    • Texture Blend

      • 一个地形中的地表由多个纹理混合组成,可以使用一张混合纹理以及四张具体的颜色纹理,混合纹理的 RGBA 四个通道去对应读取相应的 RGBA  四张纹理的值,达到纹理混合的作用(我这里图片的 A 通道损坏了)

      • 更进一步的话还有 基于高度进行混合

      • Shader "CookBook/shader_tex_blend" {
        	Properties {
        		_Color ("Color", Color) = (1,1,1,1)
        		_BlendTex ("Blend mask", 2D) = "white" {}
                _RTex ("R", 2D) = "white" {}
                _GTex ("G", 2D) = "white" {}
                _BTex ("B", 2D) = "white" {}
                _ATex ("A", 2D) = "white" {}
            }
        	SubShader {
        		Tags { "RenderType"="Opaque" }
        		LOD 200
        
        		CGPROGRAM
        		#pragma surface surf Standard fullforwardshadows
        		#pragma target 4.0
        
        		sampler2D _BlendTex;
                sampler2D _RTex;
                sampler2D _GTex;
                sampler2D _BTex;
                sampler2D _ATex;
        
        		struct Input {
                    float2 uv_BlendTex;
                    float2 uv_RTex;
                    float2 uv_GTex;
                    float2 uv_BTex;
                    float2 uv_ATex;
        		};
        
        		half _Glossiness;
        		half _Metallic;
        		fixed4 _Color;
        
        		void surf (Input IN, inout SurfaceOutputStandard o) {
        
                    float4 blendData = tex2D(_BlendTex, IN.uv_BlendTex);
        
                    float4 rTexData = tex2D(_RTex, IN.uv_RTex);
                    float4 gTexData = tex2D(_GTex, IN.uv_GTex);
                    float4 bTexData = tex2D(_BTex, IN.uv_BTex);
                    float4 aTexData = tex2D(_ATex, IN.uv_ATex);
        
                    float4 finalColor;
                    finalColor = lerp(rTexData, gTexData, blendData.r);
                    finalColor = lerp(finalColor, bTexData, blendData.g);
                    finalColor = lerp(finalColor, aTexData, blendData.b);
                    finalColor.a = 1.0;
        			
                    o.Albedo = finalColor.rgb;
                    o.Alpha = finalColor.a;
                }
        		ENDCG
        	}
        	FallBack "Diffuse"
        }

猜你喜欢

转载自blog.csdn.net/weixin_42561030/article/details/82155384