Shader攻占笔记(三)混合纹理的使用

混合纹理的使用

水墨感动态纹样

其实不算混合纹理,混合颜色可能恰当一点。若要改成纹理,将Color的部分更换成图片就可以了。其实没有完全解决接缝问题,待修改。
不用噪声的版本我也挺喜欢的,但是实用性不是很大。

在这里插入图片描述

Shader "Custom/sd_MixedColor"
{
    Properties
    {
        _MainTex("Main Color", 2D) = ""{}
        _NoiseMap("Noise Map", 2D) = ""{}
        _NoisePower("Power of Noise", Range(0, 10)) = 2
        _ColorR("R Channel Color", Color) = (1,1,1,1)
        _ColorG("G Channel Color", Color) = (1,1,1,1)
        _ColorB("B Channel Color", Color) = (1,1,1,1)
        _ColorA("A Channel Color", Color) = (1,1,1,1)
        _PlaySpeed("Play Speed", Range(0.1, 1)) = 0.5
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows
        #pragma target 3.0

        sampler2D _MainTex, _NoiseMap;
        struct Input
        {
            float2 uv_MainTex, uv_NoiseMap;
        };
        fixed4 _ColorR;
        fixed4 _ColorG;
        fixed4 _ColorB;
        fixed4 _ColorA;
        fixed _NoisePower;
        fixed _PlaySpeed;
        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed scrollNoiseVal = _NoisePower * _Time;
            //float4 noiseMap = tex2D(_NoiseMap,IN.uv_NoiseMap + scrollNoiseVal);
            float4 noiseMap = tex2D(_NoiseMap,IN.uv_NoiseMap);

            float2 center = (0.5, 0.5);
            float2 dt = IN.uv_MainTex - center;
            float n_dt = normalize(dt)* _PlaySpeed;

            float4 blendData = tex2D(_MainTex,IN.uv_MainTex + n_dt * _SinTime + noiseMap * _NoisePower);

            float4 finalColor;
            finalColor = lerp(_ColorR, _ColorG, blendData.g);
            finalColor = lerp(finalColor, _ColorB, blendData.b);
            finalColor = lerp(finalColor, _ColorA, blendData.a);
            finalColor.a = 1;
            finalColor = saturate(finalColor);

            o.Albedo = finalColor.rgb;
            o.Alpha = finalColor.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

没有噪声扰动的效果,还挺丝滑的:
在这里插入图片描述

海滩

在这里插入图片描述
深色海水部分其实是有纹理的 gif质量太差看不清
在这里插入图片描述

在这里插入图片描述

Shader "Custom/sd_MixedColor"
{
    Properties
    {
        _MainTex("Blend Data", 2D) = ""{}                       //主blend纹理信息图
        _NoiseMap("Noise Map", 2D) = ""{}                       //水波噪声图
        _NoisePower("Power of Noise", Range(0, 0.3)) = 0.2      //噪声强度
        _ColorR("R Channel Color", Color) = (1,1,1,1)           //R空间颜色
        _ColorG("G Channel Color", Color) = (1,1,1,1)           //G空间颜色
        _ColorB("B Channel Color", Color) = (1,1,1,1)           //B空间颜色
        _TexB("B Channel Tex", 2D) = ""{}                       //B空间贴图
        _BTexA("Alpha of BTex", Range(0, 1)) = 0.5              //B空间贴图的Alpha值
        _ColorA("A Channel Color", Color) = (1,1,1,1)           //Alpha空间的颜色
        _Alpha("Alpha of Water", Range(0, 1)) = 0.5             //整体水域Alpha值
    }
    SubShader
    {
        Tags { "RenderType"= "Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard
        #pragma target 3.0

        sampler2D _MainTex, _NoiseMap;
        sampler2D _TexB;
        struct Input
        {
            float2 uv_MainTex, uv_NoiseMap;
            float2 uv_TexB;
        };
        fixed4 _ColorR;
        fixed4 _ColorG;
        fixed4 _ColorB;
        fixed _BTexA;
        fixed4 _ColorA;
        fixed _NoisePower;
        fixed _Alpha;
        UNITY_INSTANCING_BUFFER_START(Props)
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            //贴图处理-------------------------
            fixed scrollNoiseVal = _NoisePower * _Time;//噪声因子
            float4 noiseMap = tex2D(_NoiseMap,IN.uv_NoiseMap + scrollNoiseVal);//使噪声map流动
            float4 picB = lerp(_ColorB, tex2D(_TexB, IN.uv_TexB + noiseMap) * _ColorB, _BTexA);//控制B空间贴图的Alpha值
            float4 blendData = tex2D(_MainTex,IN.uv_MainTex + noiseMap * _NoisePower + _SinTime.w * 0.1);//利用噪声扰动BlendUV

            //颜色处理--------------------------
            float4 finalColor;
            finalColor = lerp(_ColorG, _ColorR, blendData.r);//为R空间赋值(G和B有混合)
            finalColor = lerp(finalColor, _ColorG, blendData.g);//为R空间赋值
            finalColor = lerp(finalColor, picB, blendData.b);//为B空间赋值
            
            //Alpha设置------------------------
            finalColor = lerp(finalColor, _ColorA, (1-_Alpha));//设置水域整体的Alpha(有水or无水)
            finalColor = lerp(finalColor, _ColorA, (1 - blendData.a));//设置非水域部分的颜色
            finalColor = saturate(finalColor);//标准化
            
            //赋值------------------------------
            o.Albedo = finalColor.rgb;
            o.Alpha = finalColor.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

### 如何实现混合纹理Shader效果 #### 使用OpenGL或Unity Shader中的混合纹理技术 在计算机图形学中,混合纹理是一种通过组合多个纹理来创建更复杂表面外观的技术。这可以通过多种方式完成,在着色器内部操作可以提供高效且灵活的方法。 对于**OpenGL**环境下的混合纹理实现: ```glsl // Vertex Shader (GLSL) #version 330 core layout(location = 0) in vec3 aPos; layout(location = 1) in vec2 aTexCoord; out vec2 TexCoord; void main() { gl_Position = vec4(aPos, 1.0); TexCoord = aTexCoord; } ``` ```glsl // Fragment Shader (GLSL) #version 330 core in vec2 TexCoord; uniform sampler2D texture1; uniform sampler2D texture2; uniform float mixValue; // 控制两种纹理之间过渡程度的参数 out vec4 FragColor; void main() { vec4 color1 = texture(texture1, TexCoord); vec4 color2 = texture(texture2, TexCoord); // 混合两个颜色 FragColor = mix(color1, color2, mixValue); } ``` 上述片段展示了如何利用`mix()`函数按照指定的比例融合两张图片的颜色值[^1]。 而在**Unity ShaderLab**环境下,则采用如下形式定义混合纹理的效果: ```csharp Shader "Custom/MixedTexture" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _SecondTex ("Overlay Texture", 2D) = "black" {} _MixAmount ("Mix Amount", Range(0,1)) = 0.5 } SubShader { Tags { "RenderType"="Opaque" } CGPROGRAM #pragma surface surf Lambert struct Input { float2 uv_MainTex; float2 uv_SecondTex; }; sampler2D _MainTex; sampler2D _SecondTex; half _MixAmount; void surf(Input IN, inout SurfaceOutput o) { fixed4 col1 = tex2D(_MainTex, IN.uv_MainTex); fixed4 col2 = tex2D(_SecondTex, IN.uv_SecondTex); // Mix the two textures based on user-defined amount. o.Albedo = lerp(col1.rgb, col2.rgb, _MixAmount); } ENDCG } FallBack "Diffuse" } ``` 这段代码说明了怎样声明属性并编写顶点和片元程序逻辑以达到相同目的——即根据给定权重线性插值两幅图像之间的像素值[^2]。 值得注意的是,除了简单的线性混合外,还可以探索更多高级技巧如基于遮罩的地图、多层材质叠加以及物理基渲染(PBR),这些都能进一步增强视觉表现力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值