• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

untiy 实现贴花效果

武飞扬头像
吴梓穆
帮助1

注意,必须为你的摄像机开启提取深度纹理,如果挂载shader后没有效果,为你的摄像机挂载这个脚本,并在脚本上右键reset一下

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

public class CameraDepth : MonoBehaviour
{
    
    private void Reset()
    {
        GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
      //  GetComponent<Camera>().depthTextureMode |= DepthTextureMode.DepthNormals;
    }
}

接下来是主角shader

Shader "Custom/Decal"
{
    Properties
    {
        _Color("Color", Color) = (1,1,1,1)//贴图颜色校正
        _MainTex("Albedo (RGB)", 2D) = "white" {} //贴图的颜色
        _ShadowAmount("ShadowAmount",Range(0,1)) = 0 //阴影的浓度
    }
    SubShader
    {
        Tags{"RenderType" = "Transparent" "Queue" = "Geometry 1" "DisableBatching" = "True" } //queue必须稍晚一些
        Pass
        {
            Tags{"LightMode" = "ForwardBase"}
           // Blend SrcAlpha OneMinusSrcAlpha
            ZWrite off
            ZTest off
            Cull Front //剔除前部,防止摄像机进入cube后,贴花不显示
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdbase
            #include "UnityCG.cginc"
            #include "AutoLight.cginc"
            #include "Lighting.cginc"

            struct v2f
            {
                float4 pos : SV_POSITION;
                float4 screenPos:TEXCOORD0;
                SHADOW_COORDS(1)

              };
              float4 _Color;
              sampler2D _MainTex;
              float4 _MainTex_ST;
              sampler2D _CameraDepthTexture;  //深度纹理
              fixed _ShadowAmount;//阴影的强度

              //从深度图反推世界坐标  参数屏幕坐标
              float3 DepthToWorldPosition(float4 screenPos)
              {
                  float depth = Linear01Depth(UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture,screenPos))); 
                  float4 ndcPos = (screenPos / screenPos.w) * 2 - 1;  //要除以一个w是因为从屏幕上获取的坐标(_ProjectionParams)是没有除过w的,需要先除一下来获取NDC
                  float3 clipPos = float3(ndcPos.x, ndcPos.y, 1) * _ProjectionParams.z;
                  float3 viewPos = mul(unity_CameraInvProjection,clipPos.xyzz).xyz * depth;
                  float3 worldPos = mul(UNITY_MATRIX_I_V, float4(viewPos, 1)).xyz;
                  return worldPos;
              }

              v2f vert(appdata_base v)
              {
                  v2f o;
                  o.pos = UnityObjectToClipPos(v.vertex);
                  //屏幕坐标
                  o.screenPos = ComputeScreenPos(o.pos);
                  TRANSFER_SHADOW(o);
                  return o;
              }
              fixed4 frag(v2f i) :SV_Target
              {
                  float3 pos = DepthToWorldPosition(i.screenPos); //世界坐标
                  float3 localPos = mul(unity_WorldToObject, float4(pos,1)).xyz;//局部坐标  注意这里是把别人的世界坐标转为自己的局部坐标
                  clip(0.5 -abs(localPos));//剔除除了底面外的其他面,abs是取绝对值,对一个float3取得值结果在0-1
                  //float a=0.5-abs(localPos);

                  float2 decalUV = localPos.xz 0.5;
                  fixed3 finalColor = tex2D(_MainTex, decalUV);

                  //计算阴影
                  UNITY_LIGHT_ATTENUATION(atten, i, pos);
                  finalColor.xyz  *= lerp(_ShadowAmount,1,atten );

                  //return float4(a,a,a,1) ;
                  //return float4(localPos,1) ;
                  return float4(finalColor,1) ;
              }

                ENDCG
            }
    }
}

学新通

创建一个材质,将材质的shader设置为这个,然后在场景里创建一个cube,将材质设置为贴花材质,即可,效果如下
学新通
shader参照大佬的视频

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfkijab
系列文章
更多 icon
同类精品
更多 icon
继续加载