unity3d 怎么建shader

unity3d 怎么建shader,第1张

如果是进行3d游戏开 发的话,想必您对着两个词不会陌生。Shader(着色器)实际上就是一小段程序,它负责将输入的Mesh(网格)以指定的方式和输入的贴图或者颜色等组 合作用,然后输出。绘图单元可以依据这个输出来将图像绘制到屏幕上。输入的贴图或者颜色等,加上对应的Shader,以及对Shader的特定的参数设 置,将这些内容(Shader及输入参数)打包存储在一起,得到的就是一个Material(材质)。之后,我们便可以将材质赋予合适的 renderer(渲染器)来进行渲染(输出)了。

所以说Shader并没有什么特别神奇的,它只是一段规定好输入(颜色,贴图等)和输出(渲染器能够读懂的点和颜色的对应关系)的程序。而Shader开发者要做的就是根据输入,进行计算变换,产生输出而已。

Shader大体上可以分为两类,简单来说

表面着色器(Surface Shader) - 为你做了大部分的工作,只需要简单的技巧即可实现很多不错的效果。类比卡片机,上手以后不太需要很多努力就能拍出不错的效果。

片段着色器(Fragment Shader) - 可以做的事情更多,但是也比较难写。使用片段着色器的主要目的是可以在比较低的层级上进行更复杂(或者针对目标设备更高效)的开发。

因为是入门文章,所以之后的介绍将主要集中在表面着色器上。

学习方法

(1)由简入繁:自己写Shader,从最简单写起,简单的测试通过了,再一点点往里加。

(2)多调试:例如,有一个float变量x。假如x范围是[0,1],则在frag片段函数里输出 float4(x,0,0,1)的颜色,以红色的深浅来观察x的值;如果x范围是[0,1000],则可在frag片段函数里输出 float4(x/1000,0,0,1)的颜色。方法就这么简单,具体根据需要去调整。

(3)结合查看UnityCG.cginc等文件,以及unity的自带Shader,即Build-in Shader。

Build-in Shader下载地址

(4)看看书:建议看本教程的同时,多看看书。推荐英文的The CG Tutorial,也就是中文版的Cg教程_可编程实时图形权威指南

相关教材链接

学习小技巧

(1)查看UnityCG.cginc等文件

使用Vertex and Fragment的CG时,会#include "UnityCG.cginc",用到里面的很多函数,如TRANSFORM_TEX,UNITY_TRANSFER_DEPTH等函数的定义。那么怎么查看这些定义呢?

windows路径:Unity\Editor\Data\CGIncludes

mac路径:右键点击unity图标->show contents->Data->CGIncludes

该文件夹下有Unity关于Shader的库,如UnityCG.cginc,UnityCG.glslinc,Lighting.cginc等。打开

UnityCG.cginc(写字板MONODev等均可),后即可查看相关函数的定义。

(2)电子书的学习技巧

中文电子书,学起来快,好理解,但大多数是影印版。

英文电子书,可以很好的用关键词搜索知识点。

(3)使用#prama only_renderers d3d9 , 限定编译平台。(3)(4)配合使用效果更好

(4)打开编译后的Shader,查看对应的汇编代码或者OpenGL ES代码。

方法:左键单机shader文件,然后在Inspector面板里点击Open Compiled Shader.

首先在场景中放几个火盆,随便你想放几个。当然这里放几个,后面shader里就需要几张遮罩贴图。这里我们放俩个火盆。

我们在shader中添加三张贴图来做遮罩,猪脚一张、火盆三张,分别为

_Mask ("Mask", 2D) = "white" {}

_Mask0 ("Mask0", 2D) = "white" {}

_Mask1 ("Mask1", 2D) = "white" {}

在纹理混合中进行如下设置:

SetTexture [_Mask] {combine texture}

SetTexture [_MainTex] {combine texture,texture-previous}

SetTexture [_Mask0] {combine previous,previous-texture}

SetTexture [_Mask1] {combine previous,previous-texture}

SetTexture 的原理在

unity用shader遮罩模拟黑夜火把照明效果

中有说过,这里就不详细说了

总之就是将上一步计算的的alpha通道值减去这张贴图的alpha通道值就是了。

保存一下,回到我们的主界面,将我们的遮罩贴图拖到三个子贴图中,

但是这样场景中只看到了一个光圈

我们把他的offset都偏移一下,这样三个就齐了。

将光圈对准火盆与光圈跟随猪脚移动原理一样。

下一步让光圈移到火盆处。

我们打开脚本,

脚本中添加:

public GameObject fire

public GameObject fire0

然后按照获得俩火盆的位置:

float firex = fire.transform.position.x

float firey = fire.transform.position.y

float fire0x = fire0.transform.position.x

float fire0y = fire0.transform.position.y

然后就是根据火盆的位置获得遮罩的偏移量:

float offsetfirex=-firex/(Le*2f)

float offsetfirey=-firey/(Wi*2f)

float offsetfire0x=-fire0x/(Le*2f)

float offsetfire0y=-fire0y/(Wi*2f)

最后是改变遮罩的位置:

renderer.material.SetTextureOffset ("_Mask0", new Vector2 (offsetfirex,offsetfirey))

renderer.material.SetTextureOffset ("_Mask1", new Vector2 (offsetfire0x,offsetfire0y))

OK,回到场景运行,测试一下效果不错:

我们最后让火盆的光圈也能和猪脚一样忽大忽小:

我们在如图所示脚本位置添加:

renderer.material.SetTexture("_Mask0",mask[i])

renderer.material.SetTexture("_Mask1",mask[i])

具体脚本如下:

f(Time.time>b){

b=b+c

if(i<mask.Length-1){

i++

}else

{

i=0

}

renderer.material.SetTexture("_Mask",mask[i])

renderer.material.SetTexture("_Mask0",mask[i])

renderer.material.SetTexture("_Mask1",mask[i])

}

原理就是循环一组大小不同的的光圈图片作为遮罩的贴图,具体在

unity 贴图动画实现照明忽大忽小

http://jingyan.baidu.com/article/72ee561a58724ae16138df25.html

里面说过,就不详细说了。

最终脚本如下图:

OK,最终效果如下图,很不错吧!


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11366373.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-15
下一篇 2023-05-15

发表评论

登录后才能评论

评论列表(0条)

保存