详解Unity3D Shader开发之Shader框架
2017-01-25 12:43
363 查看
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。
CSDN视频网址:http://edu.csdn.net/lecturer/144
网上很多开发者跟我咨询关于GPU编程,其实GPU编程没有大家想象的那么难,它也是一种针对GPU显卡的编程脚本,在学习Shader编程之前,作为常识,我们要了解Shader编程开发语言有哪几种?
HLSL(High Level Shader Language)只能供微软的Direct3D以及XNA使用,微软提供的GPU编程不能跨平台使用,只能在Window平台上使用。
CG(C for Graphics)由NVIDIA公司开发,CG程序可以根据运行时的需要或者事先编译成GPU汇编代码,CG语言也是最基本的语言,它的结构跟C语言类似,容易学习。读者可以学习《CG教程-可编程实时图形权威指南》。
GLSL(OpenGL Shading Language)也称作Glslang语言,OpenGL和OpenGLES都是使用这种GPU编程语言实现跨平台的。
ShaderLab语言是Unity配备了一个强大的着色器语言(ShaderLab),它的顶点和片段是CG/HLSL高级语言编写的。
介绍完语言,写过Shader的读者都知道,Shader不好调试,通常的做法都是在程序中通过注释代码的方式逐步排除Bug,在这里给读者推荐几个调试Shader的工具:FX Composer工具,Render Monkey工具,我调试Shader使用的是Render Monkey,当然也会使用排除法。下面给读者介绍ShaderLab的内容,先看一下事例代码:
看上面的脚本中,Properties有很多项,以属性中的
_Color 定义的是Shader内部的名字表示颜色,Main Color是指示器中显示的名字,Color表示的是属性类型,(1,1,1,1)表示的是颜色的默认值。再给读者看下图中对应的项:
下面把Properties中对应的定义给读者一一展现如下:
纹理后买年的大括号内为纹理属性选项,为可选项。可用选项是:TexGen texgenmode纹理生成模式为对应贴图的自动纹理坐标生成模式,为ObjectLinear,EyeLiner,SphereMap,CubeReflect,CubeNormal之一,这些模式和OpenGL纹理生成模式相对应。注意如果使用自定义顶点程序,那么纹理生成将被忽略。
比如:_MainTex("Base", 2D) = "white"{TexGen EyeLiner}
LightmapMode 光照贴图模式,如果给出这个选项,纹理将能被渲染器的光线贴图属性所影响。纹理不能被使用在材质中,而是取自渲染器的设定。
以上是关于Properties中的说明,后面会给出subShader的说明。
CSDN视频网址:http://edu.csdn.net/lecturer/144
网上很多开发者跟我咨询关于GPU编程,其实GPU编程没有大家想象的那么难,它也是一种针对GPU显卡的编程脚本,在学习Shader编程之前,作为常识,我们要了解Shader编程开发语言有哪几种?
HLSL(High Level Shader Language)只能供微软的Direct3D以及XNA使用,微软提供的GPU编程不能跨平台使用,只能在Window平台上使用。
CG(C for Graphics)由NVIDIA公司开发,CG程序可以根据运行时的需要或者事先编译成GPU汇编代码,CG语言也是最基本的语言,它的结构跟C语言类似,容易学习。读者可以学习《CG教程-可编程实时图形权威指南》。
GLSL(OpenGL Shading Language)也称作Glslang语言,OpenGL和OpenGLES都是使用这种GPU编程语言实现跨平台的。
ShaderLab语言是Unity配备了一个强大的着色器语言(ShaderLab),它的顶点和片段是CG/HLSL高级语言编写的。
介绍完语言,写过Shader的读者都知道,Shader不好调试,通常的做法都是在程序中通过注释代码的方式逐步排除Bug,在这里给读者推荐几个调试Shader的工具:FX Composer工具,Render Monkey工具,我调试Shader使用的是Render Monkey,当然也会使用排除法。下面给读者介绍ShaderLab的内容,先看一下事例代码:
Shader "SeparateSpecular" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1) _Shininess ("Shininess", Range (0.01, 1)) = 0.078125 _ReflectColor ("Reflection Color", Color) = (1,1,1,0.5) _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {} _Cube ("Reflection Cubemap", Cube) = "_Skybox" { TexGen CubeReflect } _GrayTex("Gray(RGB)", 2D) = "white"{} _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5 _RimFaceColor ("Rim Face Color", Color) = (0.26,0.19,0.16,0.0) _RimHairColor ("Rim Hair Color", Color) = (0.26,0.19,0.16,0.0) _RimFacePower ("Rim Face Power", Range(0.5,8.0)) = 3.0 _RimHairPower ("Rim Hair Power", Range(0.5,8.0)) = 3.0 _GrayFaceColor("Face Color", Color) = (0.5, 0.5, 0.5, 1) _GrayHairColor("Hair Color", Color) = (0.5, 0.5, 0.5, 1) } SubShader { LOD 300 Tags { "RenderType"="Opaque" } CGPROGRAM #pragma surface surf BlinnPhong sampler2D _MainTex; samplerCUBE _Cube; sampler2D _GrayTex; fixed4 _Color; fixed4 _ReflectColor; half _Shininess; float _RimFacePower; float _RimHairPower; float4 _RimFaceColor; float4 _RimHairColor; float4 _GrayFaceColor; float4 _GrayHairColor; struct Input { float2 uv_MainTex; float3 worldRefl; float3 viewDir; float2 uv_GrayTex; }; void surf (Input IN, inout SurfaceOutput o) { fixed4 tex = tex2D(_MainTex, IN.uv_MainTex)* _Color; fixed4 graytex = tex2D(_GrayTex, IN.uv_GrayTex); fixed4 c = tex; fixed4 grayface = graytex * _GrayFaceColor; fixed4 grayhair = (1.0 - graytex.rgba) * _GrayHairColor; o.Albedo =c.rgb * grayhair.rgb; o.Albedo += c.rgb * grayface.rgb; o.Gloss = tex.a; o.Specular = _Shininess; fixed4 reflcol = texCUBE (_Cube, IN.worldRefl); reflcol *= tex.a; half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal)); o.Emission = reflcol.rgb * _ReflectColor.rgb + _RimHairColor.rgb * pow (rim, _RimHairPower) * grayhair.rgb; o.Emission += reflcol.rgb * _ReflectColor.rgb + _RimFaceColor.rgb * pow (rim, _RimFacePower) * grayface.rgb; o.Alpha = reflcol.a * _ReflectColor.a; } ENDCG }
看上面的脚本中,Properties有很多项,以属性中的
_Color ("Main Color", Color) = (1,1,1,1)
_Color 定义的是Shader内部的名字表示颜色,Main Color是指示器中显示的名字,Color表示的是属性类型,(1,1,1,1)表示的是颜色的默认值。再给读者看下图中对应的项:
下面把Properties中对应的定义给读者一一展现如下:
Properties定义的属性块,其中可以包含多个属性,其定义如下: name(“display name”,Range(min,max))=number 定义浮点数属性,在检视器中可通过一个标注最大最小的滑条来修改。 name(“display name”,Color)=(number,number,number,number) 定义颜色属性 name("display name",2D) = "name"{options} 定义2D纹理属性 name("display name",Rect)="name"{options} 定义长方形(非2次方)纹理属性 name("display name", Cube)="name"{options} 定义立方贴图纹理属性 name("display name",Float)=number 定义浮点数属性 name("display name",Vector)=(number, number,number,number) 定义一个四元数的容器(相当于Vector4)属性注意:对于Range和Float类型的属性只能是单精度值,对于Color和Vector类型的属性将包含4个由括号围住的的数描述。对于纹理(2D,Rect,Cube)缺省既可以是一个空字符串也可以是某个内置的缺省纹理:“white”,"black","gray","bump"。
纹理后买年的大括号内为纹理属性选项,为可选项。可用选项是:TexGen texgenmode纹理生成模式为对应贴图的自动纹理坐标生成模式,为ObjectLinear,EyeLiner,SphereMap,CubeReflect,CubeNormal之一,这些模式和OpenGL纹理生成模式相对应。注意如果使用自定义顶点程序,那么纹理生成将被忽略。
比如:_MainTex("Base", 2D) = "white"{TexGen EyeLiner}
LightmapMode 光照贴图模式,如果给出这个选项,纹理将能被渲染器的光线贴图属性所影响。纹理不能被使用在材质中,而是取自渲染器的设定。
以上是关于Properties中的说明,后面会给出subShader的说明。
相关文章推荐
- 详解Unity3D Shader开发之Shader框架
- 详解Unity3D Shader开发之渲染管线
- 详解Unity3D Shader之Shader Lab框架
- 详解Unity3D Shader开发之渲染管线
- 详解Unity3D Shader之Shader Lab框架
- unity3d Shader开发简介
- Unity3d Shader开发(一)Properties
- 开发愤怒的小鸟的Lua语言:Wax框架详解
- 整合开发Struts2,Hibernate,Spring简单框架的搭建详解
- iphone 开发之 第三方 network框架 ASIHTTPRequest 详解
- Unity3d Shader开发(三)Pass(Alpha testing )
- Unity3D Built-in Shader,unity3d内置shader详解1
- iphone 开发之 第三方 network框架 ASIHTTPRequest 详解
- Unity3d Shader开发(三)Pass(Pass Tags,Name,BindChannels )
- Unity3d Shader开发(三)Pass(Culling & Depth Testing)
- Unity3d Shader开发(三)Pass(Texturing )
- 手把手教学:详解HTML5移动开发框架PhoneJS
- Unity3D 游戏引擎之详解游戏开发音频的播放(十五)
- struts验证框架开发详解
- SSH开发框架详解