C# 着色器可以将形状旋转到面对摄影机吗?

C# 着色器可以将形状旋转到面对摄影机吗?,c#,unity3d,C#,Unity3d,我制作了一个场景,球出现在3D空间中。三角球耗费大量资源。所以我使用带有球纹理的2d曲面(四边形)来实现这一点。但现在我需要在相机每次移动时调整形状的方向。我使用位置变换和LookAt方法来实现这一点。问题是我能优化这个吗?如果可以使用着色器旋转形状,这将非常有帮助 使用UnityEngine; 公共级世界冲浪:单一行为 { 博弈对象[]矩阵; int-xSize=20; int-ySize=20; int zSize=20; //在第一帧更新之前调用Start void Start() {

我制作了一个场景,球出现在3D空间中。三角球耗费大量资源。所以我使用带有球纹理的2d曲面(四边形)来实现这一点。但现在我需要在相机每次移动时调整形状的方向。我使用位置变换和LookAt方法来实现这一点。问题是我能优化这个吗?如果可以使用着色器旋转形状,这将非常有帮助

使用UnityEngine;
公共级世界冲浪:单一行为
{
博弈对象[]矩阵;
int-xSize=20;
int-ySize=20;
int zSize=20;
//在第一帧更新之前调用Start
void Start()
{
矩阵=新游戏对象[xSize*ySize*zSize];
//var shader=shader.Find(“遗留着色器/漫反射”);
var shader=shader.Find(“精灵/默认”);
//var texture=Resources.Load(“纹理/Ball_01”);
var i=0;
对于(变量x=0f;x
通常是的,在这种特殊情况下,您需要一个四边形与相机对齐,这样做非常容易

你想要的是所谓的“广告牌着色器”。以下是一个例子:

并解释其工作原理:

基本思想是只变换原点
(0,0,0,1)
物体的形状 使用标准模型视图转换的空间到视图空间
UNITY\u MATRIX\u MV.
(在齐次坐标中,所有点都有一个1作为 第四坐标;参见“顶点”一节中的讨论 “变换”。)视图空间只是世界空间的旋转版本 使
xy
平面平行于 视图平面如“顶点变换”一节所述。因此 这是正确的空间来构造适当旋转的 广告牌我们从变换后的图像中减去
x
y
对象坐标(
vertex.x
vertex.y
) 以视图坐标为原点,然后使用 投影矩阵
UNITY\u matrix\u P

这将产生如下输出:


非常酷的FPS已上扬10倍!但是我有一个新问题,在同一个着色器中启用透明颜色过滤是否可能?@nim很乐意帮忙。我在
Pass
之前添加了一些更改,这将有助于使其透明化。如果这是可行的,请告诉我。Unity说:“检测到UnyTyMyRxxMV的使用。为了将顶点转换成视图空间,请考虑使用UNIVITOOTHOTVIEW POPs来获得更好的性能。”但所有work@nim我换了线路,试图摆脱警告。如果有,请告诉我works@nim试试看,如果这不起作用,最好只使用UNITY\u MATRIX\u MV:)
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);
        }
    }
}
Shader "Cg  shader for billboards" {
   Properties {
      _MainTex ("Texture Image", 2D) = "white" {}
      _ScaleX ("Scale X", Float) = 1.0
      _ScaleY ("Scale Y", Float) = 1.0
   }
   SubShader {
      Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
      ZWrite Off
      Blend SrcAlpha OneMinusSrcAlpha

      Pass {   
         CGPROGRAM

         #pragma vertex vert  
         #pragma fragment frag

         // User-specified uniforms            
         uniform sampler2D _MainTex;        
         uniform float _ScaleX;
         uniform float _ScaleY;

         struct vertexInput {
            float4 vertex : POSITION;
            float4 tex : TEXCOORD0;
         };
         struct vertexOutput {
            float4 pos : SV_POSITION;
            float4 tex : TEXCOORD0;
         };

         vertexOutput vert(vertexInput input) 
         {
            vertexOutput output;

            output.pos = mul(UNITY_MATRIX_P, 
              mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))
              + float4(input.vertex.x, input.vertex.y, 0.0, 0.0)
              * float4(_ScaleX, _ScaleY, 1.0, 1.0));

            output.tex = input.tex;

            return output;
         }

         float4 frag(vertexOutput input) : COLOR
         {
            return tex2D(_MainTex, float2(input.tex.xy));   
         }

         ENDCG
      }
   }
}