Permalink
Find file Copy path
e094d8b Jan 4, 2019
1 contributor

Users who have contributed to this file

127 lines (106 sloc) 2.77 KB
// Pcx - Point cloud importer & renderer for Unity
// https://github.com/keijiro/Pcx
#include "UnityCG.cginc"
#include "Common.cginc"
// Uniforms
half4 _Tint;
half _PointSize;
float4x4 _Transform;
#if _COMPUTE_BUFFER
StructuredBuffer<float4> _PointBuffer;
#endif
// Vertex input attributes
struct Attributes
{
#if _COMPUTE_BUFFER
uint vertexID : SV_VertexID;
#else
float4 position : POSITION;
half3 color : COLOR;
#endif
};
// Fragment varyings
struct Varyings
{
float4 position : SV_POSITION;
#if !PCX_SHADOW_CASTER
half3 color : COLOR;
UNITY_FOG_COORDS(0)
#endif
};
// Vertex phase
Varyings Vertex(Attributes input)
{
// Retrieve vertex attributes.
#if _COMPUTE_BUFFER
float4 pt = _PointBuffer[input.vertexID];
float4 pos = mul(_Transform, float4(pt.xyz, 1));
half3 col = PcxDecodeColor(asuint(pt.w));
#else
float4 pos = input.position;
half3 col = input.color;
#endif
#if !PCX_SHADOW_CASTER
// Color space convertion & applying tint
#if UNITY_COLORSPACE_GAMMA
col *= _Tint.rgb * 2;
#else
col *= LinearToGammaSpace(_Tint.rgb) * 2;
col = GammaToLinearSpace(col);
#endif
#endif
// Set vertex output.
Varyings o;
o.position = UnityObjectToClipPos(pos);
#if !PCX_SHADOW_CASTER
o.color = col;
UNITY_TRANSFER_FOG(o, o.position);
#endif
return o;
}
// Geometry phase
[maxvertexcount(36)]
void Geometry(point Varyings input[1], inout TriangleStream<Varyings> outStream)
{
float4 origin = input[0].position;
float2 extent = abs(UNITY_MATRIX_P._11_22 * _PointSize);
// Copy the basic information.
Varyings o = input[0];
// Determine the number of slices based on the radius of the
// point on the screen.
float radius = extent.y / origin.w * _ScreenParams.y;
uint slices = min((radius + 1) / 5, 4) + 2;
// Slightly enlarge quad points to compensate area reduction.
// Hopefully this line would be complied without branch.
if (slices == 2) extent *= 1.2;
// Top vertex
o.position.y = origin.y + extent.y;
o.position.xzw = origin.xzw;
outStream.Append(o);
UNITY_LOOP for (uint i = 1; i < slices; i++)
{
float sn, cs;
sincos(UNITY_PI / slices * i, sn, cs);
// Right side vertex
o.position.xy = origin.xy + extent * float2(sn, cs);
outStream.Append(o);
// Left side vertex
o.position.x = origin.x - extent.x * sn;
outStream.Append(o);
}
// Bottom vertex
o.position.x = origin.x;
o.position.y = origin.y - extent.y;
outStream.Append(o);
outStream.RestartStrip();
}
half4 Fragment(Varyings input) : SV_Target
{
#if PCX_SHADOW_CASTER
return 0;
#else
half4 c = half4(input.color, _Tint.a);
UNITY_APPLY_FOG(input.fogCoord, c);
return c;
#endif
}