渲染纹理实例

参考文献:《Unity Shader入门精要》

渲染纹理

 

镜子效果

Shader "Unlit/Chapter10-Mirror"
{
    Properties
    {
        _MainTex ("Main Tex", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" "Queue"="Geometry"}
        //LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            sampler2D _MainTex;

            struct a2v{
                float4 vertex:POSITION;
                float3 texcoord:TEXCOORD0;
            };

            struct v2f{
                float4 pos:SV_POSITION;
                float3 uv:TEXCOORD0;
            };

            v2f vert(a2v v){
                v2f o;
                o.pos=UnityObjectToClipPos(v.vertex);
                o.uv=v.texcoord;
                //作为镜子此刻需要翻转x
                o.uv.x=1-o.uv.x;
                //o.uv.y=1-o.uv.y;
                return o;
            }

            fixed4 frag(v2f i):SV_Target{
                return tex2D(_MainTex,i.uv);
            }

            ENDCG
        }
    }
    FallBack Off
}

 

玻璃效果

Shader "Unlit/Chapter10-GlassRefraction"
{
    Properties
    {
        _MainTex("Main Tex",2D)="white" {}   //玻璃材质纹理,默认为白色纹理
        _BumpMap("Normal Map",2D)="bump" {}  //玻璃的法线纹理
        _Cubemap("Envirnoment Cubemap",Cube)="Skybox" {}   //模拟反射的环境纹理
        _Distortion("Distortion", Range(0,100))=10    //用于控制模拟折射时图像的扭曲程度
        _RefractAmount("Refract Amount",Range(0.0,10))=1.0  //控制折射程度,为0,该玻璃只包含反射效果,为1只包含折射效果
    }
    SubShader
    {
        Tags { "Queue"="Transparent" "RenderType"="Opaque" }
        
        GrabPass {"_RefractionTex"}   //通过GrabPass定义一个抓取屏幕图像的Pass

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;   //为了定义偏移和缩放属性(Scale,Transform)
            sampler2D _BumpMap;   
            float4 _BumpMap_ST;
            samplerCUBE _Cubemap;
            float _Distortion;
            fixed _RefractAmount;

            //对应了使用GrabPass时指定的纹理名称
            sampler2D _RefractionTex;
            float4 _RefractionTex_TexelSize;

            struct a2v{
                float4 vertex : POSITION;
                float3 normal:NORMAL;
                float4 tangent:TANGENT;
                float2 texcoord:TEXCOORD0;
            };

            struct v2f{
                float4 pos:SV_POSITION;
                float4 scrPos:TEXCOORD0;
                float4 uv:TEXCOORD1;
                float4 TtoW0:TEXCOORD2;
                float4 TtoW1:TEXCOORD3;
                float4 TtoW2:TEXCOORD4;
            };

            v2f vert(a2v v){
                 v2f o;
                 o.pos=UnityObjectToClipPos(v.vertex);
                 o.scrPos=ComputeGrabScreenPos(o.pos);   //获得对应被抓取的屏幕图像的采样坐标

                 //获得MainTex和BumpMap的采样坐标
                 o.uv.xy=TRANSFORM_TEX(v.texcoord,_MainTex);   
                 o.uv.zw=TRANSFORM_TEX(v.texcoord,_BumpMap);

                 //计算顶点从切线空间到世界坐标空间的转换矩阵,通过得到切线空间三个坐标轴(副切线,切线,法线)在世界坐标空间下的表示来得到
                 float3 worldPos=mul(unity_ObjectToWorld,v.vertex).xyz;
                 fixed3 worldNormal=UnityObjectToWorldNormal(v.normal);
                 fixed3 worldTangent=UnityObjectToWorldDir(v.tangent.xyz);
                 fixed3 worldBinormal=cross(worldNormal,worldTangent)*v.tangent.w;

                 o.TtoW0=float4(worldTangent.x,worldBinormal.x,worldNormal.x,worldPos.x);
                 o.TtoW1=float4(worldTangent.y,worldBinormal.y,worldNormal.y,worldPos.y);
                 o.TtoW2=float4(worldTangent.z,worldBinormal.z,worldNormal.z,worldPos.z);

                 return o;
            }

            fixed4 frag(v2f i):SV_Target{
                float3 worldPos=float3(i.TtoW0.w,i.TtoW1.w,i.TtoW2.w);
                fixed3 worldViewDir=normalize(UnityWorldSpaceViewDir(worldPos));

                fixed3 bump=UnpackNormal(tex2D(_BumpMap,i.uv.zw));

                float2 offset=bump.xy*_Distortion*_RefractionTex_TexelSize.xy;
                i.scrPos.xy=offset*i.scrPos.z+i.scrPos.xy;
                fixed3 refrCol=tex2D(_RefractionTex,i.scrPos.xy/i.scrPos.w).rgb;

                bump=normalize(half3(dot(i.TtoW0.xyz,bump),dot(i.TtoW1.xyz,bump),dot(i.TtoW2.xyz,bump)));
                fixed3 reflDir=reflect(-worldViewDir,bump);
                fixed4 texColor=tex2D(_MainTex,i.uv.xy);
                fixed3 reflCol=texCUBE(_Cubemap,reflDir).rgb*texColor.rgb;

                fixed3 finalColor=reflCol*(1-_RefractAmount)+refrCol*_RefractAmount;

                return fixed4(finalColor,1);
            }


            
            ENDCG
        }
    }

    FallBack "Diffuse"
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值