Unity3D Shaderlab实战学习笔记 一 (《shaders for game programmers and artists》实践)

把这次学习的历程做成笔记。一个原因是想用专业、严谨的态度对待这次学习;另一个就是想分享下自己的经验。毕竟这次学习因为有一个好的思想,没有显得头昏脑胀。如果还有大牛能够指点一二,我就很开心了。

这里我假设你已经有了一定的编程水平,看过了一些关于shader编程的文档(当然肯定有Unity提供的shader文档),并且比较熟悉Unity3D。学习Unity3D的一个很好的方法就是边实践边查文档。

 

Unity3D环境的配置以前介绍过了。这里我下了一个cg toolkit当做文档参考。

这次学习准备先用Unity3D实现《Shaders for Game Programmers and Artists》中的内容。这本书使用的是ATI RenderMonkey,我本来想的是先用ATI RendMonkey做着先,但是觉得太麻烦,毕竟Unity工作方式也不太一样。所以,RenderMonkey还是放在一边先吧。

好了,准备动手。从第四章开始就是shader实战。不过建议大家还是看看前面的内容。第四章是个很基础的例子。关键在于教会你从头开始建立一个简单的shader。

大家都知道unity的shaderlab封装了很多东西,甚至已经是有自己的语法。比如surface shader。这里我并不打算用这个东西,因为我还不想学……就用vertex + fragment吧。

先看看书上的步骤

1.导入模型。

Unity就用不着那么麻烦了,因为内建了几个模型。Cube,sphere什么的,我是每样都建了一个,然后摆到摄像机能拍到的地方。

2.建立矩阵

Unity也不用那么麻烦了,Unity内建了几个矩阵,从文档里可以查到。也不用事先声明什么的。这次用到的是UNITY_MATRIX_MVP,先放着不管。

3.一个最基础的输出单一颜色的shader

现在动手

1. 新建一个工程,然后随意创建几个模型,摆到摄像机能拍到的地方。

2. 新建一个shader,把它里边的不需要的功能先删去。得到的结果如下:

Shader "Custom/Hello World" 
{
   	Properties	{
	}
	
	SubShader 
	{
        	Pass
		{
			CGPROGRAM
	  
	
			#pragma vertex Vert
		
			#pragma fragment Frag
		
			#include "UnityCG.cginc"


			V2F Vert(appdata_base v)
			{

			}

			half4 Frag(V2F i):COLOR0
			{

			}

			ENDCG
        	}

	} 
	

FallBack "Diffuse"

}

3. 除了矩阵那块以及appdata_base 文档里有说明以外照着敲代码吧,最后得到:

Shader "Custom/Hello World2" 
{
	
	Properties 
	{
	}

		SubShader 
		{
	
			Pass 
	
			{

	
				CGPROGRAM

	  
			#pragma vertex Vert

				#pragma fragment Frag
	
				#include "UnityCG.cginc"
			
			
				struct V2F
	
				{
			
					float4 pos:POSITION;

				};
		

	  
			V2F Vert(appdata_base v)

				{
			
					V2F output;
	
					output.pos = mul(UNITY_MATRIX_MVP,v.vertex);
		
					return output;
		
				}
			

				half4 Frag(V2F i):COLOR
		
				{
				
					return float4(1,0,0,1);

				}

		
				ENDCG	  
	  
	
			}

		
		}
	

	FallBack "Diffuse"

}

4. 新建一个material,然后把shader拖上去,再把material拖给之前创建的GameObject上面看效果吧…… (恶心的红色)

未命名

接下来是贴图

1. 首先有个从外界接收贴图的方式,unity有自己的一套东西,不懂的查文档……

2. 要加一个语义为TEXCOORD0的参数,表示当前取纹理的坐标

3. 最后结果如下:

Shader "Custom/Hello World3"
 {

	Properties 

	{
		
		_MainTex ("Base (RGB)", 2D) = "white" {}

	}
	

	

	SubShader 
	
	{
	
		Pass 
	
		{

	
			CGPROGRAM
	
  
			#pragma vertex Vert

			#pragma fragment Frag
	
			#include "UnityCG.cginc"
	

			sampler2D _MainTex;
		
			struct V2F
		
			{
		
				float4 pos:POSITION;
	
				float2 txr1:TEXCOORD0;
		
			};
			  
		
			V2F Vert(appdata_base v)
	
			{
				
				V2F output;
	
				output.pos = mul(UNITY_MATRIX_MVP,v.vertex);
	
				output.txr1 = v.texcoord;
			
				return output;
			
			}
			
		
			half4 Frag(V2F i):COLOR
		
			{
				
				return tex2D(_MainTex,i.txr1);
	
			}

		
			ENDCG
	  
	  
	
		}

		
	}
	
	
FallBack "Diffuse"

}

4. 看效果吧……

未命名

再接下来书上写的是显示多个物体……没必要了……

再接下来是拓展练习

1.动画

这里的动画就是扰动传进来的TEXCOORD0值,让它有规律的移动。就是乘上cos时间或者sin时间。查看unityCG.cginc可以知道unity提供了_CosTime和_SinTime

output.txr1 = v.texcoord*_CosTime;

2.混合贴图

我在网上随意找了一张青苔的图片。这个混合的原理就是把取到的颜色值相乘(前提是0到1的那种)

return tex2D(_MainTex,i.txr1)*tex2D(_SecondTex,i.txr1);
都用TEXCOORD0采样
未命名 

这样一套练习下来,相信你跟我一样会觉得还挺好玩的。下一章是Screen Effect。这个方面Unity3D就需要一些比较特别的设置。

待续。

posted on 2011-10-22 23:59  Mr.October  阅读(13764)  评论(7编辑  收藏  举报

导航