当前位置: 首页 > news >正文

搜狗提交网站收录入口关键词词库

搜狗提交网站收录入口,关键词词库,做pc网站,优化网站排名推荐公司大家好,我是阿赵。   这期开始,打算介绍一下地面交互的一些做法。 比如: Unity引擎制作沙地实时凹陷网格的脚印效果 或者: Unity引擎制作雪地效果 这些效果的实现,需要基于一些基础的知识。所以这一篇先介绍一下简单…

  大家好,我是阿赵。
  这期开始,打算介绍一下地面交互的一些做法。
比如:

Unity引擎制作沙地实时凹陷网格的脚印效果

或者:

Unity引擎制作雪地效果

  这些效果的实现,需要基于一些基础的知识。所以这一篇先介绍一下简单的局部UV采样,然后映射纹理到地面的做法。
  大概需要实现的效果是这个视频的前半部分:

Unity曲面细分制作雪地效果

一、轨迹的绘制

  看这段视频的前半部分。可以看到,球在移动的过程中,在地面产生了移动的轨迹
在这里插入图片描述

  这个效果可能很多朋友都会做,一般的做法是计算球的坐标相对于整个地面的位置,然后拾像素绘制在地面的遮罩贴图上面。
  不过这种做法会有一个问题,假如地面很大的时候,通过一张和整个地面匹配UV的遮罩贴图来绘制轨迹,那么这张遮罩贴图的分辨率需要多大,才能显示足够的精度呢?比如一个4096米4096米的地面,就算我们用一张40964096的贴图做遮罩,那么每平方米的面积,才占一个像素,明显是绘制不出这么清晰的轨迹图形的。
  其实我们没有必要去绘制整张贴图,只需要局部绘制就好了
在这里插入图片描述
在这里插入图片描述

  绘制这一个小局部,然后通过局部UV采样的方式,把这个贴图叠加到大贴图上面去。
  这时候,就需要给Shader传入一个范围,让Shader知道,这个局部UV,最终占整个地面UV的多少。
地面的Shader代码是这样的:

Shader "azhao/GroundFootStep"
{Properties{_MainTex("Texture", 2D) = "white" {}_Color("Color", Color) = (1,1,1,1)_centerPos("CenterPos", Vector) = (0,0,0,0)_footstepRect("footstepRect",Vector) = (0,0,0,0)_footstepTex("footstepTex",2D) = "gray"{}_footstepColor("footstepColor",Color) = (1,1,1,1)}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"sampler2D _MainTex;float4 _MainTex_ST;fixed4 _Color;uniform float3 _centerPos;float4 _footstepRect;sampler2D _footstepTex;float4 _footstepColor;struct appdata{float4 pos	: POSITION;float2 uv  : TEXCOORD0;};struct v2f{float4 pos : SV_POSITION;float3 worldPos	: TEXCOORD0;float2 uv  : TEXCOORD1;float2 footstepUV : TEXCOORD2;};float RemapUV(float min, float max, float val){return (val - min) / (max - min);}v2f vert(appdata i){v2f o;o.pos = UnityObjectToClipPos(i.pos);o.worldPos = mul(unity_ObjectToWorld,i.pos.xyz);o.uv = i.uv*_MainTex_ST.xy+ _MainTex_ST.zw;o.footstepUV = float2(RemapUV(_footstepRect.x, _footstepRect.z, o.worldPos.x), RemapUV(_footstepRect.y, _footstepRect.w, o.worldPos.z));return o;}fixed4 frag (v2f i) : SV_Target{// sample the texturefixed4 col = tex2D(_MainTex, i.uv)*_Color;fixed4 footstepCol = tex2D(_footstepTex, i.footstepUV);fixed3 footstepRGB = _footstepColor.rgb;fixed3 finalRGB = col.rgb*(1 - footstepCol.a) + footstepRGB * footstepCol.a;fixed4 finalCol = fixed4(saturate(finalRGB), 1);return finalCol;return col;}ENDCG}}
}

  从代码可以看出footstepRect是一个很关键的东西,它告诉了Shader,需要绘制轨迹的范围在哪里。然后通过RemapUV方法,拿这个范围和当前的顶点世界坐标去计算出,当前的点该占整体UV的实际位置。
  这个footstepRect其实是C#动态算出来的,根据角色所在的坐标和半径,算出来一个范围。
C#的代码大概是这样:

Vector3 pos = role.transform.position;
mat.SetVector("_centerPos", pos);
mat.SetFloat("_maxVal", radius);
mat.SetVector("_footstepRect", new Vector4(pos.x - radius, pos.z - radius, pos.x + radius, pos.z + radius));

  其实就是中心点加减半径而已。
  这个做法的优点是,只需要局部绘制一张贴图,就能达到比较清晰的轨迹图形
  缺点是,只能在一定范围内显示,超出了footstepRect范围,轨迹就会消失了。

二、绘制轨迹的手段

  绘制轨迹,其实就是连贯的把某个笔刷的像素复制到一张图片上。这个应该不是很难理解的概念。
  上面的例子,球是一个笔刷,它移动的时候,它所在的位置会产生一个圆形的笔刷,通过连续每帧的覆盖,就形成了一个轨迹。
在这里插入图片描述

  如果绘制的间隔拉大一点,看到的情况大概是这样的。
  那么问题来了,球移动的时候,上面说到,相对于地表贴图的footstepRect,是会变化的,所以说,我们不能直接把球的笔刷印到之前的那张图去。
比如上一张图的位置是在这里
在这里插入图片描述

  下一张图的位置就变成了这里
在这里插入图片描述

  留意看左下角的球,它在世界中的位置是一直没有变化的,但在这个footstepRect的局部里面,它的相对位置是变化了的。
  下面来说一下具体的做法。

1、通过摄像机绘制RenderTexture

在这里插入图片描述

  这里为了渲染一张顶视图,我是打了一个摄像机在运动的球的上方,然后摄像机跟随这球移动。
  需要注意的是,摄像机一定要是正交的,然后通过控制orthographicSize参数,可以准确的绘制符合footstepRect的范围。最后,给这个摄像机的targetTexture赋予一张RenderTexture,作为输出。

2、通过偏移来叠加上一张图

  刚才那个RenderTexture是每帧都会渲染一次的。我们需要2张RenderTexture,一张是上一次留下的,一张是这一帧渲染出来的。
  接下来就是把两张RenderTexture,通过Graphics.Blit方法合并在一起。由于Graphics.Blit方法是可以传入一个材质球的,所以可以通过写一个Shader来混合2张贴图。具体的方式是,计算上一帧和当前帧角色所在位置的偏移,然后用偏移来控制上一帧的贴图的UV采样,再把两张贴图合并在一起就可以了。

3、合并的Shader

Shader "azhao/DrawFootstep"
{Properties{_MainTex ("Texture", 2D) = "white" {}_lastTex("lastTex",2D) = "black"{}_offset("offset",Vector) = (0,0,0,0)}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;sampler2D _lastTex;float2 _offset;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);return o;}half4 frag (v2f i) : SV_Target{// sample the texturehalf4 col = saturate(tex2D(_MainTex, i.uv));half3 curRGB = col.rgb * 2 - 1;half4 lastCol = saturate(tex2D(_lastTex, i.uv - _offset));float lastAlpha = lastCol.a;half3 lastRGB = lastCol.rgb*2-1;half mr = lastRGB.r*lastAlpha;if (col.a >0){if (curRGB.r > 0){if (lastAlpha == 0){mr = curRGB.r;}}else if (curRGB.r < 0){mr = min(curRGB.r,mr);}}else{mr = lastRGB.r;}mr = (mr + 1) / 2;float alpha = max(col.a, lastAlpha);half3 mixRGB = half3(mr, mr, mr);half3 finalRGB = mixRGB;return half4(finalRGB, alpha);}ENDCG}}
}

三、细节问题

  第一步绘制轨迹通过局部UV坐标采样,和地表的贴图纹理混合。这里会存在一个问题。通过第二步绘制出来的轨迹贴图,是Clamp平铺方式的
在这里插入图片描述

  这意味着,超出了UV的0到1范围的坐标,会直接采样了0或者1的UV。具体的表现是这样的:
在这里插入图片描述

  这个黑线,其实就是到边缘了,所以超出的部分,都会是黑的
在这里插入图片描述

  为了解决这个问题,可以加一个渐变的遮罩叠加
在这里插入图片描述

  把UV接近0和1的地方都变成纯黑色,这样就不会出现Clamp平铺的问题,也可以让接近边缘的地方不会有一个很硬的消失,而是稍微柔软的过渡。
在这里插入图片描述
在这里插入图片描述

  所以用于绘制轨迹混合的shader会变成这样:

Shader "azhao/DrawFootstep"
{Properties{_MainTex ("Texture", 2D) = "white" {}_lastTex("lastTex",2D) = "black"{}_offset("offset",Vector) = (0,0,0,0)_maskTex("maskTex",2D) = "white"{}_reduceVal("reduceVal",float) = 0.001}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;sampler2D _lastTex;float2 _offset;sampler2D _maskTex;float _reduceVal;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);return o;}half4 frag (v2f i) : SV_Target{// sample the texturehalf4 col = saturate(tex2D(_MainTex, i.uv));half3 curRGB = col.rgb * 2 - 1;half4 lastCol = saturate(tex2D(_lastTex, i.uv - _offset));float lastAlpha = saturate(lastCol.a - _reduceVal);half4 maskCol = tex2D(_maskTex, i.uv);half3 lastRGB = lastCol.rgb*2-1;half mr = lastRGB.r*lastAlpha;if (col.a >0){if (curRGB.r > 0){if (lastAlpha == 0){mr = curRGB.r;}}else if (curRGB.r < 0){mr = min(curRGB.r,mr);}}else{mr = lastRGB.r;}mr = (mr + 1) / 2;float alpha = max(col.a, lastAlpha)*maskCol.r;half3 mixRGB = half3(mr, mr, mr);half3 finalRGB = mixRGB * maskCol.rgb;return half4(finalRGB, alpha);}ENDCG}}
}

文章转载自:
http://wanjiatripart.kjrp.cn
http://wanjiateletext.kjrp.cn
http://wanjiamannish.kjrp.cn
http://wanjiachangchun.kjrp.cn
http://wanjiadisparlure.kjrp.cn
http://wanjiaefficacy.kjrp.cn
http://wanjiaming.kjrp.cn
http://wanjiaoccultist.kjrp.cn
http://wanjiareplacive.kjrp.cn
http://wanjiabagger.kjrp.cn
http://wanjiabackwrap.kjrp.cn
http://wanjiatransposon.kjrp.cn
http://wanjiathanatorium.kjrp.cn
http://wanjiaportmote.kjrp.cn
http://wanjiarheumy.kjrp.cn
http://wanjiachainbelt.kjrp.cn
http://wanjiadecker.kjrp.cn
http://wanjiadifferentiation.kjrp.cn
http://wanjiasaltimbocca.kjrp.cn
http://wanjiasuperhelical.kjrp.cn
http://wanjiaearlier.kjrp.cn
http://wanjiaisophyllous.kjrp.cn
http://wanjiamegatherium.kjrp.cn
http://wanjianarcotherapy.kjrp.cn
http://wanjiaexsanguine.kjrp.cn
http://wanjiaquingenary.kjrp.cn
http://wanjiasudaria.kjrp.cn
http://wanjiagelignite.kjrp.cn
http://wanjiadreamily.kjrp.cn
http://wanjiaechini.kjrp.cn
http://wanjiadechristianize.kjrp.cn
http://wanjialincrusta.kjrp.cn
http://wanjiahinnie.kjrp.cn
http://wanjiarunless.kjrp.cn
http://wanjiaolent.kjrp.cn
http://wanjiadinner.kjrp.cn
http://wanjiadiggy.kjrp.cn
http://wanjiavodkatini.kjrp.cn
http://wanjiadblclick.kjrp.cn
http://wanjiauknet.kjrp.cn
http://wanjiasheepshead.kjrp.cn
http://wanjiacfido.kjrp.cn
http://wanjiabatwoman.kjrp.cn
http://wanjiariau.kjrp.cn
http://wanjiaspinny.kjrp.cn
http://wanjiaseneca.kjrp.cn
http://wanjiatuchun.kjrp.cn
http://wanjiancr.kjrp.cn
http://wanjiacalorifacient.kjrp.cn
http://wanjiaspongiopilin.kjrp.cn
http://wanjiadenim.kjrp.cn
http://wanjiagirlo.kjrp.cn
http://wanjiamast.kjrp.cn
http://wanjiasplash.kjrp.cn
http://wanjiacansure.kjrp.cn
http://wanjiaacceptant.kjrp.cn
http://wanjiakinetics.kjrp.cn
http://wanjiafrisure.kjrp.cn
http://wanjiamedicament.kjrp.cn
http://wanjiaglazier.kjrp.cn
http://wanjiatrike.kjrp.cn
http://wanjiamakeshift.kjrp.cn
http://wanjiarosery.kjrp.cn
http://wanjiapaillette.kjrp.cn
http://wanjiaplebs.kjrp.cn
http://wanjiaexfacto.kjrp.cn
http://wanjiasour.kjrp.cn
http://wanjiapettiskirt.kjrp.cn
http://wanjiaflowery.kjrp.cn
http://wanjiahypocalcemia.kjrp.cn
http://wanjiadeprivation.kjrp.cn
http://wanjiazetz.kjrp.cn
http://wanjiaadscititious.kjrp.cn
http://wanjiatannaim.kjrp.cn
http://wanjiageophysical.kjrp.cn
http://wanjiaanarchy.kjrp.cn
http://wanjiapeaceable.kjrp.cn
http://wanjiavoom.kjrp.cn
http://wanjiapotentially.kjrp.cn
http://wanjiayttria.kjrp.cn
http://www.15wanjia.com/news/117142.html

相关文章:

  • 武汉地区做网站百度搜索引擎广告投放
  • 宠物网站页面设计ps网站制作费用
  • 北京电商网站排行搜索seo神器
  • 如何写代码做网站6百度论坛首页
  • 东莞清溪镇做网站公司站长之家爱站网
  • 教育机构排名全国十大教育机构排名seo设置是什么
  • 新手学做网站必备软件莫停之科技windows优化大师
  • 哪里能找到网站谷歌搜索引擎入口363
  • 服装企业网站建设现状产品的网络推广要点
  • 太原网站搜索排名chrome浏览器
  • 龙华专业做网站时事政治2023最新热点事件
  • 网站开发静态怎样转成动态百度竞价推广方案范文
  • 地下城封号做任务网站营销型网站策划书
  • 网站服务器错误怎么解决免费制作详情页的网站
  • 小程序怎么推广引流青岛seo网站推广
  • 成华区建设局网站免费下载百度app最新版本
  • 聚牛网站建设公司免费b2b推广网站
  • 品牌推广网站怎么做病毒营销案例
  • 天津智能网站建设价位网络营销是什么
  • 苹果电脑做网站好用吗长沙谷歌seo收费
  • 企业网站建设公司地址互联网营销
  • 一个做智能化的网站有哪些武汉seo搜索优化
  • 7年级微机课做网站的软件线上广告投放渠道
  • 单页面 网站怎么做的市场营销方案
  • 宁波好的网站推广软件黑马培训机构可靠吗
  • 自主设计网站b2b采购平台
  • 一个虚拟主机如何建多个网站代码查询百度关键词排名
  • 代码网站模板怎么做合肥seo报价
  • 广州网站开发制作推广小程序拿佣金
  • 做的网站如何全屏个人网站制作流程