mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 04:53:25 +02:00
Fix the skybox color issue with background rendering when no texture is there
This commit is contained in:
parent
6b86f21491
commit
be9b244779
2 changed files with 69 additions and 54 deletions
|
@ -45,11 +45,18 @@ void Skybox::setCubemap(const gpu::TexturePointer& cubemap) {
|
||||||
|
|
||||||
|
|
||||||
void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) {
|
void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) {
|
||||||
|
const int VERTICES_SLOT = 0;
|
||||||
|
const int COLOR_SLOT = 1;
|
||||||
|
|
||||||
|
// Create the static shared elements used to render the skybox
|
||||||
static gpu::BufferPointer theBuffer;
|
static gpu::BufferPointer theBuffer;
|
||||||
static gpu::Stream::FormatPointer theFormat;
|
static gpu::Stream::FormatPointer theFormat;
|
||||||
|
static gpu::BufferPointer theConstants;
|
||||||
if (skybox.getCubemap()) {
|
static gpu::PipelinePointer thePipeline;
|
||||||
if (!theBuffer) {
|
static int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader
|
||||||
|
static std::once_flag once;
|
||||||
|
std::call_once(once, [&] {
|
||||||
|
{
|
||||||
const float CLIP = 1.0f;
|
const float CLIP = 1.0f;
|
||||||
const glm::vec2 vertices[4] = { { -CLIP, -CLIP }, { CLIP, -CLIP }, { -CLIP, CLIP }, { CLIP, CLIP } };
|
const glm::vec2 vertices[4] = { { -CLIP, -CLIP }, { CLIP, -CLIP }, { -CLIP, CLIP }, { CLIP, CLIP } };
|
||||||
theBuffer = std::make_shared<gpu::Buffer>(sizeof(vertices), (const gpu::Byte*) vertices);
|
theBuffer = std::make_shared<gpu::Buffer>(sizeof(vertices), (const gpu::Byte*) vertices);
|
||||||
|
@ -57,63 +64,65 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky
|
||||||
theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ));
|
theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 projMat;
|
{
|
||||||
viewFrustum.evalProjectionMatrix(projMat);
|
auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert)));
|
||||||
|
auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag)));
|
||||||
|
auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS));
|
||||||
|
|
||||||
Transform viewTransform;
|
gpu::Shader::BindingSet bindings;
|
||||||
viewFrustum.evalViewTransform(viewTransform);
|
bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0));
|
||||||
batch.setProjectionTransform(projMat);
|
if (!gpu::Shader::makeProgram(*skyShader, bindings)) {
|
||||||
batch.setViewTransform(viewTransform);
|
|
||||||
batch.setModelTransform(Transform()); // only for Mac
|
|
||||||
batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8);
|
|
||||||
batch.setInputFormat(theFormat);
|
|
||||||
|
|
||||||
if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) {
|
|
||||||
static gpu::BufferPointer theConstants;
|
|
||||||
static gpu::PipelinePointer thePipeline;
|
|
||||||
static int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader
|
|
||||||
if (!thePipeline) {
|
|
||||||
auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert)));
|
|
||||||
auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag)));
|
|
||||||
auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS));
|
|
||||||
|
|
||||||
gpu::Shader::BindingSet bindings;
|
|
||||||
bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0));
|
|
||||||
if (!gpu::Shader::makeProgram(*skyShader, bindings)) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
SKYBOX_CONSTANTS_SLOT = skyShader->getBuffers().findLocation("skyboxBuffer");
|
|
||||||
if (SKYBOX_CONSTANTS_SLOT == gpu::Shader::INVALID_LOCATION) {
|
|
||||||
SKYBOX_CONSTANTS_SLOT = skyShader->getUniforms().findLocation("skyboxBuffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto skyState = std::make_shared<gpu::State>();
|
|
||||||
skyState->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));
|
|
||||||
|
|
||||||
thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState));
|
|
||||||
|
|
||||||
auto color = glm::vec4(1.0f);
|
|
||||||
theConstants = std::make_shared<gpu::Buffer>(sizeof(color), (const gpu::Byte*) &color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glm::all(glm::equal(skybox.getColor(), glm::vec3(0.0f)))) {
|
SKYBOX_CONSTANTS_SLOT = skyShader->getBuffers().findLocation("skyboxBuffer");
|
||||||
auto color = glm::vec4(1.0f);
|
if (SKYBOX_CONSTANTS_SLOT == gpu::Shader::INVALID_LOCATION) {
|
||||||
theConstants->setSubData(0, sizeof(color), (const gpu::Byte*) &color);
|
SKYBOX_CONSTANTS_SLOT = skyShader->getUniforms().findLocation("skyboxBuffer");
|
||||||
} else {
|
|
||||||
theConstants->setSubData(0, sizeof(Color), (const gpu::Byte*) &skybox.getColor());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
batch.setPipeline(thePipeline);
|
auto skyState = std::make_shared<gpu::State>();
|
||||||
batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize());
|
skyState->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));
|
||||||
batch.setResourceTexture(0, skybox.getCubemap());
|
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState));
|
||||||
|
|
||||||
|
auto color = glm::vec4(1.0f);
|
||||||
|
theConstants = std::make_shared<gpu::Buffer>(sizeof(color), (const gpu::Byte*) &color);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
} else {
|
// Render
|
||||||
// skybox has no cubemap, just clear the color buffer
|
glm::mat4 projMat;
|
||||||
auto color = skybox.getColor();
|
viewFrustum.evalProjectionMatrix(projMat);
|
||||||
batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(color, 0.0f), 0.0f, 0, true);
|
|
||||||
|
Transform viewTransform;
|
||||||
|
viewFrustum.evalViewTransform(viewTransform);
|
||||||
|
batch.setProjectionTransform(projMat);
|
||||||
|
batch.setViewTransform(viewTransform);
|
||||||
|
batch.setModelTransform(Transform()); // only for Mac
|
||||||
|
batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8);
|
||||||
|
batch.setInputFormat(theFormat);
|
||||||
|
|
||||||
|
gpu::TexturePointer skymap;
|
||||||
|
auto color = glm::vec4(skybox.getColor(), 0.0f);
|
||||||
|
if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) {
|
||||||
|
skymap = skybox.getCubemap();
|
||||||
|
|
||||||
|
if (glm::all(glm::equal(skybox.getColor(), glm::vec3(0.0f)))) {
|
||||||
|
color = glm::vec4(1.0f);
|
||||||
|
} else {
|
||||||
|
color.w = 1.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// Update the constant color.
|
||||||
|
theConstants->setSubData(0, sizeof(glm::vec4), (const gpu::Byte*) &color);
|
||||||
|
|
||||||
|
batch.setPipeline(thePipeline);
|
||||||
|
batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize());
|
||||||
|
batch.setResourceTexture(0, skymap);
|
||||||
|
|
||||||
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
|
|
||||||
|
batch.setResourceTexture(0, nullptr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,14 @@ void main(void) {
|
||||||
#else
|
#else
|
||||||
|
|
||||||
vec3 coord = normalize(_normal);
|
vec3 coord = normalize(_normal);
|
||||||
vec3 texel = texture(cubeMap, coord).rgb;
|
|
||||||
vec3 color = texel * _skybox._color.rgb;
|
// Skybox color or blend with skymap
|
||||||
|
vec3 color = _skybox._color.rgb;
|
||||||
|
if (_skybox._color.a > 0.0) {
|
||||||
|
vec3 texel = texture(cubeMap, coord).rgb;
|
||||||
|
color *= texel;
|
||||||
|
}
|
||||||
|
|
||||||
vec3 pixel = pow(color, vec3(1.0/2.2)); // manual Gamma correction
|
vec3 pixel = pow(color, vec3(1.0/2.2)); // manual Gamma correction
|
||||||
_fragColor = vec4(pixel, 0.0);
|
_fragColor = vec4(pixel, 0.0);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue