nim*_*nim 2 c# unity-game-engine
我制作了一个球出现在 3D 空间中的场景。三角球耗费大量资源。所以我使用带有球纹理的二维表面(四边形)来完成此操作。但现在我需要在每次相机移动时调整形状的方向。我使用位置变换和 LookAt 方法来完成此操作。问题是我可以优化这个吗?如果可以使用着色器旋转形状,这将有很大帮助。
using UnityEngine;
public class WorldSurf : MonoBehaviour
{
GameObject[] matrix;
int xSize = 20;
int ySize = 20;
int zSize = 20;
// Start is called before the first frame update
void Start()
{
matrix = new GameObject[xSize * ySize * zSize];
//var shader = Shader.Find("Legacy Shaders/Diffuse");
var shader = Shader.Find("Sprites/Default");
//var texture = Resources.Load<Texture>("Textures/Ball_01");
var i = 0;
for (var x = 0f; x < xSize; ++x)
{
for (var y = 0f; y < ySize; ++y)
{
for (var z = 0f; z < zSize; ++z)
{
var texture = Resources.Load<Texture>("Textures/Ball_" + ((int)Random.Range(0, 15)).ToString("00"));
matrix[i++] = CreateQuad(x * 3, y * 3, z * 3, shader, texture);
}
}
}
}
static GameObject CreateQuad(float x, float y, float z, Shader shader, Texture texture)
{
var quad = GameObject.CreatePrimitive(PrimitiveType.Quad);
quad.transform.position = new Vector3(x, y, z);
quad.transform.forward = Camera.main.transform.forward;
var rend = quad.GetComponent<Renderer>();
rend.material.shader = shader;
rend.material.mainTexture = texture;
//rend.material.color = Color.red;
return quad;
}
// Update is called once per frame
void Update()
{
var pos = Camera.main.transform.position;
foreach (var itm in matrix)
{
itm.transform.LookAt(pos);
}
}
}
Run Code Online (Sandbox Code Playgroud)
一般来说是的,在这种特定情况下,如果您希望四边形与相机对齐,那么这样做非常容易。
\n\n你想要的叫做“广告牌着色器”。这是维基教科书中的一个例子:
\n\nShader "Cg shader for billboards" {\n Properties {\n _MainTex ("Texture Image", 2D) = "white" {}\n _ScaleX ("Scale X", Float) = 1.0\n _ScaleY ("Scale Y", Float) = 1.0\n }\n SubShader {\n Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}\n ZWrite Off\n Blend SrcAlpha OneMinusSrcAlpha\n\n Pass { \n CGPROGRAM\n\n #pragma vertex vert \n #pragma fragment frag\n\n // User-specified uniforms \n uniform sampler2D _MainTex; \n uniform float _ScaleX;\n uniform float _ScaleY;\n\n struct vertexInput {\n float4 vertex : POSITION;\n float4 tex : TEXCOORD0;\n };\n struct vertexOutput {\n float4 pos : SV_POSITION;\n float4 tex : TEXCOORD0;\n };\n\n vertexOutput vert(vertexInput input) \n {\n vertexOutput output;\n\n output.pos = mul(UNITY_MATRIX_P, \n mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))\n + float4(input.vertex.x, input.vertex.y, 0.0, 0.0)\n * float4(_ScaleX, _ScaleY, 1.0, 1.0));\n\n output.tex = input.tex;\n\n return output;\n }\n\n float4 frag(vertexOutput input) : COLOR\n {\n return tex2D(_MainTex, float2(input.tex.xy)); \n }\n\n ENDCG\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n以及其工作原理的解释:
\n\n\n\n\n基本思想是仅
\n( 0 , 0 , 0 , 1 )使用标准模型视图变换将对象空间的原点变换为视图空间UNITY_MATRIX_MV.(在齐次坐标中,所有点都有一个 1 作为第四个坐标;请参阅第 1 节中的讨论) xe2\x80\x9cVertex\n 变换\xe2\x80\x9d。)视图空间只是世界空间的旋转版本\n,其平面xy平行于\n 视图平面,如第 \xe2\x80\x9cVertex 变换\ 节中所述。 xe2\x80\x9d。因此,这是构建适当旋转的广告牌的正确空间。我们从视图坐标中变换后的原点减去xy对象坐标 (vertex.x和vertex.y),然后用投影矩阵 变换结果UNITY_MATRIX_P。
这将产生如下输出:
\n\n\n