Remove voxels in favor of rt
This commit is contained in:
@@ -144,9 +144,6 @@ function mesh_object_cull_mesh(raw: mesh_object_t, context: string, camera: came
|
||||
radius_scale *= 1000;
|
||||
}
|
||||
///end
|
||||
if (context == "voxel") {
|
||||
radius_scale *= 100;
|
||||
}
|
||||
if (raw.data._.instanced) {
|
||||
radius_scale *= 100;
|
||||
}
|
||||
|
||||
@@ -58,13 +58,6 @@ function render_path_ready(): bool {
|
||||
return _render_path_loading == 0;
|
||||
}
|
||||
|
||||
///if arm_voxels
|
||||
let _render_path_voxelized: i32 = 0;
|
||||
function render_path_voxelize(): bool { // Returns true if scene should be voxelized
|
||||
return ++_render_path_voxelized > 2 ? false : true;
|
||||
}
|
||||
///end
|
||||
|
||||
function render_path_render_frame() {
|
||||
if (!render_path_ready() ||_render_path_paused || app_w() == 0 || app_h() == 0) {
|
||||
return;
|
||||
|
||||
@@ -92,10 +92,6 @@ function scene_set_active(scene_name: string): object_t {
|
||||
scene_remove();
|
||||
}
|
||||
|
||||
///if arm_voxels // Revoxelize
|
||||
_render_path_voxelized = 0;
|
||||
///end
|
||||
|
||||
let format: scene_t = data_get_scene_raw(scene_name);
|
||||
let o: object_t = scene_create(format);
|
||||
return o;
|
||||
|
||||
@@ -61,11 +61,6 @@ function shader_data_get_context(raw: shader_data_t, name: string): shader_conte
|
||||
|
||||
function shader_context_create(raw: shader_context_t): shader_context_t {
|
||||
raw._ = {};
|
||||
///if (!arm_voxels)
|
||||
if (raw.name == "voxel") {
|
||||
return raw;
|
||||
}
|
||||
///end
|
||||
shader_context_parse_vertex_struct(raw);
|
||||
return shader_context_compile(raw);
|
||||
}
|
||||
|
||||
@@ -43,32 +43,11 @@ function make_material_parse_mesh_material() {
|
||||
|
||||
context_raw.ddirty = 2;
|
||||
|
||||
///if arm_voxels
|
||||
make_material_make_voxel(m);
|
||||
///end
|
||||
|
||||
///if (arm_direct3d12 || arm_vulkan)
|
||||
render_path_raytrace_dirty = 1;
|
||||
///end
|
||||
}
|
||||
|
||||
///if arm_voxels
|
||||
function make_material_make_voxel(m: material_data_t) {
|
||||
let rebuild: bool = true; // height_used;
|
||||
if (config_raw.rp_gi != false && rebuild) {
|
||||
let scon: shader_context_t = null;
|
||||
for (let i: i32 = 0; i < m._.shader._.contexts.length; ++i) {
|
||||
let c: shader_context_t = m._.shader._.contexts[i];
|
||||
if (c.name == "voxel") {
|
||||
scon = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (scon != null) make_voxel_run(scon);
|
||||
}
|
||||
}
|
||||
///end
|
||||
|
||||
function make_material_parse_paint_material() {
|
||||
let m: material_data_t = project_material_data;
|
||||
let scon: shader_context_t = null;
|
||||
@@ -132,11 +111,6 @@ function make_material_get_displace_strength(): f32 {
|
||||
return config_raw.displace_strength * 0.02 * sc.x;
|
||||
}
|
||||
|
||||
function make_material_voxelgi_half_extents(): string {
|
||||
let ext: i32 = context_raw.vxao_ext;
|
||||
return "const vec3 voxelgi_half_extents = vec3(" + ext + ", " + ext + ", " + ext + ");";
|
||||
}
|
||||
|
||||
function make_material_delete_context(c: shader_context_t) {
|
||||
app_notify_on_next_frame(function (c: shader_context_t) { // Ensure pipeline is no longer in use
|
||||
shader_context_delete(c);
|
||||
|
||||
@@ -1,37 +1,6 @@
|
||||
|
||||
function make_bake_run(con: node_shader_context_t, vert: node_shader_t, frag: node_shader_t) {
|
||||
if (context_raw.bake_type == bake_type_t.AO) { // Voxel
|
||||
///if arm_voxels
|
||||
// Apply normal channel
|
||||
frag.wposition = true;
|
||||
frag.n = true;
|
||||
frag.vvec = true;
|
||||
node_shader_add_function(frag, str_cotangent_frame);
|
||||
///if arm_direct3d11
|
||||
node_shader_write(frag, "mat3 TBN = cotangent_frame(n, vvec, tex_coord);");
|
||||
///else
|
||||
node_shader_write(frag, "mat3 TBN = cotangent_frame(n, -vvec, tex_coord);");
|
||||
///end
|
||||
node_shader_write(frag, "n = nortan * 2.0 - 1.0;");
|
||||
node_shader_write(frag, "n.y = -n.y;");
|
||||
node_shader_write(frag, "n = normalize(mul(n, TBN));");
|
||||
|
||||
node_shader_write(frag, make_material_voxelgi_half_extents());
|
||||
node_shader_write(frag, "vec3 voxpos = wposition / voxelgi_half_extents;");
|
||||
node_shader_add_uniform(frag, "sampler3D voxels");
|
||||
node_shader_add_function(frag, str_trace_ao);
|
||||
frag.n = true;
|
||||
let strength: f32 = context_raw.bake_ao_strength;
|
||||
let radius: f32 = context_raw.bake_ao_radius;
|
||||
let offset: f32 = context_raw.bake_ao_offset;
|
||||
node_shader_write(frag, "float ao = trace_ao(voxpos, n, " + radius + ", " + offset + ") * " + strength + ";");
|
||||
if (context_raw.bake_axis != bake_axis_t.XYZ) {
|
||||
let axis: string = make_bake_axis_string(context_raw.bake_axis);
|
||||
node_shader_write(frag, "ao *= dot(n, " + axis + ");");
|
||||
}
|
||||
node_shader_write(frag, "ao = 1.0 - ao;");
|
||||
node_shader_write(frag, "frag_color[0] = vec4(ao, ao, ao, 1.0);");
|
||||
///end
|
||||
}
|
||||
else if (context_raw.bake_type == bake_type_t.CURVATURE) {
|
||||
let pass: bool = parser_material_bake_passthrough;
|
||||
|
||||
@@ -112,10 +112,6 @@ function make_material_parse_mesh_material() {
|
||||
|
||||
context_raw.ddirty = 2;
|
||||
|
||||
///if arm_voxels
|
||||
make_material_make_voxel(m);
|
||||
///end
|
||||
|
||||
render_path_raytrace_dirty = 1;
|
||||
}
|
||||
|
||||
@@ -197,25 +193,6 @@ function make_material_parse_mesh_preview_material(md: material_data_t = null) {
|
||||
array_push(m._.shader._.contexts, scon);
|
||||
}
|
||||
|
||||
///if arm_voxels
|
||||
function make_material_make_voxel(m: material_data_t) {
|
||||
let rebuild: bool = make_material_height_used;
|
||||
if (config_raw.rp_gi != false && rebuild) {
|
||||
let scon: shader_context_t = null;
|
||||
for (let i: i32 = 0; i < m._.shader._.contexts.length; ++i) {
|
||||
let c: shader_context_t = m._.shader._.contexts[i];
|
||||
if (c.name == "voxel") {
|
||||
scon = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (scon != null) {
|
||||
make_voxel_run(scon);
|
||||
}
|
||||
}
|
||||
}
|
||||
///end
|
||||
|
||||
function make_material_parse_paint_material(bake_previews: bool = true) {
|
||||
if (!make_material_get_mout()) {
|
||||
return;
|
||||
@@ -578,11 +555,6 @@ function make_material_get_displace_strength(): f32 {
|
||||
return config_raw.displace_strength * 0.02 * sc.x;
|
||||
}
|
||||
|
||||
function make_material_voxelgi_half_extents(): string {
|
||||
let ext: f32 = context_raw.vxao_ext;
|
||||
return "const vec3 voxelgi_half_extents = vec3(" + ext + ", " + ext + ", " + ext + ");";
|
||||
}
|
||||
|
||||
function make_material_delete_context(c: shader_context_t) {
|
||||
app_notify_on_next_frame(function (c: shader_context_t) { // Ensure pipeline is no longer in use
|
||||
shader_context_delete(c);
|
||||
|
||||
@@ -3,7 +3,6 @@ let render_path_paint_live_layer: slot_layer_t = null;
|
||||
let render_path_paint_live_layer_drawn: i32 = 0;
|
||||
let render_path_paint_live_layer_locked: bool = false;
|
||||
let render_path_paint_dilated: bool = true;
|
||||
let render_path_paint_init_voxels: bool = true; // Bake AO
|
||||
let render_path_paint_push_undo_last: bool;
|
||||
let render_path_paint_painto: mesh_object_t = null;
|
||||
let render_path_paint_planeo: mesh_object_t = null;
|
||||
@@ -253,23 +252,6 @@ function render_path_paint_commands_paint(dilation: bool = true) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
///if arm_voxels
|
||||
if (context_raw.tool == workspace_tool_t.BAKE && context_raw.bake_type == bake_type_t.AO) {
|
||||
if (render_path_paint_init_voxels) {
|
||||
render_path_paint_init_voxels = false;
|
||||
let _rp_gi: bool = config_raw.rp_gi;
|
||||
config_raw.rp_gi = true;
|
||||
render_path_base_init_voxels();
|
||||
config_raw.rp_gi = _rp_gi;
|
||||
}
|
||||
render_path_clear_image("voxels", 0x00000000);
|
||||
render_path_set_target("");
|
||||
render_path_set_viewport(256, 256);
|
||||
render_path_bind_target("voxels", "voxels");
|
||||
render_path_draw_meshes("voxel");
|
||||
render_path_gen_mipmaps("voxels");
|
||||
}
|
||||
///end
|
||||
|
||||
let texpaint: string = "texpaint" + tid;
|
||||
if (context_raw.tool == workspace_tool_t.BAKE && context_raw.brush_time == time_delta()) {
|
||||
@@ -303,11 +285,6 @@ function render_path_paint_commands_paint(dilation: bool = true) {
|
||||
render_path_bind_target("gbuffer0", "gbuffer0");
|
||||
}
|
||||
render_path_bind_target("texpaint_blend1", "paintmask");
|
||||
///if arm_voxels
|
||||
if (context_raw.tool == workspace_tool_t.BAKE && context_raw.bake_type == bake_type_t.AO) {
|
||||
render_path_bind_target("voxels", "voxels");
|
||||
}
|
||||
///end
|
||||
if (context_raw.colorid_picked) {
|
||||
render_path_bind_target("texpaint_colorid", "texpaint_colorid");
|
||||
}
|
||||
|
||||
@@ -100,10 +100,6 @@ function make_material_parse_mesh_material() {
|
||||
}
|
||||
|
||||
context_raw.ddirty = 2;
|
||||
|
||||
///if arm_voxels
|
||||
make_material_make_voxel(m);
|
||||
///end
|
||||
}
|
||||
|
||||
function make_material_parse_particle_material() {
|
||||
@@ -178,25 +174,6 @@ function make_material_parse_mesh_preview_material() {
|
||||
array_push(m._.shader._.contexts, scon);
|
||||
}
|
||||
|
||||
///if arm_voxels
|
||||
function make_material_make_voxel(m: material_data_t) {
|
||||
let rebuild: bool = make_material_height_used;
|
||||
if (config_raw.rp_gi != false && rebuild) {
|
||||
let scon: shader_context_t = null;
|
||||
for (let i: i32 = 0; i < m._.shader._.contexts.length; ++i) {
|
||||
let c: shader_context_t = m._.shader._.contexts[i];
|
||||
if (c.name == "voxel") {
|
||||
scon = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (scon != null) {
|
||||
make_voxel_run(scon);
|
||||
}
|
||||
}
|
||||
}
|
||||
///end
|
||||
|
||||
function make_material_parse_paint_material(bake_previews: bool = true) {
|
||||
if (!make_material_get_mout()) {
|
||||
return;
|
||||
@@ -386,11 +363,6 @@ function make_material_get_displace_strength(): f32 {
|
||||
return config_raw.displace_strength * 0.02 * sc.x;
|
||||
}
|
||||
|
||||
function make_material_voxelgi_half_extents(): string {
|
||||
let ext: i32 = context_raw.vxao_ext;
|
||||
return "const vec3 voxelgi_half_extents = vec3(" + ext + ", " + ext + ", " + ext + ");";
|
||||
}
|
||||
|
||||
function make_material_delete_context(c: shader_context_t) {
|
||||
app_notify_on_next_frame(function (c: shader_context_t) { // Ensure pipeline is no longer in use
|
||||
shader_context_delete(c);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -8,7 +8,6 @@ flags.metal = os_argv().indexOf("metal") >= 0;
|
||||
flags.raytrace = flags.d3d12 || flags.vulkan || flags.metal;
|
||||
flags.embed = os_argv().indexOf("--embed") >= 0; // os_argv().indexOf("--debug") == -1; // clang 19
|
||||
flags.physics = os_argv().indexOf("--debug") == -1;
|
||||
flags.voxels = !flags.raytrace && !flags.android && !flags.ios;
|
||||
|
||||
flags.with_d3dcompiler = true;
|
||||
flags.with_nfd = true;
|
||||
@@ -104,17 +103,6 @@ if (flags.raytrace) {
|
||||
}
|
||||
}
|
||||
|
||||
if (flags.voxels) {
|
||||
project.add_define("arm_voxels");
|
||||
|
||||
if (platform === "windows") {
|
||||
project.add_assets("shaders/voxel_hlsl/*.d3d11", { destination: "data/{name}" });
|
||||
}
|
||||
else {
|
||||
project.add_shaders("shaders/voxel_glsl/*.glsl", { noprocessing: true });
|
||||
}
|
||||
}
|
||||
|
||||
let export_version_info = true;
|
||||
if (export_version_info) {
|
||||
let dir = "../" + flags.name.toLowerCase() + "/build";
|
||||
|
||||
@@ -1,3 +1,257 @@
|
||||
#version 450
|
||||
|
||||
#include "std/deferred_light.glsl"
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D gbuffer1;
|
||||
uniform vec4 envmap_data; // angle, sin(angle), cos(angle), strength
|
||||
uniform vec4 shirr[7];
|
||||
uniform sampler2D senvmap_brdf;
|
||||
uniform sampler2D senvmap_radiance;
|
||||
#ifdef SPIRV
|
||||
uniform float envmap_num_mipmaps;
|
||||
#else
|
||||
uniform int envmap_num_mipmaps;
|
||||
#endif
|
||||
uniform sampler2D ssaotex;
|
||||
uniform vec2 camera_proj;
|
||||
uniform vec3 eye;
|
||||
uniform vec3 eye_look;
|
||||
uniform vec3 point_pos;
|
||||
uniform vec3 point_col;
|
||||
uniform vec3 light_area0;
|
||||
uniform vec3 light_area1;
|
||||
uniform vec3 light_area2;
|
||||
uniform vec3 light_area3;
|
||||
uniform sampler2D sltc_mat;
|
||||
uniform sampler2D sltc_mag;
|
||||
|
||||
#include "std/gbuffer.glsl"
|
||||
#include "std/brdf.glsl"
|
||||
#include "std/math.glsl"
|
||||
#include "std/shirr.glsl"
|
||||
|
||||
in vec2 tex_coord;
|
||||
in vec3 view_ray;
|
||||
out vec4 frag_color;
|
||||
|
||||
const float LUT_SIZE = 64.0;
|
||||
const float LUT_SCALE = (LUT_SIZE - 1.0) / LUT_SIZE;
|
||||
const float LUT_BIAS = 0.5 / LUT_SIZE;
|
||||
|
||||
float integrate_edge(vec3 v1, vec3 v2) {
|
||||
float cos_theta = dot(v1, v2);
|
||||
float theta = acos(cos_theta);
|
||||
float res = cross(v1, v2).z * ((theta > 0.001) ? theta / sin(theta) : 1.0);
|
||||
return res;
|
||||
}
|
||||
|
||||
float ltc_evaluate(vec3 N, vec3 V, float dotnv, vec3 P, mat3 Minv, vec3 points0, vec3 points1, vec3 points2, vec3 points3) {
|
||||
// Construct orthonormal basis around N
|
||||
vec3 T1, T2;
|
||||
T1 = normalize(V - N * dotnv);
|
||||
T2 = cross(N, T1);
|
||||
|
||||
// Rotate area light in (T1, T2, R) basis
|
||||
Minv = mul(transpose(mat3(T1, T2, N)), Minv);
|
||||
|
||||
// Polygon (allocate 5 vertices for clipping)
|
||||
vec3 L0 = mul((points0 - P), Minv);
|
||||
vec3 L1 = mul((points1 - P), Minv);
|
||||
vec3 L2 = mul((points2 - P), Minv);
|
||||
vec3 L3 = mul((points3 - P), Minv);
|
||||
vec3 L4 = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
int n = 0;
|
||||
// Detect clipping config
|
||||
int config = 0;
|
||||
if (L0.z > 0.0) config += 1;
|
||||
if (L1.z > 0.0) config += 2;
|
||||
if (L2.z > 0.0) config += 4;
|
||||
if (L3.z > 0.0) config += 8;
|
||||
|
||||
// Clip
|
||||
if (config == 0) {
|
||||
// Clip all
|
||||
}
|
||||
else if (config == 1) { // V1 clip V2 V3 V4
|
||||
n = 3;
|
||||
L1 = -L1.z * L0 + L0.z * L1;
|
||||
L2 = -L3.z * L0 + L0.z * L3;
|
||||
}
|
||||
else if (config == 2) { // V2 clip V1 V3 V4
|
||||
n = 3;
|
||||
L0 = -L0.z * L1 + L1.z * L0;
|
||||
L2 = -L2.z * L1 + L1.z * L2;
|
||||
}
|
||||
else if (config == 3) { // V1 V2 clip V3 V4
|
||||
n = 4;
|
||||
L2 = -L2.z * L1 + L1.z * L2;
|
||||
L3 = -L3.z * L0 + L0.z * L3;
|
||||
}
|
||||
else if (config == 4) { // V3 clip V1 V2 V4
|
||||
n = 3;
|
||||
L0 = -L3.z * L2 + L2.z * L3;
|
||||
L1 = -L1.z * L2 + L2.z * L1;
|
||||
}
|
||||
else if (config == 5) { // V1 V3 clip V2 V4) impossible
|
||||
n = 0;
|
||||
}
|
||||
else if (config == 6) { // V2 V3 clip V1 V4
|
||||
n = 4;
|
||||
L0 = -L0.z * L1 + L1.z * L0;
|
||||
L3 = -L3.z * L2 + L2.z * L3;
|
||||
}
|
||||
else if (config == 7) { // V1 V2 V3 clip V4
|
||||
n = 5;
|
||||
L4 = -L3.z * L0 + L0.z * L3;
|
||||
L3 = -L3.z * L2 + L2.z * L3;
|
||||
}
|
||||
else if (config == 8) { // V4 clip V1 V2 V3
|
||||
n = 3;
|
||||
L0 = -L0.z * L3 + L3.z * L0;
|
||||
L1 = -L2.z * L3 + L3.z * L2;
|
||||
L2 = L3;
|
||||
}
|
||||
else if (config == 9) { // V1 V4 clip V2 V3
|
||||
n = 4;
|
||||
L1 = -L1.z * L0 + L0.z * L1;
|
||||
L2 = -L2.z * L3 + L3.z * L2;
|
||||
}
|
||||
else if (config == 10) { // V2 V4 clip V1 V3) impossible
|
||||
n = 0;
|
||||
}
|
||||
else if (config == 11) { // V1 V2 V4 clip V3
|
||||
n = 5;
|
||||
L4 = L3;
|
||||
L3 = -L2.z * L3 + L3.z * L2;
|
||||
L2 = -L2.z * L1 + L1.z * L2;
|
||||
}
|
||||
else if (config == 12) { // V3 V4 clip V1 V2
|
||||
n = 4;
|
||||
L1 = -L1.z * L2 + L2.z * L1;
|
||||
L0 = -L0.z * L3 + L3.z * L0;
|
||||
}
|
||||
else if (config == 13) { // V1 V3 V4 clip V2
|
||||
n = 5;
|
||||
L4 = L3;
|
||||
L3 = L2;
|
||||
L2 = -L1.z * L2 + L2.z * L1;
|
||||
L1 = -L1.z * L0 + L0.z * L1;
|
||||
}
|
||||
else if (config == 14) { // V2 V3 V4 clip V1
|
||||
n = 5;
|
||||
L4 = -L0.z * L3 + L3.z * L0;
|
||||
L0 = -L0.z * L1 + L1.z * L0;
|
||||
}
|
||||
else if (config == 15) { // V1 V2 V3 V4
|
||||
n = 4;
|
||||
}
|
||||
|
||||
if (n == 0) return 0.0;
|
||||
if (n == 3) L3 = L0;
|
||||
if (n == 4) L4 = L0;
|
||||
|
||||
// Project onto sphere
|
||||
L0 = normalize(L0);
|
||||
L1 = normalize(L1);
|
||||
L2 = normalize(L2);
|
||||
L3 = normalize(L3);
|
||||
L4 = normalize(L4);
|
||||
|
||||
// Integrate
|
||||
float sum = 0.0;
|
||||
|
||||
sum += integrate_edge(L0, L1);
|
||||
sum += integrate_edge(L1, L2);
|
||||
sum += integrate_edge(L2, L3);
|
||||
|
||||
if (n >= 4) sum += integrate_edge(L3, L4);
|
||||
if (n == 5) sum += integrate_edge(L4, L0);
|
||||
|
||||
return max(0.0, -sum);
|
||||
}
|
||||
|
||||
vec3 sample_light(const vec3 p, const vec3 n, const vec3 v, const float dotnv, const vec3 lp, const vec3 light_col,
|
||||
const vec3 albedo, const float rough, const vec3 f0, const float occ
|
||||
) {
|
||||
vec3 ld = lp - p;
|
||||
vec3 l = normalize(ld);
|
||||
float dotnl = max(0.0, dot(n, l));
|
||||
|
||||
float theta = acos(dotnv);
|
||||
vec2 tuv = vec2(rough, theta / (0.5 * PI));
|
||||
tuv = tuv * LUT_SCALE + LUT_BIAS;
|
||||
vec4 t = textureLod(sltc_mat, tuv, 0.0);
|
||||
mat3 inv = mat3(
|
||||
vec3(1.0, 0.0, t.y),
|
||||
vec3(0.0, t.z, 0.0),
|
||||
vec3(t.w, 0.0, t.x));
|
||||
float ltcspec = ltc_evaluate(n, v, dotnv, p, inv, light_area0, light_area1, light_area2, light_area3);
|
||||
ltcspec *= textureLod(sltc_mag, tuv, 0.0).a;
|
||||
|
||||
mat3 m1 = mat3(
|
||||
vec3(1.0, 0.0, 0.0),
|
||||
vec3(0.0, 1.0, 0.0),
|
||||
vec3(0.0, 0.0, 1.0));
|
||||
float ltcdiff = ltc_evaluate(n, v, dotnv, p, m1, light_area0, light_area1, light_area2, light_area3);
|
||||
vec3 direct = albedo * ltcdiff + ltcspec * 0.05;
|
||||
|
||||
direct *= attenuate(distance(p, lp));
|
||||
direct *= light_col;
|
||||
direct *= clamp(dotnl + 2.0 * occ * occ - 1.0, 0.0, 1.0); // Micro shadowing
|
||||
|
||||
return direct;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 g0 = textureLod(gbuffer0, tex_coord, 0.0); // Normal.xy, roughness, metallic/matid
|
||||
|
||||
vec3 n;
|
||||
n.z = 1.0 - abs(g0.x) - abs(g0.y);
|
||||
n.xy = n.z >= 0.0 ? g0.xy : octahedron_wrap(g0.xy);
|
||||
n = normalize(n);
|
||||
|
||||
float roughness = g0.b;
|
||||
float metallic;
|
||||
uint matid;
|
||||
unpack_f32_i16(g0.a, metallic, matid);
|
||||
vec4 g1 = textureLod(gbuffer1, tex_coord, 0.0); // Basecolor.rgb, occ
|
||||
float occ = g1.a;
|
||||
vec3 albedo = surface_albedo(g1.rgb, metallic); // g1.rgb - basecolor
|
||||
vec3 f0 = surface_f0(g1.rgb, metallic);
|
||||
|
||||
float depth = textureLod(gbufferD, tex_coord, 0.0).r * 2.0 - 1.0;
|
||||
vec3 p = get_pos(eye, eye_look, normalize(view_ray), depth, camera_proj);
|
||||
vec3 v = normalize(eye - p);
|
||||
float dotnv = max(0.0, dot(n, v));
|
||||
|
||||
occ = mix(1.0, occ, dotnv); // AO Fresnel
|
||||
|
||||
vec2 env_brdf = texelFetch(senvmap_brdf, ivec2(vec2(roughness, 1.0 - dotnv) * 256.0), 0).xy;
|
||||
|
||||
// Envmap
|
||||
vec3 envl = sh_irradiance(vec3(n.x * envmap_data.z - n.y * envmap_data.y, n.x * envmap_data.y + n.y * envmap_data.z, n.z), shirr);
|
||||
envl /= PI;
|
||||
|
||||
vec3 reflection_world = reflect(-v, n);
|
||||
float lod = mip_from_roughness(roughness, float(envmap_num_mipmaps));
|
||||
vec3 prefiltered_color = textureLod(senvmap_radiance, envmap_equirect(reflection_world, envmap_data.x), lod).rgb;
|
||||
|
||||
envl.rgb *= albedo;
|
||||
|
||||
// Indirect specular
|
||||
envl.rgb += prefiltered_color * (f0 * env_brdf.x + env_brdf.y) * 1.5;
|
||||
|
||||
envl.rgb *= envmap_data.w * occ;
|
||||
|
||||
frag_color.rgb = envl;
|
||||
frag_color.rgb *= textureLod(ssaotex, tex_coord, 0.0).r;
|
||||
|
||||
if (matid == uint(1)) { // Emission
|
||||
frag_color.rgb += g1.rgb; // materialid
|
||||
albedo = vec3(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
frag_color.rgb += sample_light(p, n, v, dotnv, point_pos, point_col, albedo, roughness, f0, occ);
|
||||
frag_color.a = 1.0; // Mark as opaque
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#version 450
|
||||
#define _Voxel
|
||||
|
||||
#include "std/deferred_light.glsl"
|
||||
@@ -1,58 +0,0 @@
|
||||
|
||||
const float voxelgi_resolution = 256.0;
|
||||
const vec3 voxelgi_half_extents = vec3(1.0, 1.0, 1.0);
|
||||
const float voxelgi_occ = 1.0;
|
||||
const float voxelgi_step = 1.0;
|
||||
const float voxelgi_range = 2.0;
|
||||
const float MAX_DISTANCE = 1.73205080757 * voxelgi_range;
|
||||
const float VOXEL_SIZE = (2.0 / voxelgi_resolution) * voxelgi_step;
|
||||
|
||||
vec3 tangent(const vec3 n) {
|
||||
vec3 t1 = cross(n, vec3(0.0, 0.0, 1.0));
|
||||
vec3 t2 = cross(n, vec3(0.0, 1.0, 0.0));
|
||||
if (length(t1) > length(t2)) return normalize(t1);
|
||||
else return normalize(t2);
|
||||
}
|
||||
|
||||
float trace_cone_ao(sampler3D voxels, const vec3 origin, vec3 dir, const float aperture, const float max_dist) {
|
||||
dir = normalize(dir);
|
||||
float sample_col = 0.0;
|
||||
float dist = 1.5 * VOXEL_SIZE * cone_offset;
|
||||
float diam = dist * aperture;
|
||||
vec3 sample_pos;
|
||||
while (sample_col < 1.0 && dist < max_dist) {
|
||||
sample_pos = dir * dist + origin;
|
||||
float mip = max(log2(diam * voxelgi_resolution), 0.0);
|
||||
float mip_sample = textureLod(voxels, sample_pos * vec3(0.5, 0.5, 0.5) + vec3(0.5, 0.5, 0.5), mip).r;
|
||||
sample_col += (1.0 - sample_col) * mip_sample;
|
||||
dist += max(diam / 2.0, VOXEL_SIZE);
|
||||
diam = dist * aperture;
|
||||
}
|
||||
return sample_col;
|
||||
}
|
||||
|
||||
float trace_shadow(sampler3D voxels, const vec3 origin, const vec3 dir) {
|
||||
return trace_cone_ao(voxels, origin, dir, 0.14 * cone_aperture, 2.5 * voxelgi_range);
|
||||
}
|
||||
|
||||
float trace_ao(const vec3 origin, const vec3 normal, sampler3D voxels) {
|
||||
const float angle_mix = 0.5;
|
||||
const float aperture = 0.55785173935;
|
||||
vec3 o1 = normalize(tangent(normal));
|
||||
vec3 o2 = normalize(cross(o1, normal));
|
||||
vec3 c1 = vec3(0.5, 0.5, 0.5) * (o1 + o2);
|
||||
vec3 c2 = vec3(0.5, 0.5, 0.5) * (o1 - o2);
|
||||
|
||||
#ifdef HLSL
|
||||
const float factor = voxelgi_occ * 0.93;
|
||||
#else
|
||||
const float factor = voxelgi_occ * 0.90;
|
||||
#endif
|
||||
|
||||
float col = trace_cone_ao(voxels, origin, normal, aperture, MAX_DISTANCE);
|
||||
col += trace_cone_ao(voxels, origin, mix(normal, o1, angle_mix), aperture, MAX_DISTANCE);
|
||||
col += trace_cone_ao(voxels, origin, mix(normal, o2, angle_mix), aperture, MAX_DISTANCE);
|
||||
col += trace_cone_ao(voxels, origin, mix(normal, -c1, angle_mix), aperture, MAX_DISTANCE);
|
||||
col += trace_cone_ao(voxels, origin, mix(normal, -c2, angle_mix), aperture, MAX_DISTANCE);
|
||||
return (col / 5.0) * factor;
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D gbuffer1;
|
||||
#ifdef _Voxel
|
||||
uniform sampler3D voxels;
|
||||
#endif
|
||||
uniform vec4 envmap_data; // angle, sin(angle), cos(angle), strength
|
||||
uniform vec4 shirr[7];
|
||||
uniform sampler2D senvmap_brdf;
|
||||
uniform sampler2D senvmap_radiance;
|
||||
#ifdef SPIRV
|
||||
uniform float envmap_num_mipmaps;
|
||||
#else
|
||||
uniform int envmap_num_mipmaps;
|
||||
#endif
|
||||
uniform sampler2D ssaotex;
|
||||
uniform vec2 camera_proj;
|
||||
uniform vec3 eye;
|
||||
uniform vec3 eye_look;
|
||||
uniform vec3 point_pos;
|
||||
uniform vec3 point_col;
|
||||
#ifdef _Voxel
|
||||
uniform float cone_offset;
|
||||
uniform float cone_aperture;
|
||||
#endif
|
||||
uniform vec3 light_area0;
|
||||
uniform vec3 light_area1;
|
||||
uniform vec3 light_area2;
|
||||
uniform vec3 light_area3;
|
||||
uniform sampler2D sltc_mat;
|
||||
uniform sampler2D sltc_mag;
|
||||
|
||||
#include "gbuffer.glsl"
|
||||
#include "brdf.glsl"
|
||||
#include "math.glsl"
|
||||
#include "shirr.glsl"
|
||||
#ifdef _Voxel
|
||||
#include "conetrace.glsl"
|
||||
#endif
|
||||
|
||||
in vec2 tex_coord;
|
||||
in vec3 view_ray;
|
||||
out vec4 frag_color;
|
||||
|
||||
const float LUT_SIZE = 64.0;
|
||||
const float LUT_SCALE = (LUT_SIZE - 1.0) / LUT_SIZE;
|
||||
const float LUT_BIAS = 0.5 / LUT_SIZE;
|
||||
|
||||
float integrate_edge(vec3 v1, vec3 v2) {
|
||||
float cos_theta = dot(v1, v2);
|
||||
float theta = acos(cos_theta);
|
||||
float res = cross(v1, v2).z * ((theta > 0.001) ? theta / sin(theta) : 1.0);
|
||||
return res;
|
||||
}
|
||||
|
||||
float ltc_evaluate(vec3 N, vec3 V, float dotnv, vec3 P, mat3 Minv, vec3 points0, vec3 points1, vec3 points2, vec3 points3) {
|
||||
// Construct orthonormal basis around N
|
||||
vec3 T1, T2;
|
||||
T1 = normalize(V - N * dotnv);
|
||||
T2 = cross(N, T1);
|
||||
|
||||
// Rotate area light in (T1, T2, R) basis
|
||||
Minv = mul(transpose(mat3(T1, T2, N)), Minv);
|
||||
|
||||
// Polygon (allocate 5 vertices for clipping)
|
||||
vec3 L0 = mul((points0 - P), Minv);
|
||||
vec3 L1 = mul((points1 - P), Minv);
|
||||
vec3 L2 = mul((points2 - P), Minv);
|
||||
vec3 L3 = mul((points3 - P), Minv);
|
||||
vec3 L4 = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
int n = 0;
|
||||
// Detect clipping config
|
||||
int config = 0;
|
||||
if (L0.z > 0.0) config += 1;
|
||||
if (L1.z > 0.0) config += 2;
|
||||
if (L2.z > 0.0) config += 4;
|
||||
if (L3.z > 0.0) config += 8;
|
||||
|
||||
// Clip
|
||||
if (config == 0) {
|
||||
// Clip all
|
||||
}
|
||||
else if (config == 1) { // V1 clip V2 V3 V4
|
||||
n = 3;
|
||||
L1 = -L1.z * L0 + L0.z * L1;
|
||||
L2 = -L3.z * L0 + L0.z * L3;
|
||||
}
|
||||
else if (config == 2) { // V2 clip V1 V3 V4
|
||||
n = 3;
|
||||
L0 = -L0.z * L1 + L1.z * L0;
|
||||
L2 = -L2.z * L1 + L1.z * L2;
|
||||
}
|
||||
else if (config == 3) { // V1 V2 clip V3 V4
|
||||
n = 4;
|
||||
L2 = -L2.z * L1 + L1.z * L2;
|
||||
L3 = -L3.z * L0 + L0.z * L3;
|
||||
}
|
||||
else if (config == 4) { // V3 clip V1 V2 V4
|
||||
n = 3;
|
||||
L0 = -L3.z * L2 + L2.z * L3;
|
||||
L1 = -L1.z * L2 + L2.z * L1;
|
||||
}
|
||||
else if (config == 5) { // V1 V3 clip V2 V4) impossible
|
||||
n = 0;
|
||||
}
|
||||
else if (config == 6) { // V2 V3 clip V1 V4
|
||||
n = 4;
|
||||
L0 = -L0.z * L1 + L1.z * L0;
|
||||
L3 = -L3.z * L2 + L2.z * L3;
|
||||
}
|
||||
else if (config == 7) { // V1 V2 V3 clip V4
|
||||
n = 5;
|
||||
L4 = -L3.z * L0 + L0.z * L3;
|
||||
L3 = -L3.z * L2 + L2.z * L3;
|
||||
}
|
||||
else if (config == 8) { // V4 clip V1 V2 V3
|
||||
n = 3;
|
||||
L0 = -L0.z * L3 + L3.z * L0;
|
||||
L1 = -L2.z * L3 + L3.z * L2;
|
||||
L2 = L3;
|
||||
}
|
||||
else if (config == 9) { // V1 V4 clip V2 V3
|
||||
n = 4;
|
||||
L1 = -L1.z * L0 + L0.z * L1;
|
||||
L2 = -L2.z * L3 + L3.z * L2;
|
||||
}
|
||||
else if (config == 10) { // V2 V4 clip V1 V3) impossible
|
||||
n = 0;
|
||||
}
|
||||
else if (config == 11) { // V1 V2 V4 clip V3
|
||||
n = 5;
|
||||
L4 = L3;
|
||||
L3 = -L2.z * L3 + L3.z * L2;
|
||||
L2 = -L2.z * L1 + L1.z * L2;
|
||||
}
|
||||
else if (config == 12) { // V3 V4 clip V1 V2
|
||||
n = 4;
|
||||
L1 = -L1.z * L2 + L2.z * L1;
|
||||
L0 = -L0.z * L3 + L3.z * L0;
|
||||
}
|
||||
else if (config == 13) { // V1 V3 V4 clip V2
|
||||
n = 5;
|
||||
L4 = L3;
|
||||
L3 = L2;
|
||||
L2 = -L1.z * L2 + L2.z * L1;
|
||||
L1 = -L1.z * L0 + L0.z * L1;
|
||||
}
|
||||
else if (config == 14) { // V2 V3 V4 clip V1
|
||||
n = 5;
|
||||
L4 = -L0.z * L3 + L3.z * L0;
|
||||
L0 = -L0.z * L1 + L1.z * L0;
|
||||
}
|
||||
else if (config == 15) { // V1 V2 V3 V4
|
||||
n = 4;
|
||||
}
|
||||
|
||||
if (n == 0) return 0.0;
|
||||
if (n == 3) L3 = L0;
|
||||
if (n == 4) L4 = L0;
|
||||
|
||||
// Project onto sphere
|
||||
L0 = normalize(L0);
|
||||
L1 = normalize(L1);
|
||||
L2 = normalize(L2);
|
||||
L3 = normalize(L3);
|
||||
L4 = normalize(L4);
|
||||
|
||||
// Integrate
|
||||
float sum = 0.0;
|
||||
|
||||
sum += integrate_edge(L0, L1);
|
||||
sum += integrate_edge(L1, L2);
|
||||
sum += integrate_edge(L2, L3);
|
||||
|
||||
if (n >= 4) sum += integrate_edge(L3, L4);
|
||||
if (n == 5) sum += integrate_edge(L4, L0);
|
||||
|
||||
return max(0.0, -sum);
|
||||
}
|
||||
|
||||
vec3 sample_light(const vec3 p, const vec3 n, const vec3 v, const float dotnv, const vec3 lp, const vec3 light_col,
|
||||
const vec3 albedo, const float rough, const vec3 f0, const float occ
|
||||
#ifdef _Voxel
|
||||
, sampler3D voxels, vec3 voxpos
|
||||
#endif
|
||||
) {
|
||||
vec3 ld = lp - p;
|
||||
vec3 l = normalize(ld);
|
||||
float dotnl = max(0.0, dot(n, l));
|
||||
|
||||
float theta = acos(dotnv);
|
||||
vec2 tuv = vec2(rough, theta / (0.5 * PI));
|
||||
tuv = tuv * LUT_SCALE + LUT_BIAS;
|
||||
vec4 t = textureLod(sltc_mat, tuv, 0.0);
|
||||
mat3 inv = mat3(
|
||||
vec3(1.0, 0.0, t.y),
|
||||
vec3(0.0, t.z, 0.0),
|
||||
vec3(t.w, 0.0, t.x));
|
||||
float ltcspec = ltc_evaluate(n, v, dotnv, p, inv, light_area0, light_area1, light_area2, light_area3);
|
||||
ltcspec *= textureLod(sltc_mag, tuv, 0.0).a;
|
||||
|
||||
mat3 m1 = mat3(
|
||||
vec3(1.0, 0.0, 0.0),
|
||||
vec3(0.0, 1.0, 0.0),
|
||||
vec3(0.0, 0.0, 1.0));
|
||||
float ltcdiff = ltc_evaluate(n, v, dotnv, p, m1, light_area0, light_area1, light_area2, light_area3);
|
||||
vec3 direct = albedo * ltcdiff + ltcspec * 0.05;
|
||||
|
||||
direct *= attenuate(distance(p, lp));
|
||||
direct *= light_col;
|
||||
direct *= clamp(dotnl + 2.0 * occ * occ - 1.0, 0.0, 1.0); // Micro shadowing
|
||||
|
||||
#ifdef _Voxel
|
||||
float voxshadow = 1.0 - trace_shadow(voxels, voxpos, l);
|
||||
direct *= vec3(voxshadow, voxshadow, voxshadow);
|
||||
#endif
|
||||
|
||||
return direct;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 g0 = textureLod(gbuffer0, tex_coord, 0.0); // Normal.xy, roughness, metallic/matid
|
||||
|
||||
vec3 n;
|
||||
n.z = 1.0 - abs(g0.x) - abs(g0.y);
|
||||
n.xy = n.z >= 0.0 ? g0.xy : octahedron_wrap(g0.xy);
|
||||
n = normalize(n);
|
||||
|
||||
float roughness = g0.b;
|
||||
float metallic;
|
||||
uint matid;
|
||||
unpack_f32_i16(g0.a, metallic, matid);
|
||||
vec4 g1 = textureLod(gbuffer1, tex_coord, 0.0); // Basecolor.rgb, occ
|
||||
float occ = g1.a;
|
||||
vec3 albedo = surface_albedo(g1.rgb, metallic); // g1.rgb - basecolor
|
||||
vec3 f0 = surface_f0(g1.rgb, metallic);
|
||||
|
||||
float depth = textureLod(gbufferD, tex_coord, 0.0).r * 2.0 - 1.0;
|
||||
vec3 p = get_pos(eye, eye_look, normalize(view_ray), depth, camera_proj);
|
||||
vec3 v = normalize(eye - p);
|
||||
float dotnv = max(0.0, dot(n, v));
|
||||
|
||||
occ = mix(1.0, occ, dotnv); // AO Fresnel
|
||||
|
||||
vec2 env_brdf = texelFetch(senvmap_brdf, ivec2(vec2(roughness, 1.0 - dotnv) * 256.0), 0).xy;
|
||||
|
||||
// Envmap
|
||||
vec3 envl = sh_irradiance(vec3(n.x * envmap_data.z - n.y * envmap_data.y, n.x * envmap_data.y + n.y * envmap_data.z, n.z), shirr);
|
||||
envl /= PI;
|
||||
|
||||
vec3 reflection_world = reflect(-v, n);
|
||||
float lod = mip_from_roughness(roughness, float(envmap_num_mipmaps));
|
||||
vec3 prefiltered_color = textureLod(senvmap_radiance, envmap_equirect(reflection_world, envmap_data.x), lod).rgb;
|
||||
|
||||
envl.rgb *= albedo;
|
||||
|
||||
// Indirect specular
|
||||
envl.rgb += prefiltered_color * (f0 * env_brdf.x + env_brdf.y) * 1.5;
|
||||
|
||||
envl.rgb *= envmap_data.w * occ;
|
||||
|
||||
#ifdef _Voxel
|
||||
vec3 voxpos = p / voxelgi_half_extents;
|
||||
float voxao = 1.0 - trace_ao(voxpos, n, voxels);
|
||||
envl.rgb *= vec3(voxao, voxao, voxao);
|
||||
#endif
|
||||
|
||||
frag_color.rgb = envl;
|
||||
frag_color.rgb *= textureLod(ssaotex, tex_coord, 0.0).r;
|
||||
|
||||
if (matid == uint(1)) { // Emission
|
||||
frag_color.rgb += g1.rgb; // materialid
|
||||
albedo = vec3(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
frag_color.rgb += sample_light(p, n, v, dotnv, point_pos, point_col, albedo, roughness, f0, occ
|
||||
#ifdef _Voxel
|
||||
, voxels, voxpos
|
||||
#endif
|
||||
);
|
||||
frag_color.a = 1.0; // Mark as opaque
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
#version 450
|
||||
#extension GL_ARB_shader_image_load_store : enable
|
||||
|
||||
const int voxelgi_resolution = 256;
|
||||
|
||||
uniform layout(r8) writeonly image3D voxels;
|
||||
|
||||
in vec3 voxposition;
|
||||
|
||||
void main() {
|
||||
if (abs(voxposition.z) > 1.0 || abs(voxposition.x) > 1.0 || abs(voxposition.y) > 1.0) return;
|
||||
imageStore(voxels, ivec3(voxelgi_resolution * (voxposition * 0.5 + 0.5)), vec4(1.0));
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#version 450
|
||||
layout(triangles) in;
|
||||
layout(triangle_strip) out;
|
||||
layout(max_vertices=3) out;
|
||||
|
||||
in vec3 voxposition_geom[];
|
||||
out vec3 voxposition;
|
||||
|
||||
void main() {
|
||||
vec3 p1 = voxposition_geom[1] - voxposition_geom[0];
|
||||
vec3 p2 = voxposition_geom[2] - voxposition_geom[0];
|
||||
vec3 p = abs(cross(p1, p2));
|
||||
for (uint i = 0; i < 3; ++i) {
|
||||
voxposition = voxposition_geom[i];
|
||||
if (p.z > p.x && p.z > p.y) {
|
||||
gl_Position = vec4(voxposition.x, voxposition.y, 0.0, 1.0);
|
||||
}
|
||||
else if (p.x > p.y && p.x > p.z) {
|
||||
gl_Position = vec4(voxposition.y, voxposition.z, 0.0, 1.0);
|
||||
}
|
||||
else {
|
||||
gl_Position = vec4(voxposition.x, voxposition.z, 0.0, 1.0);
|
||||
}
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
#version 450
|
||||
|
||||
const vec3 voxelgi_half_extents = vec3(1, 1, 1);
|
||||
|
||||
uniform mat4 W;
|
||||
|
||||
in vec4 pos;
|
||||
out vec3 voxposition_geom;
|
||||
|
||||
void main() {
|
||||
voxposition_geom = vec3(W * vec4(pos.xyz, 1.0)) / voxelgi_half_extents;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
..\..\..\..\armorcore\tools\bin\windows_x64\amake.exe --hlslbin voxel_pos.vert.hlsl ..\voxel_pos.vert.glsl
|
||||
..\..\..\..\armorcore\tools\bin\windows_x64\amake.exe --hlslbin voxel_pos.frag.hlsl ..\voxel_pos.frag.glsl
|
||||
..\..\..\..\armorcore\tools\bin\windows_x64\amake.exe --hlslbin voxel_pos.geom.hlsl ..\voxel_pos.geom.glsl
|
||||
@@ -1,9 +0,0 @@
|
||||
RWTexture3D<float> voxels;
|
||||
|
||||
struct SPIRV_Cross_Input { float3 wpos : TEXCOORD0; };
|
||||
struct SPIRV_Cross_Output { float4 frag_color : SV_TARGET0; };
|
||||
|
||||
void main(SPIRV_Cross_Input stage_input) {
|
||||
if (abs(stage_input.wpos.z) > 1.0 || abs(stage_input.wpos.x) > 1 || abs(stage_input.wpos.y) > 1) return;
|
||||
voxels[int3(256, 256, 256) * (stage_input.wpos * 0.5 + 0.5)] = 1.0;
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
struct SPIRV_Cross_Input { float4 svpos : SV_POSITION; };
|
||||
struct SPIRV_Cross_Output { float3 wpos : TEXCOORD0; float4 svpos : SV_POSITION; };
|
||||
|
||||
[maxvertexcount(3)]
|
||||
void main(triangle SPIRV_Cross_Input stage_input[3], inout TriangleStream<SPIRV_Cross_Output> output) {
|
||||
float3 p1 = stage_input[1].svpos.xyz - stage_input[0].svpos.xyz;
|
||||
float3 p2 = stage_input[2].svpos.xyz - stage_input[0].svpos.xyz;
|
||||
float3 p = abs(cross(p1, p2));
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.wpos = stage_input[i].svpos.xyz;
|
||||
if (p.z > p.x && p.z > p.y) {
|
||||
stage_output.svpos = float4(stage_input[i].svpos.x, stage_input[i].svpos.y, 0.0, 1.0);
|
||||
}
|
||||
else if (p.x > p.y && p.x > p.z) {
|
||||
stage_output.svpos = float4(stage_input[i].svpos.y, stage_input[i].svpos.z, 0.0, 1.0);
|
||||
}
|
||||
else {
|
||||
stage_output.svpos = float4(stage_input[i].svpos.x, stage_input[i].svpos.z, 0.0, 1.0);
|
||||
}
|
||||
output.Append(stage_output);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
uniform float4x4 W;
|
||||
|
||||
struct SPIRV_Cross_Input { float4 pos : TEXCOORD0; };
|
||||
struct SPIRV_Cross_Output { float4 svpos : SV_POSITION; };
|
||||
|
||||
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) {
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.svpos.xyz = mul(float4(stage_input.pos.xyz, 1.0), W).xyz / float3(1, 1, 1);
|
||||
stage_output.svpos.w = 1.0;
|
||||
return stage_output;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -603,35 +603,6 @@ function box_preferences_show() {
|
||||
}
|
||||
|
||||
if (context_raw.render_mode == render_mode_t.DEFERRED) {
|
||||
///if arm_voxels
|
||||
ui_check(context_raw.hvxao, tr("Voxel AO"));
|
||||
if (ui.is_hovered) {
|
||||
ui_tooltip(tr("Cone-traced AO and shadows"));
|
||||
}
|
||||
if (context_raw.hvxao.changed) {
|
||||
config_apply();
|
||||
}
|
||||
|
||||
ui.enabled = context_raw.hvxao.selected;
|
||||
let h: ui_handle_t = ui_handle(__ID__);
|
||||
if (h.init) {
|
||||
h.value = context_raw.vxao_offset;
|
||||
}
|
||||
context_raw.vxao_offset = ui_slider(h, tr("Cone Offset"), 1.0, 4.0, true);
|
||||
if (h.changed) {
|
||||
context_raw.ddirty = 2;
|
||||
}
|
||||
h = ui_handle(__ID__);
|
||||
if (h.init) {
|
||||
h.value = context_raw.vxao_aperture;
|
||||
}
|
||||
context_raw.vxao_aperture = ui_slider(h, tr("Aperture"), 1.0, 4.0, true);
|
||||
if (h.changed) {
|
||||
context_raw.ddirty = 2;
|
||||
}
|
||||
ui.enabled = true;
|
||||
///end
|
||||
|
||||
ui_check(context_raw.hssao, tr("SSAO"));
|
||||
if (context_raw.hssao.changed) {
|
||||
config_apply();
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
|
||||
///if arm_voxels
|
||||
function make_voxel_run(data: shader_context_t) {
|
||||
let structure: vertex_struct_t = g4_vertex_struct_create();
|
||||
g4_vertex_struct_add(structure, "pos", vertex_data_t.I16_4X_NORM);
|
||||
g4_vertex_struct_add(structure, "nor", vertex_data_t.I16_2X_NORM);
|
||||
g4_vertex_struct_add(structure, "tex", vertex_data_t.I16_2X_NORM);
|
||||
|
||||
let pipe_state: pipeline_t = data._.pipe_state;
|
||||
pipe_state.input_layout = [structure];
|
||||
|
||||
data.vertex_elements = [
|
||||
{
|
||||
name: "pos",
|
||||
data: "short4norm"
|
||||
},
|
||||
{
|
||||
name: "nor",
|
||||
data: "short2norm"
|
||||
},
|
||||
{
|
||||
name: "tex",
|
||||
data: "short2norm"
|
||||
}
|
||||
];
|
||||
|
||||
// ///if arm_skin
|
||||
// let is_mesh: bool = raw.object.constructor == mesh_object_t;
|
||||
// let skin: bool = is_mesh && cast(raw.object, mesh_object_t).data.geom.bones != null;
|
||||
// if (skin) {
|
||||
// g4_vertex_structure_add(structure, "bone", vertex_data_t.I16_4X_Normalized);
|
||||
// g4_vertex_structure_add(structure, "weight", vertex_data_t.I16_4X_Normalized);
|
||||
// array_push(data.raw.vertex_elements, { name: "bone", data: "short4norm" });
|
||||
// array_push(data.raw.vertex_elements, { name: "weight", data: "short4norm" });
|
||||
// }
|
||||
// ///end
|
||||
|
||||
pipe_state.vertex_shader = g4_shader_from_source(make_voxel_source(), shader_type_t.VERTEX);
|
||||
|
||||
g4_pipeline_compile(pipe_state);
|
||||
|
||||
data.constants = [
|
||||
{
|
||||
name: "W",
|
||||
type: "mat4",
|
||||
link: "_world_matrix"
|
||||
},
|
||||
{
|
||||
name: "N",
|
||||
type: "mat3",
|
||||
link: "_normal_matrix"
|
||||
}
|
||||
];
|
||||
data._.constants = [
|
||||
g4_pipeline_get_const_loc(pipe_state, "W"),
|
||||
g4_pipeline_get_const_loc(pipe_state, "N")
|
||||
];
|
||||
data.texture_units = [
|
||||
{
|
||||
name: "texpaint_pack"
|
||||
},
|
||||
{
|
||||
name: "voxels",
|
||||
image_uniform: true
|
||||
}
|
||||
];
|
||||
data._.tex_units = [
|
||||
g4_pipeline_get_tex_unit(pipe_state, "texpaint_pack"),
|
||||
g4_pipeline_get_tex_unit(pipe_state, "voxels")
|
||||
];
|
||||
}
|
||||
|
||||
function make_voxel_source(): string {
|
||||
let ds: f32 = make_material_get_displace_strength();
|
||||
///if arm_direct3d11
|
||||
return "#define vec3 float3 \n\
|
||||
uniform float4x4 W; \
|
||||
uniform float3x3 N; \
|
||||
Texture2D<float4> texpaint_pack; \
|
||||
SamplerState _texpaint_pack_sampler; \
|
||||
struct SPIRV_Cross_Input { float4 pos : TEXCOORD1; float2 nor : TEXCOORD0; float2 tex : TEXCOORD2; }; \
|
||||
struct SPIRV_Cross_Output { float4 svpos : SV_POSITION; }; \
|
||||
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { \
|
||||
SPIRV_Cross_Output stage_output; \
|
||||
" + make_material_voxelgi_half_extents() + " \
|
||||
stage_output.svpos.xyz = mul(float4(stage_input.pos.xyz, 1.0), W).xyz / voxelgi_half_extents.xxx; \
|
||||
float3 wnormal = normalize(mul(float3(stage_input.nor.xy, stage_input.pos.w), N)); \
|
||||
float height = texpaint_pack.SampleLevel(_texpaint_pack_sampler, stage_input.tex, 0.0).a; \
|
||||
stage_output.svpos.xyz += wnormal * height.xxx * float3(" + ds + ", " + ds + ", " + ds + "); \
|
||||
stage_output.svpos.w = 1.0; \
|
||||
return stage_output; \
|
||||
}";
|
||||
///else
|
||||
return "#version 450 \n\
|
||||
in vec4 pos; \
|
||||
in vec2 nor; \
|
||||
in vec2 tex; \
|
||||
out vec3 voxposition_geom; \
|
||||
uniform mat4 W; \
|
||||
uniform mat3 N; \
|
||||
uniform sampler2D texpaint_pack; \
|
||||
void main() { \
|
||||
" + make_material_voxelgi_half_extents() + " \
|
||||
voxposition_geom = vec3(W * vec4(pos.xyz, 1.0)) / voxelgi_half_extents; \
|
||||
vec3 wnormal = normalize(N * vec3(nor.xy, pos.w)); \
|
||||
float height = textureLod(texpaint_pack, tex, 0.0).a; \
|
||||
voxposition_geom += wnormal * vec3(height) * vec3(" + ds + "); \
|
||||
}";
|
||||
///end
|
||||
}
|
||||
///end
|
||||
@@ -6,10 +6,6 @@ let render_path_base_last_y: f32 = -1.0;
|
||||
let render_path_base_bloom_mipmaps: render_target_t[];
|
||||
let render_path_base_bloom_current_mip: i32 = 0;
|
||||
let render_path_base_bloom_sample_scale: f32;
|
||||
///if arm_voxels
|
||||
let render_path_base_voxels_res: i32 = 256;
|
||||
let render_path_base_voxels_created: bool = false;
|
||||
///end
|
||||
|
||||
function render_path_base_init() {
|
||||
pipes_init();
|
||||
@@ -17,28 +13,6 @@ function render_path_base_init() {
|
||||
render_path_base_super_sample = config_raw.rp_supersample;
|
||||
}
|
||||
|
||||
///if arm_voxels
|
||||
function render_path_base_init_voxels(target_name: string = "voxels") {
|
||||
if (config_raw.rp_gi != true || render_path_base_voxels_created) {
|
||||
return;
|
||||
}
|
||||
|
||||
render_path_base_voxels_created = true;
|
||||
|
||||
{
|
||||
let t: render_target_t = render_target_create();
|
||||
t.name = target_name;
|
||||
t.format = "R8";
|
||||
t.width = render_path_base_voxels_res;
|
||||
t.height = render_path_base_voxels_res;
|
||||
t.depth = render_path_base_voxels_res;
|
||||
t.is_image = true;
|
||||
t.mipmaps = true;
|
||||
render_path_create_render_target(t);
|
||||
}
|
||||
}
|
||||
///end
|
||||
|
||||
function render_path_base_apply_config() {
|
||||
if (render_path_base_super_sample != config_raw.rp_supersample) {
|
||||
render_path_base_super_sample = config_raw.rp_supersample;
|
||||
@@ -51,11 +25,6 @@ function render_path_base_apply_config() {
|
||||
}
|
||||
render_path_resize();
|
||||
}
|
||||
///if arm_voxels
|
||||
if (!render_path_base_voxels_created) {
|
||||
render_path_base_init_voxels();
|
||||
}
|
||||
///end
|
||||
}
|
||||
|
||||
function render_path_base_get_super_sampling(): f32 {
|
||||
@@ -254,26 +223,6 @@ function render_path_base_draw_split(draw_commands: ()=>void) {
|
||||
}
|
||||
}
|
||||
|
||||
///if arm_voxels
|
||||
function render_path_base_draw_voxels() {
|
||||
if (config_raw.rp_gi != false) {
|
||||
let voxelize: bool = context_raw.ddirty > 0 && render_path_base_taa_frame > 0;
|
||||
if (voxelize) {
|
||||
render_path_clear_image("voxels", 0x00000000);
|
||||
render_path_set_target("");
|
||||
render_path_set_viewport(render_path_base_voxels_res, render_path_base_voxels_res);
|
||||
render_path_bind_target("voxels", "voxels");
|
||||
if (make_material_height_used) {
|
||||
let tid: i32 = 0; // layers[0].id;
|
||||
render_path_bind_target("texpaint_pack" + tid, "texpaint_pack");
|
||||
}
|
||||
render_path_draw_meshes("voxel");
|
||||
render_path_gen_mipmaps("voxels");
|
||||
}
|
||||
}
|
||||
}
|
||||
///end
|
||||
|
||||
function render_path_base_init_ssao() {
|
||||
{
|
||||
let t: render_target_t = render_target_create();
|
||||
@@ -335,17 +284,8 @@ function render_path_base_draw_deferred_light() {
|
||||
render_path_bind_target("empty_white", "ssaotex");
|
||||
}
|
||||
|
||||
let voxelao_pass: bool = false;
|
||||
///if arm_voxels
|
||||
if (config_raw.rp_gi != false) {
|
||||
voxelao_pass = true;
|
||||
render_path_bind_target("voxels", "voxels");
|
||||
}
|
||||
///end
|
||||
|
||||
voxelao_pass ?
|
||||
render_path_draw_shader("shader_datas/deferred_light/deferred_light_voxel") :
|
||||
render_path_draw_shader("shader_datas/deferred_light/deferred_light");
|
||||
render_path_draw_shader("shader_datas/deferred_light/deferred_light");
|
||||
|
||||
render_path_set_depth_from("tex", "gbuffer0"); // Bind depth for world pass
|
||||
|
||||
|
||||
@@ -144,12 +144,6 @@ function render_path_deferred_init() {
|
||||
render_path_load_shader("shader_datas/supersample_resolve/supersample_resolve");
|
||||
// render_path_load_shader("shader_datas/motion_blur_pass/motion_blur_pass");
|
||||
// render_path_load_shader("shader_datas/motion_blur_veloc_pass/motion_blur_veloc_pass");
|
||||
///if arm_voxels
|
||||
{
|
||||
render_path_base_init_voxels();
|
||||
render_path_load_shader("shader_datas/deferred_light/deferred_light_voxel");
|
||||
}
|
||||
///end
|
||||
|
||||
render_path_paint_init();
|
||||
|
||||
@@ -169,9 +163,6 @@ function render_path_deferred_commands() {
|
||||
|
||||
function render_path_deferred_draw_deferred() {
|
||||
render_path_base_draw_ssao();
|
||||
///if arm_voxels
|
||||
render_path_base_draw_voxels();
|
||||
///end
|
||||
render_path_base_draw_deferred_light();
|
||||
render_path_base_draw_bloom("tex");
|
||||
// draw_motion_blur();
|
||||
|
||||
@@ -229,59 +229,6 @@ vec3 brightcontrast(const vec3 col, const float bright, const float contr) { \
|
||||
} \
|
||||
";
|
||||
|
||||
///if arm_voxels
|
||||
let str_trace_ao: string = " \
|
||||
float trace_cone_ao(sampler3D voxels, const vec3 origin, vec3 dir, const float aperture, const float max_dist, const float offset) { \
|
||||
const ivec3 voxelgi_resolution = ivec3(256, 256, 256); \
|
||||
const float voxelgi_step = 1.0; \
|
||||
const float VOXEL_SIZE = (2.0 / voxelgi_resolution.x) * voxelgi_step; \
|
||||
dir = normalize(dir); \
|
||||
float sample_col = 0.0; \
|
||||
float dist = offset; \
|
||||
float diam = dist * aperture; \
|
||||
vec3 sample_pos; \
|
||||
while (sample_col < 1.0 && dist < max_dist) { \
|
||||
sample_pos = dir * dist + origin; \
|
||||
float mip = max(log2(diam * voxelgi_resolution.x), 0); \
|
||||
float mip_sample = textureLod(voxels, sample_pos * 0.5 + vec3(0.5, 0.5, 0.5), mip).r; \
|
||||
sample_col += (1 - sample_col) * mip_sample; \
|
||||
dist += max(diam / 2, VOXEL_SIZE); \
|
||||
diam = dist * aperture; \
|
||||
} \
|
||||
return sample_col; \
|
||||
} \
|
||||
vec3 tangent(const vec3 n) { \
|
||||
vec3 t1 = cross(n, vec3(0, 0, 1)); \
|
||||
vec3 t2 = cross(n, vec3(0, 1, 0)); \
|
||||
if (length(t1) > length(t2)) return normalize(t1); \
|
||||
else return normalize(t2); \
|
||||
} \
|
||||
float trace_ao(const vec3 origin, const vec3 normal, const float vrange, const float voffset) { \
|
||||
const float angle_mix = 0.5f; \
|
||||
const float aperture = 0.55785173935; \
|
||||
vec3 o1 = normalize(tangent(normal)); \
|
||||
vec3 o2 = normalize(cross(o1, normal)); \
|
||||
vec3 c1 = 0.5f * (o1 + o2); \
|
||||
vec3 c2 = 0.5f * (o1 - o2); \
|
||||
float MAX_DISTANCE = 1.73205080757 * 2.0 * vrange; \
|
||||
const ivec3 voxelgi_resolution = ivec3(256, 256, 256); \
|
||||
const float voxelgi_step = 1.0; \
|
||||
const float VOXEL_SIZE = (2.0 / voxelgi_resolution.x) * voxelgi_step; \
|
||||
float offset = 1.5 * VOXEL_SIZE * 2.5 * voffset; \
|
||||
float col = trace_cone_ao(voxels, origin, normal, aperture, MAX_DISTANCE, offset); \
|
||||
col += trace_cone_ao(voxels, origin, mix(normal, o1, angle_mix), aperture, MAX_DISTANCE, offset); \
|
||||
col += trace_cone_ao(voxels, origin, mix(normal, o2, angle_mix), aperture, MAX_DISTANCE, offset); \
|
||||
col += trace_cone_ao(voxels, origin, mix(normal, -c1, angle_mix), aperture, MAX_DISTANCE, offset); \
|
||||
col += trace_cone_ao(voxels, origin, mix(normal, -c2, angle_mix), aperture, MAX_DISTANCE, offset); \
|
||||
col += trace_cone_ao(voxels, origin, mix(normal, -o1, angle_mix), aperture, MAX_DISTANCE, offset); \
|
||||
col += trace_cone_ao(voxels, origin, mix(normal, -o2, angle_mix), aperture, MAX_DISTANCE, offset); \
|
||||
col += trace_cone_ao(voxels, origin, mix(normal, c1, angle_mix), aperture, MAX_DISTANCE, offset); \
|
||||
col += trace_cone_ao(voxels, origin, mix(normal, c2, angle_mix), aperture, MAX_DISTANCE, offset); \
|
||||
return col / 9.0; \
|
||||
} \
|
||||
";
|
||||
///end
|
||||
|
||||
let str_cotangent_frame: string = " \
|
||||
mat3 cotangent_frame(const vec3 n, const vec3 p, const vec2 duv1, const vec2 duv2) { \
|
||||
vec3 dp1 = dFdx(p); \
|
||||
|
||||
Reference in New Issue
Block a user