wiki/Cg Programming/Unity_shder/Shading in World Space

地址

https://en.wikibooks.org/wiki/Cg_Programming/Unity/Shading_in_World_Space

重点

了解  uniform关键字及uniform参数

代码

<span style="font-weight: normal;">Shader "Cg shading in world space" {
   SubShader {
      Pass {
         CGPROGRAM

         #pragma vertex vert  
         #pragma fragment frag 
 
         // uniform float4x4 _Object2World; 
            // automatic definition of a Unity-specific uniform parameter

         struct vertexInput {
            float4 vertex : POSITION;
         };
         struct vertexOutput {
            float4 pos : SV_POSITION;
            float4 position_in_world_space : TEXCOORD0;
         };

         vertexOutput vert(vertexInput input) 
         {
            vertexOutput output; 
 
            output.pos =  mul(UNITY_MATRIX_MVP, input.vertex);
            output.position_in_world_space = 
               mul(_Object2World, input.vertex);
               // transformation of input.vertex from object 
               // coordinates to world coordinates;
            return output;
         }
 
         float4 frag(vertexOutput input) : COLOR 
         {
             float dist = distance(input.position_in_world_space, 
               float4(0.0, 0.0, 0.0, 1.0));
               // computes the distance between the fragment position 
               // and the origin (the 4th coordinate should always be 
               // 1 for points).
            
            if (dist < 5.0)
            {
               return float4(0.0, 1.0, 0.0, 1.0); 
                  // color near origin
            }
            else
            {
               return float4(0.1, 0.1, 0.1, 1.0); 
                  // color far from origin
            }
         }
 
         ENDCG  
      }
   }
}</span>
这部分里面多了_Object2World这个参数,可是我们没有定义过,哪里来的呢?
这个又是unity预定义好的,所以直接用就好了。
在vert函数中我们从Input中取到位置信息(之前说过mul函数),把变化后的位置信息存入输出的结构体,接下来再把顶点的坐标转为世界坐标存入自定义输出结构体(记住在参考书阳春白雪中提到的顶点处理的是位置、光等信息,片段中处理的是颜色信息)
在frag函数中distance函数求出每个像素距离零点的距离,然后判断显示不同的效果,大致意思是当物体在某体范围内时显示某种颜色,超出范围是另外一种颜色。
效果如图:

当然还有更多的Uniforms参数
uniform float4 _Time, _SinTime, _CosTime; // time values
   uniform float4 _ProjectionParams;
      // x = 1 or -1 (-1 if projection is flipped)
      // y = near plane; z = far plane; w = 1/far plane
   uniform float4 _ScreenParams; 
      // x = width; y = height; z = 1 + 1/width; w = 1 + 1/height
   uniform float3 _WorldSpaceCameraPos;
   uniform float4x4 _Object2World; // model matrix
   uniform float4x4 _World2Object; // inverse model matrix 
   uniform float4 _LightPositionRange; // xyz = pos, w = 1/range
   uniform float4 _WorldSpaceLightPos0; 
      // position or direction of light source

   uniform float4x4 UNITY_MATRIX_MVP; // model view projection matrix 
   uniform float4x4 UNITY_MATRIX_MV; // model view matrix
   uniform float4x4 UNITY_MATRIX_V; // view matrix
   uniform float4x4 UNITY_MATRIX_P; // projection matrix
   uniform float4x4 UNITY_MATRIX_VP; // view projection matrix
   uniform float4x4 UNITY_MATRIX_T_MV; 
      // transpose of model view matrix
   uniform float4x4 UNITY_MATRIX_IT_MV; 
      // transpose of the inverse model view matrix
   uniform float4x4 UNITY_MATRIX_TEXTURE0; // texture matrix
   uniform float4x4 UNITY_MATRIX_TEXTURE1; // texture matrix
   uniform float4x4 UNITY_MATRIX_TEXTURE2; // texture matrix
   uniform float4x4 UNITY_MATRIX_TEXTURE3; // texture matrix
   uniform float4 UNITY_LIGHTMODEL_AMBIENT; // ambient color
可是这个距离是写死的,不方便使用,如果你要在编辑器使用怎么办?

完善代码

Shader "Cg shading in world space" {
   Properties {
      _Point ("a point in world space", Vector) = (0., 0., 0., 1.0)
      _DistanceNear ("threshold distance", Float) = 5.0
      _ColorNear ("color near to point", Color) = (0.0, 1.0, 0.0, 1.0)
      _ColorFar ("color far from point", Color) = (0.3, 0.3, 0.3, 1.0)
   }
   
   SubShader {
      Pass {
         CGPROGRAM

         #pragma vertex vert  
         #pragma fragment frag 
 
         #include "UnityCG.cginc" 
            // defines _Object2World and _World2Object

         // uniforms corresponding to properties
         uniform float4 _Point;
         uniform float _DistanceNear;
         uniform float4 _ColorNear;
         uniform float4 _ColorFar;

         struct vertexInput {
            float4 vertex : POSITION;
         };
         struct vertexOutput {
            float4 pos : SV_POSITION;
            float4 position_in_world_space : TEXCOORD0;
         };

         vertexOutput vert(vertexInput input) 
         {
            vertexOutput output; 
 
            output.pos =  mul(UNITY_MATRIX_MVP, input.vertex);
            output.position_in_world_space = 
               mul(_Object2World, input.vertex);
            return output;
         }
 
         float4 frag(vertexOutput input) : COLOR 
         {
             float dist = distance(input.position_in_world_space, 
               _Point);
               // computes the distance between the fragment position 
               // and the position _Point.
            
            if (dist < _DistanceNear)
            {
               return _ColorNear; 
            }
            else
            {
               return _ColorFar; 
            }
         }
 
         ENDCG  
      }
   }
}

这里与上面不同的是多出了Properties,有了这个东西你定义的属性值就可以暴露在unity的属性面板上了,格式:
Properties {//属性
    _MainTex ("Base (RGB)", 2D) = "white" {}//变量名(“面板上显示的信息,可以作为说明”,类型)= 默认值
    (需要使用的属性,类型:2D,Color ,rect,cube,range(min,max),float,Vector)
   }
定义完了之后怎么获取呢?
uniform 通过关键字+变量名就可以取到
注意uniform 的用法(更详细的请查找参考书)
1.改关键字表示从外部获取的参数
2.不能作为局部变量的修饰来使用
这样你就可以一边在编辑器看效果,而不用改代码了

通过代码修改shader的属性值

  GetComponent(Renderer).sharedMaterial.SetVector("_Point", 
      Vector4(1.0, 0.0, 0.0, 1.0));
   GetComponent(Renderer).sharedMaterial.SetFloat("_DistanceNear", 
      10.0);
   GetComponent(Renderer).sharedMaterial.SetColor("_ColorNear", 
      Color(1.0, 0.0, 0.0));
   GetComponent(Renderer).sharedMaterial.SetColor("_ColorFar", 
      Color(1.0, 1.0, 1.0));




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值