首页 > 其他分享 >Unity引擎制作球形地面

Unity引擎制作球形地面

时间:2024-08-23 15:27:41浏览次数:7  
标签:Node False 球形 FLOAT Unity 引擎 AmplifyShaderEditor True WireConnection

<iframe allowfullscreen="true" data-mediaembed="youku" frameborder="0" id="81zaoZhk-1723948548211" src="https://player.youku.com/embed/XNjQyMjI2MTcwOA=="></iframe>

Unity引擎制作球形地面3

大家好,我是阿赵。
  之前有个朋友问我,有些游戏,角色好像走在一个球形的地面上,离角色远的东西会往下沉,直到看不见。
在这里插入图片描述

  这种效果的做法肯定不止一种的。
  最直观的做法,如果本身每张地图的范围很小,是固定只能走一定的圆弧范围的地面。这种情况我觉得直接做一个弯曲的3D模型作为地表,也可以做到。
  不过这种做弯曲3D模型的方式,局限性是比较大的,主要遇到的问题有这么几个:
1、 如果每张地图的大小不统一,需要的弧度可能也不统一,这样就变成了每个地图都要单独的去制作不同弧度的模型
2、 如果需要修改地图的弧度,可能面临着比较大工作量去修改模型
3、 游戏实际上还是二维坐标,但由于地图是有弧度的,所以需要做一个二维坐标向弯曲之后的地面映射的操作。
  后来我就建议朋友不要用这种3D模型的做法,而是用Shader控制顶点Y坐标的方法去实现。
  具体做法很简单,只需要用Shader控制模型顶点的Y坐标变化:
在这里插入图片描述

  实际有用的就是:
在这里插入图片描述

  这个部分是计算模型顶点坐标的,可以看出,我先获取了顶点的世界坐标,然后x和z是没有变化的,直接输入到最终的Append。
  然后有2个全局的变量:

1. rolePos
这个代表的是摄像机正在跟随的主角的坐标。
2. ballVal
地面的弯曲程度。

  接下来的计算很简单,把当前模型的顶点的z坐标,和主角的z坐标相减,然后乘以弯曲程度,得到一个需要向下偏移的值。最后用原来模型的y坐标减去这个偏移值就行了。用通俗简单一点的话来说,离主角z轴距离越远的顶点,需要往下偏移就越大,所以远处的东西就因为往下偏移,到完全看不见了。
在这里插入图片描述

  移动的实际过程可以参考视频:

<iframe allowfullscreen="true" data-mediaembed="youku" frameborder="0" id="TBlDBpzx-1723948602786" src="https://player.youku.com/embed/XNjQyMjI0NzYwMA=="></iframe>

Unity引擎制作球形地面2

  很明显,这个不是球形地面,而是圆柱形地面。如果真的想做到圆形地面的效果,其实也很简单,把x轴和z轴一起计算距离就行了,x和z离得远的,y就往下偏移得越多,看起来就是一个球形了。
在这里插入图片描述

在这里插入图片描述

  也许有些朋友会说,我这个不是正圆,或者说不是正圆弧的地面。但我想说的是,从效果上看,它已经完全达到我们的目的了,是不是正圆弧,并不是很重要吧。
  这样的做法好处很多:
1.不需要特殊的制作模型,一切还是按照平面的做法去做。
2.由于只是改变了高度,也即是y轴,x和z轴没有变化过,所以游戏里面的2d坐标逻辑,是完全不需要转换,就可以和场景上面的模型对应上。
3.可以随意的修改弯曲度。
  当然,缺点也是有的:
1、 由于需要控制所有场景物体的y坐标,所以项目里面所有使用到的shader都需要加y轴控制的代码。虽然我觉得项目里面所有的Shader应该是全部自己控制的,但对于很多朋友来说,他们的shader都不会自己写的,要么就是Unity自带的,要么是网上抄回来的。这种情况要全部shader自己控制是有点不切实际。
2、 对于地面模型的面数有一定的要求。由于控制的是顶点y坐标,所以如果地面的模型面数很少,比如隔几米才一个顶点,那么控制y坐标偏移,会出现不平滑的情况,其他物体要么浮在空中,要么嵌到地面。
最后分享一下ASE生成的代码,其实如果自己手写,代码可以简洁很多,无奈现在习惯了ASE的快速出效果,越来越懒了。

// Made with Amplify Shader Editor
// Available at the Unity Asset Store - http://u3d.as/y3X 
Shader "BallFloor"
{
	Properties
	{
		_MainTex("MainTex", 2D) = "white" {}
		_MainColor("MainColor", Color) = (1,1,1,0)
		[HideInInspector] _texcoord( "", 2D ) = "white" {}

	}
	
	SubShader
	{
		
		
		Tags { "RenderType"="Opaque" }
	LOD 100

		CGINCLUDE
		#pragma target 3.0
		ENDCG
		Blend Off
		AlphaToMask Off
		Cull Back
		ColorMask RGBA
		ZWrite On
		ZTest LEqual
		Offset 0 , 0
		
		
		
		Pass
		{
			Name "Unlit"
			Tags { "LightMode"="ForwardBase" }
			CGPROGRAM

			#define ASE_ABSOLUTE_VERTEX_POS 1


			#ifndef UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX
			//only defining to not throw compilation error over Unity 5.5
			#define UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input)
			#endif
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_instancing
			#include "UnityCG.cginc"
			

			struct appdata
			{
				float4 vertex : POSITION;
				float4 color : COLOR;
				float4 ase_texcoord : TEXCOORD0;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};
			
			struct v2f
			{
				float4 vertex : SV_POSITION;
				#ifdef ASE_NEEDS_FRAG_WORLD_POSITION
				float3 worldPos : TEXCOORD0;
				#endif
				float4 ase_texcoord1 : TEXCOORD1;
				UNITY_VERTEX_INPUT_INSTANCE_ID
				UNITY_VERTEX_OUTPUT_STEREO
			};

			uniform float3 rolePos;
			uniform float ballVal;
			uniform float4 _MainColor;
			uniform sampler2D _MainTex;
			uniform float4 _MainTex_ST;

			
			v2f vert ( appdata v )
			{
				v2f o;
				UNITY_SETUP_INSTANCE_ID(v);
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
				UNITY_TRANSFER_INSTANCE_ID(v, o);

				float3 ase_worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
				float temp_output_26_0 = ( ( ase_worldPos.x - rolePos.x ) * ballVal );
				float temp_output_4_0 = ( ( ase_worldPos.z - rolePos.z ) * ballVal );
				float3 appendResult2 = (float3(ase_worldPos.x , ( ase_worldPos.y - ( ( temp_output_26_0 * temp_output_26_0 ) + ( temp_output_4_0 * temp_output_4_0 ) ) ) , ase_worldPos.z));
				float3 worldToObj7 = mul( unity_WorldToObject, float4( appendResult2, 1 ) ).xyz;
				float3 VertexPos20 = worldToObj7;
				
				o.ase_texcoord1.xy = v.ase_texcoord.xy;
				
				//setting value to unused interpolator channels and avoid initialization warnings
				o.ase_texcoord1.zw = 0;
				float3 vertexValue = float3(0, 0, 0);
				#if ASE_ABSOLUTE_VERTEX_POS
				vertexValue = v.vertex.xyz;
				#endif
				vertexValue = VertexPos20;
				#if ASE_ABSOLUTE_VERTEX_POS
				v.vertex.xyz = vertexValue;
				#else
				v.vertex.xyz += vertexValue;
				#endif
				o.vertex = UnityObjectToClipPos(v.vertex);

				#ifdef ASE_NEEDS_FRAG_WORLD_POSITION
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
				#endif
				return o;
			}
			
			fixed4 frag (v2f i ) : SV_Target
			{
				UNITY_SETUP_INSTANCE_ID(i);
				UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
				fixed4 finalColor;
				#ifdef ASE_NEEDS_FRAG_WORLD_POSITION
				float3 WorldPosition = i.worldPos;
				#endif
				float2 uv_MainTex = i.ase_texcoord1.xy * _MainTex_ST.xy + _MainTex_ST.zw;
				float4 color16 = ( _MainColor * tex2D( _MainTex, uv_MainTex ) );
				
				
				finalColor = color16;
				return finalColor;
			}
			ENDCG
		}
	}
	CustomEditor "ASEMaterialInspector"
	
	
}
/*ASEBEGIN
Version=18500
1920;0;1920;1019;2189.778;742.377;1;True;True
Node;AmplifyShaderEditor.CommentaryNode;23;-1726.385,-493.2556;Inherit;False;1206.924;537.7661;Comment;12;20;7;3;2;8;4;10;5;1;11;25;27;VertexPos;1,1,1,1;0;0
Node;AmplifyShaderEditor.WorldPosInputsNode;1;-1608.486,-443.2556;Inherit;False;0;4;FLOAT3;0;FLOAT;1;FLOAT;2;FLOAT;3
Node;AmplifyShaderEditor.Vector3Node;11;-1693.886,-266.1556;Inherit;False;Global;rolePos;rolePos;2;0;Create;True;0;0;False;0;False;0,0,0;-24.19481,0,-33.37932;0;4;FLOAT3;0;FLOAT;1;FLOAT;2;FLOAT;3
Node;AmplifyShaderEditor.SimpleSubtractOpNode;25;-1428.778,-319.377;Inherit;False;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleSubtractOpNode;10;-1482.786,-221.6556;Inherit;False;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.RangedFloatNode;5;-1658.385,-38.65557;Inherit;False;Global;ballVal;ballVal;1;0;Create;True;0;0;False;0;False;0;0.1164894;0;0.2;0;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;26;-1312.778,-186.377;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;4;-1326.986,-81.95564;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;27;-1186.778,-201.377;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;8;-1099.42,-60.00696;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleAddOpNode;28;-960.7778,-115.377;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleSubtractOpNode;3;-1216.066,-293.2313;Inherit;False;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.CommentaryNode;18;-1715.685,-1092.361;Inherit;False;771.8348;492;;4;6;12;13;16;color;1,1,1,1;0;0
Node;AmplifyShaderEditor.DynamicAppendNode;2;-1110.767,-417.6276;Inherit;False;FLOAT3;4;0;FLOAT;0;False;1;FLOAT;0;False;2;FLOAT;0;False;3;FLOAT;0;False;1;FLOAT3;0
Node;AmplifyShaderEditor.SamplerNode;6;-1665.685,-830.3605;Inherit;True;Property;_MainTex;MainTex;0;0;Create;True;0;0;False;0;False;-1;None;None;True;0;False;white;Auto;False;Object;-1;Auto;Texture2D;8;0;SAMPLER2D;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;5;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4
Node;AmplifyShaderEditor.ColorNode;12;-1632.685,-1042.361;Inherit;False;Property;_MainColor;MainColor;1;0;Create;True;0;0;False;0;False;1,1,1,0;1,1,1,0;True;0;5;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;13;-1357.685,-960.3605;Inherit;False;2;2;0;COLOR;0,0,0,0;False;1;COLOR;0,0,0,0;False;1;COLOR;0
Node;AmplifyShaderEditor.TransformPositionNode;7;-965.6563,-296.1759;Inherit;False;World;Object;False;Fast;True;1;0;FLOAT3;0,0,0;False;4;FLOAT3;0;FLOAT;1;FLOAT;2;FLOAT;3
Node;AmplifyShaderEditor.RegisterLocalVarNode;20;-726.3401,-270.6392;Inherit;False;VertexPos;-1;True;1;0;FLOAT3;0,0,0;False;1;FLOAT3;0
Node;AmplifyShaderEditor.RegisterLocalVarNode;16;-1167.851,-940.5619;Inherit;False;color;-1;True;1;0;COLOR;0,0,0,0;False;1;COLOR;0
Node;AmplifyShaderEditor.GetLocalVarNode;17;-805.3762,-841.2354;Inherit;False;16;color;1;0;OBJECT;;False;1;COLOR;0
Node;AmplifyShaderEditor.GetLocalVarNode;22;-752.5753,-633.8202;Inherit;False;20;VertexPos;1;0;OBJECT;;False;1;FLOAT3;0
Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;0;-445.1787,-686.0229;Float;False;True;-1;2;ASEMaterialInspector;100;1;BallFloor;0770190933193b94aaa3065e307002fa;True;Unlit;0;0;Unlit;2;True;0;1;False;-1;0;False;-1;0;1;False;-1;0;False;-1;True;0;False;-1;0;False;-1;False;False;False;False;False;False;True;0;False;-1;True;0;False;-1;True;True;True;True;True;0;False;-1;False;False;False;True;False;255;False;-1;255;False;-1;255;False;-1;7;False;-1;1;False;-1;1;False;-1;1;False;-1;7;False;-1;1;False;-1;1;False;-1;1;False;-1;True;1;False;-1;True;3;False;-1;True;True;0;False;-1;0;False;-1;True;1;RenderType=Opaque=RenderType;True;2;0;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;1;LightMode=ForwardBase;False;0;;0;0;Standard;1;Vertex Position,InvertActionOnDeselection;0;0;1;True;False;;False;0
WireConnection;25;0;1;1
WireConnection;25;1;11;1
WireConnection;10;0;1;3
WireConnection;10;1;11;3
WireConnection;26;0;25;0
WireConnection;26;1;5;0
WireConnection;4;0;10;0
WireConnection;4;1;5;0
WireConnection;27;0;26;0
WireConnection;27;1;26;0
WireConnection;8;0;4;0
WireConnection;8;1;4;0
WireConnection;28;0;27;0
WireConnection;28;1;8;0
WireConnection;3;0;1;2
WireConnection;3;1;28;0
WireConnection;2;0;1;1
WireConnection;2;1;3;0
WireConnection;2;2;1;3
WireConnection;13;0;12;0
WireConnection;13;1;6;0
WireConnection;7;0;2;0
WireConnection;20;0;7;0
WireConnection;16;0;13;0
WireConnection;0;0;17;0
WireConnection;0;1;22;0
ASEEND*/
//CHKSM=14088912893801E38414D800F13E9F2C89931493

标签:Node,False,球形,FLOAT,Unity,引擎,AmplifyShaderEditor,True,WireConnection
From: https://blog.csdn.net/liweizhao/article/details/141295643

相关文章

  • 火山引擎VeDI实验平台助推企业量化决策能力升级
     更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 量化决策,正成为企业在数智化浪潮中掌握方向的必备之舵。 通过“拍脑袋”式的经验决策,企业往往难以优选出带来更高收益的策略。相比之下,通过数据分析带来的量化决策则是一种更为......
  • 轻松上手:Docker部署Elasticsearch,高效构建搜索引擎环境
    我在前一段时间写了一个ES简介,博主建议大家先看完简介再来安装ES,那篇博文是:深入理解Elasticsearch:让搜索性能飞起来!-CSDN博客服务器开放9200和9300端口号:1.打开目录:cd/usr/local/docker/2.创建es目录:mkdires3.打开es目录:cdes/4.下载镜像:我在这里声明一下......
  • MySQL存储引擎
    一、简介数据库存储引擎是数据库底层软件组件,数据库管理系统(DBMS)使用数据引擎进行创建、查询、更新和删除数据操作。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎,还可以获得特定的功能。现在许多不多的数据库管理系统都支持多种不同的数据引擎......
  • 六、什么是SEO优化(搜索引擎优化)?SPA单页面应用如何实现SEO优化?
    文章目录一、什么是搜索引擎优化(SEO)二、如何实现搜索引擎优化(SEO)搜索引擎工作原理实现搜索引擎优化(SEO)三、SPA单页面实现SEO优化SPA实现SEO优化的难点分析SEO实现方案:SSR服务端渲染一、什么是搜索引擎优化(SEO)seo(SearchEngineOptimization)又称网站优化,也称搜索引......
  • 云计算:数字经济的新引擎
    随着人工智能技术的飞速发展,云计算作为其背后的强大支撑,正逐渐成为数字经济的新引擎。本文将深入探讨云计算行业的布局与发展,分析其对经济金融领域的深远影响。云计算行业的崛起人工智能的助推自ChatGPT等人工智能应用的火爆,云计算行业迎来了前所未有的发展机遇。人工智能的......
  • mysql InnoDB引擎各种隔离级别的加锁机制
    文章目录概要前置知识了解各种隔离锁的验证小结概要我们都知道,mysql的InnoDB引擎在各种隔离级别下的加锁机制都是有差异的,但是对于各种隔离级别下如何加锁大家可能不太了解,今天我就通过一篇文章去带领大家去分析一下各个隔离级别的加锁过程,如果有误,欢迎大家在评论......
  • Unity跳过闪屏页
    github上一段代码,跳过UnityLogo启动屏:github链接:https://github.com/psygames/UnitySkipSplash/blob/main/SkipSplash.csUnityAPI文档,Unity暴露了SplashScreen.Stop()停止启动屏的API只需要写个静态方法,使用[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.Bef......
  • 字符串值提取工具-10-java 执行表达式引擎
    值提取系列字符串值提取工具-01-概览字符串值提取工具-02-java调用js字符串值提取工具-03-java调用groovy字符串值提取工具-04-java调用java?Janino编译工具字符串值提取工具-05-java调用shell字符串值提取工具-06-java调用python字符串值提取工具-07-java调......
  • MongoDB系列之WiredTiger引擎
    概述关系型数据库MySQL有InnoDB存储引擎,存储引擎很大程度上决定着数据库的性能。在MongoDB早期版本中,默认使用MMapV1存储引擎,其索引就是一个B-树(也称B树)。从MongoDB3.0开始引入WiredTiger(以下简称WT)存储引擎,在性能及稳定性上都有明显的提升。从MongoDB3.2开始,WT作为默认的引......
  • Apache SeaTunnel数据处理引擎适配的演进和规划
    作者|ChaoTian(tyrantlucifer),ApacheSeaTunnelPMCMember摘要ApacheSeaTunnel作为一个高性能数据同步工具,以其高效的数据处理能力,为数据集成领域带来了创新。在引擎上,ApacheSeaTunnel除了支持自身的Zeta引擎外,还支持Spark和Flink。在2024年的CommunityOverCodeAsia,Apa......