specular - closes #455; detect geometry influenced by point lights after load - fixes #482

This commit is contained in:
Mikulas Florek 2015-07-10 08:12:12 +02:00
parent 77d09f8550
commit 8b625445e2
12 changed files with 144 additions and 50 deletions

View file

@ -744,8 +744,8 @@ template <class S>
class ColorPropertyDescriptor : public IPropertyDescriptor
{
public:
typedef Vec4 (S::*Getter)(Component);
typedef void (S::*Setter)(Component, const Vec4&);
typedef Vec3 (S::*Getter)(Component);
typedef void (S::*Setter)(Component, const Vec3&);
public:
ColorPropertyDescriptor(const char* name, Getter _getter, Setter _setter, IAllocator& allocator)
@ -760,7 +760,7 @@ class ColorPropertyDescriptor : public IPropertyDescriptor
virtual void set(Component cmp, InputBlob& stream) const override
{
Vec4 f;
Vec3 f;
stream.read(&f, sizeof(f));
(static_cast<S*>(cmp.scene)->*m_setter)(cmp, f);
}
@ -768,7 +768,7 @@ class ColorPropertyDescriptor : public IPropertyDescriptor
virtual void get(Component cmp, OutputBlob& stream) const override
{
Vec4 f = (static_cast<S*>(cmp.scene)->*m_getter)(cmp);
Vec3 f = (static_cast<S*>(cmp.scene)->*m_getter)(cmp);
int len = sizeof(f);
stream.write(&f, len);
}

View file

@ -129,6 +129,12 @@ bool Material::save(JsonSerializer& serializer)
serializer.serialize("backface_culling", isBackfaceCulling());
serializer.serialize("alpha_cutout", m_is_alpha_cutout);
serializer.serialize("shadow_receiver", m_is_shadow_receiver);
serializer.serialize("shininess", m_shininess);
serializer.beginArray("specular");
serializer.serializeArrayItem(m_specular.x);
serializer.serializeArrayItem(m_specular.y);
serializer.serializeArrayItem(m_specular.z);
serializer.endArray();
serializer.serialize("z_test", isZTest());
serializer.endObject();
return false;
@ -377,6 +383,18 @@ void Material::loaded(FS::IFile* file, bool success, FS::FileSystem& fs)
{
serializer.deserialize(m_is_alpha_cutout, false);
}
else if (strcmp(label, "specular") == 0)
{
serializer.deserializeArrayBegin();
serializer.deserializeArrayItem(m_specular.x, 1.0f);
serializer.deserializeArrayItem(m_specular.y, 1.0f);
serializer.deserializeArrayItem(m_specular.z, 1.0f);
serializer.deserializeArrayEnd();
}
else if (strcmp(label, "shininess") == 0)
{
serializer.deserialize(m_shininess, 4.0f);
}
else if (strcmp(label, "shadow_receiver") == 0)
{
serializer.deserialize(m_is_shadow_receiver, true);

View file

@ -3,6 +3,7 @@
#include "core/array.h"
#include "core/resource.h"
#include "core/vec3.h"
#include <bgfx.h>
@ -68,6 +69,10 @@ public:
void enableAlphaCutout(bool enable) { m_is_alpha_cutout = enable; updateShaderInstance(); }
bool isShadowReceiver() const { return m_is_shadow_receiver; }
void enableShadowReceiving(bool enable) { m_is_shadow_receiver = enable; updateShaderInstance(); }
float getShininess() const { return m_shininess; }
void setShininess(float value) { m_shininess = value; }
Vec3 getSpecular() const { return m_specular; }
void setSpecular(const Vec3& specular) { m_specular = specular; }
uint64_t getRenderStates() const { return m_render_states; }
void setShader(Shader* shader);
@ -97,8 +102,10 @@ public:
, m_allocator(allocator)
, m_texture_count(0)
, m_render_states(0)
, m_specular(1, 1, 1)
, m_shininess(4)
, m_shader_instance(nullptr)
{
{
enableZTest(true);
enableBackfaceCulling(true);
enableShadowReceiving(true);
@ -137,6 +144,8 @@ private:
IAllocator& m_allocator;
bgfx::ProgramHandle m_program_id;
uint64_t m_render_states;
Vec3 m_specular;
float m_shininess;
};
} // ~namespace Lumix

View file

@ -249,10 +249,12 @@ namespace Lumix
m_light_pos_radius_uniform = bgfx::createUniform("u_lightPosRadius", bgfx::UniformType::Vec4);
m_light_color_uniform = bgfx::createUniform("u_lightRgbInnerR", bgfx::UniformType::Vec4);
m_light_dir_fov_uniform = bgfx::createUniform("u_lightDirFov", bgfx::UniformType::Vec4);
m_light_specular_uniform = bgfx::createUniform("u_lightSpecular", bgfx::UniformType::Mat4, 64);
m_ambient_color_uniform = bgfx::createUniform("u_ambientColor", bgfx::UniformType::Vec4);
m_shadowmap_matrices_uniform = bgfx::createUniform("u_shadowmapMatrices", bgfx::UniformType::Mat4, 4);
m_shadowmap_splits_uniform = bgfx::createUniform("u_shadowmapSplits", bgfx::UniformType::Vec4);
m_bone_matrices_uniform = bgfx::createUniform("u_boneMatrices", bgfx::UniformType::Mat4, 64);
m_specular_shininess_uniform = bgfx::createUniform("u_materialSpecularShininess", bgfx::UniformType::Vec4);
ResourceManagerBase* material_manager = pipeline.getResourceManager().get(ResourceManager::MATERIAL);
m_screen_space_material = static_cast<Material*>(material_manager->load(Lumix::Path("models/editor/screen_space.mat")));
@ -271,6 +273,7 @@ namespace Lumix
material_manager->unload(*m_screen_space_material);
material_manager->unload(*m_debug_line_material);
bgfx::destroyUniform(m_specular_shininess_uniform);
bgfx::destroyUniform(m_bone_matrices_uniform);
bgfx::destroyUniform(m_terrain_scale_uniform);
bgfx::destroyUniform(m_morph_const_uniform);
@ -284,6 +287,7 @@ namespace Lumix
bgfx::destroyUniform(m_ambient_color_uniform);
bgfx::destroyUniform(m_shadowmap_matrices_uniform);
bgfx::destroyUniform(m_shadowmap_splits_uniform);
bgfx::destroyUniform(m_light_specular_uniform);
for (int i = 0; i < m_uniforms.size(); ++i)
{
@ -581,6 +585,9 @@ namespace Lumix
Vec4 light_dir_fov(light_cmp.entity.getRotation() * Vec3(0, 0, 1), m_scene->getLightFOV(light_cmp));
bgfx::setUniform(m_light_dir_fov_uniform, &light_dir_fov);
Vec4 light_specular(m_scene->getPointLightSpecularColor(light_cmp), 1.0);
bgfx::setUniform(m_light_specular_uniform, &light_specular);
}
@ -795,6 +802,10 @@ namespace Lumix
void renderMesh(const RenderableMesh& info)
{
if (!info.m_model->isReady())
{
return;
}
int instance_idx = info.m_mesh->getInstanceIdx();
if (instance_idx == -1)
{
@ -873,6 +884,9 @@ namespace Lumix
}
}
Vec4 specular_shininess(material->getSpecular(), material->getShininess());
bgfx::setUniform(m_specular_shininess_uniform, &specular_shininess);
int global_texture_offset = material->getTextureCount();
for (int i = 0; i < m_global_textures.size(); ++i)
{
@ -1079,6 +1093,7 @@ namespace Lumix
Array<const RenderableMesh*> m_tmp_meshes;
Array<const TerrainInfo*> m_tmp_terrains;
Array<GrassInfo> m_tmp_grasses;
bgfx::UniformHandle m_specular_shininess_uniform;
bgfx::UniformHandle m_bone_matrices_uniform;
bgfx::UniformHandle m_terrain_scale_uniform;
bgfx::UniformHandle m_morph_const_uniform;
@ -1092,6 +1107,7 @@ namespace Lumix
bgfx::UniformHandle m_light_dir_fov_uniform;
bgfx::UniformHandle m_shadowmap_matrices_uniform;
bgfx::UniformHandle m_shadowmap_splits_uniform;
bgfx::UniformHandle m_light_specular_uniform;
Material* m_screen_space_material;
Material* m_debug_line_material;

View file

@ -82,7 +82,8 @@ namespace Lumix
struct PointLight
{
Vec4 m_color;
Vec3 m_color;
Vec3 m_specular_color;
float m_intensity;
float m_range;
Entity m_entity;
@ -94,11 +95,11 @@ namespace Lumix
struct GlobalLight
{
int m_uid;
Vec4 m_color;
Vec3 m_color;
float m_intensity;
Vec4 m_ambient_color;
Vec3 m_ambient_color;
float m_ambient_intensity;
Vec4 m_fog_color;
Vec3 m_fog_color;
float m_fog_density;
Entity m_entity;
};
@ -324,6 +325,7 @@ namespace Lumix
serializer.write(point_light.m_entity.index);
serializer.write(point_light.m_range);
serializer.write(point_light.m_fov);
serializer.write(point_light.m_specular_color);
}
serializer.write(m_point_light_last_uid);
@ -463,6 +465,7 @@ namespace Lumix
serializer.read(light.m_entity.index);
serializer.read(light.m_range);
serializer.read(light.m_fov);
serializer.read(light.m_specular_color);
light.m_entity.universe = &m_universe;
m_universe.addComponent(light.m_entity, POINT_LIGHT_HASH, this, light.m_uid);
}
@ -521,6 +524,10 @@ namespace Lumix
deserializeRenderables(serializer);
deserializeLights(serializer);
deserializeTerrains(serializer);
for (int i = 0; i < m_point_lights.size(); ++i)
{
detectLightInfluencedGeometry(i);
}
}
@ -633,24 +640,7 @@ namespace Lumix
}
else if (type == GLOBAL_LIGHT_HASH)
{
GlobalLight& light = m_global_lights.pushEmpty();
light.m_entity = entity;
light.m_color.set(1, 1, 1, 1);
light.m_intensity = 0;
light.m_ambient_color.set(1, 1, 1, 1);
light.m_ambient_intensity = 1;
light.m_fog_color.set(1, 1, 1, 1);
light.m_fog_density = 0;
light.m_uid = ++m_global_light_last_uid;
if (m_global_lights.size() == 1)
{
m_active_global_light_uid = light.m_uid;
}
Component cmp = m_universe.addComponent(entity, type, this, light.m_uid);
m_universe.componentCreated().invoke(cmp);
return cmp;
return createGlobalLight(entity);
}
else if (type == POINT_LIGHT_HASH)
{
@ -1572,7 +1562,7 @@ namespace Lumix
m_global_lights[getGlobalLightIndex(cmp)].m_fog_density = density;
}
virtual void setFogColor(Component cmp, const Vec4& color) override
virtual void setFogColor(Component cmp, const Vec3& color) override
{
m_global_lights[getGlobalLightIndex(cmp)].m_fog_color = color;
}
@ -1582,7 +1572,7 @@ namespace Lumix
return m_global_lights[getGlobalLightIndex(cmp)].m_fog_density;
}
virtual Vec4 getFogColor(Component cmp) override
virtual Vec3 getFogColor(Component cmp) override
{
return m_global_lights[getGlobalLightIndex(cmp)].m_fog_color;
}
@ -1609,12 +1599,12 @@ namespace Lumix
m_global_lights[getGlobalLightIndex(cmp)].m_intensity = intensity;
}
virtual void setPointLightColor(Component cmp, const Vec4& color) override
virtual void setPointLightColor(Component cmp, const Vec3& color) override
{
m_point_lights[getPointLightIndex(cmp.index)].m_color = color;
}
virtual void setGlobalLightColor(Component cmp, const Vec4& color) override
virtual void setGlobalLightColor(Component cmp, const Vec3& color) override
{
m_global_lights[getGlobalLightIndex(cmp)].m_color = color;
}
@ -1624,7 +1614,7 @@ namespace Lumix
m_global_lights[getGlobalLightIndex(cmp)].m_ambient_intensity = intensity;
}
virtual void setLightAmbientColor(Component cmp, const Vec4& color) override
virtual void setLightAmbientColor(Component cmp, const Vec3& color) override
{
m_global_lights[getGlobalLightIndex(cmp)].m_ambient_color = color;
}
@ -1639,12 +1629,22 @@ namespace Lumix
return m_global_lights[getGlobalLightIndex(cmp)].m_intensity;
}
virtual Vec4 getPointLightColor(Component cmp) override
virtual Vec3 getPointLightColor(Component cmp) override
{
return m_point_lights[getPointLightIndex(cmp.index)].m_color;
}
virtual Vec4 getGlobalLightColor(Component cmp) override
virtual void setPointLightSpecularColor(Component cmp, const Vec3& color) override
{
m_point_lights[getPointLightIndex(cmp.index)].m_specular_color = color;
}
virtual Vec3 getPointLightSpecularColor(Component cmp) override
{
return m_point_lights[getPointLightIndex(cmp.index)].m_specular_color;
}
virtual Vec3 getGlobalLightColor(Component cmp) override
{
return m_global_lights[getGlobalLightIndex(cmp)].m_color;
}
@ -1654,7 +1654,7 @@ namespace Lumix
return m_global_lights[getGlobalLightIndex(cmp)].m_ambient_intensity;
}
virtual Vec4 getLightAmbientColor(Component cmp) override
virtual Vec3 getLightAmbientColor(Component cmp) override
{
return m_global_lights[getGlobalLightIndex(cmp)].m_ambient_color;
}
@ -1806,16 +1806,41 @@ namespace Lumix
}
Component createGlobalLight(const Entity& entity)
{
GlobalLight& light = m_global_lights.pushEmpty();
light.m_entity = entity;
light.m_color.set(1, 1, 1);
light.m_intensity = 0;
light.m_ambient_color.set(1, 1, 1);
light.m_ambient_intensity = 1;
light.m_fog_color.set(1, 1, 1);
light.m_fog_density = 0;
light.m_uid = ++m_global_light_last_uid;
if (m_global_lights.size() == 1)
{
m_active_global_light_uid = light.m_uid;
}
Component cmp = m_universe.addComponent(entity, GLOBAL_LIGHT_HASH, this, light.m_uid);
m_universe.componentCreated().invoke(cmp);
return cmp;
}
Component createPointLight(const Entity& entity)
{
PointLight& light = m_point_lights.pushEmpty();
m_light_influenced_geometry.push(Array<Renderable*>(m_allocator));
light.m_entity = entity;
light.m_color.set(1, 1, 1, 1);
light.m_color.set(1, 1, 1);
light.m_intensity = 1;
light.m_range = 10;
light.m_uid = ++m_point_light_last_uid;
light.m_fov = 999;
light.m_specular_color.set(1, 1, 1);
Component cmp = m_universe.addComponent(entity, POINT_LIGHT_HASH, this, light.m_uid);
m_universe.componentCreated().invoke(cmp);

View file

@ -169,21 +169,23 @@ namespace Lumix
virtual void setLightRange(Component cmp, float range) = 0;
virtual void setPointLightIntensity(Component cmp, float intensity) = 0;
virtual void setGlobalLightIntensity(Component cmp, float intensity) = 0;
virtual void setPointLightColor(Component cmp, const Vec4& color) = 0;
virtual void setGlobalLightColor(Component cmp, const Vec4& color) = 0;
virtual void setPointLightColor(Component cmp, const Vec3& color) = 0;
virtual void setGlobalLightColor(Component cmp, const Vec3& color) = 0;
virtual void setLightAmbientIntensity(Component cmp, float intensity) = 0;
virtual void setLightAmbientColor(Component cmp, const Vec4& color) = 0;
virtual void setLightAmbientColor(Component cmp, const Vec3& color) = 0;
virtual void setFogDensity(Component cmp, float density) = 0;
virtual void setFogColor(Component cmp, const Vec4& color) = 0;
virtual void setFogColor(Component cmp, const Vec3& color) = 0;
virtual float getPointLightIntensity(Component cmp) = 0;
virtual float getGlobalLightIntensity(Component cmp) = 0;
virtual Vec4 getPointLightColor(Component cmp) = 0;
virtual Vec4 getGlobalLightColor(Component cmp) = 0;
virtual Vec3 getPointLightColor(Component cmp) = 0;
virtual Vec3 getGlobalLightColor(Component cmp) = 0;
virtual float getLightAmbientIntensity(Component cmp) = 0;
virtual Vec4 getLightAmbientColor(Component cmp) = 0;
virtual Vec3 getLightAmbientColor(Component cmp) = 0;
virtual float getFogDensity(Component cmp) = 0;
virtual Vec4 getFogColor(Component cmp) = 0;
virtual Vec3 getFogColor(Component cmp) = 0;
virtual Frustum& getFrustum() = 0;
virtual Vec3 getPointLightSpecularColor(Component cmp) = 0;
virtual void setPointLightSpecularColor(Component cmp, const Vec3& color) = 0;
protected:
virtual ~RenderScene() {}

View file

@ -126,6 +126,7 @@ namespace Lumix
editor.registerProperty("point_light", allocator.newObject<DecimalPropertyDescriptor<RenderScene> >("intensity", &RenderScene::getPointLightIntensity, &RenderScene::setPointLightIntensity, 0.0f, 1.0f, 0.05f, allocator));
editor.registerProperty("point_light", allocator.newObject<ColorPropertyDescriptor<RenderScene> >("color", &RenderScene::getPointLightColor, &RenderScene::setPointLightColor, allocator));
editor.registerProperty("point_light", allocator.newObject<ColorPropertyDescriptor<RenderScene> >("specular", &RenderScene::getPointLightSpecularColor, &RenderScene::setPointLightSpecularColor, allocator));
editor.registerProperty("point_light", allocator.newObject<DecimalPropertyDescriptor<RenderScene> >("range", &RenderScene::getLightRange, &RenderScene::setLightRange, 0.0f, FLT_MAX, 0.0f, allocator));
editor.registerProperty("point_light", allocator.newObject<DecimalPropertyDescriptor<RenderScene> >("FOV", &RenderScene::getLightFOV, &RenderScene::setLightFOV, 0.0f, 360.0f, 5.0f, allocator));

View file

@ -188,6 +188,8 @@ struct ShaderLoader
file->read(mem->data, file->size());
mem->data[file->size()] = '\0';
m_fragment_shader = bgfx::createShader(mem);
ASSERT(bgfx::isValid(m_fragment_shader));
fs.close(file);
}
checkFinish();
}
@ -200,6 +202,8 @@ struct ShaderLoader
file->read(mem->data, file->size());
mem->data[file->size()] = '\0';
m_vertex_shader = bgfx::createShader(mem);
ASSERT(bgfx::isValid(m_vertex_shader));
fs.close(file);
}
checkFinish();
}
@ -212,7 +216,7 @@ struct ShaderLoader
if (bgfx::isValid(m_vertex_shader) && bgfx::isValid(m_fragment_shader))
{
m_shader.decrementDepCount();
m_shader_instance->m_program_handles[m_global_idx] = bgfx::createProgram(m_vertex_shader, m_fragment_shader, false);
m_shader_instance->m_program_handles[m_global_idx] = bgfx::createProgram(m_vertex_shader, m_fragment_shader, true);
}
else
{

View file

@ -64,11 +64,10 @@ bool DynamicObjectItemDelegate::editorEvent(QEvent* event, QAbstractItemModel* m
dialog->connect(dialog, &QColorDialog::currentColorChanged, [model, index, dialog]()
{
QColor color = dialog->currentColor();
Lumix::Vec4 value;
Lumix::Vec3 value;
value.x = color.redF();
value.y = color.greenF();
value.z = color.blueF();
value.w = color.alphaF();
model->setData(index, color);
});
dialog->show();

View file

@ -1,6 +1,7 @@
#pragma once
#include "core/vec3.h"
#include <qabstractitemmodel.h>
#include <qstyleditemdelegate.h>
#include <functional>
@ -152,6 +153,24 @@ class DynamicObjectModel : public QAbstractItemModel
{
}
Object& propertyColor(QString name, Lumix::Vec3(T::*getter)() const, void (T::*setter)(const Lumix::Vec3&))
{
Node& node = m_node->addChild(name);
T* inst = m_instance;
node.m_getter = [getter, inst]() -> QVariant {
Lumix::Vec3 v = (inst->*getter)();
return QColor(v.x * 255, v.y * 255, v.z * 255);
};
node.m_setter = [inst, setter](const QVariant& value) {
Lumix::Vec3 c;
c.x = qvariant_cast<QColor>(value).redF();
c.y = qvariant_cast<QColor>(value).greenF();
c.z = qvariant_cast<QColor>(value).blueF();
(inst->*setter)(c);
};
return *this;
}
template <typename Getter, typename PropertyType>
Object& property(QString name, Getter getter, void (T::*setter)(PropertyType))
{

View file

@ -480,11 +480,10 @@ void EntityModel::set(Lumix::Entity entity, uint32_t component_type, int index,
case Lumix::IPropertyDescriptor::COLOR:
{
QColor color = value.value<QColor>();
Lumix::Vec4 v;
Lumix::Vec3 v;
v.x = color.redF();
v.y = color.greenF();
v.z = color.blueF();
v.w = color.alphaF();
m_editor.setProperty(cmp.type, index, *desc, &v, sizeof(v));
break;
}
@ -552,7 +551,7 @@ QVariant EntityModel::get(Lumix::Entity entity, uint32_t component_type, int ind
}
case Lumix::IPropertyDescriptor::COLOR:
{
Lumix::Vec4 c;
Lumix::Vec3 c;
input.read(c);
QColor color((int)(c.x * 255), (int)(c.y * 255), (int)(c.z * 255));
return color;

View file

@ -262,6 +262,8 @@ void ResourceModel::fillMaterialInfo(Lumix::Material* material, Node& node)
.property("Alpha cutout", &Lumix::Material::isAlphaCutout, &Lumix::Material::enableAlphaCutout)
.property("Backface culling", &Lumix::Material::isBackfaceCulling, &Lumix::Material::enableBackfaceCulling)
.property("Shadow receiver", &Lumix::Material::isShadowReceiver, &Lumix::Material::enableShadowReceiving)
.property("Shininess", &Lumix::Material::getShininess, &Lumix::Material::setShininess)
.propertyColor("Specular", &Lumix::Material::getSpecular, &Lumix::Material::setSpecular)
.property("Z test", &Lumix::Material::isZTest, &Lumix::Material::enableZTest)
.property("Shader",
[](Lumix::Material* material) -> QVariant { return material->getShader() ? material->getShader()->getPath().c_str() : ""; },