Hi there,
So I'm currently testing out an RTS idea and have been looking for efficient ways of displaying large numbers of models in a scene. Much experimentation has ended up with me doing this:
1.Capturing a model on camera
2.Writing Camera to a Render Texture
3.Using a basic mesh with a vertex shader to display multiple billboards
(this displays a seperate billboard on each of the mesh's vertices)
4.Using the model camera's render texture as the billboard texture
This actually worked pretty well initially as you can see:
![alt text][1]
Unfortunately there seems to be a depth issue when the mesh is viewed from opposite it's normals like so:
![alt text][2]
[1]: /storage/temp/64009-unitycom.png
[2]: /storage/temp/64010-unitycomp2.png
So here is my question, Is there a way to solve this while keeping the vertex shader?
Any help would be greatly appreciated, Gonna post the shader code here in case there is anything wrong with it
_SpriteTex ("Base (RGBA)", 2D) = "white" {}
_Size ("Size", Range(0, 3)) = 0.5
}
SubShader
{
Tags { }
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
// Cull Back
// Offset 1, 1
LOD 200
Pass
{
CGPROGRAM
#pragma target 5.0
#pragma vertex VS_Main
#pragma fragment FS_Main
#pragma geometry GS_Main
#include "UnityCG.cginc"
// **************************************************************
// Data structures *
// **************************************************************
struct GS_INPUT
{
float4 pos : POSITION;
float3 normal : NORMAL;
float2 tex0 : TEXCOORD0;
float3 viewT : TEXCOORD1;
};
struct FS_INPUT
{
float4 pos : POSITION;
float2 tex0 : TEXCOORD0;
};
// **************************************************************
// Vars *
// **************************************************************
float _Size;
float4x4 _VP;
Texture2D _SpriteTex;
SamplerState sampler_SpriteTex;
// **************************************************************
// Shader Programs *
// **************************************************************
// Vertex Shader ------------------------------------------------
GS_INPUT VS_Main(appdata_base v)
{
GS_INPUT output = (GS_INPUT)0;
output.pos = mul(_Object2World, v.vertex);
output.normal = normalize(v.normal);
output.tex0 = float2(0, 0);
//
return output;
}
// Geometry Shader -----------------------------------------------------
[maxvertexcount(4)]
void GS_Main(point GS_INPUT p[1], inout TriangleStream triStream)
{
float3 up = float3(0, 1, 0);
float3 look = _WorldSpaceCameraPos - p[0].pos;
look.y = 0;
look = normalize(look);
float3 right = cross(up, look);
float halfS = 0.5f * _Size;
float4 v[4];
v[0] = float4(p[0].pos + halfS * right - halfS * up, 1.0f);
v[1] = float4(p[0].pos + halfS * right + halfS * up, 1.0f);
v[2] = float4(p[0].pos - halfS * right - halfS * up, 1.0f);
v[3] = float4(p[0].pos - halfS * right + halfS * up, 1.0f);
float4x4 vp = mul(UNITY_MATRIX_MVP, _World2Object);
FS_INPUT pIn;
pIn.pos = mul(vp, v[0]);
pIn.tex0 = float2(1.0f, 0.0f);
triStream.Append(pIn);
pIn.pos = mul(vp, v[1]);
pIn.tex0 = float2(1.0f, 1.0f);
triStream.Append(pIn);
pIn.pos = mul(vp, v[2]);
pIn.tex0 = float2(0.0f, 0.0f);
triStream.Append(pIn);
pIn.pos = mul(vp, v[3]);
pIn.tex0 = float2(0.0f, 1.0f);
triStream.Append(pIn);
}
// Fragment Shader -----------------------------------------------
float4 FS_Main(FS_INPUT input) : COLOR
{
return _SpriteTex.Sample(sampler_SpriteTex, input.tex0);
}
ENDCG
}
}
Fallback "Diffuse"
}
↧