mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 10:07:58 +02:00
support opaque (and black) particles
This commit is contained in:
parent
22faf211bf
commit
3daa40087e
4 changed files with 49 additions and 28 deletions
|
@ -21,23 +21,35 @@ using namespace render::entities;
|
||||||
|
|
||||||
static uint8_t CUSTOM_PIPELINE_NUMBER = 0;
|
static uint8_t CUSTOM_PIPELINE_NUMBER = 0;
|
||||||
static gpu::Stream::FormatPointer _vertexFormat;
|
static gpu::Stream::FormatPointer _vertexFormat;
|
||||||
static std::weak_ptr<gpu::Pipeline> _texturedPipeline;
|
static std::map<std::tuple<bool, bool>, gpu::PipelinePointer> _pipelines;
|
||||||
|
|
||||||
static ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const ShapeKey& key, RenderArgs* args) {
|
static ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const ShapeKey& key, RenderArgs* args) {
|
||||||
auto texturedPipeline = _texturedPipeline.lock();
|
// FIXME: custom pipelines like this don't handle shadows or renderLayers correctly
|
||||||
if (!texturedPipeline) {
|
|
||||||
auto state = std::make_shared<gpu::State>();
|
|
||||||
state->setCullMode(gpu::State::CULL_BACK);
|
|
||||||
state->setDepthTest(true, false, gpu::LESS_EQUAL);
|
|
||||||
state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE,
|
|
||||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
|
||||||
PrepareStencil::testMask(*state);
|
|
||||||
|
|
||||||
auto program = gpu::Shader::createProgram(shader::entities_renderer::program::textured_particle);
|
if (_pipelines.empty()) {
|
||||||
_texturedPipeline = texturedPipeline = gpu::Pipeline::create(program, state);
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
bool transparent = (i % 2 == 0);
|
||||||
|
bool wireframe = (i / 2) == 0;
|
||||||
|
|
||||||
|
auto state = std::make_shared<gpu::State>();
|
||||||
|
state->setCullMode(gpu::State::CULL_BACK);
|
||||||
|
|
||||||
|
if (wireframe) {
|
||||||
|
state->setFillMode(gpu::State::FILL_LINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
state->setDepthTest(true, !transparent, gpu::LESS_EQUAL);
|
||||||
|
state->setBlendFunction(transparent, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE,
|
||||||
|
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||||
|
transparent ? PrepareStencil::testMask(*state) : PrepareStencil::testMaskDrawShape(*state);
|
||||||
|
|
||||||
|
auto program = gpu::Shader::createProgram(transparent ? shader::entities_renderer::program::textured_particle_translucent :
|
||||||
|
shader::entities_renderer::program::textured_particle);
|
||||||
|
_pipelines[std::make_tuple(transparent, wireframe)] = gpu::Pipeline::create(program, state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_shared<render::ShapePipeline>(texturedPipeline, nullptr, nullptr, nullptr);
|
return std::make_shared<render::ShapePipeline>(_pipelines[std::make_tuple(key.isTranslucent(), key.isWireframe())], nullptr, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GpuParticle {
|
struct GpuParticle {
|
||||||
|
@ -138,26 +150,25 @@ void ParticleEffectEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEn
|
||||||
_uniformBuffer.edit<ParticleUniforms>() = particleUniforms;
|
_uniformBuffer.edit<ParticleUniforms>() = particleUniforms;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemKey ParticleEffectEntityRenderer::getKey() {
|
bool ParticleEffectEntityRenderer::isTransparent() const {
|
||||||
// FIXME: implement isTransparent() for particles and an opaque pipeline
|
bool particleTransparent = _particleProperties.getColorStart().a < 1.0f || _particleProperties.getColorMiddle().a < 1.0f ||
|
||||||
auto builder = ItemKey::Builder::transparentShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
|
_particleProperties.getColorFinish().a < 1.0f || _particleProperties.getColorSpread().a > 0.0f ||
|
||||||
|
_pulseProperties.getAlphaMode() != PulseMode::NONE || (_textureLoaded && _networkTexture && _networkTexture->getGPUTexture() &&
|
||||||
if (!_visible) {
|
_networkTexture->getGPUTexture()->getUsage().isAlpha() && !_networkTexture->getGPUTexture()->getUsage().isAlphaMask());
|
||||||
builder.withInvisible();
|
return particleTransparent || Parent::isTransparent();
|
||||||
}
|
|
||||||
|
|
||||||
if (_cullWithParent) {
|
|
||||||
builder.withSubMetaCulled();
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeKey ParticleEffectEntityRenderer::getShapeKey() {
|
ShapeKey ParticleEffectEntityRenderer::getShapeKey() {
|
||||||
auto builder = ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER).withTranslucent();
|
auto builder = ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER);
|
||||||
|
|
||||||
|
if (isTransparent()) {
|
||||||
|
builder.withTranslucent();
|
||||||
|
}
|
||||||
|
|
||||||
if (_primitiveMode == PrimitiveMode::LINES) {
|
if (_primitiveMode == PrimitiveMode::LINES) {
|
||||||
builder.withWireframe();
|
builder.withWireframe();
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ protected:
|
||||||
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
|
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
|
||||||
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
|
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
|
||||||
|
|
||||||
virtual ItemKey getKey() override;
|
bool isTransparent() const override;
|
||||||
virtual ShapeKey getShapeKey() override;
|
virtual ShapeKey getShapeKey() override;
|
||||||
virtual Item::Bound getBound(RenderArgs* args) override;
|
virtual Item::Bound getBound(RenderArgs* args) override;
|
||||||
virtual void doRender(RenderArgs* args) override;
|
virtual void doRender(RenderArgs* args) override;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
DEFINES translucent:f
|
|
@ -18,5 +18,14 @@ layout(location=1) in vec2 varTexcoord;
|
||||||
layout(location=0) out vec4 outFragColor;
|
layout(location=0) out vec4 outFragColor;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
outFragColor = texture(colorMap, varTexcoord.xy) * varColor;
|
vec4 albedo = texture(colorMap, varTexcoord.xy) * varColor;
|
||||||
|
|
||||||
|
<@if not HIFI_USE_TRANSLUCENT@>
|
||||||
|
// to reduce texel flickering for floating point error we discard when alpha is "almost one"
|
||||||
|
if (albedo.a < 0.999999) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
<@endif@>
|
||||||
|
|
||||||
|
outFragColor = albedo;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue