Unity shader-贴图随着模型的变化缩放

Shader:三向贴图(Tri-planar mapping)

1.背景:

在一般的贴图方法中,模型顶点uv值传入顶点着色器,进行插值后传入片段着色器,在片段着色器内使用tex2D(texture,uv)对2D材质进行采样即可。在World Space UV-mapping中,不使用uv值,而是使用当前像素的世界坐标的两个分量来进行贴图,例如tex2D(texture,worldPos_xy)。
由于tex2D会自动对第二个参数进行0-1取值范围的限制,因此一般面积大于1的2D平面会出现一种repeat的效果,可以将uv值除以一个变量进行缩放。

2.shader方法:

复制代码
Shader "Nie/03 TextureScale"
{
    Properties
    {
        _DiffuseMap ("Texture ", 2D)  = "white" {} 
        _TextureScale ("Texture Scale",float) = 1
        _TriplanarBlendSharpness ("Blend Sharpness",float) = 1
    }
    SubShader
    {
        //定义Tags
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog
            
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal:NORMAL;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
                float3 normal:NORMAL;
                float4 wVertex : FLOAT;
            };

            float _TextureScale;
            sampler2D _DiffuseMap;
            float4 _DiffuseMap_ST;
            float _TriplanarBlendSharpness;
            
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _DiffuseMap);
                UNITY_TRANSFER_FOG(o,o.vertex);
                o.normal=mul(unity_ObjectToWorld,v.normal);
                o.wVertex=mul(unity_ObjectToWorld,v.vertex);
                return o;
            }
            
            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                float3 bWeight=(pow(abs(normalize(i.normal)),_TriplanarBlendSharpness));
                //example: sharpness=2:  0,0.25,1--->0,0.0625,1
                bWeight=bWeight/(bWeight.x+bWeight.y+bWeight.z);
                float4 xaxis_tex=tex2D(_DiffuseMap,i.wVertex.zy/_TextureScale);
                float4 yaxis_tex=tex2D(_DiffuseMap,i.wVertex.xz/_TextureScale);
                float4 zaxis_tex=tex2D(_DiffuseMap,i.wVertex.xy/_TextureScale);
                fixed4 tex=xaxis_tex*bWeight.x+yaxis_tex*bWeight.y+zaxis_tex*bWeight.z;
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, tex);
                return tex;
            }
            ENDCG
        }
    }
}
复制代码

 

3.参考文档:

https://blog.csdn.net/liu_if_else/article/details/73833656

原文链接:https://blog.csdn.net/qq_40629631/article/details/105316518

posted @   木木木林森  阅读(1662)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示