`

Unity3D Shader编程实践——“Hello Shader"

 
阅读更多

Unity3D Shader编程实践——“Hello Shader"

 

 By D.S.Qiu

尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com

 

        从去年毕业后一直都在折腾 Unity3D ,一直也没有什么积累(前几个月一直在打酱油),对于一个连数据库都没有学过的人来说,需要积累的实在太多了。那只有从自己感兴趣的开始,也许是自己本科接触过一些数字图像处理,图像的渲染处理就特别吸引我。对 Unity Shader 也只是一知半解,为了能够系统的掌握 Shader 编程就决定开始“Unity3D Shader编程实践”系列文章的写作,目的只是记录自己学习的点滴,但如果能让他人受益就更好了。好了,D.S.Qiu不喜欢废话,那就开始吧。

 

Shader和Material

        Shader和Material是3D开发必不可少的部分,D.S.Qiu一开始对这两个关系及作用一直搞不透,所以很有必要先介绍下Shader和Material的基本概念:Shader(着色器)其实就是一小段程序,它将输入的Texture(贴图),颜色或其他参数以指定方式输出。Shader都是指定给Material,Material为Shader提供输入的贴图等参数。在Material上输入的贴图或者颜色等,加上对应的Shader,以及对Shader的特定的参数设置,将这些内容(Shader及输入参数)打包存储在一起,得到的就是一个Material(材质)。之后,便可以将材质赋予Mesh(网格)的Renderer(渲染器)来进行渲染(输出)了,绘图单元根据这个输出就得到屏幕输出的图像。简而言之:Material为Shader提供具体的输入参数,而Shader是对输入参数的具体处理逻辑。

 

Hello Shader

        学习编程语言都习惯以一个Hello World 开始,这里也以“Hello Shader"开始,介绍Shader的基本结构,首先创建Material 和 Shader,而且都命名为Hello,并放入一张图片,项目工程如下图:

       下面看下HelloShader的代码:

Shader "Custom/HelloShader" {   
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		#pragma surface surf Lambert

		sampler2D _MainTex;

		struct Input {
			float2 uv_MainTex;
		};

		void surf (Input IN, inout SurfaceOutput o) {
			half4 c = tex2D (_MainTex, IN.uv_MainTex);
			//o.Albedo = c.rgb;
			o.Albedo = fixed3(1,0,0);  //返回红色
			o.Alpha = c.a;
		}
		ENDCG
	} 
	FallBack "Diffuse"
}

        在场景里创建一个Cube,把Hello Material 指定给 Mesh Renderer 的 Materials的Element 0 ,就得到下面的效果(只有一块红色):

        显然,这个Shader就是将贴图上的像素都设为红色。 下面逐行讲解下这个Shader的语句:

        第一行定义的是这个Shader的名字一般的格式是分类+名字,并用“/"分隔:

Shader "Custom/HelloShader"

        在 Properties {} 的结构中,定义的属性就是前面说到的Shader输入参数,而且 Properties{} 中定义的属性也是Material提供得到的,在Unity中Material 的 Inspector面板上可以设置对应属性的值。先看下定义 Property 的格式:

        上图中,_Color是在Shader内的变量,Main Color是在Inspector 面板显示的名字,Color是属性的类型,(1,1,0)是属性的默认值。Hello Shader在Properties只定义了一张贴图:

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

        SubShader{} 结构就是一个具体的处理,对于不同的显卡可以有不同的处理,即可以定义多个SubShader{}结构,不同的设备优先选择一个可以允许的SubShader运行。在SubShader前面定义了 Tags{} 和 LOD ,这里可以先不管,只需要理解成设置 SubShader 的参数就可,后面会做详细的介绍。

       在看下最后一句 FallBack "Diffuse",这个语句的作用是如果前面的 SubShader都不能在设备上运行的情况下,就运行FallBack 指定的Shader运行。

FallBack "Diffuse"

      

       前面讲解的是 Shader 的结构的东西,更多细节会后面的章节做介绍。本文主要介绍Hello Shader的主要处理过程:

                CGPROGRAM
		#pragma surface surf Lambert

		sampler2D _MainTex;

		struct Input {
			float2 uv_MainTex;
		};

		void surf (Input IN, inout SurfaceOutput o) {
			half4 c = tex2D (_MainTex, IN.uv_MainTex);
			//o.Albedo = c.rgb;
			o.Albedo = fixed3(1,0,0);  //返回红色
			o.Alpha = c.a;
		}
		ENDCG

        首先 CGPRPGRAM  和 ENDCG 表示这是一段CG程序,分别表示CG程序的开始和介绍。Unity的Shader用的是Nvidia Cg 语言。

 

        接下来  #pragma surface surf Lambert 声明了HelloShader 定义的是一个表面(Surface)Shader(后面会有介绍),它的处理函数式 surf ,并且指定的光照模型是 Lambert。语句的原型是这样的:

               #pragma surface surfaceFunction lightModel [optionalparams]   其中 surface 是声明为 表面Shader, surfaceFuction 是Shader的指定实现方法, lightMode[optionalparams]是Shader使用的光照模型

        这里的 surf 相当于 C语言的main函数,可以认为是Shader的执行入口,不过跟main不同的是,他可以随意命名,然后在 #pragma surface 指定就行了。

        surf 有两个参数,Input IN 和 SurfaceOutput o(inout 是一个形参的修饰符,表示可做输入或输出的引用类型),其中Input 是HelloShader定义的输入参数结构体:

struct Input {
	float2 uv_MainTex;
};

        Input结构里中指定定义了一个 float2 uv_MainTex 变量,uv_MainText表示贴图 _MainTex 的uv向量。而 _MainTex 就是前面定义 sampler2D _MainTex ,这里 sampler2D 和 float2 都是Cg的数据类型(后面会有专门章节介绍Cg的数据类型已经基本语法)。

       SurfaceOutput 类型是预定义的,可先不去深究:

struct SurfaceOutput {
    half3 Albedo;     //像素的颜色
    half3 Normal;     //像素的法向值
    half3 Emission;   //像素的发散颜色
    half Specular;    //像素的镜面高光
    half Gloss;       //像素的发光强度
    half Alpha;       //像素的透明度
};

      也就是说 surf 方法其实对输入结构 Input IN 进行处理,得到输出 SurfaceOutput o的像素结构。那HelloShader进行什么样的处理呢?

             half4 c = tex2D (_MainTex, IN.uv_MainTex);   //tex2D 是对_MainTex 的 IN.uv_MainTex位置进行采样得到(r,g,b,a)的四元组 c

       o.Albedo = fixed3(1,0,0);  //直接返回红色作为输出像素的颜色,这样导致看到就是一个红色块

       o.Alpha = c.a;     //返回c的alpha值,作为输出像素的alpha值

    将 o.Albedo = fixed3(1,0,0) 改为 o.Albedo = c.rgb 在屏幕就会输出原来的贴图。

 

 

小结:

    万事开头难,写的很简单,本来昨晚就应该写好的,但后面还是去睡觉了。只是对Shader进行了简单的介绍,很多细节都没交代清楚,意犹未尽,D.S.Qiu后面进行专门的介绍会更好些:

              Cg的基础语法

              Unity Shader的结构

              Unity Shader类型(Surface,Vert,Fragment)

       

        文章内容大多不是D.S.Qiu原创,只是为了记录自己的学习过程。

        如果您对D.S.Qiu有任何建议或意见可以在文章后面评论,或者发邮件(gd.s.qiu@gmail.com)交流,您的鼓励和支持是我前进的动力,希望能有更多更好的分享。

        转载请在文首注明出处:http://dsqiu.iteye.com/blog/2028503

更多精彩请关注D.S.Qiu的博客和微博(ID:静水逐风)

 

 

 


参考:

OneV's Den: http://onevcat.com/2013/07/shader-tutorial-1/

风宇冲: http://blog.sina.com.cn/s/blog_471132920101dfth.html

③帅哥帅: http://www.cppblog.com/lll109383670/archive/2012/02/21/166183.html

  • 大小: 44.7 KB
  • 大小: 9.1 KB
2
1
分享到:
评论

相关推荐

    Unity3D Shader开发中文视频讲义

    Unity3D Shader开发是游戏开发领域中的重要环节,它涉及到图形渲染、光照处理、材质表现等核心内容。Shader是编写图形着色器的程序,它直接影响到游戏画面的质量和性能。在Unity3D中,Shader语言通常使用的是基于Cg/...

    猫都能学会的Unity3D Shader入门指南

    如果您想深入了解 Unity3D 的核心技术,学习 Shader 编程是必经之路。然而,对于初学者来说,Shader 的学习曲线非常陡峭,相关的学习资源也非常分散。因此,本系列教程旨在为初学者提供一个系统的 Shader 入门指南,...

    猫都能学会的Unity3D Shader入门指南(一)1

    【Unity3D Shader入门指南】 ...总之,Unity3D Shader的入门虽然有一定难度,但通过逐步学习和实践,即使是猫(此处比喻新手)也能掌握。本教程将带你迈出Shader编程的第一步,让你在Unity3D的世界里更加游刃有余。

    StrumpyShaderEditor Unity3d shader 编辑器

    StrumpyShaderEditor Unity3d shader 编辑器

    Unity3D Shader实现扫描显示效果

    "Unity3D Shader实现扫描显示效果" Unity3D Shader是一种强大的图形处理技术,可以用于实现各种视觉效果。在本文中,我们将详细介绍如何使用 Unity3D Shader 实现扫描显示效果。 标题解释 TITLE:Unity3D Shader...

    Unity3d Shader代码提示加高亮 一键安装 适用于VS2017

    总之,"Unity3d Shader代码提示加高亮 一键安装 适用于VS2017" 是一款专为Unity3D开发者设计的实用工具,它提升了Shader编程的效率和舒适度,让开发过程更为顺畅。对于任何在VS2017中从事Unity Shader开发的个人或...

    unity3d shader教程

    unity3d shader基础教程,unity3d shader基础教程,unity3d shader基础教程

    Unity3D shader中文帮助手册

    通过阅读《Unity3D shader中文帮助手册》(一).pdf,开发者可以系统地学习Shader的基础知识和进阶技巧,提升在Unity3D中的图形编程能力,从而创建出更具视觉冲击力的游戏或应用。如果手册分为两部分,那么第二部分...

    Unity3D内置Shader源码与详解

    通过深入研究,开发者可以掌握Shader编程技巧,创造出更丰富、更真实的3D视觉体验。无论你是新手还是经验丰富的开发者,这个资源都能为你提供宝贵的启示,帮助你在Unity3D项目中实现更多可能性。

    Unity3D 力场/防护罩 shader

    在Unity3D游戏开发中,视觉效果的呈现是至关重要的,而着色器(Shader)则是实现这些效果的关键工具。本资源"Unity3D 力场/防护罩 shader"提供了力场和防护罩效果的实现方案,使得开发者可以创建出具有科幻感的游戏...

    Unity3d Shader代码提示加高亮 一键安装 适用于VS2013

    本资源提供的是一个专为Unity3d Shader开发优化的Visual Studio 2013插件,通过一键安装,用户可以在VS2013中享受到代码补全、高亮显示等功能,大大提升Shader编程体验。Visual Studio是微软开发的一款强大集成开发...

    Unity3D常用shader

    Unity3D是一款强大的跨平台游戏开发引擎,广泛应用于2D和3D...通过研究和实践DefaultResourcesExtra和DefaultResources中的Shader示例,开发者可以深入理解Unity3D的渲染机制,并为自己的项目创造出独特的视觉风格。

    Unity3D Shader

    ### Unity3D Shader编写教程知识点概述 #### 一、Unity3D Shader简介 Unity3D是一款功能强大的跨平台游戏引擎,被广泛应用于2D和3D游戏开发中。Shader是Unity3D中一种用于控制物体表面外观效果的技术,通过编写...

    unity3D 镜面反射shader

    在Unity中,实现镜面反射的效果是通过Shader来完成的,Shader是一种编程语言,它可以控制场景中的物体如何在屏幕上显示。在本主题中,我们将深入探讨Unity3D中的镜面反射Shader及其实现。 镜面反射在图形学中是一个...

    unityshader教程一共16篇(03)

    Unity Shader是Unity 3D引擎中的一个重要组成部分,用于控制游戏对象的外观和视觉效果。本教程系列共计16篇,本文将重点解析其中的第三部分,涵盖了Unity Shader的基础概念、重要概念和技术应用。 1. **Shader基础...

    unity3d描边效果shader

    在Unity3D中,Shader通常是基于图形编程语言如GLSL或HLSL编写的,但在Unity中更常用的是其自定义的Surface Shader语言,因为它简化了编写复杂着色器的过程。在描述中提到的"有详细的模型描边代码,很简单,但也很...

    UnityShader 实现3D模型颜色渐变效果

    - **CG Shader语言**:Unity支持基于Cg的Shader编程,Cg是一种高级着色语言,可以被编译为GPU能执行的指令。 - **表面着色器(Surface Shader)**:Unity中的Surface Shader提供了一种方便的方式来编写Shader,它...

    unity3d shader入门精要

    unity3d shader 入门文档 总结shader基本结构 和知识 非常实用

    Unity内置Shader源代码

    Unity内置Shader源代码是Unity引擎自带的一系列图形渲染程序,它们使用了Unity特有的Shader语言——ShaderLab。ShaderLab是一种简洁的脚本语言,专为在Unity中编写表面着色器而设计。通过学习Unity内置Shader的源...

Global site tag (gtag.js) - Google Analytics