《Unity Shader入门精要》总结 #第七章 基础纹理

本文是《Unity Shader入门精要》第七章的总结,详细介绍了纹理在Unity中的应用,包括单张纹理的实践与属性、凹凸映射的原理与实践,以及法线纹理在切线空间和世界空间下的计算。同时,讨论了渐变纹理和遮罩纹理的使用,如高度纹理、法线映射和遮罩纹理对模型颜色和光照的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用纹理映射可以将一张图逐纹素地控制模型颜色。

纹理大小可变,但顶点UV坐标范围通常被归一化道[0,1]范围内

1、单张纹理

1.1 实践

【补充一下第三章Properties语义块支持的属性类型,之前忘记写自己还老分不清- -】

Properties{
    Name("display name", PropertyType) = DefaultValue
}
属性类型 默认值的定义语法 例子
Int number _Int("Int", Int) = 2
Float number _Float("Float", Float) = 1.5
Range(min, max) number _Range("Range", Range(0.0, 5.0)) = 3.0
Color (number, number, number, number) _Color("Color", Color) = (1, 1, 1, 1)
Vector (number, number, number, number) _Vector("Vector", Vector) = (2, 3, 6, 1)
2D "defaulttexture" {} _2D("2D", 2D) = ""{}
Cube "defaulttexture" {} _Cube("Cube", Cube) = "white"{}
3D "defaulttexture" {} _3D("3D", 3D) = "black"{}

 

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

Shader "Unity Shaders Book/Chapter7/SingleTexture" {
	Properties{
		_Color("Color Tint", Color) = (1,1,1,1)		//控制物体整体色调
		_MainTex("Main 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 _MainTex;
			float4 _MainTex_ST;	//纹理名_ST,声明某个纹理的属性,得到缩放和平移值
								//_MainTex_ST.xy存储缩放值,即tilling,_MainTex_ST.zw存放偏移值即offset
			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 = normalize(UnityObjectToWorldNormal(v.normal));
				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{
				fixed3 worldNormal = (i.worldNormal);
				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
				fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb;	//对纹理采样,需要被采样的纹理,float2型的纹理坐标
																		//反射率albedo
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
				fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));
				
				fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
				fixed3 halfDir = normalize(worldLightDir + viewDir);
				fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(
### Unity Shader 入门教程:纹理处理 #### 创建新的 Shader 文件 在 Unity 中创建一个新的 Shader 可以通过两种方式实现。一种是在菜单栏中选择 `Assets -> Create -> Shader`,另一种方法是从 Project 视图中右键点击并选择 `Create -> Shader`[^1]。 #### 纹理尺寸优化建议 为了确保最佳性能和资源利用效率,在 Unity 中使用的纹理图像应尽可能采用2的幂次方作为宽度和高度(例如 256×256 或者 512×512)。当使用非标准尺寸时,可能会导致额外的内存消耗,并且 GPU 处理速度会受到影响而变慢[^2]。 #### 表面着色器简介 对于初学者来说,表面着色器是一个很好的起点。这类着色器允许开发者定义材质属性如漫反射颜色、高光强度等参数。值得注意的是,虽然表面上看起来像是独立类型的着色程序,但实际上它们会被编译转换成传统的顶点/片段组合形式。下面给出了一段简单的代码示例来展示如何编写一个基本的表面着色器: ```csharp SubShader { Tags {"Queue"="Transparent"} CGPROGRAM #pragma surface surf Lambert struct Input { float4 color : COLOR; }; void surf (Input IN, inout SurfaceOutput o) { o.Albedo = 1; } ENDCG } ``` 这段代码展示了如何设置一个具有透明队列标签并且应用兰伯特光照模型的简单着色器[^3]。 #### 减少过度绘制的方法 为了避免不必要的计算开销,可以通过调整场景中的对象顺序或者修改摄像机投影矩阵等方式减少视锥体内的可见几何图形数量。这样做能够显著提高渲染效率,尤其是在复杂环境中特别有用。此外,合理安排不同层次的对象遮挡关系同样有助于改善整体表现效果[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值