fix(render): draw translucent water into planar reflections
Docs Deploy / Build and Deploy MkDocs (push) Successful in 37s
Docs Deploy / Build and Deploy MkDocs (push) Successful in 37s
This commit is contained in:
7 files changed
+112
-9
No files matched your search
@@ -75,7 +75,9 @@ void main() {
|
||||
if ((mode & 32) != 0 && (mode & 4) == 0 && in_world_position.z < frame.camera_position.w) {
|
||||
discard;
|
||||
}
|
||||
if ((mode & 64) != 0) {
|
||||
vec2 base_uv = vec2(material.base_page_x, material.base_page_y)
|
||||
+ in_uv * vec2(material.base_page_w, material.base_page_h);
|
||||
if ((mode & (64 | 256)) != 0) {
|
||||
vec2 reflection_uv = gl_FragCoord.xy / vec2(textureSize(reflection_color, 0));
|
||||
vec2 span = frame.embm_bounds.zw - frame.embm_bounds.xy;
|
||||
vec2 plane_uv = vec2(1.0) - (in_world_position.yx - frame.embm_bounds.yx) / span.yx;
|
||||
@@ -92,15 +94,16 @@ void main() {
|
||||
reflection_uv = displaced_clip.xy / displaced_clip.w * 0.5 + 0.5;
|
||||
}
|
||||
}
|
||||
vec3 rgb = texture(reflection_color, reflection_uv).rgb * in_base_diffuse + in_base_specular;
|
||||
vec3 water_color = (mode & 256) != 0
|
||||
? texture(base_color, base_uv).rgb
|
||||
: texture(reflection_color, reflection_uv).rgb;
|
||||
vec3 rgb = water_color * in_base_diffuse + in_base_specular;
|
||||
out_color = vec4(mix(rgb * in_color, frame.fog_color.rgb, in_fog_factor), material.diffuse_alpha);
|
||||
if (out_color.a < material.alpha_cutoff) {
|
||||
discard;
|
||||
}
|
||||
return;
|
||||
}
|
||||
vec2 base_uv = vec2(material.base_page_x, material.base_page_y)
|
||||
+ in_uv * vec2(material.base_page_w, material.base_page_h);
|
||||
vec2 detail_uv = vec2(material.detail_page_x, material.detail_page_y)
|
||||
+ in_detail_uv * vec2(material.detail_page_w, material.detail_page_h);
|
||||
vec2 overlay_uv = vec2(material.overlay_page_x, material.overlay_page_y)
|
||||
|
||||
Binary file not shown.
@@ -1936,7 +1936,16 @@ impl VulkanSmokeRenderer {
|
||||
&[],
|
||||
);
|
||||
let mut viewport_depth = None;
|
||||
for &range_index in &self.draw_order {
|
||||
// Native reflection queues the translucent water after the reflected world.
|
||||
let draw_order =
|
||||
self.draw_order
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(|&index| !reflected || !self.draw_ranges[index].terrain_reflection)
|
||||
.chain(self.draw_order.iter().copied().filter(|&index| {
|
||||
reflected && self.draw_ranges[index].terrain_reflection
|
||||
}));
|
||||
for range_index in draw_order {
|
||||
let range = self.draw_ranges.get(range_index).ok_or(
|
||||
VulkanSmokeRendererError::InvariantViolation {
|
||||
context: "stable draw order range handle",
|
||||
@@ -1948,11 +1957,17 @@ impl VulkanSmokeRenderer {
|
||||
},
|
||||
)?;
|
||||
let mode = self.material_unlit[texture_index].round() as i32;
|
||||
if reflected && (range.terrain_reflection || mode & 8 != 0) {
|
||||
if reflected && mode & 8 != 0 {
|
||||
continue;
|
||||
}
|
||||
let state = if reflected {
|
||||
super::reflection::reflected_pipeline_state(range.pipeline_state)
|
||||
let state =
|
||||
super::reflection::reflected_pipeline_state(range.pipeline_state);
|
||||
if range.terrain_reflection {
|
||||
fparkan_render::water::legacy_reflected_water_pipeline(state)
|
||||
} else {
|
||||
state
|
||||
}
|
||||
} else {
|
||||
range.pipeline_state
|
||||
};
|
||||
@@ -1998,7 +2013,12 @@ impl VulkanSmokeRenderer {
|
||||
std::slice::from_ref(descriptor_set),
|
||||
&[frame_offset, material_offset, point_light_offset],
|
||||
);
|
||||
let alpha_cutoff = range.alpha_test_cutoff().to_ne_bytes();
|
||||
let alpha_cutoff = if state.alpha_test {
|
||||
f32::from(range.alpha_test_reference) / 255.0
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
.to_ne_bytes();
|
||||
device.device().cmd_push_constants(
|
||||
command_buffer,
|
||||
resources.pipeline_layout,
|
||||
@@ -2017,8 +2037,13 @@ impl VulkanSmokeRenderer {
|
||||
.ok_or(VulkanSmokeRendererError::InvariantViolation {
|
||||
context: "draw-range diffuse-alpha override",
|
||||
})?;
|
||||
let diffuse_alpha_override = if reflected && range.terrain_reflection {
|
||||
Some(fparkan_render::water::REFLECTED_WATER_ALPHA)
|
||||
} else {
|
||||
*diffuse_alpha_override
|
||||
};
|
||||
let material_alphas =
|
||||
draw_material_alphas(*material_alpha, *diffuse_alpha_override)
|
||||
draw_material_alphas(*material_alpha, diffuse_alpha_override)
|
||||
.map(f32::to_ne_bytes)
|
||||
.concat();
|
||||
device.device().cmd_push_constants(
|
||||
@@ -2075,6 +2100,11 @@ impl VulkanSmokeRenderer {
|
||||
};
|
||||
let material_mode = (material_mode.round() as i32
|
||||
| if reflected { 32 } else { 0 }
|
||||
| if reflected && range.terrain_reflection {
|
||||
256
|
||||
} else {
|
||||
0
|
||||
}
|
||||
| if !reflected
|
||||
&& reflection_plane.is_some()
|
||||
&& self.reflection_planes[range_index] == reflection_plane
|
||||
|
||||
Reference in new issue
Block a user