DoTween 首先导入插件,
其次 使用DoTween的脚本需要引用 命名空间,
创建执行放大效果的函数,
public void WinDoScale(){
Transform win = GameObjectFind("你想改变的物体")transform;
//设置更改窗口的大小
Vector3 max = new Vector3(1, 1, 1);
//设置变化时间
float time = 2f;
winDOScale(max, time);
}
unity里面控制是ScreenSetResolution(int width,int height,bool fullscreen);要用系统的窗口控制的话,就要用windowsApi了。
Unity发布的WebGL页面应用实现全屏/非全屏切换
如果是win浏览器平台,可以通过修改indexhtml里面,unity div的长宽比例实现页面内的全屏。
但是如果是在手机浏览器平台,全屏的功能不能这样 *** 作,会引起手机浏览器的崩溃。
只能通过传统的切换全屏方法
ScreenfullScreen = !ScreenFullScreen;
我一开始也是用button的点击事件去触发全屏,但是button点击的事件,要再点一下屏幕才会起作用。
正确的方法是用Event Trigger点击后直接进入全屏,不用再点一下屏幕
需要从shader 中获取深度值,主要涉及到渲染流水线中的以下几个节点
1观察空间:观察空间是以摄像机所在位置为原点的空间。我们尝试获取的深度信息就是在这个空间之下。
2裁剪空间(投影空间、齐次裁剪空间):将顶点转换到此空间下来判断是否在视椎体内,从而裁剪掉不在摄像机视野内的顶点;将顶点变换到此空间下可以方便做后续的投影工作。
3屏幕空间:将没有被裁剪的顶点从裁剪空间转换到此空间,从而最终呈现在屏幕上。
主要涉及到的术语
1裁剪矩阵(投影矩阵):
用于将顶点从观察空间转换到裁剪空间的矩阵。
经过裁剪矩阵的 *** 作后,顶点的x、y、z分量则被转换到裁剪空间中。
裁剪空间下的顶点满足以下条件的,即为在视野内的顶点:
-w<=x<=w;
-w<=y<=w;
-w<=z<=w;
以上裁剪原理与深度获取关系不大,只需要注意:
经过裁剪矩阵的 *** 作后,顶点的w 分量保存了顶点在观察空间下的深度信息(观察空间的顶点的z 分量)。
2齐次除法(透视除法):
经过裁剪矩阵的 *** 作之后,将裁剪空间下的顶点的x、y、z 分量分别除以w 分量的过程。此过程完成后,裁剪空间下的顶点将会转换到NDC 中,即变换到一个各分量从-1到1长度为2的立方体内部。如果使用的是透视摄像机,因为z 分量保留了深度信息,经过透视除法以后,越远离摄像机的顶点其xy分量数值将越小(因为w 分量是观察空间中顶点的z 分量,对于两个顶点,如果他们x、y 分量相同,而w 分量不同即深度不同,越远的顶点经过透视除法后,其数值也就越小)。齐次除法完成后,顶点的x、y 分量再经过简单的缩放映射即可投射到屏幕空间二维坐标中,而z 分量通过d = 05z + 05 转变为0-1 范围并作为最终会存贮于深度图中的数据。
3屏幕空间:
渲染管线中最后一个流程将裁剪空间中的顶点通过透视除法和屏幕映射映射最终从3D 的裁剪空间转换到2D 的空间中,这个2D 空间就是屏幕空间。屏幕空间是左下角为(0,0),右上角为(screenwidth, screenheight)的二维空间。
Shader 中获取深度(unity 2019419 urp)
Shader 中将顶点从裁剪空间转换到屏幕空间(即齐次除法和屏幕映射)由底层完成,而获取深度的原理就是再现这一 *** 作中某些步骤的过程。
通过顶点数据可以直接获得顶点的深度;通过顶点数据和屏幕映射公式可以逆推获得屏幕纹理坐标,使用屏幕纹理坐标可以采样深度图,然后将深度图中的数据逆推回模型空间就可以获得需要的场景深度。
1顶点着色器中需要完成将顶点从模型空间转换到裁剪空间下的任务。
2来到片元着色器中,经过Unity 渲染流程的处理,顶点输出的裁剪空间顶点(SV_POSITION 语义)坐标的xy 分量已经做了透视除法和屏幕映射处理转换到了屏幕空间当中,z 分量也做了透视除法并转换到(0,1)范围内,w 分量仍然是观察空间下的深度值。
获取顶点的深度值:
裁剪空间顶点坐标w 分量就是视角空间下的深度值,将其除以远裁面就是0-1 的深度值。
远裁剪面的距离可以通过内置的_ProjectionParamsz 变量来获取。
或者比较傻的办法:
1上面讲到片元着色器中,裁剪空间中的顶点(SV_POSITION 语义)坐标的z 分量已经做了透视除法并转换到了(0,1)范围中,此时只需要将其逆推回观察空间即可;
2利用公式:(n表示远裁剪面;f表示近裁剪面;d表示ndc中重映射后的深度值,即第2步骤计算出的数值)
zv = 1/((n-f/nf)d + 1/n) 计算出观察空间下的深度值,将其除以远裁剪面就是0-1范围的观察空间下的深度值,公式:
z01=1/((n-f)/nd + f/n)
以上公式实际上是将渲染管线处理后的顶点逆推回观察空间中,实际上是结合了投影矩阵z 分量上的处理公式、透视除法公式、屏幕映射公式三个步骤逆推出来的公式。
之所以说这个方法很傻,是因为绕了一个圈,因为顶点从裁剪空间转到屏幕空间下又逆推回了观察空间,之所以要介绍这种办法,是因为在遇到需要获取场景深度值的需求时,我们可以拿到的数据(即深度图)存储的正是步骤1 中顶点z 分量的值。
由于顶点在转换到裁剪空间时,其w 分量就是观察空间下的z 分量,如果只需要顶点的深度,还是建议直接使用裁剪空间顶点的w 分量作为深度值。
获取场景的深度值:
1上面提到在片元着色器中,顶点坐标的xy 分量已经从裁剪空间转换到了屏幕空间。
2直接将顶点坐标的xy 分量除以屏幕的长宽就可以得到0-1 范围的uv 坐标(屏幕纹理坐标),屏幕的长宽可以通过内置变量_ScreenParams 获取。
3对深度图进行采样: SAMPLE_TEXTURE2D_X(_CamearaDepthTexture, sampler_CameraDepthTexture, uv)
采样深度图需要在shader 中作如下声明:
TEXTURE2D_X_FLOAT(_CameraDepthTexture);
SAMPLER(sampler_CameraDepthTexture);
4 利用公式:(n表示远裁剪面;f表示近裁剪面;d表示深度图中的数据,即第四步结果的x分量)
zv = 1/((n-f/nf)d + 1/n) 计算出模型空间下的深度值,将其除以远裁剪面就是0-1范围的深度值,公式:
z01=1/((n-f)/nd + f/n)
也可以在顶点着色器中计算采样坐标 , 但是因为从顶点到片元着色器有一个插值过程,所以不能在顶点着色器中进行齐次除法,因此需要乘回w 分量,计算公式:(vc 为裁剪空间下的顶点坐标、vcw为该坐标的w分量)
vcw(vc/vcw05+05) => 05vc+05vcw
这也是内置函数ComputeScreenPos 的实现。
然后在片元着色器中进行齐次除法获得uv 坐标,然后从步骤3继续往下执行
如果在顶点着色器使用了ComputeScreenPos获得Vs;
那么对于步骤5 可以使用unity 内部提供的两个方法Linear01Depth、LinearEyeDepth 传入屏幕纹理坐标和_ZBufferParams 来获取观察空间的场景深度和0-1线性深度,函数内部的原理即为上述步骤5 。这也是shaderGraph 中SceneDepth 节点的做法。_ZBufferParams 是Unity 提供的内置变量,里面包含了远近裁剪平面相关的预计算。 同理,顶点的坐标也可以使用这种方式来获得,只不过顶点的深度我们可以直接通过齐次除法来取得。
源码
Shader "Custom/Depth"
{
Properties
{
}
SubShader
{
Tags { "RenderType"="Transparent" "Queue"="Geometry" "RenderPipeline" = "UniversalRenderPipeline"}
LOD 200
Pass
{
HLSLPROGRAM
#include "Packages/comunityrender-pipelinesuniversal/ShaderLibrary/Corehlsl"
#include "Packages/comunityrender-pipelinesuniversal/ShaderLibrary/Lightinghlsl"
#pragma vertex vert
#pragma fragment frag
struct a2v
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
//结合ComputeScreenPos 使用
//float4 screenUV : TEXCOORD5;
};
CBUFFER_START(UnityPerMaterial)
CBUFFER_END
TEXTURE2D_X_FLOAT(_CameraDepthTexture);
SAMPLER(sampler_CameraDepthTexture);
v2f vert(a2v i)
{
v2f o;
overtex = TransformObjectToHClip(ivertexxyz);
//需要在片元中做透视除法
//oscreenUV = ComputeScreenPos(overtex,_ProjectionParamsx);
return o;
}
half4 frag(v2f i) : SV_TARGET
{
//顶点深度
half dv = ivertexw;
//顶点01 深度
half dv01 = ivertexw / _ProjectionParamsz;
//直接获取屏幕纹理坐标
float2 screenUV = ivertexxy / _ScreenParamsxy;
//结合ComputeScreenPos 计算屏幕纹理坐标
//float2 screenUV = iscreenUVxy / iscreenUVw;
//深度图中存储的深度,需要逆推回到观察空间
float dd = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, screenUV)r;
//观察空间中的0-1场景深度
float ds01 = Linear01Depth(dd, _ZBufferParams);
//观察空间中的场景深度
float ds = LinearEyeDepth(dd, _ZBufferParams);
return ds01;
}
ENDHLSL
}
}
}
2、 *** 作方法:
1、应用商城导入插件
2、TimeLine左侧右键添加 Recorder Track,右侧右键添加 Add Recorder Clip
该clip的长度和位置,意味着你录哪段的屏。
3、Inspector面板对Clip进行设置:
Selected recorder:Movie
Format:MP4(该插件录的视频可能只支持在window上播放,放到IOS上等可能需要转码)
OutputResolution(输出分辨率):FHD-1080p
AspectRatio(长宽比):16:9
4、设置好输出位置,运行游戏,当TimeLine时间指针走完Recorder Clip的片段时,录屏也就输出到你指定的文件夹了。
二、普通录屏
注意,普通录屏必须切换到Windows平台,否则菜单栏不出现录制选项。
1、点击菜单栏Window > General > Recorder >RecorderWindows
2、点击Add New Recorders,现在你能看到跟上图所示,类似内容。进行设置。
注:
a、不同的是,这种方式的录屏,是在Recorder面板,点击StartRecording启动游戏进行录屏了,而不是TimeLine那样,点Play录屏。
b、RecorderMode中,也可设置:
SingleFrame:录几祯
FrameInterval:从第几帧到第几帧
TimeInterval:从第几秒到第几秒
三、该插件还能干的事情:
1、录制序列图(从第几帧到第几帧,输出这些)
2、录制GIF
3、录制动画片段
使用方法:
普通录屏:Add New Recorder
游戏视野(Game View)右上角有一个Stats按钮。这个按钮是按下状态时,会显示一个半透明窗口,它显示对于优化性能很有用的实时渲染统计数据。根据目标平台不同,精确的统计数据也不同。
-渲染统计窗口包含下面这些信息:-
每帧时间和FPS
绘制调用
批处理
三角形和顶点数
屏幕
Pass通道设置
可视蒙皮网格
动画
另外,性能分析窗口 rendering section of the profiler window 的渲染部分提供了这些统计数据更详细和完整的版本。
关于DrawCall和Batch的区别, 请参考: DrawCall和Batch的区别
以上就是关于unity UI 界面的窗口如何实现 点击按钮的时候 窗口界面由小到大的显示出来全部的内容,包括:unity UI 界面的窗口如何实现 点击按钮的时候 窗口界面由小到大的显示出来、如何用unity实现全屏/全屏窗口化/窗口化三种模式的切换、Unity发布的WebGL页面应用实现全屏/非全屏切换等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)