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