赞
踩
ShaderLab基本结构大致3个代码块儿(一、二、三)
(一) 属性 【Properties】
Shader “name”{
【Properties】//属性
}
属性模块允许我们在可视化面板当中为材质添加要使用的原材料。
(二) Subshader算法
SubShader是专门为GPU渲染所编写的Shader的片段,在ShaderLab中至少有一个SubShader,当然也可多个。
但是,显卡每次渲染处理的时候只能选择一个SubShaders执行。那多个SubShader的作用是为了不同硬件的渲染支持,为了Shader能在比较老的图形显卡中也能支持。一般比较越往下的SubShader要简化,运算指令要简单。
(三) 【FallBack】//后退
作用是:如果SubShader里的所有算法都不能执行的话,就会后退回到最初始的状态 可以认为是默认(一般是所有硬件都支持的渲染方式)
比如: FallBack "Diffuse" 返回到漫反射的状态
Unity当中被推荐和鼓励使用的Shader,当你在Unity当中创建一个Shader时,默认的就是Surface Shader 。由于图型管线只识别vertex shaders and fragment shader这两种形式。Surface Shader 是在vertex shaders and fragment shader上面的的一种包装,最 终Unity 引擎还是会把Surface Shader 编译成能够被硬件识别和调用的vertex shaders and fragment shader.。Surface Shader 让我们可以不用去关心这些顶点和片段程序的细节,可以直接得到我们想要的着色器。这个着色器处理了很多光照细节。
比如光照、纹理采样。 所有硬件平台都可支持,针对硬件能够执行的基本命令的Shader,当然,功能有限,但是,速度最快。
- Shader "MyCustom/MyShader" {
- Properties {//属性
- // 属性名字 界面显示名 类型 值
- _Color("MyColor",color) = (1,0,0,1)
- _AmbientColor("AmbientColor",color) = (1,0,0,1)
- _SpecularColor("SpecularColor",color) = (1,0,0,1)
- _Shininess("Shininess",range(0,8)) = 3
- _Emission("EmissionColor",color) = (1,1,1,1)
- _MainTexture("MainTexture",2d) = ""
- }
- SubShader {//shader算法
- pass//通道(存储图像的色彩)
- {
- //color(1,0,0,1) //()表示直接赋值,固定值
- //color[_Color]//【】中括号表示使用参数值
- material
- { //漫反射 必须依照光照,与灯光配合,将光打到物体表面反射光,我们才能看到物体
- diffuse[_Color]//漫反射命令,要想受光照影响,必须启用光照 lighting on
- ambient[_AmbientColor]//环境光
- specular[_SpecularColor]//高光
- shininess[_Shininess]//滑动条高光反射系数,配合启用高光的命令separateSpecular on
- emission[_Emission]//自发光
- }
- lighting on//启动光照
- separateSpecular on //启用高光
- SetTexture[_MainTexture]//设置纹理
- {
- //与材质效果混合 double 是图片亮度的表现
- combine Texture*primary double
- }
- }
- }
- // Fallback "Diffuse" //固定功能管线着色器,几乎所有硬件都支持,所以这句话可以不要
- }
代码如下:
- Shader "Custom/NewSurfaceShader" {
- Properties {
- _Color ("Color", Color) = (1,1,1,1)
- _MainTex ("Albedo (RGB)", 2D) = "white" {}
- ///_Normalmap ("Normalmap", 2D) = "Normal" {}
- _Cubemap ("Cubemap", CUBE) = "Cube" {}//CUBE unity的立方体贴图
- _Glossiness ("Smoothness", Range(0,1)) = 0.5
- _Metallic ("Metallic", Range(0,1)) = 0.0
- }
- SubShader {
- Tags { "RenderType"="Opaque" }//描述渲染类型,当前是不透明的物体//Tags {"queue" = "transparent"}//透明的物体
- LOD 200 //层级细节
- CGPROGRAM//代表当前是CG代码块,开始写CG语言了
- // Physically based Standard lighting model, and enable shadows on all light types
- #pragma surface surf Standard fullforwardshadows//编译指令
- //#pragma编译指令告诉我们surface关键词是一个表面着色器 , //surf是调用的方法 ,下面有一个surf方法
- //Standard 光照表现 基于物理的光照模型,就是我们现在所说的全局光照,物体与物体之间的影响,
- //(5.0之前是漫反射 Lambert只是受到光照而已,5.0之后实现了次时代的效果)
- //fullforwardshadows 阴影表现(平行光、点光、聚光都是有阴影的)
- // Use shader model 3.0 target, to get nicer looking lighting
- #pragma target 3.0 //表示GPU硬件支持3.0 不写这句话默认是2.0
- sampler2D _MainTex;//CG 中的图片类型,sampler2D是CG语言的一个类, //上面 属性Properties 里面声明属性_MainTex时图片表现是2D,
- sampler2D _Normalmap; //但是在CG里面,如果想让CG认识_MainTex,必须在CG代码块儿里面重新声明成sampler2D类型
- samplerCUBE _Cubemap;
- struct Input { // 类似于有一个传入值
- float2 uv_MainTex;//记录uv纹理坐标,在CG中使用图片需要记录uv纹理坐标
- /// float2 uv_Normalmap;
- float3 worldRelfect;//牵扯到反射效果,记录XYZ轴的相关影像效果
- };
- half _Glossiness;//CG中的浮点型
- half _Metallic;
- fixed4 _Color;//CG中的四阶向量
- //5.0之后光照用的Standard,所以用SurfaceOutputStandard ,如果不是Standard用SurfaceOutput就可以了
- void surf (Input IN, inout SurfaceOutputStandard o) {//IN传进来(UV的传入),inout声明的o值传出去
- // 下面是一个公式 (主纹理,uv信息),Color表示把颜色应用在uv的所有的点上,有相应的表现
- fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
- o.Albedo = c.rgb; //在表面着色器里使物体受到光照的话用o.Albedo,它表示漫反射, //把拿到的图片的rgb信息应用到漫反射表现效果上
- o.Emission=texCUBE(_Cubemap,IN.worldRelfect).rgb; //是立方体贴图反射周围环境的命令,这是没有法线贴图时反射效果的代码写法
- o.Normal=UnpackNormal(tex2D (Normalmap, IN.uv_Normalmap)); //是法线贴图
- // Metallic and smoothness come from slider variables
- o.Metallic = _Metallic;//金属光泽表现
- o.Smoothness = _Glossiness;//高光光泽度
- o.Alpha = c.a;
- }
- ENDCG //CG语言代码块儿结束
- }
- FallBack "Diffuse"//如果SubShader里的所有算法都不能执行的话,就会后退回到最初始的状态
- }
注意:
如果没有用到法线贴图,想要实现反射时物体表面把图片直接反射过来就可以了,但是如果牵扯到法线、物体表面、又要牵扯到反射效果的话,就不仅仅是物体表面把图片反射过来就行了,还要考虑到法线贴图里面的凹凸细节里面的像素,反射效果就比普通平面效果稍微复杂一些,这时就要借助WorldReflectionVector。
下面是详细代码:
- Shader "Custom/NewSurfaceShader" {
- Properties{
- _Color("Color", Color) = (1,1,1,1)
- _MainTex("Albedo (RGB)", 2D) = "white" {}
- _Normalmap ("Normalmap", 2D) = "Normal" {}
- _Cubemap("Cubemap", CUBE) = "Cube" {}
- _Glossiness("Smoothness", Range(0,1)) = 0.5
- _Metallic("Metallic", Range(0,1)) = 0.0
- }
- SubShader{
- Tags{ "RenderType" = "Opaque" }
- LOD 200
- CGPROGRAM
- #pragma surface surf Standard fullforwardshadows//编译指令
-
- #pragma target 3.0
- sampler2D _MainTex;
- sampler2D _Normalmap;
- samplerCUBE _Cubemap;
- struct Input {
- float2 uv_MainTex;
- float2 uv_Normalmap;
- float3 worldRefl;
- //法线与反射效果配合需要将添加到Input结构中
- INTERNAL_DATA
- };
- half _Glossiness;//CG中的浮点型
- half _Metallic;
- fixed4 _Color;
- void surf(Input IN, inout SurfaceOutputStandard o) {
- fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
- o.Albedo = c.rgb;
- //不需要法线的反射效果
- // o.Emission=texCUBE(_Cubemap,IN.worldRefl).rgb;
- //下面是法线与反射效果配合,编写完法线命令输出后并结合WorldReflectionVector函数将计算像素中的逐个向量
- o.Normal = UnpackNormal(tex2D(_Normalmap, IN.uv_Normalmap)); //是法线贴图
- o.Emission = texCUBE(_Cubemap, WorldReflectionVector(IN, o.Normal)).rgb;
- o.Metallic = _Metallic;//金属光泽表现
- o.Smoothness = _Glossiness;//高光光泽度
- o.Alpha = c.a;
- }
- ENDCG
- }
- FallBack "Diffuse"
- }
补充如何创建Cubemap
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。