Implement ambient-only lights
This commit is contained in:
parent
67cfbd92ad
commit
e9047a267b
13 changed files with 69 additions and 28 deletions
|
@ -359,7 +359,7 @@ void CharacterGeneration::reloadCharacterModel() {
|
|||
.modelSupplier(bind(&CharacterGeneration::getCharacterModel, this, _1))
|
||||
.modelScale(kModelScale)
|
||||
.cameraFromModelNode("camerahook")
|
||||
.ambientLightColor(glm::vec3(0.2f))
|
||||
.lightingRefFromModelNode("cgbody_light")
|
||||
.build());
|
||||
|
||||
lblModel.setScene(move(scene));
|
||||
|
|
|
@ -120,7 +120,7 @@ void ClassSelection::setupClassButton(int index, Gender gender, ClassType clazz)
|
|||
.modelSupplier([&](SceneGraph &sceneGraph) { return getCharacterModel(appearance, sceneGraph); })
|
||||
.modelScale(kModelScale)
|
||||
.cameraFromModelNode("camerahook")
|
||||
.ambientLightColor(glm::vec3(0.2f))
|
||||
.lightingRefFromModelNode("cgbody_light")
|
||||
.build());
|
||||
|
||||
Control &control3d = getControl("3D_MODEL" + to_string(index + 1));
|
||||
|
|
|
@ -89,7 +89,7 @@ void PortraitSelection::loadHeadModel() {
|
|||
.modelSupplier(bind(&PortraitSelection::getCharacterModel, this, _1))
|
||||
.modelScale(kModelScale)
|
||||
.cameraFromModelNode(_charGen->character().gender == Gender::Male ? "camerahookm" : "camerahookf")
|
||||
.ambientLightColor(glm::vec3(0.2f))
|
||||
.lightingRefFromModelNode("cghead_light")
|
||||
.build());
|
||||
|
||||
control.setScene(move(scene));
|
||||
|
@ -118,7 +118,6 @@ shared_ptr<ModelSceneNode> PortraitSelection::getCharacterModel(SceneGraph &scen
|
|||
auto model = make_shared<ModelSceneNode>(_game->services().graphics().models().get("cghead_light"), ModelUsage::GUI, &sceneGraph);
|
||||
model->attach("cghead_light", creatureModel);
|
||||
|
||||
|
||||
return move(model);
|
||||
}
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ void CharacterMenu::refresh3D() {
|
|||
.modelSupplier(bind(&CharacterMenu::getSceneModel, this, _1))
|
||||
.modelOffset(glm::vec2(0.0f, 1.7f))
|
||||
.cameraFromModelNode("camerahook")
|
||||
.ambientLightColor(glm::vec3(0.2f))
|
||||
.lightingRefFromModelNode("charmain_light")
|
||||
.build();
|
||||
|
||||
control3d.setScene(move(scene));
|
||||
|
|
|
@ -117,7 +117,7 @@ void MainMenu::setup3DView() {
|
|||
.modelSupplier(bind(&MainMenu::getKotorModel, this, _1))
|
||||
.modelScale(kKotorModelSize)
|
||||
.cameraFromModelNode("camerahook")
|
||||
.ambientLightColor(glm::vec3(0.1f))
|
||||
.lightingRefFromModelNode("rootdummy")
|
||||
.build());
|
||||
|
||||
control.setScene(move(scene));
|
||||
|
|
|
@ -138,7 +138,8 @@ struct ShaderLight {
|
|||
glm::vec4 color { 1.0f };
|
||||
float multiplier { 1.0f };
|
||||
float radius { 1.0f };
|
||||
char padding[8];
|
||||
int ambientOnly { 0 };
|
||||
char padding[4];
|
||||
};
|
||||
|
||||
struct LightingUniforms {
|
||||
|
|
|
@ -130,6 +130,7 @@ struct Light {
|
|||
vec4 color;
|
||||
float multiplier;
|
||||
float radius;
|
||||
bool ambientOnly;
|
||||
};
|
||||
|
||||
layout(std140) uniform Lighting {
|
||||
|
|
|
@ -267,6 +267,12 @@ void main() {
|
|||
|
||||
vec3 ambient = uGeneral.ambientColor.rgb * albedo * ao;
|
||||
|
||||
for (int i = 0; i < uLightCount; ++i) {
|
||||
if (!uLights[i].ambientOnly) continue;
|
||||
float attenuation = getAttenuationQuadratic(i);
|
||||
ambient += attenuation * uLights[i].multiplier * uLights[i].color.rgb * albedo * ao;
|
||||
}
|
||||
|
||||
if (isFeatureEnabled(FEATURE_PBRIBL)) {
|
||||
vec3 F = fresnelSchlickRoughness(max(dot(N, V), 0.0), F0, roughness);
|
||||
|
||||
|
@ -293,6 +299,8 @@ void main() {
|
|||
vec3 Lo = vec3(0.0);
|
||||
|
||||
for (int i = 0; i < uLightCount; ++i) {
|
||||
if (uLights[i].ambientOnly) continue;
|
||||
|
||||
vec3 L = normalize(uLights[i].position.xyz - fragPosition);
|
||||
vec3 H = normalize(V + L);
|
||||
|
||||
|
|
|
@ -27,7 +27,20 @@ namespace graphics {
|
|||
|
||||
char g_shaderBaseBlinnPhong[] = R"END(
|
||||
vec3 getLightingIndirect(vec3 N) {
|
||||
return uGeneral.ambientColor.rgb * uMaterial.ambient.rgb;
|
||||
vec3 result = uGeneral.ambientColor.rgb * uMaterial.ambient.rgb;
|
||||
|
||||
for (int i = 0; i < uLightCount; ++i) {
|
||||
if (!uLights[i].ambientOnly) continue;
|
||||
|
||||
vec3 ambient = uLights[i].multiplier * uLights[i].color.rgb * uMaterial.ambient.rgb;
|
||||
|
||||
float attenuation = getAttenuationQuadratic(i);
|
||||
ambient *= attenuation;
|
||||
|
||||
result += ambient;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
vec3 getLightingDirect(vec3 N) {
|
||||
|
@ -35,6 +48,8 @@ vec3 getLightingDirect(vec3 N) {
|
|||
vec3 V = normalize(uGeneral.cameraPosition.xyz - fragPosition);
|
||||
|
||||
for (int i = 0; i < uLightCount; ++i) {
|
||||
if (uLights[i].ambientOnly) continue;
|
||||
|
||||
vec3 L = normalize(uLights[i].position.xyz - fragPosition);
|
||||
vec3 H = normalize(V + L);
|
||||
|
||||
|
@ -51,7 +66,7 @@ vec3 getLightingDirect(vec3 N) {
|
|||
result += diffuse + specular;
|
||||
}
|
||||
|
||||
return result;
|
||||
return min(vec3(1.0), result);
|
||||
}
|
||||
)END";
|
||||
|
||||
|
@ -73,7 +88,7 @@ void main() {
|
|||
} else if (isFeatureEnabled(FEATURE_LIGHTING)) {
|
||||
vec3 indirect = getLightingIndirect(N);
|
||||
vec3 direct = getLightingDirect(N);
|
||||
lighting = min(vec3(1.0), indirect + (1.0 - shadow) * direct);
|
||||
lighting = indirect + (1.0 - shadow) * direct;
|
||||
} else if (isFeatureEnabled(FEATURE_SELFILLUM)) {
|
||||
lighting = uGeneral.selfIllumColor.rgb;
|
||||
} else {
|
||||
|
|
|
@ -54,19 +54,28 @@ unique_ptr<SceneGraph> SceneBuilder::build() {
|
|||
_modelScale + _modelOffset.y,
|
||||
_zNear, _zFar));
|
||||
|
||||
auto camera = make_shared<CameraSceneNode>("", projection, scene.get());
|
||||
scene->addRoot(model);
|
||||
scene->setAmbientLightColor(_ambientLightColor);
|
||||
|
||||
auto cameraNode = make_shared<CameraSceneNode>("", projection, scene.get());
|
||||
if (_cameraNodeName.empty()) {
|
||||
camera->setLocalTransform(_cameraTransform);
|
||||
cameraNode->setLocalTransform(_cameraTransform);
|
||||
} else {
|
||||
shared_ptr<ModelNode> refModelNode(model->model()->getNodeByName(_cameraNodeName));
|
||||
if (refModelNode) {
|
||||
camera->setLocalTransform(refModelNode->absoluteTransform() * _cameraTransform);
|
||||
shared_ptr<ModelNode> modelNode(model->model()->getNodeByName(_cameraNodeName));
|
||||
if (modelNode) {
|
||||
cameraNode->setLocalTransform(modelNode->absoluteTransform() * _cameraTransform);
|
||||
}
|
||||
}
|
||||
scene->setActiveCamera(move(cameraNode));
|
||||
|
||||
scene->addRoot(move(model));
|
||||
scene->setAmbientLightColor(_ambientLightColor);
|
||||
scene->setActiveCamera(camera);
|
||||
if (!_lightingRefNodeName.empty()) {
|
||||
shared_ptr<ModelNode> modelNode(model->model()->getNodeByName(_lightingRefNodeName));
|
||||
if (modelNode) {
|
||||
auto lightingRefNode = make_shared<DummySceneNode>(modelNode, scene.get());
|
||||
lightingRefNode->setLocalTransform(modelNode->absoluteTransform());
|
||||
scene->setLightingRefNode(move(lightingRefNode));
|
||||
}
|
||||
}
|
||||
|
||||
return move(scene);
|
||||
}
|
||||
|
@ -97,18 +106,23 @@ SceneBuilder &SceneBuilder::modelOffset(glm::vec2 offset) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
SceneBuilder &SceneBuilder::cameraTransform(const glm::mat4 &transform) {
|
||||
_cameraTransform = transform;
|
||||
SceneBuilder &SceneBuilder::cameraTransform(glm::mat4 transform) {
|
||||
_cameraTransform = move(transform);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SceneBuilder &SceneBuilder::cameraFromModelNode(const std::string &nodeName) {
|
||||
_cameraNodeName = nodeName;
|
||||
SceneBuilder &SceneBuilder::cameraFromModelNode(string nodeName) {
|
||||
_cameraNodeName = move(nodeName);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SceneBuilder &SceneBuilder::ambientLightColor(const glm::vec3 &color) {
|
||||
_ambientLightColor = color;
|
||||
SceneBuilder &SceneBuilder::ambientLightColor(glm::vec3 color) {
|
||||
_ambientLightColor = move(color);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SceneBuilder &SceneBuilder::lightingRefFromModelNode(string nodeName) {
|
||||
_lightingRefNodeName = move(nodeName);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,9 +48,10 @@ public:
|
|||
SceneBuilder &modelSupplier(const std::function<std::shared_ptr<scene::ModelSceneNode>(scene::SceneGraph &)> &supplier);
|
||||
SceneBuilder &modelScale(float scale);
|
||||
SceneBuilder &modelOffset(glm::vec2 offset);
|
||||
SceneBuilder &cameraTransform(const glm::mat4 &transform);
|
||||
SceneBuilder &cameraFromModelNode(const std::string &nodeName);
|
||||
SceneBuilder &ambientLightColor(const glm::vec3 &color);
|
||||
SceneBuilder &cameraTransform(glm::mat4 transform);
|
||||
SceneBuilder &cameraFromModelNode(std::string nodeName);
|
||||
SceneBuilder &ambientLightColor(glm::vec3 color);
|
||||
SceneBuilder &lightingRefFromModelNode(std::string nodeName);
|
||||
|
||||
private:
|
||||
graphics::GraphicsOptions _options;
|
||||
|
@ -65,6 +66,7 @@ private:
|
|||
glm::mat4 _cameraTransform { 1.0f };
|
||||
std::string _cameraNodeName;
|
||||
glm::vec3 _ambientLightColor { 0.0f };
|
||||
std::string _lightingRefNodeName;
|
||||
};
|
||||
|
||||
} // namespace gui
|
||||
|
|
|
@ -327,6 +327,7 @@ void MeshSceneNode::drawSingle(bool shadowPass) {
|
|||
shaderLight.color = glm::vec4(lights[i]->color(), 1.0f);
|
||||
shaderLight.multiplier = lights[i]->multiplier();
|
||||
shaderLight.radius = lights[i]->radius();
|
||||
shaderLight.ambientOnly = static_cast<int>(lights[i]->modelNode()->light()->ambientOnly);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ void SceneGraph::updateLighting() {
|
|||
_closestLights.clear();
|
||||
|
||||
if (_lightingRefNode) {
|
||||
getLightsAt(*_lightingRefNode, _closestLights, kMaxLights, [](auto &light) { return !light.modelNode()->light()->ambientOnly; });
|
||||
getLightsAt(*_lightingRefNode, _closestLights, kMaxLights);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue