分享

Unityshader实例01:冰块材质

 勤奋不止 2024-03-20 发布于北京

简单版本

效果如下

这里写图片描述

原理

使用法线贴图扭曲透明颜色贴图的uv值

Shader 代码1

Shader"PengLu/normal/iceTrans" {
Properties {
    _Color ("Main Color", Color) = (1,1,1,1)
    _MainTex ("BaseTex ", 2D) = "white" {}
    _BumpMap ("Normalmap", 2D) = "bump" {}
    _BumpAmt ("Distortion", range (0,2)) = 0.1

}

SubShader {
    Tags { "Queue"="Transparent""RenderType"="Opaque" }
    ZWrite off



CGPROGRAM
#pragma surface surfLambert nolightmap nodirlightmap alpha:blend

 sampler2D _BumpMap;
 sampler2D _MainTex;
 float4 _Color;
 float _BumpAmt;

struct Input {
    float2 uv_MainTex;
    float2 uv_BumpMap;
};


void surf (Input IN,inout SurfaceOutput o) {
    fixed3 nor = UnpackNormal (tex2D(_BumpMap, IN.uv_BumpMap));
    fixed4 trans =tex2D(_MainTex,IN.uv_MainTex+nor.xy*_BumpAmt)*_Color;

    o.Albedo = trans.rgb;
    o.Alpha =trans.a;
    o.Emission = trans; 
}
ENDCG
}

FallBack"Transparent/VertexLit"
}

升级版本

效果如下
这里写图片描述

原理

使用grabtexture 截取屏幕并扭曲uv坐标,以达到透明折射的效果。
一些热浪扭曲效果也可用此shader引申出来

shader 代码2

Shader "PengLu/Custom/iceRefrationVF" {
Properties {
    _Color ("Main Color", Color) = (1,1,1,1)
    _MainTex ("BaseTex", 2D) = "white" {}
    _BumpMap ("Normalmap", 2D) = "bump" {}
    _BumpAmt ("Distortion", range (0,1)) = 0.12

}

Category {

    // We must be transparent, so other objects are drawn before this one.
    Tags { "Queue"="Transparent" "RenderType"="Opaque" }
     zwrite off



    SubShader {

        // This pass grabs the screen behind the object into a texture.
        // We can access the result in the next pass as _GrabTexture
        GrabPass {
            Name "BASE"
            Tags { "LightMode" = "Always" }
        }

        // Main pass: Take the texture grabbed above and use the bumpmap to perturb it
        // on to the screen
        Pass {
            Name "BASE"
            Tags { "LightMode" = "Always" }

        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #pragma multi_compile_fog
        #include "UnityCG.cginc"

        struct appdata_t {
            float4 vertex : POSITION;
            float2 texcoord: TEXCOORD0;
        };

        struct v2f {
            float4 vertex : SV_POSITION;
            float4 uvgrab : TEXCOORD0;
            float2 uvbump : TEXCOORD1;
            float2 uvmain : TEXCOORD2;
            UNITY_FOG_COORDS(3)
        };

        float _BumpAmt;
        float4 _BumpMap_ST;
        float4 _MainTex_ST;

        v2f vert (appdata_t v)
        {
            v2f o;
            o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
            #if UNITY_UV_STARTS_AT_TOP
            float scale = -1.0;
            #else
            float scale = 1.0;
            #endif
            o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
            o.uvgrab.zw = o.vertex.zw;
            //以上7行可以用o.uvgrab = ComputeGrabScreenPos(o.vertex);代替
            o.uvbump = TRANSFORM_TEX( v.texcoord, _BumpMap );
            o.uvmain = TRANSFORM_TEX( v.texcoord, _MainTex );
            UNITY_TRANSFER_FOG(o,o.vertex);
            return o;
        }

        sampler2D _GrabTexture;
//      float4 _GrabTexture_TexelSize;
        float4 _Color;
        sampler2D _BumpMap;
        sampler2D _MainTex;


        half4 frag (v2f i) : SV_Target
        {
            // calculate perturbed coordinates
            half2 bump = UnpackNormal(tex2D( _BumpMap, i.uvbump )).rg; 
            // we could optimize this by just reading the x & y without reconstructing the Z
            float2 offset = bump * _BumpAmt ;
            i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy;

            half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
            half4 tint = tex2D(_MainTex, i.uvmain)*_Color*2;
            col *= tint;
            UNITY_APPLY_FOG(i.fogCoord, col);
            return col;
        }
        ENDCG
                }
            }

            // ------------------------------------------------------------------
            // Fallback for older cards and Unity non-Pro

            SubShader {
                Blend DstColor Zero
                Pass {
                    Name "BASE"
                    SetTexture [_MainTex] { combine texture }
                }
            }
        }

}

surface版本 shader代码:


Shader "PengLu/Custom/iceRefrationSurf" {
Properties {
    _Color ("Main Color", Color) = (1,1,1,1)
    _MainTex ("BaseTex", 2D) = "white" {}
    _BumpMap ("Normalmap", 2D) = "bump" {}
    _BumpAmt ("Distortion", range (0,1)) = 0.12
}

SubShader {
    Tags { "Queue"="Transparent" "RenderType"="Opaque" }
     ZWrite off
     Lighting off

    GrabPass {                          
            Name "BASE"
            Tags { "LightMode" = "Always" }
        }

CGPROGRAM
#pragma surface surf Lambert nolightmap nodirlightmap
#pragma target 3.0
#pragma debug

float4 _Color;
sampler2D _MainTex;
sampler2D _BumpMap;
sampler2D _GrabTexture;
float _BumpAmt;



struct Input {
    float2 uv_MainTex;
    float2 uv_BumpMap;
    float4 screenPos;
};


void surf (Input IN, inout SurfaceOutput o) {
    fixed3 nor = UnpackNormal (tex2D(_BumpMap, IN.uv_BumpMap));
    fixed4 col = tex2D(_MainTex,IN.uv_MainTex);
    float4 screenUV2 = IN.screenPos;
    screenUV2.xy = screenUV2.xy / screenUV2.w;
    screenUV2.xy += nor.xy * _BumpAmt;

    fixed4 trans = tex2D(_GrabTexture,screenUV2.xy)*_Color;
    trans*=col; 
    o.Albedo = trans.rgb;
    o.Emission = trans.rgb;
;   
}                                                                                                                                                                                                                                                                                                   
ENDCG
}

FallBack "Transparent/VertexLit"
}

surface版本效果

surface版本目前还有问题,在编辑视图里面结果是对的,但是再camera显示不正确。暂时能力不够没找到方法修改

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多