一些通过uv纹理坐标实现的简单shader(一)

    所谓纹理,简单说就是一张图片,通过规定好的原点和二维坐标(一般称为uv坐标),就可以获得图片任意像素的颜色信息。
    三维建模时,为了控制模型外观,我们会通过纹理映射技术将图片“黏”在模型表面。在模型的每个顶点上,一般会存储一个 二维坐标信息,其对应的就是纹理图片的uv坐标,通过这个坐标,就可以确定每个顶点的颜色。当然,也可以通过纹理图片的像素存储其他信息,比如 模型顶点的法线等。
    一般而言,为了显示正确的效果,模型顶点存储的uv坐标确定的而通过改变uv的值,我们就能够做出一些简单的效果,下面就来演示一个很常见波纹效果,其效果如下:
这里写图片描述
    我们使用的是unity的顶点与片段着色器,首先是一些准备工作,如下:

Shader "Custom/Ripple" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}

    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200

        Pass
        {

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            sampler2D _MainTex;
            float4 _MainTex_ST;

            struct v2f
            {
                float4 pos : POSITION;
                float2 uv : TEXCOORD0;
            };

            v2f vert(appdata_full v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                return o;
            }

            float4 frag(v2f i) : COLOR
            {      
               //to do something
            }

            ENDCG
        }
    }
    FallBack "Diffuse"
}

    为了得到上图的效果,我们需要在片段着色器中对uv做相应的处理。 先看图, 想要产生这种类似于水面的波动效果,最简单的就是让图片的每一个像素沿着某个方向周期性的往复运动, 像下面这样:这种运动可以通过平面简谐波进行模拟,其波函数我们简写为y=Acos(at+bx),其中t为时间,x为与原点(已知振动方程的点)的距离。在我们的shader中, t很容易用_Time[1]表示,距离我们可以取uv.x(即u相同让它有相同的运动),同时为了方便调整其他参数,我们先在Properties里添加如下定义:

          _Scale("Scale", Range(0,500.0)) = 3.0                                
        _Speed("Speed", Range(-50,50.0)) = 1.0
        _Identity("Identity",Range(50,100.0))=80

    然后在片段着色器中做如下处理:


    float4 frag(v2f i) : COLOR
    {
        float4 o;
        half2 uv = i.uv;
        half r = uv.x;//sqrt(uv.x*uv.x + uv.y*uv.y);
        half z = cos(_Scale*r + _Time[1] * _Speed) /_Identity;
        o.rgb = tex2D(_MainTex, uv+ float2(z,0)).rgb;
        o.a =1;
        return o;
    }

     运行,调整一下参数,可以得到下面这样的效果, 可以清晰的感觉到像素在沿着x轴进行波动。
这里写图片描述
    当然,为了效果好一点,我们可以作如下修改:

    void surf(Input IN, inout SurfaceOutput o) {
        half2 uv = IN.uv_MainTex;
        half r =sqrt(uv.x*uv.x + uv.y*uv.y);
        half z = cos(_Scale*r+_Time[1] * _Speed)/80;
        o.Albedo = _Color.rgb * tex2D(_MainTex, IN.uv_MainTex + float2(z,z)).rgb;
        o.Alpha = _Color.a;
    }

    这里像素会沿着原点与该点的向量方向进行往复运动,因此与原点距离相同的圆上的点都有着相似的运动,其效果如下:
这里写图片描述

ML

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值