Adding Variable Rate Shading support to Godot
Improve GI renderer and add VRS support Implement render device has_feature and move subgroup settings to limit_get
This commit is contained in:
parent
e3a8ab68ce
commit
d139131aab
44 changed files with 1574 additions and 466 deletions
|
|
@ -88,7 +88,7 @@ layout(set = 0, binding = 0) uniform sampler2DArray source_color;
|
|||
layout(set = 1, binding = 0) uniform sampler2DArray source_depth;
|
||||
layout(location = 1) out float depth;
|
||||
#endif /* MODE_TWO_SOURCES */
|
||||
#else
|
||||
#else /* MULTIVIEW */
|
||||
layout(set = 0, binding = 0) uniform sampler2D source_color;
|
||||
#ifdef MODE_TWO_SOURCES
|
||||
layout(set = 1, binding = 0) uniform sampler2D source_color2;
|
||||
|
|
@ -139,7 +139,7 @@ void main() {
|
|||
//uv.y = 1.0 - uv.y;
|
||||
uv = 1.0 - uv;
|
||||
}
|
||||
#endif
|
||||
#endif /* MODE_PANORAMA_TO_DP */
|
||||
|
||||
#ifdef MULTIVIEW
|
||||
vec4 color = textureLod(source_color, uv, 0.0);
|
||||
|
|
@ -148,12 +148,13 @@ void main() {
|
|||
depth = textureLod(source_depth, uv, 0.0).r;
|
||||
#endif /* MODE_TWO_SOURCES */
|
||||
|
||||
#else
|
||||
#else /* MULTIVIEW */
|
||||
vec4 color = textureLod(source_color, uv, 0.0);
|
||||
#ifdef MODE_TWO_SOURCES
|
||||
color += textureLod(source_color2, uv, 0.0);
|
||||
#endif /* MODE_TWO_SOURCES */
|
||||
#endif /* MULTIVIEW */
|
||||
|
||||
if (params.force_luminance) {
|
||||
color.rgb = vec3(max(max(color.r, color.g), color.b));
|
||||
}
|
||||
|
|
@ -163,5 +164,6 @@ void main() {
|
|||
if (params.srgb) {
|
||||
color.rgb = linear_to_srgb(color.rgb);
|
||||
}
|
||||
|
||||
frag_color = color;
|
||||
}
|
||||
|
|
|
|||
72
servers/rendering/renderer_rd/shaders/effects/vrs.glsl
Normal file
72
servers/rendering/renderer_rd/shaders/effects/vrs.glsl
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#[vertex]
|
||||
|
||||
#version 450
|
||||
|
||||
#VERSION_DEFINES
|
||||
|
||||
#ifdef MULTIVIEW
|
||||
#ifdef has_VK_KHR_multiview
|
||||
#extension GL_EXT_multiview : enable
|
||||
#define ViewIndex gl_ViewIndex
|
||||
#else // has_VK_KHR_multiview
|
||||
#define ViewIndex 0
|
||||
#endif // has_VK_KHR_multiview
|
||||
#endif //MULTIVIEW
|
||||
|
||||
#ifdef MULTIVIEW
|
||||
layout(location = 0) out vec3 uv_interp;
|
||||
#else
|
||||
layout(location = 0) out vec2 uv_interp;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
|
||||
uv_interp.xy = base_arr[gl_VertexIndex];
|
||||
#ifdef MULTIVIEW
|
||||
uv_interp.z = ViewIndex;
|
||||
#endif
|
||||
|
||||
gl_Position = vec4(uv_interp.xy * 2.0 - 1.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
#[fragment]
|
||||
|
||||
#version 450
|
||||
|
||||
#VERSION_DEFINES
|
||||
|
||||
#ifdef MULTIVIEW
|
||||
#ifdef has_VK_KHR_multiview
|
||||
#extension GL_EXT_multiview : enable
|
||||
#define ViewIndex gl_ViewIndex
|
||||
#else // has_VK_KHR_multiview
|
||||
#define ViewIndex 0
|
||||
#endif // has_VK_KHR_multiview
|
||||
#endif //MULTIVIEW
|
||||
|
||||
#ifdef MULTIVIEW
|
||||
layout(location = 0) in vec3 uv_interp;
|
||||
layout(set = 0, binding = 0) uniform sampler2DArray source_color;
|
||||
#else /* MULTIVIEW */
|
||||
layout(location = 0) in vec2 uv_interp;
|
||||
layout(set = 0, binding = 0) uniform sampler2D source_color;
|
||||
#endif /* MULTIVIEW */
|
||||
|
||||
layout(location = 0) out uint frag_color;
|
||||
|
||||
void main() {
|
||||
#ifdef MULTIVIEW
|
||||
vec3 uv = uv_interp;
|
||||
#else
|
||||
vec2 uv = uv_interp;
|
||||
#endif
|
||||
|
||||
#ifdef MULTIVIEW
|
||||
vec4 color = textureLod(source_color, uv, 0.0);
|
||||
#else /* MULTIVIEW */
|
||||
vec4 color = textureLod(source_color, uv, 0.0);
|
||||
#endif /* MULTIVIEW */
|
||||
|
||||
// See if we can change the sampler to one that returns int...
|
||||
frag_color = uint(color.r * 256.0);
|
||||
}
|
||||
|
|
@ -8,6 +8,12 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
|||
|
||||
#define M_PI 3.141592
|
||||
|
||||
/* Specialization Constants (Toggles) */
|
||||
|
||||
layout(constant_id = 0) const bool sc_half_res = false;
|
||||
layout(constant_id = 1) const bool sc_use_full_projection_matrix = false;
|
||||
layout(constant_id = 2) const bool sc_use_vrs = false;
|
||||
|
||||
#define SDFGI_MAX_CASCADES 8
|
||||
|
||||
//set 0 for SDFGI and render buffers
|
||||
|
|
@ -97,18 +103,20 @@ layout(set = 0, binding = 18, std140) uniform SceneData {
|
|||
}
|
||||
scene_data;
|
||||
|
||||
layout(r8ui, set = 0, binding = 19) uniform restrict readonly uimage2D vrs_buffer;
|
||||
|
||||
layout(push_constant, std430) uniform Params {
|
||||
uint view_index;
|
||||
uint max_voxel_gi_instances;
|
||||
bool high_quality_vct;
|
||||
bool orthogonal;
|
||||
uint view_index;
|
||||
|
||||
vec4 proj_info;
|
||||
|
||||
float z_near;
|
||||
float z_far;
|
||||
float pad1;
|
||||
float pad2;
|
||||
float pad3;
|
||||
}
|
||||
params;
|
||||
|
||||
|
|
@ -140,34 +148,34 @@ vec4 blend_color(vec4 src, vec4 dst) {
|
|||
}
|
||||
|
||||
vec3 reconstruct_position(ivec2 screen_pos) {
|
||||
#ifdef USE_MULTIVIEW
|
||||
vec4 pos;
|
||||
pos.xy = (2.0 * vec2(screen_pos) / vec2(scene_data.screen_size)) - 1.0;
|
||||
pos.z = texelFetch(sampler2D(depth_buffer, linear_sampler), screen_pos, 0).r * 2.0 - 1.0;
|
||||
pos.w = 1.0;
|
||||
if (sc_use_full_projection_matrix) {
|
||||
vec4 pos;
|
||||
pos.xy = (2.0 * vec2(screen_pos) / vec2(scene_data.screen_size)) - 1.0;
|
||||
pos.z = texelFetch(sampler2D(depth_buffer, linear_sampler), screen_pos, 0).r * 2.0 - 1.0;
|
||||
pos.w = 1.0;
|
||||
|
||||
pos = scene_data.inv_projection[params.view_index] * pos;
|
||||
pos = scene_data.inv_projection[params.view_index] * pos;
|
||||
|
||||
return pos.xyz / pos.w;
|
||||
#else
|
||||
vec3 pos;
|
||||
pos.z = texelFetch(sampler2D(depth_buffer, linear_sampler), screen_pos, 0).r;
|
||||
|
||||
pos.z = pos.z * 2.0 - 1.0;
|
||||
if (params.orthogonal) {
|
||||
pos.z = ((pos.z + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0;
|
||||
return pos.xyz / pos.w;
|
||||
} else {
|
||||
pos.z = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - pos.z * (params.z_far - params.z_near));
|
||||
}
|
||||
pos.z = -pos.z;
|
||||
vec3 pos;
|
||||
pos.z = texelFetch(sampler2D(depth_buffer, linear_sampler), screen_pos, 0).r;
|
||||
|
||||
pos.xy = vec2(screen_pos) * params.proj_info.xy + params.proj_info.zw;
|
||||
if (!params.orthogonal) {
|
||||
pos.xy *= pos.z;
|
||||
}
|
||||
pos.z = pos.z * 2.0 - 1.0;
|
||||
if (params.orthogonal) {
|
||||
pos.z = ((pos.z + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0;
|
||||
} else {
|
||||
pos.z = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - pos.z * (params.z_far - params.z_near));
|
||||
}
|
||||
pos.z = -pos.z;
|
||||
|
||||
return pos;
|
||||
#endif
|
||||
pos.xy = vec2(screen_pos) * params.proj_info.xy + params.proj_info.zw;
|
||||
if (!params.orthogonal) {
|
||||
pos.xy *= pos.z;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
void sdfvoxel_gi_process(uint cascade, vec3 cascade_pos, vec3 cam_pos, vec3 cam_normal, vec3 cam_specular_normal, float roughness, out vec3 diffuse_light, out vec3 specular_light) {
|
||||
|
|
@ -587,7 +595,6 @@ void voxel_gi_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3
|
|||
|
||||
vec4 fetch_normal_and_roughness(ivec2 pos) {
|
||||
vec4 normal_roughness = texelFetch(sampler2D(normal_roughness_buffer, linear_sampler), pos, 0);
|
||||
|
||||
normal_roughness.xyz = normalize(normal_roughness.xyz * 2.0 - 1.0);
|
||||
return normal_roughness;
|
||||
}
|
||||
|
|
@ -600,7 +607,7 @@ void process_gi(ivec2 pos, vec3 vertex, inout vec4 ambient_light, inout vec4 ref
|
|||
if (normal.length() > 0.5) {
|
||||
//valid normal, can do GI
|
||||
float roughness = normal_roughness.w;
|
||||
vec3 view = -normalize(mat3(scene_data.cam_transform) * (vertex - scene_data.eye_offset[params.view_index].xyz));
|
||||
vec3 view = -normalize(mat3(scene_data.cam_transform) * (vertex - scene_data.eye_offset[gl_GlobalInvocationID.z].xyz));
|
||||
vertex = mat3(scene_data.cam_transform) * vertex;
|
||||
normal = normalize(mat3(scene_data.cam_transform) * normal);
|
||||
vec3 reflection = normalize(reflect(-view, normal));
|
||||
|
|
@ -648,9 +655,35 @@ void process_gi(ivec2 pos, vec3 vertex, inout vec4 ambient_light, inout vec4 ref
|
|||
void main() {
|
||||
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
|
||||
|
||||
#ifdef MODE_HALF_RES
|
||||
pos <<= 1;
|
||||
#endif
|
||||
uint vrs_x, vrs_y;
|
||||
if (sc_use_vrs) {
|
||||
ivec2 vrs_pos;
|
||||
|
||||
// Currenty we use a 16x16 texel, possibly some day make this configurable.
|
||||
if (sc_half_res) {
|
||||
vrs_pos = pos >> 3;
|
||||
} else {
|
||||
vrs_pos = pos >> 4;
|
||||
}
|
||||
|
||||
uint vrs_texel = imageLoad(vrs_buffer, vrs_pos).r;
|
||||
// note, valid values for vrs_x and vrs_y are 1, 2 and 4.
|
||||
vrs_x = 1 << ((vrs_texel >> 2) & 3);
|
||||
vrs_y = 1 << (vrs_texel & 3);
|
||||
|
||||
if (mod(pos.x, vrs_x) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mod(pos.y, vrs_y) != 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sc_half_res) {
|
||||
pos <<= 1;
|
||||
}
|
||||
|
||||
if (any(greaterThanEqual(pos, scene_data.screen_size))) { //too large, do nothing
|
||||
return;
|
||||
}
|
||||
|
|
@ -663,10 +696,69 @@ void main() {
|
|||
|
||||
process_gi(pos, vertex, ambient_light, reflection_light);
|
||||
|
||||
#ifdef MODE_HALF_RES
|
||||
pos >>= 1;
|
||||
#endif
|
||||
if (sc_half_res) {
|
||||
pos >>= 1;
|
||||
}
|
||||
|
||||
imageStore(ambient_buffer, pos, ambient_light);
|
||||
imageStore(reflection_buffer, pos, reflection_light);
|
||||
|
||||
if (sc_use_vrs) {
|
||||
if (vrs_x > 1) {
|
||||
imageStore(ambient_buffer, pos + ivec2(1, 0), ambient_light);
|
||||
imageStore(reflection_buffer, pos + ivec2(1, 0), reflection_light);
|
||||
}
|
||||
|
||||
if (vrs_x > 2) {
|
||||
imageStore(ambient_buffer, pos + ivec2(2, 0), ambient_light);
|
||||
imageStore(reflection_buffer, pos + ivec2(2, 0), reflection_light);
|
||||
|
||||
imageStore(ambient_buffer, pos + ivec2(3, 0), ambient_light);
|
||||
imageStore(reflection_buffer, pos + ivec2(3, 0), reflection_light);
|
||||
}
|
||||
|
||||
if (vrs_y > 1) {
|
||||
imageStore(ambient_buffer, pos + ivec2(0, 1), ambient_light);
|
||||
imageStore(reflection_buffer, pos + ivec2(0, 1), reflection_light);
|
||||
}
|
||||
|
||||
if (vrs_y > 1 && vrs_x > 1) {
|
||||
imageStore(ambient_buffer, pos + ivec2(1, 1), ambient_light);
|
||||
imageStore(reflection_buffer, pos + ivec2(1, 1), reflection_light);
|
||||
}
|
||||
|
||||
if (vrs_y > 1 && vrs_x > 2) {
|
||||
imageStore(ambient_buffer, pos + ivec2(2, 1), ambient_light);
|
||||
imageStore(reflection_buffer, pos + ivec2(2, 1), reflection_light);
|
||||
|
||||
imageStore(ambient_buffer, pos + ivec2(3, 1), ambient_light);
|
||||
imageStore(reflection_buffer, pos + ivec2(3, 1), reflection_light);
|
||||
}
|
||||
|
||||
if (vrs_y > 2) {
|
||||
imageStore(ambient_buffer, pos + ivec2(0, 2), ambient_light);
|
||||
imageStore(reflection_buffer, pos + ivec2(0, 2), reflection_light);
|
||||
imageStore(ambient_buffer, pos + ivec2(0, 3), ambient_light);
|
||||
imageStore(reflection_buffer, pos + ivec2(0, 3), reflection_light);
|
||||
}
|
||||
|
||||
if (vrs_y > 2 && vrs_x > 1) {
|
||||
imageStore(ambient_buffer, pos + ivec2(1, 2), ambient_light);
|
||||
imageStore(reflection_buffer, pos + ivec2(1, 2), reflection_light);
|
||||
imageStore(ambient_buffer, pos + ivec2(1, 3), ambient_light);
|
||||
imageStore(reflection_buffer, pos + ivec2(1, 3), reflection_light);
|
||||
}
|
||||
|
||||
if (vrs_y > 2 && vrs_x > 2) {
|
||||
imageStore(ambient_buffer, pos + ivec2(2, 2), ambient_light);
|
||||
imageStore(reflection_buffer, pos + ivec2(2, 2), reflection_light);
|
||||
imageStore(ambient_buffer, pos + ivec2(2, 3), ambient_light);
|
||||
imageStore(reflection_buffer, pos + ivec2(2, 3), reflection_light);
|
||||
|
||||
imageStore(ambient_buffer, pos + ivec2(3, 2), ambient_light);
|
||||
imageStore(reflection_buffer, pos + ivec2(3, 2), reflection_light);
|
||||
imageStore(ambient_buffer, pos + ivec2(3, 3), ambient_light);
|
||||
imageStore(reflection_buffer, pos + ivec2(3, 3), reflection_light);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue