Enable back-face culling when rendering scene

This is in line with how vanilla does it. While at it:

- Replace ambigous rotations in Control with separate meshes
- Draw blur and result in WorldRenderPipeline using NDC quads
This commit is contained in:
Vsevolod Kremianskii 2021-05-04 09:12:36 +07:00
parent d78bd29e6d
commit ea4b444af8
10 changed files with 59 additions and 90 deletions

View file

@ -293,8 +293,6 @@ void Control::drawBorder(const Border &border, const glm::ivec2 &offset, const g
glm::mat4 transform(1.0f);
transform = glm::translate(transform, glm::vec3(x, y, 0.0f));
transform = glm::scale(transform, glm::vec3(border.dimension, height, 1.0f));
transform = glm::rotate(transform, glm::half_pi<float>(), glm::vec3(0.0f, 0.0f, 1.0f));
transform = glm::rotate(transform, glm::pi<float>(), glm::vec3(1.0f, 0.0f, 0.0f));
ShaderUniforms uniforms;
uniforms.combined.general.projection = Window::instance().getOrthoProjection();
@ -302,15 +300,14 @@ void Control::drawBorder(const Border &border, const glm::ivec2 &offset, const g
uniforms.combined.general.color = glm::vec4(color, 1.0f);
Shaders::instance().activate(ShaderProgram::SimpleGUI, uniforms);
Meshes::instance().getQuad()->draw();
Meshes::instance().getQuadSwapFlipX()->draw();
}
// Right edge
{
glm::mat4 transform(1.0f);
transform = glm::translate(transform, glm::vec3(x + size.x, y, 0.0f));
transform = glm::translate(transform, glm::vec3(x + size.x - border.dimension, y, 0.0f));
transform = glm::scale(transform, glm::vec3(border.dimension, height, 1.0f));
transform = glm::rotate(transform, glm::half_pi<float>(), glm::vec3(0.0f, 0.0f, 1.0f));
ShaderUniforms uniforms;
uniforms.combined.general.projection = Window::instance().getOrthoProjection();
@ -318,7 +315,7 @@ void Control::drawBorder(const Border &border, const glm::ivec2 &offset, const g
uniforms.combined.general.color = glm::vec4(color, 1.0f);
Shaders::instance().activate(ShaderProgram::SimpleGUI, uniforms);
Meshes::instance().getQuadFlipX()->draw();
Meshes::instance().getQuadSwap()->draw();
}
}

View file

@ -56,6 +56,20 @@ static const vector<float> g_quadFlipXYVertices {
0.0f, 1.0f, 0.0f, 1.0f, 1.0f
};
static const vector<float> g_quadSwapVertices {
0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 0.0f, 0.0f
};
static const vector<float> g_quadSwapFlipXVertices {
0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
static const vector<float> g_quadNDCVertices {
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
@ -63,6 +77,13 @@ static const vector<float> g_quadNDCVertices {
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f
};
static const vector<float> g_quadNDCFlipYVertices {
-1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 0.0f, 1.0f
};
static const vector<float> g_billboardVertices = {
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
@ -258,7 +279,10 @@ void Meshes::init() {
_quadFlipX = getMesh(4, g_quadFlipXVertices, g_quadIndices, g_quadOffsets);
_quadFlipY = getMesh(4, g_quadFlipYVertices, g_quadIndices, g_quadOffsets);
_quadFlipXY = getMesh(4, g_quadFlipXYVertices, g_quadIndices, g_quadOffsets);
_quadSwap = getMesh(4, g_quadSwapVertices, g_quadIndices, g_quadOffsets);
_quadSwapFlipX = getMesh(4, g_quadSwapFlipXVertices, g_quadIndices, g_quadOffsets);
_quadNDC = getMesh(4, g_quadNDCVertices, g_quadIndices, g_quadOffsets);
_quadNDCFlipY = getMesh(4, g_quadNDCFlipYVertices, g_quadIndices, g_quadOffsets);
_billboard = getMesh(4, g_billboardVertices, g_quadIndices, g_quadOffsets);
_grass = getMesh(4, g_grassVertices, g_quadIndices, g_quadOffsets);
_cube = getMesh(8, g_cubeVertices, g_cubeIndices, g_cubeOffsets);

View file

@ -43,7 +43,10 @@ public:
std::shared_ptr<Mesh> getQuadFlipX() const { return _quadFlipX; }
std::shared_ptr<Mesh> getQuadFlipY() const { return _quadFlipY; }
std::shared_ptr<Mesh> getQuadFlipXY() const { return _quadFlipXY; }
std::shared_ptr<Mesh> getQuadSwap() const { return _quadSwap; }
std::shared_ptr<Mesh> getQuadSwapFlipX() const { return _quadSwapFlipX; }
std::shared_ptr<Mesh> getQuadNDC() const { return _quadNDC; }
std::shared_ptr<Mesh> getQuadNDCFlipY() const { return _quadNDCFlipY; }
std::shared_ptr<Mesh> getBillboard() const { return _billboard; }
std::shared_ptr<Mesh> getGrass() const { return _grass; }
std::shared_ptr<Mesh> getCube() const { return _cube; }
@ -58,7 +61,10 @@ private:
std::shared_ptr<Mesh> _quadFlipX;
std::shared_ptr<Mesh> _quadFlipY;
std::shared_ptr<Mesh> _quadFlipXY;
std::shared_ptr<Mesh> _quadSwap;
std::shared_ptr<Mesh> _quadSwapFlipX;
std::shared_ptr<Mesh> _quadNDC;
std::shared_ptr<Mesh> _quadNDCFlipY;
std::shared_ptr<Mesh> _billboard;
std::shared_ptr<Mesh> _grass;
std::shared_ptr<Mesh> _cube;

View file

@ -1157,29 +1157,6 @@ void main() {
}
)END";
static constexpr GLchar kShaderFragmentDebugCubeMap[] = R"END(
const bool RGB = true;
//uniform sampler2D uDiffuse;
uniform samplerCube uDiffuse;
in vec2 fragTexCoords;
out vec4 fragColor;
void main() {
vec2 cubeMapCoords = 2.0 * fragTexCoords - 1.0;
vec4 diffuseSample = texture(uDiffuse, vec3(cubeMapCoords.x, -1.0, -cubeMapCoords.y));
//vec4 diffuseSample = texture(uDiffuse, fragTexCoords);
if (RGB) {
fragColor = vec4(diffuseSample.rgb, 1.0);
} else {
fragColor = vec4(vec3(diffuseSample.r), 1.0);
}
}
)END";
Shaders &Shaders::instance() {
static Shaders instance;
return instance;
@ -1208,7 +1185,6 @@ void Shaders::init() {
initShader(ShaderName::FragmentBRDF, GL_FRAGMENT_SHADER, { kShaderBaseHeader, kShaderBasePBR, kShaderBasePBRIBL, kShaderFragmentBRDF });
initShader(ShaderName::FragmentBlur, GL_FRAGMENT_SHADER, { kShaderBaseHeader, kShaderFragmentBlur });
initShader(ShaderName::FragmentPresentWorld, GL_FRAGMENT_SHADER, { kShaderBaseHeader, kShaderFragmentPresentWorld });
initShader(ShaderName::FragmentDebugCubeMap, GL_FRAGMENT_SHADER, { kShaderBaseHeader, kShaderFragmentDebugCubeMap });
initProgram(ShaderProgram::SimpleColor, { ShaderName::VertexSimple, ShaderName::FragmentColor });
initProgram(ShaderProgram::SimpleDepth, { ShaderName::VertexSimple, ShaderName::GeometryDepth, ShaderName::FragmentDepth });
@ -1218,7 +1194,6 @@ void Shaders::init() {
initProgram(ShaderProgram::SimpleBRDF, { ShaderName::VertexSimple, ShaderName::FragmentBRDF });
initProgram(ShaderProgram::SimpleBlur, { ShaderName::VertexSimple, ShaderName::FragmentBlur });
initProgram(ShaderProgram::SimplePresentWorld, { ShaderName::VertexSimple, ShaderName::FragmentPresentWorld });
initProgram(ShaderProgram::SimpleDebugCubeMap, { ShaderName::VertexSimple, ShaderName::FragmentDebugCubeMap });
initProgram(ShaderProgram::ModelColor, { ShaderName::VertexModel, ShaderName::FragmentColor });
initProgram(ShaderProgram::ModelBlinnPhong, { ShaderName::VertexModel, ShaderName::FragmentBlinnPhong });
initProgram(ShaderProgram::ModelPBR, { ShaderName::VertexModel, ShaderName::FragmentPBR });

View file

@ -44,7 +44,6 @@ enum class ShaderProgram {
SimpleBRDF,
SimpleBlur,
SimplePresentWorld,
SimpleDebugCubeMap,
ModelColor,
ModelBlinnPhong,
ModelPBR,
@ -240,8 +239,7 @@ private:
FragmentPrefilter,
FragmentBRDF,
FragmentBlur,
FragmentPresentWorld,
FragmentDebugCubeMap
FragmentPresentWorld
};
bool _inited { false };

View file

@ -76,6 +76,12 @@ void withAdditiveBlending(const function<void()> &block) {
withBlending(GL_SRC_ALPHA, GL_ONE, GL_SRC_ALPHA, GL_ONE, block);
}
void withBackFaceCulling(const function<void()> &block) {
glEnable(GL_CULL_FACE);
block();
glDisable(GL_CULL_FACE);
}
void setActiveTextureUnit(int n) {
glActiveTexture(GL_TEXTURE0 + n);
}

View file

@ -34,6 +34,7 @@ void withViewport(const glm::ivec4 &viewport, const std::function<void()> &block
void withScissorTest(const glm::ivec4 &bounds, const std::function<void()> &block);
void withDepthTest(const std::function<void()> &block);
void withAdditiveBlending(const std::function<void()> &block);
void withBackFaceCulling(const std::function<void()> &block);
void setActiveTextureUnit(int n);

View file

@ -59,7 +59,7 @@ void LightSceneNode::drawLensFlares(const LensFlare &flare) {
Shaders::instance().activate(ShaderProgram::BillboardGUI, uniforms);
withAdditiveBlending([]() {
Meshes::instance().getQuadNDC()->draw();
Meshes::instance().getBillboard()->draw();
});
}

View file

@ -48,7 +48,6 @@ const float kShadowFarPlane = 10000.0f;
const float kOrthographicScale = 10.0f;
static bool g_wireframesEnabled = false;
static bool g_debugCubeMap = false;
WorldRenderPipeline::WorldRenderPipeline(SceneGraph *scene, const GraphicsOptions &opts) :
_scene(scene), _opts(opts) {
@ -135,8 +134,12 @@ void WorldRenderPipeline::init() {
void WorldRenderPipeline::render() {
computeLightSpaceMatrices();
drawShadows();
drawGeometry();
withBackFaceCulling([this]() {
drawShadows();
drawGeometry();
});
applyHorizontalBlur();
applyVerticalBlur();
drawResult();
@ -281,20 +284,15 @@ void WorldRenderPipeline::applyHorizontalBlur() {
setActiveTextureUnit(TextureUnits::diffuse);
_geometryColor2->bind();
glm::mat4 transform(1.0f);
transform = glm::scale(transform, glm::vec3(w, h, 1.0f));
ShaderUniforms uniforms;
uniforms.combined.featureMask |= UniformFeatureFlags::blur;
uniforms.combined.general.projection = Window::instance().getOrthoProjection();
uniforms.combined.general.model = move(transform);
uniforms.combined.blur.resolution = glm::vec2(w, h);
uniforms.combined.blur.direction = glm::vec2(1.0f, 0.0f);
Shaders::instance().activate(ShaderProgram::SimpleBlur, uniforms);
withDepthTest([]() {
Meshes::instance().getQuad()->draw();
Meshes::instance().getQuadNDC()->draw();
});
}
@ -309,64 +307,30 @@ void WorldRenderPipeline::applyVerticalBlur() {
setActiveTextureUnit(TextureUnits::diffuse);
_horizontalBlurColor->bind();
glm::mat4 transform(1.0f);
transform = glm::scale(transform, glm::vec3(w, h, 1.0f));
ShaderUniforms uniforms;
uniforms.combined.featureMask |= UniformFeatureFlags::blur;
uniforms.combined.general.projection = Window::instance().getOrthoProjection();
uniforms.combined.general.model = move(transform);
uniforms.combined.blur.resolution = glm::vec2(_opts.width, _opts.height);
uniforms.combined.blur.resolution = glm::vec2(w, h);
uniforms.combined.blur.direction = glm::vec2(0.0f, 1.0f);
Shaders::instance().activate(ShaderProgram::SimpleBlur, uniforms);
withDepthTest([]() {
Meshes::instance().getQuad()->draw();
Meshes::instance().getQuadNDC()->draw();
});
_verticalBlur.unbind();
}
void WorldRenderPipeline::drawResult() {
float w = static_cast<float>(_opts.width);
float h = static_cast<float>(_opts.height);
setActiveTextureUnit(TextureUnits::diffuse);
_geometryColor1->bind();
glm::mat4 transform(1.0f);
transform = glm::scale(transform, glm::vec3(w, h, 1.0f));
setActiveTextureUnit(TextureUnits::bloom);
_verticalBlurColor->bind();
if (g_debugCubeMap) {
setActiveTextureUnit(TextureUnits::diffuse);
auto envmap = Textures::instance().get("cm_baremetal", TextureUsage::EnvironmentMap);
PBRIBL::Derived derived;
if (PBRIBL::instance().getDerived(envmap.get(), derived)) {
derived.brdfLookup->bind();
} else {
envmap->bind();
}
//_shadowsDepth->bind();
ShaderUniforms uniforms;
uniforms.combined.general.projection = Window::instance().getOrthoProjection();
uniforms.combined.general.model = move(transform);
Shaders::instance().activate(ShaderProgram::SimpleDebugCubeMap, uniforms);
Meshes::instance().getQuad()->draw();
} else {
setActiveTextureUnit(TextureUnits::diffuse);
_geometryColor1->bind();
setActiveTextureUnit(TextureUnits::bloom);
_verticalBlurColor->bind();
ShaderUniforms uniforms;
uniforms.combined.general.projection = Window::instance().getOrthoProjection();
uniforms.combined.general.model = move(transform);
Shaders::instance().activate(ShaderProgram::SimplePresentWorld, uniforms);
Meshes::instance().getQuad()->draw();
}
ShaderUniforms uniforms;
Shaders::instance().activate(ShaderProgram::SimplePresentWorld, uniforms);
Meshes::instance().getQuadNDC()->draw();
}
} // namespace scene

View file

@ -86,10 +86,8 @@ void Video::draw() {
_texture->bind();
ShaderUniforms uniforms;
uniforms.combined.general.projection = glm::ortho(0.0f, 1.0f, 0.0f, 1.0f);
Shaders::instance().activate(ShaderProgram::SimpleGUI, uniforms);
Meshes::instance().getQuad()->draw();
Meshes::instance().getQuadNDCFlipY()->draw();
}
void Video::finish() {