Bloom can now have a dirt texture applied
This commit is contained in:
committed by
Mathias Agopian
parent
a4e4021950
commit
8bbf0ce9ef
@@ -249,10 +249,14 @@ Java_com_google_android_filament_View_nSetAmbientOcclusionOptions(JNIEnv*, jclas
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetBloomOptions(JNIEnv*, jclass,
|
||||
jlong nativeView, jfloat strength, jint resolution, jfloat anamorphism, jint levels,
|
||||
jlong nativeView, jlong nativeTexture,
|
||||
jfloat dirtStrength, jfloat strength, jint resolution, jfloat anamorphism, jint levels,
|
||||
jint blendMode, jboolean threshold, jboolean enabled) {
|
||||
View* view = (View*) nativeView;
|
||||
Texture* dirt = (Texture*) nativeTexture;
|
||||
View::BloomOptions options = {
|
||||
.dirt = dirt,
|
||||
.dirtStrength = dirtStrength,
|
||||
.strength = strength,
|
||||
.resolution = (uint32_t)resolution,
|
||||
.anamorphism = anamorphism,
|
||||
|
||||
@@ -175,6 +175,9 @@ public class View {
|
||||
* anamorphism: Bloom's aspect ratio (x/y), for artistic purposes.
|
||||
* threshold: When enabled, a threshold at 1.0 is applied on the source image, this is
|
||||
* useful for artistic reasons.
|
||||
* dirt: A dirt/scratch/smudges texture (that can be RGB), which gets added to the
|
||||
* bloom effect. Smudges are visible where bloom occurs.
|
||||
* dirtStrength: Strength of the dirt texture.
|
||||
*
|
||||
* @see setBloomOptions
|
||||
*/
|
||||
@@ -185,6 +188,17 @@ public class View {
|
||||
INTERPOLATE
|
||||
}
|
||||
|
||||
/**
|
||||
* User provided dirt texture
|
||||
*/
|
||||
@Nullable
|
||||
public Texture dirt = null;
|
||||
|
||||
/**
|
||||
* strength of the dirt texture
|
||||
*/
|
||||
public float dirtStrength = 0.2f;
|
||||
|
||||
/**
|
||||
* Strength of the bloom effect, between 0.0 and 1.0
|
||||
*/
|
||||
@@ -802,7 +816,8 @@ public class View {
|
||||
*/
|
||||
public void setBloomOptions(@NonNull BloomOptions options) {
|
||||
mBloomOptions = options;
|
||||
nSetBloomOptions(getNativeObject(), options.strength, options.resolution,
|
||||
nSetBloomOptions(getNativeObject(), options.dirt.getNativeObject(),
|
||||
options.dirtStrength, options.strength, options.resolution,
|
||||
options.anamorphism, options.levels, options.blendingMode.ordinal(),
|
||||
options.threshold, options.enabled);
|
||||
}
|
||||
@@ -862,5 +877,5 @@ public class View {
|
||||
private static native void nSetAmbientOcclusion(long nativeView, int ordinal);
|
||||
private static native int nGetAmbientOcclusion(long nativeView);
|
||||
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity);
|
||||
private static native void nSetBloomOptions(long nativeView, float strength, int resolution, float anamorphism, int levels, int blendMode, boolean threshold, boolean enabled);
|
||||
private static native void nSetBloomOptions(long nativeView, long dirtNativeObject, float dirtStrength, float strength, int resolution, float anamorphism, int levels, int blendMode, boolean threshold, boolean enabled);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ class Camera;
|
||||
class MaterialInstance;
|
||||
class RenderTarget;
|
||||
class Scene;
|
||||
class Texture;
|
||||
class Viewport;
|
||||
|
||||
/**
|
||||
@@ -140,19 +141,24 @@ public:
|
||||
* anamorphism: Bloom's aspect ratio (x/y), for artistic purposes.
|
||||
* threshold: When enabled, a threshold at 1.0 is applied on the source image, this is
|
||||
* useful for artistic reasons.
|
||||
* dirt: A dirt/scratch/smudges texture (that can be RGB), which gets added to the
|
||||
* bloom effect. Smudges are visible where bloom occurs.
|
||||
* dirtStrength: Strength of the dirt texture.
|
||||
*/
|
||||
struct BloomOptions {
|
||||
enum class BlendMode : uint8_t {
|
||||
ADD, //!< Bloom is modulated by the strength parameter and added to the scene
|
||||
INTERPOLATE //!< Bloom is interpolated with the scene using the strength parameter
|
||||
};
|
||||
float strength = 0.10f; //!< Between 0.0 and 1.0
|
||||
uint32_t resolution = 360; //!< Resolution of minor axis (2^levels to 4096)
|
||||
float anamorphism = 1.0f; //!< Bloom x/y aspect-ratio (1/32 to 32)
|
||||
uint8_t levels = 6; //!< number of blur levels (3 to 12)
|
||||
BlendMode blendMode = BlendMode::ADD; //!< How the bloom effect is applied
|
||||
bool threshold = true; //!< Whether to threshold the source
|
||||
bool enabled = false; //!< enable or disable bloom
|
||||
Texture* dirt = nullptr; //!< User provided dirt texture
|
||||
float dirtStrength = 0.2f; //!< strength of the dirt texture
|
||||
float strength = 0.10f; //!< Between 0.0 and 1.0
|
||||
uint32_t resolution = 360; //!< Resolution of minor axis (2^levels to 4096)
|
||||
float anamorphism = 1.0f; //!< Bloom x/y aspect-ratio (1/32 to 32)
|
||||
uint8_t levels = 6; //!< number of blur levels (3 to 12)
|
||||
BlendMode blendMode = BlendMode::ADD; //!< How the bloom effect is applied
|
||||
bool threshold = true; //!< Whether to threshold the source
|
||||
bool enabled = false; //!< enable or disable bloom
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -133,8 +133,11 @@ void PostProcessManager::init() noexcept {
|
||||
mSeparableGaussianBlurKernelStorageSize = mSeparableGaussianBlur.getMaterial()->reflect("kernel")->size;
|
||||
|
||||
DriverApi& driver = mEngine.getDriverApi();
|
||||
mNoSSAOTexture = driver.createTexture(SamplerType::SAMPLER_2D, 1,
|
||||
TextureFormat::R8, 0, 1, 1, 1, TextureUsage::DEFAULT);
|
||||
mDummyOneTexture = driver.createTexture(SamplerType::SAMPLER_2D, 1,
|
||||
TextureFormat::RGBA8, 0, 1, 1, 1, TextureUsage::DEFAULT);
|
||||
|
||||
mDummyZeroTexture = driver.createTexture(SamplerType::SAMPLER_2D, 1,
|
||||
TextureFormat::RGBA8, 0, 1, 1, 1, TextureUsage::DEFAULT);
|
||||
|
||||
mNoiseTexture = driver.createTexture(SamplerType::SAMPLER_2D, 1,
|
||||
TextureFormat::RGB16F, 0, 16, 16, 1, TextureUsage::DEFAULT);
|
||||
@@ -164,17 +167,19 @@ void PostProcessManager::init() noexcept {
|
||||
}
|
||||
driver.update2DImage(mNoiseTexture, 0, 0, 0, 16, 16, std::move(noiseData));
|
||||
|
||||
|
||||
PixelBufferDescriptor data(driver.allocate(1), 1, PixelDataFormat::R, PixelDataType::UBYTE);
|
||||
auto p = static_cast<uint8_t *>(data.buffer);
|
||||
*p = 0xFFu;
|
||||
driver.update2DImage(mNoSSAOTexture, 0, 0, 0, 1, 1, std::move(data));
|
||||
PixelBufferDescriptor dataOne(driver.allocate(4), 4, PixelDataFormat::RGBA, PixelDataType::UBYTE);
|
||||
PixelBufferDescriptor dataZero(driver.allocate(4), 4, PixelDataFormat::RGBA, PixelDataType::UBYTE);
|
||||
*static_cast<uint32_t *>(dataOne.buffer) = 0xFFFFFFFF;
|
||||
*static_cast<uint32_t *>(dataZero.buffer) = 0;
|
||||
driver.update2DImage(mDummyOneTexture, 0, 0, 0, 1, 1, std::move(dataOne));
|
||||
driver.update2DImage(mDummyZeroTexture, 0, 0, 0, 1, 1, std::move(dataZero));
|
||||
}
|
||||
|
||||
void PostProcessManager::terminate(DriverApi& driver) noexcept {
|
||||
driver.destroyTexture(mNoSSAOTexture);
|
||||
driver.destroyTexture(mNoiseTexture);
|
||||
FEngine& engine = mEngine;
|
||||
driver.destroyTexture(mDummyOneTexture);
|
||||
driver.destroyTexture(mDummyZeroTexture);
|
||||
driver.destroyTexture(mNoiseTexture);
|
||||
mSSAO.terminate(engine);
|
||||
mMipmapDepth.terminate(engine);
|
||||
mBilateralBlur.terminate(engine);
|
||||
@@ -200,15 +205,26 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::toneMapping(FrameGraph& fg,
|
||||
FrameGraphId<FrameGraphTexture> input;
|
||||
FrameGraphId<FrameGraphTexture> output;
|
||||
FrameGraphId<FrameGraphTexture> bloom;
|
||||
FrameGraphId<FrameGraphTexture> dirt;
|
||||
FrameGraphRenderTargetHandle rt;
|
||||
};
|
||||
|
||||
FrameGraphId<FrameGraphTexture> bloomBlur;
|
||||
FrameGraphId<FrameGraphTexture> bloomDirt;
|
||||
|
||||
float bloom = 0.0f;
|
||||
if (bloomOptions.enabled) {
|
||||
bloom = clamp(bloomOptions.strength, 0.0f, 1.0f);
|
||||
bloomBlur = bloomPass(fg, input, TextureFormat::R11F_G11F_B10F, bloomOptions, scale);
|
||||
if (bloomOptions.dirt) {
|
||||
FTexture* fdirt = upcast(bloomOptions.dirt);
|
||||
FrameGraphTexture frameGraphTexture { .texture = fdirt->getHwHandle() };
|
||||
bloomDirt = fg.import("dirt", {
|
||||
.width = (uint32_t)fdirt->getWidth(0u),
|
||||
.height = (uint32_t)fdirt->getHeight(0u),
|
||||
.format = fdirt->getFormat()
|
||||
}, frameGraphTexture);
|
||||
}
|
||||
}
|
||||
|
||||
auto& ppToneMapping = fg.addPass<PostProcessToneMapping>("tonemapping",
|
||||
@@ -222,33 +238,49 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::toneMapping(FrameGraph& fg,
|
||||
});
|
||||
data.rt = builder.createRenderTarget(data.output);
|
||||
|
||||
if (!bloomBlur.isValid()) {
|
||||
// we need a dummy texture
|
||||
bloomBlur = builder.createTexture("dummy", {});
|
||||
if (bloomBlur.isValid()) {
|
||||
data.bloom = builder.sample(bloomBlur);
|
||||
}
|
||||
if (bloomDirt.isValid()) {
|
||||
data.dirt = builder.sample(bloomDirt);
|
||||
}
|
||||
data.bloom = builder.sample(bloomBlur);
|
||||
},
|
||||
[=](FrameGraphPassResources const& resources,
|
||||
PostProcessToneMapping const& data, DriverApi& driver) {
|
||||
auto const& colorTexture = resources.getTexture(data.input);
|
||||
auto const& bloomTexture = resources.getTexture(data.bloom);
|
||||
|
||||
FMaterialInstance* pInstance = mTonemapping.getMaterialInstance();
|
||||
pInstance->setParameter("colorBuffer", colorTexture, { /* shader uses texelFetch */ });
|
||||
pInstance->setParameter("bloomBuffer", bloomTexture, {
|
||||
Handle<HwTexture> colorTexture = resources.getTexture(data.input);
|
||||
|
||||
Handle<HwTexture> bloomTexture =
|
||||
data.bloom.isValid() ? resources.getTexture(data.bloom) : getZeroTexture();
|
||||
|
||||
Handle<HwTexture> dirtTexture =
|
||||
data.dirt.isValid() ? resources.getTexture(data.dirt) : getOneTexture();
|
||||
|
||||
FMaterialInstance* mi = mTonemapping.getMaterialInstance();
|
||||
mi->setParameter("colorBuffer", colorTexture, { /* shader uses texelFetch */ });
|
||||
mi->setParameter("bloomBuffer", bloomTexture, {
|
||||
.filterMag = SamplerMagFilter::LINEAR,
|
||||
.filterMin = SamplerMinFilter::LINEAR /* always read base level in shader */
|
||||
});
|
||||
mi->setParameter("dirtBuffer", dirtTexture, {
|
||||
.filterMag = SamplerMagFilter::LINEAR,
|
||||
.filterMin = SamplerMinFilter::LINEAR
|
||||
});
|
||||
|
||||
float2 bloomParameter{ bloom / float(bloomOptions.levels), 1.0f };
|
||||
float4 bloomParameter{
|
||||
bloom / float(bloomOptions.levels),
|
||||
1.0f,
|
||||
(bloomOptions.enabled && bloomOptions.dirt) ? bloomOptions.dirtStrength : 0.0f,
|
||||
0.0f
|
||||
};
|
||||
if (bloomOptions.blendMode == View::BloomOptions::BlendMode::INTERPOLATE) {
|
||||
bloomParameter.y = 1.0f - bloomParameter.x;
|
||||
}
|
||||
|
||||
pInstance->setParameter("dithering", dithering);
|
||||
pInstance->setParameter("bloom", bloomParameter);
|
||||
pInstance->setParameter("fxaa", fxaa);
|
||||
pInstance->commit(driver);
|
||||
mi->setParameter("dithering", dithering);
|
||||
mi->setParameter("bloom", bloomParameter);
|
||||
mi->setParameter("fxaa", fxaa);
|
||||
mi->commit(driver);
|
||||
|
||||
const uint8_t variant = uint8_t(translucent ?
|
||||
PostProcessVariant::TRANSLUCENT : PostProcessVariant::OPAQUE);
|
||||
@@ -256,12 +288,12 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::toneMapping(FrameGraph& fg,
|
||||
PipelineState pipeline{
|
||||
.program = mTonemapping.getMaterial()->getProgram(variant),
|
||||
.rasterState = mTonemapping.getMaterial()->getRasterState(),
|
||||
.scissor = pInstance->getScissor()
|
||||
.scissor = mi->getScissor()
|
||||
};
|
||||
|
||||
auto const& target = resources.getRenderTarget(data.rt);
|
||||
driver.beginRenderPass(target.target, target.params);
|
||||
pInstance->use(driver);
|
||||
mi->use(driver);
|
||||
driver.draw(pipeline, fullScreenRenderPrimitive);
|
||||
driver.endRenderPass();
|
||||
});
|
||||
|
||||
@@ -77,9 +77,8 @@ public:
|
||||
FrameGraphId<FrameGraphTexture> output, uint8_t dstLevel,
|
||||
bool reinhard, size_t kernelWidth, float sigma = 6.0f) noexcept;
|
||||
|
||||
backend::Handle<backend::HwTexture> getNoSSAOTexture() const {
|
||||
return mNoSSAOTexture;
|
||||
}
|
||||
backend::Handle<backend::HwTexture> getOneTexture() const { return mDummyOneTexture; }
|
||||
backend::Handle<backend::HwTexture> getZeroTexture() const { return mDummyZeroTexture; }
|
||||
|
||||
private:
|
||||
details::FEngine& mEngine;
|
||||
@@ -134,7 +133,8 @@ private:
|
||||
PostProcessMaterial mTonemapping;
|
||||
PostProcessMaterial mFxaa;
|
||||
|
||||
backend::Handle<backend::HwTexture> mNoSSAOTexture;
|
||||
backend::Handle<backend::HwTexture> mDummyOneTexture;
|
||||
backend::Handle<backend::HwTexture> mDummyZeroTexture;
|
||||
backend::Handle<backend::HwTexture> mNoiseTexture;
|
||||
|
||||
size_t mSeparableGaussianBlurKernelStorageSize = 0;
|
||||
|
||||
@@ -344,7 +344,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
|
||||
[&ppm, &js, &view, jobFroxelize]
|
||||
(FrameGraphPassResources const& resources, auto const& data, DriverApi& driver) {
|
||||
view.prepareSSAO(data.ssao.isValid() ? resources.getTexture(data.ssao)
|
||||
: ppm.getNoSSAOTexture());
|
||||
: ppm.getOneTexture());
|
||||
view.commitUniforms(driver);
|
||||
if (jobFroxelize) {
|
||||
auto sync = jobFroxelize;
|
||||
|
||||
@@ -245,6 +245,7 @@ public:
|
||||
}
|
||||
|
||||
void setBloomOptions(BloomOptions options) noexcept {
|
||||
options.dirtStrength = math::saturate(options.dirtStrength);
|
||||
options.levels = math::clamp(options.levels, uint8_t(3), uint8_t(12));
|
||||
mBloomOptions = options;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,11 @@ material {
|
||||
name : bloomBuffer,
|
||||
precision: medium
|
||||
},
|
||||
{
|
||||
type : sampler2d,
|
||||
name : dirtBuffer,
|
||||
precision: medium
|
||||
},
|
||||
{
|
||||
type : int,
|
||||
name : dithering
|
||||
@@ -20,7 +25,7 @@ material {
|
||||
name : fxaa
|
||||
},
|
||||
{
|
||||
type : float2,
|
||||
type : float4,
|
||||
name : bloom
|
||||
}
|
||||
],
|
||||
|
||||
@@ -154,6 +154,14 @@ public:
|
||||
*/
|
||||
void enableSSAO(bool b) { mEnableSsao = b; }
|
||||
|
||||
/**
|
||||
* Enables Bloom.
|
||||
* Defaults to true.
|
||||
*/
|
||||
void enableBloom(bool bloom) {
|
||||
mBloomOptions.enabled = bloom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the intensity of the IBL.
|
||||
* See also filament::IndirectLight::setIntensity().
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
struct Config {
|
||||
std::string title;
|
||||
std::string iblDirectory;
|
||||
std::string dirt;
|
||||
float scale = 1.0f;
|
||||
bool splitView = false;
|
||||
filament::Engine::Backend backend = filament::Engine::Backend::OPENGL;
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
#include "Cube.h"
|
||||
#include "NativeWindowHelper.h"
|
||||
|
||||
#include <stb_image.h>
|
||||
|
||||
#include "generated/resources/resources.h"
|
||||
|
||||
using namespace filament;
|
||||
@@ -137,6 +139,7 @@ void FilamentApp::run(const Config& config, SetupCallback setupCallback,
|
||||
window->mDepthView->getView()->setClearColor({0, 0, 0, 1});
|
||||
}
|
||||
|
||||
loadDirt(config);
|
||||
loadIBL(config);
|
||||
if (mIBL != nullptr) {
|
||||
mIBL->getSkybox()->setLayerMask(0x7, 0x4);
|
||||
@@ -452,6 +455,37 @@ void FilamentApp::loadIBL(const Config& config) {
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentApp::loadDirt(const Config& config) {
|
||||
if (!config.dirt.empty()) {
|
||||
Path dirtPath(config.dirt);
|
||||
|
||||
if (!dirtPath.exists()) {
|
||||
std::cerr << "The specified dirt file does not exist: " << dirtPath << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dirtPath.isFile()) {
|
||||
std::cerr << "The specified dirt path is not a file: " << dirtPath << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
int w, h, n;
|
||||
|
||||
unsigned char* data = stbi_load(dirtPath.getAbsolutePath().c_str(), &w, &h, &n, 3);
|
||||
assert(n == 3);
|
||||
|
||||
mDirt = Texture::Builder()
|
||||
.width(w)
|
||||
.height(h)
|
||||
.format(Texture::InternalFormat::RGB8)
|
||||
.build(*mEngine);
|
||||
|
||||
mDirt->setImage(*mEngine, 0, { data, size_t(w * h * 3),
|
||||
Texture::Format::RGB, Texture::Type::UBYTE,
|
||||
(Texture::PixelBufferDescriptor::Callback)&stbi_image_free });
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentApp::initSDL() {
|
||||
ASSERT_POSTCONDITION(SDL_Init(SDL_INIT_EVENTS) == 0, "SDL_Init Failure");
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ public:
|
||||
filament::Material const* getDefaultMaterial() const noexcept { return mDefaultMaterial; }
|
||||
filament::Material const* getTransparentMaterial() const noexcept { return mTransparentMaterial; }
|
||||
IBL* getIBL() const noexcept { return mIBL.get(); }
|
||||
filament::Texture* getDirtTexture() const noexcept { return mDirt; }
|
||||
filament::View* getGuiView() const noexcept;
|
||||
|
||||
void close() { mClosed = true; }
|
||||
@@ -199,10 +200,12 @@ private:
|
||||
void initSDL();
|
||||
|
||||
void loadIBL(const Config& config);
|
||||
void loadDirt(const Config& config);
|
||||
|
||||
filament::Engine* mEngine = nullptr;
|
||||
filament::Scene* mScene = nullptr;
|
||||
std::unique_ptr<IBL> mIBL;
|
||||
filament::Texture* mDirt = nullptr;
|
||||
bool mClosed = false;
|
||||
uint64_t mTime = 0;
|
||||
|
||||
|
||||
@@ -88,6 +88,8 @@ static void printUsage(char* name) {
|
||||
" Enable shadow plane\n\n"
|
||||
" --single\n"
|
||||
" Only apply the edited material to the first renderable in the scene\n\n"
|
||||
" --dirt\n"
|
||||
" Specify a dirt texture\n\n"
|
||||
);
|
||||
const std::string from("SAMPLE_MATERIAL");
|
||||
for (size_t pos = usage.find(from); pos != std::string::npos; pos = usage.find(from, pos)) {
|
||||
@@ -97,7 +99,7 @@ static void printUsage(char* name) {
|
||||
}
|
||||
|
||||
static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
static constexpr const char* OPTSTR = "ha:vps:i:";
|
||||
static constexpr const char* OPTSTR = "ha:vps:i:d:";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "api", required_argument, nullptr, 'a' },
|
||||
@@ -106,6 +108,7 @@ static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
{ "scale", required_argument, nullptr, 's' },
|
||||
{ "shadow-plane", no_argument, nullptr, 'p' },
|
||||
{ "single", no_argument, nullptr, 'n' },
|
||||
{ "dirt", required_argument, nullptr, 'd' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
};
|
||||
int opt;
|
||||
@@ -149,6 +152,9 @@ static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
|
||||
case 'n':
|
||||
g_singleMode = true;
|
||||
break;
|
||||
case 'd':
|
||||
config->dirt = arg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,6 +295,8 @@ static void setup(Engine* engine, View*, Scene* scene) {
|
||||
params.lightIntensity = c.w * pIndirectLight->getIntensity();
|
||||
params.lightColor = c.rgb;
|
||||
}
|
||||
|
||||
g_params.bloomOptions.dirt = FilamentApp::get().getDirtTexture();
|
||||
}
|
||||
|
||||
static void gui(filament::Engine* engine, filament::View*) {
|
||||
@@ -401,6 +409,7 @@ static void gui(filament::Engine* engine, filament::View*) {
|
||||
ImGui::Checkbox("bloom", ¶ms.bloomOptions.enabled);
|
||||
if (params.bloomOptions.enabled) {
|
||||
ImGui::SliderFloat("strength", ¶ms.bloomOptions.strength, 0.0f, 1.0f);
|
||||
ImGui::SliderFloat("dirt", ¶ms.bloomOptions.dirtStrength, 0.0f, 1.0f);
|
||||
}
|
||||
ImGui::Checkbox("dithering", ¶ms.dithering);
|
||||
ImGui::Unindent();
|
||||
@@ -520,6 +529,5 @@ int main(int argc, char* argv[]) {
|
||||
g_config.title = "Material Sandbox";
|
||||
FilamentApp& filamentApp = FilamentApp::get();
|
||||
filamentApp.run(g_config, setup, cleanup, gui, preRender);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,16 @@
|
||||
// Bloom
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
vec3 bloom(const vec3 color) {
|
||||
vec3 bloom(vec3 color) {
|
||||
highp vec2 uv = variable_vertex.xy;
|
||||
vec3 blurred = textureLod(materialParams_bloomBuffer, uv, 0.0).rgb;
|
||||
return blurred * materialParams.bloom.x + color * materialParams.bloom.y;
|
||||
color = blurred * materialParams.bloom.x + color * materialParams.bloom.y;
|
||||
|
||||
if (materialParams.bloom.z > 0.0) {
|
||||
float dirtIntensity = materialParams.bloom.z;
|
||||
vec3 dirt = textureLod(materialParams_dirtBuffer, uv, 0.0).rgb;
|
||||
color += blurred * dirt * dirtIntensity;
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user