Shader学习之案例—《镜子1》

废话不多说先上效果图,我使用的是在unity5.3.3版本。
 


一、原理

1、首先要准备的素材是三个,对没错,就是三个因为镜子里面的那个物体其实是实物的复制体而已;一个Plane作为镜子,还有一个实物和虚物体。

2、新建一个材质使用下面的Shader代码,并将此材质球赋给那个虚物体

[C#]  纯文本查看  复制代码
Shader "Custom/Cg shader for virtual objects in mirrors" {
        Properties{
                _Color("Virtual Object's Color", Color) = (1, 1, 1, 1)
        }
                SubShader{
                Tags{ "Queue" = "Transparent+20" }

                Pass{
                Blend OneMinusDstAlpha DstAlpha

                CGPROGRAM

#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"

                uniform float4 _Color;
        uniform float4x4 _WorldToMirror;

        struct vertexInput {
                float4 vertex : POSITION;
        };
        struct vertexOutput {
                float4 pos : SV_POSITION;
                float4 posInMirror : TEXCOORD0;
        };

        vertexOutput vert(vertexInput input)
        {
                vertexOutput output;

                output.posInMirror = mul(_WorldToMirror,
                        mul(_Object2World, input.vertex));
                output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
                return output;
        }

        float4 frag(vertexOutput input) : COLOR
        {
                //如果镜子里的物体出来了就剔除掉
                if (input.posInMirror.y > 0.0)
                {
                        discard;
                }
        return float4(_Color.rgb, 0.0);
        }

                ENDCG
        }
        }
}


3、另外在建一个材质使用下面的Shader代码,并将此材质球赋值给实物体

[C#]  纯文本查看  复制代码
Shader "Unlit/Cg shader for Real objects"
{
        Properties{
                _Color("Virtual Object's Color", Color) = (1, 1, 1, 1)
        }
   SubShader {
      Pass {
         CGPROGRAM

         #pragma vertex vert
         #pragma fragment frag
                uniform float4 _Color;
         float4 vert(float4 vertexPos : POSITION) : SV_POSITION
         {
            return mul(UNITY_MATRIX_MVP, vertexPos);
         }

         float4 frag(void) : COLOR
         {
            return float4(_Color.rgb, 1.0);
         }

         ENDCG
      }
   }
}


4、最后新建一个C#脚本,代码如下,将此代码赋给虚物体,并将Plane和虚物体拖动赋值给里面的对应两个变量

本帖隐藏的内容
[C#]  纯文本查看  复制代码
using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
public class PlacingTheVirtualObj : MonoBehaviour {

    public GameObject objectInFrontOfMirror;
    public GameObject mirrorPlane;

    // Use this for initialization
    void Start () {
       
        }

    // Update is called once per frame
    void Update() {
        if (null != mirrorPlane)
        {
            //这句话决定了镜子里的物体是否可见
            GetComponent<Renderer>().sharedMaterial.SetMatrix("_WorldToMirror",mirrorPlane.GetComponent<Renderer>().worldToLocalMatrix);
            if (null != objectInFrontOfMirror)
            {
                //将实物的颜色值赋给镜中的物体
                Color realColor = objectInFrontOfMirror.GetComponent<Renderer>().material.GetColor("_Color");
                GetComponent<Renderer>().material.SetColor("_Color", realColor);

                transform.position = objectInFrontOfMirror.transform.position;
                transform.rotation = objectInFrontOfMirror.transform.rotation;
                transform.localScale =
                   -objectInFrontOfMirror.transform.localScale;
                //new Vector3(0.0f, 1.0f, 0.0f)为表面的法线方向
                transform.RotateAround(objectInFrontOfMirror.transform.position,mirrorPlane.transform.TransformDirection( new Vector3(0.0f, 1.0f, 0.0f)), 180.0f);
              Vector3  positionInMirrorSpace  =
                   mirrorPlane.transform.InverseTransformPoint(objectInFrontOfMirror.transform.position);
                positionInMirrorSpace.y = -positionInMirrorSpace.y;
                transform.position = mirrorPlane.transform.TransformPoint(
                   positionInMirrorSpace);
            }
        }
    }
}




二、此方案的优劣

1、优点:性能开销比较小,镜子里的虚物体清晰

2、缺点:目前虚物体只能实时的同步实物体的颜色,贴图和其他纹理或者模型面数复杂的情况都没有响应的处理、并不是完全的实时反射物体,因为要实现创建好虚物体。

3、有待发现.....

三、后续待....

当然,我可以为您提供一个简单的Shader Graph描边案例。以下是一个使用Unity的Shader Graph实现描边效果的示例步骤: 1. 在Unity中创建一个新的Shader Graph材质。 2. 将材质应用于您想要进行描边的对象上。 3. 在Shader Graph编辑器中,创建一个新的Sub Graph(子图),并将其命名为"Outline"(或其他您喜欢的名称)。 4. 在Sub Graph中添加一个"Sample Texture 2D"节点,并将其命名为"Main Texture"。将该节点连接到输出节点。 5. 添加一个"Color"节点,并连接到"Main Texture"节点的采样输出。 6. 添加一个"Gradient Noise"节点,并将其命名为"Noise". 这将用于创建描边效果的噪声纹理。 7. 创建两个新的属性节点,一个用于控制描边颜色,另一个用于控制描边宽度。将这两个属性连接到"Outline" Sub Graph中的适当节点。 8. 使用"Step"节点和"Noise"节点结合创建描边效果。将"Noise"节点的输出连接到"Step"节点的输入,并将描边宽度属性连接到"Step"节点的阈值输入。然后将"Step"节点的输出连接到一个"Multiply"节点。 9. 将"Multiply"节点的输出连接到"Color"节点的输入。这样,您就可以通过调整描边宽度属性来控制描边的强度。 10. 将"Color"节点的输出连接到输出节点,然后将"Outline" Sub Graph的输出节点连接到Sub Graph的主输出节点。 11. 返回到主Shader Graph编辑器中,将"Outline" Sub Graph的输出节点连接到主输出节点。 12. 在主Shader Graph中添加一个"Color"节点,用于控制对象的基础颜色。 13. 将主Shader Graph的基础颜色连接到"Outline" Sub Graph的输入节点。 14. 调整描边颜色和描边宽度属性,来达到您想要的描边效果。 15. 应用该材质,并查看对象的描边效果。 这只是一个简单的示例,您可以根据自己的需求对描边效果进行进一步定制。希望对您有所帮助!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值