Shader入门——我的第一篇shader

Posted 御雪妃舞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shader入门——我的第一篇shader相关的知识,希望对你有一定的参考价值。

说到shader,很早前就开始看了,但是只是个大概,没有深入的研究,所以只能大概看看,自己写不出来,但是后来发现做项目过程中还是自己写比较快,于是,从这篇博客开始,准备深入研究一下。


另外,发现博客被抄袭和转载的厉害,还被别人加上了别人的水印,这点很不喜欢,所以,以后的博客,楼主会加自己的水印。


言归正传,我们将简单的从开头,属性和简单的调用介绍,后面还有一个博主研究的郁闷的问题,会的可以解答下:


1.前期准备

前期准备很简单,新建一个工程,新建一个场景,并保存,在场景中创建一个plane,两个球,如图:



然后,在Project面板下新建一个文件夹,叫1DiffuseShading,在下面分别建立Materials和Shaders文件夹,子文件夹下新建对应的shader和材质,并命名,最终结果如图:



2.Shader头部路径

如下是我新建的Shader的头部路径
Shader "MyShaders/_BasicDiffuse"



shader的头部路径代表的是你的材质选择shader时的下拉菜单的路径,也可以直接把shader拖到材质上,如图

或者直接下拉菜单选择:


3.Shader属性


Properties
	
		_EmissiveColor("Emissive Color",Color) = (1,1,1,1)
		_AmbientColor("Ambient Color",Color) = (1,1,1,1)
		_MySliderVale("This is  a Slider",Range(0,10)) = 2.5
		_Color("Color",Color) = (1,1,1,1)
	

这一段代码就是我的Shader的属性,包含变量名,变量显示名,变量类型,变量默认值,详细如下

这里举列的是Color,下面我们介绍下还有那些类型和举列,具体见下面表格

4.调用变量

整个代码如下:
Shader "MyShaders/_BasicDiffuse"

	Properties
	
		_EmissiveColor("Emissive Color",Color) = (1,1,1,1)
		_AmbientColor("Ambient Color",Color) = (1,1,1,1)
		_MySliderVale("This is  a Slider",Range(0,10)) = 2.5
	

		SubShader
		
			Tags  "RenderType" = "Opaque" 
			LOD 200


			CGPROGRAM
			#pragma surface surf Lambert

			float4 _EmissiveColor;
			float4 _AmbientColor;
			float _MySliderVale;

			struct Input
			
				float2 uv_MainTex;
			;

			void surf(Input IN,inout SurfaceOutput o)
			
				float4 c;
				c = pow((_EmissiveColor + _AmbientColor), _MySliderVale);
				o.Albedo = c.rgb;
				o.Alpha = c.a;
			

			ENDCG

		


其中这个

Tags:

标签,暗示你的Shader输出什么 RenderType有Opaque(非透明物体),Transparent(透明物体)                                "IgnoreProjector"="True"(不被Projectors影 响)        "ForceNoShadowCasting"="True"(从不产生阴影)
"Queue"="xxx"(指定渲染顺序队列),预定义的Queue有Backgroud,Geometry,AlphaTest,Transparent,Overalay
  • Background - 最早被调用的渲染,用来渲染天空盒或者背景
  • Geometry - 这是默认值,用来渲染非透明物体(普通情况下,场景中的绝大多数物体应该是非透明的)
  • AlphaTest - 用来渲染经过Alpha Test的像素,单独为AlphaTest设定一个Queue是出于对效率的考虑
  • Transparent - 以从后往前的顺序渲染透明物体
  • Overlay - 用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等特效)


LOD:

Level of Detail,Diffuse用200,根据设备图形性能调整值。
  • VertexLit及其系列 = 100
  • Decal, Reflective VertexLit = 150
  • Diffuse = 200
  • Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit = 250
  • Bumped, Specular = 300
  • Bumped Specular = 400
  • Parallax = 500
  • Parallax Specular = 600


CGPROGRAM:

    与ENDCG对应,代表这部分代码是cg代码
   
然后三个Float开始的字段要跟属性的名字一致,是为了跟属性面板里的变量建立连接, 名字一定要一样,这样我们下面方法点用的就是这个变量,也就是你面板里的变量值。
下面我们看surf方法,是让两种颜色相加然后做了增减,最后显示输出。 我给了Emissive Color一个红色,Ambinet Color一个绿色,最后输出了黄色:
如同颜色的变化,效果如图:


色彩效果如图:


红色加上绿色应该是黄色

5.关于pow的疑问

出来效果是对的,但是博主对pow有了疑问,C#中Mathf.pow是指x的y次方,参数是float,源码如图

然后我试着f传入四元数是不可以的,然后我查了cg官网对pow的解释,也是说x的y次方。官网如图:
然后博主产生了严重的怀疑,按照高中数学的话,pow的结果应该是一个值,为何cg脚本里结果是一个四维数?


然后继续问,找到了官网pow的源码处理:地址:http://http.developer.nvidia.com/Cg/pow.html


有如下发现:
a.发现pow的重载方法,第一和第二个参数都是一样的,而我们shader中的第二个参数不是四元数?
b.log没有底数
后来技术群里问了下,大家猜测第二个参数是自动填充的,四个值一样,都是我们传的float,然后log的底数应该默认是e. 依据这样的条件下,我们做了这样的运算:


也就是说

我们验证我们上面unity里的效果,红加上绿应该等于黄色:

可是根据这个算出来确是红色加绿色等于白色。楼主郁闷了?不知道哪一步是有问题的,总不能官网上的方法是错的吧?求大神指教


以上是关于Shader入门——我的第一篇shader的主要内容,如果未能解决你的问题,请参考以下文章

Unity Shader 入门精要——双面渲染透明效果

Unity Shader入门精要学习笔记 - 第8章 透明效果

Unity Shader入门精要学习笔记 - 第10章 高级纹理

Unity Shader-后处理:简单的颜色调整(亮度,饱和度,对比度)

Unity Shader入门精要学习笔记 - 第6章 开始 Unity 中的基础光照

unity给子物体添加Shader