Shader-凹凸映射和法线映射

  • 法线贴图为蓝色色调是切线空间,五颜六色的为模型空间
  • 实现凹凸映射的方法
  1. 高度纹理
  2. 法线纹理(高度映射,法线映射):高度映射:在贴图的效果上提供高度贴图,通过颜色的亮暗实现高浅;法线映射:使用法线的颜色实现
  • 法线映射
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "LXC/14 Rock_Large"{
	Properties{
		_Color("Color",Color)=(1,1,1,1)					
		_MainTex("Main Tex",2D)="white"{}
		_NormalMap("Normal Map",2D)="bump"{}		//法线贴图,bump默认的为模型自带贴图
	}
		SubShader{
			Pass{
				Tags{"LightMode" = "ForwardBase"}		
				CGPROGRAM
// Upgrade NOTE: excluded shader from DX11; has structs without semantics (struct v2f members lightDir)
#pragma exclude_renderers d3d11
#include "Lighting.cginc"								
#pragma vertex vert										
#pragma fragment frag

				sampler2D _NormalMap;			//取得法线贴图
				float4 _NormalMap_ST;			//发现贴的ST属性,放大缩小偏移
				fixed4 _Color;				
				sampler2D _MainTex;		
				float4 _MainTex_ST;	


				struct a2v {
					float4 vertex:POSITION;
					//切线空间的确定是通过法线和切线确定的,法线和切线是存储到模型里面的
					float3 normal:NORMAL;
					float4 tangent:TANGENT;		//切线	tangent.w是用来确定切线空间中坐标轴方向的

					float4 texcoord:TEXCOORD0;	
				};

				struct v2f {
					float4 svPos:SV_POSITION;
					float3 lightDir : TEXCOORD0;	//切线空间下 平行光的方向
					float4 worldVertex:TEXCOORD1;
					float4 uv:TEXCOORD2;			//xy 用来存储MainTex的纹理坐标,zw用来存储NormalMap的纹理坐标		
				};



				//获取切线和法线只能在顶点函数内获取

				v2f vert(a2v v) {						
					v2f f;		
					f.svPos = UnityObjectToClipPos(v.vertex);
					f.worldNormal = UnityObjectToWorldNormal(v.normal);
					f.worldVertex = mul(v.vertex, unity_WorldToObject);
					f.uv.xy = v.texcoord.xy *_MainTex_ST.xy +_MainTex_ST.zw;	
					f.uv.zw = v.texcoord.xy * _NormalMap_ST.xy + _NormalMap_ST.zw;	//计算法线贴的图的偏移和大小
					
					//调用这个宏之后,会得到一个矩阵rotation 这个矩阵用来把模型空间下的方向转换成切线空间下
					TANGENT_SPACE_ROTATION;	
					//转换光的方向
					//得到模型空间下的平行光方向	ObjSpaceLightDir(v.vertex)
					f.lightDir = mul(rotation,ObjSpaceLightDir(v.vertex));

					return f;
				}




				//把所有跟法线方向有关的运算都放在 切线空间下
				//从法线贴图里获取的法线方向都是切线空间下的
				fixed4 frag(v2f f):SV_Target {			
					//取得图片里的法线
					fixed4 normalColor = tex2D(_NormalMap,f.uv.zw);		//获取颜色值
					//不能自己做转换,贴图材质是normalmap,所以要使用unity自带方法UnpackNormal
					//fixed3 tangentNormal =normalize( normalColor.xyz * 2 - 1);  切线空间下的法线	normal = pixel*2 - 1
					fixed3 tangentNormal=UnpackNormal(normalColor);
					tangentNormal=normalize(tangentNormal);

					fixed3 lightDir = normalize(f.lightDir);

					fixed3 texColor = tex2D(_MainTex,f.uv.xy)*_Color.rgb;		

					fixed3 diffuse = _LightColor0.rgb * texColor * max(dot(tangentNormal, lightDir), 0);
					
					fixed3 tempColor = diffuse + UNITY_LIGHTMODEL_AMBIENT.rgb*texColor;
					return fixed4(tempColor, 1);
				}
				ENDCG
		}
	}
	Fallback "Specular"
}
  • 凹凸参数控制凹凸程度
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "LXC/14 Rock_Large"{
	Properties{
		_Color("Color",Color)=(1,1,1,1)					
		_MainTex("Main Tex",2D)="white"{}
		_NormalMap("Normal Map",2D)="bump"{}	
		_BumpScale("Bump Scale",Float)=1		//凹凸参数
	}
		SubShader{
			Pass{
				Tags{"LightMode" = "ForwardBase"}		
				CGPROGRAM
// Upgrade NOTE: excluded shader from DX11; has structs without semantics (struct v2f members lightDir)
#pragma exclude_renderers d3d11

#include "Lighting.cginc"								
#pragma vertex vert										
#pragma fragment frag

				sampler2D _NormalMap;			
				float4 _NormalMap_ST;		
				fixed4 _Color;				
				sampler2D _MainTex;		
				float4 _MainTex_ST;	
				float4 _BumpScale;


				struct a2v {
					float4 vertex:POSITION;
					float3 normal:NORMAL;
					float4 tangent:TANGENT;	
					float4 texcoord:TEXCOORD0;	
				};

				struct v2f {
					float4 svPos:SV_POSITION;
					float3 lightDir : TEXCOORD0;	
					float4 worldVertex:TEXCOORD1;
					float4 uv:TEXCOORD2;				
				};



				
				v2f vert(a2v v) {						
					v2f f;		
					f.svPos = UnityObjectToClipPos(v.vertex);
					f.worldNormal = UnityObjectToWorldNormal(v.normal);
					f.worldVertex = mul(v.vertex, unity_WorldToObject);
					f.uv.xy = v.texcoord.xy *_MainTex_ST.xy +_MainTex_ST.zw;	
					f.uv.zw = v.texcoord.xy * _NormalMap_ST.xy + _NormalMap_ST.zw;
					TANGENT_SPACE_ROTATION;	
					f.lightDir = mul(rotation,ObjSpaceLightDir(v.vertex));

					return f;
				}




				fixed4 frag(v2f f):SV_Target {			
					fixed4 normalColor = tex2D(_NormalMap,f.uv.zw);	
					fixed3 tangentNormal=UnpackNormal(normalColor);

					tangentNormal.xy = tangentNormal.xy*_BumpScale;		//控制法线xy的大小

					tangentNormal=normalize(tangentNormal);
					
					fixed3 lightDir = normalize(f.lightDir);

					fixed3 texColor = tex2D(_MainTex,f.uv.xy)*_Color.rgb;		

					fixed3 diffuse = _LightColor0.rgb * texColor * max(dot(tangentNormal, lightDir), 0);
					
					fixed3 tempColor = diffuse + UNITY_LIGHTMODEL_AMBIENT.rgb*texColor;
					return fixed4(tempColor, 1);
				}
				ENDCG
		}
	}
	Fallback "Specular"
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值