Implement area fog
This commit is contained in:
parent
b4d4803c7d
commit
43ada622db
11 changed files with 109 additions and 14 deletions
|
@ -640,7 +640,13 @@ static glm::vec3 getRandomPointInTriangle(const Walkmesh::Face &face) {
|
|||
void Area::fill(SceneGraph &sceneGraph) {
|
||||
sceneGraph.clear();
|
||||
|
||||
// Room models + grass
|
||||
// Area properties
|
||||
|
||||
sceneGraph.setAmbientLightColor(_ambientColor);
|
||||
sceneGraph.setFogEnabled(_fogEnabled);
|
||||
sceneGraph.setFogNear(_fogNear);
|
||||
sceneGraph.setFogFar(_fogFar);
|
||||
sceneGraph.setFogColor(_fogColor);
|
||||
|
||||
shared_ptr<GrassSceneNode> grass;
|
||||
if (_grass.texture) {
|
||||
|
@ -648,6 +654,8 @@ void Area::fill(SceneGraph &sceneGraph) {
|
|||
sceneGraph.setGrass(grass);
|
||||
}
|
||||
|
||||
// Room models
|
||||
|
||||
for (auto &room : _rooms) {
|
||||
shared_ptr<ModelSceneNode> sceneNode(room.second->model());
|
||||
if (sceneNode) {
|
||||
|
|
|
@ -195,6 +195,7 @@ private:
|
|||
CreatureFinder _creatureFinder;
|
||||
Grass _grass;
|
||||
Perception _perception;
|
||||
glm::vec3 _ambientColor { 0.0f };
|
||||
|
||||
// Scripts
|
||||
|
||||
|
@ -234,6 +235,15 @@ private:
|
|||
|
||||
// END Stealth
|
||||
|
||||
// Fog
|
||||
|
||||
bool _fogEnabled { false };
|
||||
float _fogNear { 0.0f };
|
||||
float _fogFar { 0.0f };
|
||||
glm::vec3 _fogColor { 0.0f };
|
||||
|
||||
// END Fog
|
||||
|
||||
void init();
|
||||
|
||||
void loadLYT();
|
||||
|
@ -274,6 +284,7 @@ private:
|
|||
void loadMap(const resource::GffStruct &are);
|
||||
void loadStealthXP(const resource::GffStruct &are);
|
||||
void loadGrass(const resource::GffStruct &are);
|
||||
void loadFog(const resource::GffStruct &are);
|
||||
|
||||
// END Loading ARE
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ void Area::loadARE(const GffStruct &are) {
|
|||
loadMap(are);
|
||||
loadStealthXP(are);
|
||||
loadGrass(are);
|
||||
loadFog(are);
|
||||
}
|
||||
|
||||
void Area::loadCameraStyle(const GffStruct &are) {
|
||||
|
@ -60,15 +61,7 @@ void Area::loadCameraStyle(const GffStruct &are) {
|
|||
}
|
||||
|
||||
void Area::loadAmbientColor(const GffStruct &are) {
|
||||
int ambientColorValue = are.getInt("DynAmbientColor");
|
||||
glm::vec3 ambientColor(
|
||||
ambientColorValue & 0xff,
|
||||
(ambientColorValue >> 8) & 0xff,
|
||||
(ambientColorValue >> 16) & 0xff);
|
||||
|
||||
ambientColor /= 255.0f;
|
||||
|
||||
_game->sceneGraph().setAmbientLightColor(ambientColor);
|
||||
_ambientColor = are.getColor("DynAmbientColor");
|
||||
}
|
||||
|
||||
void Area::loadScripts(const GffStruct &are) {
|
||||
|
@ -103,6 +96,13 @@ void Area::loadGrass(const GffStruct &are) {
|
|||
_grass.probabilities[3] = are.getFloat("Grass_Prob_LR");
|
||||
}
|
||||
|
||||
void Area::loadFog(const GffStruct &are) {
|
||||
_fogEnabled = are.getBool("SunFogOn");
|
||||
_fogNear = are.getFloat("SunFogNear");
|
||||
_fogFar = are.getFloat("SunFogFar");
|
||||
_fogColor = are.getColor("SunFogColor");
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
||||
|
|
|
@ -521,7 +521,7 @@ void MdlReader::doLoad() {
|
|||
uint8_t classification = readByte();
|
||||
uint8_t subclassification = readByte();
|
||||
ignore(1); // unknown
|
||||
uint8_t ignoreFog = readByte();
|
||||
uint8_t affectedByFog = readByte();
|
||||
uint32_t numChildModels = readUint32();
|
||||
ArrayDefinition animationArrayDef(readArrayDefinition());
|
||||
uint32_t superModelRef = readUint32();
|
||||
|
@ -552,6 +552,7 @@ void MdlReader::doLoad() {
|
|||
}
|
||||
|
||||
_model = make_unique<Model>(name, getClassification(classification), animationScale, move(rootNode), anims, superModel);
|
||||
_model->setAffectedByFog(affectedByFog != 0);
|
||||
}
|
||||
|
||||
MdlReader::ArrayDefinition MdlReader::readArrayDefinition() {
|
||||
|
|
|
@ -61,6 +61,8 @@ public:
|
|||
|
||||
void init();
|
||||
|
||||
bool isAffectedByFog() const { return _affectedByFog; }
|
||||
|
||||
std::vector<std::string> getAnimationNames() const;
|
||||
std::shared_ptr<Animation> getAnimation(const std::string &name) const;
|
||||
std::shared_ptr<ModelNode> findNodeByNumber(uint16_t number) const;
|
||||
|
@ -73,6 +75,8 @@ public:
|
|||
std::shared_ptr<Model> superModel() const { return _superModel; }
|
||||
const AABB &aabb() const { return _aabb; }
|
||||
|
||||
void setAffectedByFog(bool affected) { _affectedByFog = affected; }
|
||||
|
||||
private:
|
||||
std::string _name;
|
||||
Classification _classification;
|
||||
|
@ -84,6 +88,7 @@ private:
|
|||
std::unordered_map<uint16_t, std::shared_ptr<ModelNode>> _nodeByNumber;
|
||||
std::unordered_map<std::string, std::shared_ptr<ModelNode>> _nodeByName;
|
||||
AABB _aabb;
|
||||
bool _affectedByFog { false };
|
||||
|
||||
void initInternal(const std::shared_ptr<ModelNode> &node);
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ const int FEATURE_PARTICLES = 0x400;
|
|||
const int FEATURE_WATER = 0x800;
|
||||
const int FEATURE_HDR = 0x1000;
|
||||
const int FEATURE_CUSTOMMAT = 0x2000;
|
||||
const int FEATURE_FOG = 0x20000;
|
||||
|
||||
const int NUM_CUBE_FACES = 6;
|
||||
const int MAX_BONES = 128;
|
||||
|
@ -85,11 +86,14 @@ struct General {
|
|||
vec4 ambientColor;
|
||||
vec4 selfIllumColor;
|
||||
vec4 discardColor;
|
||||
vec4 fogColor;
|
||||
vec2 uvOffset;
|
||||
float alpha;
|
||||
float waterAlpha;
|
||||
float roughness;
|
||||
float exposure;
|
||||
float fogNear;
|
||||
float fogFar;
|
||||
};
|
||||
|
||||
struct Material {
|
||||
|
@ -294,6 +298,11 @@ float getLightAttenuation(int light) {
|
|||
|
||||
return D / (D + r);
|
||||
}
|
||||
|
||||
vec3 applyFog(vec3 rgb, float distance) {
|
||||
float fogAmount = clamp(distance - uGeneral.fogNear, 0.0, uGeneral.fogFar - uGeneral.fogNear) / (uGeneral.fogFar - uGeneral.fogNear);
|
||||
return mix(rgb, uGeneral.fogColor.rgb, fogAmount);
|
||||
}
|
||||
)END";
|
||||
|
||||
static constexpr GLchar kShaderBasePBR[] = R"END(
|
||||
|
@ -661,7 +670,8 @@ void main() {
|
|||
diffuseSample = vec4(vec3(0.5), 1.0);
|
||||
}
|
||||
|
||||
vec3 V = normalize(uGeneral.cameraPosition.xyz - fragPosition);
|
||||
vec3 cameraToFragment = uGeneral.cameraPosition.xyz - fragPosition;
|
||||
vec3 V = normalize(cameraToFragment);
|
||||
|
||||
vec3 N;
|
||||
if (isFeatureEnabled(FEATURE_BUMPMAPS)) {
|
||||
|
@ -711,6 +721,9 @@ void main() {
|
|||
vec3 S = vec3(1.0) - max(vec3(0.0), vec3(getShadow()) - uGeneral.ambientColor.rgb);
|
||||
objectColor *= S;
|
||||
}
|
||||
if (isFeatureEnabled(FEATURE_FOG)) {
|
||||
objectColor = applyFog(objectColor, length(cameraToFragment));
|
||||
}
|
||||
|
||||
float objectAlpha = uGeneral.alpha;
|
||||
if (!isFeatureEnabled(FEATURE_ENVMAP) && !isFeatureEnabled(FEATURE_BUMPMAPS)) {
|
||||
|
@ -754,7 +767,8 @@ void main() {
|
|||
N = normalize(fragNormal);
|
||||
}
|
||||
|
||||
vec3 V = normalize(uGeneral.cameraPosition.xyz - fragPosition);
|
||||
vec3 cameraToFragment = uGeneral.cameraPosition.xyz - fragPosition;
|
||||
vec3 V = normalize(cameraToFragment);
|
||||
vec3 R = reflect(-V, N);
|
||||
|
||||
vec3 albedo = isFeatureEnabled(FEATURE_HDR) ? pow(diffuseSample.rgb, vec3(GAMMA)) : diffuseSample.rgb;
|
||||
|
@ -850,6 +864,9 @@ void main() {
|
|||
vec3 S = vec3(1.0) - max(vec3(0.0), vec3(getShadow()) - uGeneral.ambientColor.rgb);
|
||||
objectColor *= S;
|
||||
}
|
||||
if (isFeatureEnabled(FEATURE_FOG)) {
|
||||
objectColor = applyFog(objectColor, length(cameraToFragment));
|
||||
}
|
||||
|
||||
float objectAlpha = uGeneral.alpha;
|
||||
if (!isFeatureEnabled(FEATURE_ENVMAP) && !isFeatureEnabled(FEATURE_BUMPMAPS)) {
|
||||
|
|
|
@ -71,6 +71,7 @@ struct UniformFeatureFlags {
|
|||
static constexpr int blur = 0x4000;
|
||||
static constexpr int text = 0x8000;
|
||||
static constexpr int grass = 0x10000;
|
||||
static constexpr int fog = 0x20000;
|
||||
};
|
||||
|
||||
struct ShaderGeneral {
|
||||
|
@ -82,12 +83,14 @@ struct ShaderGeneral {
|
|||
glm::vec4 ambientColor { 1.0f };
|
||||
glm::vec4 selfIllumColor { 1.0f };
|
||||
glm::vec4 discardColor { 0.0f };
|
||||
glm::vec4 fogColor { 0.0f };
|
||||
glm::vec2 uvOffset { 0.0f };
|
||||
float alpha { 1.0f };
|
||||
float waterAlpha { 1.0f };
|
||||
float roughness { 0.0f };
|
||||
float exposure { 1.0f };
|
||||
char padding[8];
|
||||
float fogNear { 0.0f };
|
||||
float fogFar { 0.0f };
|
||||
};
|
||||
|
||||
struct ShaderMaterial {
|
||||
|
|
|
@ -65,6 +65,24 @@ uint32_t GffStruct::getUint(const string &name, uint32_t defValue) const {
|
|||
return field->uintValue;
|
||||
}
|
||||
|
||||
static glm::vec3 colorFromUint32(uint32_t value) {
|
||||
glm::vec3 result(
|
||||
value & 0xff,
|
||||
(value >> 8) & 0xff,
|
||||
(value >> 16) & 0xff);
|
||||
|
||||
result /= 255.0f;
|
||||
|
||||
return move(result);
|
||||
}
|
||||
|
||||
glm::vec3 GffStruct::getColor(const string &name, glm::vec3 defValue) const {
|
||||
const Field *field = get(name);
|
||||
if (!field) return move(defValue);
|
||||
|
||||
return colorFromUint32(field->uintValue);
|
||||
}
|
||||
|
||||
float GffStruct::getFloat(const string &name, float defValue) const {
|
||||
const Field *field = get(name);
|
||||
if (!field) return defValue;
|
||||
|
|
|
@ -85,6 +85,7 @@ public:
|
|||
bool getBool(const std::string &name, bool defValue = false) const;
|
||||
int getInt(const std::string &name, int defValue = 0) const;
|
||||
uint32_t getUint(const std::string &name, uint32_t defValue = 0) const;
|
||||
glm::vec3 getColor(const std::string &name, glm::vec3 defValue = glm::vec3(0.0f)) const;
|
||||
float getFloat(const std::string &name, float defValue = 0.0f) const;
|
||||
std::string getString(const std::string &name, std::string defValue = "") const;
|
||||
glm::vec3 getVector(const std::string &name, glm::vec3 defValue = glm::vec3(0.0f)) const;
|
||||
|
|
|
@ -305,6 +305,13 @@ void ModelNodeSceneNode::drawSingle(bool shadowPass) {
|
|||
uniforms.combined.general.waterAlpha = waterAlpha;
|
||||
}
|
||||
}
|
||||
|
||||
if (_sceneGraph->isFogEnabled() && _modelSceneNode->model()->isAffectedByFog()) {
|
||||
uniforms.combined.featureMask |= UniformFeatureFlags::fog;
|
||||
uniforms.combined.general.fogNear = _sceneGraph->fogNear();
|
||||
uniforms.combined.general.fogFar = _sceneGraph->fogFar();
|
||||
uniforms.combined.general.fogColor = glm::vec4(_sceneGraph->fogColor(), 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
Shaders::instance().activate(program, uniforms);
|
||||
|
|
|
@ -97,6 +97,21 @@ public:
|
|||
|
||||
// END Lights and shadows
|
||||
|
||||
// Fog
|
||||
|
||||
bool isFogEnabled() const { return _fogEnabled; }
|
||||
|
||||
float fogNear() const { return _fogNear; }
|
||||
float fogFar() const { return _fogFar; }
|
||||
const glm::vec3 &fogColor() const { return _fogColor; }
|
||||
|
||||
void setFogEnabled(bool enabled) { _fogEnabled = enabled; }
|
||||
void setFogNear(float near) { _fogNear = near; }
|
||||
void setFogFar(float far) { _fogFar = far; }
|
||||
void setFogColor(glm::vec3 color) { _fogColor = std::move(color); }
|
||||
|
||||
// END Fog
|
||||
|
||||
private:
|
||||
render::GraphicsOptions _opts;
|
||||
|
||||
|
@ -127,6 +142,15 @@ private:
|
|||
|
||||
// END Shadows
|
||||
|
||||
// Fog
|
||||
|
||||
bool _fogEnabled { false };
|
||||
float _fogNear { 0.0f };
|
||||
float _fogFar { 0.0f };
|
||||
glm::vec3 _fogColor { 0.0f };
|
||||
|
||||
// END Fog
|
||||
|
||||
void refreshNodeLists();
|
||||
void refreshFromSceneNode(const std::shared_ptr<SceneNode> &node);
|
||||
void refreshShadowLight();
|
||||
|
|
Loading…
Reference in a new issue