shader的简单应用—1

来源:互联网 发布:360比价软件 手机 编辑:程序博客网 时间:2024/06/08 18:17

    shader编程其实是对GPU编程,我们的shader编程不像untiy脚本对CPU编程那样,它需要简介,简单。接下来做几个很有意思的shader

   Shader "Custom/CartoonShader" {
Properties {
    
_BorderColor("BorderColor",Color)=(0.6,0,0,1)
_CenterX("CenterX",float)=.5
_CenterY("CenterY",float)=.5
_Distance("Distance",float)=0
        _Background("Background",2D)="black"{}

            //属性代码块主要unity编辑面板和CG交互。
}


CGINCLUDE
#include "UnityCG.cginc"
float4 _BorderColor;
float _CenterX;
float _CenterY;
float _Distance;
sampler2D _Background;
float4 _Background_ST;
        //根据属性块中的属性来定义相应的变量。

struct input
{
  float4 vertex:POSITION;
  float2 uv:TEXCOORD;
};
     struct output
{
 float4 pos:SV_POSITION;
 float2 uv:TEXCOORD0;
};
output vert(input i)
{
   output o;
   o.pos=mul(UNITY_MATRIX_MVP,i.vertex);
            o.uv.xy = TRANSFORM_TEX(i.uv, _Background);

#if !UNITY_UV_STARTS_AT_TOP//主要区分openGL的屏幕原点和Dx屏幕原点。
o.uv.y = 1 - o.uv.y;
#endif
return o;
}
float4 frag(output o):COLOR
{  


  #if !UNITY_UV_STARTS_AT_TOP//同样这句注释意思和上面一样
  float realY = _ScreenParams.y - _CenterY;
  #else
  float realY = _CenterY;
  #endif


        float distance = length (half2(o.uv.x * _ScreenParams.x, o.uv.y * _ScreenParams.y) - half2(_CenterX, realY));
float4 screenColor = float4(0,0,0,0); 
float delta = distance - _Distance; 
fixed4 maskColor = lerp(_BorderColor, tex2D(_Background, o.uv.xy), clamp(delta / 5, 0, 1));
return lerp(screenColor, maskColor, (clamp(delta, -15, 0) / 15) + 1);

               //这里代码就只有2个插值了,应该很好理解
}

ENDCG

SubShader 
{
Tags { "Queue" = "Transparent" }
LOD 200
Lighting Off
pass
{
  CGPROGRAM
  #pragma vertex vert
  #pragma fragment frag
  ENDCG
  
                 Blend SrcAlpha OneMinusSrcAlpha
}

FallBack "Diffuse"
}

这里就是一个类似于技能冷却的效果。

Shader "Custom/CoolShader" {
Properties {
    
_BkColor("BkColor",Color)=(0.6,0,0,1)
_CenterX("CenterX",float)=.5
_CenterY("CenterY",float)=.5
_Angle("Angle",float)=0
_Constant("Constant",float)=0
    _Background("Background",2D)="black"{}
}


CGINCLUDE
#include "UnityCG.cginc"
float4 _BkColor;
float _CenterX;
float _CenterY;
float _Angle;
float _Constant;
sampler2D _Background;
float4 _Background_ST;


struct input
{
  float4 vertex:POSITION;
  float2 uv:TEXCOORD;
};
    struct output
{
 float4 pos:SV_POSITION;
 float2 uv:TEXCOORD0;
};
output vert(input i)
{
   output o;
   o.pos=mul(UNITY_MATRIX_MVP,i.vertex);
o.uv.xy=TRANSFORM_TEX(i.uv,_Background);
#if !UNITY_UV_STARTS_AT_TOP
o.uv.y = 1 - o.uv.y;
#endif
   return o;
}
float4 frag(output o):COLOR
{  


  #if !UNITY_UV_STARTS_AT_TOP
  float realY=_ScreenParams.y-_CenterY;
  #else
  float realY = _CenterY;
  #endif


  float2 vector1 =normalize(float2(_CenterX,0));
  float2 vector2 =normalize(float2(o.uv.x*_ScreenParams.x,o.uv.y*_ScreenParams.y)-float2(_CenterX,realY)); 
  float angle=acos(dot(vector1,vector2));


  if(_Angle<=_Constant)
  {  
      if(angle<_Angle && vector2.y>=0)
  {    
     return tex2D(_Background,o.uv.xy);
  }
  else
  {
      return _BkColor;
  }
  }
  else if(_Angle>_Constant)
  {   


      if(angle<(2*_Constant-_Angle)&&vector2.y<0)
      return _BkColor;
  else
  {   
     return tex2D(_Background,o.uv.xy);   
  }
  }
  else
  {
     return _BkColor;
  }
}


ENDCG


SubShader 
{
Tags { "Queue" = "Transparent" }
LOD 200
Lighting Off
pass
{
  CGPROGRAM
  #pragma vertex vert
  #pragma fragment frag
  ENDCG
  
                  Blend SrcAlpha OneMinusSrcAlpha
}

FallBack "Diffuse"
}

这里我这个shader写的有的不好的,因为用了大量的条件判断语句,这shader里面这应该是绝对避免的。但是如果我们不用条件语句就无法完成这样的效果,如果是这样的话,我建议你还是勉强的用一下,如果可以用UnityCG.cginc库里面的函数的话,那就不用这种繁琐的条件语句,大量的条件数据会降低GPU的执行效率,因为GPU是并行的,等于它还要等待判断结果结束,才可以跳到下一个条件中去,这会大大降低GPU的处理效率的。这里我就sb一把了。强烈建议不要用条件语句!强烈建议不要用条件语句!强烈建议不要用条件语句!

Shader "Custom/Pixelate" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Scale ("1/单位格子的大下", Range(0,350)) = 50
}


CGINCLUDE
#include  "UnityCG.cginc"
        sampler2D _MainTex;
half4 _MainTex_ST;
half _Scale;
fixed4 _Color;

struct output
{
  half4 pos:SV_POSITION;
  half2 uv:TEXCOORD0;
};
output vert(appdata_full i)
{
  output o;
  o.pos=mul(UNITY_MATRIX_MVP,i.vertex);
  o.uv.xy=TRANSFORM_TEX(i.texcoord,_MainTex);
  return o;
}
half4 frag (output o):COLOR
{   
   half ratio= 1/_Scale;
   half2 PixpleUV=half2(ratio*ceil(o.uv.x/ratio),ratio*ceil(o.uv.y/ratio));
return tex2D(_MainTex,PixpleUV)*_Color;
}
ENDCG


SubShader 
{

Tags { "RenderType"="Opaque" }
Lighting Off
LOD 200

GrabPass { "_ScreenContent" }
Pass
{
  CGPROGRAM
  #pragma fragment frag 
  #pragma vertex vert
  ENDCG
}

FallBack "Diffuse"
}

 这个着色器代码的主要作用是暗中马赛克的效果,用来模糊图片。从上面的shader代码可以看出来其实写这种着色器代码不是很难吧,难点是在你不知道一个效果的原理,当我告诉你这个马赛克效果原理的时候你一定会觉得很简单,我们知道之所以图片会清晰是每个像素的颜色会不同,即使是相近像素也会用插值进行过度,如果我把10*10这么大个像素快都贴一种颜色,你看起来不就迷糊了嘛。这些只是shader的简单

当然这样还是显示不出来,这里还要配合GL库里面的方法来实现。这里先简介几个shader。

0 0