36.镜面效果实现

36.高级纹理-渲染纹理-镜面效果-效果实现


36.1 知识点

实现镜面效果 Shader

主要步骤

  1. 新建一个名为 Lesson36_Mirror 的 Shader。
  2. 复制之前 Shader 开发入门中的 Lesson25_Single_Texture_Color_Sampler Shader(Lesson25_纹理_单张纹理_纹理颜色采样)。
  3. 在顶点着色器中,反转 UV 坐标的 X 轴。由于 UV 坐标范围是 0 到 1,我们可以直接使用 1 - uv.x 来实现反转。
  4. 将渲染纹理应用到该 Shader 的纹理中。

新建Shader Lesson36_Mirror,复制Shader开发入门中的 Lesson25_纹理_单张纹理_纹理颜色采样中的Shader Lesson25_Single_Texture_Color_Sampler

Shader "Unlit/Lesson36_Mirror"
{
    Properties
    {
        //主纹理
        _MainTex("MainTex", 2D) = ""{}
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            //映射对应纹理属性的图片颜色相关数据
            sampler2D _MainTex;
            //映射对应纹理属性的 缩放 平(偏)移数据
            float4 _MainTex_ST; //xy代表缩放 zw代表平移

            v2f_img vert(appdata_base appdata_base)
            {
                v2f_img v2f_img;
                v2f_img.pos = UnityObjectToClipPos(appdata_base.vertex);

                
                //appdata_base.texcoord.xy //代表uv坐标
                //appdata_base.texcoord.zw //代表一些额外信息 例如深度值
                
                //先缩放 后平移 这个是一个固定的算法 规则如此
                //如果没有进行缩放和平移 那么 这个计算后 值是不会产生变化的
                //因为缩放默认值是1和1 ,平移默认值是0和0
                
                v2f_img.uv = appdata_base.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;

                
                //另一种写法 使用纹理的宏
                // Transforms 2D UV by scale/bias property
                //#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)
                
                //TRANSFORM_TEX(appdata_base.texcoord.xy, _MainTex);
                
                return v2f_img;
            }

            fixed4 frag(v2f_img v2f_img) : SV_Target
            {
                //这传入的uv 是经过插值运算后的 就是每一个片元都有自己的一个uv坐标
                //这样才能精准的在贴图当中取出颜色
                fixed4 color = tex2D(_MainTex, v2f_img.uv);

                return color;
            }
            ENDCG
        }
    }
}

在顶点函数中,让UV坐标的X轴反向(坐标范围0~1,想要反向直接用 1 - uv.x 即可

v2f_img vert (appdata_base appdata_base)
{
    v2f_img v2f_img;
    v2f_img.pos = UnityObjectToClipPos(appdata_base.vertex);

    
    //appdata_base.texcoord.xy //代表uv坐标
    //appdata_base.texcoord.zw //代表一些额外信息 例如深度值
    
    //先缩放 后平移 这个是一个固定的算法 规则如此
    //如果没有进行缩放和平移 那么 这个计算后 值是不会产生变化的
    //因为缩放默认值是1和1 ,平移默认值是0和0
    
    v2f_img.uv = appdata_base.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;

    //另一种写法 使用纹理的宏
    // Transforms 2D UV by scale/bias property
    //#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)
    
    //TRANSFORM_TEX(appdata_base.texcoord.xy, _MainTex);
    
    //由于是镜面效果,所以需要让纹理在x轴方向进行反向
    //原本0的位置变为1 0.1的位置变为0.9 1的位置变为0
    v2f_img.uv.x = 1 - v2f_img.uv.x;
    
    return v2f_img;
}

创建材质赋值shader,将渲染纹理应用到该Shader的纹理中,材质赋值给镜子,可以看到镜面效果

  1. 在 Unity 中创建一个新材质。
  2. 将材质的 Shader 设置为 Unlit/Lesson36_Mirror
  3. 将材质赋值给一个镜子对象,观察镜面效果。


发现镜子没有阴影,可以添加漫反射的 Fallback

为了让镜面对象能够处理阴影,我们可以在 Shader 中添加 Fallback "Diffuse"。这会使用 Unity 默认的 Diffuse Shader 作为后备,从而确保镜面对象能够正确接收阴影。

Fallback "Diffuse"

通过添加 Fallback "Diffuse",即使该镜面 Shader 不支持阴影处理,Unity 也会回退到标准的 Diffuse Shader 来处理阴影计算。


36.2 知识点代码

Lesson36_高级纹理_渲染纹理_镜面效果_效果实现.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson36_高级纹理_渲染纹理_镜面效果_效果实现 : MonoBehaviour
{
    void Start()
    {
        #region 知识点  

        //1.新建Shader Lesson36_Mirror,
        //复制Shader开发入门中的 Lesson25_纹理_单张纹理_纹理颜色采样中的Shader Lesson25_Single_Texture_Color_Sampler
        //2.在顶点着色器中,让UV坐标的X轴反向(坐标范围0~1,想要反向直接用 1 - uv.x 即可
        //3.将渲染纹理应用到该Shader的纹理中

        #endregion
    }
}

Lesson36_Mirror.shader

Shader "Unlit/Lesson36_Mirror"
{
    Properties
    {
        //主纹理
        _MainTex("MainTex", 2D) = "white"{}
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            //映射对应纹理属性的图片颜色相关数据
            sampler2D _MainTex;
            //映射对应纹理属性的 缩放 平(偏)移数据
            float4 _MainTex_ST; //xy代表缩放 zw代表平移

            v2f_img vert (appdata_base appdata_base)
            {
               v2f_img v2f_img;
               v2f_img.pos = UnityObjectToClipPos(appdata_base.vertex);

                
                //appdata_base.texcoord.xy //代表uv坐标
                //appdata_base.texcoord.zw //代表一些额外信息 例如深度值
                
                //先缩放 后平移 这个是一个固定的算法 规则如此
                //如果没有进行缩放和平移 那么 这个计算后 值是不会产生变化的
                //因为缩放默认值是1和1 ,平移默认值是0和0
                
               v2f_img.uv = appdata_base.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;

                //另一种写法 使用纹理的宏
                // Transforms 2D UV by scale/bias property
                //#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)
                
                //TRANSFORM_TEX(appdata_base.texcoord.xy, _MainTex);
                
               //由于是镜面效果,所以需要让纹理在x轴方向进行反向
               //原本0的位置变为1 0.1的位置变为0.9 1的位置变为0
               v2f_img.uv.x = 1 - v2f_img.uv.x;
                
               return v2f_img;
            }

            fixed4 frag (v2f_img v2f_img) : SV_Target
            {
                //这传入的uv 是经过插值运算后的 就是每一个片元都有自己的一个uv坐标
                //这样才能精准的在贴图当中取出颜色
                fixed4 color = tex2D(_MainTex, v2f_img.uv);

                return color;
            }
            ENDCG
        }
    }
    Fallback "Diffuse"
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏