fix procedural transparency

This commit is contained in:
SamGondelman 2016-08-10 13:49:35 -07:00
parent 9b27f8bc0f
commit d8545bc7a3
4 changed files with 26 additions and 13 deletions

View file

@ -91,11 +91,6 @@ void RenderableShapeEntityItem::render(RenderArgs* args) {
_procedural.reset(new Procedural(getUserData()));
_procedural->_vertexSource = simple_vert;
_procedural->_fragmentSource = simple_frag;
_procedural->_state->setCullMode(gpu::State::CULL_NONE);
_procedural->_state->setDepthTest(true, true, gpu::LESS_EQUAL);
_procedural->_state->setBlendFunction(true,
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
}
gpu::Batch& batch = *args->_batch;

View file

@ -63,7 +63,19 @@ QJsonValue Procedural::getProceduralData(const QString& proceduralJson) {
return doc.object()[PROCEDURAL_USER_DATA_KEY];
}
Procedural::Procedural() : _state { std::make_shared<gpu::State>() } {
Procedural::Procedural() {
_opaqueState->setCullMode(gpu::State::CULL_NONE);
_opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL);
_opaqueState->setBlendFunction(false,
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
_transparentState->setCullMode(gpu::State::CULL_NONE);
_transparentState->setDepthTest(true, true, gpu::LESS_EQUAL);
_transparentState->setBlendFunction(true,
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
_proceduralDataDirty = false;
}
@ -230,7 +242,7 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm
_shaderSource = _networkShader->_source;
}
if (!_pipeline || _shaderDirty) {
if (!_opaquePipeline || !_transparentPipeline || _shaderDirty) {
if (!_vertexShader) {
_vertexShader = gpu::Shader::createVertex(_vertexSource);
}
@ -268,7 +280,8 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm
slotBindings.insert(gpu::Shader::Binding(std::string("iChannel3"), 3));
gpu::Shader::makeProgram(*_shader, slotBindings);
_pipeline = gpu::Pipeline::create(_shader, _state);
_opaquePipeline = gpu::Pipeline::create(_shader, _opaqueState);
_transparentPipeline = gpu::Pipeline::create(_shader, _transparentState);
for (size_t i = 0; i < NUM_STANDARD_UNIFORMS; ++i) {
const std::string& name = STANDARD_UNIFORM_NAMES[i];
_standardUniformSlots[i] = _shader->getUniforms().findLocation(name);
@ -277,7 +290,7 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm
_frameCount = 0;
}
batch.setPipeline(_pipeline);
batch.setPipeline(isFading() ? _transparentPipeline : _opaquePipeline);
if (_shaderDirty || _uniformsDirty) {
setupUniforms();

View file

@ -43,15 +43,17 @@ public:
glm::vec4 getColor(const glm::vec4& entityColor);
quint64 getFadeStartTime() { return _fadeStartTime; }
bool isFading() { return _isFading; }
bool isFading() { return _doesFade && _isFading; }
void setIsFading(bool isFading) { _isFading = isFading; }
void setDoesFade(bool doesFade) { _doesFade = doesFade; }
uint8_t _version { 1 };
std::string _vertexSource;
std::string _fragmentSource;
gpu::StatePointer _state;
gpu::StatePointer _opaqueState { std::make_shared<gpu::State>() };
gpu::StatePointer _transparentState { std::make_shared<gpu::State>() };
enum StandardUniforms {
DATE,
@ -89,7 +91,8 @@ protected:
UniformLambdas _uniforms;
int32_t _standardUniformSlots[NUM_STANDARD_UNIFORMS];
NetworkTexturePointer _channels[MAX_PROCEDURAL_TEXTURE_CHANNELS];
gpu::PipelinePointer _pipeline;
gpu::PipelinePointer _opaquePipeline;
gpu::PipelinePointer _transparentPipeline;
gpu::ShaderPointer _vertexShader;
gpu::ShaderPointer _fragmentShader;
gpu::ShaderPointer _shader;
@ -113,6 +116,7 @@ private:
quint64 _fadeStartTime;
bool _hasStartedFade { false };
bool _isFading { false };
bool _doesFade { true };
};
#endif

View file

@ -22,7 +22,8 @@ ProceduralSkybox::ProceduralSkybox() : model::Skybox() {
_procedural._vertexSource = skybox_vert;
_procedural._fragmentSource = skybox_frag;
// Adjust the pipeline state for background using the stencil test
_procedural._state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));
_procedural.setDoesFade(false);
_procedural._opaqueState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));
}
void ProceduralSkybox::clear() {