mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-07-18 06:51:26 +00:00
Packs particle size and angle to axes
We need to have per-vertex data to be constant to use instancing. Now we have only UV coordinates.
This commit is contained in:
@@ -8,26 +8,37 @@
|
||||
VERTEX_INPUT_ATTRIBUTE(0, vec3, a_vertex);
|
||||
VERTEX_INPUT_ATTRIBUTE(1, vec4, a_color);
|
||||
VERTEX_INPUT_ATTRIBUTE(2, vec2, a_uv0);
|
||||
VERTEX_INPUT_ATTRIBUTE(3, vec2, a_uv1);
|
||||
VERTEX_INPUT_ATTRIBUTE(4, vec3, a_axisX);
|
||||
VERTEX_INPUT_ATTRIBUTE(5, vec3, a_axisY);
|
||||
VERTEX_INPUT_ATTRIBUTE(3, vec4, a_axisX); // .w is a particle diagonal size
|
||||
VERTEX_INPUT_ATTRIBUTE(4, vec4, a_axisY); // .w is a particle angle
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 viewAxisX = vec3(modelViewMatrix[0][0], modelViewMatrix[1][0], modelViewMatrix[2][0]);
|
||||
vec3 viewAxisY = vec3(modelViewMatrix[0][1], modelViewMatrix[1][1], modelViewMatrix[2][1]);
|
||||
vec2 offset = a_uv1;
|
||||
|
||||
vec3 axisX = (spaceTransform * vec4(a_axisX, 0.0)).xyz;
|
||||
vec3 axisY = (spaceTransform * vec4(a_axisY, 0.0)).xyz;
|
||||
const float PI_4 = 0.7853981633974483;
|
||||
const float HALF_INV_SQRT2 = 0.35355339059327376;
|
||||
float particleHalfSize = a_axisX.w * HALF_INV_SQRT2;
|
||||
// Currently we store an angle to a particle corner.
|
||||
float particleAngle = a_axisY.w - PI_4;
|
||||
float sinParticleAngle = sin(particleAngle);
|
||||
float cosParticleAngle = cos(particleAngle);
|
||||
mat2 rotationMatrix = mat2(
|
||||
cosParticleAngle, -sinParticleAngle,
|
||||
sinParticleAngle, cosParticleAngle
|
||||
);
|
||||
vec2 offset = rotationMatrix * ((a_uv0 * 2.0 - 1.0) * particleHalfSize);
|
||||
|
||||
vec3 axisX = (spaceTransform * vec4(a_axisX.xyz, 0.0)).xyz;
|
||||
vec3 axisY = (spaceTransform * vec4(a_axisY.xyz, 0.0)).xyz;
|
||||
vec3 particlePosition = (spaceTransform * vec4(a_vertex, 1.0)).xyz;
|
||||
|
||||
vec3 particleAxisX = viewAxisX;
|
||||
vec3 particleAxisY = viewAxisY;
|
||||
if (a_axisX != vec3(0.0))
|
||||
if (a_axisX.xyz != vec3(0.0))
|
||||
{
|
||||
particleAxisX = axisX;
|
||||
if (a_axisY != vec3(0.0))
|
||||
if (a_axisY.xyz != vec3(0.0))
|
||||
particleAxisY = axisY;
|
||||
else
|
||||
{
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
<stream name="pos" attribute="a_vertex"/>
|
||||
<stream name="color" attribute="a_color"/>
|
||||
<stream name="uv0" attribute="a_uv0"/>
|
||||
<stream name="uv1" attribute="a_uv1"/>
|
||||
<stream name="uv2" attribute="a_axisX"/>
|
||||
<stream name="uv3" attribute="a_axisY"/>
|
||||
<stream name="uv1" attribute="a_axisX"/>
|
||||
<stream name="uv2" attribute="a_axisY"/>
|
||||
</vertex>
|
||||
|
||||
<fragment file="glsl/particle.fs"/>
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
<stream name="pos" attribute="a_vertex"/>
|
||||
<stream name="color" attribute="a_color"/>
|
||||
<stream name="uv0" attribute="a_uv0"/>
|
||||
<stream name="uv1" attribute="a_uv1"/>
|
||||
<stream name="uv2" attribute="a_axisX"/>
|
||||
<stream name="uv3" attribute="a_axisY"/>
|
||||
<stream name="uv1" attribute="a_axisX"/>
|
||||
<stream name="uv2" attribute="a_axisY"/>
|
||||
</vertex>
|
||||
|
||||
<fragment file="glsl/particle.fs"/>
|
||||
|
||||
@@ -97,19 +97,16 @@ CParticleEmitter::CParticleEmitter(const CParticleEmitterTypePtr& type) :
|
||||
m_AttributePos.format = Renderer::Backend::Format::R32G32B32_SFLOAT;
|
||||
m_VertexArray.AddAttribute(&m_AttributePos);
|
||||
|
||||
m_AttributeAxis.format = Renderer::Backend::Format::R32G32_SFLOAT;
|
||||
m_VertexArray.AddAttribute(&m_AttributeAxis);
|
||||
|
||||
m_AttributeUV.format = Renderer::Backend::Format::R32G32_SFLOAT;
|
||||
m_VertexArray.AddAttribute(&m_AttributeUV);
|
||||
|
||||
m_AttributeColor.format = Renderer::Backend::Format::R8G8B8A8_UNORM;
|
||||
m_VertexArray.AddAttribute(&m_AttributeColor);
|
||||
|
||||
m_AttributeAxisX.format = Renderer::Backend::Format::R32G32B32_SFLOAT;
|
||||
m_AttributeAxisX.format = Renderer::Backend::Format::R32G32B32A32_SFLOAT;
|
||||
m_VertexArray.AddAttribute(&m_AttributeAxisX);
|
||||
|
||||
m_AttributeAxisY.format = Renderer::Backend::Format::R32G32B32_SFLOAT;
|
||||
m_AttributeAxisY.format = Renderer::Backend::Format::R32G32B32A32_SFLOAT;
|
||||
m_VertexArray.AddAttribute(&m_AttributeAxisY);
|
||||
|
||||
m_VertexArray.SetNumberOfVertices(m_Type->m_MaxParticles * 4);
|
||||
@@ -131,7 +128,7 @@ CParticleEmitter::CParticleEmitter(const CParticleEmitterTypePtr& type) :
|
||||
m_IndexArray.FreeBackingStore();
|
||||
|
||||
const uint32_t stride = m_VertexArray.GetStride();
|
||||
const std::array<Renderer::Backend::SVertexAttributeFormat, 6> attributes{{
|
||||
const std::array<Renderer::Backend::SVertexAttributeFormat, 5> attributes{{
|
||||
{Renderer::Backend::VertexAttributeStream::POSITION,
|
||||
m_AttributePos.format, m_AttributePos.offset, stride,
|
||||
Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0},
|
||||
@@ -142,12 +139,9 @@ CParticleEmitter::CParticleEmitter(const CParticleEmitterTypePtr& type) :
|
||||
m_AttributeUV.format, m_AttributeUV.offset, stride,
|
||||
Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0},
|
||||
{Renderer::Backend::VertexAttributeStream::UV1,
|
||||
m_AttributeAxis.format, m_AttributeAxis.offset, stride,
|
||||
Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0},
|
||||
{Renderer::Backend::VertexAttributeStream::UV2,
|
||||
m_AttributeAxisX.format, m_AttributeAxisX.offset, stride,
|
||||
Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0},
|
||||
{Renderer::Backend::VertexAttributeStream::UV3,
|
||||
{Renderer::Backend::VertexAttributeStream::UV2,
|
||||
m_AttributeAxisY.format, m_AttributeAxisY.offset, stride,
|
||||
Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0},
|
||||
}};
|
||||
@@ -173,11 +167,10 @@ void CParticleEmitter::UpdateArrayData(int frameNumber)
|
||||
// Regenerate the vertex array data:
|
||||
|
||||
VertexArrayIterator<CVector3D> attrPos = m_AttributePos.GetIterator<CVector3D>();
|
||||
VertexArrayIterator<float[2]> attrAxis = m_AttributeAxis.GetIterator<float[2]>();
|
||||
VertexArrayIterator<float[2]> attrUV = m_AttributeUV.GetIterator<float[2]>();
|
||||
VertexArrayIterator<SColor4ub> attrColor = m_AttributeColor.GetIterator<SColor4ub>();
|
||||
VertexArrayIterator<CVector3D> attrAxisX = m_AttributeAxisX.GetIterator<CVector3D>();
|
||||
VertexArrayIterator<CVector3D> attrAxisY = m_AttributeAxisY.GetIterator<CVector3D>();
|
||||
VertexArrayIterator<CVector4D> attrAxisX = m_AttributeAxisX.GetIterator<CVector4D>();
|
||||
VertexArrayIterator<CVector4D> attrAxisY = m_AttributeAxisY.GetIterator<CVector4D>();
|
||||
|
||||
ENSURE(m_Particles.size() <= m_Type->m_MaxParticles);
|
||||
|
||||
@@ -223,26 +216,6 @@ void CParticleEmitter::UpdateArrayData(int frameNumber)
|
||||
*attrPos++ = particle.pos;
|
||||
*attrPos++ = particle.pos;
|
||||
|
||||
// Compute corner offsets, split into sin/cos components so the vertex
|
||||
// shader can multiply by the camera-right (or left?) and camera-up vectors
|
||||
// to get rotating billboards:
|
||||
|
||||
float s = sin(particle.angle) * particle.size * 0.5f;
|
||||
float c = cos(particle.angle) * particle.size * 0.5f;
|
||||
|
||||
(*attrAxis)[0] = c;
|
||||
(*attrAxis)[1] = s;
|
||||
++attrAxis;
|
||||
(*attrAxis)[0] = s;
|
||||
(*attrAxis)[1] = -c;
|
||||
++attrAxis;
|
||||
(*attrAxis)[0] = -c;
|
||||
(*attrAxis)[1] = -s;
|
||||
++attrAxis;
|
||||
(*attrAxis)[0] = -s;
|
||||
(*attrAxis)[1] = c;
|
||||
++attrAxis;
|
||||
|
||||
(*attrUV)[0] = 1;
|
||||
(*attrUV)[1] = 0;
|
||||
++attrUV;
|
||||
@@ -273,15 +246,20 @@ void CParticleEmitter::UpdateArrayData(int frameNumber)
|
||||
*attrColor++ = color;
|
||||
*attrColor++ = color;
|
||||
|
||||
*attrAxisX++ = particle.axisX;
|
||||
*attrAxisX++ = particle.axisX;
|
||||
*attrAxisX++ = particle.axisX;
|
||||
*attrAxisX++ = particle.axisX;
|
||||
const CVector4D axisXAndSize{
|
||||
particle.axisX.X, particle.axisX.Y, particle.axisX.Z, particle.size};
|
||||
const CVector4D axisYAndAngle{
|
||||
particle.axisY.X, particle.axisY.Y, particle.axisY.Z, particle.angle};
|
||||
|
||||
*attrAxisY++ = particle.axisY;
|
||||
*attrAxisY++ = particle.axisY;
|
||||
*attrAxisY++ = particle.axisY;
|
||||
*attrAxisY++ = particle.axisY;
|
||||
*attrAxisX++ = axisXAndSize;
|
||||
*attrAxisX++ = axisXAndSize;
|
||||
*attrAxisX++ = axisXAndSize;
|
||||
*attrAxisX++ = axisXAndSize;
|
||||
|
||||
*attrAxisY++ = axisYAndAngle;
|
||||
*attrAxisY++ = axisYAndAngle;
|
||||
*attrAxisY++ = axisYAndAngle;
|
||||
*attrAxisY++ = axisYAndAngle;
|
||||
}
|
||||
|
||||
m_ParticleBounds = bounds;
|
||||
|
||||
@@ -186,7 +186,6 @@ private:
|
||||
|
||||
VertexArray m_VertexArray;
|
||||
VertexArray::Attribute m_AttributePos;
|
||||
VertexArray::Attribute m_AttributeAxis;
|
||||
VertexArray::Attribute m_AttributeUV;
|
||||
VertexArray::Attribute m_AttributeColor;
|
||||
VertexArray::Attribute m_AttributeAxisX, m_AttributeAxisY;
|
||||
|
||||
Reference in New Issue
Block a user