Shader入门——我的第一篇shader

来源:互联网 发布:java常见面试题集合 编辑:程序博客网 时间:2024/06/05 11:46

说到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 200CGPROGRAM#pragma surface surf Lambertfloat4 _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里的效果,红加上绿应该等于黄色:


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



0 0