mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 20:13:09 +02:00
Add depth bias option to simple programs
Simple programs are now lazily generated and stored in a hash
This commit is contained in:
parent
d243190caf
commit
0093403bba
2 changed files with 93 additions and 44 deletions
|
@ -50,37 +50,44 @@
|
|||
|
||||
static const std::string glowIntensityShaderHandle = "glowIntensity";
|
||||
|
||||
gpu::PipelinePointer DeferredLightingEffect::getPipeline(SimpleProgramKey config) {
|
||||
auto it = _simplePrograms.find(config);
|
||||
if (it != _simplePrograms.end()) {
|
||||
return it.value();
|
||||
}
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
if (config.isCulled()) {
|
||||
state->setCullMode(gpu::State::CULL_BACK);
|
||||
} else {
|
||||
state->setCullMode(gpu::State::CULL_NONE);
|
||||
}
|
||||
state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||
if (config.hasDepthBias()) {
|
||||
state->setDepthBias(1.0f);
|
||||
state->setDepthBiasSlopeScale(1.0f);
|
||||
}
|
||||
state->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);
|
||||
|
||||
gpu::ShaderPointer program = (config.isEmissive()) ? _emissiveShader : _simpleShader;
|
||||
gpu::PipelinePointer pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state));
|
||||
_simplePrograms.insert(config, pipeline);
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) {
|
||||
auto VS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(simple_vert)));
|
||||
auto PS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(simple_textured_frag)));
|
||||
auto PSEmissive = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(simple_textured_emisive_frag)));
|
||||
|
||||
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PS));
|
||||
gpu::ShaderPointer programEmissive = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PSEmissive));
|
||||
_simpleShader = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PS));
|
||||
_emissiveShader = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PSEmissive));
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
gpu::Shader::makeProgram(*programEmissive, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setCullMode(gpu::State::CULL_BACK);
|
||||
state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||
state->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);
|
||||
|
||||
|
||||
gpu::StatePointer stateCullNone = gpu::StatePointer(new gpu::State());
|
||||
stateCullNone->setCullMode(gpu::State::CULL_NONE);
|
||||
stateCullNone->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||
stateCullNone->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);
|
||||
|
||||
_simpleProgram = gpu::PipelinePointer(gpu::Pipeline::create(program, state));
|
||||
_simpleProgramCullNone = gpu::PipelinePointer(gpu::Pipeline::create(program, stateCullNone));
|
||||
_simpleProgramEmissive = gpu::PipelinePointer(gpu::Pipeline::create(programEmissive, state));
|
||||
_simpleProgramEmissiveCullNone = gpu::PipelinePointer(gpu::Pipeline::create(programEmissive, stateCullNone));
|
||||
gpu::Shader::makeProgram(*_simpleShader, slotBindings);
|
||||
gpu::Shader::makeProgram(*_emissiveShader, slotBindings);
|
||||
|
||||
_viewState = viewState;
|
||||
loadLightProgram(directional_light_frag, false, _directionalLight, _directionalLightLocations);
|
||||
|
@ -117,21 +124,12 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) {
|
|||
lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset(_ambientLightMode % gpu::SphericalHarmonics::NUM_PRESET));
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled, bool emmisive) {
|
||||
if (emmisive) {
|
||||
if (culled) {
|
||||
batch.setPipeline(_simpleProgramEmissive);
|
||||
} else {
|
||||
batch.setPipeline(_simpleProgramEmissiveCullNone);
|
||||
}
|
||||
} else {
|
||||
if (culled) {
|
||||
batch.setPipeline(_simpleProgram);
|
||||
} else {
|
||||
batch.setPipeline(_simpleProgramCullNone);
|
||||
}
|
||||
}
|
||||
if (!textured) {
|
||||
void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled,
|
||||
bool emmisive, bool depthBias) {
|
||||
SimpleProgramKey config{textured, culled, emmisive, depthBias};
|
||||
batch.setPipeline(getPipeline(config));
|
||||
|
||||
if (!config.isTextured()) {
|
||||
// If it is not textured, bind white texture and keep using textured pipeline
|
||||
batch.setUniformTexture(0, DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
class AbstractViewStateInterface;
|
||||
class RenderArgs;
|
||||
class SimpleProgramKey;
|
||||
|
||||
/// Handles deferred lighting for the bits that require it (voxels...)
|
||||
class DeferredLightingEffect : public Dependency {
|
||||
|
@ -34,7 +35,8 @@ public:
|
|||
void init(AbstractViewStateInterface* viewState);
|
||||
|
||||
/// Sets up the state necessary to render static untextured geometry with the simple program.
|
||||
void bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true, bool emmisive = false);
|
||||
void bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true,
|
||||
bool emmisive = false, bool depthBias = false);
|
||||
|
||||
//// Renders a solid sphere with the simple program.
|
||||
void renderSolidSphere(gpu::Batch& batch, float radius, int slices, int stacks, const glm::vec4& color);
|
||||
|
@ -95,11 +97,11 @@ private:
|
|||
};
|
||||
|
||||
static void loadLightProgram(const char* fragSource, bool limited, ProgramObject& program, LightLocations& locations);
|
||||
gpu::PipelinePointer getPipeline(SimpleProgramKey config);
|
||||
|
||||
gpu::PipelinePointer _simpleProgram;
|
||||
gpu::PipelinePointer _simpleProgramCullNone;
|
||||
gpu::PipelinePointer _simpleProgramEmissive;
|
||||
gpu::PipelinePointer _simpleProgramEmissiveCullNone;
|
||||
gpu::ShaderPointer _simpleShader;
|
||||
gpu::ShaderPointer _emissiveShader;
|
||||
QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms;
|
||||
|
||||
ProgramObject _directionalSkyboxLight;
|
||||
LightLocations _directionalSkyboxLightLocations;
|
||||
|
@ -160,4 +162,53 @@ private:
|
|||
model::SkyboxPointer _skybox;
|
||||
};
|
||||
|
||||
class SimpleProgramKey {
|
||||
public:
|
||||
enum FlagBit {
|
||||
IS_TEXTURED_FLAG = 0,
|
||||
IS_CULLED_FLAG,
|
||||
IS_EMISSIVE_FLAG,
|
||||
HAS_DEPTH_BIAS_FLAG,
|
||||
|
||||
NUM_FLAGS,
|
||||
};
|
||||
|
||||
enum Flag {
|
||||
IS_TEXTURED = (1 << IS_TEXTURED_FLAG),
|
||||
IS_CULLED = (1 << IS_CULLED_FLAG),
|
||||
IS_EMISSIVE = (1 << IS_EMISSIVE_FLAG),
|
||||
HAS_DEPTH_BIAS = (1 << HAS_DEPTH_BIAS_FLAG),
|
||||
};
|
||||
typedef unsigned short Flags;
|
||||
|
||||
bool isFlag(short flagNum) const { return bool((_flags & flagNum) != 0); }
|
||||
|
||||
bool isTextured() const { return isFlag(IS_TEXTURED); }
|
||||
bool isCulled() const { return isFlag(IS_CULLED); }
|
||||
bool isEmissive() const { return isFlag(IS_EMISSIVE); }
|
||||
bool hasDepthBias() const { return isFlag(HAS_DEPTH_BIAS); }
|
||||
|
||||
Flags _flags = 0;
|
||||
short _spare = 0;
|
||||
|
||||
int getRaw() const { return *reinterpret_cast<const int*>(this); }
|
||||
|
||||
|
||||
SimpleProgramKey(bool textured = false, bool culled = true,
|
||||
bool emissive = false, bool depthBias = false) {
|
||||
_flags = (textured ? IS_TEXTURED : 0) | (culled ? IS_CULLED : 0) |
|
||||
(emissive ? IS_EMISSIVE : 0) | (depthBias ? HAS_DEPTH_BIAS : 0);
|
||||
}
|
||||
|
||||
SimpleProgramKey(int bitmask) : _flags(bitmask) {}
|
||||
};
|
||||
|
||||
inline uint qHash(const SimpleProgramKey& key, uint seed) {
|
||||
return qHash(key.getRaw(), seed);
|
||||
}
|
||||
|
||||
inline bool operator==(const SimpleProgramKey& a, const SimpleProgramKey& b) {
|
||||
return a.getRaw() == b.getRaw();
|
||||
}
|
||||
|
||||
#endif // hifi_DeferredLightingEffect_h
|
||||
|
|
Loading…
Reference in a new issue