feat: Implement BillboardToWorldZ emitters

This commit is contained in:
Vsevolod Kremianskii 2021-01-11 20:26:16 +07:00
parent f051c2988a
commit 24f2f51d8f
4 changed files with 24 additions and 7 deletions

View file

@ -76,6 +76,7 @@ layout(std140) uniform General {
uniform vec2 uBillboardSize;
uniform vec4 uParticleCenter;
uniform int uBillboardFrame;
uniform bool uBillboardToWorldZ;
};
layout(std140) uniform Lighting {
@ -165,6 +166,9 @@ void main() {
)END";
static const GLchar kSourceVertexBillboard[] = R"END(
const vec3 RIGHT = vec3(1.0, 0.0, 0.0);
const vec3 FORWARD = vec3(0.0, 1.0, 0.0);
uniform mat4 uProjection;
uniform mat4 uView;
@ -174,13 +178,23 @@ layout(location = 2) in vec2 aTexCoords;
out vec2 fragTexCoords;
void main() {
vec3 cameraRight = vec3(uView[0][0], uView[1][0], uView[2][0]);
vec3 cameraUp = vec3(uView[0][1], uView[1][1], uView[2][1]);
vec3 position;
vec3 position =
uParticleCenter.xyz +
cameraRight * aPosition.x * uBillboardSize.x +
cameraUp * aPosition.y * uBillboardSize.y;
if (uBillboardToWorldZ) {
position =
uParticleCenter.xyz +
RIGHT * aPosition.x * uBillboardSize.x +
FORWARD * aPosition.y * uBillboardSize.y;
} else {
vec3 cameraRight = vec3(uView[0][0], uView[1][0], uView[2][0]);
vec3 cameraUp = vec3(uView[0][1], uView[1][1], uView[2][1]);
position =
uParticleCenter.xyz +
cameraRight * aPosition.x * uBillboardSize.x +
cameraUp * aPosition.y * uBillboardSize.y;
}
gl_Position = uProjection * uView * vec4(position, 1.0);
fragTexCoords = aTexCoords;

View file

@ -93,7 +93,8 @@ struct GeneralUniforms {
glm::vec2 billboardSize { 0.0f };
glm::vec4 particleCenter { 0.0f };
int billboardFrame { 0 };
char padding3[12];
int billboardToWorldZ { 0 };
char padding3[8];
};
struct SkeletalUniforms {

View file

@ -59,6 +59,7 @@ static bool validateEmitter(const Emitter &emitter) {
switch (emitter.renderType()) {
case Emitter::RenderType::Normal:
case Emitter::RenderType::BillboardToWorldZ:
break;
default:
warn("validateEmitter: unsupported render type: " + to_string(static_cast<int>(emitter.renderType())));

View file

@ -103,6 +103,7 @@ void ParticleSceneNode::renderSingle(bool shadowPass) const {
locals.general.billboardSize = glm::vec2(_size);
locals.general.particleCenter = _absoluteTransform[3];
locals.general.billboardFrame = _frame;
locals.general.billboardToWorldZ = _emitter->renderType() == Emitter::RenderType::BillboardToWorldZ;
Shaders::instance().activate(ShaderProgram::BillboardBillboard, locals);