Unity Shader分享

Unity Shader学习—GLSL编写shader

2017-11-07  本文已影响42人  一个有味道的名字

在unity中,一般都是用Cg语言编写顶点片元着色器,或者直接使用表面着色器,这两者的编写语言都是Cg,除了Cg外,我们还可以使用OpenGL编写。

用Cg编写的方式称为HLSL,用OpenGL编写的方式称为GLSL。

那么,我们习惯上使用Cg,也就是HLSL在unity中编写shader,但偶尔换个口味也是可以的。
这里介绍的就是使用GLSL编写shader。

当然,这里介绍的只是语法结构,并不是涉及很多,而我本身也不是很擅长去编写这类shader。

通过这个语法结构,我们可以将一些用OpenGL编写的着色器拿到unity中使用。

OK,直接来看一下代码:

简单的改变颜色shader代码

Shader "LearnShader/GLSL/GLSLTest"{
    Properties{
        _Color("Color",Color) = (1,1,1,1)
    }
    SubShader{
        Tags{
            "Queue" = "Geometry" 
            "RenderType" = "Opaque"
            "PreviewType" = "Plane"
        }
        Pass{
            GLSLPROGRAM
            #ifdef VERTEX
            void main(){
                gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
            }
            #endif
            #ifdef FRAGMENT
            uniform vec4 _Color;
            void main(){
                gl_FragColor = _Color;
            }
            #endif
            ENDGLSL
        }
    }
}

OK,如果你直接把这段代码拷贝进unity中的话会报错的。
在编写shader之间,我们需要对unity做一点点改变,使其支持GLSL编写shader。

找到桌面上的unity快捷方式键,右键,打开属性面板,如下图:

Paste_Image.png

在目标那一栏中,最后面添加:-force-opengl
如果你的unity是打开的,那么就关闭重启一下。
然后就是正常的创建shader代码,然后将上述代码写好,保存即可。

需要我们注意的是:

  1. 如果你想通过inspector面板调节shader属性,那么除了在Properties块中定义属性外,在Pass块中定义属性需要在其类型前面加上 uniform 关键字。
  2. GLSL的代码段是被包括在 GLSLPROGRAM 与ENDGLSL之间。
  3. 顶点与片元着色器,都是通过 #ifdef 与 #endif 加上 VERTEX 与 FRAGMENT 关键字确定的。
  4. 顶点与片元着色器中的类似gl_Position等是OpenGL中的语法。

以上就是关于使用GLSL编写shader的语法结构。

最后给出一个比较有意思的shader,也是使用GLSL编写的。

代码如下:

Shader "LearnShader/GLSL/GLSLTest"{
    Properties{
        _MainTex("Base(RGB)",2D) = "white"{}
    }
    SubShader{
        Tags{"RenderType" = "Opaque" "Queue" = "Geometry"}
        Pass{
            GLSLPROGRAM
            #ifdef VERTEX
            void main(){
                gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
            }
            #endif
            #ifdef FRAGMENT
            uniform sampler2D _MainTex;
            const float size = 0.5;

            void main(){
               vec2 realSize = vec2(textureSize(_MainTex, 0));
               float ratio = (realSize.x > realSize.y) ? 
               realSize.y/realSize.x : realSize.x/realSize.y;
               
               vec2 texSize = vec2(512., 512.);
               vec2 xy = gl_FragCoord.xy;
               
               if(realSize.x > realSize.y) {
                  xy.x = xy.x * ratio;
               }
               else
![Animation.gif](http:https://img.haomeiwen.com/i5301156/17a2bc8700542539.gif?imageMogr2/auto-orient/strip)
{
                  xy.y = xy.y * ratio;
               }
               
               vec2 center = vec2(texSize/2.);

               float maxV = dot(center, center);
               float minV = floor(maxV*(1. - size));
               float diff = maxV - minV;
               
               vec2 uv = xy / texSize;
               
               vec4 srcColor = texture2D(_MainTex, uv);

               float dx = center.x - xy.x;
               float dy = center.y - xy.y;
               
               float dstSq = pow(dx, 2.) + pow(dy, 2.);
               
               float v = (dstSq / diff);
               float r = clamp(srcColor.r + v, 0., 1.);
               float g = clamp(srcColor.g + v, 0., 1.);
               float b = clamp(srcColor.b + v, 0., 1.);
               
               gl_FragColor = vec4( r, g, b, 1.0 );
            }
            #endif
            ENDGLSL
        }
    }
}

结果:

Animation.gif
上一篇下一篇

猜你喜欢

热点阅读