Unity 实现贴花/投影效果

news/2024/10/30 15:24:40/

【核心思路】

实现投影效果有以下几种思路:

一是对处理渲染到相机的最终画面,将想投影的贴图修改上去。

二是对被投影的物体的Shader加上关键字,开启关键字的时候用想投影的贴图。

三是在一个物体上渲染想投影的贴图,让这个物体最后绘制,且只绘制那些被遮挡的部分,

本文采用第三种实现方式。

【实现效果】

 【Build-In Shader】

Shader "Unlit/DecalShader"
{Properties{[HDR] _Color ("Tint", Color) = (0, 0, 0, 1)_MainTex ("Texture", 2D) = "white" {}}SubShader{Tags{ "RenderType"="Transparent" "Queue"="Transparent-400" "DisableBatching"="True"}//选择透明渲染,要在所有透明物体渲染完成之后再渲染Blend SrcAlpha OneMinusSrcAlphaZWrite off //关闭深度写入,投影不需要Pass{CGPROGRAM#include "UnityCG.cginc"//定义顶点和片元着色器函数#pragma vertex vert#pragma fragment fragsampler2D _MainTex;float4 _MainTex_ST;fixed4 _Color;//相加深度图,要用C#代码开启相机深度图Camera.main.depthTextureMode = DepthTextureMode.Depthsampler2D_float _CameraDepthTexture;struct appdata{float4 vertex : POSITION;};struct v2f{float4 position : SV_POSITION;float4 screenPos : TEXCOORD0;float3 ray : TEXCOORD1;};v2f vert(appdata v){v2f o;float3 worldPos = mul(unity_ObjectToWorld, v.vertex);o.position = UnityWorldToClipPos(worldPos);o.ray = worldPos - _WorldSpaceCameraPos;//这个点的世界坐标减去相机的世界坐标,得到从相机到这个点的方向向量o.screenPos = ComputeScreenPos (o.position);//计算这个点A在屏幕空间的位置return o;}float3 getProjectedObjectPos(float2 screenPos, float3 worldRay){//根据屏幕目标采样相机深度纹理得到一个深度,注意这个深度是其他物体的,我们叫点B的深度,我们只是用了点A在屏幕坐标float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screenPos);depth = Linear01Depth (depth) * _ProjectionParams.z;worldRay = normalize(worldRay);worldRay /= dot(worldRay, -UNITY_MATRIX_V[2].xyz);//这一步不可少,如果仅用worldRay * depth,计算出来的深度是相机到点的直线距离,而在Unity中,有near plane和far plane,plane上的任意一点到相机的深度都是一样的,这里用相机朝向和相机到这个点的方向得到这个点的实际单位长度//with that reconstruct world and object space positionsfloat3 worldPos = _WorldSpaceCameraPos + worldRay * depth; //计算得到了B点的世界坐标float3 objectPos =  mul (unity_WorldToObject, float4(worldPos,1)).xyz; //将点B变换到A所在物体的坐标系中clip(0.5 - abs(objectPos));//Cube的世界坐标归一化后,有效值是从-0.5到0.5,其他的需要舍弃objectPos += 0.5;//采样纹理时的坐标范围为0~1,要加0.5return objectPos;}fixed4 frag(v2f i) : SV_TARGET{float2 screenUv = i.screenPos.xy / i.screenPos.w;float2 uv = getProjectedObjectPos(screenUv, i.ray).xz;//计算出来的uv不是0就是1,直接当作uv坐标来用fixed4 col = tex2D(_MainTex, uv);col *= _Color;return col;}ENDCG}}
}

【参考】

 Unlit Dynamic Decals/Projection | Ronja's tutorials


http://www.ppmy.cn/news/122259.html

相关文章

投影仪原理概述

光线折射与反射 我们高中都学过透镜的折射作用,即光穿过不同介质时,在交界面处发生折射和反射,不过反射很简单就不讲了,我们主要讨论折射: 一束光从光疏介质(空气)到光密介质(水&a…

计算机投影仪的作用是什么,投影电脑

投影电脑,是一种小型、方便携带的智能投影设备,通过触控笔操控投影屏作为基本的输入设备。投影电脑将图像投射到显示区域后,当触控笔指向图像时,主机感应到触控信号,从而使用户通过触控笔互动操作而不是传统的键盘或鼠…

android手机屏幕投影,安卓手机屏幕投影到电脑(笔记本)教程分享

指明笔记本是因为多数笔记本屏幕支持投影功能,台机的话因为屏幕和主机多数分离,并且屏幕不具有投影功能。不在此教程范围。当然,台机想投影也不是不可能,方法有很多,也可以考虑去买一块可直接投影的屏幕或者投影接收器…

圆柱体的投影特点_环形屏幕投影技术的特点和优势

近年来,随着投影技术的不断创新和发展,它逐渐成熟和完善。它突破了传统的单一投影仪和窗帘的投影方式,可以达到越来越多的科幻投影显示效果,给人们的生活增添更多的色彩。全息投影、交互式投影、立体投影、投影融合等新的投影技术…

全息投影必须要有全息介质吗?

既然是投影,自然是需要一块幕布的,因为投影最起码的光学基础就是漫反射。目前的全息投影会用水幕、烟雾、半透磨、特殊玻璃、塑料,甚至是旋转的叶片等作为幕布。这些材料,都有一个特点,那就是在弱光下可以达到接近透明…

投影仪幕布增益_别再说幕布是花瓶 投影幕布的作用原来这么大

在投影机的使用中,大多数人都不会关注投影幕布在整个使用过程中发挥的作用。很多朋友都觉得投影幕布是个可有可无的产品,有的话自然更好,没有的话也无伤大雅。但事实真是如此吗?今天我们一起来探讨一下。 投影幕布是个可有可无的产…

投影幕布尺寸计算器_投影距离计算器

什么是安装距离? 所谓安装距离是指投影机在安装之前,投影机的安装位置到投影屏幕(幕布)之间的距离,这个距离基本确定了你能获得多大尺寸的投影画面。 投影距离计算器 最小安装距离(米)=最小焦距(米)*画面投影尺寸(英寸)液晶片尺寸(英寸) 最大安装距离(米)=最大焦距(米)*画面…

可视性穿孔_“大开眼界,意大利的艺术精工” SCREENLINE顶级穿孔透声投影幕

要在家里玩家庭影院,要考虑的地方十分多,例如视频部分应该用电视机还是投影幕?虽然电视机的尺寸已经越来越大,基本上可以满足客厅影院的需求,但是如果想要震撼的大屏效果,那一定要选投影组合了,…