feat(render3d): gpu.ludic - the seam for a second graphics API, and what the GPU can do
Render state (depth, blending, culling, colour writes, alpha-to-coverage, depth bias, scissor) and uniforms go through gpu_* / u_* and nowhere else; OpenGL state is cached and only changes reach the driver. Frames are bit-identical to before at the fixed viewpoints. R3D_GFX=gl|vk or gpu_request chooses a backend, falling back to OpenGL with a reason. gpu_caps_probe() asks Vulkan, on Windows, for the 1.3 floor, ray tracing, mesh shaders, the NVIDIA RTX generation, Reflex and HDR colour spaces, for a game's settings to grey out what a machine cannot use; R3D_CAPS pretends to be a given card for tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
208cad7ca1
commit
54eeef5f8d
17 changed files with 652 additions and 312 deletions
|
|
@ -144,17 +144,17 @@ function post_measure() -> void {
|
|||
if post_p_adapt == 0 { post_p_adapt = r3d_program("fullscreen.vert", "adapt.frag", "") }
|
||||
let next = 1 - post_adapt_i
|
||||
target_bind(post_adapt_t[next])
|
||||
gl_disable(GL_DEPTH_TEST)
|
||||
gpu_depth_test(false)
|
||||
gl_use_program(post_p_adapt)
|
||||
r3d_bind_2d(post_p_adapt, "u_scene", 0, post_hdr.color)
|
||||
r3d_bind_2d(post_p_adapt, "u_prev", 1, post_adapt_t[post_adapt_i].color)
|
||||
u_f(gl_uniform(post_p_adapt, "u_lod"), fi(post_mips - 1))
|
||||
u_f(gl_uniform(post_p_adapt, "u_key"), post_key)
|
||||
u_f(gl_uniform(post_p_adapt, "u_max"), post_exposure_max)
|
||||
u_f(gl_uniform(post_p_adapt, "u_rate"), fl(0.08))
|
||||
u_f(gpu_uniform(post_p_adapt, "u_lod"), fi(post_mips - 1))
|
||||
u_f(gpu_uniform(post_p_adapt, "u_key"), post_key)
|
||||
u_f(gpu_uniform(post_p_adapt, "u_max"), post_exposure_max)
|
||||
u_f(gpu_uniform(post_p_adapt, "u_rate"), fl(0.08))
|
||||
var reset = F_ZERO
|
||||
if post_adapt_reset { reset = F_ONE; post_adapt_reset = false }
|
||||
u_f(gl_uniform(post_p_adapt, "u_reset"), reset)
|
||||
u_f(gpu_uniform(post_p_adapt, "u_reset"), reset)
|
||||
mesh_draw(post_fs)
|
||||
post_adapt_i = next
|
||||
gl_bind_texture(GL_TEXTURE_2D, post_hdr.color)
|
||||
|
|
@ -164,11 +164,11 @@ function post_measure() -> void {
|
|||
function post_begin_scene() -> void {
|
||||
target_bind(post_hdr)
|
||||
if post_ms_fbo != 0 { gl_bind_framebuffer(GL_FRAMEBUFFER, post_ms_fbo); gl_enable(GL_MULTISAMPLE) }
|
||||
gl_enable(GL_DEPTH_TEST)
|
||||
gl_depth_func(GL_LESS)
|
||||
gl_depth_mask(1)
|
||||
gl_enable(GL_CULL_FACE)
|
||||
gl_cull_face(GL_BACK)
|
||||
gpu_depth_test(true)
|
||||
gpu_depth_func(GL_LESS)
|
||||
gpu_depth_write(true)
|
||||
gpu_cull(true)
|
||||
gpu_cull_face(GL_BACK)
|
||||
gl_clear_color(0.0, 0.0, 0.0, 1.0)
|
||||
gl_clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
||||
}
|
||||
|
|
@ -217,30 +217,30 @@ function post_capture_prev() -> void {
|
|||
}
|
||||
|
||||
function post_ssao_pass() -> void {
|
||||
gl_disable(GL_DEPTH_TEST)
|
||||
gl_disable(GL_BLEND)
|
||||
gpu_depth_test(false)
|
||||
gpu_blend(false)
|
||||
target_bind(post_ao)
|
||||
gl_use_program(post_p_ao)
|
||||
r3d_bind_2d(post_p_ao, "u_depth", 0, post_hdr.depth)
|
||||
r3d_bind_2d(post_p_ao, "u_prev_color", 1, post_prev.color)
|
||||
u_f(gl_uniform(post_p_ao, "u_frame"), fi(post_frame % 64))
|
||||
u_mat4(gl_uniform(post_p_ao, "u_inv_proj"), cam_inv_proj)
|
||||
u_mat4(gl_uniform(post_p_ao, "u_proj"), cam_proj)
|
||||
u_f2(gl_uniform(post_p_ao, "u_texel"), fr(1, post_w), fr(1, post_h))
|
||||
u_f(gl_uniform(post_p_ao, "u_radius"), post_ao_radius)
|
||||
u_f(gl_uniform(post_p_ao, "u_intensity"), post_ao_intensity)
|
||||
u_f(gpu_uniform(post_p_ao, "u_frame"), fi(post_frame % 64))
|
||||
u_mat4(gpu_uniform(post_p_ao, "u_inv_proj"), cam_inv_proj)
|
||||
u_mat4(gpu_uniform(post_p_ao, "u_proj"), cam_proj)
|
||||
u_f2(gpu_uniform(post_p_ao, "u_texel"), fr(1, post_w), fr(1, post_h))
|
||||
u_f(gpu_uniform(post_p_ao, "u_radius"), post_ao_radius)
|
||||
u_f(gpu_uniform(post_p_ao, "u_intensity"), post_ao_intensity)
|
||||
mesh_draw(post_fs)
|
||||
target_bind(post_ao_blur)
|
||||
gl_use_program(post_p_ao_blur)
|
||||
r3d_bind_2d(post_p_ao_blur, "u_ao", 0, post_ao.color)
|
||||
r3d_bind_2d(post_p_ao_blur, "u_depth", 1, post_hdr.depth)
|
||||
u_f2(gl_uniform(post_p_ao_blur, "u_texel"), fr(1, post_ao.w), fr(1, post_ao.h))
|
||||
u_f2(gpu_uniform(post_p_ao_blur, "u_texel"), fr(1, post_ao.w), fr(1, post_ao.h))
|
||||
mesh_draw(post_fs)
|
||||
}
|
||||
|
||||
function post_bloom_pass() -> void {
|
||||
gl_disable(GL_DEPTH_TEST)
|
||||
gl_disable(GL_BLEND)
|
||||
gpu_depth_test(false)
|
||||
gpu_blend(false)
|
||||
var src = post_color
|
||||
var sw = post_w; var sh = post_h
|
||||
gl_use_program(post_p_down)
|
||||
|
|
@ -248,60 +248,60 @@ function post_bloom_pass() -> void {
|
|||
let t = post_bloom[i]
|
||||
target_bind(t)
|
||||
r3d_bind_2d(post_p_down, "u_src", 0, src)
|
||||
u_f2(gl_uniform(post_p_down, "u_texel"), fr(1, sw), fr(1, sh))
|
||||
u_f2(gpu_uniform(post_p_down, "u_texel"), fr(1, sw), fr(1, sh))
|
||||
var th = f_neg1()
|
||||
if i == 0 { th = fl(1.2) }
|
||||
u_f(gl_uniform(post_p_down, "u_threshold"), th)
|
||||
u_f(gpu_uniform(post_p_down, "u_threshold"), th)
|
||||
mesh_draw(post_fs)
|
||||
src = t.color; sw = t.w; sh = t.h
|
||||
}
|
||||
gl_use_program(post_p_up)
|
||||
gl_enable(GL_BLEND)
|
||||
gl_blend_func(GL_ONE, GL_ONE)
|
||||
gpu_blend(true)
|
||||
gpu_blend_func(GL_ONE, GL_ONE)
|
||||
var i = BLOOM_LEVELS - 1
|
||||
while i > 0 {
|
||||
let from = post_bloom[i]
|
||||
let to = post_bloom[i - 1]
|
||||
target_bind(to)
|
||||
r3d_bind_2d(post_p_up, "u_src", 0, from.color)
|
||||
u_f2(gl_uniform(post_p_up, "u_texel"), fr(1, from.w), fr(1, from.h))
|
||||
u_f(gl_uniform(post_p_up, "u_radius"), F_ONE)
|
||||
u_f2(gpu_uniform(post_p_up, "u_texel"), fr(1, from.w), fr(1, from.h))
|
||||
u_f(gpu_uniform(post_p_up, "u_radius"), F_ONE)
|
||||
mesh_draw(post_fs)
|
||||
i -= 1
|
||||
}
|
||||
gl_disable(GL_BLEND)
|
||||
gpu_blend(false)
|
||||
}
|
||||
|
||||
function post_tonemap(color_tex: int) -> void {
|
||||
if post_auto { post_measure() }
|
||||
target_bind(post_ldr)
|
||||
gl_disable(GL_DEPTH_TEST)
|
||||
gpu_depth_test(false)
|
||||
gl_use_program(post_p_tone)
|
||||
r3d_bind_2d(post_p_tone, "u_hdr", 0, color_tex)
|
||||
r3d_bind_2d(post_p_tone, "u_bloom", 1, post_bloom[0].color)
|
||||
r3d_bind_2d(post_p_tone, "u_ao", 2, post_ao_blur.color)
|
||||
u_f(gl_uniform(post_p_tone, "u_ao_strength"), post_ao_strength)
|
||||
u_f(gl_uniform(post_p_tone, "u_gi_strength"), post_gi_strength)
|
||||
u_f(gl_uniform(post_p_tone, "u_exposure"), post_exposure)
|
||||
u_f(gpu_uniform(post_p_tone, "u_ao_strength"), post_ao_strength)
|
||||
u_f(gpu_uniform(post_p_tone, "u_gi_strength"), post_gi_strength)
|
||||
u_f(gpu_uniform(post_p_tone, "u_exposure"), post_exposure)
|
||||
var auto = F_ZERO
|
||||
if post_auto and post_adapt_t != null { auto = F_ONE; r3d_bind_2d(post_p_tone, "u_adapt", 3, post_adapt_t[post_adapt_i].color) }
|
||||
u_f(gl_uniform(post_p_tone, "u_auto"), auto)
|
||||
u_f(gl_uniform(post_p_tone, "u_bloom_strength"), post_bloom_strength)
|
||||
u_f(gl_uniform(post_p_tone, "u_vignette"), post_vignette)
|
||||
u_f(gl_uniform(post_p_tone, "u_saturation"), post_saturation)
|
||||
u_f(gl_uniform(post_p_tone, "u_contrast"), post_contrast)
|
||||
u_f3(gl_uniform(post_p_tone, "u_wb"), fl(1.02), F_ONE, fl(0.97))
|
||||
u_f3(gl_uniform(post_p_tone, "u_lift"), fl(0.004), fl(0.004), fl(0.012))
|
||||
u_f3(gl_uniform(post_p_tone, "u_gain"), fl(0.99), fl(0.995), fl(1.0))
|
||||
u_f(gpu_uniform(post_p_tone, "u_auto"), auto)
|
||||
u_f(gpu_uniform(post_p_tone, "u_bloom_strength"), post_bloom_strength)
|
||||
u_f(gpu_uniform(post_p_tone, "u_vignette"), post_vignette)
|
||||
u_f(gpu_uniform(post_p_tone, "u_saturation"), post_saturation)
|
||||
u_f(gpu_uniform(post_p_tone, "u_contrast"), post_contrast)
|
||||
u_f3(gpu_uniform(post_p_tone, "u_wb"), fl(1.02), F_ONE, fl(0.97))
|
||||
u_f3(gpu_uniform(post_p_tone, "u_lift"), fl(0.004), fl(0.004), fl(0.012))
|
||||
u_f3(gpu_uniform(post_p_tone, "u_gain"), fl(0.99), fl(0.995), fl(1.0))
|
||||
mesh_draw(post_fs)
|
||||
# sharpen + grain onto the screen
|
||||
gl_bind_framebuffer(GL_FRAMEBUFFER, gl_screen)
|
||||
gl_viewport(0, 0, gl_w, gl_h)
|
||||
gl_use_program(post_p_sharp)
|
||||
r3d_bind_2d(post_p_sharp, "u_src", 0, post_ldr.color)
|
||||
u_f2(gl_uniform(post_p_sharp, "u_texel"), fr(1, post_w), fr(1, post_h))
|
||||
u_f(gl_uniform(post_p_sharp, "u_amount"), post_sharpen)
|
||||
u_f(gl_uniform(post_p_sharp, "u_grain"), post_grain)
|
||||
u_f(gl_uniform(post_p_sharp, "u_time"), r3d_time)
|
||||
u_f2(gpu_uniform(post_p_sharp, "u_texel"), fr(1, post_w), fr(1, post_h))
|
||||
u_f(gpu_uniform(post_p_sharp, "u_amount"), post_sharpen)
|
||||
u_f(gpu_uniform(post_p_sharp, "u_grain"), post_grain)
|
||||
u_f(gpu_uniform(post_p_sharp, "u_time"), r3d_time)
|
||||
mesh_draw(post_fs)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue