Every lit program blends toward the horizon colour (the prefiltered sky with the sun's inscatter, so it carries the day's grade); the sky's horizon band is pulled to the same colour, wider the closer the wall. The far plane, scatter and stream cull reach and the shadow cascades are clamped to the wall; the reflection pass shares the shaders and the cull. 0 is off: every branch is gated on u_fog_wall > 0 and r3d_reach hands back the far it was given. R3D_FOG_WALL=<m> for a shot. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
955 lines
42 KiB
Text
955 lines
42 KiB
Text
# env.ludic — the one gate every R3D_* switch goes through.
|
|
# The debug views, feature kills, file writers and hardware fakes are developer
|
|
# tools: a headless build (tests, benchmarks, frame dumps) always honours them, a
|
|
# windowed build - which is what a player runs - only when R3D_DEV is set to
|
|
# anything but "0". Read every R3D_* through r3d_env_has / r3d_env, never
|
|
# Os.has_env / Os.env.
|
|
export state Render3dState {
|
|
ac_lit: AcProg = null
|
|
ac_lit_cut: AcProg = null
|
|
ac_sh: AcProg = null
|
|
ac_sh_cut: AcProg = null
|
|
ac_out: AcProg = null
|
|
ac_out_cut: AcProg = null
|
|
@max(2048) ac_actors: []Actor = null
|
|
ac_next_id: int = 0
|
|
@max(2048) ac_spare: []Actor = null # released actors, taken again by actor_new (actor_release)
|
|
ac_frame: int = 0
|
|
ac_oq: []OutlineReq = null
|
|
ac_oq_n: int = 0 # live entries; the array is kept and reused
|
|
ac_oq_closed: bool = true
|
|
ac_census_at: int = -2
|
|
ac_proxy: Mesh = null # the capsule a figure casts in the far cascades (actor.ludic)
|
|
ac_proxy_s: floats = null # its scale and its world matrix, made with it
|
|
ac_proxy_m: floats = null
|
|
ac_lp0: floats = floats(3)
|
|
ac_lpx: floats = floats(3)
|
|
ac_lpy: floats = floats(3)
|
|
ac_lpz: floats = floats(3)
|
|
ac_cc_actors: int = 0
|
|
ac_cc_draws: int = 0
|
|
ac_cc_skinned: int = 0
|
|
ac_cc_cut: int = 0
|
|
cam_pos: floats = null # x, y, z
|
|
cam_yaw: float = 0.0 # radians, 0 = looking down -z
|
|
cam_pitch: float = 0.0
|
|
cam_fov: float = 0.0 # vertical, radians
|
|
cam_near: float = 0.0
|
|
cam_far: float = 0.0
|
|
cam_aspect: float = 0.0
|
|
cam_view: floats = null
|
|
cam_proj: floats = null
|
|
cam_vp: floats = null
|
|
cam_inv_vp: floats = null
|
|
cam_inv_proj: floats = null
|
|
cam_vp_clean: floats = null # view-projection, kept for depth reconstruction
|
|
cam_inv_vp_clean: floats = null
|
|
cam_fwd: floats = null
|
|
cam_right: floats = null
|
|
cam_planes: floats = floats(16)
|
|
day_on: bool = false
|
|
day_hours: float = 0.0 # float bits, 0 .. 24
|
|
day_light: float = 0.0 # 0 night .. 1 full day (float bits)
|
|
day_ibl: floats = null # rgb scale on the sky's light
|
|
day_sun_base: floats = null # the HDRI's sun radiance, kept
|
|
day_az0: float = 0.0 # the sun's azimuth at the reference hour (radians, yaw convention)
|
|
day_yaw0: float = 0.0 # the sky yaw the scene was tuned at
|
|
day_hour0: float = 0.0 # the hour the photograph was taken (10.5)
|
|
day_dir: float = 0.0 # +1 / -1: which way the sun travels in yaw
|
|
day_az: float = 0.0
|
|
day_el: float = 0.0
|
|
day_gen: int = 0 # bumps when the light moved enough to rebake the terrain shadow
|
|
day_baked_az: float = 0.0
|
|
day_baked_el: float = 0.0
|
|
day_sky_baked: float = 0.0 # the sky yaw the convolutions were baked at
|
|
fire_pos: floats = null
|
|
fire_color: floats = null
|
|
day_moon: bool = false
|
|
day_moon_phase: float = 0.5 # 0.5: full, which is where the game used to be
|
|
day_moon_illum: float = 1.0 # the lit fraction, derived from the phase
|
|
day_moon_dir: floats = null # toward the moon, whether or not it is up
|
|
hand_pos: floats = null
|
|
hand_color: floats = null
|
|
hand_dir: floats = null
|
|
hand_cone: float = 0.0
|
|
hand_reach: float = 0.0 # metres the hand light reaches (float bits)
|
|
day_overcast: float = 0.0 # 0 clear .. 1 a low grey sky (float bits): dims the sun and the sky's light
|
|
day_flash: float = 0.0 # a lightning flash this frame (0..1): the sun brightens for it
|
|
day_fog_mul: float = 1.0 # multiplies the base fog density (rain and snow thicken the air)
|
|
day_fog_base: float = 0.0
|
|
ds_on: int = -1 # -1: not read yet
|
|
ds_counting: bool = false
|
|
ds_from: int = 90
|
|
ds_frames: int = 60
|
|
ds_frame_no: int = 0
|
|
ds_outside: pointer = "(outside passes)"
|
|
ds_pass_names: []pointer = null
|
|
ds_pass_prog: []long = null # program changes inside the pass
|
|
ds_pass_tex: []long = null # texture binds inside the pass
|
|
ds_pass_i: int = 0
|
|
ds_row_pass: []int = null
|
|
ds_row_prog: []int = null
|
|
ds_row_kind: []int = null
|
|
ds_row_draws: []long = null
|
|
ds_row_inst: []long = null
|
|
ds_row_idx: []long = null
|
|
ds_last: int = -1
|
|
r3d_dev_v: int = -1
|
|
gltf_dir: string = null
|
|
gltf_bin: pointer = null
|
|
gltf_doc: Val = null
|
|
gltf_count: int = 0
|
|
gltf_ctype: int = 0
|
|
gltf_comps: int = 0
|
|
gltf_tex_paths: []pointer = null
|
|
gltf_tex_ids: words = null
|
|
gltf_tex_refs: words = null # how many primitives use each cached texture (model_release)
|
|
gltf_tex_n: int = 0
|
|
gltf_white: int = 0
|
|
gltf_flat: int = 0
|
|
gltf_mat_names: []string = null
|
|
gltf_mat_diff: words = null
|
|
gltf_mat_nrm: words = null
|
|
gltf_mat_arm: words = null
|
|
gltf_mat_n: int = 0
|
|
gltf_kept: []Model = null # gltf_cached's: a still model by dir, file and node, loaded once
|
|
gltf_kept_dir: []string = null
|
|
gltf_kept_file: []string = null
|
|
gltf_kept_node: []string = null
|
|
gltf_cutout: bool = false # the material being loaded is alpha-blended (a cut-out atlas)
|
|
gpu_kind: int = 0 # the backend running; 0 until gpu_select
|
|
gpu_wanted: int = 0 # what was asked for (setting or R3D_GFX)
|
|
gpu_fallback_reason: string = null # why the wanted backend is not the one running
|
|
gpu_s_depth_test: int = -1
|
|
gpu_s_depth_func: int = -1
|
|
gpu_s_depth_write: int = -1
|
|
gpu_s_blend: int = -1
|
|
gpu_s_blend_src: int = -1
|
|
gpu_s_blend_dst: int = -1
|
|
gpu_s_cull: int = -1
|
|
gpu_s_cull_face: int = -1
|
|
gpu_s_color_write: int = -1
|
|
gpu_s_a2c: int = -1
|
|
gpu_s_bias: int = -1
|
|
gpu_s_bias_f: float = 0.0 # float bits, for a backend that bakes the bias into a pipeline
|
|
gpu_s_bias_u: float = 0.0
|
|
gpu_s_scissor: int = -1
|
|
gpu_prog_ids: []int = null
|
|
gpu_prog_keys: []string = null
|
|
gpu_prog_cur: int = 0
|
|
gpu_u_tmp: words = words(4)
|
|
gpu_cap_probed: bool = false
|
|
gpu_cap_windows: bool = false # the advanced features exist on this platform at all
|
|
gpu_cap_vulkan: bool = false # a Vulkan loader, an instance and a device
|
|
gpu_cap_floor: bool = false # Vulkan 1.3 with everything the renderer's floor needs
|
|
gpu_cap_rt: bool = false # ray query + acceleration structures
|
|
gpu_cap_mesh: bool = false # VK_EXT_mesh_shader
|
|
gpu_cap_nvidia: bool = false
|
|
gpu_cap_rtx: int = 0 # the RTX generation (20, 30, 40, 50); 0 = not RTX
|
|
gpu_cap_reflex: bool = false # VK_NV_low_latency2
|
|
gpu_cap_hdr: bool = false # the instance offers HDR colour spaces
|
|
gpu_cap_device: string = ""
|
|
gpu_tx: words = null
|
|
gpu_tx_cap: int = 0
|
|
gpu_bound_2d: int = 0
|
|
gpu_bound_array: int = 0
|
|
gpu_unit_2d: words = null
|
|
gpu_unit_cur: int = 0
|
|
gpu_fb: words = null
|
|
gpu_fb_cap: int = 0
|
|
gpu_fb_cur: int = 0
|
|
gpu_rb_samples: int = 0
|
|
gpu_drawbufs: words = null
|
|
gpu_variants: []GpuVariant = null
|
|
gvk_ready: bool = false
|
|
gvk_inst: pointer = null
|
|
gvk_pd: pointer = null
|
|
gvk_dev: pointer = null
|
|
gvk_queue: pointer = null
|
|
gvk_family: int = -1
|
|
gvk_mp: bytes = null # VkPhysicalDeviceMemoryProperties
|
|
gvk_device_name: string = ""
|
|
gvk_sc_dead: int = 0 # textures released since the kept-set cache was emptied
|
|
gvk_read_px: bytes = null # gvk_read_screen's read-back, gvk_read_cap bytes, made again only at a new size
|
|
gvk_read_cap: int = 0
|
|
gvk_renderer_name: string = "" # "<device> (Vulkan)", made once with the device
|
|
gvk_why: string = "" # why the device did not come up, for the fallback notice
|
|
gvk_max_aniso: int = 0x3F800000 # the device's anisotropy limit as float bits; 1.0 when it has none
|
|
gvk_want_surface: bool = false # set before gvk_init when the renderer will present to a window
|
|
gvk_has_surface: bool = false # the instance and device can make a surface and a swapchain
|
|
gvk_errlog: string = null
|
|
gvk_errlog_read: bool = false
|
|
gvk_has_mdi: bool = false # multiDrawIndirect + drawIndirectFirstInstance
|
|
gvk_has_dic: bool = false # drawIndirectCount
|
|
gvk_has_mesh: bool = false # VK_EXT_mesh_shader with its meshShader feature on
|
|
gvk_mesh_fn: pointer = null # vkCmdDrawMeshTasksEXT: the device's own, the interposer exports none
|
|
gvk_n_allocs: int = 0
|
|
gvk_blk_mem: []long = null
|
|
gvk_blk_kind: []int = null # memory type * 2, + 1 for images
|
|
gvk_blk_size: []int = null
|
|
gvk_blk_map: []pointer = null
|
|
@max(4096) gvk_fr_blk: []int = null # free ranges: block, offset, length (0 = an unused slot)
|
|
@max(4096) gvk_fr_off: []int = null
|
|
@max(4096) gvk_fr_len: []int = null
|
|
gvk_al_blk: []int = null # per allocation id: its block, or -1 for its own memory
|
|
gvk_al_mem: []long = null # its own memory when it has one
|
|
gvk_al_off: []int = null
|
|
gvk_al_len: []int = null
|
|
gvk_al_map: []pointer = null
|
|
@max(4096) gvk_al_spare: []int = null # ids to reuse
|
|
gvk_pool: long = 0
|
|
gvk_fence: bytes = null
|
|
gvk_frame_fence: bytes = null # the presented frame still on the GPU (one frame in flight)
|
|
gvk_tmp_buf: pointer = null # the per-call scratch ring (gvk_tmp)
|
|
gvk_tmp_off: int = 0
|
|
gvk_seen: words = null # gvk_draw's vertex buffers already bound, reused
|
|
gvk_frame_pending: bool = false
|
|
gvk_frame_pending_cb: pointer = null
|
|
gvk_frame_pending_no: int = -1 # which frame it is (gvk_frame_no when it was submitted)
|
|
gvk_dpools: []long = null # a descriptor pool per frame slot (frame_no & 1)
|
|
gvk_ring_end: int = 0 # the end of this frame's half of the ring
|
|
@max(4096) gvk_retired_frame: []int = null # the last frame that read each retired buffer
|
|
gvk_labels: bool = false # R3D_VK_LABELS: each profiled pass is a debug label (Metal System Trace)
|
|
gvk_inflight: int = -1
|
|
gvk_nopool: bool = false
|
|
gvk_bc_said: int = 0 # attachments refused for being compressed, said so far
|
|
gvk_map_slot: []pointer = null # gvk_mem_new's mapped-pointer slot, made once
|
|
gvk_lay_sig: words = null # gvk_layout_id's scratch: one layout as numbers
|
|
gvk_lay_seen: words = null
|
|
gvk_lay_flat: []int = null # every layout known, end to end; gvk_lay_off / _len find each
|
|
gvk_lay_off: []int = null
|
|
gvk_lay_len: []int = null
|
|
@max(4096) gvk_tex_spare: []int = null # ids of freed textures, handed out again by gvk_tex_new
|
|
@max(4096) gvk_buf_spare: []int = null # the same for buffers (gvk_buf_delete)
|
|
gvk_has_bc: bool = false # textureCompressionBC: .dds textures are uploaded compressed
|
|
# R3D_VK_PROF: Vulkan objects made and destroyed, reported every 120 frames
|
|
gvk_mk_img: int = 0
|
|
gvk_mk_view: int = 0
|
|
gvk_mk_buf: int = 0
|
|
gvk_mk_mem: int = 0
|
|
gvk_mk_smp: int = 0
|
|
gvk_mk_set: int = 0
|
|
gvk_mk_cmd: int = 0
|
|
gvk_mk_dpool: int = 0
|
|
gvk_mk_x_img: int = 0
|
|
gvk_mk_x_view: int = 0
|
|
gvk_mk_x_buf: int = 0
|
|
gvk_mk_x_mem: int = 0
|
|
gvk_label_depth: int = 0 # -1 until asked: 1 leaves the presented frame in flight
|
|
gvk_has_hqr: bool = false
|
|
gvk_ts_period: float = 0.0 # float bits: nanoseconds per timestamp tick
|
|
gvk_qpool: long = 0
|
|
gvk_q_active: int = -1
|
|
gvk_prog_var: []GpuVariant = null
|
|
gvk_prog_vs: []long = null
|
|
gvk_prog_fs: []long = null
|
|
gvk_prog_dsl: []long = null
|
|
gvk_prog_layout: []long = null
|
|
gvk_spv_dir: string = ""
|
|
gvk_spv_len: int = 0
|
|
gvk_prog_mesh: []int = null
|
|
gvk_cp_pipe: []long = null
|
|
gvk_cp_layout: []long = null
|
|
gvk_cp_dsl: []long = null
|
|
gvk_cp_nbuf: []int = null
|
|
gvk_cp_ntex: []int = null
|
|
gvk_pipe_keys: []string = null
|
|
gvk_pipe: []long = null
|
|
gvk_zero_vbuf: int = 0
|
|
gvk_skip_said: words = null # per program: its skipped draws have been reported
|
|
gvk_ublk_v: []bytes = null # per program: the vertex stage's block as last set
|
|
gvk_ublk_f: []bytes = null
|
|
gvk_prog_tex: []words = null # per program: the texture bound to each manifest sampler
|
|
gvk_prog_unit: []words = null # per program: the unit + 1 each sampler was pointed at with u_i
|
|
gvk_prog_dirty: []int = null # per program: its blocks or textures changed since its last set
|
|
gvk_set_last: []long = null # per program: the descriptor set its last draw used
|
|
gvk_set_frame: []int = null # per program: the frame that set belongs to
|
|
gvk_set_tex: []words = null # per program: the textures that set was filled with
|
|
gvk_ring_buf: int = 0 # a gvk_buf handle
|
|
gvk_ring_off: int = 0
|
|
gvk_ring_align: int = 256
|
|
gvk_dpool: long = 0
|
|
gvk_white: int = 0 # a 1x1 white texture for a sampler nothing was bound to
|
|
gvk_msaa_max: int = 0 # samples the scene may use (gvk_frame_init reads the device's limits)
|
|
gvk_kpool: long = 0
|
|
gvk_sc_prog: []int = null # per cached set: its program
|
|
gvk_sc_koff: []int = null # per cached set: where its key starts in gvk_sc_keys
|
|
gvk_sc_set: []long = null
|
|
gvk_sc_next: []int = null # the program's next cached set, -1 at the end
|
|
gvk_sc_keys: []long = null # per texture of a key: handle * 65536 + generation, sampler
|
|
gvk_sc_head: words = null # per program (< 4096): its most recently made set, -1 if none
|
|
@max(130) gvk_sc_tmp: []long = null # this draw's key while it is looked up
|
|
gvk_set_offs: bytes = null # this draw's dynamic offsets, in binding order
|
|
gvk_set_ndyn: int = 0
|
|
@max(4096) gvk_ub_frame: []int = null # per program: the frame its blocks were last copied into the ring
|
|
@max(4096) gvk_ub_offv: []int = null
|
|
@max(4096) gvk_ub_offf: []int = null
|
|
gvk_sc_made: int = 0 # sets made since start (R3D_VK_PROF)
|
|
gvk_default_smp: long = 0 # linear, clamped: for a texture slot nothing was bound to
|
|
gvk_cb: pointer = null
|
|
gvk_in_pass: bool = false
|
|
gvk_fb_cur: int = 0
|
|
gvk_fb_read: int = 0
|
|
gvk_fb_draw: int = 0
|
|
gvk_pass_w: int = 0
|
|
gvk_pass_h: int = 0
|
|
gvk_pass_ncolor: int = 0
|
|
gvk_pass_cfmt: int = 0
|
|
gvk_pass_dfmt: int = 0
|
|
gvk_pass_samples: int = 1 # the attachments' sample count, which every pipeline in the pass must match
|
|
gvk_pass_col: words = null # the pass's colour attachments: texture, layer + 1
|
|
gvk_pass_dep: words = null # its depth attachment: texture, layer + 1
|
|
gvk_clear_bits: int = 0 # GL_COLOR_BUFFER_BIT / GL_DEPTH_BUFFER_BIT waiting for the pass
|
|
gvk_clear_rgba: floats = null # float bits
|
|
gvk_vp: words = null # x, y, w, h
|
|
gvk_sc: words = null # scissor on, x, y (OpenGL rows), w, h
|
|
gvk_screen_color: int = 0
|
|
gvk_screen_depth: int = 0
|
|
gvk_screen_w: int = 0
|
|
gvk_screen_h: int = 0
|
|
gvk_layer_views: []int = null # generation * 4096 + layer, beside gvk_layer_view_tex
|
|
gvk_layer_view: []long = null
|
|
gvk_layer_view_tex: []int = null # the texture each cached view is of, so a release drops them
|
|
gvk_fb_ncolor: words = null # per framebuffer: colour slots drawn (draw buffers; 0 = none)
|
|
gvk_hdr_want: bool = false # r3d_hdr: the setting
|
|
gvk_hdr_on: bool = false # the swapchain is HDR10 now
|
|
gvk_has_colorspace: bool = false # the instance took VK_EXT_swapchain_colorspace
|
|
gvk_has_hdr_meta: bool = false # the device took VK_EXT_hdr_metadata
|
|
r3d_hdr_peak: float = 0.0 # 0 until r3d_hdr_calibrate: 1000
|
|
r3d_hdr_paper: float = 0.0 # 200
|
|
r3d_hdr_black: float = 0.0 # 0
|
|
gvk_fb_counter: int = 0
|
|
gvk_prog_counter: int = 0
|
|
gvk_wireframe: int = 0
|
|
gvk_state: GvkState = null
|
|
gvk_ind_buf: int = 0
|
|
gvk_ind_off: int = 0
|
|
gvk_ind_n: int = 0
|
|
gvk_ind_cbuf: int = 0
|
|
gvk_ind_coff: int = 0
|
|
gvk_mesh_x: int = 0
|
|
gvk_mesh_y: int = 0
|
|
gvk_mesh_z: int = 0
|
|
gvk_surface: long = 0
|
|
gvk_swap: long = 0
|
|
gvk_swap_n: int = 0
|
|
gvk_swap_images: bytes = null
|
|
gvk_swap_fmt: int = 0
|
|
gvk_swap_w: int = 0
|
|
gvk_swap_h: int = 0
|
|
gvk_vsync: bool = true
|
|
gvk_acq_fence: bytes = null
|
|
gvk_swap_stale: bool = false
|
|
gvk_size_buf: words = null
|
|
gvk_prof_state: int = -1
|
|
gvk_us_pipe: long = 0
|
|
gvk_us_set: long = 0
|
|
gvk_us_draw: long = 0
|
|
gvk_n_draws: int = 0
|
|
gvk_n_asked: int = 0 # draws that reached gvk_draw_now: every one the renderer asked for
|
|
gvk_n_flush: int = 0
|
|
gvk_prof_frames: int = 0
|
|
gvk_n_pipe_new: int = 0 # pipelines made this profile window
|
|
gvk_pc_prog: []int = null
|
|
gvk_pc_layout: []int = null
|
|
gvk_pc_state: []int = null
|
|
gvk_pc_bias: []int = null
|
|
gvk_pc_pass: []int = null
|
|
gvk_pc_pipe: []long = null
|
|
gvk_pc_last: words = null
|
|
gvk_tex_image: []long = null
|
|
gvk_tex_view: []long = null
|
|
gvk_tex_mem: []long = null
|
|
gvk_tex_levels: []int = null
|
|
gvk_tex_layers: []int = null
|
|
gvk_tex_vkfmt: []int = null
|
|
gvk_tex_dims_w: []int = null
|
|
gvk_tex_dims_h: []int = null
|
|
gvk_tex_glfmt: []int = null # the format the renderer asked for (gpu.ludic's vocabulary)
|
|
gvk_tex_array: []int = null # 1 for an array image
|
|
gvk_tex_gen: []int = null # bumped whenever the image behind a handle is replaced
|
|
gvk_tex_smp_sig: []int = null # the sampling parameters the cached sampler was made for
|
|
gvk_tex_smp: []long = null
|
|
gvk_tex_samples: []int = null # 1, or the sample count of a multisampled renderbuffer
|
|
gvk_storage_samples: int = 1 # what the next gvk_tex_storage makes: gpu_rb_storage sets it around its call
|
|
gvk_unpack_swap: bool = false # GL_UNPACK_SWAP_BYTES: 16-bit PNG samples arrive big-endian
|
|
gvk_st_buf: long = 0
|
|
gvk_st_mem: long = 0
|
|
gvk_smp_keys: []int = null # 7 numbers per sampler: filters, wraps, compare, anisotropy, bias
|
|
gvk_smp: []long = null
|
|
gvk_buf: []long = null
|
|
gvk_buf_mem: []long = null
|
|
gvk_buf_size: []int = null
|
|
gvk_buf_map: []pointer = null # host-visible buffers stay mapped for their whole life
|
|
gvk_buf_used: []int = null # the frame (gvk_frame_no) a draw last bound the buffer in
|
|
gvk_bsp_buf: []long = null # per handle, a second buffer a re-filled one swaps with (gvk_buf_reserve)
|
|
gvk_bsp_mem: []long = null
|
|
gvk_bsp_size: []int = null
|
|
gvk_bsp_map: []pointer = null
|
|
gvk_bsp_used: []int = null
|
|
gvk_frame_no: int = 1
|
|
@max(4096) gvk_retired_buf: []long = null
|
|
@max(4096) gvk_retired_mem: []long = null
|
|
@max(16384) gvk_buf_gpu: []int = null
|
|
grass_prog: int = 0
|
|
grass_mesh: Mesh = null
|
|
grass_on: bool = true
|
|
grass_wind: float = 0.0
|
|
grass_s0: float = 0.0 # float bits: blade spacing at the camera (m)
|
|
grass_d0: float = 0.0 # the distance at which the spacing has doubled (m)
|
|
grass_radius: float = 0.0 # no blades past this (m)
|
|
grass_draws: int = 0
|
|
grass_dbg: int = 0
|
|
grass_merge: bool = false
|
|
grass_rec: words = null # VkDrawIndexedIndirectCommand records, 5 words each
|
|
grass_tv: floats = null # per record: corner x, corner z, indices per cell, 0 (float bits)
|
|
grass_chunk_tv: floats = null
|
|
grass_n: int = 0
|
|
grass_cmds: int = 0
|
|
grass_band_start: words = null # per band: its first record
|
|
grass_band_cells: words = null # ... and its cells per tile side
|
|
grass_band_n: int = 0
|
|
gg_on: bool = false # the blades are culled on the GPU (grass_gpu.ludic)
|
|
gg_reset: int = 0
|
|
gg_cull: int = 0
|
|
gg_prog: int = 0
|
|
gg_tiles_buf: []int = null
|
|
gg_tv: floats = null
|
|
gg_out: int = 0
|
|
gg_cmds: int = 0
|
|
gg_mesh: []Mesh = null
|
|
gg_n: int = 0
|
|
gg_max: int = 0
|
|
gg_rb: words = null # the per-frame dispatch arguments, made once (grass_gpu.ludic)
|
|
gg_cb: words = null
|
|
gg_bufs: words = null
|
|
gg_texs: words = null
|
|
gg_pr: words = null
|
|
grass_band_mesh: []Mesh = null # per band: the blade it draws (rows fall with distance)
|
|
grass_mesh3: Mesh = null # three rows: the middle distance
|
|
grass_mesh2: Mesh = null # two rows, one quad: far enough that the arch is under a pixel
|
|
grass_mesh_on: bool = false
|
|
grass_mesh_prog: int = 0
|
|
r3d_draw_cb: fn() = null
|
|
r3d_casters_cb: fn(floats) = null
|
|
r3d_fill_cb: fn(Stream, int, int, int) = null
|
|
ov_prog: int = 0
|
|
ov_mesh: Mesh = null
|
|
ov_vbo: int = 0
|
|
ov_buf: pointer = null
|
|
ov_n: int = 0
|
|
ov_tex: int = 0
|
|
ov_mode: int = 2 # what the next quads read: 0 the image texture, 1 the font, 2 a flat colour
|
|
ov_voff: float = 0.0 # float bits: 4 x ov_mode, added to v (overlay.frag)
|
|
ov_white: int = 0
|
|
ov_font: int = 0
|
|
ov_font_adv: floats = null # float bits, em units, one per glyph in the atlas
|
|
ov_font_n: int = 0 # glyphs in the atlas
|
|
ov_font_map: words = null
|
|
ov_font_hi_cp: words = null # code points >= OV_MAP_N, ascending
|
|
ov_font_hi_g: words = null
|
|
ov_font_hi_n: int = 0
|
|
ov_font_space: int = 0 # the glyph for ' ', and for what has none: '?'
|
|
ov_font_qmark: int = 0
|
|
ov_font_cols: int = 16
|
|
ov_font_rows: int = 6
|
|
ov_font_cell: int = 128 # px per cell in the atlas
|
|
ov_font_em: int = 100 # px per em in the atlas
|
|
ov_pad_x: float = 0.0 # float bits, em
|
|
ov_base_y: float = 0.0
|
|
ov_ready: bool = false
|
|
ov_open: bool = false
|
|
ov_dbg: bool = false
|
|
ov_ranges: words = null
|
|
ov_nr: int = 0
|
|
ov_range_start: int = 0
|
|
ov_clip_x: int = 0 # the current clip rectangle in screen pixels (top-left origin)
|
|
ov_clip_y: int = 0
|
|
ov_clip_w: int = 0
|
|
ov_clip_h: int = 0
|
|
ov_prog_sdr: int = 0
|
|
ov_prog_hdr: int = 0
|
|
ov_hdr_scale: float = 0.0 # float bits; 0 until ov_begin sets 1
|
|
ov_u8_len: int = 1
|
|
post_hdr: Target = null
|
|
post_ms_fbo: int = 0 # 4x multisampled scene target, resolved into post_hdr
|
|
post_ms_samples: int = 1 # temporal AA carries the edges; R3D_MSAA=n to compare
|
|
post_bloom: []Target = null
|
|
post_p_down: int = 0
|
|
post_p_up: int = 0
|
|
post_p_tone: int = 0
|
|
post_fs: Mesh = null
|
|
post_exposure: float = 0.0
|
|
post_bloom_strength: int = 0
|
|
post_vignette: float = 0.0
|
|
post_saturation: float = 0.0
|
|
post_contrast: float = 0.0
|
|
post_w: int = 0
|
|
post_h: int = 0
|
|
post_key: float = 0.0 # target mean luminance after exposure (float bits)
|
|
post_lum: words = null
|
|
post_mips: int = 0
|
|
post_adapt: float = 0.0 # smoothed exposure (float bits)
|
|
post_exposure_max: float = 20.0 # 20: the ceiling auto-exposure may reach (night lowers it)
|
|
post_wb_r: float = 1.02 # 1.02
|
|
post_wb_g: float = 1.0 # 1.0
|
|
post_wb_b: float = 0.97 # 0.97
|
|
post_lift_r: float = 0.004 # 0.004
|
|
post_lift_g: float = 0.004 # 0.004
|
|
post_lift_b: float = 0.012 # 0.012
|
|
post_gain_r: float = 0.99 # 0.99
|
|
post_gain_g: float = 0.995 # 0.995
|
|
post_gain_b: float = 1.0 # 1.0
|
|
post_ao: Target = null
|
|
post_ao_blur: Target = null
|
|
post_p_ao: int = 0
|
|
post_p_ao_blur: int = 0
|
|
post_ao_radius: float = 0.0
|
|
post_ao_intensity: float = 0.0
|
|
post_ao_strength: float = 0.0
|
|
post_gi_strength: float = 0.4 # 0.4
|
|
post_no_gi: bool = false
|
|
post_ldr: Target = null
|
|
post_depth_copy: Target = null
|
|
post_vol: Target = null
|
|
post_p_vol: int = 0
|
|
post_vol_density: float = 0.002 # 0.002
|
|
post_vol_falloff: float = 0.005 # 0.005
|
|
post_vol_mist: float = 0.0 # the day sets these two
|
|
post_prev: Target = null # last frame's scene colour, for the SSGI bounce only
|
|
post_scene: Target = null # this frame's scene colour before the water, for refraction
|
|
post_frame: int = 0
|
|
post_color_w: int = 0 # its size: the display's when DLSS upscaled it
|
|
post_color_h: int = 0
|
|
post_color: int = 0 # the HDR colour the rest of post reads # the resolved depth, copied so passes can read it while drawing into the frame
|
|
post_p_sharp: int = 0
|
|
post_p_dof: int = 0
|
|
post_dof: Target = null
|
|
post_p_tone_hdr: int = 0 # the tonemap's HDR10 variant, made the first time HDR is on
|
|
post_ldr_hdr: bool = false # post_ldr was made for HDR10 output (10-bit)
|
|
post_sharpen: float = 0.0
|
|
post_grain: int = 0
|
|
post_adapt_t: []Target = null
|
|
post_adapt_i: int = 0
|
|
post_p_adapt: int = 0
|
|
post_adapt_reset: bool = true
|
|
prof_on: bool = false
|
|
prof_names: []pointer = null
|
|
prof_ids: words = null # PROF_SLOTS * PROF_RING query objects
|
|
prof_ns: []long = null # accumulated nanoseconds per slot
|
|
prof_hits: []long = null # samples accumulated per slot
|
|
prof_n: int = 0 # slots in use
|
|
prof_frame: int = 0
|
|
prof_active: int = -1 # slot whose query is currently open
|
|
prof_scratch: words = null
|
|
prof_gen: []int = null
|
|
prof_gen_cur: int = 0
|
|
prof_ft: []long = null # real frame times, microseconds
|
|
prof_last_us: long = 0
|
|
prof_chunk_us: []long = null
|
|
prof_chunk_kind: []int = null
|
|
prof_chunk_band: []int = null
|
|
prof_chunk_n: []int = null
|
|
prof_gen_us_cur: long = 0
|
|
prof_gen_us: []long = null # generation microseconds per frame
|
|
prof_layer_us_cur: long = 0 # rebuilding and uploading instance buffers
|
|
prof_bake_us_cur: long = 0 # the height-field shadow rebake
|
|
prof_layer_us: []long = null
|
|
prof_bake_us: []long = null
|
|
prof_dt: []long = null # frame time, aligned with the arrays above
|
|
prof_up_cur: long = 0 # instance bytes uploaded this frame
|
|
prof_up: []long = null
|
|
prof_pre_swap: long = 0
|
|
prof_cpu_us: []long = null
|
|
prof_sum_dt: long = 0 # sums over the frames past the first eight, for the mean split
|
|
prof_sum_cpu: long = 0
|
|
prof_sum_game: long = 0
|
|
prof_sum_n: int = 0
|
|
prof_mark_last: long = 0
|
|
prof_mark_best: long = 0
|
|
prof_mark_name: pointer = null
|
|
prof_mark_us: []long = null
|
|
prof_mark_who: []pointer = null
|
|
prof_mk_names: []pointer = null
|
|
prof_mk_us: []long = null
|
|
prof_mk_n: int = 0
|
|
prof_game_us_cur: long = 0
|
|
prof_game_us: []long = null
|
|
r3d_root: string = "packages/ludic.render3d" # where shaders/ lives
|
|
r3d_assets: string = "assets/polyhaven" # where the CC0 assets live
|
|
r3d_root_found: bool = false
|
|
r3d_prog_log: int = -1
|
|
q_scratch: floats = floats(16)
|
|
q_sy: floats = null # views of q_scratch's second, third and fourth
|
|
q_sz: floats = null
|
|
q_st: floats = null
|
|
r3d_sky_prog: int = 0
|
|
r3d_fog_wall: float = 0.0 # r3d_fog_wall: > 0, nothing past it is seen or drawn
|
|
r3d_fog_density: float = 0.0
|
|
r3d_fog_falloff: float = 0.0
|
|
r3d_fog_inscatter: float = 0.02 # 0.02, what the shader used to hard-code
|
|
r3d_fog_desat: float = 1.35 # 1.35
|
|
r3d_sky_relight: float = 0.0
|
|
r3d_time: float = 0.0
|
|
r3d_ready: bool = false
|
|
r3d_plate: bool = false
|
|
r3d_small: bool = false # set before r3d_open: a small UI window (a launcher) - the ring, the memory blocks and the descriptor pools sized for it
|
|
r3d_sky_path: string = null
|
|
r3d_debug: bool = false
|
|
r3d_debug_shadow: bool = false
|
|
r3d_clip_y: float = -2147483600.0 # -2^31: no clipping
|
|
r3d_prepass_env: int = -1
|
|
r3d_test_frame: int = 0
|
|
r3d_test_resize: int = 0
|
|
r3d_no_shadow: bool = false
|
|
r3d_no_trees: bool = false
|
|
r3d_no_refl: bool = false
|
|
r3d_cam_log: int = -1
|
|
sc_prog: int = 0
|
|
sc_prog_fol: int = 0
|
|
sc_prog_wind: int = 0
|
|
sc_prog_blade: int = 0
|
|
sc_prog_flower: int = 0
|
|
sc_prog_card: int = 0
|
|
sc_prog_card_shadow: int = 0
|
|
sc_prog_card_cheap: int = 0
|
|
sc_blade_base: floats = null
|
|
sc_blade_tip: floats = null
|
|
sc_blade_tint: floats = null
|
|
sc_prog_shadow: int = 0
|
|
sc_prog_shadow_wind: int = 0
|
|
sc_prog_shadow_fol: int = 0 # foliage meshes: alpha-tested casters
|
|
sc_prog_fol_depth: int = 0
|
|
sc_prog_fol_eq: int = 0
|
|
sc_prepass: bool = false # the main pass is drawing over what the prepass laid down
|
|
sc_imp_prog: int = 0
|
|
sc_imp_prog_shadow: int = 0
|
|
sc_bake_prog: int = 0
|
|
sc_bake_card_prog: int = 0
|
|
sc_bake_flower_prog: int = 0
|
|
sc_card: Mesh = null
|
|
sc_ident_buf: int = 0
|
|
sc_layers: []Layer = null
|
|
sc_debug_dump: bool = false
|
|
sc_printed: bool = false
|
|
sc_dump_n: int = 0
|
|
sc_view_gen: int = 1
|
|
sc_view_pos: floats = null
|
|
sc_view_fwd: floats = null
|
|
sc_cull_prog: int = 0
|
|
sc_cull_tried: bool = false
|
|
sc_ind_base: int = -1 # >= 0: layer_draw_model / layer_draw_depth draw records from here
|
|
sc_ind_n: int = 1 # records each of those draws covers: one per level of a material
|
|
sc_ind_stride: int = 4 # records between one material's first and the next's (3 for the shadow LOD)
|
|
sc_freeze: bool = false # a secondary pass (reflection) reuses the partition
|
|
sc_dbg_level: int = -1
|
|
sc_dbg_lod: bool = false
|
|
sc_dbg_tint: floats = null
|
|
sc_cast_all: int = -1
|
|
sc_cast_gen: int = -1
|
|
sc_cast_dy: float = 0.0
|
|
sc_cast_k: float = 0.0
|
|
sc_skip_blade: bool = false
|
|
sc_skip_grass: bool = false
|
|
grass_force: bool = false # R3D_BLADES: the blades on whatever the game set
|
|
grass_env_off: bool = false # R3D_NOBLADES: the blades off whatever the game set
|
|
sc_skip_card: bool = false
|
|
cb_state: int = 12345
|
|
shadow_res: int = 2048
|
|
shadow_refused: int = 0 # the last size the graphics card had no memory for (0: none)
|
|
sh_tex: int = 0
|
|
sh_fbo: int = 0
|
|
sh_vp: floats = null # the cascades' view-projections, 16 floats each
|
|
sh_vp_v: [][]float = null # a view of each
|
|
sh_split: floats = null # view-space far distance of each cascade
|
|
sh_range: floats = null # 4 light-frustum depth extents (metres)
|
|
sh_texel: floats = null # 4 shadow texel sizes (metres)
|
|
sh_tmp_proj: floats = null
|
|
sh_tmp_vp: floats = null
|
|
sh_tmp_inv: floats = null
|
|
sh_tmp_view: floats = null
|
|
sh_corner: floats = null
|
|
sh_cascade: int = 0 # the cascade being rendered (for casters that skip far ones)
|
|
sh_printed2: bool = false
|
|
sh_printed3: bool = false
|
|
sh_force: int = -1 # R3D_FORCE=<c> pins every pixel to cascade c (debug)
|
|
sh_printed: bool = false
|
|
sky_tex: int = 0
|
|
sky_w: int = 0
|
|
sky_h: int = 0
|
|
sky_irradiance: int = 0
|
|
sky_prefilter: int = 0 # GL_TEXTURE_2D_ARRAY
|
|
sky_brdf: int = 0
|
|
sun_dir: floats = null # toward the sun (float bits)
|
|
sun_color: floats = null # radiance (float bits)
|
|
sky_fullscreen: Mesh = null
|
|
sky_yaw: float = 0.0 # radians: the HDRI is turned by this about y
|
|
sky_rot_s: float = 0.0
|
|
sky_rot_c: float = 0.0
|
|
sun_hdri: floats = null # the sun direction as found in the file
|
|
sky_baked: bool = false # the IBL set exists, baked at sky_baked_yaw
|
|
sky_baked_yaw: float = 0.0
|
|
sky_p_irr: int = 0
|
|
sky_p_pre: int = 0
|
|
sky_p_brdf: int = 0
|
|
sky_prefilter_w: int = 512
|
|
STREAM_MAX_CHUNKS: int = 4096
|
|
stream_all: []Stream = null
|
|
stream_cap_read: bool = false
|
|
stream_no_evict: bool = false # R3D_NOEVICT: the old behaviour, for comparison
|
|
stream_walk_no: int = 0 # counts ring walks; a chunk's age is measured in these
|
|
stream_evictions: int = 0
|
|
stream_us_gen: long = 0 # generating new chunks (stream_fill)
|
|
stream_us_gather: long = 0 # copying cached chunks into the layer buffer
|
|
stream_us_walk: long = 0 # the ring walk itself
|
|
stream_walks: int = 0 # streams that walked their whole ring this frame
|
|
stream_debug_n: int = 0
|
|
stream_scratch: floats = null
|
|
gvk_pipe_bufs: words = null # a pipeline's vertex buffers, while it is made
|
|
gsl_up: floats = floats(3)
|
|
sh_fit_cview: floats = floats(3) # shadow_fit's scratch
|
|
sh_fit_corners: floats = floats(24)
|
|
sh_fit_center: floats = floats(3)
|
|
sh_fit_eye: floats = floats(3)
|
|
sh_fit_up: floats = floats(3)
|
|
sh_fit_out: floats = floats(16)
|
|
water_eye: floats = floats(3) # water_reflection_pass's scratch
|
|
water_mirror: floats = floats(16)
|
|
water_mv: floats = floats(16)
|
|
sc_lod_counts: words = words(64) # layer_partition_lods' scratch (SC_LOD_ROOM)
|
|
sc_lod_start: words = words(64)
|
|
sc_lod_fill: words = words(64)
|
|
sc_gpu_rec: words = words(29 * 5) # layer_gpu_prepare's (SC_RECS * 5) and layer_gpu_cull's
|
|
sc_gpu_zeros: words = words(5)
|
|
sc_gpu_pr: words = words(36)
|
|
sc_gpu_bufs: words = words(4) # the camera's up for DLSS's constants
|
|
ov_nine_buf: floats = floats(16) # ov_nine's corners and uvs
|
|
gvk_ac: pointer = null # the VkAllocationCallbacks every create and destroy is given (R3D_ALLOC_VK=1)
|
|
gvk_prime_b: words = null # buffers made since the frame began, read once so MoltenVK makes their
|
|
@max(16384) gvk_prime_h: []long = null # Metal buffers now (gvk_prime), and their handles
|
|
gvk_prime_n: int = 0
|
|
gvk_prime_dst: long = 0 # the 64 bytes those reads land in
|
|
gvk_prime_mem: long = 0
|
|
stream_loose: Chunk = null # the record for a chunk no stream's cache can keep this walk
|
|
stream_deadline: long = 0
|
|
gsl_on: bool = false # slInit succeeded: the interposer is the loader, the plugins are in
|
|
gsl_dlss_ok: bool = false # what this adapter can run, from slIsFeatureSupported
|
|
gsl_rr_ok: bool = false
|
|
gsl_fg_ok: bool = false
|
|
gsl_reflex_ok: bool = false
|
|
gsl_pcl_ok: bool = false
|
|
gsl_feats: bytes = null # kept alive: Preferences points at it
|
|
gsl_logdir: bytes = null # and at this
|
|
gsl_vp: bytes = null # sl::ViewportHandle 0, the one view
|
|
gsl_tok_buf: bytes = null
|
|
gsl_idx_buf: bytes = null
|
|
gsl_token: pointer = null # this frame's sl::FrameToken, owned by Streamline
|
|
gsl_frame_n: int = 0
|
|
gsl_said: bool = false # one failure message, not one a frame
|
|
gsl_fresh: bool = false # a token was taken since the last frame started (a present took it)
|
|
gsl_reflex_mode: int = 0 # 0 off, 1 low latency, 2 low latency + boost
|
|
gsl_reflex_applied: int = -1
|
|
gsl_f_sleep: pointer = null
|
|
gsl_f_marker: pointer = null
|
|
gsl_dlss_mode: int = 0 # 0 off, 1 DLAA, 2 quality, 3 balanced, 4 performance
|
|
gsl_opts: bytes = null
|
|
gsl_opt_mode: int = -1
|
|
gsl_opt_w: int = 0
|
|
gsl_opt_h: int = 0
|
|
gsl_rw: int = 0 # the render size DLSS asked for
|
|
gsl_rh: int = 0
|
|
gsl_set_mode: int = -1
|
|
gsl_set_w: int = 0
|
|
gsl_set_h: int = 0
|
|
gsl_mv: Target = null
|
|
gsl_out: Target = null
|
|
gsl_consts: bytes = null
|
|
gsl_tags: bytes = null
|
|
gsl_res: bytes = null
|
|
gsl_inputs: bytes = null
|
|
gsl_prev_vp: floats = null
|
|
gsl_reset: bool = true
|
|
gsl_jitter_x: float = 0.0 # float bits, NDC offsets the projection carries this frame
|
|
gsl_jitter_y: float = 0.0
|
|
gsl_jpx: float = 0.0 # float bits, the same in pixels
|
|
gsl_jpy: float = 0.0
|
|
gsl_eval_ok: bool = true # the last evaluate worked: only then is the next frame jittered
|
|
TERRAIN_HALF: int = 4096 # world half-size in metres (8 km square)
|
|
cd_mesh: Mesh = null
|
|
cd_range: floats = null # float bits: how far each level is drawn
|
|
cd_min: []floats = null # per level: min height of each patch (float bits)
|
|
cd_max: []floats = null
|
|
cd_draws: int = 0
|
|
cd_far_draws: int = 0
|
|
cd_near_draws: int = 0
|
|
ter_force_far: bool = false
|
|
ter_no_split: bool = false
|
|
ter_force_near: bool = false
|
|
ter_skip: bool = false
|
|
ter_height_tex: int = 0
|
|
ter_normal_tex: int = 0 # the baked surface normal, x and z in RG16F (y rebuilt when read)
|
|
ter_heights: floats = null # CPU copy, float bits, TERRAIN_RES^2
|
|
ter_reflect: bool = false # drawing the reflection: the mid mesh is plenty
|
|
ter_prog: int = 0
|
|
ter_prog_far: int = 0
|
|
ter_prog_near: int = 0 # the detailed tier alone (NEAR_ONLY)
|
|
ter_sun_prog: int = 0 # tersun.frag: sun visibility into a screen buffer
|
|
ter_sun_inline: bool = false # the ground's shader reads the cascades itself (Vulkan); no sun pass
|
|
ter_sun_tgt: Target = null # that buffer, at the frame's size
|
|
ter_sun_refl: Target = null # and at the reflection's, which is smaller
|
|
ter_sun_dumped: bool = false
|
|
ter_sun_checked: bool = false
|
|
ter_sun_done: bool = false # the caller already ran the pass (so it can time it)
|
|
ter_sun_pass: bool = false # selection is drawing the visibility pass
|
|
ter_sun_tex: int = 0
|
|
ter_prog_cur: int = 0 # the program currently bound during selection
|
|
ter_smooth: bool = false # generate the analytic test ground instead of a survey
|
|
ter_far_split: float = 0.0 # metres: beyond this the terrain takes its cheap far path (R3D_TFAR)
|
|
ter_far_band: float = 0.0 # half-width of the near/far blend (R3D_TBAND)
|
|
ter_snow_line: float = 0.0
|
|
ter_tex: words = null # 11 material textures (see terrain_bind)
|
|
ter_ox: float = 0.0 # world x/z of the terrain centre (float bits)
|
|
ter_oz: float = 0.0
|
|
ter_dem_tex: int = 0 # a real height map (16-bit), or 0 for the procedural valley
|
|
ter_dem_min: float = 0.0
|
|
ter_dem_max: float = 0.0
|
|
ter_dem_base: float = 0.0
|
|
ter_ortho_tex: int = 0 # a photograph of the same window, draped with distance
|
|
ter_carpet: int = 0 # the distant-grass carpet (carpet_bake), 0 = none
|
|
ter_shadow_tex: int = 0 # height-field sun shadow: RG32F (lowest lit height, occluder distance)
|
|
ter_shadow_yaw: float = 1000000000.0 # the sky yaw it was baked for
|
|
ter_shadow_gen: int = -1 # the daylight generation it was baked for
|
|
ter_shadow_prog: int = 0
|
|
ter_lake_level: float = 0.0 # a lake carved into the height map (float bits; ex = 0 → none)
|
|
ter_lake_cx: float = 0.0
|
|
ter_lake_cz: float = 0.0
|
|
ter_lake_ex: float = 0.0
|
|
ter_lake_ez: float = 0.0
|
|
ter_lake_carve: bool = true
|
|
ter_sea_level: float = 0.0
|
|
ter_sea_set: bool = false
|
|
ter_isle_cx: float = 0.0
|
|
ter_isle_cz: float = 0.0
|
|
ter_isle_r: float = 0.0
|
|
ter_isle_fall: float = 0.0
|
|
ter_isle_mode: int = 0
|
|
ter_ortho_px: pointer = null # the photograph on the CPU (RGB8, TERRAIN_RES^2) for placement rules
|
|
ter_ortho_w: int = 0
|
|
ter_ortho_c: int = 3
|
|
ter_h_scale: float = 0.0
|
|
ter_o_scale: float = 0.0
|
|
ter_bw: floats = floats(8)
|
|
ter_wire: bool = false
|
|
ter_printed: bool = false
|
|
ter_scr: floats = floats(16)
|
|
tex_w: int = 0 # the last decoded image
|
|
tex_h: int = 0
|
|
tex_channels: int = 0
|
|
tex_depth: int = 0 # bits per sample (8 or 16)
|
|
tex_file_len: int = 0
|
|
tex_anisotropy: fixed = 16.0
|
|
tex_size_ws: []int = new []int
|
|
tex_size_hs: []int = new []int
|
|
hdr_max_lum: float = 0.0 # float bits of the brightest texel (sun finding)
|
|
hdr_max_x: int = 0
|
|
hdr_max_y: int = 0
|
|
hdr_sun_r: float = 0.0 # irradiance (float bits) of everything above the IBL clip: the sun
|
|
hdr_sun_g: float = 0.0
|
|
hdr_sun_b: float = 0.0
|
|
hdr_clip: float = 0.0 # float bits; texels above this (per channel) feed the sun, not the IBL
|
|
tex_dump_alpha: bool = false
|
|
water_mesh: Mesh = null
|
|
water_prog: int = 0
|
|
water_level: float = 0.0
|
|
water_cx: float = 0.0
|
|
water_cz: float = 0.0
|
|
water_ex: float = 0.0
|
|
water_ez: float = 0.0
|
|
water_on: bool = false
|
|
water_refl: Target = null # the world mirrored in the surface, half resolution
|
|
water_refl_div: int = 2 # R3D_REFLDIV overrides: 2 = half res, 4 = quarter
|
|
water_saved: floats = floats(16 * 4 + 3) # the real camera's matrices, restored after the pass
|
|
water_saved_vp: floats = null # views of its second and third matrices
|
|
water_saved_ivp: floats = null
|
|
water_dumped: bool = false
|
|
wb_n: int = 0
|
|
wb_level: floats = null
|
|
wb_cx: floats = null
|
|
wb_cz: floats = null
|
|
wb_ex: floats = null
|
|
wb_ez: floats = null
|
|
wb_reflect: words = null
|
|
wb_primary: int = -1 # the body the reflection pass mirrors, or -1
|
|
wb_cells: floats = null # x0, z0, x1, z1 of each rectangle with water showing
|
|
wb_ncells: int = -1 # -1: not built for the current mirrored body
|
|
wb_blocks: words = null # x0, z0, x1, z1, first cell, cells past the last - of each block
|
|
wb_nblocks: int = 0
|
|
wb_refl_always: int = -1
|
|
wb_dbg: int = -1
|
|
wb_build_us: long = 0 # how long the last water_cells_build took (R3D_REFL_DBG prints it)
|
|
grass_blade_tex: int = 0
|
|
grass_blade_cols: int = 8
|
|
grass_push_x: float = 0.0
|
|
grass_push_z: float = 0.0
|
|
grass_push_r: float = 0.0
|
|
post_auto: bool = true
|
|
post_contact: float = 1.25 # 1.25: how hard a thing is darkened where it meets the ground
|
|
post_vol_steps: float = 24.0 # 24
|
|
post_vol_far: float = 800.0 # 800 m
|
|
post_vol_g: float = 0.6 # 0.6: air throws light forward
|
|
post_vol_mist_h: float = 40.0 # 40 m
|
|
post_fxaa: float = 1.0
|
|
post_dof_focus: float = 10.0 # 10 m
|
|
post_dof_aperture: float = 0.0 # 0 = no lens, and no pass
|
|
post_dof_max: float = 12.0 # 12 px
|
|
r3d_global_defs: string = ""
|
|
r3d_fog_scale: float = 1.0 # float bits: a setting's multiplier over the density the day sets
|
|
r3d_fog_base: float = 0.0 # the height fog is measured from (float bits); 0 = y = 0
|
|
r3d_ground_alb_r: float = 0.3
|
|
r3d_ground_alb_g: float = 0.34
|
|
r3d_ground_alb_b: float = 0.14
|
|
r3d_ground_hi_r: float = 0.289
|
|
r3d_ground_hi_g: float = 0.28
|
|
r3d_ground_hi_b: float = 0.26
|
|
r3d_ground_hi_y: float = 480.0 # 480
|
|
r3d_ground_hi_w: float = 150.0 # 150
|
|
r3d_dem_path: string = null
|
|
r3d_dem_min: float = 0.0
|
|
r3d_dem_max: float = 0.0
|
|
r3d_dem_base: float = 0.0
|
|
r3d_dem_ox: float = 0.0
|
|
r3d_dem_oz: float = 0.0
|
|
r3d_ortho_path: string = null
|
|
r3d_debug_max: bool = false
|
|
r3d_cloud_shadow: float = 0.5 # 0.5
|
|
sc_a2c: bool = true
|
|
sc_bake_flower: bool = false
|
|
sc_dbg_blade: int = 0
|
|
sc_skip_flower: bool = false
|
|
sh_enabled: bool = true
|
|
sh_skip_terrain: bool = false
|
|
sh_probe_x: float = 0.0
|
|
sh_probe_y: float = 0.0
|
|
sh_probe_z: float = 0.0
|
|
sky_sun_boost: float = 2.3 # 2.3: the photograph's thin cloud dims its sun; a crisper day wants more
|
|
sky_start_yaw: float = 0.0
|
|
STREAM_BUDGET_US: int = 2500 # microseconds of generation per frame; a setting may move it
|
|
stream_budget_left: int = 0
|
|
ter_wet: float = 0.0
|
|
ter_dem_blur: float = 0.0 # gaussian texels applied to the survey (0 for lidar; ~3 for 30 m data)
|
|
wt_wade_x: float = 0.0
|
|
wt_wade_z: float = 0.0
|
|
wt_wade_s: float = 0.0
|
|
}
|
|
function r3d_dev(render3d_st: mut Render3dState) -> bool {
|
|
if render3d_st.r3d_dev_v < 0 { if Os.has_env("R3D_DEV") and Os.env("R3D_DEV") != "0" { render3d_st.r3d_dev_v = 1 } else { render3d_st.r3d_dev_v = 0 } }
|
|
return render3d_st.r3d_dev_v == 1
|
|
}
|
|
function r3d_env_has(render3d_st: mut Render3dState, name: string) -> bool {
|
|
if is_windowed() and not r3d_dev(render3d_st) { return false }
|
|
return Os.has_env(name)
|
|
}
|
|
function r3d_env(render3d_st: mut Render3dState, name: string) -> string {
|
|
if is_windowed() and not r3d_dev(render3d_st) { return "" }
|
|
return Os.env(name)
|
|
}
|