Skip to content

Commit f0f67f0

Browse files
committed
Some light improvements
1 parent fdc5583 commit f0f67f0

5 files changed

Lines changed: 95 additions & 26 deletions

File tree

engine/core/component/LightComponent.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,17 @@ namespace Supernova{
4444
float outerConeCos = 0.642787635f; // cos(Angle::defaultToRad(100 / 2));
4545

4646
bool shadows = false;
47+
bool automaticShadowCamera = true;
4748
float shadowBias = 0.001f;
4849
unsigned int mapResolution = 1024;
49-
Vector2 shadowCameraNearFar = Vector2(0.0f, 0.0f); // when zero it gets value from scene camera or light range
50+
Vector2 shadowCameraNearFar = Vector2(0.1f, 10.0f); // when automatic it gets value from scene camera or light range
5051
unsigned int numShadowCascades = 3;
5152

5253
LightCamera cameras[6];
5354
FramebufferRender framebuffer[MAX_SHADOWCASCADES];
5455
int shadowMapIndex;
56+
57+
bool needUpdateShadowMap = true;
5558
};
5659

5760
}

engine/core/object/Light.cpp

Lines changed: 76 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "util/Angle.h"
88
#include "util/Color.h"
9+
#include "subsystem/RenderSystem.h"
910
#include <math.h>
1011

1112
using namespace Supernova;
@@ -23,7 +24,10 @@ Light::~Light(){
2324
void Light::setType(LightType type){
2425
LightComponent& lightcomp = getComponent<LightComponent>();
2526

26-
lightcomp.type = type;
27+
if (lightcomp.type != type){
28+
lightcomp.type = type;
29+
scene->getSystem<RenderSystem>()->needReloadMeshes();
30+
}
2731
}
2832

2933
LightType Light::getType() const{
@@ -36,8 +40,10 @@ void Light::setDirection(Vector3 direction){
3640
LightComponent& lightcomp = getComponent<LightComponent>();
3741
Transform& transform = getComponent<Transform>();
3842

39-
lightcomp.direction = direction;
40-
transform.needUpdate = true; //Does not affect children
43+
if (lightcomp.direction != direction){
44+
lightcomp.direction = direction;
45+
transform.needUpdate = true;
46+
}
4147
}
4248

4349
void Light::setDirection(const float x, const float y, const float z){
@@ -69,7 +75,10 @@ Vector3 Light::getColor() const{
6975
void Light::setRange(float range){
7076
LightComponent& lightcomp = getComponent<LightComponent>();
7177

72-
lightcomp.range = range;
78+
if (lightcomp.range != range){
79+
lightcomp.range = range;
80+
lightcomp.needUpdateShadowMap = true;
81+
}
7382
}
7483

7584
float Light::getRange() const{
@@ -82,8 +91,9 @@ void Light::setIntensity(float intensity){
8291
LightComponent& lightcomp = getComponent<LightComponent>();
8392
Transform& transform = getComponent<Transform>();
8493

85-
if (intensity > 0 && lightcomp.intensity == 0)
86-
transform.needUpdate = true; //Does not affect children
94+
if (intensity > 0 && lightcomp.intensity == 0){
95+
lightcomp.needUpdateShadowMap = true;
96+
}
8797

8898
lightcomp.intensity = intensity;
8999
}
@@ -97,14 +107,25 @@ float Light::getIntensity() const{
97107
void Light::setConeAngle(float inner, float outer){
98108
LightComponent& lightcomp = getComponent<LightComponent>();
99109

100-
lightcomp.innerConeCos = cos(Angle::defaultToRad(inner / 2));
101-
lightcomp.outerConeCos = cos(Angle::defaultToRad(outer / 2));
110+
float innerConeCos = cos(Angle::defaultToRad(inner / 2));
111+
float outerConeCos = cos(Angle::defaultToRad(outer / 2));
112+
113+
if (lightcomp.innerConeCos != innerConeCos || lightcomp.outerConeCos != outerConeCos){
114+
lightcomp.innerConeCos = innerConeCos;
115+
lightcomp.outerConeCos = outerConeCos;
116+
lightcomp.needUpdateShadowMap = true;
117+
}
102118
}
103119

104120
void Light::setInnerConeAngle(float inner){
105121
LightComponent& lightcomp = getComponent<LightComponent>();
106122

107-
lightcomp.innerConeCos = cos(Angle::defaultToRad(inner / 2));
123+
float innerConeCos = cos(Angle::defaultToRad(inner / 2));
124+
125+
if (lightcomp.innerConeCos != innerConeCos){
126+
lightcomp.innerConeCos = innerConeCos;
127+
lightcomp.needUpdateShadowMap = true;
128+
}
108129
}
109130

110131
float Light::getInnerConeAngle() const{
@@ -116,7 +137,12 @@ float Light::getInnerConeAngle() const{
116137
void Light::setOuterConeAngle(float outer){
117138
LightComponent& lightcomp = getComponent<LightComponent>();
118139

119-
lightcomp.outerConeCos = cos(Angle::defaultToRad(outer / 2));
140+
float outerConeCos = cos(Angle::defaultToRad(outer / 2));
141+
142+
if (lightcomp.outerConeCos != outerConeCos){
143+
lightcomp.outerConeCos = outerConeCos;
144+
lightcomp.needUpdateShadowMap = true;
145+
}
120146
}
121147

122148
float Light::getOuterConeAngle() const{
@@ -128,7 +154,12 @@ float Light::getOuterConeAngle() const{
128154
void Light::setShadows(bool shadows){
129155
LightComponent& lightcomp = getComponent<LightComponent>();
130156

131-
lightcomp.shadows = shadows;
157+
if (lightcomp.shadows != shadows){
158+
lightcomp.shadows = shadows;
159+
160+
lightcomp.needUpdateShadowMap = true;
161+
scene->getSystem<RenderSystem>()->needReloadMeshes();
162+
}
132163
}
133164

134165
bool Light::isShadows() const{
@@ -164,13 +195,21 @@ unsigned int Light::getShadowMapSize() const{
164195
void Light::setShadowCameraNearFar(float near, float far){
165196
LightComponent& lightcomp = getComponent<LightComponent>();
166197

167-
lightcomp.shadowCameraNearFar = Vector2(near, far);
198+
if (lightcomp.shadowCameraNearFar != Vector2(near, far)){
199+
lightcomp.shadowCameraNearFar = Vector2(near, far);
200+
lightcomp.automaticShadowCamera = false;
201+
lightcomp.needUpdateShadowMap = true;
202+
}
168203
}
169204

170205
void Light::setCameraNear(float near){
171206
LightComponent& lightcomp = getComponent<LightComponent>();
172207

173-
lightcomp.shadowCameraNearFar.x = near;
208+
if (lightcomp.shadowCameraNearFar.x != near){
209+
lightcomp.shadowCameraNearFar.x = near;
210+
lightcomp.automaticShadowCamera = false;
211+
lightcomp.needUpdateShadowMap = true;
212+
}
174213
}
175214

176215
float Light::getCameraNear() const{
@@ -182,7 +221,11 @@ float Light::getCameraNear() const{
182221
void Light::setCameraFar(float far){
183222
LightComponent& lightcomp = getComponent<LightComponent>();
184223

185-
lightcomp.shadowCameraNearFar.y = far;
224+
if (lightcomp.shadowCameraNearFar.y != far){
225+
lightcomp.shadowCameraNearFar.y = far;
226+
lightcomp.automaticShadowCamera = false;
227+
lightcomp.needUpdateShadowMap = true;
228+
}
186229
}
187230

188231
float Light::getCameraFar() const{
@@ -191,10 +234,28 @@ float Light::getCameraFar() const{
191234
return lightcomp.shadowCameraNearFar.y;
192235
}
193236

237+
void Light::setAutomaticShadowCamera(bool automatic){
238+
LightComponent& lightcomp = getComponent<LightComponent>();
239+
240+
if (lightcomp.automaticShadowCamera != automatic){
241+
lightcomp.automaticShadowCamera = automatic;
242+
lightcomp.needUpdateShadowMap = true;
243+
}
244+
}
245+
246+
bool Light::isAutomaticShadowCamera() const{
247+
LightComponent& lightcomp = getComponent<LightComponent>();
248+
249+
return lightcomp.automaticShadowCamera;
250+
}
251+
194252
void Light::setNumCascades(unsigned int numCascades){
195253
LightComponent& lightcomp = getComponent<LightComponent>();
196254

197-
lightcomp.numShadowCascades = numCascades;
255+
if (lightcomp.numShadowCascades != numCascades){
256+
lightcomp.numShadowCascades = numCascades;
257+
lightcomp.needUpdateShadowMap = true;
258+
}
198259
}
199260

200261
float Light::getNumCascades() const{

engine/core/object/Light.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ namespace Supernova{
5353
void setCameraFar(float far);
5454
float getCameraFar() const;
5555

56+
void setAutomaticShadowCamera(bool automatic);
57+
bool isAutomaticShadowCamera() const;
58+
5659
void setNumCascades(unsigned int numCascades);
5760
float getNumCascades() const;
5861
};

engine/core/script/binding/ObjectClassesLua.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ void LuaBinding::registerObjectClasses(lua_State *L){
289289
.addFunction("setCameraNear", &Light::setCameraNear)
290290
.addProperty("cameraFar", &Light::getCameraFar, &Light::setCameraFar)
291291
.addFunction("setCameraFar", &Light::setCameraFar)
292+
.addProperty("automaticShadowCamera", &Light::isAutomaticShadowCamera, &Light::setAutomaticShadowCamera)
292293
.addProperty("numCascades", &Light::getNumCascades, &Light::setNumCascades)
293294
.addFunction("setNumCascades", &Light::setNumCascades)
294295
.endClass();

engine/core/subsystem/RenderSystem.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2355,10 +2355,8 @@ void RenderSystem::sortInstancedMesh(InstancedMeshComponent& instmesh, MeshCompo
23552355
}
23562356

23572357
void RenderSystem::configureLightShadowNearFar(LightComponent& light, const CameraComponent& camera){
2358-
if (light.shadowCameraNearFar.x == 0.0){
2358+
if (light.automaticShadowCamera){
23592359
light.shadowCameraNearFar.x = camera.nearClip;
2360-
}
2361-
if (light.shadowCameraNearFar.y == 0.0){
23622360
if (light.range == 0.0){
23632361
light.shadowCameraNearFar.y = camera.farClip;
23642362
}else{
@@ -2935,6 +2933,16 @@ void RenderSystem::update(double dt){
29352933
if (!lines.loadCalled){
29362934
loadLines(entity, lines, pipelines);
29372935
}
2936+
2937+
}else if (signature.test(scene->getComponentId<LightComponent>())){
2938+
LightComponent& light = scene->getComponent<LightComponent>(entity);
2939+
2940+
if (mainCamera.needUpdate || transform.needUpdate || light.needUpdateShadowMap){
2941+
// need to be updated ONLY for main camera
2942+
updateLightFromScene(light, transform, mainCamera);
2943+
2944+
light.needUpdateShadowMap = false;
2945+
}
29382946
}
29392947

29402948
if (mainCamera.needUpdate || transform.needUpdate){
@@ -2949,13 +2957,6 @@ void RenderSystem::update(double dt){
29492957
updateTerrain(terrain, transform, mainCamera, mainCameraTransform);
29502958
}
29512959
}
2952-
2953-
// need to be updated ONLY for main camera
2954-
if (signature.test(scene->getComponentId<LightComponent>())){
2955-
LightComponent& light = scene->getComponent<LightComponent>(entity);
2956-
2957-
updateLightFromScene(light, transform, mainCamera);
2958-
}
29592960

29602961
if (signature.test(scene->getComponentId<AudioComponent>())){
29612962
AudioComponent& audio = scene->getComponent<AudioComponent>(entity);

0 commit comments

Comments
 (0)