mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
Compare commits
3 Commits
75cccf0c4c
...
ab40c2eb34
| Author | SHA1 | Date | |
|---|---|---|---|
| ab40c2eb34 | |||
| 3b5a3b994f | |||
| e1eaf62f09 |
@@ -1,35 +1,137 @@
|
|||||||
#version 460
|
#version 460
|
||||||
|
|
||||||
in vec2 TexCoord;
|
in vec2 TexCoord;
|
||||||
|
in vec3 rayDir;
|
||||||
|
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
uniform sampler2D u_sceneTexture;
|
layout (binding = 0) uniform sampler2D u_sceneTexture;
|
||||||
|
layout (binding = 1) uniform sampler2D u_depthTexture;
|
||||||
|
layout (binding = 2) uniform sampler2D u_shadowMap;
|
||||||
|
uniform mat4 u_lightSpaceMatrix;
|
||||||
uniform float u_time;
|
uniform float u_time;
|
||||||
uniform bool u_underwater;
|
uniform bool u_underwater;
|
||||||
uniform vec3 u_waterColor;
|
uniform vec3 u_waterColor;
|
||||||
uniform float u_fogDensity;
|
uniform float u_fogDensity;
|
||||||
|
uniform mat4 InverseViewProjection;
|
||||||
|
uniform vec3 cameraPos;
|
||||||
|
uniform vec3 sunDir;
|
||||||
|
uniform vec3 sunColor;
|
||||||
|
uniform float waterDensity;
|
||||||
|
|
||||||
|
float hash(vec2 p) {
|
||||||
|
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
|
||||||
|
}
|
||||||
|
|
||||||
|
float noise(vec2 p) {
|
||||||
|
vec2 i = floor(p);
|
||||||
|
vec2 f = fract(p);
|
||||||
|
f = f * f * (3.0 - 2.0 * f);
|
||||||
|
|
||||||
|
return mix(
|
||||||
|
mix(hash(i), hash(i + vec2(1.0, 0.0)), f.x),
|
||||||
|
mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), f.x),
|
||||||
|
f.y
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
float fbm(vec2 p) {
|
||||||
|
float value = 0.0;
|
||||||
|
float amp = 0.5;
|
||||||
|
float freq = 1.0;
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
value += amp * noise(p * freq);
|
||||||
|
freq *= 2.0;
|
||||||
|
amp *= 0.5;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getCausticValue(float x, float y, float z) {
|
||||||
|
float w = 8.0;
|
||||||
|
float strength = 4.0;
|
||||||
|
vec2 coord = vec2(x, y) * w + z * 0.5;
|
||||||
|
|
||||||
|
float n = fbm(coord);
|
||||||
|
|
||||||
|
float caustic = pow(n, 3.0) * strength;
|
||||||
|
return caustic;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getShadow(vec3 worldPos) {
|
||||||
|
vec4 posLightSpace = u_lightSpaceMatrix * vec4(worldPos, 1.0);
|
||||||
|
vec3 projCoords = posLightSpace.xyz / posLightSpace.w;
|
||||||
|
projCoords = projCoords * 0.5 + 0.5;
|
||||||
|
|
||||||
|
if (projCoords.z > 1.0) return 1.0;
|
||||||
|
|
||||||
|
float closestDepth = texture(u_shadowMap, projCoords.xy).r;
|
||||||
|
float currentDepth = projCoords.z;
|
||||||
|
|
||||||
|
return currentDepth - 0.005 > closestDepth ? 0.0 : 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 original = texture(u_sceneTexture, TexCoord);
|
vec4 original = texture(u_sceneTexture, TexCoord);
|
||||||
|
|
||||||
if (!u_underwater) {
|
if (!u_underwater) {
|
||||||
FragColor = original;
|
FragColor = original;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float rawDepth = texture(u_depthTexture, TexCoord).r;
|
||||||
|
vec3 ndc = vec3(TexCoord * 2.0 - 1.0, rawDepth * 2.0 - 1.0);
|
||||||
|
vec4 worldPosH = InverseViewProjection * vec4(ndc, 1.0);
|
||||||
|
vec3 worldPos = worldPosH.xyz / worldPosH.w;
|
||||||
|
float sceneDistance = distance(cameraPos, worldPos);
|
||||||
|
|
||||||
vec2 distoredUV = TexCoord;
|
vec2 distoredUV = TexCoord;
|
||||||
float strength = 0.003;
|
float strength = 0.003;
|
||||||
distoredUV.x += sin(TexCoord.y * 15.0 + u_time * 5.0) * strength;
|
distoredUV.x += sin(TexCoord.y * 15.0 + u_time * 5.0) * strength;
|
||||||
distoredUV.y += cos(TexCoord.x * 15.0 + u_time * 4.3) * strength;
|
distoredUV.y += cos(TexCoord.x * 15.0 + u_time * 4.3) * strength;
|
||||||
distoredUV = clamp(distoredUV, 0.001, 0.999);
|
distoredUV = clamp(distoredUV, 0.001, 0.999);
|
||||||
vec4 distorted = texture(u_sceneTexture, distoredUV);
|
vec4 distorted = texture(u_sceneTexture, distoredUV);
|
||||||
|
|
||||||
|
float rawCaustic = getCausticValue(TexCoord.x, TexCoord.y, u_time * 0.3);
|
||||||
|
float caustic = 0.5 + rawCaustic * 0.5;
|
||||||
|
vec3 causticLight = vec3(caustic * 0.9, caustic, caustic * 0.7);
|
||||||
|
|
||||||
float caustic = 0.9 + 0.1 * sin(TexCoord.x * 20.0 + u_time) * cos(TexCoord.y * 20.0 + u_time * 1.2);
|
|
||||||
vec3 causticLight = vec3(caustic, caustic * 0.95, caustic * 0.9);
|
|
||||||
//vec3 causticLight = vec3(1.0);
|
|
||||||
float fogFactor = clamp(1.0 - (TexCoord.y * u_fogDensity * 10.0), 0.0, 1.0);
|
float fogFactor = clamp(1.0 - (TexCoord.y * u_fogDensity * 10.0), 0.0, 1.0);
|
||||||
vec3 mixed = mix(u_waterColor, distorted.rgb * causticLight, fogFactor);
|
vec3 mixed = mix(u_waterColor, distorted.rgb * causticLight, fogFactor);
|
||||||
|
// Volume Scattering
|
||||||
|
vec3 rayOrigin = cameraPos;
|
||||||
|
vec3 rayDirection = normalize(rayDir);
|
||||||
|
|
||||||
FragColor = vec4(mixed, 1.0);
|
float maxDist = 10.0; // Maximum visible distance
|
||||||
|
float stepSize = 0.4;
|
||||||
|
float phasePower = 8.0; // Beam Sharpness
|
||||||
|
|
||||||
|
vec3 scattering = vec3(0.0);
|
||||||
|
float transmittance = 1.0;
|
||||||
|
|
||||||
|
float cosTheta = dot(rayDirection, sunDir);
|
||||||
|
float phase = pow(max(cosTheta, 0.0), phasePower);
|
||||||
|
|
||||||
|
for (float t = 0.0; t < maxDist; t += stepSize) {
|
||||||
|
|
||||||
|
if (t > sceneDistance) break;
|
||||||
|
vec3 pos = rayOrigin + rayDirection * t;
|
||||||
|
|
||||||
|
float shadow = getShadow(pos);
|
||||||
|
|
||||||
|
float density = waterDensity;
|
||||||
|
|
||||||
|
|
||||||
|
vec3 absorption = vec3(0.3, 0.08, 0.02); // Absorption coefficient per meter
|
||||||
|
vec3 sunLightAtPos = sunColor * exp(-absorption * t);
|
||||||
|
|
||||||
|
scattering += density * phase * sunLightAtPos * transmittance * stepSize * shadow;
|
||||||
|
|
||||||
|
float extinction = waterDensity * 1.5; // Extinction coefficient, tunable
|
||||||
|
transmittance *= exp(-extinction * stepSize);
|
||||||
|
if (transmittance < 0.01) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
FragColor.rgb = mixed + scattering;
|
||||||
|
FragColor.a = 1.0;
|
||||||
}
|
}
|
||||||
@@ -3,9 +3,18 @@
|
|||||||
layout (location = 0) in vec2 pos;
|
layout (location = 0) in vec2 pos;
|
||||||
layout (location = 1) in vec2 texCoord;
|
layout (location = 1) in vec2 texCoord;
|
||||||
|
|
||||||
out vec2 TexCoord;
|
uniform mat4 InverseViewProjection;
|
||||||
|
uniform vec3 cameraPos;
|
||||||
|
|
||||||
|
out vec2 TexCoord;
|
||||||
|
out vec3 rayDir;
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = vec4(pos.x, pos.y, 0.0, 1.0);
|
|
||||||
TexCoord = texCoord;
|
TexCoord = texCoord;
|
||||||
|
vec4 clipPos = vec4(pos, 1.0, 1.0);
|
||||||
|
vec4 worldPosH = InverseViewProjection * clipPos;
|
||||||
|
vec3 worldPos = worldPosH.xyz / worldPosH.w;
|
||||||
|
vec3 RayDir = worldPos - cameraPos;
|
||||||
|
rayDir = normalize(RayDir);
|
||||||
|
gl_Position = clipPos;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -237,9 +237,9 @@ void main() {
|
|||||||
vec3 sceneViewPos = reconstructViewPos(screenUV, sceneDepthRaw);
|
vec3 sceneViewPos = reconstructViewPos(screenUV, sceneDepthRaw);
|
||||||
float waterDepth = vert_pos.z - sceneViewPos.z;
|
float waterDepth = vert_pos.z - sceneViewPos.z;
|
||||||
waterDepth = max(waterDepth, 0.0);
|
waterDepth = max(waterDepth, 0.0);
|
||||||
// fully deep water
|
|
||||||
const float DEPTH_FADE_DISTANCE = 8.0;
|
const float DEPTH_FADE_DISTANCE = 10;
|
||||||
float depthFactor = underwater ? 0.0 : clamp(waterDepth / DEPTH_FADE_DISTANCE, 0.0, 1.0);
|
float depthFactor = clamp(waterDepth / DEPTH_FADE_DISTANCE, 0.0, 1.0);
|
||||||
|
|
||||||
if (underwater) {
|
if (underwater) {
|
||||||
reflectColor = vec3(0.0);
|
reflectColor = vec3(0.0);
|
||||||
@@ -287,7 +287,7 @@ void main() {
|
|||||||
|
|
||||||
if (enableDepthFade) {
|
if (enableDepthFade) {
|
||||||
vec3 shallowColor = vec3(0.4, 0.75, 0.7);
|
vec3 shallowColor = vec3(0.4, 0.75, 0.7);
|
||||||
vec3 deepColor = vec3(0.0, 0.08, 0.15);
|
vec3 deepColor = vec3(0.0, 0.015, 0.045);
|
||||||
|
|
||||||
vec3 waterTint = mix(shallowColor, deepColor, depthFactor);
|
vec3 waterTint = mix(shallowColor, deepColor, depthFactor);
|
||||||
|
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ constexpr float CROSS_NORMALS[2][6][3] = {
|
|||||||
{0.0f, 1.0f, 0.0f}}};
|
{0.0f, 1.0f, 0.0f}}};
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
// [-1, 1]
|
||||||
constexpr float QUAD_VERTICES[] = {
|
constexpr float QUAD_VERTICES[] = {
|
||||||
// postion // texcoorlds
|
// postion // texcoorlds
|
||||||
-1.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f,
|
-1.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f,
|
||||||
|
|||||||
@@ -45,10 +45,12 @@ public:
|
|||||||
float& cloud_threshold_low();
|
float& cloud_threshold_low();
|
||||||
float& cloud_threshold_high();
|
float& cloud_threshold_high();
|
||||||
float& refract_strength();
|
float& refract_strength();
|
||||||
|
float& underwater_fog_density();
|
||||||
|
float& water_density();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ParallelLight {
|
struct ParallelLight {
|
||||||
glm::vec3 sundir;
|
glm::vec3 sundir; // direction from sun to vertex
|
||||||
glm::vec3 lightdir;
|
glm::vec3 lightdir;
|
||||||
float sun_height = 0.0f;
|
float sun_height = 0.0f;
|
||||||
float day_light = 0.0f;
|
float day_light = 0.0f;
|
||||||
@@ -56,6 +58,7 @@ private:
|
|||||||
glm::vec3 sun_color;
|
glm::vec3 sun_color;
|
||||||
glm::vec3 directional_light_color;
|
glm::vec3 directional_light_color;
|
||||||
glm::vec3 finnal_ambient_color;
|
glm::vec3 finnal_ambient_color;
|
||||||
|
glm::mat4 light_space_matrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SkyUniform {
|
struct SkyUniform {
|
||||||
@@ -115,7 +118,7 @@ private:
|
|||||||
|
|
||||||
GLuint m_fbo = 0;
|
GLuint m_fbo = 0;
|
||||||
GLuint m_screen_texture = 0;
|
GLuint m_screen_texture = 0;
|
||||||
GLuint m_depth_texture = 0;
|
GLuint m_screen_depth_texture = 0;
|
||||||
|
|
||||||
GLuint m_oit_fbo = 0;
|
GLuint m_oit_fbo = 0;
|
||||||
GLuint m_accum_texture = 0;
|
GLuint m_accum_texture = 0;
|
||||||
@@ -152,6 +155,10 @@ private:
|
|||||||
|
|
||||||
float m_refract_strength = 0.03f;
|
float m_refract_strength = 0.03f;
|
||||||
|
|
||||||
|
float m_underwater_fog_density = 0.08f;
|
||||||
|
|
||||||
|
float m_water_density = 0.12f;
|
||||||
|
|
||||||
ParallelLight m_parallel_light;
|
ParallelLight m_parallel_light;
|
||||||
SkyUniform m_sky_uniform;
|
SkyUniform m_sky_uniform;
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -662,6 +662,11 @@ void DevPanel::show_shader_tab_item() {
|
|||||||
ImGui::Checkbox("Water Perturb", &m_app.renderer().water_perturb());
|
ImGui::Checkbox("Water Perturb", &m_app.renderer().water_perturb());
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::Checkbox("WaterDepthFade", &m_app.renderer().water_depth_fade());
|
ImGui::Checkbox("WaterDepthFade", &m_app.renderer().water_depth_fade());
|
||||||
|
ImGui::SliderFloat("Underwater Fog Density",
|
||||||
|
&m_app.renderer().underwater_fog_density(), 0.0f,
|
||||||
|
1.0f);
|
||||||
|
ImGui::SliderFloat("Water Density", &m_app.renderer().water_density(),
|
||||||
|
0.0f, 1.0f);
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ Renderer::~Renderer() {
|
|||||||
glDeleteVertexArrays(NUM_VAO, m_vao.data());
|
glDeleteVertexArrays(NUM_VAO, m_vao.data());
|
||||||
glDeleteFramebuffers(1, &m_fbo);
|
glDeleteFramebuffers(1, &m_fbo);
|
||||||
glDeleteTextures(1, &m_screen_texture);
|
glDeleteTextures(1, &m_screen_texture);
|
||||||
glDeleteTextures(1, &m_depth_texture);
|
glDeleteTextures(1, &m_screen_depth_texture);
|
||||||
|
|
||||||
glDeleteFramebuffers(1, &m_oit_fbo);
|
glDeleteFramebuffers(1, &m_oit_fbo);
|
||||||
glDeleteTextures(1, &m_accum_texture);
|
glDeleteTextures(1, &m_accum_texture);
|
||||||
@@ -443,11 +443,19 @@ void Renderer::render_underwater() {
|
|||||||
shader.set_loc("u_time", static_cast<float>(glfwGetTime()));
|
shader.set_loc("u_time", static_cast<float>(glfwGetTime()));
|
||||||
shader.set_loc("u_underwater", m_camera.is_under_water());
|
shader.set_loc("u_underwater", m_camera.is_under_water());
|
||||||
shader.set_loc("u_waterColor", glm::vec3(0.1f, 0.25f, 0.35f));
|
shader.set_loc("u_waterColor", glm::vec3(0.1f, 0.25f, 0.35f));
|
||||||
shader.set_loc("u_fogDensity", 0.08f);
|
shader.set_loc("u_fogDensity", m_underwater_fog_density);
|
||||||
|
shader.set_loc("cameraPos", m_camera.get_camera_pos());
|
||||||
|
shader.set_loc("sunDir", -m_parallel_light.sundir);
|
||||||
|
shader.set_loc("waterDensity", m_water_density);
|
||||||
|
shader.set_loc("InverseViewProjection", glm::inverse(m_p_mat * m_v_mat));
|
||||||
|
shader.set_loc("sunColor", m_parallel_light.sun_color);
|
||||||
|
shader.set_loc("u_lightSpaceMatrix", m_parallel_light.light_space_matrix);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, m_screen_texture);
|
glBindTexture(GL_TEXTURE_2D, m_screen_texture);
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_screen_depth_texture);
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_depth_map_texture);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
@@ -483,7 +491,7 @@ void Renderer::updata_framebuffer(int width, int height) {
|
|||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||||
|
|
||||||
glDeleteTextures(1, &m_screen_texture);
|
glDeleteTextures(1, &m_screen_texture);
|
||||||
glDeleteTextures(1, &m_depth_texture);
|
glDeleteTextures(1, &m_screen_depth_texture);
|
||||||
|
|
||||||
glGenTextures(1, &m_screen_texture);
|
glGenTextures(1, &m_screen_texture);
|
||||||
glBindTexture(GL_TEXTURE_2D, m_screen_texture);
|
glBindTexture(GL_TEXTURE_2D, m_screen_texture);
|
||||||
@@ -495,14 +503,14 @@ void Renderer::updata_framebuffer(int width, int height) {
|
|||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||||
m_screen_texture, 0);
|
m_screen_texture, 0);
|
||||||
|
|
||||||
glGenTextures(1, &m_depth_texture);
|
glGenTextures(1, &m_screen_depth_texture);
|
||||||
glBindTexture(GL_TEXTURE_2D, m_depth_texture);
|
glBindTexture(GL_TEXTURE_2D, m_screen_depth_texture);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, width, height, 0,
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, width, height, 0,
|
||||||
GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
|
||||||
m_depth_texture, 0);
|
m_screen_depth_texture, 0);
|
||||||
|
|
||||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
Logger::error("FBO incomplete after resize!");
|
Logger::error("FBO incomplete after resize!");
|
||||||
@@ -587,7 +595,7 @@ void Renderer::updata_framebuffer(int width, int height) {
|
|||||||
#pragma region render_world
|
#pragma region render_world
|
||||||
void Renderer::render_world() {
|
void Renderer::render_world() {
|
||||||
// shader map
|
// shader map
|
||||||
glm::mat4 light_space_matrix;
|
glm::mat4& light_space_matrix = m_parallel_light.light_space_matrix;
|
||||||
auto& m_render_snapshots = m_world.render_snapshots();
|
auto& m_render_snapshots = m_world.render_snapshots();
|
||||||
auto& camera_pos = m_camera.get_camera_pos();
|
auto& camera_pos = m_camera.get_camera_pos();
|
||||||
float texels_per_unit = 0.0f;
|
float texels_per_unit = 0.0f;
|
||||||
@@ -868,7 +876,7 @@ void Renderer::render_world() {
|
|||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, m_screen_texture);
|
glBindTexture(GL_TEXTURE_2D, m_screen_texture);
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glBindTexture(GL_TEXTURE_2D, m_depth_texture);
|
glBindTexture(GL_TEXTURE_2D, m_screen_depth_texture);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
for (const auto& snapshot : m_render_snapshots) {
|
for (const auto& snapshot : m_render_snapshots) {
|
||||||
@@ -980,4 +988,6 @@ float& Renderer::cloud_speed() { return m_cloud_speed; }
|
|||||||
float& Renderer::cloud_threshold_low() { return m_cloud_threshold_low; }
|
float& Renderer::cloud_threshold_low() { return m_cloud_threshold_low; }
|
||||||
float& Renderer::cloud_threshold_high() { return m_cloud_threshold_high; }
|
float& Renderer::cloud_threshold_high() { return m_cloud_threshold_high; }
|
||||||
float& Renderer::refract_strength() { return m_refract_strength; }
|
float& Renderer::refract_strength() { return m_refract_strength; }
|
||||||
|
float& Renderer::underwater_fog_density() { return m_underwater_fog_density; }
|
||||||
|
float& Renderer::water_density() { return m_water_density; }
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
Reference in New Issue
Block a user