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

View file

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

View file

@ -59,6 +59,7 @@ static bool validateEmitter(const Emitter &emitter) {
switch (emitter.renderType()) { switch (emitter.renderType()) {
case Emitter::RenderType::Normal: case Emitter::RenderType::Normal:
case Emitter::RenderType::BillboardToWorldZ:
break; break;
default: default:
warn("validateEmitter: unsupported render type: " + to_string(static_cast<int>(emitter.renderType()))); 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.billboardSize = glm::vec2(_size);
locals.general.particleCenter = _absoluteTransform[3]; locals.general.particleCenter = _absoluteTransform[3];
locals.general.billboardFrame = _frame; locals.general.billboardFrame = _frame;
locals.general.billboardToWorldZ = _emitter->renderType() == Emitter::RenderType::BillboardToWorldZ;
Shaders::instance().activate(ShaderProgram::BillboardBillboard, locals); Shaders::instance().activate(ShaderProgram::BillboardBillboard, locals);