Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--release/datafiles/gmon.outbin0 -> 2072089 bytes
-rw-r--r--release/scripts/startup/bl_ui/properties_data_lamp.py46
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py63
-rw-r--r--release/scripts/startup/bl_ui/properties_world.py24
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py39
-rw-r--r--source/blender/blenkernel/intern/library_query.c4
-rw-r--r--source/blender/blenkernel/intern/object.c13
-rw-r--r--source/blender/blenkernel/intern/world.c10
-rw-r--r--source/blender/blenloader/intern/readfile.c24
-rw-r--r--source/blender/blenloader/intern/versioning_270.c23
-rw-r--r--source/blender/blenloader/intern/writefile.c11
-rw-r--r--source/blender/editors/include/ED_view3d.h4
-rw-r--r--source/blender/editors/object/CMakeLists.txt1
-rw-r--r--source/blender/editors/object/object_add.c4
-rw-r--r--source/blender/editors/object/object_intern.h4
-rw-r--r--source/blender/editors/object/object_ops.c3
-rw-r--r--source/blender/editors/object/object_probe.c162
-rw-r--r--source/blender/editors/render/render_intern.h2
-rw-r--r--source/blender/editors/render/render_opengl.c2
-rw-r--r--source/blender/editors/render/render_ops.c2
-rw-r--r--source/blender/editors/render/render_shading.c47
-rw-r--r--source/blender/editors/render/render_update.c72
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c6
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c6
-rw-r--r--source/blender/editors/space_view3d/drawobject.c36
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c72
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c521
-rw-r--r--source/blender/gpu/CMakeLists.txt43
-rw-r--r--source/blender/gpu/GPU_compositing.h7
-rw-r--r--source/blender/gpu/GPU_draw.h7
-rw-r--r--source/blender/gpu/GPU_framebuffer.h3
-rw-r--r--source/blender/gpu/GPU_ltc.h48
-rw-r--r--source/blender/gpu/GPU_material.h85
-rw-r--r--source/blender/gpu/GPU_pbr.h85
-rw-r--r--source/blender/gpu/GPU_probe.h118
-rw-r--r--source/blender/gpu/GPU_shader.h14
-rw-r--r--source/blender/gpu/GPU_texture.h19
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c108
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h13
-rw-r--r--source/blender/gpu/intern/gpu_compositing.c221
-rw-r--r--source/blender/gpu/intern/gpu_draw.c181
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c1
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c88
-rw-r--r--source/blender/gpu/intern/gpu_material.c1295
-rw-r--r--source/blender/gpu/intern/gpu_pbr.c327
-rw-r--r--source/blender/gpu/intern/gpu_probe.c685
-rw-r--r--source/blender/gpu/intern/gpu_shader.c186
-rw-r--r--source/blender/gpu/intern/gpu_texture.c308
-rw-r--r--source/blender/gpu/shaders/gpu_shader_display_sh_frag.glsl58
-rw-r--r--source/blender/gpu/shaders/gpu_shader_display_sh_vert.glsl13
-rw-r--r--source/blender/gpu/shaders/gpu_shader_downsample_maxz_frag.glsl74
-rw-r--r--source/blender/gpu/shaders/gpu_shader_downsample_maxz_vert.glsl6
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_colormanage_frag.glsl99
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl1241
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material_bsdf_ambient_occlusion.glsl160
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material_bsdf_anisotropic.glsl772
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material_bsdf_diffuse.glsl263
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material_bsdf_glass.glsl345
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material_bsdf_glossy.glsl710
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material_bsdf_refraction.glsl490
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material_bsdf_toon.glsl273
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material_bsdf_translucent.glsl55
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material_bsdf_transparent.glsl30
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material_bsdf_velvet.glsl156
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material_new_shading.glsl1207
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material_utils.glsl1113
-rw-r--r--source/blender/gpu/shaders/gpu_shader_probe_sh_compute_frag.glsl108
-rw-r--r--source/blender/gpu/shaders/gpu_shader_probe_sh_compute_vert.glsl5
-rw-r--r--source/blender/makesdna/DNA_color_types.h3
-rw-r--r--source/blender/makesdna/DNA_gpu_types.h47
-rw-r--r--source/blender/makesdna/DNA_image_types.h4
-rw-r--r--source/blender/makesdna/DNA_node_types.h1
-rw-r--r--source/blender/makesdna/DNA_object_types.h41
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h10
-rw-r--r--source/blender/makesdna/DNA_world_types.h12
-rw-r--r--source/blender/makesrna/intern/rna_color.c10
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_object.c184
-rw-r--r--source/blender/makesrna/intern/rna_scene.c12
-rw-r--r--source/blender/makesrna/intern/rna_space.c141
-rw-r--r--source/blender/makesrna/intern/rna_world.c53
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.c30
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_blackbody.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c64
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c48
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c57
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c56
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c56
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_toon.c50
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c49
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.c31
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c43
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_emission.c8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_fresnel.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_geometry.c17
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_holdout.c1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_lamp.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_layer_weight.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_light_falloff.c13
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_object_info.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_lamp.c11
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tangent.c24
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_coord.c8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c16
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c46
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_texture.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_wavelength.c7
-rw-r--r--source/blender/python/intern/gpu_offscreen.c4
-rw-r--r--source/gameengine/Ketsji/BL_BlenderShader.cpp2
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp2
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp2
112 files changed, 11718 insertions, 1690 deletions
diff --git a/.gitignore b/.gitignore
index 977fd9c2627..8347d2d2944 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,8 @@ __pycache__/
*~
*.swp
*.swo
+*.sublime-project
+*.sublime-workspace
*#
# QtCreator
diff --git a/release/datafiles/gmon.out b/release/datafiles/gmon.out
new file mode 100644
index 00000000000..9f19378ce5d
--- /dev/null
+++ b/release/datafiles/gmon.out
Binary files differ
diff --git a/release/scripts/startup/bl_ui/properties_data_lamp.py b/release/scripts/startup/bl_ui/properties_data_lamp.py
index 30cd39d2e2f..c5d985e7b12 100644
--- a/release/scripts/startup/bl_ui/properties_data_lamp.py
+++ b/release/scripts/startup/bl_ui/properties_data_lamp.py
@@ -388,6 +388,52 @@ class DATA_PT_falloff_curve(DataButtonsPanel, Panel):
self.layout.template_curve_mapping(lamp, "falloff_curve", use_negative_slope=True)
+class DATA_PT_viewport(DataButtonsPanel, Panel):
+ bl_label = "Viewport Settings"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'CYCLES'}
+
+ @classmethod
+ def poll(cls, context):
+ lamp = context.lamp
+ engine = context.scene.render.engine
+
+ return lamp and (engine in cls.COMPAT_ENGINES)
+
+ def draw(self, context):
+ layout = self.layout
+
+ lamp = context.lamp
+
+ split = layout.split()
+ col = split.column()
+ col.prop(lamp, "use_specular")
+ col.prop(lamp, "use_diffuse")
+
+
+ if lamp.type in {'SPOT','SUN','AREA'}:
+
+ col = split.column()
+ col.prop(lamp, "use_shadow", text="Use Shadow")
+
+ layout.label(text="Shadow Settings:")
+
+ col = layout.column(align=True)
+ col.active = lamp.use_shadow
+ col.prop(lamp, "ge_shadow_buffer_type", text="", toggle=True)
+ col.prop(lamp, "shadow_buffer_size", text="Size")
+ col.prop(lamp, "shadow_buffer_bias", text="Bias")
+ col.prop(lamp, "shadow_buffer_bleed_bias", text="Bleed Bias")
+
+ row = layout.row(align=True)
+ row.active = lamp.use_shadow
+ row.prop(lamp, "shadow_buffer_clip_start", text="Clip Start")
+ row.prop(lamp, "shadow_buffer_clip_end", text="Clip End")
+
+ if lamp.type == 'SUN':
+ row = layout.row()
+ row.prop(lamp, "shadow_frustum_size", text="Frustum Size")
+
class DATA_PT_custom_props_lamp(DataButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index 3ff7a248c60..55b24065060 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -323,6 +323,69 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel):
layout.prop(ob, "use_extra_recalc_data")
+class OBJECT_PT_probe_settings(ObjectButtonsPanel, Panel):
+ bl_label = "Viewport Probe"
+ bl_context = "object"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'CYCLES'}
+
+ @classmethod
+ def poll(cls, context):
+ return (context.object)
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.object
+
+ layout.prop(ob, "probe_type", expand=True)
+
+ if ob.probe_type == 'OBJECT':
+ layout.prop(ob, "probe_object")
+
+ elif ob.probe_type in {'CUBE', 'PLANE'}:
+ split = layout.split()
+
+ layout.operator("object.probe_update", text="Update Probe", icon="FILE_REFRESH").type = 'ACTIVE_PROBE'
+
+ col = split.column()
+ col.prop(ob, "probe_refresh_auto", text="Auto Refresh")
+ col.prop(ob, "probe_compute_sh")
+ col = split.column()
+ col.prop(ob, "probe_refresh_double", text="Double Refresh")
+ col.prop(ob, "probe_use_layers")
+
+ split = layout.split()
+
+ col = split.column(align=True)
+ col.label(text="Quality:")
+ col.prop(ob, "probe_size", text="Reflection")
+ col.prop(ob, "probe_sh_quality", text="Diffuse")
+
+ col = split.column(align=True)
+ col.label(text="Clipping:")
+
+ if ob.probe_type == 'PLANE':
+ col.prop(ob, "probe_clip_bias", text="Bias")
+ else :
+ col.prop(ob, "probe_clip_start", text="Start")
+
+ col.prop(ob, "probe_clip_end", text="End")
+
+ if ob.probe_type == 'PLANE':
+ row = layout.row()
+ row.prop(ob, "probe_reflection_plane", text="Reflection Plane")
+ layout.prop(ob, "probe_object", text="Default Cube Probe")
+
+ elif ob.probe_type == 'CUBE':
+ row = layout.row()
+ row.prop(ob, "probe_parallax_type", text="Parallax")
+
+ row = layout.row()
+ row.active = (ob.probe_parallax_type in {"ELLIPSOID", "BOX"})
+ row.prop(ob, "probe_parallax_volume", text="Parallax Volume")
+
+
from bl_ui.properties_animviz import (
MotionPathButtonsPanel,
OnionSkinButtonsPanel,
diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py
index e07349a99ee..9bf23dacca6 100644
--- a/release/scripts/startup/bl_ui/properties_world.py
+++ b/release/scripts/startup/bl_ui/properties_world.py
@@ -243,6 +243,30 @@ class WORLD_PT_mist(WorldButtonsPanel, Panel):
layout.prop(world.mist_settings, "falloff")
+class WORLD_PT_probe_settings(WorldButtonsPanel, Panel):
+ bl_label = "Viewport Probe"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'CYCLES'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ world = context.world
+ split = layout.split()
+
+ col = split.column()
+ col.prop(world, "probe_refresh_auto")
+ col = split.column()
+ col.prop(world, "probe_compute_sh")
+
+ layout.operator("world.probe_update", text="Update Probe", icon="FILE_REFRESH")
+
+ layout.label(text="Quality:")
+ row = layout.row(align=True)
+ row.prop(world, "probe_size", text="Reflection")
+ row.prop(world, "probe_sh_quality", text="Diffuse")
+
+
class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_context_path = "world"
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 1748d1d3738..a8ab0934abd 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -3213,6 +3213,11 @@ class VIEW3D_PT_view3d_display(Panel):
col.prop(view, "show_only_render")
col.prop(view, "show_world")
+ if scene.render.use_shading_nodes:
+ col = layout.column()
+ col.active = view.show_world
+ col.prop(view, "show_world_sh")
+
col = layout.column()
display_all = not view.show_only_render
col.active = display_all
@@ -3321,6 +3326,38 @@ class VIEW3D_PT_view3d_shading(Panel):
if scene.render.use_shading_nodes or gs.material_mode != 'GLSL':
col.prop(view, "show_textured_shadeless")
+ if scene.render.use_shading_nodes and view.viewport_shade == 'MATERIAL':
+ pbr_settings = view.pbr_settings
+
+ col.prop(pbr_settings, "use_realistic_mat", text="Material Preview")
+ if pbr_settings.use_realistic_mat:
+ brdf_settings = pbr_settings.brdf;
+ subcol = col.column(align=True)
+ subcol.prop(brdf_settings, "samples")
+ subcol.prop(brdf_settings, "lodbias")
+
+ col.prop(pbr_settings, "use_ssao", text="Material Ambient Occlusion")
+ if pbr_settings.use_ssao:
+ ssao_settings = pbr_settings.ssao;
+ subcol = col.column(align=True)
+ subcol.prop(ssao_settings, "factor")
+ subcol.prop(scene.world.light_settings, "distance")
+ subcol.prop(ssao_settings, "samples")
+ subcol.prop(ssao_settings, "steps")
+
+ col.prop(pbr_settings, "use_ssr", text="Material Reflections")
+ if pbr_settings.use_ssr:
+ ssr_settings = pbr_settings.ssr;
+ subcol = col.column(align=True)
+ subcol.prop(ssr_settings, "attenuation")
+ subcol.prop(ssr_settings, "steps")
+ subcol.prop(ssr_settings, "thickness")
+
+ if pbr_settings.use_ssao or pbr_settings.use_ssr:
+ col.prop(pbr_settings, "use_backface", text="Backface Buffer")
+
+ col.prop(pbr_settings, "use_layer_override")
+
col.prop(view, "show_backface_culling")
if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}:
@@ -3329,7 +3366,9 @@ class VIEW3D_PT_view3d_shading(Panel):
fx_settings = view.fx_settings
+
if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}:
+ col.prop(fx_settings, "use_colormanagement", text="Color Management")
sub = col.column()
sub.active = view.region_3d.view_perspective == 'CAMERA'
sub.prop(fx_settings, "use_dof")
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index cb864334208..5e4f5f160eb 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -492,6 +492,10 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
}
}
+ CALLBACK_INVOKE(object->probe, IDWALK_NOP);
+ CALLBACK_INVOKE(object->parallaxcorrect, IDWALK_NOP);
+ CALLBACK_INVOKE(object->reflectionplane, IDWALK_NOP);
+
modifiers_foreachIDLink(object, library_foreach_modifiersForeachIDLink, &data);
BKE_constraints_id_loop(&object->constraints, library_foreach_constraintObjectLooper, &data);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index cdd7560e3c4..b03eaa5bf85 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -129,6 +129,7 @@
#include "CCGSubSurf.h"
#include "GPU_material.h"
+#include "GPU_probe.h"
/* Vertex parent modifies original BMesh which is not safe for threading.
* Ideally such a modification should be handled as a separate DAG update
@@ -214,7 +215,6 @@ void BKE_object_free_modifiers(Object *ob)
/* same for softbody */
BKE_object_free_softbody(ob);
- /* modifiers may have stored data in the DM cache */
BKE_object_free_derived_caches(ob);
}
@@ -438,6 +438,8 @@ void BKE_object_free(Object *ob)
}
GPU_lamp_free(ob);
+ GPU_probe_free(&ob->gpuprobe);
+
BKE_sculptsession_free(ob);
BLI_freelistN(&ob->pc_ids);
@@ -643,6 +645,14 @@ void BKE_object_init(Object *ob)
ob->col_mask = 0xffff;
ob->preview = NULL;
+ /* Viewport Probe defaults */
+ ob->probesize = 256;
+ ob->probeshres = 32;
+ ob->probeflags = (OB_PROBE_AUTO_UPDATE | OB_PROBE_COMPUTE_SH);
+ ob->probeclipsta = 0.1f;
+ ob->probeclipend = 1000.0f;
+ ob->probeclipbias = 0.01f;
+
/* NT fluid sim defaults */
ob->fluidsimSettings = NULL;
@@ -1160,6 +1170,7 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches)
obn->derivedFinal = NULL;
BLI_listbase_clear(&obn->gpulamp);
+ BLI_listbase_clear(&obn->gpuprobe);
BLI_listbase_clear(&obn->pc_ids);
obn->mpath = NULL;
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index caa9a1e357f..0e2e9ac75c2 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -53,6 +53,7 @@
#include "BKE_world.h"
#include "GPU_material.h"
+#include "GPU_probe.h"
/** Free (or release) any data used by this world (does not free the world itself). */
void BKE_world_free(World *wrld)
@@ -73,6 +74,8 @@ void BKE_world_free(World *wrld)
}
GPU_material_free(&wrld->gpumaterial);
+
+ GPU_probe_free(&wrld->gpuprobe);
BKE_icon_id_delete((struct ID *)wrld);
BKE_previewimg_free(&wrld->preview);
@@ -106,6 +109,11 @@ void BKE_world_init(World *wrld)
wrld->preview = NULL;
wrld->miststa = 5.0f;
wrld->mistdist = 25.0f;
+
+ /* Viewport Probe defaults */
+ wrld->probesize = 512;
+ wrld->probeshres = 64;
+ wrld->probeflags = (WO_PROBE_AUTO_UPDATE | WO_PROBE_COMPUTE_SH);
}
World *add_world(Main *bmain, const char *name)
@@ -141,6 +149,7 @@ World *BKE_world_copy(Main *bmain, World *wrld)
BKE_previewimg_id_copy(&wrldn->id, &wrld->id);
BLI_listbase_clear(&wrldn->gpumaterial);
+ BLI_listbase_clear(&wrldn->gpuprobe);
BKE_id_copy_ensure_local(bmain, &wrld->id, &wrldn->id);
@@ -167,6 +176,7 @@ World *localize_world(World *wrld)
wrldn->preview = NULL;
BLI_listbase_clear(&wrldn->gpumaterial);
+ BLI_listbase_clear(&wrldn->gpuprobe);
return wrldn;
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 60f276b1744..12982241c19 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3593,6 +3593,7 @@ static void direct_link_world(FileData *fd, World *wrld)
wrld->preview = direct_link_preview_image(fd, wrld->preview);
BLI_listbase_clear(&wrld->gpumaterial);
+ BLI_listbase_clear(&wrld->gpuprobe);
}
@@ -4955,6 +4956,13 @@ static void lib_link_object(FileData *fd, Main *main)
level->source = ob;
}
}
+
+ {
+ ob->probe = newlibadr(fd, ob->id.lib, ob->probe);
+ ob->parallaxcorrect = newlibadr(fd, ob->id.lib, ob->parallaxcorrect);
+ ob->reflectionplane = newlibadr(fd, ob->id.lib, ob->reflectionplane);
+ BLI_listbase_clear(&ob->gpuprobe);
+ }
}
}
@@ -5537,6 +5545,8 @@ static void direct_link_object(FileData *fd, Object *ob)
link_list(fd, &ob->lodlevels);
ob->currentlod = ob->lodlevels.first;
+ BLI_listbase_clear(&ob->gpuprobe);
+
ob->preview = direct_link_preview_image(fd, ob->preview);
}
@@ -7045,6 +7055,7 @@ static bool direct_link_screen(FileData *fd, bScreen *sc)
BLI_listbase_clear(&v3d->afterdraw_xraytransp);
v3d->properties_storage = NULL;
v3d->defmaterial = NULL;
+ v3d->pbr = NULL;
/* render can be quite heavy, set to solid on load */
if (v3d->drawtype == OB_RENDER)
@@ -7055,7 +7066,14 @@ static bool direct_link_screen(FileData *fd, bScreen *sc)
v3d->fx_settings.dof = newdataadr(fd, v3d->fx_settings.dof);
if (v3d->fx_settings.ssao)
v3d->fx_settings.ssao = newdataadr(fd, v3d->fx_settings.ssao);
-
+
+ if (v3d->pbr_settings.ssr)
+ v3d->pbr_settings.ssr = newdataadr(fd, v3d->pbr_settings.ssr);
+ if (v3d->pbr_settings.ssao)
+ v3d->pbr_settings.ssao = newdataadr(fd, v3d->pbr_settings.ssao);
+ if (v3d->pbr_settings.brdf)
+ v3d->pbr_settings.brdf = newdataadr(fd, v3d->pbr_settings.brdf);
+
blo_do_versions_view3d_split_250(v3d, &sl->regionbase);
}
else if (sl->spacetype == SPACE_IPO) {
@@ -9426,6 +9444,10 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
expand_doit(fd, mainvar, level->source);
}
}
+
+ expand_doit(fd, mainvar, ob->probe);
+ expand_doit(fd, mainvar, ob->parallaxcorrect);
+ expand_doit(fd, mainvar, ob->reflectionplane);
}
static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index dfaa59c4e3f..eaa7d487862 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -1084,6 +1084,29 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
+ /* XXX I don't know against which version I should test */
+ if (!MAIN_VERSION_ATLEAST(main, 277, 0)) {
+ {
+ World *wo;
+ for (wo = main->world.first; wo; wo = wo->id.next) {
+ wo->probesize = 512;
+ wo->probeflags = (WO_PROBE_AUTO_UPDATE | WO_PROBE_COMPUTE_SH);
+ wo->probeshres = 64;
+ }
+ }
+
+ {
+ Object *ob;
+ for (ob = main->object.first; ob; ob = ob->id.next) {
+ ob->probesize = 256;
+ ob->probeflags = (OB_PROBE_AUTO_UPDATE | OB_PROBE_COMPUTE_SH);
+ ob->probeclipsta = 0.1f;
+ ob->probeclipend = 1000.0f;
+ ob->probeshres = 32;
+ }
+ }
+ }
+
if (!MAIN_VERSION_ATLEAST(main, 277, 1)) {
for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
ParticleEditSettings *pset = &scene->toolsettings->particle;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index dbc67d30b35..8e797e38de3 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -3065,6 +3065,17 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
if (v3d->fx_settings.dof) {
writestruct(wd, DATA, GPUDOFSettings, 1, v3d->fx_settings.dof);
}
+
+ if (v3d->pbr_settings.brdf) {
+ writestruct(wd, DATA, GPUBRDFSettings, 1, v3d->pbr_settings.brdf);
+ }
+ if (v3d->pbr_settings.ssr)
+ {
+ writestruct(wd, DATA, GPUSSRSettings, 1, v3d->pbr_settings.ssr);
+ }
+ if (v3d->pbr_settings.ssao) {
+ writestruct(wd, DATA, GPUSSAOSettings, 1, v3d->pbr_settings.ssao);
+ }
}
else if (sl->spacetype == SPACE_IPO) {
SpaceIpo *sipo = (SpaceIpo *)sl;
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 48c1e2d1996..422836b5be2 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -328,10 +328,10 @@ void *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d);
void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, void *rv3dmat_pt);
bool ED_view3d_context_activate(struct bContext *C);
-void ED_view3d_draw_offscreen_init(struct Scene *scene, struct View3D *v3d);
+void ED_view3d_draw_offscreen_init(struct Scene *scene, struct View3D *v3d, struct ARegion *ar);
void ED_view3d_draw_offscreen(
struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int winx, int winy, float viewmat[4][4],
- float winmat[4][4], bool do_bgpic, bool do_sky, bool is_persp, const char *viewname,
+ float winmat[4][4], bool do_bgpic, bool do_sky, bool is_persp, bool do_meshes, const char *viewname,
struct GPUFX *fx, struct GPUFXSettings *fx_settings,
struct GPUOffScreen *ofs);
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt
index b3d02d45e13..98b9b1a11f2 100644
--- a/source/blender/editors/object/CMakeLists.txt
+++ b/source/blender/editors/object/CMakeLists.txt
@@ -50,6 +50,7 @@ set(SRC
object_hook.c
object_lattice.c
object_lod.c
+ object_probe.c
object_modifier.c
object_ops.c
object_random.c
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 9f91feee4c6..0cb91fd0269 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -112,6 +112,7 @@
#include "UI_resources.h"
#include "GPU_material.h"
+#include "GPU_probe.h"
#include "object_intern.h"
@@ -1104,6 +1105,9 @@ static void object_delete_check_glsl_update(Object *ob)
if (ob->gpulamp.first)
GPU_lamp_free(ob);
}
+
+ if (ob->gpuprobe.first)
+ GPU_probe_free(&ob->gpuprobe);
}
/* remove base from a specific scene */
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 9710e4f843d..a599835917c 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -272,6 +272,10 @@ void OBJECT_OT_bake(wmOperatorType *ot);
void OBJECT_OT_lod_add(struct wmOperatorType *ot);
void OBJECT_OT_lod_remove(struct wmOperatorType *ot);
+/* object_probe.c */
+void OBJECT_OT_probe_update(struct wmOperatorType *ot);
+void OBJECT_OT_probe_set_active_as_probe(struct wmOperatorType *ot);
+
/* object_random.c */
void TRANSFORM_OT_vertex_random(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 7e7e1ef182c..7c7e80edbf7 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -251,6 +251,9 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_lod_add);
WM_operatortype_append(OBJECT_OT_lod_remove);
+ WM_operatortype_append(OBJECT_OT_probe_update);
+ WM_operatortype_append(OBJECT_OT_probe_set_active_as_probe);
+
WM_operatortype_append(TRANSFORM_OT_vertex_random);
WM_operatortype_append(OBJECT_OT_data_transfer);
diff --git a/source/blender/editors/object/object_probe.c b/source/blender/editors/object/object_probe.c
new file mode 100644
index 00000000000..17c0296ac90
--- /dev/null
+++ b/source/blender/editors/object/object_probe.c
@@ -0,0 +1,162 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/object/object_probe.c
+ * \ingroup edobj
+ */
+
+#include "DNA_object_types.h"
+
+#include "BKE_context.h"
+
+#include "BLI_listbase.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "GPU_probe.h"
+
+#include "ED_screen.h"
+#include "ED_object.h"
+
+#include "object_intern.h"
+
+enum {
+ UPDATE_PROBE_ACTIVE = 1,
+ UPDATE_PROBE_SELECTED = 2,
+ UPDATE_PROBE_ALL = 3,
+};
+
+static int object_probe_update_exec(bContext *C, wmOperator *op)
+{
+ const int mode = RNA_enum_get(op->ptr, "type");
+
+ if (mode == UPDATE_PROBE_ACTIVE) {
+ Object *ob = ED_object_context(C);
+ if (ob->gpuprobe.first) {
+ LinkData *link;
+ for (link = ob->gpuprobe.first; link; link = link->next) {
+ GPUProbe *ref = (GPUProbe *)link->data;
+ GPU_probe_set_update(ref, true);
+ }
+ }
+ }
+ else if (mode == UPDATE_PROBE_SELECTED) {
+ CTX_DATA_BEGIN(C, Object *, ob, selected_objects) {
+ if (ob->gpuprobe.first) {
+ LinkData *link;
+ for (link = ob->gpuprobe.first; link; link = link->next) {
+ GPUProbe *ref = (GPUProbe *)link->data;
+ GPU_probe_set_update(ref, true);
+ }
+ }
+ }
+ CTX_DATA_END;
+ }
+ else if (mode == UPDATE_PROBE_ALL) {
+ CTX_DATA_BEGIN(C, Object *, ob, editable_objects) {
+ if (ob->gpuprobe.first) {
+ LinkData *link;
+ for (link = ob->gpuprobe.first; link; link = link->next) {
+ GPUProbe *ref = (GPUProbe *)link->data;
+ GPU_probe_set_update(ref, true);
+ }
+ }
+ }
+ CTX_DATA_END;
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_probe_update(wmOperatorType *ot)
+{
+ static EnumPropertyItem type_items[] = {
+ {UPDATE_PROBE_ACTIVE, "ACTIVE_PROBE", 0, "Active Probes", ""},
+ {UPDATE_PROBE_SELECTED, "SELECT_PROBE", 0, "Selected Probes", ""},
+ {UPDATE_PROBE_ALL, "ALL_PROBE", 0, "All Probes", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* identifiers */
+ ot->name = "Update Probe";
+ ot->description = "Update the environment captured by Probe objects";
+ ot->idname = "OBJECT_OT_probe_update";
+
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = object_probe_update_exec;
+ ot->poll = ED_operator_object_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER;
+
+ /* properties */
+ ot->prop = RNA_def_enum(ot->srna, "type", type_items, 1, "Type", "");
+}
+
+/* ************ Active as Probe ************** */
+
+static int object_active_as_probe_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *obt = ED_object_context(C);
+
+ CTX_DATA_BEGIN(C, Object *, ob, selected_objects) {
+ if (ob != obt) {
+ if (obt->probetype == OB_PROBE_CUBEMAP || obt->probetype == OB_PROBE_PLANAR) {
+ if (!ob->probetype)
+ ob->probetype = OB_PROBE_OBJECT;
+ ob->probe = obt;
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_probe_set_active_as_probe(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Set Active as Probe";
+ ot->description = "Make selected objects use the active Probe";
+ ot->idname = "OBJECT_OT_probe_set_active_as_probe";
+
+ /* api callbacks */
+ ot->exec = object_active_as_probe_exec;
+ ot->poll = ED_operator_object_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+} \ No newline at end of file
diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h
index fb07b03c286..2be5930d9e4 100644
--- a/source/blender/editors/render/render_intern.h
+++ b/source/blender/editors/render/render_intern.h
@@ -50,6 +50,8 @@ void MATERIAL_OT_new(struct wmOperatorType *ot);
void TEXTURE_OT_new(struct wmOperatorType *ot);
void WORLD_OT_new(struct wmOperatorType *ot);
+void WORLD_OT_probe_update(struct wmOperatorType *ot);
+
void MATERIAL_OT_copy(struct wmOperatorType *ot);
void MATERIAL_OT_paste(struct wmOperatorType *ot);
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index ee2772ce31a..423763fa46b 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -660,7 +660,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
* running notifiers again will overwrite */
oglrender->scene->customdata_mask |= oglrender->scene->customdata_mask_modal;
- if (oglrender->v3d->fx_settings.fx_flag & (GPU_FX_FLAG_DOF | GPU_FX_FLAG_SSAO)) {
+ if (oglrender->v3d->fx_settings.fx_flag) {
oglrender->fx = GPU_fx_compositor_create();
}
}
diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c
index c09e8576dc2..6799220c3cd 100644
--- a/source/blender/editors/render/render_ops.c
+++ b/source/blender/editors/render/render_ops.c
@@ -56,6 +56,8 @@ void ED_operatortypes_render(void)
WM_operatortype_append(MATERIAL_OT_copy);
WM_operatortype_append(MATERIAL_OT_paste);
+ WM_operatortype_append(WORLD_OT_probe_update);
+
WM_operatortype_append(SCENE_OT_render_layer_add);
WM_operatortype_append(SCENE_OT_render_layer_remove);
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 5a0c250c777..49cb8a8730a 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -85,6 +85,9 @@
#include "ED_render.h"
#include "ED_screen.h"
+#include "GPU_material.h"
+#include "GPU_probe.h"
+
#include "RNA_define.h"
#include "UI_interface.h"
@@ -600,7 +603,7 @@ static int new_world_exec(bContext *C, wmOperator *UNUSED(op))
RNA_property_update(C, &ptr, prop);
}
- WM_event_add_notifier(C, NC_WORLD | NA_ADDED, wo);
+ WM_event_add_notifier(C, NC_WORLD | NA_ADDED | ND_WORLD_DRAW, wo);
return OPERATOR_FINISHED;
}
@@ -619,6 +622,48 @@ void WORLD_OT_new(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
+/********************** world probe operator *********************/
+
+static int world_probe_update_poll(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ World *wo = scene->world;
+ return (wo != NULL);
+}
+
+static int world_probe_update_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+ World *wo = scene->world;
+
+ if (wo && wo->gpuprobe.first) {
+ LinkData *link;
+ for (link = wo->gpuprobe.first; link; link = link->next) {
+ GPUProbe *ref = (GPUProbe *)link->data;
+ GPU_probe_set_update(ref, true);
+ }
+ }
+
+ WM_event_add_notifier(C, NC_WORLD | ND_WORLD_DRAW, wo);
+
+ return OPERATOR_FINISHED;
+}
+
+void WORLD_OT_probe_update(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Update World Probe";
+ ot->description = "Update the environment probe";
+ ot->idname = "WORLD_OT_probe_update";
+
+ /* api callbacks */
+ ot->exec = world_probe_update_exec;
+ ot->poll = world_probe_update_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER;
+}
+
/********************** render layer operators *********************/
static int render_layer_add_exec(bContext *C, wmOperator *UNUSED(op))
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index f11a8177bf8..326b3b6d770 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -56,6 +56,7 @@
#include "GPU_material.h"
#include "GPU_buffers.h"
+#include "GPU_probe.h"
#include "RE_engine.h"
#include "RE_pipeline.h"
@@ -307,6 +308,16 @@ static void material_changed(Main *bmain, Material *ma)
if (parent->gpumaterial.first)
GPU_material_free(&parent->gpumaterial);
+
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (ob->gpuprobe.first) {
+ LinkData *link;
+ for (link = ob->gpuprobe.first; link; link = link->next) {
+ GPUProbe *probe = (GPUProbe *)link->data;
+ GPU_probe_auto_update(probe);
+ }
+ }
+ }
}
/* find if we have a scene with textured display */
@@ -356,6 +367,16 @@ static void lamp_changed(Main *bmain, Lamp *la)
if (defmaterial.gpumaterial.first)
GPU_material_free(&defmaterial.gpumaterial);
+
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (ob->gpuprobe.first) {
+ LinkData *link;
+ for (link = ob->gpuprobe.first; link; link = link->next) {
+ GPUProbe *probe = (GPUProbe *)link->data;
+ GPU_probe_auto_update(probe);
+ }
+ }
+ }
}
static int material_uses_texture(Material *ma, Tex *tex)
@@ -394,6 +415,16 @@ static void texture_changed(Main *bmain, Tex *tex)
if (ma->gpumaterial.first)
GPU_material_free(&ma->gpumaterial);
+
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (ob->gpuprobe.first) {
+ LinkData *link;
+ for (link = ob->gpuprobe.first; link; link = link->next) {
+ GPUProbe *probe = (GPUProbe *)link->data;
+ GPU_probe_auto_update(probe);
+ }
+ }
+ }
}
/* find lamps */
@@ -424,7 +455,25 @@ static void texture_changed(Main *bmain, Tex *tex)
BKE_icon_changed(BKE_icon_id_ensure(&wo->id));
if (wo->gpumaterial.first)
- GPU_material_free(&wo->gpumaterial);
+ GPU_material_free(&wo->gpumaterial);
+
+ if (wo->gpuprobe.first) {
+ LinkData *link;
+ for (link = wo->gpuprobe.first; link; link = link->next) {
+ GPUProbe *probe = (GPUProbe *)link->data;
+ GPU_probe_auto_update(probe);
+ }
+ }
+
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (ob->gpuprobe.first) {
+ LinkData *link;
+ for (link = ob->gpuprobe.first; link; link = link->next) {
+ GPUProbe *probe = (GPUProbe *)link->data;
+ GPU_probe_auto_update(probe);
+ }
+ }
+ }
}
/* find compositing nodes */
@@ -481,6 +530,25 @@ static void world_changed(Main *bmain, World *wo)
if (wo->gpumaterial.first)
GPU_material_free(&wo->gpumaterial);
+
+ if (wo->gpuprobe.first){
+ LinkData *link;
+ for (link = wo->gpuprobe.first; link; link = link->next) {
+ GPUProbe *probe = (GPUProbe *)link->data;
+ GPU_probe_auto_update(probe);
+ }
+ }
+
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (ob->gpuprobe.first) {
+ LinkData *link;
+ for (link = ob->gpuprobe.first; link; link = link->next) {
+ GPUProbe *probe = (GPUProbe *)link->data;
+ GPU_probe_auto_update(probe);
+ }
+ }
+ }
+
}
static void image_changed(Main *bmain, Image *ima)
@@ -521,7 +589,7 @@ static void scene_changed(Main *bmain, Scene *scene)
for (wo = bmain->world.first; wo; wo = wo->id.next)
if (wo->gpumaterial.first)
GPU_material_free(&wo->gpumaterial);
-
+
if (defmaterial.gpumaterial.first)
GPU_material_free(&defmaterial.gpumaterial);
}
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index bf344e1f721..0924c9a9288 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -1416,9 +1416,9 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
BKE_paint_init(scene, ePaintTextureProjective, PAINT_CURSOR_TEXTURE_PAINT);
- if (U.glreslimit != 0)
- GPU_free_images();
- GPU_paint_set_mipmap(0);
+ //if (U.glreslimit != 0)
+ // GPU_free_images();
+ //GPU_paint_set_mipmap(0);
toggle_paint_cursor(C, 1);
}
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index ecbfd5c7c85..d273f898f63 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -322,7 +322,7 @@ static bool set_draw_settings_cached(
if (textured) {
if (texpaint) {
c_badtex = false;
- if (GPU_verify_image(ima, NULL, GL_TEXTURE_2D, 0, 1, 0, false)) {
+ if (GPU_verify_image(ima, NULL, GL_TEXTURE_2D, 0, 1, 0, false, false)) {
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
@@ -474,7 +474,7 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
/* load the stencil texture here */
if (Gtexdraw.stencil != NULL) {
glActiveTexture(GL_TEXTURE2);
- if (GPU_verify_image(Gtexdraw.stencil, NULL, GL_TEXTURE_2D, false, false, false, false)) {
+ if (GPU_verify_image(Gtexdraw.stencil, NULL, GL_TEXTURE_2D, false, false, false, false, false)) {
float col[4] = {imapaint->stencil_col[0], imapaint->stencil_col[1], imapaint->stencil_col[2], 1.0f};
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
@@ -1092,7 +1092,7 @@ static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
if (ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node, NULL)) {
/* get openl texture */
int mipmap = 1;
- int bindcode = (ima) ? GPU_verify_image(ima, iuser, GL_TEXTURE_2D, 0, 0, mipmap, false) : 0;
+ int bindcode = (ima) ? GPU_verify_image(ima, iuser, GL_TEXTURE_2D, 0, 0, mipmap, false, false) : 0;
if (bindcode) {
NodeTexBase *texbase = node->storage;
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 4af84589eb8..ac898fe7438 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -1170,7 +1170,7 @@ static void draw_transp_sun_volume(Lamp *la)
}
#endif
-static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
+static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
const char dt, const short dflag, const unsigned char ob_wire_col[4], const bool is_obact)
{
Object *ob = base->object;
@@ -1312,9 +1312,17 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
}
- if (la->type == LA_LOCAL) {
- if (la->mode & LA_SPHERE) {
- drawcircball(GL_LINE_LOOP, vec, la->dist, imat);
+
+ if (BKE_scene_use_new_shading_nodes(scene)) {
+ if (la->type == LA_LOCAL || la->type == LA_SPOT) {
+ drawcircball(GL_LINE_LOOP, vec, la->area_size, imat);
+ }
+ }
+ else {
+ if (la->type == LA_LOCAL) {
+ if (la->mode & LA_SPHERE) {
+ drawcircball(GL_LINE_LOOP, vec, la->dist, imat);
+ }
}
}
@@ -3707,7 +3715,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
}
else if (check_object_draw_texture(scene, v3d, dt)) {
if (draw_glsl_material(scene, ob, v3d, dt)) {
- glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+ glFrontFace(((ob->transflag & OB_NEG_SCALE) != (v3d->flag3 & V3D_FLIP_NORMALS)) ? GL_CW : GL_CCW);
finalDM->drawMappedFacesGLSL(finalDM, GPU_object_material_bind,
draw_em_fancy__setGLSLFaceOpts, em);
@@ -3720,7 +3728,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
}
}
else {
- glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+ glFrontFace(((ob->transflag & OB_NEG_SCALE) != (v3d->flag3 & V3D_FLIP_NORMALS)) ? GL_CW : GL_CCW);
finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, GPU_object_material_bind, NULL, me->edit_btmesh, DM_DRAW_SKIP_HIDDEN | DM_DRAW_NEED_NORMALS);
glFrontFace(GL_CCW);
@@ -3996,7 +4004,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
}
/* vertexpaint, faceselect wants this, but it doesnt work for shaded? */
- glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+ glFrontFace(((ob->transflag & OB_NEG_SCALE) != (v3d->flag3 & V3D_FLIP_NORMALS)) ? GL_CW : GL_CCW);
if (dt == OB_BOUNDBOX) {
if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_WIRE) == 0)
@@ -4028,7 +4036,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
if (draw_glsl_material(scene, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) {
Paint *p;
- glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+ glFrontFace(((ob->transflag & OB_NEG_SCALE) != (v3d->flag3 & V3D_FLIP_NORMALS)) ? GL_CW : GL_CCW);
if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene))) {
GPUVertexAttribs gattribs;
@@ -4120,7 +4128,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
draw_mesh_object_outline(v3d, ob, dm);
}
- glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+ glFrontFace(((ob->transflag & OB_NEG_SCALE) != (v3d->flag3 & V3D_FLIP_NORMALS)) ? GL_CW : GL_CCW);
if (ob->sculpt && (p = BKE_paint_get_active(scene))) {
float planes[4][4];
@@ -4579,7 +4587,7 @@ static bool drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d,
DM_update_materials(dm, ob);
- glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+ glFrontFace(((ob->transflag & OB_NEG_SCALE) != (v3d->flag3 & V3D_FLIP_NORMALS)) ? GL_CW : GL_CCW);
if (dt > OB_WIRE && dm->getNumPolys(dm)) {
bool glsl = draw_glsl_material(scene, ob, v3d, dt);
@@ -4749,10 +4757,10 @@ static bool drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *ba
GLenum mode;
if (ob->type == OB_MBALL) {
- mode = (ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW;
+ mode = ((ob->transflag & OB_NEG_SCALE) != (v3d->flag3 & V3D_FLIP_NORMALS)) ? GL_CW : GL_CCW;
}
else {
- mode = (ob->transflag & OB_NEG_SCALE) ? GL_CCW : GL_CW;
+ mode = ((ob->transflag & OB_NEG_SCALE) != (v3d->flag3 & V3D_FLIP_NORMALS)) ? GL_CCW : GL_CW;
}
glFrontFace(mode);
@@ -7717,7 +7725,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
break;
case OB_LAMP:
if (!render_override) {
- drawlamp(v3d, rv3d, base, dt, dflag, ob_wire_col, is_obact);
+ drawlamp(scene, v3d, rv3d, base, dt, dflag, ob_wire_col, is_obact);
}
break;
case OB_CAMERA:
@@ -8463,7 +8471,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
}
- glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+ glFrontFace(((ob->transflag & OB_NEG_SCALE) != (v3d->flag3 & V3D_FLIP_NORMALS)) ? GL_CW : GL_CCW);
if (dm) {
dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind);
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 075b1faf502..8139a407a43 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -35,6 +35,7 @@
#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_world_types.h"
#include "MEM_guardedalloc.h"
@@ -57,6 +58,8 @@
#include "GPU_compositing.h"
#include "GPU_framebuffer.h"
#include "GPU_material.h"
+#include "GPU_probe.h"
+#include "GPU_pbr.h"
#include "BIF_gl.h"
@@ -428,10 +431,20 @@ static void view3d_free(SpaceLink *sl)
MEM_freeN(vd->defmaterial);
}
+ if (vd->pbr)
+ GPU_pbr_free(vd->pbr);
+
if (vd->fx_settings.ssao)
MEM_freeN(vd->fx_settings.ssao);
if (vd->fx_settings.dof)
MEM_freeN(vd->fx_settings.dof);
+
+ if (vd->pbr_settings.brdf)
+ MEM_freeN(vd->pbr_settings.brdf);
+ if (vd->pbr_settings.ssr)
+ MEM_freeN(vd->pbr_settings.ssr);
+ if (vd->pbr_settings.ssao)
+ MEM_freeN(vd->pbr_settings.ssao);
}
@@ -461,6 +474,7 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
/* copy or clear inside new stuff */
v3dn->defmaterial = NULL;
+ v3dn->pbr = NULL;
BLI_duplicatelist(&v3dn->bgpicbase, &v3do->bgpicbase);
for (bgpic = v3dn->bgpicbase.first; bgpic; bgpic = bgpic->next) {
@@ -478,6 +492,13 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
if (v3dn->fx_settings.ssao)
v3dn->fx_settings.ssao = MEM_dupallocN(v3do->fx_settings.ssao);
+ if (v3dn->pbr_settings.brdf)
+ v3dn->pbr_settings.brdf = MEM_dupallocN(v3do->pbr_settings.brdf);
+ if (v3dn->pbr_settings.ssr)
+ v3dn->pbr_settings.ssr = MEM_dupallocN(v3do->pbr_settings.ssr);
+ if (v3dn->pbr_settings.ssao)
+ v3dn->pbr_settings.ssao = MEM_dupallocN(v3do->pbr_settings.ssao);
+
return (SpaceLink *)v3dn;
}
@@ -799,6 +820,52 @@ static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene
}
}
+static void view3d_tag_probes_update(ARegion *ar, wmNotifier *wmn, Scene *scene)
+{
+ wmWindow *win = wmn->wm->winactive;
+
+ Base *base;
+
+ if (!win) return;
+
+ base = scene->base.first;
+ while (base) {
+ Object *ob = base->object;
+
+ if (ob->gpuprobe.first) {
+ LinkData *link;
+ for (link = ob->gpuprobe.first; link; link = link->next) {
+ GPUProbe *probe = (GPUProbe *)link->data;
+ GPU_probe_auto_update(probe);
+ }
+ }
+
+ base = base->next;
+ }
+}
+
+static void view3d_tag_world_probe_update(ARegion *ar, wmNotifier *wmn, Scene *scene)
+{
+ wmWindow *win = wmn->wm->winactive;
+
+ if (!win) return;
+
+ if (scene->world) {
+ World *wo = scene->world;
+
+ if (wo->gpuprobe.first) {
+ LinkData *link;
+ for (link = wo->gpuprobe.first; link; link = link->next) {
+ GPUProbe *probe = (GPUProbe *)link->data;
+ GPU_probe_auto_update(probe);
+ }
+ }
+ }
+
+ /* usualy other probes depends on the world lighting so update them */
+ view3d_tag_probes_update(ar, wmn, scene);
+}
+
static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmNotifier *wmn)
{
Scene *scene = sc->scene;
@@ -842,6 +909,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
ED_region_tag_redraw(ar);
break;
case ND_WORLD:
+ view3d_tag_world_probe_update(ar, wmn, scene);
/* handled by space_view3d_listener() for v3d access */
break;
case ND_DRAW_RENDER_VIEWPORT:
@@ -870,6 +938,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case ND_KEYS:
case ND_PARTICLE:
case ND_LOD:
+ view3d_tag_probes_update(ar, wmn, scene);
ED_region_tag_redraw(ar);
break;
}
@@ -938,12 +1007,14 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
!DEG_depsgraph_use_legacy())
#endif
{
+ view3d_tag_probes_update(ar, wmn, scene);
ED_region_tag_redraw(ar);
}
break;
}
case ND_SHADING_DRAW:
case ND_SHADING_LINKS:
+ view3d_tag_probes_update(ar, wmn, scene);
ED_region_tag_redraw(ar);
break;
}
@@ -951,6 +1022,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case NC_WORLD:
switch (wmn->data) {
case ND_WORLD_DRAW:
+ view3d_tag_world_probe_update(ar, wmn, scene);
/* handled by space_view3d_listener() for v3d access */
break;
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index a01f5dbc640..6a58b41a34f 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -100,6 +100,8 @@
#include "GPU_material.h"
#include "GPU_compositing.h"
#include "GPU_extensions.h"
+#include "GPU_probe.h"
+#include "GPU_pbr.h"
#include "view3d_intern.h" /* own include */
@@ -2502,11 +2504,17 @@ static void gpu_render_lamp_update(Scene *scene, View3D *v3d,
View3DShadow *shadow;
unsigned int layers;
- lamp = GPU_lamp_from_blender(scene, ob, par);
+ lamp = GPU_lamp_from_blender(scene, ob, par, BKE_scene_use_new_shading_nodes(scene));
if (lamp) {
- GPU_lamp_update(lamp, lay, (ob->restrictflag & OB_RESTRICT_RENDER), obmat);
+ bool hide = (ob->restrictflag & OB_RESTRICT_VIEW);
+ GPU_lamp_update(lamp, lay, hide, obmat);
GPU_lamp_update_colors(lamp, la->r, la->g, la->b, la->energy);
+
+ if (la->area_shape == LA_AREA_SQUARE)
+ GPU_lamp_update_size(lamp, la->area_size, la->area_size);
+ else
+ GPU_lamp_update_size(lamp, la->area_size, la->area_sizey);
layers = lay & v3d->lay;
if (srl)
@@ -2586,7 +2594,7 @@ static void gpu_update_lamps_shadows_world(Scene *scene, View3D *v3d)
/* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */
ED_view3d_draw_offscreen(
scene, v3d, &ar, winsize, winsize, viewmat, winmat,
- false, false, true,
+ false, false, true, true,
NULL, NULL, NULL, NULL);
GPU_lamp_shadow_buffer_unbind(shadow->lamp);
@@ -2607,6 +2615,373 @@ static void gpu_update_lamps_shadows_world(Scene *scene, View3D *v3d)
}
}
+/* ***************** Probes rendering *************** */
+
+typedef struct View3DProbe {
+ struct View3DProbe *next, *prev;
+ GPUProbe *probe;
+} View3DProbe;
+
+static void gpu_update_probes(Scene *scene, View3D *v3d, ARegion *basear)
+{
+ ListBase probelist;
+ ListBase afterlist;
+ int i = 0;
+ bool do_sky = false;
+ View3DProbe *vprobe;
+ GPUProbe *probe;
+ Scene *sce_iter;
+ Object *ob;
+ Base *base;
+ RegionView3D *baserv3d = basear->regiondata;
+
+ /* gathering probes */
+ BLI_listbase_clear(&probelist);
+ BLI_listbase_clear(&afterlist);
+
+ /* Order matters : watch BLI_addhead and BLI_addtail
+ * rendering the world first
+ * then the cubemaps
+ * finally the planar reflections. */
+
+ /* Objects Probe (don't do dupliobjects) */
+ for (SETLOOPER(scene, sce_iter, base)) {
+ ob = base->object;
+
+ if (ob->probetype == OB_PROBE_CUBEMAP || ob->probetype == OB_PROBE_PLANAR) {
+ probe = GPU_probe_object(scene, ob);
+
+ /* XXX free probes if size or type changes */
+ if (probe && ((GPU_probe_get_size(probe) != ob->probesize) ||
+ (GPU_probe_get_type(probe) != ob->probetype))) {
+ if (ob->gpuprobe.first)
+ GPU_probe_free(&ob->gpuprobe);
+ probe = GPU_probe_object(scene, ob);
+ }
+
+ if (probe) {
+ if (ob->probetype == OB_PROBE_CUBEMAP) {
+ GPU_probe_update_layers(probe, ob->lay);
+
+ if (ob->parallaxcorrect)
+ GPU_probe_update_parallax(probe, ob->parallaxcorrect->obmat, ob->obmat);
+ else
+ GPU_probe_update_parallax(probe, ob->obmat, ob->obmat);
+
+ if (GPU_probe_get_update(probe)) {
+ GPU_probe_update_clip(probe, ob->probeclipsta, ob->probeclipend);
+ GPU_probe_update_sh_res(probe, ob->probeshres);
+
+ vprobe = MEM_callocN(sizeof(View3DProbe), "View3DProbe");
+ vprobe->probe = probe;
+ BLI_addhead(&probelist, vprobe);
+
+ if (ob->probeflags & OB_PROBE_DOUBLE_UPDATE) {
+ vprobe = MEM_callocN(sizeof(View3DProbe), "View3DProbe");
+ vprobe->probe = probe;
+ BLI_addhead(&afterlist, vprobe);
+ }
+ }
+ }
+ else if (ob->probetype == OB_PROBE_PLANAR) {
+
+ GPU_probe_update_layers(probe, ob->lay);
+ GPU_probe_update_clip(probe, ob->probeclipbias, ob->probeclipend);
+
+ if (ob->probe) {
+ if (ob->probe->parallaxcorrect)
+ GPU_probe_update_parallax(probe, ob->probe->parallaxcorrect->obmat, ob->probe->obmat);
+ else
+ GPU_probe_update_parallax(probe, ob->probe->obmat, ob->probe->obmat);
+ }
+
+ if (ob->reflectionplane)
+ GPU_probe_update_ref_plane(probe, ob->reflectionplane->obmat);
+ else
+ GPU_probe_update_ref_plane(probe, ob->obmat);
+
+ vprobe = MEM_callocN(sizeof(View3DProbe), "View3DProbe");
+ vprobe->probe = probe;
+ BLI_addtail(&probelist, vprobe);
+
+ if (ob->probeflags & OB_PROBE_DOUBLE_UPDATE) {
+ vprobe = MEM_callocN(sizeof(View3DProbe), "View3DProbe");
+ vprobe->probe = probe;
+ BLI_addtail(&afterlist, vprobe);
+ }
+ }
+ }
+ }
+ else {
+ if (ob->gpuprobe.first)
+ GPU_probe_free(&ob->gpuprobe);
+ }
+ }
+
+ /* World Probe */
+ if (scene->world) {
+ do_sky = true;
+ probe = GPU_probe_world(scene, scene->world);
+
+ /* XXX free probes if size change */
+ if (probe && (GPU_probe_get_size(probe) != scene->world->probesize)) {
+ if (scene->world->gpuprobe.first)
+ GPU_probe_free(&scene->world->gpuprobe);
+ probe = GPU_probe_world(scene, scene->world);
+ }
+
+ if (probe && GPU_probe_get_update(probe)) {
+ GPU_probe_update_sh_res(probe, scene->world->probeshres);
+
+ vprobe = MEM_callocN(sizeof(View3DProbe), "View3DProbe");
+ vprobe->probe = probe;
+ BLI_addhead(&probelist, vprobe);
+ }
+ }
+
+ BLI_movelisttolist(&probelist, &afterlist);
+
+ /* Updating probes */
+ for (vprobe = probelist.first, i = 0; vprobe; vprobe = vprobe->next, i++) {
+
+ float viewmat[4][4], winmat[4][4];
+ int drawtype, lay, winsize, flag2 = v3d->flag2, flag3 = v3d->flag3, restrictflag;
+ int pbr_flag = v3d->pbr_settings.pbr_flag;
+ ARegion ar = {NULL};
+ RegionView3D rv3d = {{{0}}};
+ Object *ob = GPU_probe_get_object(vprobe->probe);
+ bool is_cubemap = (GPU_probe_get_type(vprobe->probe) == OB_PROBE_CUBEMAP);
+
+ drawtype = v3d->drawtype;
+ lay = v3d->lay;
+
+ v3d->drawtype = OB_MATERIAL;
+ v3d->lay = GPU_probe_get_layers(vprobe->probe);
+ v3d->flag2 &= ~(V3D_SOLID_TEX | V3D_SHOW_SOLID_MATCAP);
+ v3d->flag2 |= V3D_RENDER_OVERRIDE;
+ v3d->flag3 |= V3D_SHOW_WORLD;
+ v3d->flag3 &= ~V3D_SHOW_WORLD_DIFFUSE;
+ v3d->flag3 |= V3D_PROBE_CAPTURE;
+ v3d->pbr_settings.pbr_flag &= ~GPU_PBR_FLAG_SSR;
+ v3d->pbr_settings.pbr_flag &= ~GPU_PBR_FLAG_SSAO;
+
+ if (ob) {
+ restrictflag = ob->restrictflag;
+ ob->restrictflag |= OB_RESTRICT_VIEW;
+ v3d->probe_source = ob;
+ }
+ else {
+ v3d->probe_source = NULL;
+ }
+
+ GPU_probe_buffer_bind(vprobe->probe);
+
+ /* cubemap */
+ if (is_cubemap) {
+ for (int face = 0; face < 6; face++) {
+ GPU_probe_switch_fb_cubeface(vprobe->probe, face, viewmat, &winsize, winmat);
+
+ ar.regiondata = &rv3d;
+ ar.regiontype = RGN_TYPE_WINDOW;
+ rv3d.persp = RV3D_CAMOB;
+ copy_m4_m4(rv3d.winmat, winmat);
+ copy_m4_m4(rv3d.viewmat, viewmat);
+ invert_m4_m4(rv3d.viewinv, rv3d.viewmat);
+ mul_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat);
+ invert_m4_m4(rv3d.persinv, rv3d.viewinv);
+
+ ED_view3d_draw_offscreen(
+ scene, v3d, &ar, winsize, winsize, viewmat, winmat,
+ false, do_sky, true, (bool)ob,
+ NULL, NULL, NULL, NULL);
+ }
+ }
+ /* planar */
+ else {
+ ar.regiondata = &rv3d;
+ ar.regiontype = RGN_TYPE_WINDOW;
+ rv3d.persp = RV3D_CAMOB;
+
+ /* Getting normal camera */
+ view3d_winmatrix_set(basear, v3d, NULL);
+ view3d_viewmatrix_set(scene, v3d, baserv3d); /* note: calls BKE_object_where_is_calc for camera... */
+
+ /* Flip it along the plane */
+ GPU_probe_attach_planar_fb(vprobe->probe, baserv3d->viewmat, baserv3d->winmat, viewmat, &winsize, false);
+
+ copy_m4_m4(rv3d.viewmat, viewmat);
+ invert_m4_m4(rv3d.viewinv, rv3d.viewmat);
+ mul_m4_m4m4(rv3d.persmat, baserv3d->winmat, rv3d.viewmat);
+ invert_m4_m4(rv3d.persinv, rv3d.viewinv);
+
+ v3d->flag3 |= V3D_FLIP_NORMALS;
+
+ ED_view3d_draw_offscreen(
+ scene, v3d, &ar, winsize, winsize, viewmat, baserv3d->winmat,
+ false, do_sky, true, true,
+ NULL, NULL, NULL, NULL);
+
+ /* Non-fliped Camera for refraction */
+ GPU_probe_attach_planar_fb(vprobe->probe, baserv3d->viewmat, baserv3d->winmat, viewmat, &winsize, true);
+
+ copy_m4_m4(rv3d.viewmat, viewmat);
+ invert_m4_m4(rv3d.viewinv, rv3d.viewmat);
+ mul_m4_m4m4(rv3d.persmat, baserv3d->winmat, rv3d.viewmat);
+ invert_m4_m4(rv3d.persinv, rv3d.viewinv);
+
+ v3d->flag3 &= ~V3D_FLIP_NORMALS;
+
+ ED_view3d_draw_offscreen(
+ scene, v3d, &ar, winsize, winsize, viewmat, baserv3d->winmat,
+ false, do_sky, true, true,
+ NULL, NULL, NULL, NULL);
+
+ }
+
+ GPU_probe_buffer_unbind(vprobe->probe);
+
+ v3d->drawtype = drawtype;
+ v3d->lay = lay;
+ v3d->flag2 = flag2;
+ v3d->flag3 = flag3;
+ v3d->probe_source = NULL;
+ v3d->pbr_settings.pbr_flag = pbr_flag;
+
+ if (ob)
+ ob->restrictflag = restrictflag;
+
+ GPU_probe_rebuild_mipmaps(vprobe->probe);
+
+ GPU_probe_sh_compute(vprobe->probe);
+
+ GPU_probe_set_update(vprobe->probe, false);
+ }
+
+ BLI_freelistN(&probelist);
+}
+
+/* ***************** Scene buffer update *************** */
+
+static void gpu_update_scene_buffer(Scene *scene, View3D *v3d, ARegion *basear)
+{
+ int drawtype = v3d->drawtype, winsize[2], flag2 = v3d->flag2, flag3 = v3d->flag3;
+ float clipsta, clipend;
+ ARegion ar = {NULL};
+ RegionView3D *baserv3d = basear->regiondata;
+ RegionView3D rv3d = {{{0}}};
+ GPUScreenBuffer *scene_buffer;
+ int res[2] = {basear->winx, basear->winy};
+ int pbr_flag = v3d->pbr_settings.pbr_flag;
+
+ scene_buffer = GPU_pbr_scene_buffer(v3d->pbr, res[0], res[1]);
+
+ v3d->drawtype = OB_MATERIAL;
+ v3d->flag2 &= ~(V3D_SOLID_TEX | V3D_SHOW_SOLID_MATCAP);
+ v3d->flag2 |= V3D_RENDER_OVERRIDE;
+ v3d->flag3 |= V3D_SHOW_WORLD;
+ v3d->flag3 &= ~V3D_SHOW_WORLD_DIFFUSE;
+ v3d->flag3 |= V3D_PROBE_CAPTURE;
+ v3d->pbr_settings.pbr_flag &= ~GPU_PBR_FLAG_SSR;
+ v3d->pbr_settings.pbr_flag &= ~GPU_PBR_FLAG_SSAO;
+
+ ar.regiondata = &rv3d;
+ ar.regiontype = RGN_TYPE_WINDOW;
+ rv3d.persp = RV3D_CAMOB;
+
+ /* Getting camera coords */
+ ED_view3d_viewplane_get(v3d, baserv3d, basear->winx, basear->winy, NULL, &clipsta, &clipend, NULL);
+ view3d_winmatrix_set(basear, v3d, NULL);
+ view3d_viewmatrix_set(scene, v3d, baserv3d); /* note: calls BKE_object_where_is_calc for camera... */
+
+ GPU_scenebuf_bind(scene_buffer, baserv3d->winmat, winsize, clipsta, clipend);
+
+ copy_m4_m4(rv3d.viewmat, baserv3d->viewmat);
+ invert_m4_m4(rv3d.viewinv, rv3d.viewmat);
+ mul_m4_m4m4(rv3d.persmat, baserv3d->winmat, rv3d.viewmat);
+ invert_m4_m4(rv3d.persinv, rv3d.viewinv);
+
+ ED_view3d_draw_offscreen(
+ scene, v3d, &ar, winsize[0], winsize[1], baserv3d->viewmat, baserv3d->winmat,
+ false, (bool)scene->world, true, true,
+ NULL, NULL, NULL, NULL);
+
+ v3d->drawtype = drawtype;
+ v3d->flag2 = flag2;
+ v3d->flag3 = flag3;
+ v3d->pbr_settings.pbr_flag = pbr_flag;
+
+ GPU_scenebuf_unbind(scene_buffer);
+ GPU_scenebuf_filter_texture(scene_buffer);
+}
+
+static void gpu_update_backface_buffer(Scene *scene, View3D *v3d, ARegion *basear)
+{
+ int drawtype = v3d->drawtype, winsize[2], flag2 = v3d->flag2, flag3 = v3d->flag3;
+ float clipsta, clipend;
+ ARegion ar = {NULL};
+ RegionView3D *baserv3d = basear->regiondata;
+ RegionView3D rv3d = {{{0}}};
+ GPUScreenBuffer *backface_buffer;
+ int res[2] = {basear->winx, basear->winy};
+
+ backface_buffer = GPU_pbr_backface_buffer(v3d->pbr, res[0], res[1]);
+
+ v3d->drawtype = OB_SOLID;
+ v3d->flag2 &= ~(V3D_SOLID_TEX | V3D_SHOW_SOLID_MATCAP);
+ v3d->flag2 |= V3D_BACKFACE_CULLING | V3D_RENDER_OVERRIDE | V3D_RENDER_SHADOW;
+ v3d->flag3 |= V3D_FLIP_NORMALS;
+
+ ar.regiondata = &rv3d;
+ ar.regiontype = RGN_TYPE_WINDOW;
+ rv3d.persp = RV3D_CAMOB;
+
+ /* Getting camera coords */
+ ED_view3d_viewplane_get(v3d, baserv3d, basear->winx, basear->winy, NULL, &clipsta, &clipend, NULL);
+ view3d_winmatrix_set(basear, v3d, NULL);
+ view3d_viewmatrix_set(scene, v3d, baserv3d); /* note: calls BKE_object_where_is_calc for camera... */
+
+ GPU_scenebuf_bind(backface_buffer, baserv3d->winmat, winsize, clipsta, clipend);
+
+ copy_m4_m4(rv3d.viewmat, baserv3d->viewmat);
+ invert_m4_m4(rv3d.viewinv, rv3d.viewmat);
+ mul_m4_m4m4(rv3d.persmat, baserv3d->winmat, rv3d.viewmat);
+ invert_m4_m4(rv3d.persinv, rv3d.viewinv);
+
+ ED_view3d_draw_offscreen(
+ scene, v3d, &ar, winsize[0], winsize[1], baserv3d->viewmat, baserv3d->winmat,
+ false, (bool)scene->world, true, true,
+ NULL, NULL, NULL, NULL);
+
+ v3d->drawtype = drawtype;
+ v3d->flag2 = flag2;
+ v3d->flag3 = flag3;
+
+ GPU_scenebuf_unbind(backface_buffer);
+ GPU_scenebuf_filter_texture(backface_buffer);
+}
+
+
+static void gpu_pbr_update(Scene *scene, View3D *v3d, ARegion *ar)
+{
+ GPUPBR *pbr = v3d->pbr;
+
+ gpu_update_probes(scene, v3d, ar);
+
+ if (v3d->pbr_settings.pbr_flag & (GPU_PBR_FLAG_SSR | GPU_PBR_FLAG_SSAO))
+ gpu_update_scene_buffer(scene, v3d, ar);
+ else if (pbr->scene) {
+ GPU_scenebuf_free(pbr->scene);
+ pbr->scene = NULL;
+ }
+
+ if ((v3d->pbr_settings.pbr_flag & GPU_PBR_FLAG_BACKFACE) && (v3d->pbr_settings.pbr_flag & (GPU_PBR_FLAG_SSR | GPU_PBR_FLAG_SSAO)))
+ gpu_update_backface_buffer(scene, v3d, ar);
+ else if (pbr->backface) {
+ GPU_scenebuf_free(pbr->backface);
+ pbr->backface = NULL;
+ }
+}
+
/* *********************** customdata **************** */
CustomDataMask ED_view3d_datamask(const Scene *scene, const View3D *v3d)
@@ -2692,7 +3067,7 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view
rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f;
rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
}
-
+
/* calculate pixelsize factor once, is used for lamps and obcenters */
{
/* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
@@ -2971,11 +3346,22 @@ void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, void *rv3dmat_pt)
rv3d->pixsize = rv3dmat->pixsize;
}
-void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
+void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d, ARegion *ar)
{
/* shadow buffers, before we setup matrices */
- if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
+ if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype)){
gpu_update_lamps_shadows_world(scene, v3d);
+
+ /* Cycles Material Mode only */
+ if (BKE_scene_use_new_shading_nodes(scene) && (v3d->pbr_settings.pbr_flag & GPU_PBR_FLAG_ENABLE)) {
+ GPU_pbr_settings_validate(&v3d->pbr_settings);
+
+ if (!v3d->pbr)
+ v3d->pbr = GPU_pbr_create();
+
+ gpu_pbr_update(scene, v3d, ar);
+ }
+ }
}
/*
@@ -2983,25 +3369,39 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
*/
static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar)
{
+ GPUFXSettings *fx_settings = &v3d->fx_settings;
+ bool use_color_correction = (fx_settings->fx_flag2 && (fx_settings->fx_flag2 & GPU_FX_FLAG_COLORMANAGEMENT)) ? false : true;
+
if (scene->world && (v3d->flag3 & V3D_SHOW_WORLD)) {
bool glsl = GPU_glsl_support();
+
if (glsl) {
RegionView3D *rv3d = ar->regiondata;
- GPUMaterial *gpumat = GPU_material_world(scene, scene->world);
+ GPUMaterial *gpumat;
+ GPUProbe *gpuprobe;
+ bool material_not_bound;
- /* calculate full shader for background */
- GPU_material_bind(gpumat, 1, 1, 1.0, false, rv3d->viewmat, rv3d->viewinv, rv3d->viewcamtexcofac, (v3d->scenelock != 0));
-
- bool material_not_bound = !GPU_material_bound(gpumat);
+ if (v3d->flag3 & V3D_SHOW_WORLD_DIFFUSE) {
+ gpuprobe = GPU_probe_world(scene, scene->world);
+ GPU_probe_sh_shader_bind(gpuprobe);
+ }
+ else {
+ gpumat = GPU_material_world(scene, scene->world);
- if (material_not_bound) {
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+ /* calculate full shader for background */
+ GPU_material_bind(gpumat, 1, 1, 1.0, true, rv3d->viewmat, rv3d->viewinv, rv3d->viewcamtexcofac, (v3d->scenelock != 0));
+
+ material_not_bound = !GPU_material_bound(gpumat);
+
+ if (material_not_bound) {
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+ }
}
// Draw world
glEnable(GL_DEPTH_TEST);
@@ -3012,15 +3412,20 @@ static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar)
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, 1.0);
glEnd();
- //
- if (material_not_bound) {
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
+
+ if (v3d->flag3 & V3D_SHOW_WORLD_DIFFUSE) {
+ GPU_probe_sh_shader_unbind();
}
+ else {
+ if (material_not_bound) {
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ }
- GPU_material_unbind(gpumat);
+ GPU_material_unbind(gpumat);
+ }
glDepthFunc(GL_LEQUAL);
glDisable(GL_DEPTH_TEST);
@@ -3038,10 +3443,17 @@ static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar)
static GLushort indices[VIEWGRAD_RES_X - 1][VIEWGRAD_RES_X - 1][4];
static bool buf_calculated = false;
- IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings,
- &scene->display_settings);
- IMB_colormanagement_pixel_to_display_space_v3(col_zen, &scene->world->zenr, &scene->view_settings,
- &scene->display_settings);
+ if (use_color_correction) {
+ IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings,
+ &scene->display_settings);
+ IMB_colormanagement_pixel_to_display_space_v3(col_zen, &scene->world->zenr, &scene->view_settings,
+ &scene->display_settings);
+ }
+ else {
+ copy_v3_v3(col_hor, &scene->world->horr);
+ copy_v3_v3(col_zen, &scene->world->zenr);
+ }
+
glMatrixMode(GL_PROJECTION);
glPushMatrix();
@@ -3140,8 +3552,13 @@ static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar)
}
else { /* solid sky */
float col_hor[3];
- IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings,
+ if (use_color_correction) {
+ IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings,
&scene->display_settings);
+ }
+ else {
+ copy_v3_v3(col_hor, &scene->world->horr);
+ }
glClearColor(col_hor[0], col_hor[1], col_hor[2], 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -3188,7 +3605,7 @@ static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar)
void ED_view3d_draw_offscreen(
Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy,
float viewmat[4][4], float winmat[4][4],
- bool do_bgpic, bool do_sky, bool is_persp, const char *viewname,
+ bool do_bgpic, bool do_sky, bool is_persp, bool do_meshes, const char *viewname,
GPUFX *fx, GPUFXSettings *fx_settings,
GPUOffScreen *ofs)
{
@@ -3231,15 +3648,21 @@ void ED_view3d_draw_offscreen(
view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat);
/* framebuffer fx needed, we need to draw offscreen first */
- if (v3d->fx_settings.fx_flag && fx) {
+ if ((v3d->fx_settings.fx_flag || v3d->fx_settings.fx_flag2) && fx) {
GPUSSAOSettings *ssao = NULL;
+ char fx_flag2 = v3d->fx_settings.fx_flag2;
+
+ /* Don't do color management fx for offscreen */
+ v3d->fx_settings.fx_flag2 &= ~GPU_FX_FLAG_COLORMANAGEMENT;
if (v3d->drawtype < OB_SOLID) {
ssao = v3d->fx_settings.ssao;
v3d->fx_settings.ssao = NULL;
}
- do_compositing = GPU_fx_compositor_initialize_passes(fx, &ar->winrct, NULL, fx_settings);
+ do_compositing = GPU_fx_compositor_initialize_passes(fx, &ar->winrct, NULL, fx_settings, scene);
+
+ v3d->fx_settings.fx_flag2 = fx_flag2;
if (ssao)
v3d->fx_settings.ssao = ssao;
@@ -3255,7 +3678,8 @@ void ED_view3d_draw_offscreen(
}
/* main drawing call */
- view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true, do_compositing ? fx : NULL);
+ if (do_meshes)
+ view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true, do_compositing ? fx : NULL);
/* post process */
if (do_compositing) {
@@ -3327,7 +3751,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
}
}
- ED_view3d_draw_offscreen_init(scene, v3d);
+ ED_view3d_draw_offscreen_init(scene, v3d, ar);
GPU_offscreen_bind(ofs, true);
@@ -3370,7 +3794,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
/* Single-pass render, common case */
ED_view3d_draw_offscreen(
scene, v3d, ar, sizex, sizey, NULL, winmat,
- draw_background, draw_sky, !is_ortho, viewname,
+ draw_background, draw_sky, !is_ortho, true, viewname,
fx, &fx_settings, ofs);
if (ibuf->rect_float) {
@@ -3396,7 +3820,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
/* first sample buffer, also initializes 'rv3d->persmat' */
ED_view3d_draw_offscreen(
scene, v3d, ar, sizex, sizey, NULL, winmat,
- draw_background, draw_sky, !is_ortho, viewname,
+ draw_background, draw_sky, !is_ortho, true, viewname,
fx, &fx_settings, ofs);
GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, rect_temp);
@@ -3415,7 +3839,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
ED_view3d_draw_offscreen(
scene, v3d, ar, sizex, sizey, NULL, winmat_jitter,
- draw_background, draw_sky, !is_ortho, viewname,
+ draw_background, draw_sky, !is_ortho, true, viewname,
fx, &fx_settings, ofs);
GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, rect_temp);
@@ -3842,14 +4266,25 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Vie
wmWindow *win = CTX_wm_window(C);
RegionView3D *rv3d = ar->regiondata;
unsigned int lay_used = v3d->lay_used;
-
+
+
/* post processing */
bool do_compositing = false;
/* shadow buffers, before we setup matrices */
- if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
+ if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype)) {
gpu_update_lamps_shadows_world(scene, v3d);
+ if (BKE_scene_use_new_shading_nodes(scene) && (v3d->pbr_settings.pbr_flag & GPU_PBR_FLAG_ENABLE)) {
+ GPU_pbr_settings_validate(&v3d->pbr_settings);
+
+ if (!v3d->pbr)
+ v3d->pbr = GPU_pbr_create();
+
+ gpu_pbr_update(scene, v3d, ar);
+ }
+ }
+
/* reset default OpenGL lights if needed (i.e. after preferences have been altered) */
if (rv3d->rflag & RV3D_GPULIGHT_UPDATE) {
rv3d->rflag &= ~RV3D_GPULIGHT_UPDATE;
@@ -3873,7 +4308,7 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Vie
#endif
/* framebuffer fx needed, we need to draw offscreen first */
- if (v3d->fx_settings.fx_flag && v3d->drawtype >= OB_SOLID) {
+ if ((v3d->fx_settings.fx_flag || v3d->fx_settings.fx_flag2) && v3d->drawtype >= OB_SOLID) {
GPUFXSettings fx_settings;
BKE_screen_gpu_fx_validate(&v3d->fx_settings);
fx_settings = v3d->fx_settings;
@@ -3886,7 +4321,7 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Vie
fx_settings.dof = NULL;
}
- do_compositing = GPU_fx_compositor_initialize_passes(rv3d->compositor, &ar->winrct, &ar->drawrct, &fx_settings);
+ do_compositing = GPU_fx_compositor_initialize_passes(rv3d->compositor, &ar->winrct, &ar->drawrct, &fx_settings, scene);
}
/* clear the background */
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 8885209ce01..d00efc3979c 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -55,7 +55,9 @@ set(SRC
intern/gpu_extensions.c
intern/gpu_framebuffer.c
intern/gpu_init_exit.c
+ intern/gpu_pbr.c
intern/gpu_material.c
+ intern/gpu_probe.c
intern/gpu_select.c
intern/gpu_shader.c
intern/gpu_texture.c
@@ -69,6 +71,18 @@ set(SRC
shaders/gpu_shader_fx_dof_hq_geo.glsl
shaders/gpu_shader_fx_vert.glsl
shaders/gpu_shader_material.glsl
+ shaders/gpu_shader_material_bsdf_anisotropic.glsl
+ shaders/gpu_shader_material_bsdf_velvet.glsl
+ shaders/gpu_shader_material_bsdf_diffuse.glsl
+ shaders/gpu_shader_material_bsdf_glass.glsl
+ shaders/gpu_shader_material_bsdf_translucent.glsl
+ shaders/gpu_shader_material_bsdf_transparent.glsl
+ shaders/gpu_shader_material_bsdf_glossy.glsl
+ shaders/gpu_shader_material_bsdf_refraction.glsl
+ shaders/gpu_shader_material_bsdf_toon.glsl
+ shaders/gpu_shader_material_bsdf_ambient_occlusion.glsl
+ shaders/gpu_shader_material_new_shading.glsl
+ shaders/gpu_shader_material_utils.glsl
shaders/gpu_shader_sep_gaussian_blur_frag.glsl
shaders/gpu_shader_sep_gaussian_blur_vert.glsl
shaders/gpu_shader_basic_frag.glsl
@@ -78,9 +92,16 @@ set(SRC
shaders/gpu_shader_vsm_store_frag.glsl
shaders/gpu_shader_vsm_store_vert.glsl
shaders/gpu_shader_fx_depth_resolve.glsl
+ shaders/gpu_shader_fx_colormanage_frag.glsl
shaders/gpu_shader_fire_frag.glsl
shaders/gpu_shader_smoke_frag.glsl
shaders/gpu_shader_smoke_vert.glsl
+ shaders/gpu_shader_probe_sh_compute_frag.glsl
+ shaders/gpu_shader_probe_sh_compute_vert.glsl
+ shaders/gpu_shader_display_sh_frag.glsl
+ shaders/gpu_shader_display_sh_vert.glsl
+ shaders/gpu_shader_downsample_maxz_frag.glsl
+ shaders/gpu_shader_downsample_maxz_vert.glsl
GPU_basic_shader.h
GPU_buffers.h
@@ -91,7 +112,10 @@ set(SRC
GPU_framebuffer.h
GPU_glew.h
GPU_init_exit.h
+ GPU_pbr.h
+ GPU_ltc.h
GPU_material.h
+ GPU_probe.h
GPU_select.h
GPU_shader.h
GPU_texture.h
@@ -104,6 +128,18 @@ data_to_c_simple(shaders/gpu_shader_fire_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_smoke_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_smoke_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_material.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_material_bsdf_anisotropic.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_material_bsdf_velvet.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_material_bsdf_diffuse.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_material_bsdf_glass.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_material_bsdf_translucent.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_material_bsdf_transparent.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_material_bsdf_glossy.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_material_bsdf_refraction.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_material_bsdf_toon.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_material_bsdf_ambient_occlusion.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_material_new_shading.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_material_utils.glsl SRC)
data_to_c_simple(shaders/gpu_shader_sep_gaussian_blur_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_sep_gaussian_blur_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_basic_frag.glsl SRC)
@@ -121,7 +157,14 @@ data_to_c_simple(shaders/gpu_shader_fx_dof_hq_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_fx_dof_hq_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_fx_dof_hq_geo.glsl SRC)
data_to_c_simple(shaders/gpu_shader_fx_depth_resolve.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_fx_colormanage_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_fx_lib.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_probe_sh_compute_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_probe_sh_compute_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_display_sh_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_display_sh_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_downsample_maxz_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_downsample_maxz_vert.glsl SRC)
if(WITH_GAMEENGINE)
add_definitions(-DWITH_GAMEENGINE)
diff --git a/source/blender/gpu/GPU_compositing.h b/source/blender/gpu/GPU_compositing.h
index d506d91a9aa..d1621f7713c 100644
--- a/source/blender/gpu/GPU_compositing.h
+++ b/source/blender/gpu/GPU_compositing.h
@@ -40,6 +40,7 @@ extern "C" {
typedef struct GPUFX GPUFX;
struct GPUDOFSettings;
struct GPUSSAOSettings;
+struct GPUCCSettings;
struct GPUOffScreen;
struct GPUFXSettings;
struct rcti;
@@ -66,10 +67,12 @@ typedef enum GPUFXShaderEffect {
GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_THREE = 9,
GPU_SHADER_FX_DEPTH_RESOLVE = 10,
+
+ GPU_SHADER_FX_COLORMANAGE = 11,
} GPUFXShaderEffect;
/* keep in synch with enum above! */
-#define MAX_FX_SHADERS 11
+#define MAX_FX_SHADERS 12
/* generate a new FX compositor */
GPUFX *GPU_fx_compositor_create(void);
@@ -80,7 +83,7 @@ void GPU_fx_compositor_destroy(GPUFX *fx);
/* initialize a framebuffer with size taken from the viewport */
bool GPU_fx_compositor_initialize_passes(
GPUFX *fx, const struct rcti *rect, const struct rcti *scissor_rect,
- const struct GPUFXSettings *fx_settings);
+ const struct GPUFXSettings *fx_settings, struct Scene *scene);
/* do compositing on the fx passes that have been initialized */
bool GPU_fx_do_composite_pass(
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index 90b65af87c8..d5dbd55279d 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -32,6 +32,8 @@
#ifndef __GPU_DRAW_H__
#define __GPU_DRAW_H__
+#include "GPU_glew.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -113,6 +115,7 @@ void GPU_render_text(
/* Mipmap settings
* - these will free textures on changes */
+void GPU_generate_mipmap(GLenum target);
void GPU_set_mipmap(bool mipmap);
bool GPU_get_mipmap(void);
void GPU_set_linear_mipmap(bool linear);
@@ -135,10 +138,10 @@ void GPU_update_images_framechange(void);
int GPU_update_image_time(struct Image *ima, double time);
int GPU_verify_image(
struct Image *ima, struct ImageUser *iuser,
- int textarget, int tftile, bool compare, bool mipmap, bool is_data);
+ int textarget, int tftile, bool compare, bool mipmap, bool is_data, bool is_envmap);
void GPU_create_gl_tex(
unsigned int *bind, unsigned int *rect, float *frect, int rectw, int recth,
- int textarget, bool mipmap, bool use_hight_bit_depth, struct Image *ima);
+ int textarget, bool mipmap, bool use_hight_bit_depth, struct Image *ima, bool is_envmap);
void GPU_create_gl_tex_compressed(
unsigned int *bind, unsigned int *pix, int x, int y, int mipmap,
int textarget, struct Image *ima, struct ImBuf *ibuf);
diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h
index 2719b8fa6a8..f7ffecf9511 100644
--- a/source/blender/gpu/GPU_framebuffer.h
+++ b/source/blender/gpu/GPU_framebuffer.h
@@ -51,6 +51,7 @@ void GPU_texture_bind_as_framebuffer(struct GPUTexture *tex);
GPUFrameBuffer *GPU_framebuffer_create(void);
int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, struct GPUTexture *tex, int slot, char err_out[256]);
+int GPU_framebuffer_cubeface_attach(GPUFrameBuffer *fb, struct GPUTexture *tex, int slot, int cubeface, char err_out[256]);
void GPU_framebuffer_texture_detach(struct GPUTexture *tex);
void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot);
void GPU_framebuffer_texture_unbind(GPUFrameBuffer *fb, struct GPUTexture *tex);
@@ -66,6 +67,8 @@ void GPU_framebuffer_blur(
GPUFrameBuffer *fb, struct GPUTexture *tex,
GPUFrameBuffer *blurfb, struct GPUTexture *blurtex);
+void GPU_framebuffer_hiz_construction(GPUFrameBuffer *fb, struct GPUTexture *tex, const bool max);
+
/* GPU OffScreen
* - wrapper around framebuffer and texture for simple offscreen drawing
* - changes size if graphics card can't support it */
diff --git a/source/blender/gpu/GPU_ltc.h b/source/blender/gpu/GPU_ltc.h
new file mode 100644
index 00000000000..c99c8d8aea6
--- /dev/null
+++ b/source/blender/gpu/GPU_ltc.h
@@ -0,0 +1,48 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Clement Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file GPU_ltc.h
+ * \ingroup gpu
+ */
+
+#ifndef __GPU_LTC_H__
+#define __GPU_LTC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* XXX should be used only in gpu_texture.c */
+/* It's here only to not bloat the gpu_texture.c file */
+static float ltc_mat_ggx[64*64*4] = {0.000200, -0.000000, 1.000000, -0.000000, 0.000504, -0.000000, 1.000000, -0.000000, 0.002016, -0.000000, 1.000000, -0.000000, 0.004535, -0.000000, 1.000000, -0.000000, 0.008063, -0.000000, 1.000000, -0.000000, 0.012598, -0.000000, 1.000000, -0.000000, 0.018141, -0.000000, 1.000000, -0.000000, 0.024692, -0.000000, 1.000000, -0.000000, 0.032252, -0.000000, 1.000000, -0.000000, 0.040821, -0.000000, 1.000000, -0.000000, 0.050400, -0.000000, 1.000000, -0.000000, 0.060989, -0.000000, 1.000000, -0.000000, 0.072591, -0.000000, 1.000000, -0.000000, 0.085206, -0.000000, 1.000000, -0.000000, 0.098836, -0.000000, 1.000000, -0.000000, 0.113483, -0.000000, 1.000000, -0.000000, 0.129147, -0.000000, 1.000000, -0.000000, 0.145828, -0.000000, 1.000000, -0.000000, 0.163499, -0.000000, 1.000000, -0.000000, 0.181972, -0.000000, 1.000000, -0.000000, 0.199498, -0.000000, 1.000000, -0.000000, 0.220031, -0.000000, 1.000000, -0.000000, 0.241588, -0.000000, 1.000000, -0.000000, 0.264120, -0.000000, 1.000000, -0.000000, 0.287521, -0.000000, 1.000000, -0.000000, 0.311478, -0.000000, 1.000000, -0.000000, 0.335127, -0.000000, 1.000000, -0.000000, 0.359811, -0.000000, 1.000000, -0.000000, 0.386446, -0.000000, 1.000000, -0.000000, 0.413161, -0.000000, 1.000000, -0.000000, 0.439142, -0.000000, 1.000000, -0.000000, 0.467039, -0.000000, 1.000000, -0.000000, 0.495170, -0.000000, 1.000000, -0.000000, 0.522324, -0.000000, 1.000000, -0.000000, 0.551482, -0.000000, 1.000000, -0.000000, 0.579621, -0.000000, 1.000000, -0.000000, 0.608255, -0.000000, 1.000000, -0.000000, 0.636515, -0.000000, 1.000000, -0.000000, 0.664835, -0.000000, 1.000000, -0.000000, 0.692549, -0.000000, 1.000000, -0.000000, 0.720375, -0.000000, 1.000000, -0.000000, 0.747238, -0.000000, 1.000000, -0.000000, 0.773956, -0.000000, 1.000000, -0.000000, 0.799879, -0.000000, 1.000000, -0.000000, 0.824889, -0.000000, 1.000000, -0.000000, 0.849357, -0.000000, 1.000000, -0.000000, 0.873016, -0.000000, 1.000000, -0.000000, 0.895670, -0.000000, 1.000000, -0.000000, 0.917194, -0.000000, 1.000000, -0.000000, 0.937978, -0.000000, 1.000000, -0.000000, 0.957872, -0.000000, 1.000000, -0.000000, 0.976736, -0.000000, 1.000000, -0.000000, 0.994433, -0.000000, 1.000000, -0.000000, 1.011206, -0.000000, 1.000000, -0.000000, 1.026820, -0.000000, 1.000000, -0.000000, 1.041720, -0.000000, 1.000000, -0.000000, 1.055657, -0.000000, 1.000000, -0.000000, 1.068642, -0.000000, 1.000000, -0.000000, 1.080646, -0.000000, 1.000000, -0.000000, 1.091637, -0.000000, 1.000000, -0.000000, 1.101837, -0.000000, 1.000000, -0.000000, 1.111292, -0.000000, 1.000000, -0.000000, 1.120025, -0.000000, 1.000000, -0.000000, 1.127918, -0.000000, 1.000000, -0.000000, 0.000200, -0.000005, 1.000623, 0.024938, 0.000504, -0.000013, 1.000643, 0.024938, 0.002016, -0.000050, 1.000618, 0.024938, 0.004535, -0.000113, 1.000621, 0.024938, 0.008063, -0.000201, 1.000746, 0.024938, 0.012596, -0.000314, 1.000463, 0.024937, 0.018140, -0.000452, 1.000511, 0.024939, 0.024693, -0.000616, 1.000541, 0.024938, 0.032253, -0.000804, 1.000684, 0.024938, 0.040815, -0.001018, 1.000524, 0.024940, 0.050399, -0.001257, 1.000582, 0.024937, 0.060989, -0.001521, 1.000655, 0.024937, 0.072591, -0.001810, 1.000608, 0.024938, 0.085204, -0.002125, 1.000622, 0.024939, 0.098835, -0.002465, 1.000632, 0.024937, 0.113483, -0.002830, 1.000640, 0.024939, 0.129143, -0.003220, 1.000568, 0.024938, 0.145830, -0.003633, 1.000635, 0.024938, 0.163497, -0.004062, 1.000626, 0.024938, 0.181956, -0.004424, 1.000612, 0.024924, 0.199791, -0.004593, 1.000627, 0.024890, 0.220029, -0.005480, 1.000594, 0.024935, 0.241586, -0.006010, 1.000616, 0.024933, 0.264115, -0.006550, 1.000607, 0.024927, 0.287514, -0.007072, 1.000595, 0.024909, 0.311455, -0.007472, 1.000616, 0.024872, 0.335083, -0.007491, 1.000589, 0.024755, 0.359805, -0.008810, 1.000601, 0.024877, 0.386438, -0.009282, 1.000640, 0.024824, 0.413131, -0.009534, 1.000599, 0.024708, 0.439249, -0.009701, 1.000497, 0.024573, 0.466997, -0.010878, 1.000467, 0.024652, 0.495138, -0.010959, 1.000539, 0.024455, 0.522654, -0.011386, 1.000518, 0.024318, 0.551415, -0.012022, 1.000533, 0.024216, 0.579610, -0.011805, 1.000495, 0.023867, 0.608185, -0.012773, 1.000474, 0.023834, 0.636492, -0.012377, 1.000488, 0.023327, 0.664826, -0.013172, 1.000576, 0.023205, 0.692674, -0.012847, 1.000505, 0.022708, 0.720341, -0.013141, 1.000424, 0.022349, 0.747373, -0.013227, 1.000449, 0.021871, 0.773980, -0.012739, 1.000478, 0.021171, 0.799839, -0.012999, 1.000396, 0.020606, 0.825113, -0.012727, 1.000425, 0.020006, 0.849579, -0.012170, 1.000469, 0.019089, 0.873046, -0.011855, 1.000411, 0.018291, 0.895777, -0.011711, 1.000426, 0.017534, 0.917518, -0.011107, 1.000373, 0.016542, 0.938264, -0.010439, 1.000322, 0.015512, 0.958032, -0.009807, 1.000324, 0.014491, 0.976838, -0.009268, 1.000341, 0.013468, 0.994631, -0.008662, 1.000318, 0.012376, 1.011434, -0.007923, 1.000289, 0.011187, 1.027169, -0.007132, 1.000216, 0.010078, 1.041929, -0.006332, 1.000096, 0.008924, 1.055767, -0.005554, 1.000156, 0.007770, 1.068595, -0.004811, 1.000084, 0.006611, 1.080612, -0.003950, 1.000047, 0.005485, 1.091785, -0.003174, 1.000109, 0.004352, 1.101998, -0.002363, 1.000029, 0.003180, 1.111423, -0.001552, 0.999985, 0.002091, 1.120007, -0.000786, 0.999947, 0.000991, 1.127918, 0.000004, 1.000000, -0.000004, 0.000200, -0.000010, 1.002495, 0.049907, 0.000504, -0.000025, 1.002476, 0.049908, 0.002016, -0.000101, 1.002500, 0.049908, 0.004535, -0.000226, 1.002487, 0.049908, 0.008062, -0.000402, 1.002364, 0.049908, 0.012598, -0.000629, 1.002412, 0.049908, 0.018140, -0.000905, 1.002379, 0.049908, 0.024691, -0.001232, 1.002490, 0.049907, 0.032251, -0.001610, 1.002398, 0.049908, 0.040821, -0.002037, 1.002392, 0.049908, 0.050398, -0.002515, 1.002431, 0.049907, 0.060989, -0.003044, 1.002475, 0.049908, 0.072592, -0.003623, 1.002546, 0.049907, 0.085204, -0.004252, 1.002467, 0.049907, 0.098832, -0.004932, 1.002450, 0.049908, 0.113481, -0.005663, 1.002482, 0.049907, 0.129145, -0.006443, 1.002443, 0.049907, 0.145825, -0.007271, 1.002495, 0.049906, 0.163491, -0.008128, 1.002475, 0.049903, 0.181911, -0.008826, 1.002459, 0.049879, 0.200065, -0.009285, 1.002443, 0.049824, 0.220025, -0.010966, 1.002450, 0.049897, 0.241581, -0.012025, 1.002463, 0.049893, 0.264099, -0.013105, 1.002395, 0.049881, 0.287493, -0.014145, 1.002390, 0.049855, 0.311399, -0.014925, 1.002414, 0.049769, 0.335096, -0.015239, 1.002363, 0.049591, 0.359815, -0.017559, 1.002415, 0.049777, 0.386365, -0.018554, 1.002354, 0.049675, 0.413017, -0.019043, 1.002297, 0.049444, 0.439519, -0.019815, 1.002284, 0.049253, 0.466938, -0.021741, 1.002307, 0.049327, 0.494999, -0.021887, 1.002181, 0.048922, 0.522922, -0.022844, 1.002107, 0.048677, 0.551270, -0.024014, 1.002101, 0.048478, 0.579771, -0.024156, 1.002060, 0.047904, 0.608156, -0.025317, 1.002077, 0.047594, 0.636662, -0.025321, 1.001975, 0.046876, 0.664846, -0.026018, 1.001992, 0.046354, 0.692877, -0.026041, 1.001846, 0.045504, 0.720316, -0.026252, 1.001846, 0.044655, 0.747658, -0.026159, 1.001931, 0.043670, 0.774252, -0.026086, 1.001845, 0.042515, 0.800179, -0.025653, 1.001794, 0.041211, 0.825525, -0.025170, 1.001787, 0.039823, 0.850013, -0.024788, 1.001806, 0.038409, 0.873593, -0.023992, 1.001688, 0.036767, 0.896343, -0.022985, 1.001666, 0.034900, 0.918062, -0.022005, 1.001548, 0.033010, 0.938928, -0.021110, 1.001503, 0.031143, 0.958667, -0.019893, 1.001341, 0.029059, 0.977457, -0.018546, 1.001194, 0.026888, 0.995243, -0.017152, 1.001095, 0.024713, 1.012023, -0.015750, 1.001100, 0.022496, 1.027614, -0.014289, 1.000851, 0.020153, 1.042389, -0.012688, 1.000724, 0.017839, 1.056161, -0.011118, 1.000572, 0.015529, 1.068968, -0.009540, 1.000407, 0.013240, 1.080866, -0.007963, 1.000258, 0.010940, 1.091944, -0.006416, 1.000254, 0.008716, 1.102104, -0.004771, 1.000175, 0.006434, 1.111571, -0.003056, 1.000148, 0.004169, 1.120084, -0.001458, 1.000050, 0.002033, 1.127981, 0.000021, 0.999987, -0.000027, 0.000200, -0.000015, 1.005620, 0.074940, 0.000504, -0.000038, 1.005650, 0.074939, 0.002016, -0.000151, 1.005613, 0.074939, 0.004535, -0.000340, 1.005618, 0.074939, 0.008062, -0.000604, 1.005614, 0.074939, 0.012597, -0.000944, 1.005616, 0.074940, 0.018141, -0.001359, 1.005558, 0.074939, 0.024695, -0.001851, 1.005495, 0.074940, 0.032253, -0.002417, 1.005616, 0.074939, 0.040822, -0.003059, 1.005591, 0.074940, 0.050399, -0.003777, 1.005596, 0.074940, 0.060989, -0.004570, 1.005599, 0.074939, 0.072591, -0.005440, 1.005616, 0.074940, 0.085203, -0.006385, 1.005616, 0.074939, 0.098833, -0.007406, 1.005595, 0.074938, 0.113481, -0.008502, 1.005605, 0.074938, 0.129147, -0.009674, 1.005605, 0.074937, 0.145817, -0.010916, 1.005513, 0.074937, 0.163485, -0.012199, 1.005579, 0.074928, 0.181824, -0.013172, 1.005552, 0.074885, 0.200274, -0.014100, 1.005524, 0.074825, 0.220017, -0.016464, 1.005529, 0.074928, 0.241568, -0.018052, 1.005490, 0.074914, 0.264084, -0.019671, 1.005457, 0.074898, 0.287450, -0.021217, 1.005431, 0.074860, 0.311281, -0.022341, 1.005395, 0.074717, 0.335228, -0.023296, 1.005320, 0.074526, 0.360047, -0.025965, 1.005302, 0.074649, 0.386273, -0.027808, 1.005285, 0.074575, 0.412855, -0.028504, 1.005167, 0.074237, 0.439705, -0.030007, 1.005129, 0.074013, 0.466975, -0.032263, 1.005082, 0.073967, 0.494874, -0.032931, 1.004960, 0.073475, 0.523066, -0.034348, 1.004834, 0.073084, 0.551198, -0.035739, 1.004806, 0.072657, 0.579889, -0.036575, 1.004687, 0.072029, 0.608282, -0.037434, 1.004605, 0.071309, 0.636812, -0.038323, 1.004589, 0.070507, 0.665010, -0.038676, 1.004403, 0.069424, 0.693063, -0.039237, 1.004340, 0.068370, 0.720750, -0.039332, 1.004224, 0.066988, 0.747911, -0.039179, 1.004117, 0.065447, 0.774576, -0.039110, 1.004035, 0.063838, 0.800737, -0.038542, 1.004027, 0.061923, 0.825966, -0.037966, 1.003825, 0.059859, 0.850534, -0.036943, 1.003786, 0.057529, 0.874289, -0.035853, 1.003560, 0.055081, 0.897152, -0.034730, 1.003549, 0.052476, 0.919029, -0.033242, 1.003454, 0.049647, 0.939851, -0.031508, 1.003215, 0.046670, 0.959599, -0.029695, 1.002916, 0.043588, 0.978293, -0.027845, 1.002720, 0.040401, 0.996085, -0.025775, 1.002445, 0.037060, 1.012768, -0.023607, 1.002133, 0.033726, 1.028404, -0.021374, 1.001822, 0.030217, 1.043150, -0.019108, 1.001602, 0.026820, 1.056760, -0.016823, 1.001274, 0.023372, 1.069471, -0.014378, 1.000964, 0.019891, 1.081283, -0.011884, 1.000684, 0.016405, 1.092238, -0.009398, 1.000514, 0.012950, 1.102384, -0.007030, 1.000319, 0.009579, 1.111737, -0.004751, 1.000225, 0.006384, 1.120274, -0.002404, 1.000046, 0.003192, 1.128182, 0.000031, 1.000020, 0.000033, 0.000200, -0.000020, 1.010006, 0.100065, 0.000504, -0.000050, 1.009927, 0.100065, 0.002016, -0.000202, 1.010026, 0.100064, 0.004535, -0.000454, 1.010018, 0.100065, 0.008062, -0.000807, 1.009891, 0.100064, 0.012599, -0.001261, 1.010175, 0.100064, 0.018141, -0.001815, 1.010067, 0.100065, 0.024692, -0.002471, 1.010014, 0.100066, 0.032251, -0.003227, 1.009950, 0.100065, 0.040818, -0.004084, 1.009963, 0.100067, 0.050401, -0.005043, 1.010032, 0.100064, 0.060988, -0.006102, 1.009979, 0.100064, 0.072588, -0.007263, 1.009984, 0.100063, 0.085205, -0.008525, 1.010023, 0.100063, 0.098832, -0.009888, 1.009960, 0.100062, 0.113479, -0.011352, 1.009974, 0.100063, 0.129142, -0.012916, 1.009945, 0.100062, 0.145817, -0.014573, 1.009924, 0.100058, 0.163468, -0.016276, 1.009912, 0.100050, 0.181674, -0.017411, 1.009859, 0.099975, 0.200435, -0.019002, 1.009842, 0.099932, 0.220005, -0.021978, 1.009820, 0.100043, 0.241550, -0.024096, 1.009778, 0.100031, 0.264058, -0.026250, 1.009765, 0.100002, 0.287399, -0.028286, 1.009724, 0.099939, 0.311134, -0.029698, 1.009596, 0.099748, 0.335350, -0.031442, 1.009508, 0.099582, 0.360295, -0.034401, 1.009475, 0.099613, 0.386112, -0.037030, 1.009329, 0.099558, 0.412733, -0.038163, 1.009250, 0.099137, 0.439833, -0.040250, 1.009125, 0.098866, 0.467099, -0.042583, 1.009011, 0.098626, 0.494828, -0.044299, 1.008803, 0.098149, 0.523217, -0.045876, 1.008712, 0.097600, 0.551338, -0.047440, 1.008509, 0.096929, 0.579917, -0.048995, 1.008371, 0.096178, 0.608454, -0.049901, 1.008212, 0.095145, 0.636785, -0.051224, 1.007963, 0.094151, 0.665220, -0.051675, 1.007741, 0.092728, 0.693194, -0.052278, 1.007616, 0.091195, 0.721008, -0.052406, 1.007327, 0.089384, 0.748196, -0.052529, 1.007219, 0.087461, 0.774975, -0.051950, 1.006851, 0.085133, 0.801129, -0.051456, 1.006732, 0.082628, 0.826668, -0.050569, 1.006612, 0.079817, 0.851291, -0.049328, 1.006374, 0.076710, 0.875056, -0.047988, 1.006183, 0.073481, 0.897872, -0.046149, 1.005742, 0.069943, 0.919803, -0.044144, 1.005514, 0.066151, 0.940701, -0.042095, 1.005153, 0.062247, 0.960580, -0.039730, 1.004843, 0.058158, 0.979427, -0.037104, 1.004535, 0.053850, 0.997157, -0.034369, 1.004023, 0.049403, 1.013777, -0.031555, 1.003622, 0.044944, 1.029452, -0.028571, 1.003212, 0.040414, 1.044029, -0.025416, 1.002698, 0.035723, 1.057586, -0.022217, 1.002202, 0.031072, 1.070148, -0.019037, 1.001703, 0.026429, 1.081875, -0.015936, 1.001322, 0.021896, 1.092789, -0.012734, 1.001053, 0.017288, 1.102704, -0.009454, 1.000604, 0.012841, 1.112011, -0.006199, 1.000387, 0.008446, 1.120590, -0.003010, 1.000166, 0.004122, 1.128283, 0.000027, 0.999956, -0.000038, 0.000200, -0.000025, 1.015664, 0.125315, 0.000504, -0.000063, 1.015664, 0.125316, 0.002016, -0.000253, 1.015727, 0.125315, 0.004535, -0.000568, 1.015695, 0.125314, 0.008063, -0.001010, 1.015823, 0.125316, 0.012599, -0.001579, 1.015867, 0.125315, 0.018141, -0.002273, 1.015758, 0.125316, 0.024691, -0.003094, 1.015662, 0.125316, 0.032252, -0.004042, 1.015674, 0.125316, 0.040820, -0.005115, 1.015678, 0.125316, 0.050400, -0.006316, 1.015684, 0.125315, 0.060989, -0.007642, 1.015685, 0.125315, 0.072590, -0.009096, 1.015703, 0.125314, 0.085203, -0.010676, 1.015654, 0.125314, 0.098833, -0.012383, 1.015670, 0.125315, 0.113477, -0.014215, 1.015635, 0.125312, 0.129138, -0.016173, 1.015599, 0.125311, 0.145815, -0.018246, 1.015610, 0.125306, 0.163450, -0.020360, 1.015564, 0.125294, 0.181595, -0.021807, 1.015460, 0.125204, 0.200563, -0.023971, 1.015440, 0.125165, 0.220186, -0.027280, 1.015412, 0.125250, 0.241528, -0.030164, 1.015342, 0.125267, 0.264020, -0.032847, 1.015269, 0.125233, 0.287311, -0.035345, 1.015232, 0.125138, 0.310993, -0.037108, 1.015063, 0.124903, 0.335467, -0.039653, 1.014970, 0.124749, 0.360497, -0.042914, 1.014819, 0.124702, 0.385986, -0.046142, 1.014685, 0.124623, 0.412703, -0.048050, 1.014543, 0.124193, 0.439929, -0.050527, 1.014315, 0.123833, 0.467163, -0.052880, 1.014087, 0.123375, 0.494824, -0.055672, 1.013898, 0.122982, 0.523222, -0.057388, 1.013647, 0.122166, 0.551557, -0.059328, 1.013403, 0.121343, 0.579884, -0.061315, 1.013059, 0.120430, 0.608619, -0.062531, 1.012745, 0.119140, 0.637014, -0.063778, 1.012425, 0.117721, 0.665425, -0.064734, 1.012067, 0.116069, 0.693580, -0.065315, 1.011712, 0.114146, 0.721194, -0.065535, 1.011200, 0.111846, 0.748586, -0.065501, 1.010896, 0.109309, 0.775437, -0.065091, 1.010576, 0.106504, 0.801554, -0.064332, 1.010136, 0.103308, 0.827079, -0.063078, 1.009629, 0.099695, 0.851693, -0.061728, 1.009233, 0.095946, 0.875586, -0.059853, 1.008726, 0.091802, 0.898589, -0.057727, 1.008412, 0.087339, 0.920421, -0.055377, 1.007767, 0.082687, 0.941533, -0.052571, 1.007529, 0.077716, 0.961426, -0.049544, 1.006929, 0.072574, 0.980287, -0.046400, 1.006393, 0.067217, 0.998080, -0.042966, 1.005872, 0.061757, 1.014940, -0.039321, 1.005346, 0.056072, 1.030455, -0.035585, 1.004609, 0.050410, 1.045078, -0.031823, 1.004151, 0.044622, 1.058555, -0.027947, 1.003421, 0.038893, 1.071009, -0.023891, 1.002704, 0.032977, 1.082594, -0.019822, 1.002023, 0.027290, 1.093265, -0.015765, 1.001403, 0.021543, 1.103132, -0.011790, 1.000944, 0.016072, 1.112348, -0.007784, 1.000550, 0.010511, 1.120845, -0.003849, 1.000224, 0.005174, 1.128573, 0.000057, 0.999975, -0.000039, 0.000200, -0.000030, 1.022609, 0.150725, 0.000504, -0.000076, 1.022728, 0.150725, 0.002016, -0.000304, 1.022728, 0.150725, 0.004535, -0.000684, 1.022733, 0.150725, 0.008062, -0.001215, 1.022715, 0.150725, 0.012598, -0.001899, 1.022720, 0.150725, 0.018141, -0.002734, 1.022659, 0.150725, 0.024694, -0.003722, 1.022801, 0.150724, 0.032254, -0.004861, 1.022779, 0.150726, 0.040815, -0.006152, 1.022693, 0.150724, 0.050400, -0.007596, 1.022716, 0.150725, 0.060990, -0.009192, 1.022733, 0.150725, 0.072587, -0.010939, 1.022630, 0.150723, 0.085203, -0.012839, 1.022676, 0.150725, 0.098828, -0.014891, 1.022659, 0.150725, 0.113473, -0.017095, 1.022589, 0.150720, 0.129137, -0.019449, 1.022572, 0.150716, 0.145803, -0.021938, 1.022508, 0.150712, 0.163417, -0.024443, 1.022471, 0.150691, 0.181580, -0.026329, 1.022406, 0.150600, 0.200667, -0.028997, 1.022336, 0.150553, 0.220429, -0.032584, 1.022296, 0.150610, 0.241497, -0.036260, 1.022202, 0.150658, 0.263975, -0.039465, 1.022119, 0.150619, 0.287210, -0.042385, 1.021988, 0.150490, 0.310935, -0.044758, 1.021771, 0.150241, 0.335556, -0.047922, 1.021658, 0.150076, 0.360667, -0.051493, 1.021437, 0.149931, 0.386028, -0.054931, 1.021228, 0.149754, 0.412665, -0.058007, 1.021023, 0.149400, 0.439951, -0.060813, 1.020723, 0.148913, 0.467262, -0.063461, 1.020332, 0.148319, 0.494972, -0.066738, 1.020097, 0.147798, 0.523153, -0.068976, 1.019630, 0.146903, 0.551700, -0.071268, 1.019245, 0.145863, 0.580046, -0.073439, 1.018797, 0.144695, 0.608649, -0.075193, 1.018201, 0.143237, 0.637239, -0.076536, 1.017746, 0.141463, 0.665388, -0.077771, 1.017111, 0.139462, 0.693755, -0.078344, 1.016609, 0.137082, 0.721345, -0.078817, 1.015863, 0.134403, 0.748879, -0.078512, 1.015390, 0.131252, 0.775560, -0.078128, 1.014652, 0.127866, 0.801897, -0.077094, 1.013877, 0.123928, 0.827193, -0.075863, 1.013021, 0.119733, 0.851990, -0.073973, 1.012395, 0.115055, 0.875823, -0.071765, 1.011595, 0.110098, 0.898655, -0.069241, 1.010862, 0.104722, 0.920915, -0.066232, 1.010185, 0.098991, 0.941969, -0.062980, 1.009588, 0.093044, 0.961882, -0.059507, 1.008777, 0.086925, 0.980952, -0.055606, 1.008252, 0.080520, 0.998955, -0.051503, 1.007633, 0.073890, 1.015756, -0.047292, 1.006908, 0.067302, 1.031571, -0.042804, 1.006338, 0.060412, 1.046095, -0.038132, 1.005512, 0.053497, 1.059542, -0.033380, 1.004592, 0.046569, 1.072006, -0.028613, 1.003731, 0.039679, 1.083348, -0.023811, 1.002871, 0.032772, 1.093969, -0.018930, 1.002068, 0.025894, 1.103697, -0.014098, 1.001284, 0.019178, 1.112813, -0.009339, 1.000820, 0.012652, 1.121193, -0.004661, 1.000324, 0.006226, 1.128930, 0.000052, 0.999988, -0.000008, 0.000200, -0.000035, 1.030857, 0.176327, 0.000504, -0.000089, 1.031137, 0.176326, 0.002016, -0.000355, 1.031049, 0.176325, 0.004535, -0.000800, 1.031105, 0.176326, 0.008062, -0.001422, 1.030973, 0.176326, 0.012598, -0.002221, 1.031168, 0.176326, 0.018141, -0.003199, 1.031093, 0.176326, 0.024695, -0.004354, 1.031297, 0.176326, 0.032253, -0.005687, 1.031091, 0.176327, 0.040821, -0.007197, 1.031012, 0.176326, 0.050399, -0.008886, 1.031068, 0.176325, 0.060987, -0.010752, 1.030967, 0.176323, 0.072588, -0.012797, 1.031028, 0.176324, 0.085200, -0.015019, 1.030985, 0.176322, 0.098829, -0.017419, 1.030983, 0.176320, 0.113474, -0.019997, 1.030953, 0.176317, 0.129133, -0.022748, 1.030891, 0.176312, 0.145800, -0.025655, 1.030825, 0.176306, 0.163372, -0.028510, 1.030781, 0.176279, 0.181578, -0.030914, 1.030683, 0.176187, 0.200761, -0.034076, 1.030574, 0.176139, 0.220645, -0.037985, 1.030476, 0.176160, 0.241473, -0.042391, 1.030384, 0.176238, 0.263922, -0.046105, 1.030241, 0.176175, 0.287074, -0.049390, 1.030049, 0.176013, 0.310915, -0.052511, 1.029839, 0.175776, 0.335604, -0.056236, 1.029608, 0.175578, 0.360775, -0.060118, 1.029355, 0.175359, 0.386196, -0.063907, 1.029052, 0.175083, 0.412599, -0.067997, 1.028766, 0.174791, 0.439916, -0.071088, 1.028326, 0.174174, 0.467444, -0.074247, 1.027890, 0.173487, 0.495132, -0.077728, 1.027374, 0.172774, 0.523117, -0.080822, 1.026763, 0.171824, 0.551783, -0.083228, 1.026205, 0.170554, 0.580234, -0.085682, 1.025614, 0.169090, 0.608568, -0.087860, 1.024668, 0.167468, 0.637357, -0.089346, 1.023939, 0.165283, 0.665507, -0.090704, 1.022946, 0.162966, 0.693704, -0.091388, 1.022010, 0.160131, 0.721396, -0.091783, 1.021085, 0.156957, 0.748676, -0.091688, 1.019894, 0.153292, 0.775370, -0.090992, 1.018608, 0.149158, 0.801547, -0.089881, 1.017646, 0.144551, 0.827013, -0.088267, 1.016355, 0.139614, 0.851708, -0.086132, 1.015446, 0.134026, 0.875652, -0.083707, 1.014321, 0.128101, 0.898703, -0.080619, 1.013454, 0.121841, 0.920904, -0.077280, 1.012634, 0.115379, 0.942077, -0.073484, 1.011770, 0.108355, 0.962245, -0.069252, 1.010894, 0.101153, 0.981385, -0.064807, 1.010114, 0.093666, 0.999379, -0.060080, 1.009294, 0.086007, 1.016494, -0.055007, 1.008591, 0.078194, 1.032357, -0.049760, 1.007821, 0.070328, 1.047061, -0.044468, 1.006871, 0.062358, 1.060675, -0.038960, 1.006062, 0.054279, 1.073032, -0.033343, 1.004911, 0.046158, 1.084293, -0.027699, 1.003791, 0.038111, 1.094724, -0.022130, 1.002744, 0.030239, 1.104302, -0.016508, 1.001815, 0.022397, 1.113290, -0.010846, 1.001083, 0.014747, 1.121649, -0.005294, 1.000490, 0.007234, 1.129230, 0.000071, 0.999975, -0.000053, 0.000200, -0.000040, 1.040431, 0.202155, 0.000504, -0.000102, 1.040912, 0.202154, 0.002016, -0.000407, 1.041328, 0.202152, 0.004535, -0.000917, 1.040877, 0.202154, 0.008063, -0.001630, 1.040867, 0.202153, 0.012598, -0.002547, 1.040870, 0.202153, 0.018140, -0.003667, 1.040808, 0.202153, 0.024692, -0.004991, 1.040861, 0.202153, 0.032252, -0.006519, 1.040861, 0.202153, 0.040822, -0.008252, 1.040864, 0.202153, 0.050397, -0.010187, 1.040717, 0.202151, 0.060988, -0.012327, 1.040791, 0.202152, 0.072582, -0.014669, 1.040640, 0.202149, 0.085198, -0.017217, 1.040716, 0.202147, 0.098827, -0.019968, 1.040748, 0.202141, 0.113467, -0.022921, 1.040632, 0.202142, 0.129129, -0.026074, 1.040606, 0.202137, 0.145793, -0.029399, 1.040566, 0.202127, 0.163294, -0.032524, 1.040459, 0.202078, 0.181589, -0.035552, 1.040315, 0.201996, 0.200844, -0.039208, 1.040221, 0.201948, 0.220835, -0.043489, 1.040047, 0.201945, 0.241471, -0.048523, 1.039921, 0.202031, 0.263854, -0.052764, 1.039756, 0.201957, 0.286935, -0.056387, 1.039497, 0.201743, 0.310902, -0.060338, 1.039252, 0.201531, 0.335642, -0.064594, 1.038954, 0.201286, 0.360859, -0.068772, 1.038582, 0.200983, 0.386419, -0.073086, 1.038160, 0.200651, 0.412588, -0.077887, 1.037724, 0.200343, 0.439836, -0.081391, 1.037182, 0.199618, 0.467538, -0.085121, 1.036602, 0.198839, 0.495286, -0.088718, 1.035893, 0.197895, 0.523231, -0.092514, 1.035121, 0.196887, 0.551730, -0.095238, 1.034127, 0.195390, 0.580302, -0.097949, 1.033131, 0.193668, 0.608559, -0.100418, 1.031962, 0.191773, 0.637224, -0.102129, 1.030838, 0.189319, 0.665597, -0.103578, 1.029511, 0.186529, 0.693535, -0.104652, 1.028263, 0.183303, 0.721325, -0.104766, 1.026611, 0.179497, 0.748384, -0.104717, 1.025128, 0.175283, 0.775058, -0.103846, 1.023385, 0.170493, 0.801387, -0.102728, 1.022236, 0.165187, 0.826412, -0.100679, 1.019908, 0.159362, 0.851314, -0.098451, 1.018839, 0.153059, 0.875100, -0.095363, 1.017306, 0.146284, 0.898280, -0.092008, 1.016151, 0.138975, 0.920450, -0.088095, 1.014880, 0.131361, 0.941727, -0.083690, 1.013556, 0.123417, 0.962308, -0.079077, 1.012998, 0.115201, 0.981364, -0.073894, 1.011841, 0.106711, 0.999798, -0.068435, 1.011021, 0.098063, 1.016983, -0.062830, 1.010194, 0.089183, 1.033039, -0.056914, 1.009292, 0.080190, 1.047994, -0.050721, 1.008474, 0.071010, 1.061580, -0.044454, 1.007386, 0.061867, 1.074023, -0.038145, 1.006135, 0.052711, 1.085470, -0.031679, 1.004890, 0.043595, 1.095673, -0.025157, 1.003627, 0.034506, 1.105000, -0.018702, 1.002331, 0.025468, 1.113795, -0.012458, 1.001278, 0.016834, 1.122012, -0.006169, 1.000548, 0.008265, 1.129683, 0.000078, 0.999988, -0.000072, 0.000200, -0.000046, 1.052496, 0.228243, 0.000504, -0.000115, 1.052079, 0.228243, 0.002016, -0.000460, 1.052079, 0.228241, 0.004535, -0.001035, 1.052091, 0.228242, 0.008062, -0.001840, 1.051962, 0.228242, 0.012598, -0.002875, 1.052087, 0.228242, 0.018141, -0.004140, 1.052088, 0.228242, 0.024692, -0.005636, 1.052096, 0.228239, 0.032251, -0.007361, 1.052029, 0.228243, 0.040820, -0.009316, 1.052038, 0.228241, 0.050399, -0.011501, 1.052042, 0.228239, 0.060990, -0.013917, 1.052046, 0.228238, 0.072586, -0.016562, 1.051990, 0.228236, 0.085198, -0.019437, 1.051946, 0.228234, 0.098824, -0.022542, 1.051879, 0.228229, 0.113467, -0.025875, 1.051841, 0.228227, 0.129121, -0.029430, 1.051724, 0.228219, 0.145780, -0.033170, 1.051672, 0.228205, 0.163222, -0.036567, 1.051556, 0.228143, 0.181604, -0.040245, 1.051382, 0.228069, 0.200913, -0.044395, 1.051230, 0.228010, 0.221005, -0.049088, 1.051062, 0.227988, 0.241667, -0.054506, 1.050881, 0.228044, 0.263777, -0.059437, 1.050643, 0.227986, 0.286841, -0.063590, 1.050312, 0.227755, 0.310879, -0.068224, 1.050009, 0.227525, 0.335650, -0.072986, 1.049597, 0.227253, 0.360869, -0.077435, 1.049121, 0.226845, 0.386609, -0.082385, 1.048587, 0.226466, 0.412742, -0.087570, 1.047987, 0.226059, 0.439789, -0.091929, 1.047308, 0.225331, 0.467558, -0.096038, 1.046423, 0.224409, 0.495406, -0.099938, 1.045481, 0.223288, 0.523417, -0.104050, 1.044512, 0.222066, 0.551755, -0.107503, 1.043408, 0.220487, 0.580468, -0.110234, 1.042016, 0.218451, 0.608904, -0.112993, 1.040535, 0.216200, 0.637230, -0.115173, 1.038934, 0.213458, 0.665566, -0.116433, 1.036961, 0.210158, 0.693413, -0.117589, 1.035130, 0.206457, 0.721025, -0.117885, 1.033080, 0.202197, 0.748054, -0.117606, 1.030752, 0.197296, 0.774631, -0.116771, 1.028608, 0.191813, 0.800677, -0.115194, 1.026350, 0.185691, 0.826062, -0.113138, 1.024472, 0.179053, 0.850590, -0.110359, 1.022174, 0.171839, 0.874550, -0.107072, 1.020381, 0.164067, 0.897567, -0.103268, 1.018777, 0.155959, 0.919609, -0.098794, 1.016886, 0.147320, 0.941177, -0.094067, 1.015880, 0.138365, 0.961752, -0.088670, 1.014616, 0.129051, 0.981518, -0.082965, 1.013807, 0.119515, 0.999880, -0.076971, 1.012793, 0.109897, 1.017370, -0.070518, 1.011894, 0.099872, 1.033661, -0.063830, 1.010943, 0.089883, 1.048672, -0.057040, 1.009802, 0.079691, 1.062479, -0.049917, 1.008670, 0.069458, 1.075052, -0.042735, 1.007429, 0.059191, 1.086371, -0.035513, 1.005991, 0.048894, 1.096623, -0.028359, 1.004468, 0.038770, 1.105871, -0.021111, 1.002927, 0.028745, 1.114481, -0.013908, 1.001728, 0.018884, 1.122610, -0.006843, 1.000740, 0.009264, 1.130165, 0.000062, 0.999983, -0.000006, 0.000200, -0.000051, 1.064931, 0.254630, 0.000504, -0.000128, 1.064668, 0.254630, 0.002016, -0.000513, 1.064794, 0.254630, 0.004535, -0.001155, 1.064851, 0.254630, 0.008063, -0.002053, 1.064966, 0.254630, 0.012598, -0.003208, 1.064840, 0.254630, 0.018140, -0.004619, 1.064602, 0.254631, 0.024695, -0.006288, 1.064965, 0.254632, 0.032251, -0.008211, 1.064795, 0.254630, 0.040821, -0.010393, 1.064802, 0.254628, 0.050398, -0.012830, 1.064758, 0.254627, 0.060987, -0.015525, 1.064731, 0.254625, 0.072584, -0.018474, 1.064615, 0.254621, 0.085199, -0.021682, 1.064672, 0.254619, 0.098826, -0.025144, 1.064630, 0.254613, 0.113465, -0.028860, 1.064515, 0.254606, 0.129119, -0.032823, 1.064416, 0.254598, 0.145767, -0.036969, 1.064347, 0.254579, 0.163190, -0.040754, 1.064132, 0.254506, 0.181622, -0.044989, 1.063951, 0.254437, 0.200981, -0.049642, 1.063745, 0.254370, 0.221145, -0.054776, 1.063547, 0.254324, 0.241896, -0.060538, 1.063289, 0.254346, 0.263684, -0.066113, 1.063013, 0.254296, 0.286796, -0.070925, 1.062625, 0.254059, 0.310867, -0.076187, 1.062216, 0.253817, 0.335644, -0.081406, 1.061703, 0.253481, 0.360917, -0.086336, 1.061066, 0.253005, 0.386786, -0.091790, 1.060454, 0.252558, 0.412921, -0.097230, 1.059568, 0.252008, 0.439722, -0.102574, 1.058706, 0.251323, 0.467559, -0.106972, 1.057682, 0.250239, 0.495605, -0.111329, 1.056612, 0.248944, 0.523589, -0.115561, 1.055101, 0.247471, 0.551787, -0.119732, 1.053745, 0.245777, 0.580426, -0.122711, 1.051829, 0.243448, 0.608778, -0.125436, 1.049642, 0.240769, 0.637069, -0.127993, 1.047749, 0.237739, 0.665251, -0.129448, 1.045244, 0.233928, 0.692977, -0.130408, 1.042279, 0.229640, 0.720346, -0.130931, 1.039693, 0.224829, 0.747365, -0.130392, 1.036675, 0.219144, 0.773734, -0.129540, 1.033719, 0.212965, 0.799578, -0.127689, 1.030774, 0.206047, 0.825002, -0.125456, 1.028551, 0.198576, 0.849564, -0.122291, 1.025800, 0.190471, 0.873412, -0.118720, 1.023657, 0.181739, 0.896628, -0.114323, 1.021381, 0.172586, 0.918952, -0.109587, 1.019674, 0.162914, 0.940602, -0.104093, 1.018126, 0.153039, 0.960917, -0.098187, 1.016339, 0.142774, 0.980911, -0.091963, 1.015440, 0.132316, 0.999686, -0.085159, 1.014377, 0.121453, 1.017538, -0.078139, 1.013498, 0.110527, 1.033918, -0.070797, 1.012332, 0.099437, 1.049390, -0.063129, 1.011368, 0.088157, 1.063402, -0.055354, 1.010111, 0.076951, 1.076096, -0.047522, 1.008774, 0.065616, 1.087562, -0.039447, 1.007202, 0.054310, 1.097591, -0.031359, 1.005346, 0.042948, 1.106782, -0.023393, 1.003710, 0.031799, 1.115234, -0.015461, 1.002116, 0.020943, 1.123166, -0.007589, 1.000858, 0.010288, 1.130796, 0.000104, 1.000032, -0.000024, 0.000200, -0.000056, 1.078780, 0.281356, 0.000504, -0.000142, 1.079271, 0.281355, 0.002015, -0.000567, 1.078635, 0.281355, 0.004535, -0.001276, 1.079164, 0.281356, 0.008064, -0.002269, 1.079300, 0.281355, 0.012598, -0.003544, 1.079149, 0.281355, 0.018143, -0.005104, 1.079329, 0.281355, 0.024691, -0.006947, 1.079073, 0.281353, 0.032254, -0.009074, 1.079253, 0.281354, 0.040822, -0.011484, 1.079176, 0.281353, 0.050399, -0.014177, 1.079057, 0.281349, 0.060987, -0.017153, 1.079007, 0.281347, 0.072586, -0.020412, 1.078998, 0.281343, 0.085203, -0.023956, 1.078962, 0.281336, 0.098823, -0.027778, 1.078839, 0.281332, 0.113464, -0.031882, 1.078783, 0.281325, 0.129114, -0.036255, 1.078633, 0.281315, 0.145748, -0.040790, 1.078545, 0.281287, 0.163179, -0.045024, 1.078311, 0.281208, 0.181649, -0.049791, 1.078135, 0.281137, 0.201042, -0.054953, 1.077845, 0.281063, 0.221267, -0.060551, 1.077576, 0.281006, 0.242114, -0.066663, 1.077257, 0.280978, 0.263568, -0.072771, 1.076897, 0.280925, 0.286744, -0.078349, 1.076405, 0.280689, 0.310840, -0.084201, 1.075898, 0.280418, 0.335612, -0.089846, 1.075287, 0.280020, 0.360975, -0.095394, 1.074482, 0.279513, 0.386932, -0.101290, 1.073617, 0.278961, 0.413171, -0.107042, 1.072719, 0.278283, 0.439886, -0.113083, 1.071698, 0.277547, 0.467535, -0.118010, 1.070213, 0.276311, 0.495701, -0.122793, 1.068857, 0.274867, 0.523772, -0.127278, 1.067037, 0.273153, 0.551849, -0.131671, 1.064923, 0.271176, 0.580338, -0.135293, 1.062749, 0.268626, 0.608771, -0.138065, 1.059944, 0.265569, 0.636756, -0.140565, 1.056851, 0.262054, 0.664574, -0.142434, 1.053461, 0.257807, 0.692151, -0.143237, 1.049910, 0.252930, 0.719376, -0.143717, 1.046426, 0.247414, 0.745852, -0.143117, 1.042377, 0.241001, 0.772300, -0.141975, 1.038789, 0.233797, 0.798050, -0.140114, 1.035290, 0.226218, 0.823370, -0.137379, 1.032374, 0.217785, 0.847735, -0.134119, 1.028853, 0.208748, 0.871897, -0.129985, 1.026395, 0.198877, 0.894950, -0.125324, 1.023787, 0.188803, 0.917909, -0.120007, 1.022073, 0.178493, 0.939567, -0.114099, 1.020098, 0.167466, 0.960534, -0.107748, 1.018851, 0.156223, 0.980423, -0.100748, 1.017362, 0.144716, 0.999334, -0.093494, 1.015961, 0.133028, 1.017561, -0.085728, 1.015059, 0.120953, 1.034225, -0.077627, 1.013888, 0.108943, 1.049937, -0.069375, 1.012898, 0.096678, 1.064265, -0.060807, 1.011635, 0.084350, 1.077188, -0.052052, 1.010095, 0.071964, 1.088637, -0.043304, 1.008399, 0.059531, 1.098766, -0.034458, 1.006397, 0.047134, 1.107697, -0.025637, 1.004354, 0.034887, 1.116055, -0.016932, 1.002611, 0.022948, 1.123819, -0.008437, 1.001023, 0.011386, 1.131333, 0.000087, 0.999952, -0.000097, 0.000200, -0.000062, 1.095622, 0.308458, 0.000504, -0.000155, 1.094863, 0.308458, 0.002016, -0.000622, 1.095169, 0.308458, 0.004535, -0.001399, 1.095156, 0.308458, 0.008063, -0.002487, 1.095413, 0.308455, 0.012598, -0.003886, 1.095147, 0.308458, 0.018141, -0.005596, 1.095150, 0.308457, 0.024692, -0.007616, 1.095140, 0.308457, 0.032252, -0.009947, 1.095098, 0.308456, 0.040822, -0.012589, 1.095096, 0.308453, 0.050399, -0.015541, 1.095070, 0.308451, 0.060985, -0.018803, 1.094922, 0.308448, 0.072583, -0.022375, 1.094902, 0.308444, 0.085197, -0.026258, 1.094882, 0.308438, 0.098822, -0.030448, 1.094775, 0.308429, 0.113460, -0.034944, 1.094641, 0.308419, 0.129112, -0.039731, 1.094530, 0.308403, 0.145711, -0.044610, 1.094332, 0.308365, 0.163178, -0.049362, 1.094149, 0.308285, 0.181679, -0.054666, 1.093876, 0.308210, 0.201109, -0.060336, 1.093603, 0.308132, 0.221388, -0.066414, 1.093250, 0.308047, 0.242315, -0.072881, 1.092835, 0.307985, 0.263651, -0.079453, 1.092391, 0.307902, 0.286720, -0.085882, 1.091866, 0.307688, 0.310817, -0.092274, 1.091225, 0.307379, 0.335562, -0.098306, 1.090346, 0.306906, 0.361043, -0.104572, 1.089423, 0.306374, 0.387051, -0.110843, 1.088437, 0.305710, 0.413405, -0.117062, 1.087228, 0.304906, 0.440122, -0.123501, 1.085879, 0.304017, 0.467522, -0.129245, 1.084197, 0.302783, 0.495721, -0.134285, 1.082284, 0.301104, 0.523925, -0.139143, 1.080109, 0.299142, 0.551814, -0.143638, 1.077043, 0.296825, 0.579878, -0.147774, 1.074071, 0.294071, 0.608316, -0.150724, 1.070621, 0.290519, 0.636059, -0.153168, 1.066390, 0.286424, 0.663481, -0.155139, 1.062069, 0.281559, 0.690753, -0.155944, 1.057211, 0.276024, 0.717767, -0.156176, 1.052682, 0.269622, 0.743937, -0.155783, 1.047747, 0.262532, 0.770214, -0.154245, 1.043510, 0.254609, 0.795542, -0.152192, 1.039121, 0.246007, 0.821099, -0.149256, 1.035962, 0.236663, 0.845452, -0.145605, 1.032320, 0.226751, 0.869780, -0.141186, 1.029390, 0.216165, 0.893141, -0.136137, 1.026485, 0.204937, 0.916034, -0.130332, 1.024389, 0.193624, 0.938089, -0.124040, 1.022270, 0.181756, 0.959488, -0.117011, 1.020457, 0.169339, 0.979594, -0.109617, 1.018871, 0.156875, 0.998912, -0.101562, 1.017533, 0.144288, 1.017100, -0.093164, 1.016445, 0.131370, 1.034413, -0.084488, 1.015453, 0.118322, 1.050347, -0.075377, 1.014259, 0.104963, 1.064958, -0.066108, 1.013057, 0.091722, 1.078045, -0.056702, 1.011491, 0.078231, 1.089749, -0.047106, 1.009662, 0.064797, 1.099831, -0.037467, 1.007417, 0.051315, 1.108789, -0.027990, 1.005144, 0.038064, 1.116865, -0.018464, 1.002925, 0.025008, 1.124609, -0.009068, 1.001221, 0.012250, 1.132040, 0.000093, 0.999984, -0.000071, 0.000200, -0.000067, 1.112554, 0.335981, 0.000504, -0.000169, 1.112660, 0.335981, 0.002016, -0.000677, 1.112827, 0.335981, 0.004533, -0.001523, 1.112147, 0.335982, 0.008063, -0.002709, 1.112882, 0.335979, 0.012598, -0.004233, 1.112891, 0.335980, 0.018141, -0.006095, 1.112882, 0.335980, 0.024693, -0.008296, 1.112877, 0.335978, 0.032252, -0.010834, 1.112860, 0.335976, 0.040824, -0.013713, 1.112965, 0.335974, 0.050398, -0.016927, 1.112753, 0.335971, 0.060991, -0.020482, 1.112826, 0.335970, 0.072587, -0.024371, 1.112676, 0.335962, 0.085199, -0.028597, 1.112593, 0.335955, 0.098822, -0.033159, 1.112453, 0.335943, 0.113461, -0.038052, 1.112329, 0.335930, 0.129108, -0.043255, 1.112144, 0.335910, 0.145665, -0.048412, 1.111905, 0.335857, 0.163185, -0.053786, 1.111668, 0.335781, 0.181710, -0.059608, 1.111345, 0.335696, 0.201166, -0.065794, 1.110979, 0.335606, 0.221489, -0.072361, 1.110553, 0.335505, 0.242471, -0.079184, 1.110112, 0.335396, 0.263900, -0.086213, 1.109584, 0.335271, 0.286688, -0.093491, 1.108927, 0.335089, 0.310773, -0.100406, 1.108091, 0.334737, 0.335573, -0.106987, 1.107169, 0.334208, 0.361117, -0.113844, 1.106097, 0.333600, 0.387175, -0.120463, 1.104826, 0.332828, 0.413665, -0.127245, 1.103415, 0.331929, 0.440386, -0.133927, 1.101632, 0.330851, 0.467527, -0.140496, 1.099563, 0.329538, 0.495630, -0.145874, 1.096956, 0.327618, 0.523864, -0.150997, 1.094201, 0.325390, 0.551705, -0.155713, 1.090342, 0.322688, 0.579383, -0.159993, 1.086010, 0.319483, 0.607301, -0.163238, 1.081226, 0.315522, 0.634873, -0.165667, 1.076065, 0.310840, 0.662028, -0.167606, 1.070466, 0.305377, 0.688755, -0.168626, 1.064601, 0.299056, 0.715612, -0.168578, 1.059269, 0.291963, 0.741604, -0.167961, 1.053648, 0.284018, 0.767757, -0.166439, 1.048928, 0.275474, 0.793264, -0.164023, 1.044343, 0.266056, 0.818165, -0.160965, 1.039909, 0.255750, 0.843255, -0.156896, 1.036180, 0.244843, 0.867249, -0.152262, 1.032303, 0.233464, 0.890994, -0.146655, 1.029365, 0.221128, 0.913829, -0.140574, 1.026607, 0.208554, 0.936508, -0.133640, 1.024512, 0.195772, 0.957720, -0.126220, 1.022421, 0.182420, 0.978940, -0.118164, 1.021293, 0.168852, 0.998285, -0.109558, 1.019444, 0.155261, 1.016764, -0.100562, 1.017825, 0.141395, 1.034387, -0.091064, 1.016996, 0.127311, 1.050916, -0.081468, 1.015945, 0.113089, 1.065652, -0.071463, 1.014547, 0.098879, 1.079155, -0.061240, 1.013066, 0.084468, 1.090822, -0.050980, 1.010788, 0.069940, 1.101100, -0.040549, 1.008563, 0.055475, 1.109824, -0.030101, 1.005950, 0.041033, 1.117828, -0.019884, 1.003453, 0.027022, 1.125443, -0.009900, 1.001484, 0.013306, 1.132869, 0.000094, 1.000004, -0.000046, 0.000200, -0.000073, 1.132849, 0.363970, 0.000504, -0.000183, 1.132155, 0.363969, 0.002016, -0.000734, 1.132516, 0.363969, 0.004535, -0.001651, 1.132256, 0.363969, 0.008062, -0.002934, 1.132318, 0.363966, 0.012597, -0.004585, 1.132386, 0.363968, 0.018141, -0.006602, 1.132457, 0.363967, 0.024693, -0.008987, 1.132511, 0.363967, 0.032252, -0.011737, 1.132488, 0.363965, 0.040819, -0.014853, 1.132241, 0.363959, 0.050398, -0.018336, 1.132372, 0.363958, 0.060988, -0.022185, 1.132373, 0.363954, 0.072582, -0.026396, 1.132137, 0.363943, 0.085195, -0.030973, 1.132071, 0.363935, 0.098822, -0.035913, 1.131978, 0.363922, 0.113461, -0.041209, 1.131801, 0.363905, 0.129116, -0.046833, 1.131535, 0.363867, 0.145640, -0.052346, 1.131290, 0.363814, 0.163199, -0.058275, 1.131046, 0.363734, 0.181742, -0.064623, 1.130671, 0.363642, 0.201227, -0.071336, 1.130224, 0.363539, 0.221587, -0.078396, 1.129758, 0.363419, 0.242625, -0.085545, 1.129213, 0.363256, 0.264183, -0.093110, 1.128549, 0.363097, 0.286668, -0.101206, 1.127767, 0.362939, 0.310745, -0.108586, 1.126796, 0.362516, 0.335602, -0.115827, 1.125686, 0.361953, 0.361202, -0.123212, 1.124451, 0.361275, 0.387298, -0.130294, 1.122861, 0.360376, 0.413918, -0.137553, 1.121154, 0.359362, 0.440680, -0.144577, 1.118825, 0.358069, 0.467667, -0.151558, 1.116002, 0.356581, 0.495449, -0.157621, 1.112778, 0.354531, 0.523514, -0.162844, 1.108842, 0.351915, 0.551250, -0.167744, 1.104075, 0.348797, 0.578629, -0.172132, 1.098733, 0.345222, 0.605757, -0.175733, 1.092224, 0.340665, 0.633392, -0.178109, 1.086201, 0.335286, 0.660783, -0.180009, 1.080110, 0.329286, 0.687219, -0.181105, 1.073419, 0.322319, 0.713873, -0.181046, 1.067410, 0.314616, 0.740094, -0.180219, 1.061414, 0.306014, 0.765233, -0.178559, 1.055287, 0.296704, 0.790885, -0.175806, 1.049727, 0.286394, 0.815464, -0.172354, 1.044519, 0.275189, 0.840259, -0.168048, 1.040375, 0.263441, 0.864285, -0.162904, 1.036010, 0.250918, 0.888806, -0.157194, 1.033525, 0.237611, 0.911682, -0.150486, 1.029490, 0.223809, 0.934481, -0.143212, 1.026778, 0.209705, 0.956337, -0.135233, 1.024632, 0.195281, 0.977380, -0.126650, 1.022737, 0.180878, 0.997427, -0.117552, 1.021110, 0.166112, 1.016666, -0.107814, 1.019869, 0.151231, 1.034337, -0.097814, 1.018543, 0.136375, 1.051082, -0.087330, 1.017476, 0.121187, 1.066326, -0.076614, 1.016083, 0.106043, 1.079897, -0.065793, 1.014227, 0.090566, 1.092136, -0.054654, 1.012334, 0.074988, 1.102315, -0.043516, 1.009627, 0.059577, 1.111105, -0.032509, 1.006808, 0.044202, 1.118861, -0.021381, 1.003917, 0.028995, 1.126363, -0.010489, 1.001670, 0.014269, 1.133598, 0.000083, 0.999989, -0.000035, 0.000200, -0.000079, 1.155026, 0.392470, 0.000504, -0.000198, 1.154184, 0.392469, 0.002016, -0.000791, 1.153990, 0.392469, 0.004535, -0.001780, 1.154045, 0.392469, 0.008063, -0.003164, 1.154007, 0.392466, 0.012598, -0.004944, 1.154022, 0.392469, 0.018141, -0.007119, 1.154015, 0.392468, 0.024692, -0.009690, 1.154017, 0.392466, 0.032254, -0.012656, 1.154069, 0.392465, 0.040826, -0.016018, 1.153980, 0.392459, 0.050399, -0.019771, 1.153911, 0.392456, 0.060987, -0.023919, 1.153860, 0.392447, 0.072588, -0.028461, 1.153777, 0.392442, 0.085197, -0.033393, 1.153582, 0.392428, 0.098822, -0.038716, 1.153434, 0.392412, 0.113462, -0.044422, 1.153271, 0.392390, 0.129101, -0.050455, 1.153019, 0.392359, 0.145642, -0.056392, 1.152721, 0.392283, 0.163223, -0.062859, 1.152404, 0.392201, 0.181779, -0.069721, 1.151941, 0.392099, 0.201289, -0.076968, 1.151422, 0.391978, 0.221678, -0.084518, 1.150861, 0.391833, 0.242752, -0.092017, 1.150156, 0.391618, 0.264474, -0.100184, 1.149402, 0.391421, 0.286768, -0.108921, 1.148545, 0.391249, 0.310719, -0.116815, 1.147388, 0.390773, 0.335638, -0.124785, 1.146042, 0.390168, 0.361240, -0.132630, 1.144529, 0.389394, 0.387443, -0.140298, 1.142602, 0.388391, 0.414067, -0.147913, 1.140361, 0.387199, 0.440904, -0.155362, 1.137612, 0.385742, 0.467771, -0.162574, 1.133659, 0.383926, 0.494907, -0.169312, 1.129246, 0.381715, 0.522801, -0.174778, 1.124228, 0.378678, 0.550751, -0.179824, 1.118697, 0.375158, 0.578018, -0.184284, 1.112019, 0.370851, 0.605291, -0.188215, 1.105151, 0.365928, 0.632269, -0.190760, 1.097677, 0.360114, 0.659432, -0.192457, 1.090816, 0.353498, 0.685839, -0.193458, 1.083286, 0.346094, 0.711876, -0.193502, 1.076245, 0.337754, 0.738184, -0.192371, 1.069684, 0.328412, 0.763723, -0.190531, 1.063249, 0.318164, 0.789192, -0.187726, 1.057265, 0.306900, 0.813744, -0.183783, 1.051177, 0.295021, 0.838408, -0.179328, 1.045902, 0.282144, 0.862116, -0.173573, 1.040853, 0.268438, 0.885636, -0.167350, 1.036515, 0.254108, 0.909342, -0.160229, 1.033269, 0.239082, 0.931962, -0.152529, 1.029627, 0.224024, 0.954671, -0.144080, 1.027507, 0.208393, 0.975707, -0.135023, 1.024657, 0.192630, 0.996644, -0.125258, 1.022998, 0.176741, 1.015817, -0.115089, 1.021234, 0.160926, 1.034301, -0.104317, 1.020025, 0.145042, 1.051131, -0.093218, 1.018739, 0.129052, 1.066836, -0.081828, 1.017419, 0.112905, 1.081027, -0.070132, 1.015714, 0.096578, 1.093225, -0.058382, 1.013465, 0.080077, 1.103691, -0.046527, 1.010853, 0.063580, 1.112431, -0.034624, 1.007702, 0.047118, 1.120035, -0.022913, 1.004551, 0.031018, 1.127336, -0.011284, 1.001924, 0.015283, 1.134510, 0.000170, 0.999937, -0.000058, 0.000200, -0.000084, 1.177044, 0.421534, 0.000504, -0.000212, 1.177312, 0.421533, 0.002016, -0.000850, 1.177730, 0.421533, 0.004535, -0.001912, 1.177722, 0.421533, 0.008063, -0.003399, 1.177844, 0.421529, 0.012598, -0.005310, 1.177768, 0.421533, 0.018141, -0.007646, 1.177730, 0.421531, 0.024692, -0.010407, 1.177663, 0.421530, 0.032252, -0.013592, 1.177681, 0.421527, 0.040821, -0.017201, 1.177562, 0.421524, 0.050401, -0.021234, 1.177445, 0.421516, 0.060988, -0.025688, 1.177461, 0.421509, 0.072590, -0.030565, 1.177364, 0.421498, 0.085200, -0.035860, 1.177205, 0.421482, 0.098823, -0.041572, 1.177011, 0.421462, 0.113465, -0.047694, 1.176794, 0.421436, 0.129094, -0.054122, 1.176504, 0.421396, 0.145652, -0.060530, 1.176203, 0.421311, 0.163245, -0.067517, 1.175805, 0.421218, 0.181825, -0.074919, 1.175271, 0.421108, 0.201360, -0.082700, 1.174717, 0.420974, 0.221773, -0.090727, 1.174021, 0.420795, 0.242908, -0.098719, 1.173173, 0.420536, 0.264742, -0.107417, 1.172285, 0.420296, 0.287091, -0.116601, 1.171326, 0.420065, 0.310723, -0.125265, 1.169907, 0.419582, 0.335685, -0.133876, 1.168352, 0.418912, 0.361285, -0.142140, 1.166322, 0.418006, 0.387562, -0.150436, 1.164136, 0.416899, 0.414175, -0.158388, 1.161162, 0.415513, 0.441021, -0.166258, 1.157608, 0.413836, 0.467698, -0.173720, 1.152519, 0.411702, 0.494730, -0.180843, 1.147020, 0.409102, 0.522524, -0.186906, 1.141256, 0.405789, 0.550055, -0.192004, 1.134114, 0.401759, 0.577512, -0.196588, 1.127086, 0.397153, 0.604348, -0.200420, 1.119029, 0.391767, 0.630970, -0.203320, 1.110308, 0.385573, 0.658023, -0.204883, 1.102643, 0.378245, 0.684422, -0.205716, 1.094573, 0.370191, 0.710405, -0.205767, 1.086405, 0.361231, 0.736417, -0.204513, 1.078712, 0.351106, 0.761836, -0.202281, 1.071619, 0.340096, 0.787140, -0.199395, 1.064873, 0.328139, 0.812197, -0.195185, 1.058313, 0.315044, 0.836342, -0.190191, 1.052085, 0.300933, 0.860311, -0.184343, 1.046705, 0.286411, 0.883597, -0.177415, 1.041072, 0.270897, 0.906852, -0.170003, 1.036797, 0.254825, 0.929991, -0.161592, 1.033264, 0.238176, 0.952478, -0.152792, 1.030250, 0.221581, 0.974216, -0.143032, 1.027331, 0.204378, 0.995372, -0.132922, 1.025135, 0.187470, 1.015330, -0.122009, 1.023250, 0.170538, 1.034070, -0.110740, 1.022021, 0.153777, 1.051295, -0.099016, 1.020271, 0.136916, 1.067460, -0.086920, 1.018948, 0.119880, 1.082022, -0.074729, 1.017336, 0.102565, 1.094378, -0.062036, 1.014820, 0.084994, 1.104998, -0.049413, 1.011999, 0.067650, 1.113773, -0.036812, 1.008711, 0.050148, 1.121263, -0.024274, 1.005141, 0.032976, 1.128420, -0.012038, 1.002196, 0.016239, 1.135496, 0.000106, 1.000042, -0.000062, 0.000200, -0.000090, 1.203048, 0.451217, 0.000504, -0.000227, 1.203226, 0.451215, 0.002016, -0.000909, 1.203450, 0.451215, 0.004535, -0.002046, 1.203569, 0.451215, 0.008062, -0.003638, 1.203609, 0.451209, 0.012598, -0.005684, 1.203580, 0.451214, 0.018141, -0.008185, 1.203515, 0.451212, 0.024694, -0.011141, 1.203618, 0.451211, 0.032253, -0.014549, 1.203609, 0.451207, 0.040815, -0.018409, 1.203302, 0.451203, 0.050401, -0.022727, 1.203454, 0.451195, 0.060990, -0.027495, 1.203480, 0.451188, 0.072591, -0.032713, 1.203220, 0.451172, 0.085203, -0.038378, 1.203058, 0.451154, 0.098829, -0.044489, 1.202838, 0.451130, 0.113466, -0.051031, 1.202530, 0.451098, 0.129084, -0.057808, 1.202270, 0.451041, 0.145669, -0.064769, 1.201904, 0.450956, 0.163278, -0.072278, 1.201411, 0.450853, 0.181880, -0.080224, 1.200825, 0.450721, 0.201436, -0.088537, 1.200164, 0.450566, 0.221865, -0.097009, 1.199335, 0.450351, 0.243083, -0.105591, 1.198383, 0.450062, 0.265033, -0.114818, 1.197380, 0.449769, 0.287456, -0.124372, 1.196137, 0.449438, 0.310758, -0.133892, 1.194554, 0.448974, 0.335721, -0.143052, 1.192649, 0.448216, 0.361348, -0.151868, 1.190233, 0.447202, 0.387573, -0.160644, 1.187211, 0.445926, 0.414159, -0.169028, 1.183452, 0.444313, 0.440950, -0.177169, 1.178562, 0.442315, 0.467998, -0.185090, 1.173540, 0.439960, 0.494566, -0.192396, 1.166344, 0.436989, 0.521730, -0.198915, 1.159283, 0.433439, 0.549405, -0.204240, 1.151503, 0.428984, 0.576755, -0.208861, 1.143004, 0.423839, 0.603635, -0.212734, 1.134099, 0.418012, 0.629979, -0.215712, 1.124555, 0.411445, 0.656597, -0.217385, 1.115293, 0.403628, 0.683317, -0.218093, 1.106460, 0.394639, 0.708990, -0.217835, 1.097389, 0.385012, 0.734898, -0.216774, 1.088940, 0.373999, 0.760342, -0.214120, 1.080385, 0.362128, 0.785517, -0.210821, 1.072959, 0.349184, 0.809933, -0.206443, 1.065450, 0.335080, 0.834339, -0.200942, 1.058701, 0.320257, 0.858793, -0.194938, 1.052711, 0.304133, 0.882300, -0.187615, 1.047044, 0.287771, 0.905560, -0.179626, 1.042083, 0.270571, 0.927916, -0.170753, 1.037077, 0.252741, 0.950415, -0.161270, 1.033200, 0.234656, 0.972920, -0.151239, 1.030418, 0.216652, 0.993893, -0.140358, 1.027479, 0.198252, 1.014204, -0.128963, 1.024897, 0.180113, 1.033878, -0.117128, 1.023648, 0.162282, 1.051754, -0.104678, 1.022230, 0.144366, 1.067924, -0.092000, 1.020453, 0.126455, 1.082643, -0.078837, 1.018518, 0.108194, 1.095503, -0.065669, 1.016199, 0.089966, 1.106290, -0.052345, 1.013113, 0.071530, 1.115219, -0.039024, 1.009636, 0.053158, 1.122587, -0.025789, 1.005801, 0.034959, 1.129461, -0.012622, 1.002442, 0.017222, 1.136468, 0.000152, 0.999964, -0.000065, 0.000200, -0.000096, 1.231156, 0.481574, 0.000504, -0.000243, 1.232187, 0.481572, 0.002016, -0.000971, 1.231948, 0.481572, 0.004535, -0.002184, 1.231919, 0.481572, 0.008061, -0.003882, 1.231453, 0.481566, 0.012597, -0.006066, 1.231800, 0.481572, 0.018142, -0.008736, 1.231756, 0.481569, 0.024693, -0.011889, 1.232062, 0.481570, 0.032254, -0.015528, 1.231915, 0.481563, 0.040822, -0.019650, 1.231863, 0.481559, 0.050402, -0.024255, 1.231737, 0.481550, 0.060992, -0.029342, 1.231678, 0.481537, 0.072592, -0.034908, 1.231537, 0.481521, 0.085207, -0.040953, 1.231336, 0.481499, 0.098834, -0.047469, 1.231071, 0.481469, 0.113474, -0.054441, 1.230757, 0.481431, 0.129077, -0.061556, 1.230424, 0.481359, 0.145691, -0.069091, 1.230022, 0.481269, 0.163321, -0.077151, 1.229461, 0.481156, 0.181936, -0.085636, 1.228718, 0.481011, 0.201516, -0.094484, 1.228023, 0.480830, 0.221963, -0.103362, 1.227057, 0.480562, 0.243264, -0.112628, 1.225997, 0.480247, 0.265291, -0.122366, 1.224744, 0.479891, 0.287824, -0.132256, 1.223255, 0.479461, 0.310927, -0.142614, 1.221348, 0.478978, 0.335749, -0.152326, 1.218953, 0.478132, 0.361361, -0.161747, 1.215806, 0.476971, 0.387480, -0.170879, 1.211853, 0.475477, 0.414231, -0.179865, 1.207783, 0.473686, 0.441065, -0.188331, 1.202051, 0.471415, 0.467923, -0.196454, 1.195463, 0.468647, 0.494526, -0.204048, 1.187542, 0.465459, 0.521318, -0.211020, 1.179235, 0.461650, 0.548654, -0.216520, 1.170110, 0.456868, 0.575778, -0.221098, 1.160163, 0.451227, 0.602610, -0.224923, 1.149751, 0.444866, 0.628891, -0.227895, 1.139169, 0.437577, 0.655635, -0.230020, 1.129736, 0.429369, 0.682115, -0.230419, 1.119516, 0.419673, 0.707514, -0.229789, 1.108277, 0.409143, 0.733169, -0.228520, 1.099159, 0.397296, 0.758342, -0.225793, 1.089839, 0.384578, 0.783477, -0.222049, 1.081428, 0.370323, 0.808497, -0.217562, 1.073742, 0.355253, 0.832790, -0.211697, 1.065850, 0.339282, 0.856677, -0.204989, 1.058834, 0.322181, 0.880662, -0.197653, 1.053291, 0.304610, 0.903474, -0.188858, 1.046822, 0.286042, 0.926313, -0.179746, 1.041663, 0.267224, 0.948458, -0.169542, 1.036532, 0.247978, 0.970873, -0.159005, 1.033008, 0.228535, 0.992958, -0.147658, 1.029844, 0.208819, 1.013413, -0.135771, 1.026930, 0.189486, 1.033483, -0.123256, 1.025545, 0.170422, 1.051872, -0.110401, 1.023935, 0.152075, 1.068396, -0.096860, 1.022092, 0.133169, 1.083731, -0.083259, 1.020221, 0.114022, 1.096849, -0.069266, 1.017663, 0.094772, 1.107864, -0.055203, 1.014524, 0.075432, 1.116600, -0.041097, 1.010514, 0.055980, 1.123871, -0.027083, 1.006313, 0.036839, 1.130718, -0.013510, 1.002778, 0.018156, 1.137649, 0.000154, 1.000033, -0.000028, 0.000200, -0.000103, 1.264025, 0.512670, 0.000504, -0.000258, 1.262437, 0.512667, 0.002016, -0.001033, 1.262691, 0.512668, 0.004535, -0.002325, 1.262834, 0.512667, 0.008063, -0.004133, 1.262783, 0.512659, 0.012598, -0.006458, 1.262803, 0.512666, 0.018141, -0.009299, 1.262720, 0.512665, 0.024683, -0.012652, 1.262061, 0.512655, 0.032257, -0.016532, 1.262858, 0.512656, 0.040826, -0.020919, 1.262709, 0.512649, 0.050403, -0.025820, 1.262685, 0.512639, 0.060993, -0.031233, 1.262544, 0.512625, 0.072597, -0.037157, 1.262435, 0.512607, 0.085211, -0.043587, 1.262209, 0.512581, 0.098842, -0.050520, 1.261907, 0.512544, 0.113484, -0.057926, 1.261575, 0.512500, 0.129097, -0.065460, 1.261293, 0.512420, 0.145727, -0.073543, 1.260736, 0.512316, 0.163375, -0.082134, 1.260117, 0.512190, 0.182011, -0.091173, 1.259299, 0.512024, 0.201598, -0.100540, 1.258381, 0.511810, 0.222084, -0.109931, 1.257293, 0.511505, 0.243446, -0.119838, 1.256050, 0.511151, 0.265574, -0.130090, 1.254607, 0.510724, 0.288230, -0.140421, 1.252808, 0.510191, 0.311336, -0.151343, 1.250489, 0.509627, 0.335719, -0.161689, 1.247279, 0.508688, 0.361314, -0.171748, 1.243467, 0.507393, 0.387541, -0.181399, 1.239145, 0.505758, 0.414204, -0.190768, 1.233760, 0.503676, 0.441092, -0.199659, 1.227433, 0.501129, 0.467789, -0.207934, 1.219247, 0.498078, 0.494454, -0.215747, 1.210441, 0.494630, 0.520950, -0.222869, 1.200559, 0.490467, 0.547802, -0.228881, 1.189872, 0.485444, 0.575563, -0.233760, 1.180081, 0.479268, 0.602426, -0.237566, 1.168544, 0.472272, 0.628772, -0.240447, 1.156546, 0.464390, 0.654963, -0.242427, 1.145123, 0.455345, 0.681384, -0.242980, 1.134322, 0.444885, 0.707173, -0.242150, 1.122665, 0.433338, 0.732477, -0.240435, 1.111733, 0.420647, 0.757567, -0.237806, 1.101271, 0.406799, 0.782341, -0.233503, 1.091341, 0.391761, 0.806690, -0.228346, 1.082042, 0.375576, 0.830804, -0.222386, 1.073504, 0.358545, 0.854940, -0.215141, 1.065880, 0.340431, 0.878709, -0.207207, 1.058850, 0.321690, 0.901928, -0.198273, 1.052588, 0.301930, 0.924845, -0.188476, 1.046521, 0.281513, 0.946932, -0.177996, 1.040966, 0.261234, 0.969256, -0.166644, 1.036670, 0.240356, 0.991323, -0.154968, 1.032694, 0.219748, 1.013013, -0.142425, 1.030061, 0.199103, 1.032845, -0.129456, 1.027254, 0.178936, 1.051887, -0.115763, 1.025497, 0.159243, 1.069179, -0.101851, 1.023807, 0.139560, 1.084499, -0.087357, 1.021441, 0.119607, 1.097921, -0.072796, 1.018780, 0.099501, 1.109281, -0.058037, 1.015566, 0.079211, 1.118194, -0.043226, 1.011494, 0.058873, 1.125351, -0.028633, 1.007089, 0.038736, 1.132002, -0.013996, 1.003014, 0.019063, 1.138951, 0.000132, 1.000036, -0.000007, 0.000200, -0.000109, 1.296791, 0.544571, 0.000504, -0.000274, 1.296055, 0.544568, 0.002016, -0.001098, 1.297239, 0.544568, 0.004535, -0.002470, 1.296600, 0.544568, 0.008062, -0.004390, 1.296368, 0.544559, 0.012597, -0.006860, 1.296454, 0.544566, 0.018141, -0.009878, 1.296522, 0.544565, 0.024693, -0.013444, 1.296536, 0.544560, 0.032256, -0.017559, 1.296638, 0.544557, 0.040824, -0.022218, 1.296491, 0.544547, 0.050408, -0.027426, 1.296552, 0.544532, 0.060997, -0.033173, 1.296283, 0.544518, 0.072600, -0.039463, 1.296113, 0.544496, 0.085220, -0.046292, 1.295894, 0.544466, 0.098851, -0.053648, 1.295545, 0.544422, 0.113496, -0.061487, 1.295201, 0.544371, 0.129112, -0.069467, 1.294754, 0.544273, 0.145765, -0.078092, 1.294209, 0.544160, 0.163431, -0.087231, 1.293534, 0.544017, 0.182088, -0.096837, 1.292580, 0.543828, 0.201698, -0.106713, 1.291586, 0.543585, 0.222231, -0.116699, 1.290325, 0.543238, 0.243653, -0.127208, 1.288888, 0.542836, 0.265855, -0.137949, 1.287131, 0.542329, 0.288623, -0.148847, 1.284936, 0.541700, 0.311830, -0.160204, 1.282109, 0.540997, 0.335728, -0.171324, 1.278036, 0.540045, 0.361403, -0.181915, 1.273912, 0.538603, 0.387647, -0.192124, 1.268881, 0.536741, 0.414217, -0.201807, 1.262363, 0.534432, 0.441090, -0.211093, 1.254755, 0.531623, 0.467823, -0.219678, 1.245456, 0.528314, 0.494361, -0.227581, 1.234953, 0.524391, 0.521264, -0.235087, 1.224839, 0.519902, 0.547881, -0.241508, 1.213175, 0.514574, 0.574965, -0.246315, 1.200505, 0.507837, 0.601847, -0.250061, 1.187901, 0.500286, 0.628207, -0.252822, 1.174601, 0.491502, 0.654445, -0.254691, 1.161944, 0.481726, 0.680175, -0.255318, 1.149305, 0.470727, 0.706168, -0.254257, 1.136708, 0.458045, 0.731458, -0.252100, 1.124047, 0.444438, 0.756378, -0.249115, 1.112942, 0.429611, 0.781311, -0.244899, 1.101800, 0.413501, 0.805755, -0.239225, 1.091662, 0.395889, 0.829867, -0.232830, 1.082291, 0.377860, 0.853067, -0.225193, 1.072820, 0.358704, 0.877084, -0.216648, 1.065415, 0.338413, 0.900123, -0.207390, 1.058403, 0.317596, 0.923370, -0.197095, 1.051412, 0.296301, 0.946021, -0.186084, 1.045877, 0.274498, 0.967669, -0.174262, 1.040316, 0.252565, 0.989761, -0.161814, 1.035489, 0.230312, 1.012163, -0.149076, 1.032540, 0.208746, 1.032547, -0.135299, 1.029598, 0.187180, 1.052032, -0.121277, 1.027355, 0.166482, 1.069907, -0.106582, 1.025622, 0.145939, 1.085563, -0.091589, 1.023244, 0.125362, 1.099447, -0.076263, 1.020661, 0.104087, 1.110848, -0.060825, 1.017035, 0.083036, 1.119923, -0.045319, 1.012675, 0.061719, 1.126805, -0.029852, 1.007668, 0.040583, 1.133282, -0.014846, 1.003335, 0.019969, 1.140128, 0.000149, 1.000024, -0.000037, 0.000200, -0.000116, 1.334863, 0.577350, 0.000504, -0.000291, 1.333350, 0.577348, 0.002015, -0.001164, 1.332853, 0.577347, 0.004535, -0.002618, 1.333295, 0.577347, 0.008062, -0.004655, 1.333189, 0.577336, 0.012598, -0.007273, 1.333309, 0.577345, 0.018141, -0.010472, 1.333274, 0.577342, 0.024694, -0.014253, 1.333231, 0.577339, 0.032254, -0.018614, 1.333265, 0.577332, 0.040827, -0.023556, 1.333261, 0.577321, 0.050400, -0.029069, 1.332893, 0.577309, 0.061000, -0.035166, 1.332998, 0.577288, 0.072608, -0.041833, 1.332901, 0.577263, 0.085227, -0.049067, 1.332603, 0.577226, 0.098864, -0.056860, 1.332264, 0.577177, 0.113507, -0.065114, 1.331825, 0.577109, 0.129146, -0.073610, 1.331311, 0.577005, 0.145808, -0.082766, 1.330639, 0.576872, 0.163494, -0.092458, 1.329878, 0.576709, 0.182176, -0.102639, 1.328889, 0.576501, 0.201804, -0.112983, 1.327710, 0.576207, 0.222394, -0.123650, 1.326256, 0.575823, 0.243881, -0.134780, 1.324593, 0.575363, 0.266122, -0.145931, 1.322426, 0.574751, 0.289043, -0.157500, 1.319837, 0.574033, 0.312330, -0.169208, 1.316301, 0.573181, 0.336120, -0.181125, 1.312251, 0.572188, 0.361506, -0.192232, 1.307003, 0.570631, 0.387757, -0.202981, 1.301068, 0.568558, 0.414365, -0.213160, 1.293695, 0.566027, 0.440986, -0.222617, 1.283958, 0.562942, 0.467943, -0.231583, 1.274057, 0.559219, 0.494821, -0.239881, 1.262864, 0.554913, 0.521486, -0.247336, 1.250633, 0.549953, 0.547884, -0.253921, 1.237448, 0.544251, 0.574582, -0.259099, 1.223164, 0.537120, 0.601342, -0.262695, 1.208784, 0.528650, 0.627861, -0.265337, 1.194424, 0.518978, 0.653745, -0.266872, 1.179361, 0.508525, 0.679348, -0.267403, 1.165010, 0.496705, 0.705068, -0.266429, 1.151693, 0.482926, 0.730312, -0.263829, 1.137584, 0.468519, 0.755576, -0.260491, 1.125328, 0.452213, 0.780371, -0.256166, 1.113759, 0.435127, 0.804632, -0.250079, 1.101656, 0.416833, 0.828983, -0.243181, 1.091235, 0.397009, 0.852585, -0.235383, 1.081475, 0.376647, 0.875237, -0.226031, 1.071806, 0.355506, 0.899152, -0.216343, 1.064453, 0.333133, 0.922121, -0.205772, 1.057161, 0.311073, 0.944523, -0.193980, 1.050447, 0.287781, 0.967313, -0.181920, 1.044531, 0.264350, 0.989042, -0.168822, 1.039312, 0.241128, 1.010881, -0.155350, 1.035298, 0.218138, 1.032368, -0.141231, 1.032073, 0.195579, 1.052254, -0.126521, 1.029395, 0.173399, 1.070207, -0.111243, 1.026938, 0.151866, 1.086528, -0.095617, 1.024957, 0.130711, 1.100670, -0.079687, 1.021924, 0.108865, 1.112461, -0.063593, 1.018281, 0.086760, 1.121588, -0.047313, 1.013747, 0.064575, 1.128522, -0.031385, 1.008433, 0.042499, 1.134759, -0.015356, 1.003569, 0.020840, 1.141448, 0.000114, 0.999978, -0.000056, 0.000200, -0.000122, 1.372763, 0.611086, 0.000503, -0.000308, 1.371456, 0.611084, 0.002016, -0.001232, 1.373440, 0.611084, 0.004535, -0.002771, 1.373387, 0.611083, 0.008061, -0.004926, 1.372916, 0.611083, 0.012601, -0.007700, 1.373956, 0.611084, 0.018142, -0.011084, 1.373419, 0.611078, 0.024695, -0.015087, 1.373492, 0.611074, 0.032255, -0.019701, 1.373360, 0.611066, 0.040827, -0.024930, 1.373327, 0.611055, 0.050408, -0.030769, 1.373222, 0.611037, 0.061004, -0.037217, 1.373079, 0.611014, 0.072613, -0.044270, 1.372895, 0.610982, 0.085238, -0.051923, 1.372624, 0.610941, 0.098878, -0.060161, 1.372252, 0.610883, 0.113522, -0.068785, 1.371785, 0.610798, 0.129176, -0.077863, 1.371103, 0.610683, 0.145876, -0.087593, 1.370541, 0.610537, 0.163570, -0.097847, 1.369496, 0.610349, 0.182283, -0.108592, 1.368477, 0.610109, 0.201930, -0.119420, 1.366980, 0.609763, 0.222570, -0.130789, 1.365375, 0.609343, 0.244123, -0.142514, 1.363456, 0.608815, 0.266437, -0.154232, 1.360916, 0.608114, 0.289467, -0.166370, 1.357909, 0.607291, 0.312861, -0.178505, 1.353588, 0.606272, 0.336736, -0.190980, 1.349211, 0.605153, 0.361740, -0.202859, 1.343319, 0.603548, 0.387878, -0.213997, 1.335908, 0.601268, 0.414357, -0.224584, 1.326676, 0.598499, 0.441442, -0.234664, 1.317331, 0.595066, 0.468409, -0.243875, 1.305818, 0.590996, 0.494999, -0.252121, 1.291863, 0.586293, 0.521730, -0.259714, 1.278212, 0.580840, 0.547894, -0.266242, 1.262656, 0.574494, 0.573865, -0.271578, 1.246364, 0.567007, 0.601124, -0.275503, 1.231274, 0.557771, 0.627606, -0.277954, 1.215252, 0.547255, 0.654004, -0.279404, 1.199977, 0.535766, 0.679554, -0.279632, 1.183995, 0.522792, 0.704280, -0.278457, 1.167428, 0.508488, 0.729830, -0.275706, 1.152760, 0.492425, 0.754376, -0.271640, 1.137942, 0.475285, 0.779209, -0.266911, 1.125222, 0.456679, 0.803562, -0.260838, 1.112179, 0.437267, 0.827985, -0.253353, 1.101439, 0.416227, 0.851737, -0.245027, 1.089890, 0.394728, 0.874850, -0.235719, 1.080018, 0.372244, 0.897680, -0.225051, 1.070807, 0.348846, 0.921351, -0.214051, 1.063180, 0.324961, 0.943818, -0.202039, 1.056148, 0.300836, 0.966368, -0.189134, 1.049277, 0.276333, 0.987426, -0.175613, 1.042176, 0.251862, 1.010162, -0.161473, 1.038567, 0.227217, 1.031224, -0.146866, 1.034102, 0.203582, 1.052317, -0.131644, 1.031600, 0.180629, 1.070879, -0.115909, 1.028913, 0.158165, 1.087407, -0.099638, 1.026193, 0.135905, 1.102159, -0.083091, 1.023567, 0.113394, 1.114006, -0.066178, 1.019567, 0.090325, 1.123374, -0.049430, 1.014856, 0.067302, 1.130310, -0.032557, 1.009141, 0.044264, 1.136334, -0.016157, 1.003984, 0.021807, 1.142961, 0.000172, 0.999951, -0.000077, 0.000200, -0.000129, 1.416584, 0.645866, 0.000504, -0.000326, 1.417762, 0.645865, 0.002016, -0.001302, 1.417825, 0.645866, 0.004535, -0.002929, 1.417142, 0.645865, 0.008062, -0.005207, 1.416968, 0.645864, 0.012598, -0.008136, 1.417109, 0.645862, 0.018141, -0.011715, 1.417001, 0.645859, 0.024690, -0.015941, 1.416878, 0.645853, 0.032257, -0.020823, 1.417134, 0.645843, 0.040827, -0.026347, 1.416983, 0.645829, 0.050411, -0.032518, 1.416949, 0.645808, 0.061007, -0.039330, 1.416694, 0.645781, 0.072621, -0.046783, 1.416599, 0.645746, 0.085249, -0.054865, 1.416241, 0.645695, 0.098897, -0.063563, 1.415832, 0.645630, 0.113546, -0.072607, 1.415264, 0.645529, 0.129220, -0.082257, 1.414482, 0.645396, 0.145888, -0.092515, 1.413626, 0.645268, 0.163659, -0.103393, 1.412710, 0.645018, 0.182385, -0.114684, 1.411418, 0.644739, 0.202078, -0.126098, 1.409822, 0.644348, 0.222772, -0.138145, 1.407948, 0.643872, 0.244370, -0.150405, 1.405678, 0.643255, 0.266787, -0.162798, 1.402763, 0.642463, 0.289844, -0.175434, 1.398863, 0.641504, 0.313540, -0.188158, 1.394695, 0.640346, 0.337489, -0.201014, 1.389376, 0.639042, 0.362008, -0.213719, 1.382439, 0.637412, 0.387990, -0.225248, 1.373281, 0.634930, 0.414728, -0.236348, 1.363729, 0.631861, 0.441635, -0.246701, 1.352304, 0.628155, 0.468588, -0.256167, 1.339162, 0.623625, 0.495337, -0.264662, 1.323811, 0.618458, 0.521886, -0.272207, 1.307630, 0.612373, 0.548355, -0.278890, 1.291265, 0.605263, 0.574535, -0.284442, 1.273752, 0.597048, 0.600870, -0.288389, 1.256171, 0.587401, 0.627715, -0.290816, 1.238447, 0.576001, 0.653830, -0.291886, 1.221036, 0.563198, 0.679175, -0.291629, 1.202283, 0.549249, 0.704539, -0.290489, 1.185866, 0.533881, 0.729126, -0.287529, 1.168822, 0.516966, 0.754297, -0.283184, 1.152934, 0.498501, 0.778678, -0.277732, 1.137821, 0.478728, 0.802473, -0.271203, 1.123387, 0.457814, 0.826596, -0.263494, 1.110573, 0.435865, 0.850835, -0.254572, 1.099099, 0.412597, 0.874203, -0.244815, 1.088403, 0.388995, 0.897271, -0.233993, 1.078085, 0.364487, 0.919667, -0.221934, 1.068543, 0.339344, 0.943001, -0.209714, 1.061081, 0.313770, 0.965688, -0.196367, 1.054023, 0.287928, 0.987598, -0.182263, 1.047247, 0.262157, 1.009280, -0.167775, 1.041376, 0.236855, 1.031762, -0.152530, 1.037647, 0.211847, 1.051965, -0.136809, 1.033396, 0.187546, 1.071699, -0.120418, 1.031021, 0.164186, 1.088881, -0.103618, 1.028403, 0.141184, 1.103482, -0.086271, 1.024987, 0.117665, 1.115646, -0.068973, 1.020884, 0.093896, 1.125258, -0.051285, 1.015966, 0.069978, 1.132045, -0.033998, 1.009990, 0.046126, 1.138004, -0.016696, 1.004270, 0.022635, 1.144463, 0.000089, 0.999987, -0.000016, 0.000200, -0.000136, 1.463614, 0.681786, 0.000504, -0.000344, 1.465345, 0.681785, 0.002015, -0.001374, 1.464172, 0.681783, 0.004535, -0.003092, 1.464846, 0.681784, 0.008062, -0.005496, 1.464783, 0.681784, 0.012598, -0.008588, 1.464883, 0.681781, 0.018141, -0.012366, 1.464740, 0.681777, 0.024692, -0.016829, 1.464665, 0.681770, 0.032258, -0.021980, 1.464720, 0.681760, 0.040829, -0.027811, 1.464625, 0.681742, 0.050415, -0.034324, 1.464571, 0.681720, 0.061013, -0.041513, 1.464346, 0.681688, 0.072628, -0.049375, 1.464131, 0.681644, 0.085264, -0.057903, 1.463847, 0.681588, 0.098918, -0.067067, 1.463369, 0.681509, 0.113568, -0.076570, 1.462549, 0.681389, 0.129265, -0.086782, 1.461703, 0.681239, 0.145997, -0.097637, 1.460840, 0.681047, 0.163751, -0.109101, 1.459737, 0.680806, 0.182505, -0.120922, 1.458231, 0.680480, 0.202241, -0.133007, 1.456393, 0.680042, 0.222987, -0.145693, 1.454258, 0.679503, 0.244638, -0.158488, 1.451543, 0.678792, 0.267132, -0.171585, 1.448115, 0.677907, 0.290365, -0.184746, 1.443992, 0.676796, 0.314178, -0.198101, 1.439271, 0.675498, 0.338289, -0.211370, 1.432830, 0.673922, 0.362543, -0.224489, 1.424163, 0.672151, 0.388470, -0.236914, 1.415160, 0.669601, 0.415105, -0.248342, 1.403811, 0.666255, 0.441925, -0.258957, 1.390149, 0.662166, 0.468668, -0.268556, 1.374104, 0.657229, 0.495720, -0.277359, 1.358102, 0.651347, 0.522574, -0.285078, 1.340754, 0.644598, 0.548981, -0.291718, 1.322033, 0.636820, 0.574946, -0.297087, 1.302148, 0.627812, 0.600744, -0.301079, 1.282130, 0.617485, 0.627565, -0.303566, 1.263339, 0.605047, 0.653598, -0.304330, 1.242712, 0.591167, 0.679239, -0.303820, 1.223212, 0.576025, 0.704043, -0.302064, 1.203763, 0.559649, 0.728796, -0.299095, 1.185434, 0.541271, 0.753581, -0.294392, 1.167630, 0.521800, 0.778577, -0.288603, 1.151930, 0.500628, 0.802550, -0.281604, 1.136072, 0.478434, 0.825803, -0.273472, 1.121673, 0.455384, 0.849768, -0.264011, 1.108491, 0.430811, 0.873250, -0.253653, 1.096550, 0.405524, 0.896725, -0.242642, 1.085905, 0.380038, 0.919158, -0.230191, 1.075091, 0.353482, 0.942236, -0.217145, 1.066848, 0.326605, 0.965031, -0.203555, 1.059310, 0.299842, 0.987048, -0.188777, 1.051749, 0.272859, 1.008718, -0.173613, 1.044999, 0.246040, 1.031097, -0.157972, 1.040066, 0.219826, 1.052493, -0.141589, 1.035951, 0.194278, 1.071773, -0.124814, 1.032520, 0.169830, 1.089646, -0.107321, 1.029803, 0.146135, 1.104932, -0.089726, 1.026612, 0.122127, 1.117687, -0.071433, 1.022391, 0.097461, 1.127188, -0.053395, 1.017113, 0.072556, 1.134010, -0.035151, 1.010934, 0.047749, 1.139746, -0.017427, 1.004633, 0.023530, 1.146205, 0.000151, 1.000020, -0.000106, 0.000200, -0.000144, 1.517643, 0.718949, 0.000504, -0.000362, 1.516387, 0.718947, 0.002016, -0.001449, 1.516742, 0.718946, 0.004536, -0.003261, 1.517196, 0.718946, 0.008063, -0.005796, 1.516806, 0.718945, 0.012598, -0.009057, 1.516986, 0.718943, 0.018140, -0.013039, 1.516603, 0.718937, 0.024694, -0.017747, 1.516739, 0.718929, 0.032260, -0.023178, 1.516994, 0.718917, 0.040831, -0.029325, 1.516649, 0.718896, 0.050419, -0.036192, 1.516594, 0.718870, 0.061019, -0.043770, 1.516327, 0.718833, 0.072638, -0.052056, 1.516054, 0.718782, 0.085274, -0.061039, 1.515628, 0.718714, 0.098938, -0.070676, 1.515199, 0.718623, 0.113607, -0.080679, 1.514222, 0.718483, 0.129329, -0.091485, 1.513354, 0.718316, 0.146077, -0.102931, 1.512301, 0.718096, 0.163856, -0.114986, 1.510977, 0.717818, 0.182640, -0.127305, 1.509225, 0.717432, 0.202432, -0.140147, 1.507152, 0.716939, 0.223229, -0.153468, 1.504780, 0.716331, 0.244943, -0.166875, 1.501612, 0.715527, 0.267559, -0.180658, 1.497898, 0.714523, 0.290926, -0.194405, 1.493208, 0.713266, 0.314863, -0.208302, 1.487388, 0.711758, 0.339053, -0.222020, 1.479677, 0.709982, 0.363627, -0.235683, 1.470950, 0.707958, 0.388887, -0.248723, 1.459907, 0.705346, 0.415474, -0.260563, 1.446579, 0.701644, 0.442065, -0.271352, 1.429962, 0.697134, 0.469418, -0.281541, 1.414343, 0.691665, 0.496419, -0.290429, 1.395681, 0.685227, 0.523071, -0.298032, 1.375347, 0.677815, 0.549641, -0.304679, 1.354816, 0.669063, 0.575489, -0.309902, 1.332505, 0.659071, 0.601108, -0.313771, 1.309752, 0.647799, 0.627199, -0.316225, 1.288381, 0.634856, 0.653243, -0.316679, 1.265785, 0.619627, 0.678960, -0.315816, 1.244333, 0.603244, 0.704055, -0.313776, 1.223315, 0.585191, 0.728713, -0.310417, 1.203142, 0.565969, 0.753301, -0.305786, 1.184323, 0.545347, 0.777890, -0.299262, 1.166070, 0.522753, 0.802354, -0.291830, 1.149599, 0.499017, 0.826005, -0.283281, 1.133655, 0.474335, 0.848920, -0.273512, 1.118132, 0.449019, 0.872765, -0.262525, 1.105606, 0.422329, 0.895950, -0.250769, 1.093539, 0.395057, 0.918816, -0.238257, 1.082388, 0.367709, 0.941089, -0.224381, 1.072484, 0.339350, 0.964514, -0.210289, 1.064054, 0.311239, 0.987128, -0.195488, 1.056645, 0.283272, 1.009064, -0.179491, 1.049549, 0.255163, 1.030163, -0.163172, 1.042741, 0.227757, 1.052502, -0.146457, 1.038270, 0.200970, 1.072971, -0.129054, 1.035014, 0.175767, 1.091223, -0.111285, 1.032231, 0.151118, 1.106518, -0.092617, 1.028211, 0.126196, 1.119235, -0.074168, 1.023686, 0.100828, 1.129311, -0.055212, 1.018311, 0.075240, 1.135983, -0.036571, 1.011485, 0.049558, 1.141648, -0.017954, 1.004952, 0.024273, 1.147938, 0.000125, 1.000009, -0.000048, 0.000199, -0.000151, 1.566887, 0.757466, 0.000504, -0.000382, 1.574111, 0.757466, 0.002016, -0.001527, 1.573735, 0.757466, 0.004535, -0.003435, 1.573737, 0.757466, 0.008062, -0.006107, 1.573782, 0.757464, 0.012599, -0.009542, 1.573796, 0.757460, 0.018142, -0.013739, 1.573710, 0.757455, 0.024694, -0.018697, 1.573562, 0.757446, 0.032259, -0.024418, 1.573667, 0.757429, 0.040834, -0.030895, 1.573555, 0.757407, 0.050422, -0.038127, 1.573383, 0.757376, 0.061025, -0.046108, 1.573086, 0.757332, 0.072650, -0.054835, 1.572833, 0.757274, 0.085296, -0.064294, 1.572395, 0.757195, 0.098962, -0.074376, 1.571729, 0.757087, 0.113649, -0.084955, 1.570571, 0.756925, 0.129389, -0.096334, 1.569582, 0.756729, 0.146167, -0.108406, 1.568444, 0.756481, 0.163973, -0.121056, 1.566905, 0.756158, 0.182798, -0.133970, 1.564939, 0.755715, 0.202650, -0.147522, 1.562666, 0.755167, 0.223502, -0.161466, 1.559877, 0.754465, 0.245269, -0.175539, 1.556008, 0.753552, 0.268010, -0.189957, 1.552013, 0.752420, 0.291474, -0.204361, 1.546509, 0.751008, 0.315527, -0.218714, 1.539575, 0.749266, 0.339954, -0.233029, 1.530968, 0.747232, 0.364649, -0.247149, 1.520994, 0.744906, 0.389520, -0.260672, 1.507748, 0.742123, 0.415717, -0.272873, 1.491777, 0.738187, 0.442862, -0.284317, 1.475658, 0.733189, 0.469939, -0.294552, 1.456572, 0.727165, 0.496916, -0.303517, 1.435237, 0.720043, 0.523480, -0.311061, 1.412192, 0.711640, 0.550092, -0.317596, 1.389033, 0.702174, 0.576384, -0.322921, 1.365086, 0.691225, 0.602280, -0.326806, 1.341317, 0.678841, 0.627676, -0.329057, 1.316518, 0.664815, 0.653458, -0.329372, 1.291877, 0.648548, 0.679227, -0.328067, 1.268126, 0.630676, 0.704476, -0.325585, 1.244424, 0.611585, 0.729232, -0.321775, 1.223010, 0.590803, 0.753405, -0.316713, 1.201297, 0.568653, 0.777274, -0.309858, 1.181071, 0.544763, 0.801882, -0.301866, 1.162826, 0.519747, 0.826030, -0.292861, 1.145704, 0.493531, 0.849359, -0.282794, 1.129629, 0.466900, 0.871837, -0.271197, 1.114155, 0.439230, 0.895896, -0.258954, 1.102334, 0.410570, 0.918951, -0.245878, 1.090163, 0.381314, 0.941148, -0.231897, 1.078738, 0.352268, 0.963464, -0.216743, 1.068862, 0.322688, 0.986628, -0.201486, 1.061077, 0.293523, 1.009289, -0.185521, 1.053561, 0.264125, 1.030659, -0.168429, 1.046627, 0.235706, 1.052382, -0.151210, 1.040953, 0.208022, 1.073476, -0.133289, 1.036534, 0.181245, 1.092237, -0.114768, 1.033580, 0.155661, 1.108200, -0.095917, 1.029997, 0.130223, 1.121435, -0.076492, 1.025374, 0.104098, 1.131382, -0.057204, 1.019485, 0.077776, 1.137994, -0.037747, 1.012188, 0.051250, 1.143441, -0.018673, 1.005309, 0.025245, 1.149714, 0.000216, 1.000004, -0.000120, 0.000200, -0.000159, 1.633988, 0.797469, 0.000504, -0.000402, 1.636076, 0.797469, 0.002016, -0.001607, 1.635679, 0.797467, 0.004535, -0.003617, 1.636040, 0.797468, 0.008063, -0.006430, 1.636159, 0.797467, 0.012599, -0.010046, 1.636128, 0.797462, 0.018141, -0.014464, 1.635730, 0.797457, 0.024696, -0.019685, 1.635836, 0.797445, 0.032259, -0.025705, 1.635719, 0.797426, 0.040835, -0.032523, 1.635610, 0.797401, 0.050425, -0.040135, 1.635460, 0.797363, 0.061033, -0.048536, 1.635182, 0.797313, 0.072661, -0.057718, 1.634817, 0.797243, 0.085315, -0.067666, 1.634314, 0.797150, 0.098985, -0.078179, 1.633350, 0.797016, 0.113699, -0.089383, 1.632253, 0.796839, 0.129456, -0.101364, 1.631025, 0.796623, 0.146275, -0.114081, 1.629867, 0.796331, 0.164108, -0.127318, 1.628043, 0.795956, 0.182983, -0.140901, 1.625813, 0.795458, 0.202891, -0.155174, 1.623149, 0.794834, 0.223787, -0.169654, 1.619686, 0.794015, 0.245678, -0.184540, 1.615694, 0.793013, 0.268495, -0.199543, 1.610812, 0.791727, 0.292093, -0.214639, 1.604629, 0.790107, 0.316184, -0.229499, 1.596061, 0.788154, 0.340986, -0.244407, 1.587195, 0.785797, 0.365808, -0.258907, 1.575031, 0.783093, 0.390528, -0.272746, 1.559448, 0.779970, 0.416510, -0.285845, 1.543294, 0.775852, 0.443443, -0.297404, 1.523476, 0.770323, 0.470442, -0.307757, 1.501515, 0.763721, 0.497499, -0.316846, 1.477841, 0.755889, 0.524316, -0.324561, 1.452427, 0.746662, 0.551212, -0.331060, 1.427421, 0.736004, 0.577323, -0.335956, 1.400369, 0.723810, 0.602976, -0.339501, 1.373093, 0.710184, 0.628357, -0.341577, 1.345853, 0.695017, 0.653642, -0.342031, 1.319040, 0.677972, 0.679440, -0.340342, 1.292490, 0.658877, 0.704744, -0.337356, 1.267182, 0.638085, 0.729692, -0.333042, 1.243280, 0.615615, 0.753920, -0.327504, 1.219751, 0.592054, 0.777695, -0.320537, 1.197796, 0.566967, 0.801426, -0.311880, 1.176872, 0.540643, 0.825649, -0.302211, 1.158160, 0.512906, 0.849282, -0.291665, 1.141257, 0.484587, 0.872341, -0.280050, 1.125469, 0.455556, 0.895110, -0.266978, 1.110222, 0.425652, 0.918841, -0.253326, 1.097419, 0.395015, 0.941209, -0.238899, 1.086101, 0.364948, 0.963142, -0.223523, 1.075023, 0.334151, 0.985996, -0.207346, 1.065628, 0.303708, 1.008718, -0.190889, 1.057256, 0.273008, 1.030554, -0.173517, 1.049720, 0.243221, 1.053085, -0.155645, 1.043837, 0.214426, 1.074267, -0.137472, 1.039312, 0.187036, 1.093591, -0.118385, 1.035457, 0.160512, 1.109850, -0.098883, 1.031630, 0.134384, 1.123516, -0.079050, 1.026762, 0.107424, 1.133578, -0.058977, 1.020640, 0.080317, 1.140289, -0.039013, 1.013096, 0.052944, 1.145610, -0.019228, 1.005694, 0.025989, 1.151704, 0.000105, 0.999981, -0.000019, 0.000200, -0.000168, 1.704841, 0.839096, 0.000504, -0.000423, 1.704242, 0.839097, 0.002016, -0.001691, 1.703821, 0.839091, 0.004534, -0.003805, 1.703804, 0.839094, 0.008063, -0.006765, 1.704224, 0.839092, 0.012598, -0.010570, 1.704013, 0.839087, 0.018142, -0.015219, 1.703889, 0.839079, 0.024697, -0.020712, 1.704023, 0.839066, 0.032261, -0.027046, 1.703836, 0.839045, 0.040837, -0.034218, 1.703608, 0.839014, 0.050429, -0.042224, 1.703414, 0.838972, 0.061041, -0.051061, 1.703148, 0.838912, 0.072676, -0.060717, 1.702744, 0.838831, 0.085340, -0.071175, 1.702223, 0.838724, 0.099023, -0.082182, 1.700984, 0.838567, 0.113759, -0.094007, 1.699764, 0.838367, 0.129546, -0.106621, 1.698462, 0.838112, 0.146382, -0.119956, 1.696938, 0.837782, 0.164260, -0.133760, 1.694868, 0.837346, 0.183188, -0.148108, 1.692262, 0.836780, 0.203158, -0.163075, 1.689251, 0.836073, 0.224147, -0.178255, 1.685408, 0.835148, 0.246147, -0.193900, 1.680946, 0.833992, 0.269072, -0.209553, 1.675277, 0.832546, 0.292718, -0.225226, 1.667626, 0.830727, 0.317159, -0.240836, 1.658952, 0.828510, 0.341979, -0.256103, 1.647624, 0.825843, 0.366844, -0.270887, 1.633014, 0.822760, 0.392043, -0.285324, 1.617191, 0.819159, 0.417356, -0.298817, 1.597501, 0.814788, 0.444093, -0.310711, 1.575184, 0.808751, 0.471379, -0.321410, 1.551590, 0.801294, 0.498267, -0.330421, 1.524134, 0.792711, 0.525401, -0.338331, 1.496672, 0.782480, 0.551846, -0.344430, 1.467062, 0.770659, 0.578009, -0.349047, 1.436943, 0.757348, 0.604054, -0.352490, 1.407611, 0.742541, 0.629387, -0.354158, 1.377441, 0.726071, 0.654435, -0.354422, 1.347651, 0.707524, 0.679845, -0.352663, 1.318769, 0.687067, 0.704892, -0.348994, 1.290600, 0.664637, 0.729763, -0.344105, 1.263997, 0.640663, 0.754345, -0.338129, 1.239273, 0.615484, 0.778629, -0.330905, 1.215858, 0.589210, 0.801939, -0.322113, 1.192318, 0.561550, 0.825723, -0.311673, 1.171380, 0.532175, 0.849387, -0.300410, 1.152991, 0.502055, 0.872792, -0.288328, 1.136139, 0.471308, 0.895083, -0.275087, 1.119534, 0.440427, 0.918335, -0.260700, 1.105542, 0.409260, 0.941577, -0.245717, 1.093070, 0.377142, 0.963992, -0.230079, 1.081207, 0.345289, 0.986510, -0.213523, 1.071488, 0.313508, 1.008806, -0.196157, 1.062011, 0.281962, 1.030724, -0.178467, 1.053240, 0.251177, 1.053782, -0.160291, 1.047057, 0.220986, 1.075451, -0.141308, 1.041842, 0.192256, 1.094947, -0.121975, 1.037704, 0.165023, 1.111783, -0.101744, 1.033300, 0.138228, 1.125525, -0.081476, 1.028234, 0.110679, 1.135873, -0.060770, 1.021695, 0.082672, 1.142478, -0.040207, 1.013838, 0.054506, 1.147889, -0.019908, 1.006166, 0.026938, 1.153852, 0.000204, 0.999983, -0.000123, 0.000199, -0.000176, 1.771601, 0.882501, 0.000504, -0.000445, 1.779195, 0.882504, 0.002016, -0.001779, 1.779635, 0.882498, 0.004536, -0.004003, 1.779586, 0.882499, 0.008062, -0.007115, 1.778613, 0.882496, 0.012598, -0.011116, 1.778678, 0.882492, 0.018142, -0.016005, 1.778531, 0.882481, 0.024696, -0.021782, 1.778556, 0.882466, 0.032262, -0.028444, 1.778507, 0.882442, 0.040842, -0.035987, 1.778385, 0.882408, 0.050436, -0.044404, 1.778034, 0.882364, 0.061053, -0.053695, 1.777761, 0.882287, 0.072692, -0.063842, 1.777256, 0.882190, 0.085364, -0.074821, 1.776518, 0.882067, 0.099064, -0.086368, 1.775080, 0.881884, 0.113828, -0.098805, 1.773836, 0.881657, 0.129649, -0.112090, 1.772370, 0.881361, 0.146518, -0.126067, 1.770594, 0.880982, 0.164440, -0.140493, 1.768089, 0.880484, 0.183437, -0.155646, 1.765301, 0.879843, 0.203468, -0.171266, 1.761698, 0.879035, 0.224562, -0.187231, 1.757518, 0.877982, 0.246665, -0.203540, 1.752318, 0.876667, 0.269652, -0.219916, 1.745356, 0.875028, 0.293531, -0.236255, 1.737186, 0.872977, 0.318048, -0.252410, 1.726709, 0.870448, 0.342963, -0.268192, 1.713109, 0.867400, 0.368336, -0.283587, 1.698087, 0.863882, 0.393512, -0.298186, 1.678638, 0.859724, 0.418602, -0.311882, 1.655604, 0.854835, 0.445080, -0.324500, 1.632250, 0.848353, 0.472289, -0.335295, 1.605069, 0.840218, 0.499128, -0.344256, 1.573846, 0.830556, 0.525834, -0.351716, 1.541120, 0.819269, 0.553177, -0.358241, 1.511385, 0.806222, 0.579480, -0.362640, 1.477866, 0.791647, 0.605205, -0.365513, 1.444218, 0.775398, 0.630617, -0.366822, 1.410954, 0.757144, 0.655730, -0.366785, 1.379010, 0.737323, 0.680529, -0.364904, 1.347280, 0.715601, 0.705800, -0.360990, 1.316416, 0.691547, 0.730550, -0.355397, 1.286344, 0.666141, 0.754970, -0.348664, 1.258954, 0.638929, 0.779042, -0.340774, 1.232965, 0.611015, 0.802839, -0.331767, 1.209775, 0.581877, 0.825793, -0.321054, 1.185813, 0.551509, 0.849512, -0.309016, 1.165080, 0.519698, 0.873120, -0.296369, 1.147091, 0.487506, 0.895942, -0.282704, 1.129658, 0.455320, 0.917996, -0.268007, 1.113463, 0.422605, 0.941281, -0.252329, 1.100040, 0.389347, 0.964584, -0.236203, 1.087973, 0.356430, 0.986371, -0.219209, 1.075983, 0.323089, 1.009522, -0.201588, 1.066940, 0.290806, 1.031976, -0.183296, 1.057999, 0.258682, 1.053461, -0.164509, 1.049542, 0.227722, 1.076121, -0.145165, 1.043718, 0.197439, 1.096597, -0.125199, 1.039607, 0.169578, 1.113908, -0.104921, 1.035528, 0.142222, 1.127939, -0.083623, 1.029807, 0.113802, 1.138391, -0.062589, 1.023312, 0.085164, 1.145110, -0.041376, 1.014806, 0.056186, 1.150141, -0.020433, 1.006501, 0.027654, 1.156069, 0.000097, 0.999949, -0.000046, 0.000200, -0.000185, 1.858268, 0.927857, 0.000504, -0.000468, 1.861583, 0.927859, 0.002016, -0.001870, 1.860659, 0.927855, 0.004535, -0.004208, 1.860963, 0.927867, 0.008063, -0.007480, 1.860766, 0.927855, 0.012594, -0.011683, 1.859996, 0.927851, 0.018142, -0.016828, 1.860739, 0.927839, 0.024698, -0.022901, 1.860763, 0.927818, 0.032263, -0.029903, 1.860501, 0.927791, 0.040846, -0.037834, 1.860431, 0.927751, 0.050440, -0.046680, 1.859827, 0.927690, 0.061066, -0.056446, 1.859624, 0.927610, 0.072713, -0.067109, 1.859039, 0.927505, 0.085393, -0.078613, 1.858144, 0.927357, 0.099120, -0.090747, 1.856618, 0.927145, 0.113910, -0.103850, 1.855221, 0.926884, 0.129755, -0.117777, 1.853470, 0.926546, 0.146669, -0.132441, 1.851413, 0.926104, 0.164648, -0.147565, 1.848498, 0.925530, 0.183708, -0.163470, 1.845281, 0.924802, 0.203832, -0.179763, 1.841273, 0.923871, 0.225029, -0.196564, 1.836481, 0.922691, 0.247221, -0.213537, 1.830273, 0.921198, 0.270343, -0.230662, 1.822374, 0.919320, 0.294399, -0.247740, 1.812975, 0.917008, 0.319040, -0.264448, 1.800693, 0.914141, 0.344269, -0.280831, 1.785923, 0.910707, 0.369625, -0.296478, 1.767203, 0.906585, 0.394925, -0.311287, 1.744434, 0.901918, 0.420583, -0.325578, 1.720938, 0.896240, 0.446200, -0.338384, 1.693005, 0.889335, 0.472969, -0.349187, 1.660901, 0.880394, 0.500490, -0.358687, 1.628806, 0.869705, 0.527312, -0.366042, 1.593001, 0.857145, 0.554207, -0.372045, 1.557046, 0.842943, 0.580620, -0.376134, 1.520192, 0.826837, 0.606480, -0.378636, 1.482947, 0.808891, 0.631815, -0.379414, 1.445954, 0.789119, 0.657021, -0.378972, 1.410833, 0.767564, 0.681686, -0.376728, 1.376575, 0.744338, 0.706498, -0.372844, 1.342935, 0.718799, 0.731258, -0.366649, 1.311052, 0.691756, 0.755937, -0.359354, 1.280478, 0.662683, 0.779259, -0.350487, 1.250585, 0.632892, 0.803295, -0.340941, 1.225722, 0.602160, 0.826570, -0.330174, 1.201003, 0.570520, 0.849954, -0.317854, 1.178488, 0.537651, 0.873696, -0.304426, 1.158302, 0.503799, 0.896695, -0.290120, 1.139886, 0.469645, 0.919149, -0.275106, 1.122884, 0.435625, 0.942121, -0.259282, 1.107691, 0.401228, 0.964627, -0.242123, 1.093661, 0.367086, 0.986614, -0.224575, 1.081580, 0.332885, 1.009623, -0.206837, 1.071375, 0.299209, 1.033126, -0.188092, 1.062241, 0.266187, 1.054954, -0.168637, 1.052912, 0.233733, 1.077660, -0.149166, 1.047047, 0.203192, 1.097983, -0.128587, 1.041607, 0.173918, 1.115586, -0.107339, 1.036850, 0.145531, 1.130170, -0.086203, 1.031427, 0.116890, 1.141018, -0.064171, 1.024395, 0.087388, 1.147681, -0.042530, 1.015719, 0.057733, 1.152560, -0.021011, 1.006883, 0.028413, 1.158406, 0.000158, 0.999897, -0.000106, 0.000200, -0.000195, 1.950982, 0.975366, 0.000504, -0.000491, 1.950207, 0.975365, 0.002015, -0.001966, 1.950675, 0.975362, 0.004535, -0.004423, 1.951281, 0.975370, 0.008062, -0.007863, 1.951045, 0.975362, 0.012597, -0.012285, 1.951199, 0.975356, 0.018145, -0.017692, 1.951528, 0.975340, 0.024699, -0.024074, 1.951194, 0.975321, 0.032266, -0.031434, 1.950865, 0.975288, 0.040853, -0.039771, 1.951038, 0.975244, 0.050452, -0.049067, 1.950336, 0.975173, 0.061077, -0.059324, 1.949805, 0.975078, 0.072736, -0.070526, 1.949133, 0.974951, 0.085431, -0.082528, 1.947947, 0.974777, 0.099182, -0.095345, 1.946337, 0.974540, 0.113999, -0.109118, 1.944725, 0.974241, 0.129888, -0.123741, 1.942857, 0.973852, 0.146842, -0.139071, 1.940251, 0.973342, 0.164890, -0.154986, 1.937086, 0.972684, 0.184025, -0.171661, 1.933404, 0.971856, 0.204245, -0.188672, 1.928770, 0.970785, 0.225528, -0.206252, 1.923041, 0.969448, 0.247841, -0.223972, 1.915788, 0.967742, 0.271157, -0.241827, 1.907008, 0.965607, 0.295297, -0.259562, 1.895854, 0.963007, 0.320121, -0.276909, 1.881289, 0.959722, 0.345566, -0.293883, 1.864528, 0.955831, 0.371012, -0.309816, 1.842062, 0.951127, 0.396834, -0.325157, 1.818068, 0.945725, 0.422277, -0.339357, 1.788874, 0.939318, 0.447928, -0.352387, 1.758283, 0.931470, 0.474315, -0.363680, 1.723668, 0.921900, 0.501560, -0.372963, 1.686081, 0.909996, 0.528391, -0.380159, 1.645816, 0.896244, 0.554754, -0.385545, 1.603709, 0.880326, 0.581888, -0.389778, 1.565475, 0.862716, 0.607791, -0.391839, 1.524196, 0.843146, 0.633511, -0.392331, 1.483921, 0.821554, 0.658621, -0.391193, 1.445013, 0.798336, 0.683160, -0.388424, 1.406963, 0.773299, 0.707429, -0.384104, 1.370996, 0.746668, 0.732212, -0.377945, 1.335879, 0.717502, 0.756871, -0.369856, 1.302489, 0.686954, 0.781065, -0.360707, 1.271815, 0.655372, 0.804167, -0.350091, 1.242416, 0.622683, 0.827948, -0.338941, 1.217208, 0.589185, 0.850901, -0.326427, 1.192354, 0.555005, 0.873589, -0.312199, 1.169639, 0.519594, 0.897085, -0.297374, 1.150181, 0.484105, 0.920459, -0.281932, 1.132858, 0.448661, 0.942637, -0.265625, 1.115401, 0.413051, 0.965341, -0.248332, 1.101078, 0.377329, 0.987530, -0.229983, 1.087377, 0.342349, 1.010739, -0.211647, 1.076582, 0.307824, 1.033449, -0.192725, 1.065900, 0.273368, 1.055618, -0.172726, 1.056958, 0.240238, 1.079345, -0.152640, 1.049620, 0.208322, 1.100058, -0.131931, 1.044084, 0.178242, 1.118547, -0.110351, 1.039387, 0.149493, 1.132748, -0.088128, 1.033049, 0.119673, 1.143419, -0.066069, 1.025521, 0.089728, 1.150316, -0.043513, 1.016378, 0.059253, 1.155208, -0.021593, 1.007506, 0.029140, 1.160871, 0.000111, 0.999916, -0.000035, 0.000201, -0.000206, 2.061000, 1.025243, 0.000504, -0.000516, 2.049647, 1.025237, 0.002015, -0.002066, 2.050169, 1.025237, 0.004535, -0.004650, 2.051254, 1.025255, 0.008063, -0.008266, 2.051302, 1.025236, 0.012600, -0.012915, 2.051508, 1.025226, 0.018144, -0.018594, 2.050981, 1.025215, 0.024700, -0.025304, 2.050841, 1.025190, 0.032267, -0.033038, 2.050537, 1.025152, 0.040852, -0.041795, 2.050660, 1.025090, 0.050460, -0.051570, 2.049921, 1.025017, 0.061094, -0.062347, 2.049350, 1.024908, 0.072762, -0.074111, 2.048517, 1.024760, 0.085475, -0.086661, 2.047009, 1.024555, 0.099249, -0.100160, 2.045261, 1.024278, 0.114106, -0.114628, 2.043508, 1.023941, 0.130032, -0.130002, 2.041321, 1.023488, 0.147050, -0.145985, 2.038299, 1.022905, 0.165164, -0.162762, 2.034658, 1.022151, 0.184380, -0.180172, 2.030312, 1.021200, 0.204704, -0.198022, 2.024944, 1.019966, 0.226129, -0.216359, 2.018546, 1.018424, 0.248582, -0.234923, 2.010153, 1.016519, 0.272011, -0.253474, 1.999659, 1.014072, 0.296259, -0.271820, 1.986076, 1.011071, 0.321423, -0.289959, 1.970618, 1.007389, 0.346897, -0.307283, 1.949667, 1.002955, 0.372750, -0.323817, 1.925287, 0.997633, 0.398603, -0.339241, 1.896006, 0.991354, 0.424351, -0.353633, 1.863658, 0.983937, 0.449887, -0.366660, 1.827430, 0.975254, 0.475715, -0.378213, 1.789521, 0.964753, 0.502204, -0.387133, 1.745632, 0.951594, 0.530179, -0.394976, 1.705347, 0.936344, 0.556732, -0.400134, 1.658928, 0.918907, 0.583123, -0.403439, 1.613077, 0.899504, 0.609477, -0.405285, 1.567884, 0.878172, 0.634927, -0.405055, 1.523507, 0.854396, 0.660357, -0.403494, 1.481712, 0.829259, 0.684851, -0.400104, 1.439000, 0.802359, 0.709654, -0.395536, 1.400956, 0.773534, 0.733472, -0.388996, 1.362156, 0.743230, 0.757502, -0.380263, 1.325113, 0.711090, 0.782249, -0.370594, 1.292913, 0.677166, 0.806017, -0.359509, 1.262088, 0.642527, 0.828687, -0.347126, 1.232059, 0.607589, 0.852372, -0.334474, 1.207160, 0.571938, 0.874266, -0.320074, 1.181978, 0.535518, 0.898168, -0.304719, 1.161156, 0.498375, 0.920456, -0.288246, 1.140667, 0.461179, 0.942832, -0.271311, 1.122780, 0.424533, 0.966458, -0.254154, 1.108743, 0.387784, 0.988907, -0.235659, 1.093872, 0.351689, 1.011557, -0.216322, 1.081959, 0.315743, 1.035099, -0.197007, 1.070885, 0.280402, 1.056354, -0.176878, 1.059968, 0.246472, 1.079854, -0.156058, 1.051815, 0.212818, 1.101494, -0.134772, 1.045757, 0.182143, 1.120587, -0.113071, 1.041169, 0.152867, 1.135399, -0.090411, 1.034844, 0.122796, 1.146612, -0.067477, 1.026974, 0.091888, 1.153168, -0.044849, 1.017303, 0.060779, 1.157912, -0.021998, 1.007735, 0.029919, 1.163607, 0.000121, 0.999959, 0.000003, 0.000200, -0.000216, 2.163956, 1.077737, 0.000504, -0.000543, 2.161128, 1.077732, 0.002016, -0.002173, 2.162732, 1.077729, 0.004535, -0.004887, 2.161402, 1.077749, 0.008066, -0.008692, 2.163252, 1.077732, 0.012599, -0.013576, 2.161300, 1.077727, 0.018145, -0.019546, 2.161151, 1.077702, 0.024702, -0.026599, 2.161223, 1.077675, 0.032272, -0.034729, 2.160949, 1.077632, 0.040862, -0.043936, 2.160967, 1.077575, 0.050470, -0.054203, 2.160035, 1.077473, 0.061113, -0.065528, 2.159490, 1.077348, 0.072794, -0.077882, 2.158517, 1.077178, 0.085528, -0.091030, 2.156605, 1.076937, 0.099337, -0.105251, 2.154828, 1.076631, 0.114228, -0.120456, 2.152812, 1.076229, 0.130202, -0.136573, 2.150298, 1.075713, 0.147284, -0.153306, 2.146752, 1.075031, 0.165480, -0.170931, 2.142744, 1.074173, 0.184793, -0.189083, 2.137475, 1.073063, 0.205224, -0.207840, 2.131320, 1.071683, 0.226743, -0.226939, 2.123154, 1.069914, 0.249401, -0.246344, 2.114086, 1.067718, 0.272955, -0.265640, 2.101599, 1.064924, 0.297494, -0.284846, 2.086612, 1.061512, 0.322731, -0.303452, 2.067356, 1.057359, 0.348451, -0.321330, 2.043711, 1.052294, 0.374451, -0.338201, 2.015033, 1.046153, 0.400454, -0.353816, 1.981139, 1.039003, 0.426434, -0.368216, 1.944128, 1.030498, 0.452088, -0.381251, 1.903094, 1.020454, 0.477901, -0.392833, 1.860402, 1.008793, 0.504173, -0.402408, 1.814402, 0.994791, 0.531520, -0.409545, 1.766273, 0.977733, 0.558049, -0.414351, 1.714119, 0.958625, 0.584778, -0.417437, 1.664612, 0.937189, 0.610808, -0.418519, 1.613793, 0.913543, 0.636915, -0.418094, 1.565942, 0.888137, 0.662204, -0.415742, 1.518783, 0.860728, 0.686848, -0.411746, 1.473306, 0.831793, 0.710992, -0.406153, 1.430153, 0.800862, 0.735382, -0.399519, 1.389824, 0.768768, 0.759079, -0.390927, 1.350744, 0.734825, 0.782912, -0.380111, 1.313559, 0.699450, 0.806746, -0.368383, 1.280028, 0.663191, 0.830269, -0.355606, 1.249814, 0.625927, 0.853305, -0.341988, 1.221138, 0.588644, 0.876326, -0.327545, 1.195837, 0.550849, 0.898322, -0.311779, 1.171844, 0.512694, 0.921811, -0.294944, 1.150671, 0.474225, 0.944563, -0.277333, 1.132224, 0.435772, 0.967089, -0.259340, 1.115422, 0.398001, 0.989754, -0.240836, 1.100405, 0.360802, 1.012470, -0.221293, 1.086533, 0.323566, 1.036426, -0.201191, 1.075496, 0.287387, 1.058709, -0.180590, 1.064233, 0.252184, 1.081593, -0.159810, 1.055296, 0.218441, 1.103146, -0.137772, 1.047978, 0.186223, 1.122814, -0.115347, 1.042693, 0.156019, 1.137790, -0.092582, 1.036049, 0.125579, 1.149184, -0.069152, 1.027944, 0.093986, 1.156062, -0.045661, 1.018039, 0.062122, 1.160733, -0.022719, 1.008072, 0.030650, 1.166487, 0.000231, 1.000063, -0.000120, 0.000201, -0.000228, 2.308308, 1.133128, 0.000504, -0.000571, 2.283756, 1.133123, 0.002016, -0.002284, 2.283756, 1.133123, 0.004535, -0.005138, 2.283310, 1.133144, 0.008048, -0.009119, 2.266192, 1.133138, 0.012600, -0.014274, 2.284377, 1.133110, 0.018147, -0.020553, 2.284204, 1.133093, 0.024702, -0.027964, 2.283517, 1.133060, 0.032272, -0.036510, 2.282997, 1.133007, 0.040866, -0.046188, 2.282986, 1.132930, 0.050481, -0.056979, 2.282260, 1.132824, 0.061133, -0.068881, 2.281533, 1.132678, 0.072830, -0.081850, 2.280504, 1.132481, 0.085592, -0.095657, 2.278304, 1.132202, 0.099431, -0.110594, 2.276269, 1.131845, 0.114360, -0.126590, 2.273890, 1.131383, 0.130388, -0.143454, 2.270761, 1.130784, 0.147547, -0.161029, 2.266794, 1.130003, 0.165836, -0.179523, 2.262332, 1.129016, 0.185269, -0.198527, 2.256326, 1.127738, 0.205822, -0.218138, 2.249031, 1.126156, 0.227527, -0.238141, 2.239993, 1.124132, 0.250325, -0.258302, 2.228878, 1.121594, 0.274070, -0.278329, 2.214204, 1.118449, 0.298793, -0.298310, 2.196654, 1.114528, 0.324131, -0.317462, 2.173394, 1.109783, 0.350101, -0.335853, 2.146395, 1.103901, 0.376293, -0.353064, 2.112341, 1.096954, 0.402547, -0.368950, 2.073700, 1.088642, 0.428791, -0.383462, 2.031152, 1.078946, 0.454976, -0.396635, 1.986661, 1.067536, 0.480566, -0.407873, 1.937038, 1.054403, 0.506154, -0.417303, 1.885155, 1.038894, 0.532862, -0.424194, 1.830369, 1.020535, 0.560354, -0.429344, 1.776976, 0.999295, 0.587114, -0.431949, 1.721214, 0.975990, 0.613345, -0.432547, 1.665739, 0.950239, 0.639335, -0.431338, 1.612200, 0.922467, 0.664996, -0.428473, 1.561035, 0.892593, 0.688947, -0.423355, 1.508240, 0.861325, 0.713403, -0.417235, 1.461776, 0.828289, 0.737649, -0.409848, 1.418888, 0.793863, 0.761275, -0.400901, 1.376807, 0.758074, 0.784778, -0.390174, 1.337204, 0.721974, 0.808762, -0.377683, 1.301527, 0.682718, 0.831993, -0.364037, 1.267144, 0.644001, 0.854696, -0.349494, 1.236023, 0.605478, 0.877933, -0.334499, 1.209284, 0.565588, 0.900180, -0.318435, 1.183967, 0.526138, 0.923039, -0.301669, 1.161513, 0.486524, 0.945895, -0.283298, 1.140838, 0.446747, 0.968069, -0.264438, 1.122475, 0.408041, 0.991179, -0.245463, 1.106968, 0.369477, 1.012926, -0.225680, 1.091435, 0.331626, 1.036995, -0.205401, 1.079561, 0.294288, 1.060909, -0.184310, 1.068215, 0.257696, 1.083531, -0.162846, 1.058133, 0.223343, 1.105644, -0.141040, 1.050851, 0.190541, 1.125691, -0.117965, 1.045001, 0.159310, 1.141297, -0.094377, 1.038028, 0.128238, 1.152672, -0.070831, 1.029694, 0.096282, 1.159333, -0.046853, 1.019136, 0.063720, 1.163819, -0.022991, 1.008518, 0.031234, 1.169564, 0.000125, 1.000069, -0.000024, 0.000202, -0.000241, 2.458341, 1.191742, 0.000504, -0.000600, 2.418738, 1.191740, 0.002015, -0.002401, 2.418821, 1.191730, 0.004535, -0.005405, 2.421986, 1.191756, 0.008071, -0.009618, 2.424988, 1.191753, 0.012600, -0.015012, 2.420242, 1.191727, 0.018145, -0.021612, 2.419937, 1.191703, 0.024704, -0.029410, 2.419746, 1.191662, 0.032278, -0.038398, 2.419409, 1.191604, 0.040874, -0.048574, 2.418995, 1.191515, 0.050496, -0.059920, 2.418190, 1.191389, 0.061160, -0.072432, 2.417487, 1.191221, 0.072871, -0.086009, 2.415853, 1.190984, 0.085664, -0.100559, 2.413669, 1.190664, 0.099543, -0.116283, 2.411423, 1.190256, 0.114520, -0.133071, 2.408711, 1.189719, 0.130616, -0.150670, 2.404900, 1.189019, 0.147856, -0.169197, 2.400512, 1.188125, 0.166235, -0.188545, 2.394939, 1.186972, 0.185804, -0.208480, 2.388232, 1.185515, 0.206488, -0.228883, 2.379190, 1.183673, 0.228383, -0.249897, 2.369208, 1.181382, 0.251305, -0.270851, 2.355459, 1.178478, 0.275349, -0.291780, 2.339142, 1.174857, 0.300106, -0.312257, 2.316655, 1.170411, 0.325849, -0.332225, 2.291540, 1.164883, 0.351782, -0.350862, 2.257242, 1.158196, 0.378248, -0.368431, 2.218671, 1.150173, 0.404674, -0.384428, 2.173680, 1.140703, 0.431385, -0.399230, 2.127083, 1.129555, 0.457407, -0.411875, 2.073236, 1.116436, 0.483275, -0.423013, 2.018223, 1.101373, 0.509278, -0.432624, 1.962674, 1.084257, 0.534751, -0.439261, 1.900814, 1.064592, 0.561895, -0.443801, 1.839558, 1.040881, 0.588677, -0.445872, 1.777763, 1.015208, 0.614900, -0.445896, 1.716550, 0.987252, 0.641051, -0.444148, 1.657984, 0.957271, 0.666409, -0.440299, 1.600832, 0.924841, 0.691872, -0.435318, 1.548237, 0.891185, 0.716638, -0.428631, 1.497572, 0.855929, 0.739864, -0.419872, 1.447043, 0.819676, 0.763707, -0.410456, 1.403648, 0.781455, 0.786744, -0.399390, 1.360844, 0.742965, 0.809585, -0.386381, 1.320529, 0.703260, 0.834164, -0.372622, 1.286467, 0.662385, 0.856713, -0.357177, 1.252306, 0.621379, 0.879820, -0.341458, 1.223070, 0.580238, 0.902721, -0.325024, 1.197115, 0.539028, 0.924650, -0.307543, 1.172314, 0.498592, 0.947613, -0.289557, 1.151171, 0.457980, 0.969590, -0.269799, 1.129986, 0.417696, 0.992961, -0.250111, 1.113321, 0.377529, 1.014582, -0.229761, 1.097149, 0.339096, 1.038069, -0.209375, 1.083913, 0.301119, 1.061661, -0.188038, 1.071241, 0.263506, 1.085069, -0.165874, 1.060508, 0.227921, 1.107744, -0.143437, 1.052930, 0.194062, 1.127982, -0.120574, 1.046396, 0.162506, 1.144541, -0.096569, 1.039880, 0.130788, 1.155876, -0.072039, 1.030946, 0.098057, 1.162719, -0.047888, 1.020124, 0.064956, 1.167089, -0.023740, 1.008953, 0.031966, 1.172775, 0.000277, 1.000067, -0.000111, 0.000200, -0.000251, 2.573709, 1.253951, 0.000504, -0.000632, 2.572401, 1.253940, 0.002015, -0.002527, 2.571267, 1.253927, 0.004535, -0.005687, 2.572481, 1.253948, 0.008062, -0.010108, 2.571851, 1.253941, 0.012588, -0.015780, 2.568431, 1.253934, 0.018139, -0.022731, 2.569765, 1.253893, 0.024709, -0.030948, 2.572115, 1.253853, 0.032283, -0.040401, 2.571456, 1.253785, 0.040883, -0.051105, 2.571041, 1.253683, 0.050514, -0.063041, 2.570153, 1.253538, 0.061188, -0.076195, 2.569085, 1.253336, 0.072926, -0.090402, 2.567184, 1.253065, 0.085746, -0.105745, 2.564731, 1.252697, 0.099661, -0.122296, 2.561995, 1.252218, 0.114699, -0.139912, 2.559019, 1.251590, 0.130882, -0.158362, 2.555017, 1.250766, 0.148202, -0.177856, 2.549419, 1.249744, 0.166706, -0.198049, 2.542908, 1.248423, 0.186404, -0.219014, 2.535205, 1.246741, 0.207272, -0.240376, 2.524893, 1.244596, 0.229345, -0.262230, 2.512804, 1.241917, 0.252494, -0.284134, 2.496923, 1.238610, 0.276690, -0.305828, 2.476583, 1.234474, 0.301798, -0.327107, 2.451548, 1.229292, 0.327423, -0.347300, 2.418630, 1.222997, 0.353848, -0.366699, 2.381002, 1.215366, 0.380342, -0.384421, 2.334413, 1.206199, 0.407390, -0.400855, 2.285660, 1.195374, 0.433913, -0.415241, 2.228604, 1.182290, 0.460837, -0.428275, 2.171532, 1.167385, 0.486381, -0.438573, 2.105639, 1.150401, 0.511959, -0.447348, 2.040835, 1.130990, 0.537586, -0.454152, 1.974797, 1.109302, 0.564035, -0.458684, 1.907895, 1.084131, 0.590690, -0.460058, 1.839482, 1.055803, 0.617250, -0.459662, 1.772332, 1.025103, 0.643406, -0.457260, 1.707313, 0.992502, 0.668794, -0.452666, 1.644722, 0.957657, 0.693930, -0.446641, 1.586832, 0.921340, 0.718708, -0.439121, 1.531197, 0.883841, 0.743469, -0.430429, 1.480765, 0.844931, 0.766080, -0.419622, 1.430338, 0.804786, 0.789801, -0.408368, 1.386295, 0.764206, 0.812718, -0.395392, 1.343758, 0.722565, 0.835453, -0.380699, 1.304655, 0.680585, 0.858801, -0.364834, 1.269287, 0.637235, 0.881537, -0.348092, 1.237493, 0.594579, 0.904656, -0.331087, 1.208862, 0.552313, 0.926357, -0.312966, 1.182365, 0.510080, 0.949001, -0.294684, 1.159452, 0.468677, 0.971598, -0.275361, 1.138706, 0.426723, 0.994905, -0.254947, 1.120552, 0.385875, 1.017981, -0.234109, 1.104215, 0.345751, 1.040840, -0.213040, 1.089276, 0.306762, 1.063893, -0.191616, 1.075845, 0.269066, 1.086907, -0.169272, 1.063788, 0.232171, 1.109937, -0.146076, 1.054977, 0.197826, 1.130808, -0.122544, 1.048572, 0.165272, 1.146831, -0.098492, 1.040742, 0.133280, 1.158955, -0.073710, 1.031818, 0.100262, 1.166161, -0.048610, 1.020747, 0.066165, 1.170491, -0.024209, 1.009380, 0.032741, 1.176111, 0.000010, 1.000042, 0.000056, 0.000202, -0.000267, 2.786357, 1.320169, 0.000504, -0.000665, 2.741889, 1.320168, 0.002015, -0.002660, 2.740000, 1.320143, 0.004536, -0.005987, 2.744276, 1.320161, 0.008063, -0.010644, 2.743432, 1.320162, 0.012600, -0.016628, 2.741741, 1.320148, 0.018144, -0.023937, 2.741314, 1.320127, 0.024708, -0.032577, 2.741916, 1.320061, 0.032290, -0.042536, 2.742132, 1.319976, 0.040894, -0.053799, 2.741199, 1.319861, 0.050533, -0.066361, 2.740258, 1.319691, 0.061223, -0.080202, 2.739045, 1.319458, 0.072985, -0.095109, 2.736519, 1.319138, 0.085841, -0.111296, 2.733903, 1.318715, 0.099808, -0.128685, 2.730944, 1.318156, 0.114903, -0.147202, 2.727293, 1.317424, 0.131164, -0.166575, 2.722169, 1.316485, 0.148599, -0.187019, 2.716148, 1.315274, 0.167245, -0.208240, 2.708701, 1.313733, 0.187078, -0.230151, 2.698998, 1.311792, 0.208153, -0.252538, 2.687341, 1.309343, 0.230418, -0.275295, 2.672621, 1.306247, 0.253802, -0.298066, 2.653619, 1.302374, 0.278261, -0.320673, 2.629943, 1.297573, 0.303527, -0.342528, 2.599228, 1.291625, 0.329571, -0.363531, 2.562226, 1.284374, 0.355939, -0.382963, 2.515491, 1.275478, 0.382987, -0.401306, 2.464858, 1.264866, 0.409917, -0.417455, 2.404877, 1.252184, 0.437015, -0.432067, 2.341408, 1.237415, 0.463474, -0.444204, 2.271837, 1.220687, 0.489835, -0.454631, 2.200593, 1.200973, 0.516054, -0.463338, 2.129733, 1.179346, 0.541397, -0.469425, 2.055635, 1.155039, 0.566798, -0.473526, 1.980812, 1.127866, 0.593114, -0.474632, 1.904723, 1.097304, 0.619945, -0.473597, 1.832456, 1.063603, 0.646325, -0.470656, 1.761501, 1.027971, 0.672320, -0.465675, 1.694248, 0.990692, 0.697163, -0.458527, 1.629227, 0.951582, 0.721472, -0.449904, 1.568132, 0.911197, 0.745855, -0.440140, 1.512084, 0.869745, 0.770089, -0.429338, 1.460694, 0.827648, 0.792546, -0.416701, 1.410739, 0.784728, 0.815161, -0.403151, 1.365438, 0.741884, 0.837994, -0.388714, 1.324811, 0.697800, 0.861220, -0.372573, 1.287723, 0.653341, 0.883737, -0.355024, 1.252491, 0.609455, 0.906784, -0.337092, 1.221844, 0.565275, 0.928493, -0.318370, 1.192881, 0.521558, 0.951495, -0.299605, 1.169131, 0.478149, 0.973586, -0.280067, 1.146316, 0.436325, 0.996400, -0.259823, 1.127860, 0.394409, 1.019780, -0.238313, 1.110521, 0.353045, 1.042775, -0.216506, 1.093915, 0.312803, 1.066822, -0.194695, 1.080326, 0.274100, 1.089869, -0.172290, 1.067722, 0.236657, 1.113606, -0.149264, 1.058471, 0.201603, 1.134229, -0.124814, 1.050701, 0.168398, 1.150922, -0.100070, 1.043051, 0.135616, 1.163224, -0.075155, 1.033742, 0.102144, 1.169965, -0.049933, 1.021818, 0.067532, 1.174200, -0.024461, 1.009916, 0.033215, 1.179766, 0.000188, 1.000045, -0.000014, 0.000202, -0.000281, 2.964186, 1.390880, 0.000505, -0.000702, 2.945157, 1.390903, 0.002015, -0.002802, 2.931184, 1.390863, 0.004535, -0.006307, 2.935673, 1.390900, 0.008063, -0.011213, 2.934274, 1.390890, 0.012598, -0.017516, 2.932216, 1.390876, 0.018147, -0.025221, 2.933324, 1.390832, 0.024711, -0.034322, 2.933945, 1.390769, 0.032295, -0.044810, 2.933496, 1.390674, 0.040904, -0.056673, 2.932487, 1.390538, 0.050555, -0.069906, 2.931571, 1.390342, 0.061259, -0.084468, 2.929914, 1.390064, 0.073053, -0.100152, 2.927039, 1.389695, 0.085948, -0.117202, 2.924241, 1.389201, 0.099968, -0.135531, 2.920760, 1.388548, 0.115135, -0.154906, 2.915998, 1.387692, 0.131496, -0.175352, 2.910285, 1.386611, 0.149049, -0.196783, 2.903174, 1.385190, 0.167848, -0.219066, 2.894584, 1.383407, 0.187879, -0.241983, 2.883171, 1.381148, 0.209143, -0.265398, 2.869102, 1.378261, 0.231689, -0.289254, 2.852238, 1.374690, 0.255223, -0.312776, 2.828264, 1.370166, 0.279952, -0.336260, 2.800175, 1.364591, 0.305572, -0.358865, 2.764282, 1.357758, 0.331650, -0.380223, 2.717845, 1.349413, 0.358491, -0.400252, 2.665326, 1.339084, 0.385445, -0.418422, 2.602293, 1.326773, 0.412947, -0.434993, 2.536973, 1.312141, 0.439681, -0.448757, 2.459463, 1.295205, 0.467272, -0.461427, 2.386250, 1.275573, 0.493568, -0.471102, 2.303225, 1.253400, 0.519743, -0.478930, 2.221945, 1.228890, 0.544882, -0.484098, 2.136425, 1.201730, 0.570690, -0.488125, 2.057093, 1.172022, 0.595905, -0.489185, 1.975334, 1.139312, 0.622747, -0.487535, 1.895055, 1.103038, 0.648695, -0.483482, 1.815995, 1.064364, 0.675159, -0.478096, 1.744272, 1.024098, 0.700714, -0.470492, 1.675257, 0.982186, 0.725641, -0.461398, 1.609135, 0.939137, 0.748552, -0.449825, 1.545091, 0.894791, 0.772808, -0.438185, 1.489394, 0.850373, 0.795928, -0.425073, 1.437026, 0.805287, 0.818900, -0.411028, 1.389654, 0.760003, 0.841633, -0.396047, 1.345873, 0.714914, 0.863213, -0.379637, 1.305185, 0.669271, 0.886662, -0.362227, 1.269147, 0.622935, 0.908504, -0.343068, 1.234714, 0.577757, 0.931425, -0.323982, 1.204997, 0.532922, 0.953835, -0.304347, 1.178871, 0.488154, 0.975813, -0.284219, 1.155019, 0.444885, 0.997662, -0.263544, 1.133941, 0.402224, 1.021167, -0.242611, 1.116100, 0.360530, 1.044038, -0.220065, 1.098348, 0.318968, 1.068837, -0.197580, 1.084605, 0.279107, 1.092548, -0.174779, 1.071217, 0.241111, 1.116157, -0.151596, 1.060486, 0.204913, 1.137486, -0.127478, 1.052751, 0.171410, 1.154694, -0.101915, 1.044807, 0.137999, 1.166867, -0.076246, 1.034824, 0.103807, 1.173715, -0.050661, 1.022501, 0.068802, 1.178236, -0.025355, 1.010324, 0.034155, 1.183545, 0.000205, 1.000059, -0.000110, 0.000201, -0.000294, 3.161080, 1.466721, 0.000505, -0.000740, 3.155526, 1.466737, 0.002016, -0.002957, 3.152852, 1.466688, 0.004537, -0.006655, 3.150654, 1.466667, 0.008066, -0.011828, 3.153109, 1.466694, 0.012604, -0.018479, 3.152143, 1.466721, 0.018150, -0.026598, 3.151025, 1.466636, 0.024714, -0.036191, 3.150300, 1.466562, 0.032301, -0.047249, 3.149861, 1.466450, 0.040924, -0.059766, 3.149548, 1.466289, 0.050579, -0.073703, 3.147516, 1.466055, 0.061306, -0.089022, 3.145680, 1.465738, 0.073135, -0.105563, 3.142428, 1.465301, 0.086075, -0.123544, 3.139113, 1.464715, 0.100153, -0.142853, 3.135064, 1.463956, 0.115411, -0.163183, 3.129509, 1.462962, 0.131876, -0.184760, 3.122959, 1.461670, 0.149570, -0.207172, 3.114153, 1.460045, 0.168523, -0.230578, 3.103626, 1.457945, 0.188784, -0.254658, 3.090818, 1.455279, 0.210264, -0.279114, 3.073352, 1.451998, 0.233030, -0.303930, 3.052592, 1.447780, 0.256959, -0.328517, 3.025187, 1.442568, 0.281901, -0.352755, 2.990341, 1.436026, 0.307728, -0.375894, 2.946820, 1.427979, 0.334197, -0.397924, 2.892845, 1.418249, 0.360966, -0.417914, 2.827937, 1.406370, 0.388478, -0.436526, 2.758006, 1.392134, 0.415567, -0.452366, 2.674696, 1.375244, 0.443518, -0.466917, 2.595136, 1.355660, 0.470631, -0.478417, 2.504173, 1.333123, 0.497419, -0.487825, 2.413227, 1.308181, 0.523961, -0.495064, 2.321239, 1.280227, 0.549708, -0.499844, 2.228911, 1.249894, 0.575296, -0.502844, 2.138834, 1.217130, 0.600168, -0.503368, 2.049030, 1.181412, 0.625874, -0.501622, 1.962267, 1.142648, 0.652164, -0.496936, 1.876900, 1.101268, 0.678029, -0.490319, 1.796344, 1.057782, 0.703248, -0.481575, 1.718925, 1.012884, 0.728520, -0.471822, 1.648358, 0.966487, 0.752577, -0.460134, 1.581989, 0.919880, 0.776163, -0.447164, 1.520109, 0.873087, 0.800016, -0.433601, 1.465081, 0.825803, 0.822176, -0.418388, 1.412564, 0.778249, 0.844873, -0.402704, 1.366184, 0.730849, 0.865955, -0.385633, 1.321865, 0.684037, 0.888173, -0.368255, 1.283464, 0.637192, 0.910994, -0.349332, 1.249215, 0.590131, 0.934270, -0.329612, 1.218366, 0.543213, 0.956653, -0.309228, 1.189808, 0.497752, 0.978476, -0.288310, 1.163674, 0.452837, 1.000755, -0.267243, 1.141389, 0.409481, 1.023827, -0.246015, 1.122012, 0.367354, 1.045572, -0.223777, 1.103303, 0.325171, 1.070445, -0.200837, 1.088010, 0.284442, 1.094268, -0.177211, 1.073650, 0.245138, 1.118639, -0.153531, 1.063051, 0.208289, 1.139786, -0.129074, 1.053921, 0.173607, 1.157848, -0.104051, 1.045968, 0.140467, 1.170697, -0.077694, 1.035782, 0.105594, 1.177874, -0.051393, 1.023483, 0.069898, 1.182242, -0.025392, 1.010620, 0.034532, 1.187612, -0.000032, 1.000062, -0.000035, 0.000202, -0.000313, 3.450327, 1.548291, 0.000504, -0.000780, 3.396162, 1.548289, 0.002015, -0.003120, 3.395621, 1.548260, 0.004533, -0.007019, 3.394299, 1.548217, 0.008066, -0.012486, 3.398803, 1.548274, 0.012600, -0.019500, 3.396363, 1.548245, 0.018151, -0.028076, 3.396805, 1.548192, 0.024722, -0.038209, 3.396384, 1.548109, 0.032306, -0.049868, 3.395158, 1.547979, 0.040936, -0.063077, 3.394303, 1.547785, 0.050610, -0.077791, 3.392979, 1.547513, 0.061360, -0.093869, 3.389910, 1.547134, 0.073227, -0.111380, 3.386669, 1.546619, 0.086217, -0.130371, 3.382974, 1.545938, 0.100364, -0.150684, 3.378046, 1.545039, 0.115733, -0.172116, 3.371719, 1.543880, 0.132309, -0.194809, 3.363764, 1.542380, 0.150174, -0.218431, 3.353699, 1.540462, 0.169340, -0.242954, 3.341397, 1.538002, 0.189788, -0.268175, 3.324957, 1.534894, 0.211581, -0.293776, 3.304776, 1.530954, 0.234561, -0.319619, 3.278192, 1.526033, 0.258776, -0.345089, 3.244910, 1.519926, 0.284059, -0.370176, 3.203338, 1.512296, 0.310312, -0.394171, 3.152477, 1.502956, 0.336748, -0.416137, 3.083616, 1.491463, 0.364029, -0.436752, 3.010481, 1.477493, 0.391575, -0.455102, 2.925454, 1.460933, 0.419409, -0.471378, 2.834380, 1.441554, 0.446811, -0.484714, 2.733329, 1.418861, 0.474489, -0.496021, 2.633630, 1.393405, 0.501751, -0.504991, 2.530935, 1.364633, 0.528488, -0.511392, 2.426653, 1.333234, 0.554428, -0.515395, 2.323633, 1.299138, 0.580434, -0.517761, 2.224964, 1.262462, 0.605474, -0.517598, 2.127228, 1.223784, 0.629888, -0.514946, 2.030545, 1.182321, 0.655579, -0.510177, 1.939070, 1.138515, 0.681940, -0.503097, 1.852355, 1.091502, 0.707228, -0.493537, 1.768084, 1.043464, 0.731894, -0.482372, 1.690840, 0.994242, 0.756741, -0.470312, 1.619277, 0.944749, 0.780160, -0.456412, 1.553430, 0.894816, 0.803384, -0.441492, 1.493357, 0.845202, 0.826347, -0.425944, 1.437830, 0.795954, 0.849145, -0.409532, 1.388578, 0.746915, 0.870617, -0.391988, 1.341527, 0.698025, 0.892943, -0.374229, 1.302188, 0.649579, 0.913828, -0.355148, 1.262877, 0.601833, 0.936830, -0.335238, 1.230136, 0.554521, 0.958687, -0.313939, 1.199596, 0.507208, 0.982008, -0.292741, 1.173619, 0.461357, 1.003691, -0.270940, 1.149015, 0.416031, 1.027223, -0.249102, 1.128689, 0.372457, 1.050048, -0.226899, 1.109444, 0.330281, 1.074105, -0.204329, 1.092943, 0.288987, 1.098971, -0.180560, 1.078591, 0.249075, 1.123324, -0.155987, 1.066885, 0.211519, 1.145445, -0.130929, 1.057617, 0.176506, 1.162856, -0.105269, 1.048453, 0.142345, 1.175360, -0.079267, 1.037439, 0.107452, 1.182514, -0.052547, 1.024393, 0.071252, 1.186575, -0.025744, 1.011093, 0.035019, 1.192050, 0.000318, 1.000013, -0.000152, 0.000204, -0.000334, 3.909175, 1.636412, 0.000504, -0.000825, 3.678647, 1.636410, 0.002015, -0.003298, 3.678315, 1.636387, 0.004533, -0.007417, 3.674126, 1.636310, 0.008062, -0.013190, 3.676771, 1.636376, 0.012603, -0.020613, 3.678135, 1.636369, 0.018153, -0.029675, 3.677315, 1.636299, 0.024723, -0.040378, 3.676872, 1.636196, 0.032318, -0.052708, 3.675750, 1.636038, 0.040955, -0.066660, 3.674803, 1.635810, 0.050645, -0.082203, 3.672735, 1.635494, 0.061429, -0.099150, 3.669047, 1.635048, 0.073333, -0.117679, 3.665401, 1.634437, 0.086388, -0.137725, 3.661315, 1.633634, 0.100620, -0.159081, 3.654992, 1.632571, 0.116087, -0.181721, 3.647341, 1.631202, 0.132820, -0.205611, 3.637877, 1.629432, 0.150867, -0.230542, 3.626333, 1.627161, 0.170234, -0.256239, 3.610671, 1.624266, 0.190981, -0.282751, 3.591685, 1.620589, 0.213013, -0.309430, 3.565864, 1.615999, 0.236387, -0.336427, 3.534826, 1.610216, 0.260943, -0.362931, 3.493984, 1.603047, 0.286497, -0.388644, 3.442075, 1.593920, 0.312769, -0.412912, 3.375973, 1.582961, 0.339832, -0.435635, 3.299355, 1.569343, 0.367214, -0.456181, 3.208994, 1.553137, 0.394935, -0.474325, 3.108910, 1.533791, 0.422935, -0.490318, 3.001767, 1.511093, 0.451166, -0.503827, 2.891735, 1.485145, 0.478695, -0.514185, 2.773430, 1.455617, 0.506313, -0.522502, 2.657639, 1.422946, 0.533427, -0.528119, 2.541132, 1.387843, 0.559942, -0.531430, 2.426950, 1.349542, 0.585150, -0.531978, 2.312437, 1.309303, 0.610500, -0.531054, 2.205966, 1.266280, 0.635380, -0.528058, 2.101993, 1.221709, 0.659852, -0.522751, 2.002950, 1.175062, 0.685151, -0.515026, 1.908647, 1.125078, 0.710920, -0.505020, 1.819389, 1.074296, 0.736066, -0.493268, 1.735806, 1.022420, 0.760503, -0.480032, 1.658607, 0.970230, 0.785091, -0.465986, 1.589424, 0.917077, 0.807523, -0.449721, 1.522533, 0.864888, 0.830974, -0.433461, 1.465416, 0.813006, 0.852659, -0.415808, 1.409076, 0.761689, 0.874841, -0.397855, 1.360758, 0.711258, 0.896322, -0.379041, 1.316829, 0.661721, 0.918134, -0.360048, 1.278574, 0.612263, 0.939356, -0.340108, 1.242200, 0.564369, 0.961025, -0.318877, 1.210305, 0.516506, 0.984371, -0.297130, 1.183689, 0.469342, 1.006905, -0.274661, 1.157466, 0.423080, 1.029941, -0.252234, 1.135066, 0.378315, 1.052751, -0.229268, 1.114518, 0.335169, 1.077981, -0.206662, 1.097760, 0.293336, 1.102542, -0.183331, 1.082051, 0.252984, 1.126539, -0.158797, 1.068935, 0.214990, 1.149023, -0.133014, 1.058996, 0.178903, 1.167550, -0.106641, 1.050245, 0.144559, 1.179994, -0.079952, 1.038648, 0.108667, 1.187104, -0.053316, 1.025284, 0.072209, 1.191406, -0.026826, 1.011453, 0.035833, 1.196748, 0.000226, 1.000034, -0.000061, 0.000200, -0.000346, 3.996419, 1.732034, 0.000504, -0.000873, 4.000138, 1.732038, 0.002016, -0.003492, 4.002078, 1.732012, 0.004538, -0.007859, 4.005626, 1.731962, 0.008064, -0.013963, 3.998500, 1.731999, 0.012590, -0.021794, 3.995024, 1.732004, 0.018154, -0.031406, 3.999233, 1.731901, 0.024727, -0.042733, 3.998497, 1.731774, 0.032327, -0.055781, 3.997064, 1.731599, 0.040974, -0.070543, 3.995856, 1.731325, 0.050685, -0.086984, 3.993839, 1.730945, 0.061506, -0.104897, 3.989519, 1.730417, 0.073458, -0.124506, 3.985313, 1.729697, 0.086573, -0.145706, 3.979984, 1.728747, 0.100909, -0.168211, 3.972562, 1.727491, 0.116509, -0.192198, 3.963836, 1.725854, 0.133404, -0.217280, 3.951919, 1.723749, 0.151659, -0.243556, 3.937734, 1.721093, 0.171288, -0.270611, 3.919021, 1.717640, 0.192301, -0.298389, 3.895171, 1.713272, 0.214683, -0.326338, 3.864171, 1.707825, 0.238392, -0.354394, 3.824682, 1.700956, 0.263151, -0.381636, 3.771168, 1.692392, 0.289155, -0.408266, 3.709961, 1.681769, 0.315832, -0.433070, 3.630302, 1.668539, 0.342942, -0.455741, 3.534719, 1.652513, 0.370892, -0.476655, 3.431531, 1.633428, 0.398985, -0.494692, 3.314933, 1.610694, 0.427206, -0.510313, 3.189741, 1.584240, 0.455266, -0.522760, 3.058325, 1.554195, 0.483472, -0.532872, 2.927213, 1.520805, 0.511192, -0.540229, 2.794112, 1.484026, 0.538706, -0.545105, 2.663786, 1.443796, 0.565422, -0.547251, 2.534841, 1.401429, 0.591270, -0.547115, 2.408437, 1.356231, 0.616787, -0.545113, 2.291284, 1.308887, 0.641380, -0.540853, 2.177478, 1.260447, 0.665344, -0.534561, 2.069265, 1.210634, 0.690147, -0.527115, 1.969776, 1.158569, 0.714578, -0.516171, 1.870847, 1.104593, 0.740349, -0.504048, 1.782674, 1.049578, 0.764563, -0.489683, 1.698614, 0.994458, 0.788710, -0.474541, 1.624447, 0.938612, 0.812154, -0.458099, 1.554453, 0.883694, 0.834566, -0.440345, 1.490045, 0.830220, 0.857486, -0.422491, 1.432889, 0.776499, 0.879224, -0.403588, 1.380669, 0.724257, 0.899971, -0.383819, 1.333124, 0.673311, 0.922111, -0.364250, 1.292648, 0.622999, 0.942842, -0.343873, 1.253933, 0.573304, 0.964398, -0.323206, 1.221027, 0.525090, 0.986860, -0.301711, 1.191806, 0.477580, 1.009760, -0.278695, 1.165162, 0.430624, 1.033347, -0.255591, 1.141715, 0.384482, 1.055937, -0.232039, 1.119739, 0.340532, 1.081178, -0.208664, 1.102117, 0.297311, 1.105696, -0.184935, 1.085062, 0.256227, 1.129575, -0.160673, 1.070918, 0.217709, 1.152135, -0.135414, 1.060642, 0.181471, 1.171221, -0.108462, 1.051041, 0.146380, 1.184412, -0.081008, 1.039694, 0.110120, 1.191820, -0.053710, 1.025903, 0.073052, 1.196195, -0.026625, 1.011816, 0.036129, 1.201677, -0.000175, 0.999945, 0.000098, 0.000196, -0.000360, 4.100786, 1.836290, 0.000504, -0.000925, 4.370184, 1.836295, 0.002018, -0.003706, 4.385247, 1.836243, 0.004534, -0.008324, 4.370146, 1.836210, 0.008064, -0.014805, 4.372335, 1.836256, 0.012597, -0.023116, 4.359918, 1.836259, 0.018158, -0.033299, 4.371503, 1.836123, 0.024732, -0.045301, 4.370533, 1.835988, 0.032344, -0.059143, 4.369649, 1.835768, 0.040999, -0.074779, 4.367861, 1.835454, 0.050739, -0.092178, 4.364322, 1.834974, 0.061594, -0.111161, 4.359221, 1.834355, 0.073604, -0.131958, 4.354620, 1.833499, 0.086796, -0.154393, 4.347915, 1.832355, 0.101246, -0.178201, 4.339152, 1.830880, 0.116990, -0.203531, 4.328327, 1.828936, 0.134086, -0.230043, 4.314240, 1.826442, 0.152589, -0.257718, 4.296795, 1.823230, 0.172514, -0.286176, 4.273985, 1.819124, 0.193853, -0.315295, 4.244136, 1.813909, 0.216582, -0.344507, 4.205152, 1.807410, 0.240668, -0.373646, 4.154781, 1.799084, 0.265904, -0.401897, 4.091563, 1.788905, 0.292226, -0.429136, 4.013199, 1.776206, 0.319045, -0.454057, 3.912886, 1.760500, 0.346721, -0.477219, 3.800927, 1.741586, 0.374849, -0.497883, 3.675652, 1.718818, 0.403078, -0.515504, 3.536892, 1.692138, 0.431597, -0.530621, 3.391351, 1.661434, 0.460246, -0.542852, 3.242817, 1.626989, 0.488899, -0.552238, 3.093685, 1.588582, 0.517215, -0.559045, 2.944163, 1.546300, 0.544480, -0.562351, 2.794189, 1.501299, 0.571542, -0.563394, 2.650239, 1.453758, 0.598167, -0.562590, 2.513757, 1.403321, 0.624104, -0.559636, 2.384203, 1.352431, 0.648789, -0.554148, 2.259149, 1.298758, 0.672715, -0.546779, 2.140250, 1.244943, 0.696258, -0.537896, 2.030401, 1.189971, 0.720048, -0.527401, 1.928311, 1.134526, 0.744078, -0.514142, 1.830175, 1.076504, 0.768895, -0.499352, 1.740731, 1.018032, 0.792551, -0.482982, 1.658911, 0.960250, 0.817007, -0.466406, 1.586579, 0.903029, 0.839035, -0.447616, 1.516969, 0.846484, 0.862742, -0.429261, 1.458675, 0.791420, 0.884307, -0.409479, 1.402989, 0.737125, 0.905641, -0.389303, 1.352817, 0.683912, 0.926185, -0.368344, 1.306684, 0.632690, 0.947229, -0.347366, 1.267395, 0.581739, 0.969502, -0.326720, 1.233192, 0.532305, 0.990758, -0.304973, 1.201017, 0.484166, 1.012749, -0.282816, 1.173018, 0.437385, 1.035533, -0.259084, 1.147184, 0.390755, 1.059915, -0.235239, 1.125388, 0.345399, 1.084348, -0.211044, 1.105859, 0.301356, 1.109544, -0.186698, 1.088888, 0.259708, 1.133770, -0.161900, 1.073848, 0.220324, 1.157553, -0.136604, 1.063190, 0.183857, 1.176461, -0.110428, 1.053110, 0.148521, 1.190137, -0.082898, 1.041484, 0.112124, 1.197215, -0.054554, 1.026844, 0.074160, 1.201654, -0.026744, 1.012264, 0.036527, 1.207085, 0.000399, 1.000034, -0.000201, 0.000191, -0.000373, 4.194318, 1.950551, 0.000504, -0.000983, 4.804350, 1.950552, 0.002015, -0.003931, 4.802820, 1.950518, 0.004536, -0.008847, 4.805254, 1.950472, 0.008064, -0.015725, 4.804152, 1.950517, 0.012693, -0.024740, 4.826828, 1.949914, 0.018159, -0.035365, 4.803103, 1.950349, 0.024740, -0.048122, 4.803220, 1.950183, 0.032361, -0.062822, 4.801522, 1.949917, 0.041034, -0.079430, 4.799593, 1.949538, 0.050815, -0.097841, 4.797179, 1.948972, 0.061702, -0.118026, 4.789557, 1.948246, 0.073766, -0.140112, 4.783293, 1.947204, 0.087066, -0.163819, 4.775698, 1.945855, 0.101637, -0.189122, 4.764612, 1.944052, 0.117558, -0.215884, 4.751486, 1.941710, 0.134884, -0.243968, 4.734791, 1.938727, 0.153637, -0.273170, 4.712078, 1.934891, 0.173890, -0.303146, 4.683575, 1.929976, 0.195643, -0.333704, 4.646766, 1.923740, 0.218767, -0.364170, 4.596814, 1.915888, 0.243337, -0.394530, 4.535509, 1.905970, 0.268860, -0.423512, 4.452006, 1.893623, 0.295173, -0.450609, 4.345682, 1.878286, 0.322784, -0.476488, 4.231632, 1.859391, 0.350616, -0.499420, 4.093553, 1.836912, 0.379127, -0.519862, 3.944127, 1.809625, 0.407860, -0.537373, 3.782223, 1.778529, 0.436717, -0.551802, 3.615563, 1.742684, 0.465345, -0.562951, 3.440672, 1.702289, 0.494158, -0.571334, 3.268070, 1.658666, 0.522896, -0.577227, 3.100668, 1.611027, 0.551379, -0.580514, 2.937615, 1.559742, 0.578992, -0.580610, 2.778703, 1.507257, 0.605095, -0.577729, 2.621626, 1.451941, 0.630653, -0.573000, 2.476506, 1.395218, 0.656175, -0.566944, 2.341592, 1.337862, 0.681036, -0.558988, 2.216478, 1.279275, 0.704713, -0.549211, 2.096972, 1.220526, 0.726894, -0.537190, 1.983311, 1.161709, 0.749865, -0.524167, 1.881100, 1.102095, 0.773553, -0.508991, 1.785637, 1.042039, 0.797102, -0.491658, 1.697234, 0.981588, 0.821187, -0.474093, 1.620250, 0.921265, 0.843848, -0.454980, 1.547071, 0.862757, 0.866662, -0.435421, 1.482008, 0.804700, 0.888696, -0.414990, 1.424116, 0.749432, 0.910945, -0.394472, 1.372658, 0.694767, 0.932300, -0.373239, 1.325157, 0.641106, 0.952850, -0.351347, 1.282217, 0.589689, 0.974718, -0.329809, 1.244897, 0.539322, 0.996445, -0.307902, 1.212306, 0.490083, 1.017580, -0.285392, 1.181402, 0.442702, 1.040342, -0.262782, 1.155996, 0.395911, 1.064399, -0.238995, 1.131708, 0.350206, 1.089464, -0.214297, 1.111215, 0.305175, 1.115565, -0.189293, 1.093094, 0.262686, 1.140640, -0.163843, 1.077994, 0.223078, 1.163824, -0.137789, 1.066014, 0.185651, 1.182577, -0.111087, 1.055615, 0.150045, 1.195775, -0.083945, 1.042940, 0.113457, 1.203175, -0.056145, 1.028015, 0.075453, 1.207282, -0.027685, 1.012552, 0.037217, 1.213019, 0.000362, 0.999938, -0.000293, 0.000187, -0.000388, 4.316009, 2.076500, 0.000504, -0.001048, 5.317799, 2.076499, 0.002014, -0.004182, 5.306557, 2.076523, 0.004539, -0.009425, 5.317505, 2.076453, 0.008063, -0.016737, 5.312143, 2.076410, 0.012614, -0.026171, 5.316434, 2.076389, 0.018158, -0.037641, 5.307836, 2.076265, 0.024767, -0.051266, 5.315297, 2.076044, 0.032372, -0.066859, 5.307433, 2.075743, 0.041066, -0.084538, 5.304809, 2.075270, 0.050871, -0.104062, 5.299277, 2.074622, 0.061821, -0.125613, 5.293419, 2.073708, 0.073970, -0.149085, 5.286629, 2.072457, 0.087375, -0.174214, 5.275937, 2.070804, 0.102105, -0.201136, 5.263267, 2.068647, 0.118223, -0.229505, 5.246309, 2.065846, 0.135814, -0.259217, 5.225496, 2.062189, 0.154887, -0.289990, 5.196580, 2.057566, 0.175510, -0.321618, 5.160716, 2.051593, 0.197636, -0.353632, 5.112202, 2.043949, 0.221168, -0.385303, 5.046981, 2.034445, 0.246099, -0.416511, 4.965386, 2.022368, 0.272070, -0.446377, 4.860735, 2.007160, 0.299090, -0.474279, 4.735140, 1.988598, 0.326702, -0.499809, 4.584962, 1.965865, 0.355017, -0.522790, 4.420447, 1.938705, 0.383856, -0.542755, 4.241942, 1.906370, 0.413059, -0.559903, 4.053302, 1.869455, 0.441882, -0.573174, 3.852753, 1.827946, 0.471516, -0.584151, 3.660377, 1.781652, 0.500872, -0.591843, 3.466027, 1.730885, 0.529677, -0.596253, 3.272812, 1.676821, 0.557683, -0.597604, 3.084286, 1.620064, 0.585652, -0.596591, 2.906111, 1.560909, 0.612819, -0.593138, 2.738258, 1.500318, 0.639848, -0.588245, 2.584172, 1.438127, 0.664758, -0.580140, 2.430697, 1.375746, 0.688754, -0.570189, 2.290701, 1.312727, 0.712848, -0.559420, 2.162679, 1.250063, 0.735111, -0.546570, 2.042186, 1.187840, 0.757521, -0.532944, 1.933435, 1.125513, 0.780056, -0.517981, 1.833524, 1.063827, 0.802513, -0.500724, 1.739053, 1.002154, 0.825462, -0.481625, 1.652381, 0.939811, 0.848973, -0.462327, 1.577560, 0.878279, 0.871521, -0.441928, 1.509291, 0.819200, 0.892325, -0.420297, 1.443799, 0.761607, 0.914935, -0.399072, 1.389647, 0.705351, 0.936429, -0.377232, 1.339903, 0.650213, 0.957614, -0.355091, 1.295467, 0.597773, 0.979578, -0.332767, 1.256692, 0.545914, 1.000860, -0.310147, 1.221666, 0.495661, 1.022550, -0.287395, 1.190775, 0.448026, 1.045005, -0.264582, 1.162641, 0.400490, 1.068703, -0.241464, 1.138358, 0.354088, 1.093098, -0.217504, 1.115973, 0.309812, 1.119230, -0.192140, 1.096284, 0.266297, 1.144608, -0.165975, 1.080042, 0.225831, 1.168599, -0.139174, 1.067749, 0.187761, 1.187970, -0.111910, 1.056635, 0.151322, 1.201240, -0.083978, 1.043566, 0.114337, 1.208895, -0.056089, 1.028366, 0.076083, 1.213344, -0.028369, 1.013074, 0.037735, 1.219220, -0.000534, 0.999968, 0.000076, 0.000182, -0.000404, 4.433519, 2.216201, 0.000504, -0.001117, 5.911693, 2.216198, 0.002017, -0.004469, 5.919142, 2.216190, 0.004536, -0.010051, 5.913172, 2.216130, 0.008065, -0.017867, 5.911791, 2.216145, 0.012467, -0.027603, 5.785357, 2.216447, 0.018156, -0.040159, 5.901121, 2.215958, 0.024758, -0.054670, 5.908781, 2.215654, 0.032395, -0.071352, 5.906098, 2.215283, 0.041108, -0.090201, 5.902558, 2.214715, 0.050955, -0.111004, 5.895707, 2.213905, 0.061968, -0.134002, 5.888736, 2.212807, 0.074206, -0.159038, 5.880633, 2.211303, 0.087742, -0.185801, 5.867001, 2.209297, 0.102652, -0.214368, 5.851446, 2.206657, 0.119006, -0.244573, 5.830722, 2.203232, 0.136883, -0.276067, 5.802688, 2.198778, 0.156335, -0.308660, 5.767185, 2.193091, 0.177396, -0.341940, 5.719726, 2.185858, 0.200070, -0.375591, 5.658792, 2.176584, 0.224067, -0.408564, 5.573508, 2.164759, 0.249420, -0.440668, 5.465696, 2.149777, 0.275879, -0.471138, 5.332207, 2.131225, 0.303307, -0.499204, 5.173339, 2.108794, 0.331189, -0.524547, 4.985102, 2.080585, 0.359932, -0.547256, 4.785788, 2.047792, 0.389063, -0.566479, 4.569344, 2.009518, 0.418725, -0.583031, 4.349557, 1.965601, 0.448181, -0.595809, 4.121278, 1.916911, 0.477703, -0.605102, 3.892291, 1.863530, 0.507999, -0.612462, 3.676557, 1.806286, 0.536889, -0.615451, 3.456241, 1.745841, 0.565778, -0.616029, 3.249464, 1.681137, 0.593863, -0.613644, 3.050273, 1.615238, 0.620770, -0.608268, 2.859599, 1.548003, 0.647171, -0.601116, 2.683287, 1.480447, 0.673458, -0.592840, 2.524036, 1.412084, 0.698064, -0.581973, 2.371046, 1.345130, 0.721011, -0.568963, 2.229104, 1.278440, 0.744293, -0.555642, 2.103213, 1.212448, 0.766314, -0.540934, 1.985370, 1.146287, 0.788164, -0.525271, 1.878842, 1.082600, 0.809019, -0.507986, 1.779821, 1.019978, 0.830947, -0.489717, 1.691630, 0.956931, 0.853732, -0.469345, 1.607513, 0.894207, 0.874904, -0.447618, 1.531176, 0.833436, 0.897289, -0.426124, 1.467302, 0.773611, 0.919226, -0.404025, 1.408321, 0.716016, 0.940860, -0.381454, 1.356209, 0.659515, 0.962764, -0.358901, 1.310082, 0.604629, 0.984322, -0.335983, 1.268485, 0.552335, 1.005343, -0.312533, 1.230662, 0.501591, 1.028153, -0.289452, 1.199168, 0.452032, 1.049283, -0.265754, 1.168575, 0.404347, 1.073687, -0.242571, 1.143533, 0.357445, 1.097546, -0.218681, 1.119859, 0.312534, 1.123340, -0.194465, 1.099634, 0.269437, 1.148166, -0.168797, 1.081968, 0.228586, 1.172518, -0.141552, 1.068789, 0.189866, 1.192930, -0.113325, 1.057548, 0.152772, 1.206816, -0.084800, 1.044145, 0.115390, 1.215045, -0.056019, 1.028938, 0.076493, 1.220048, -0.027733, 1.013338, 0.037767, 1.225852, 0.000050, 0.999927, -0.000160, 0.000178, -0.000422, 4.587902, 2.372253, 0.000504, -0.001195, 6.624675, 2.372248, 0.002016, -0.004782, 6.626884, 2.372187, 0.004531, -0.010746, 6.607379, 2.372318, 0.008081, -0.019161, 6.640102, 2.372084, 0.012637, -0.029945, 6.653708, 2.372128, 0.018167, -0.042999, 6.623837, 2.371902, 0.024769, -0.058516, 6.624484, 2.371595, 0.032421, -0.076370, 6.620877, 2.371120, 0.041164, -0.096474, 6.615235, 2.370428, 0.051057, -0.118786, 6.607844, 2.369440, 0.062136, -0.143390, 6.599216, 2.368075, 0.074490, -0.170034, 6.588018, 2.366218, 0.088179, -0.198717, 6.572526, 2.363747, 0.103307, -0.229147, 6.551868, 2.360517, 0.119964, -0.261253, 6.526089, 2.356304, 0.138173, -0.294703, 6.489593, 2.350797, 0.158072, -0.329261, 6.443573, 2.343783, 0.179592, -0.364298, 6.379764, 2.334673, 0.202709, -0.399375, 6.295845, 2.323125, 0.227335, -0.433616, 6.184929, 2.308547, 0.253230, -0.466794, 6.045905, 2.289980, 0.280100, -0.497509, 5.871803, 2.266964, 0.308146, -0.525956, 5.672422, 2.239074, 0.336544, -0.551101, 5.443256, 2.204809, 0.365223, -0.572471, 5.188034, 2.164827, 0.395484, -0.592088, 4.943783, 2.119489, 0.424416, -0.606026, 4.666400, 2.067262, 0.455641, -0.619671, 4.418961, 2.009937, 0.485298, -0.627583, 4.152737, 1.948900, 0.514774, -0.632072, 3.893344, 1.882692, 0.544172, -0.634033, 3.645332, 1.814073, 0.573283, -0.633239, 3.414651, 1.742717, 0.602155, -0.630008, 3.195712, 1.669703, 0.630520, -0.624550, 2.994536, 1.596021, 0.657121, -0.615749, 2.799373, 1.522572, 0.682071, -0.604738, 2.616102, 1.448978, 0.707605, -0.593301, 2.456112, 1.376250, 0.731492, -0.579628, 2.303517, 1.305297, 0.754139, -0.564473, 2.165340, 1.235548, 0.776505, -0.548787, 2.041646, 1.167051, 0.796833, -0.531415, 1.923334, 1.100534, 0.817565, -0.513778, 1.818176, 1.035144, 0.837981, -0.495167, 1.723830, 0.971583, 0.858513, -0.475690, 1.638448, 0.908841, 0.879892, -0.454099, 1.559420, 0.846701, 0.902258, -0.432038, 1.491471, 0.785332, 0.924114, -0.409316, 1.428878, 0.726409, 0.944230, -0.385618, 1.370785, 0.668588, 0.967001, -0.362604, 1.323529, 0.612943, 0.988579, -0.339117, 1.279679, 0.559038, 1.010210, -0.315355, 1.240104, 0.506867, 1.032084, -0.291408, 1.205261, 0.456934, 1.054671, -0.267387, 1.175197, 0.407792, 1.078314, -0.243346, 1.148153, 0.360992, 1.102443, -0.219205, 1.123799, 0.315577, 1.128524, -0.194996, 1.102624, 0.271742, 1.153989, -0.169897, 1.085134, 0.230702, 1.179420, -0.143960, 1.071699, 0.192146, 1.200098, -0.116173, 1.060179, 0.155164, 1.214837, -0.086655, 1.046290, 0.117071, 1.222749, -0.056956, 1.030040, 0.077450, 1.227273, -0.027883, 1.013650, 0.038092, 1.233293, 0.000831, 1.000043, -0.000462, 0.000173, -0.000442, 4.741539, 2.547922, 0.000504, -0.001284, 7.491127, 2.547919, 0.002014, -0.005132, 7.484889, 2.547844, 0.004523, -0.011521, 7.439875, 2.547587, 0.008059, -0.020524, 7.483694, 2.547725, 0.012586, -0.032029, 7.470912, 2.547685, 0.018081, -0.045948, 7.422534, 2.547686, 0.024783, -0.062844, 7.487581, 2.547107, 0.032451, -0.082011, 7.483603, 2.546522, 0.041233, -0.103540, 7.475124, 2.545684, 0.051181, -0.127537, 7.467521, 2.544438, 0.062347, -0.153921, 7.456266, 2.542744, 0.074829, -0.182427, 7.440422, 2.540459, 0.088703, -0.213134, 7.420694, 2.537380, 0.104080, -0.245750, 7.394875, 2.533347, 0.121050, -0.279941, 7.358515, 2.528069, 0.139697, -0.315591, 7.313001, 2.521237, 0.160036, -0.351980, 7.246342, 2.512378, 0.182147, -0.388993, 7.163688, 2.500993, 0.205799, -0.425570, 7.048339, 2.486450, 0.231091, -0.461093, 6.902586, 2.468174, 0.257405, -0.494668, 6.712721, 2.444774, 0.284956, -0.525889, 6.491261, 2.415538, 0.313180, -0.553693, 6.232833, 2.380610, 0.342327, -0.578724, 5.953834, 2.338525, 0.371689, -0.599706, 5.649698, 2.290256, 0.401919, -0.617615, 5.347900, 2.235157, 0.432204, -0.631632, 5.036417, 2.173932, 0.463151, -0.643082, 4.735976, 2.107298, 0.493388, -0.649970, 4.432044, 2.036121, 0.524128, -0.654188, 4.145472, 1.961595, 0.553930, -0.654671, 3.866877, 1.883602, 0.583856, -0.653051, 3.607848, 1.804521, 0.611762, -0.646994, 3.356237, 1.724047, 0.639117, -0.638860, 3.122531, 1.643016, 0.666279, -0.629093, 2.913178, 1.563932, 0.692936, -0.617862, 2.722675, 1.484614, 0.716498, -0.603279, 2.536926, 1.406734, 0.742273, -0.589878, 2.381054, 1.331469, 0.764031, -0.572744, 2.228312, 1.256796, 0.786601, -0.555933, 2.095451, 1.185290, 0.807776, -0.537992, 1.972866, 1.115940, 0.828400, -0.519596, 1.863394, 1.048371, 0.847412, -0.499847, 1.760630, 0.982934, 0.866850, -0.479920, 1.670998, 0.919972, 0.886340, -0.459434, 1.587962, 0.858100, 0.906933, -0.437767, 1.515505, 0.796714, 0.927490, -0.414068, 1.448243, 0.736162, 0.950217, -0.390910, 1.390505, 0.677613, 0.971545, -0.366964, 1.337865, 0.620477, 0.992901, -0.342603, 1.291104, 0.565807, 1.015460, -0.318596, 1.251138, 0.513086, 1.037859, -0.294242, 1.214291, 0.461573, 1.060535, -0.269601, 1.182517, 0.411838, 1.086885, -0.245608, 1.155300, 0.363221, 1.111237, -0.220589, 1.129715, 0.317174, 1.138718, -0.196008, 1.108103, 0.273213, 1.164223, -0.170408, 1.089640, 0.231968, 1.187256, -0.144205, 1.074145, 0.192987, 1.207851, -0.116945, 1.061615, 0.156118, 1.222217, -0.088852, 1.047599, 0.118674, 1.230315, -0.059381, 1.030869, 0.078993, 1.235052, -0.029145, 1.014126, 0.038924, 1.241359, 0.000479, 1.000114, -0.000211, 0.000169, -0.000465, 4.953966, 2.747437, 0.000504, -0.001384, 8.544530, 2.747430, 0.002015, -0.005537, 8.545147, 2.747339, 0.004542, -0.012477, 8.557734, 2.747125, 0.008064, -0.022143, 8.530193, 2.747341, 0.012543, -0.034411, 8.465151, 2.747411, 0.018178, -0.049792, 8.543328, 2.746874, 0.024810, -0.067784, 8.547247, 2.746396, 0.032489, -0.088416, 8.537436, 2.745730, 0.041313, -0.111580, 8.526655, 2.744596, 0.051332, -0.137462, 8.517438, 2.743082, 0.062603, -0.165860, 8.502803, 2.740950, 0.075240, -0.196548, 8.481507, 2.738057, 0.089341, -0.229440, 8.454287, 2.734174, 0.105021, -0.264395, 8.420289, 2.729086, 0.122399, -0.301020, 8.373503, 2.722420, 0.141526, -0.338997, 8.309059, 2.713686, 0.162451, -0.377589, 8.221539, 2.702492, 0.185098, -0.416349, 8.100116, 2.687893, 0.209406, -0.454284, 7.941704, 2.669386, 0.235098, -0.490450, 7.733318, 2.645590, 0.262100, -0.524592, 7.486120, 2.615709, 0.290103, -0.555558, 7.193498, 2.579231, 0.319135, -0.583516, 6.874796, 2.534957, 0.348286, -0.606714, 6.516118, 2.483017, 0.378840, -0.627850, 6.163912, 2.424214, 0.409608, -0.644715, 5.801404, 2.357563, 0.440553, -0.657657, 5.435955, 2.285835, 0.470599, -0.665621, 5.063481, 2.207940, 0.503172, -0.673767, 4.743532, 2.126440, 0.533884, -0.676009, 4.413409, 2.040694, 0.563808, -0.674536, 4.092169, 1.953979, 0.591849, -0.668913, 3.787057, 1.865897, 0.621474, -0.663159, 3.520578, 1.777762, 0.650500, -0.655018, 3.275065, 1.689902, 0.678011, -0.643949, 3.043141, 1.603528, 0.703490, -0.630030, 2.827104, 1.519484, 0.728250, -0.614910, 2.632620, 1.436677, 0.752165, -0.598649, 2.455570, 1.355753, 0.775894, -0.581771, 2.295932, 1.278884, 0.797650, -0.563193, 2.152291, 1.202767, 0.818505, -0.543750, 2.022099, 1.130338, 0.838596, -0.524017, 1.903562, 1.060263, 0.858396, -0.504064, 1.797204, 0.993077, 0.877088, -0.483418, 1.701208, 0.928606, 0.896606, -0.462786, 1.617736, 0.866039, 0.914342, -0.440943, 1.539227, 0.804293, 0.933550, -0.419129, 1.470383, 0.745206, 0.955237, -0.396100, 1.409100, 0.685832, 0.976700, -0.371743, 1.354930, 0.627953, 0.997681, -0.346882, 1.305249, 0.572127, 1.020784, -0.322391, 1.262603, 0.517941, 1.043840, -0.297564, 1.225115, 0.466188, 1.067224, -0.272639, 1.190817, 0.415499, 1.092358, -0.247664, 1.161265, 0.366782, 1.117573, -0.222260, 1.133935, 0.319377, 1.145730, -0.196933, 1.111750, 0.275293, 1.170822, -0.170577, 1.091981, 0.233306, 1.194559, -0.143878, 1.075810, 0.193950, 1.214819, -0.116347, 1.062438, 0.156724, 1.229830, -0.088233, 1.048092, 0.118984, 1.238185, -0.059408, 1.031325, 0.079385, 1.243527, -0.030703, 1.014698, 0.039893, 1.249724, -0.001520, 0.999819, 0.000760, 0.000164, -0.000489, 5.157359, 2.976300, 0.000505, -0.001502, 9.891415, 2.976286, 0.002016, -0.006000, 9.857730, 2.976197, 0.004543, -0.013519, 9.870651, 2.975832, 0.008064, -0.023985, 9.855780, 2.976170, 0.012611, -0.037471, 9.850209, 2.975941, 0.018162, -0.053866, 9.827134, 2.974968, 0.024820, -0.073390, 9.849955, 2.975010, 0.032545, -0.095758, 9.842021, 2.974073, 0.041418, -0.120834, 9.829989, 2.972700, 0.051511, -0.148861, 9.817421, 2.970736, 0.062920, -0.179456, 9.797347, 2.968033, 0.075744, -0.212674, 9.771533, 2.964371, 0.090131, -0.248193, 9.735924, 2.959437, 0.106187, -0.285748, 9.687707, 2.952881, 0.124035, -0.325017, 9.622684, 2.944273, 0.143733, -0.365463, 9.531452, 2.933093, 0.165262, -0.406157, 9.401732, 2.918484, 0.188622, -0.446833, 9.232451, 2.899529, 0.213693, -0.486209, 9.013432, 2.875137, 0.239987, -0.522925, 8.725671, 2.844166, 0.267796, -0.557452, 8.400028, 2.805649, 0.296547, -0.588266, 8.023041, 2.758720, 0.325838, -0.614837, 7.606773, 2.702676, 0.355479, -0.636760, 7.160680, 2.638483, 0.386984, -0.657230, 6.736765, 2.566849, 0.418853, -0.673592, 6.313742, 2.488091, 0.450302, -0.684966, 5.884479, 2.402458, 0.481149, -0.691591, 5.455771, 2.311816, 0.512177, -0.695337, 5.055698, 2.217330, 0.543437, -0.696370, 4.681506, 2.121285, 0.574309, -0.694186, 4.334716, 2.024160, 0.604787, -0.689158, 4.008524, 1.927738, 0.633483, -0.680580, 3.703505, 1.830456, 0.660766, -0.669088, 3.418386, 1.734934, 0.688471, -0.656673, 3.168101, 1.642316, 0.715729, -0.642820, 2.941735, 1.550744, 0.740435, -0.626155, 2.730570, 1.463345, 0.764114, -0.608299, 2.537561, 1.378151, 0.787028, -0.589519, 2.364323, 1.297630, 0.807985, -0.569257, 2.207970, 1.217830, 0.830663, -0.550055, 2.076646, 1.142746, 0.850416, -0.528812, 1.948085, 1.070757, 0.869609, -0.507478, 1.834684, 1.001282, 0.888324, -0.486131, 1.734879, 0.934987, 0.907482, -0.464910, 1.645974, 0.871203, 0.924829, -0.442742, 1.563550, 0.809260, 0.942958, -0.420777, 1.491264, 0.750037, 0.961999, -0.398842, 1.428069, 0.691715, 0.981043, -0.375967, 1.369668, 0.635669, 1.002371, -0.351469, 1.318588, 0.578689, 1.025343, -0.326601, 1.273628, 0.524424, 1.048511, -0.301395, 1.234572, 0.471403, 1.072242, -0.275835, 1.198354, 0.419950, 1.096758, -0.250200, 1.166392, 0.370733, 1.122781, -0.224474, 1.138991, 0.322864, 1.150871, -0.198592, 1.114313, 0.277723, 1.177319, -0.171805, 1.093534, 0.234950, 1.201765, -0.144291, 1.077462, 0.195376, 1.222629, -0.115949, 1.063288, 0.157315, 1.237334, -0.087140, 1.048366, 0.118843, 1.246153, -0.058094, 1.031224, 0.079207, 1.252570, -0.029194, 1.014695, 0.039376, 1.259060, -0.000418, 0.999881, 0.000307, 0.000159, -0.000515, 5.393984, 3.241865, 0.000505, -0.001636, 11.548038, 3.241848, 0.002016, -0.006534, 11.506640, 3.241718, 0.004537, -0.014706, 11.513460, 3.241196, 0.008068, -0.026134, 11.510533, 3.241693, 0.012573, -0.040676, 11.428978, 3.241030, 0.018212, -0.058794, 11.510745, 3.240924, 0.024847, -0.079926, 11.497339, 3.240201, 0.032603, -0.104160, 11.484607, 3.238994, 0.041543, -0.131552, 11.470801, 3.237182, 0.051738, -0.162012, 11.453219, 3.234635, 0.063313, -0.195260, 11.427244, 3.231153, 0.076381, -0.231205, 11.388534, 3.226361, 0.091096, -0.269678, 11.340406, 3.219943, 0.107600, -0.310170, 11.270127, 3.211448, 0.126017, -0.352435, 11.178583, 3.200168, 0.146411, -0.395551, 11.046559, 3.185328, 0.168663, -0.438627, 10.858624, 3.165972, 0.192730, -0.480660, 10.606379, 3.140735, 0.218497, -0.520987, 10.288093, 3.108388, 0.245752, -0.558483, 9.907480, 3.067586, 0.273993, -0.592090, 9.453246, 3.016931, 0.303495, -0.622416, 8.966138, 2.956444, 0.333717, -0.648303, 8.443776, 2.885116, 0.363928, -0.668640, 7.894122, 2.805963, 0.396240, -0.687748, 7.385728, 2.718338, 0.427161, -0.699903, 6.838511, 2.622346, 0.460175, -0.711210, 6.356371, 2.522476, 0.492593, -0.717734, 5.878312, 2.417984, 0.524449, -0.719956, 5.423285, 2.310941, 0.556010, -0.719127, 4.997909, 2.201885, 0.587032, -0.715077, 4.600426, 2.093330, 0.617030, -0.707574, 4.235885, 1.986585, 0.644684, -0.695781, 3.881712, 1.881279, 0.674483, -0.685313, 3.590960, 1.777918, 0.700290, -0.669619, 3.303138, 1.678004, 0.727892, -0.654728, 3.057771, 1.581162, 0.751694, -0.635727, 2.826642, 1.487769, 0.776271, -0.617343, 2.622178, 1.399628, 0.799502, -0.597683, 2.441265, 1.313195, 0.821768, -0.577090, 2.276954, 1.232316, 0.841960, -0.555165, 2.125744, 1.153914, 0.861582, -0.532983, 1.991236, 1.079598, 0.881460, -0.510933, 1.874027, 1.008883, 0.899952, -0.488321, 1.766812, 0.940802, 0.918954, -0.466405, 1.673436, 0.875653, 0.936130, -0.443623, 1.586986, 0.813130, 0.954799, -0.421532, 1.513558, 0.752241, 0.972435, -0.398897, 1.445787, 0.694711, 0.990147, -0.376302, 1.384382, 0.638770, 1.009189, -0.353623, 1.331934, 0.583826, 1.029687, -0.330635, 1.284478, 0.530476, 1.052604, -0.305698, 1.243632, 0.477187, 1.076524, -0.279917, 1.204997, 0.425349, 1.101701, -0.253951, 1.171750, 0.375165, 1.127264, -0.227541, 1.142519, 0.326869, 1.156397, -0.201265, 1.116817, 0.280912, 1.183020, -0.173943, 1.095289, 0.237447, 1.208448, -0.145860, 1.078296, 0.196694, 1.230417, -0.116901, 1.064416, 0.158409, 1.248617, -0.087507, 1.050504, 0.119483, 1.257310, -0.057353, 1.032796, 0.079092, 1.263076, -0.027785, 1.015128, 0.038883, 1.269870, 0.001331, 0.999935, -0.000557, 0.000154, -0.000549, 5.705205, 3.554136, 0.000506, -0.001797, 13.703335, 3.554133, 0.002014, -0.007156, 13.614074, 3.553937, 0.004544, -0.016145, 13.657344, 3.553096, 0.008070, -0.028652, 13.627997, 3.553894, 0.012584, -0.044617, 13.606235, 3.554000, 0.018180, -0.064288, 13.581339, 3.549637, 0.024887, -0.087627, 13.608851, 3.552006, 0.032690, -0.114134, 13.599099, 3.550341, 0.041705, -0.144154, 13.579829, 3.547982, 0.052035, -0.177400, 13.552845, 3.544641, 0.063810, -0.213813, 13.515619, 3.539941, 0.077171, -0.252978, 13.460460, 3.533696, 0.092329, -0.294852, 13.393559, 3.524977, 0.109390, -0.338688, 13.292376, 3.513655, 0.128455, -0.384018, 13.147332, 3.498484, 0.149661, -0.429960, 12.945774, 3.478323, 0.172694, -0.475024, 12.658979, 3.451862, 0.197650, -0.518614, 12.289564, 3.417602, 0.224156, -0.559298, 11.828307, 3.372913, 0.252008, -0.596110, 11.285162, 3.317454, 0.281165, -0.629292, 10.684922, 3.251171, 0.311434, -0.658379, 10.052939, 3.172222, 0.342741, -0.683455, 9.405296, 3.082825, 0.373543, -0.701674, 8.716078, 2.983976, 0.407008, -0.719664, 8.108425, 2.876244, 0.438623, -0.729882, 7.461252, 2.763279, 0.471872, -0.738696, 6.880182, 2.645590, 0.504700, -0.743136, 6.324308, 2.524680, 0.537118, -0.743676, 5.808302, 2.402723, 0.569412, -0.741181, 5.332306, 2.281437, 0.598202, -0.732348, 4.857402, 2.161401, 0.629640, -0.724832, 4.465554, 2.043872, 0.659239, -0.713435, 4.093661, 1.930129, 0.686547, -0.698539, 3.752593, 1.817654, 0.715529, -0.684471, 3.457593, 1.712567, 0.739456, -0.664983, 3.171220, 1.610687, 0.764892, -0.646322, 2.929674, 1.512031, 0.789301, -0.626393, 2.710719, 1.419033, 0.809881, -0.603498, 2.506139, 1.330115, 0.833385, -0.582934, 2.336089, 1.245859, 0.854254, -0.560419, 2.178470, 1.165042, 0.873964, -0.537294, 2.040087, 1.086633, 0.893433, -0.514264, 1.911969, 1.015028, 0.911756, -0.490657, 1.799840, 0.944938, 0.930894, -0.467601, 1.703188, 0.878743, 0.948078, -0.444043, 1.612092, 0.815356, 0.966162, -0.421155, 1.534444, 0.753883, 0.984166, -0.398238, 1.462397, 0.695534, 1.002184, -0.375278, 1.400793, 0.638806, 1.019669, -0.352159, 1.344172, 0.584549, 1.039571, -0.329651, 1.295227, 0.531660, 1.059989, -0.306804, 1.251281, 0.480529, 1.081116, -0.283345, 1.211504, 0.430071, 1.105742, -0.258568, 1.176400, 0.380277, 1.133080, -0.232146, 1.144519, 0.331076, 1.161888, -0.205244, 1.118059, 0.284040, 1.192408, -0.177932, 1.097561, 0.239958, 1.221043, -0.149532, 1.082021, 0.198751, 1.244141, -0.120046, 1.067634, 0.160114, 1.259465, -0.089542, 1.051626, 0.121101, 1.268124, -0.058593, 1.033296, 0.079898, 1.274330, -0.028011, 1.015382, 0.039038, 1.281590, 0.002330, 1.000087, -0.001259, 0.000149, -0.000587, 6.059834, 3.927143, 0.000507, -0.001992, 16.560400, 3.927149, 0.002014, -0.007910, 16.406326, 3.926821, 0.004549, -0.017856, 16.545532, 3.927027, 0.008064, -0.031632, 16.375853, 3.925487, 0.012450, -0.048749, 15.928564, 3.928272, 0.018030, -0.070371, 16.072989, 3.917862, 0.024964, -0.096897, 16.458925, 3.924489, 0.032807, -0.126073, 16.377851, 3.921896, 0.041917, -0.159205, 16.351561, 3.918860, 0.052416, -0.195762, 16.307037, 3.914339, 0.064464, -0.235784, 16.255514, 3.907954, 0.078225, -0.278812, 16.176226, 3.899254, 0.093900, -0.324457, 16.066530, 3.887455, 0.111657, -0.372174, 15.913818, 3.871777, 0.131478, -0.420530, 15.669197, 3.850776, 0.153574, -0.469330, 15.355453, 3.822348, 0.177505, -0.516029, 14.908978, 3.785168, 0.203383, -0.560585, 14.352687, 3.736602, 0.230569, -0.600607, 13.666022, 3.675046, 0.259188, -0.636296, 12.900244, 3.599811, 0.289272, -0.668312, 12.111226, 3.510550, 0.320490, -0.695986, 11.292102, 3.408535, 0.353031, -0.719848, 10.493485, 3.295667, 0.385228, -0.737073, 9.661955, 3.171998, 0.419219, -0.752419, 8.909942, 3.042428, 0.452096, -0.761179, 8.155107, 2.907108, 0.484909, -0.766166, 7.450609, 2.769858, 0.518306, -0.768596, 6.811866, 2.631935, 0.550067, -0.765683, 6.205275, 2.492870, 0.582562, -0.761197, 5.663215, 2.358645, 0.614450, -0.753834, 5.165358, 2.227377, 0.644563, -0.742860, 4.712554, 2.097547, 0.673658, -0.729294, 4.306101, 1.974920, 0.702857, -0.714839, 3.943352, 1.857613, 0.729350, -0.696774, 3.609432, 1.743601, 0.754958, -0.677394, 3.308389, 1.636607, 0.779575, -0.657018, 3.043803, 1.533841, 0.800491, -0.633342, 2.793592, 1.437092, 0.825030, -0.612471, 2.590307, 1.344272, 0.847535, -0.589882, 2.406477, 1.256436, 0.865979, -0.564850, 2.231999, 1.173938, 0.886254, -0.541357, 2.083556, 1.094722, 0.905566, -0.517353, 1.950928, 1.021107, 0.924607, -0.493320, 1.835979, 0.948941, 0.943365, -0.469366, 1.731417, 0.881060, 0.960405, -0.444745, 1.635838, 0.816479, 0.977893, -0.420493, 1.552981, 0.754604, 0.996573, -0.397150, 1.481595, 0.694917, 1.014000, -0.373483, 1.414070, 0.638445, 1.031807, -0.349985, 1.356031, 0.584035, 1.051877, -0.327062, 1.305041, 0.530010, 1.071701, -0.304134, 1.258836, 0.479439, 1.093109, -0.280962, 1.217297, 0.429763, 1.116681, -0.258121, 1.182063, 0.381050, 1.143886, -0.235365, 1.150039, 0.333395, 1.175163, -0.211621, 1.125074, 0.287477, 1.203675, -0.184061, 1.102339, 0.243301, 1.230477, -0.154815, 1.083927, 0.201826, 1.253134, -0.124513, 1.067989, 0.162271, 1.270092, -0.093383, 1.052032, 0.122855, 1.279576, -0.061770, 1.033685, 0.081639, 1.286472, -0.030317, 1.015583, 0.040411, 1.294476, 0.000964, 1.000206, -0.000454, 0.000144, -0.000630, 6.467978, 4.381146, 0.000504, -0.002208, 20.193617, 4.381151, 0.002017, -0.008834, 20.206446, 4.380687, 0.004536, -0.019864, 20.183254, 4.380550, 0.008174, -0.035759, 20.564249, 4.381247, 0.012608, -0.055034, 20.111612, 4.382390, 0.018198, -0.079119, 20.106096, 4.379815, 0.025057, -0.108067, 20.215635, 4.376874, 0.032962, -0.140630, 20.153549, 4.374143, 0.042199, -0.177350, 20.084061, 4.369558, 0.052928, -0.218094, 20.026609, 4.363287, 0.065327, -0.262407, 19.940054, 4.354386, 0.079568, -0.309833, 19.806814, 4.342127, 0.095961, -0.360074, 19.641878, 4.325533, 0.114516, -0.411747, 19.370914, 4.302950, 0.135349, -0.463726, 18.983900, 4.271991, 0.158293, -0.514211, 18.433926, 4.230856, 0.183348, -0.562511, 17.733471, 4.176250, 0.209959, -0.606310, 16.864214, 4.105895, 0.238736, -0.646958, 15.935207, 4.020104, 0.268543, -0.681574, 14.890014, 3.916094, 0.299996, -0.712458, 13.846786, 3.798239, 0.331930, -0.737130, 12.758296, 3.664191, 0.365222, -0.758156, 11.732940, 3.521867, 0.399061, -0.774364, 10.741743, 3.369831, 0.433480, -0.786412, 9.812527, 3.212079, 0.467002, -0.792373, 8.915130, 3.053715, 0.500754, -0.795410, 8.094276, 2.894526, 0.534023, -0.794617, 7.342067, 2.735959, 0.566988, -0.790689, 6.664186, 2.581160, 0.599960, -0.784433, 6.052983, 2.432318, 0.630599, -0.773378, 5.486277, 2.287630, 0.660807, -0.760334, 4.982516, 2.150183, 0.690103, -0.745430, 4.531104, 2.017266, 0.717315, -0.727511, 4.120734, 1.891699, 0.743819, -0.708376, 3.759599, 1.772680, 0.770147, -0.688632, 3.441912, 1.660620, 0.793510, -0.665931, 3.152600, 1.553166, 0.816535, -0.643045, 2.898883, 1.452080, 0.839163, -0.619917, 2.674488, 1.355544, 0.859066, -0.594923, 2.469262, 1.267232, 0.879489, -0.570343, 2.292209, 1.181702, 0.898525, -0.544975, 2.131086, 1.102089, 0.918359, -0.520585, 1.994526, 1.024744, 0.937502, -0.496044, 1.873079, 0.951712, 0.955573, -0.471010, 1.761232, 0.883374, 0.972957, -0.445712, 1.661604, 0.818008, 0.991248, -0.421201, 1.577169, 0.754446, 1.008997, -0.396444, 1.499653, 0.694518, 1.028127, -0.372362, 1.432030, 0.637259, 1.045710, -0.347895, 1.369870, 0.581515, 1.065977, -0.324409, 1.317341, 0.527713, 1.087469, -0.301181, 1.270447, 0.476281, 1.109943, -0.277866, 1.228398, 0.426403, 1.134440, -0.254849, 1.190986, 0.377822, 1.160986, -0.231754, 1.157681, 0.330740, 1.188458, -0.207973, 1.128665, 0.286014, 1.214405, -0.183424, 1.103711, 0.243600, 1.239504, -0.157972, 1.084253, 0.203686, 1.262961, -0.130607, 1.068258, 0.165214, 1.280340, -0.099652, 1.051919, 0.126067, 1.292129, -0.067363, 1.034016, 0.084791, 1.299876, -0.035026, 1.015775, 0.042786, 1.308328, -0.002944, 0.999963, 0.001385, 0.000138, -0.000681, 6.943771, 4.946556, 0.000503, -0.002486, 25.346689, 4.946532, 0.002016, -0.009973, 25.494320, 4.946311, 0.004539, -0.022440, 25.484949, 4.945823, 0.008069, -0.039836, 25.420902, 4.945311, 0.012628, -0.062172, 25.394403, 4.945041, 0.018294, -0.089609, 25.440279, 4.943295, 0.025079, -0.121584, 25.399988, 4.939368, 0.033142, -0.158595, 25.356537, 4.936200, 0.042596, -0.199971, 25.295067, 4.929842, 0.053628, -0.245624, 25.196465, 4.920586, 0.066496, -0.295240, 25.055311, 4.907700, 0.081434, -0.348006, 24.846170, 4.889647, 0.098640, -0.403167, 24.527803, 4.864680, 0.118231, -0.459106, 24.051735, 4.830574, 0.140139, -0.513907, 23.352467, 4.783530, 0.164198, -0.565953, 22.418245, 4.720530, 0.190502, -0.614858, 21.324049, 4.638075, 0.218530, -0.658304, 20.038671, 4.535464, 0.248094, -0.696133, 18.639786, 4.411646, 0.279435, -0.729388, 17.234526, 4.268872, 0.312002, -0.757534, 15.830426, 4.109603, 0.346173, -0.781866, 14.495901, 3.938782, 0.379435, -0.797579, 13.136444, 3.756138, 0.414945, -0.812334, 11.946491, 3.571258, 0.449991, -0.821119, 10.811908, 3.384217, 0.484636, -0.825066, 9.763482, 3.198076, 0.518675, -0.824728, 8.796811, 3.015808, 0.552559, -0.821710, 7.932528, 2.836886, 0.587272, -0.817478, 7.185156, 2.664995, 0.616960, -0.804441, 6.445302, 2.502223, 0.648054, -0.792063, 5.818812, 2.345851, 0.678575, -0.777793, 5.264731, 2.197150, 0.707287, -0.760476, 4.766033, 2.056042, 0.735851, -0.742541, 4.335871, 1.922805, 0.760594, -0.720503, 3.928021, 1.798585, 0.784534, -0.697719, 3.579153, 1.680605, 0.811029, -0.677036, 3.285307, 1.568942, 0.831809, -0.651479, 3.001423, 1.465496, 0.854364, -0.627376, 2.760672, 1.367849, 0.872639, -0.600496, 2.540697, 1.275644, 0.894296, -0.576297, 2.355273, 1.188638, 0.913123, -0.550377, 2.188563, 1.105652, 0.932025, -0.524640, 2.040739, 1.028614, 0.949876, -0.498402, 1.910315, 0.954421, 0.968933, -0.473220, 1.795750, 0.884061, 0.985366, -0.447086, 1.690336, 0.817765, 1.004940, -0.422394, 1.599626, 0.753295, 1.022217, -0.396726, 1.519055, 0.693380, 1.041490, -0.371854, 1.448745, 0.635747, 1.059920, -0.346769, 1.384292, 0.579508, 1.080408, -0.322343, 1.328798, 0.525045, 1.101632, -0.297979, 1.279898, 0.473773, 1.124812, -0.274059, 1.234005, 0.422949, 1.148503, -0.249954, 1.195373, 0.374609, 1.174554, -0.225988, 1.160362, 0.327350, 1.202931, -0.201932, 1.131307, 0.283494, 1.229335, -0.176886, 1.105885, 0.241092, 1.254254, -0.151225, 1.085802, 0.201514, 1.275743, -0.124282, 1.068524, 0.162866, 1.292929, -0.097122, 1.051493, 0.124991, 1.305805, -0.068939, 1.033890, 0.085521, 1.314991, -0.040082, 1.015927, 0.045247, 1.324033, -0.009923, 0.999893, 0.004738, 0.000131, -0.000745, 7.562414, 5.671075, 0.000473, -0.002681, 27.216688, 5.670949, 0.002021, -0.011462, 32.962402, 5.670177, 0.004540, -0.025728, 33.183949, 5.670197, 0.008087, -0.045746, 33.185688, 5.667313, 0.012673, -0.071427, 33.170441, 5.668396, 0.018358, -0.102673, 33.145138, 5.665252, 0.025299, -0.139780, 33.303326, 5.653404, 0.033469, -0.181718, 33.107243, 5.652829, 0.043139, -0.228698, 32.859524, 5.645676, 0.054622, -0.280648, 32.694893, 5.631547, 0.068115, -0.336524, 32.422569, 5.611561, 0.083957, -0.395671, 32.035511, 5.583449, 0.102259, -0.456164, 31.415047, 5.543651, 0.123021, -0.515765, 30.470440, 5.488278, 0.146127, -0.572309, 29.186451, 5.413118, 0.171749, -0.625710, 27.653852, 5.312369, 0.199549, -0.673853, 25.902435, 5.185774, 0.229188, -0.715905, 23.978609, 5.030582, 0.260421, -0.751533, 21.999035, 4.853484, 0.293421, -0.782309, 20.087366, 4.656137, 0.327077, -0.806332, 18.186535, 4.443975, 0.361892, -0.825818, 16.418409, 4.223844, 0.397146, -0.840019, 14.774344, 3.998959, 0.434169, -0.852434, 13.321097, 3.775443, 0.469288, -0.856632, 11.929448, 3.552818, 0.504319, -0.857130, 10.675201, 3.338825, 0.540067, -0.855903, 9.591900, 3.130547, 0.575404, -0.851565, 8.607655, 2.932930, 0.606782, -0.839818, 7.690560, 2.743876, 0.638660, -0.827508, 6.900781, 2.565115, 0.670577, -0.814154, 6.216821, 2.395215, 0.696718, -0.793162, 5.551886, 2.238233, 0.725990, -0.775291, 5.015406, 2.090264, 0.754140, -0.755758, 4.546843, 1.950834, 0.775992, -0.729824, 4.094254, 1.820582, 0.802990, -0.708909, 3.732984, 1.699191, 0.828291, -0.686483, 3.413194, 1.583805, 0.847406, -0.659162, 3.103861, 1.478093, 0.864951, -0.631051, 2.832976, 1.378496, 0.887154, -0.606590, 2.616645, 1.282127, 0.906337, -0.580124, 2.413988, 1.194643, 0.927184, -0.554835, 2.244380, 1.110354, 0.943810, -0.527583, 2.081964, 1.031996, 0.963630, -0.502243, 1.948979, 0.956718, 0.979691, -0.475006, 1.822701, 0.886957, 0.997690, -0.448815, 1.715714, 0.819006, 1.016460, -0.423044, 1.621868, 0.754892, 1.035485, -0.397637, 1.539537, 0.693707, 1.053165, -0.371775, 1.462285, 0.634867, 1.072394, -0.346372, 1.396193, 0.578574, 1.093397, -0.321291, 1.338344, 0.524341, 1.115194, -0.296102, 1.287594, 0.472059, 1.137943, -0.271023, 1.240495, 0.421674, 1.164163, -0.246367, 1.201224, 0.371963, 1.191457, -0.221414, 1.164472, 0.325040, 1.220253, -0.196228, 1.134325, 0.280343, 1.245456, -0.169991, 1.108214, 0.238098, 1.270647, -0.143314, 1.087277, 0.197886, 1.292124, -0.115881, 1.069397, 0.159560, 1.309091, -0.087816, 1.051426, 0.120547, 1.321130, -0.059301, 1.032904, 0.080834, 1.332484, -0.030912, 1.015767, 0.040933, 1.342834, -0.002172, 0.999591, 0.001185, 0.000125, -0.000830, 8.392562, 6.634228, 0.000443, -0.002936, 29.687805, 6.634032, 0.002016, -0.013374, 45.025234, 6.633008, 0.004540, -0.030089, 45.020294, 6.633056, 0.008092, -0.053499, 45.066029, 6.626466, 0.012710, -0.083610, 44.810101, 6.630330, 0.018485, -0.120260, 45.216747, 6.614516, 0.025134, -0.161031, 44.674168, 6.600349, 0.033897, -0.212161, 44.819195, 6.610186, 0.043978, -0.266661, 44.450245, 6.593605, 0.056094, -0.326582, 44.134544, 6.570142, 0.070528, -0.390342, 43.591648, 6.536712, 0.087498, -0.456162, 42.708160, 6.488329, 0.107138, -0.521609, 41.365093, 6.420198, 0.129461, -0.584225, 39.525822, 6.323702, 0.154245, -0.641931, 37.186111, 6.193606, 0.181228, -0.692829, 34.478470, 6.026897, 0.210711, -0.738440, 31.680904, 5.825769, 0.242181, -0.777397, 28.828054, 5.595428, 0.275337, -0.809980, 26.042755, 5.342321, 0.309698, -0.835990, 23.376804, 5.073076, 0.345702, -0.858077, 20.965754, 4.794572, 0.382135, -0.874122, 18.710079, 4.516676, 0.419871, -0.887133, 16.713011, 4.241767, 0.455609, -0.891199, 14.819674, 3.972124, 0.492617, -0.894082, 13.187921, 3.717271, 0.528186, -0.891270, 11.708584, 3.471719, 0.563462, -0.885719, 10.422834, 3.237760, 0.596013, -0.874241, 9.237741, 3.019060, 0.629455, -0.862814, 8.248549, 2.813572, 0.661110, -0.848126, 7.358398, 2.621046, 0.690314, -0.829798, 6.569392, 2.441627, 0.720589, -0.812314, 5.905934, 2.274629, 0.745631, -0.788704, 5.276800, 2.119423, 0.771488, -0.766133, 4.752773, 1.974380, 0.798704, -0.744726, 4.306095, 1.839482, 0.820172, -0.718062, 3.889792, 1.713244, 0.844368, -0.693972, 3.545456, 1.594809, 0.863128, -0.665748, 3.212762, 1.487512, 0.880094, -0.637003, 2.926572, 1.386724, 0.904252, -0.613728, 2.704260, 1.288131, 0.920506, -0.585217, 2.483164, 1.199845, 0.940919, -0.559603, 2.300348, 1.114958, 0.957044, -0.531597, 2.130516, 1.034754, 0.972648, -0.503583, 1.979313, 0.960912, 0.994318, -0.478813, 1.859664, 0.889786, 1.008754, -0.450943, 1.742705, 0.820833, 1.028667, -0.425516, 1.645220, 0.756332, 1.046145, -0.398977, 1.557184, 0.693921, 1.067212, -0.373657, 1.480814, 0.635955, 1.084111, -0.346657, 1.408762, 0.578832, 1.106749, -0.321392, 1.350468, 0.523561, 1.128440, -0.295773, 1.294865, 0.471146, 1.151073, -0.270028, 1.246118, 0.420298, 1.178601, -0.244816, 1.204226, 0.370575, 1.206845, -0.219027, 1.166896, 0.323716, 1.235963, -0.192622, 1.135756, 0.278058, 1.263030, -0.165331, 1.109240, 0.235743, 1.288937, -0.137489, 1.088379, 0.195390, 1.310681, -0.108685, 1.068987, 0.156439, 1.334352, -0.079710, 1.054273, 0.117096, 1.344847, -0.049947, 1.034598, 0.076554, 1.354943, -0.020272, 1.016079, 0.035585, 1.365515, 0.009170, 0.999969, -0.004771, 0.000117, -0.000935, 9.424866, 7.979243, 0.000410, -0.003275, 33.013195, 7.979422, 0.002009, -0.016024, 64.370331, 7.977156, 0.004541, -0.036176, 64.655952, 7.976128, 0.008109, -0.064384, 64.864494, 7.964988, 0.012694, -0.099984, 64.487198, 7.971348, 0.018554, -0.143991, 64.637970, 7.923116, 0.025303, -0.192040, 61.930538, 7.953975, 0.035297, -0.259442, 66.274422, 7.921861, 0.045226, -0.318370, 63.334690, 7.909609, 0.058370, -0.388821, 62.686401, 7.864696, 0.074083, -0.461667, 61.332054, 7.801843, 0.092537, -0.533744, 59.125607, 7.708949, 0.113781, -0.601905, 55.997845, 7.575799, 0.137786, -0.664409, 52.177567, 7.393524, 0.164770, -0.721193, 48.019485, 7.161756, 0.193894, -0.768842, 43.460278, 6.882018, 0.225586, -0.810332, 39.086590, 6.564607, 0.259311, -0.845096, 34.896049, 6.221983, 0.294517, -0.872849, 30.952213, 5.865831, 0.331163, -0.895159, 27.375792, 5.507064, 0.368964, -0.912860, 24.213310, 5.149763, 0.407255, -0.925338, 21.364958, 4.806172, 0.444704, -0.930956, 18.791691, 4.472272, 0.482041, -0.932576, 16.521160, 4.160864, 0.519572, -0.931547, 14.589918, 3.865206, 0.556236, -0.926554, 12.887797, 3.590445, 0.590431, -0.915839, 11.352402, 3.332747, 0.622723, -0.901266, 10.002660, 3.093264, 0.657029, -0.888747, 8.905210, 2.873842, 0.686164, -0.868666, 7.876704, 2.666740, 0.719168, -0.853152, 7.051816, 2.479017, 0.742294, -0.826169, 6.226034, 2.306498, 0.770320, -0.804936, 5.590831, 2.141328, 0.792337, -0.777772, 4.984083, 1.994663, 0.819050, -0.755478, 4.507655, 1.853950, 0.837684, -0.726072, 4.049884, 1.725590, 0.861324, -0.701424, 3.678201, 1.606303, 0.880741, -0.673615, 3.337163, 1.495452, 0.903335, -0.648506, 3.055720, 1.391162, 0.920311, -0.619640, 2.792068, 1.294734, 0.935769, -0.590245, 2.554566, 1.204518, 0.956592, -0.564944, 2.366468, 1.118630, 0.972424, -0.536842, 2.187863, 1.038323, 0.986269, -0.508020, 2.023480, 0.963803, 1.006122, -0.482411, 1.895137, 0.890986, 1.022504, -0.455110, 1.775886, 0.820936, 1.037905, -0.427450, 1.665951, 0.758556, 1.059281, -0.402198, 1.577363, 0.696126, 1.076613, -0.375156, 1.493391, 0.636676, 1.097828, -0.349577, 1.421129, 0.579947, 1.116671, -0.322955, 1.355205, 0.525140, 1.140514, -0.297406, 1.299979, 0.471460, 1.166473, -0.271786, 1.249847, 0.420473, 1.192591, -0.245461, 1.204625, 0.371118, 1.223349, -0.219412, 1.166686, 0.322600, 1.254833, -0.192660, 1.134121, 0.277572, 1.285808, -0.165167, 1.108617, 0.234417, 1.322015, -0.137236, 1.093841, 0.194640, 1.342172, -0.106871, 1.074616, 0.155001, 1.357238, -0.075759, 1.053550, 0.114648, 1.367725, -0.044279, 1.033851, 0.073254, 1.379461, -0.013001, 1.015713, 0.031895, 1.391625, 0.018075, 1.000203, -0.009397, 0.000109, -0.001093, 10.986820, 9.992467, 0.000378, -0.003779, 37.989063, 9.992861, 0.002028, -0.020252, 101.850441, 9.988345, 0.004557, -0.045429, 101.106750, 9.983879, 0.008115, -0.080453, 100.646606, 9.953411, 0.012864, -0.125836, 101.366592, 9.943727, 0.018734, -0.179350, 100.786118, 9.908408, 0.026314, -0.243680, 99.779343, 9.821631, 0.035500, -0.313552, 98.608231, 9.782450, 0.047562, -0.394644, 97.689568, 9.845875, 0.062065, -0.476697, 95.177795, 9.755218, 0.079552, -0.557933, 91.095581, 9.615121, 0.099905, -0.632818, 85.110382, 9.408299, 0.123231, -0.699926, 77.948921, 9.120996, 0.149980, -0.760671, 70.491119, 8.764173, 0.179550, -0.812251, 62.821407, 8.341752, 0.211839, -0.855909, 55.512890, 7.876337, 0.246434, -0.892023, 48.744549, 7.386268, 0.282317, -0.919200, 42.462059, 6.886009, 0.319580, -0.940333, 36.901031, 6.400318, 0.360135, -0.962176, 32.353752, 5.937503, 0.397805, -0.969755, 27.996445, 5.489783, 0.437077, -0.976494, 24.359192, 5.072855, 0.474388, -0.975265, 21.124300, 4.684682, 0.513695, -0.975335, 18.476677, 4.326597, 0.551542, -0.970264, 16.167391, 3.999049, 0.587525, -0.960365, 14.143442, 3.696317, 0.621251, -0.945944, 12.374341, 3.414176, 0.654738, -0.930709, 10.877112, 3.160455, 0.685794, -0.911702, 9.580887, 2.921461, 0.717135, -0.892948, 8.481939, 2.707478, 0.740798, -0.865086, 7.435941, 2.510382, 0.770920, -0.845137, 6.650625, 2.329648, 0.792303, -0.815956, 5.879976, 2.163206, 0.818363, -0.792225, 5.274404, 2.008042, 0.837362, -0.762396, 4.700960, 1.867576, 0.862266, -0.738465, 4.254798, 1.735819, 0.880069, -0.708890, 3.828697, 1.614690, 0.896021, -0.678588, 3.451655, 1.503477, 0.920156, -0.654832, 3.168722, 1.395800, 0.934948, -0.624740, 2.879533, 1.299955, 0.949686, -0.595203, 2.628258, 1.208597, 0.970989, -0.570041, 2.433689, 1.122310, 0.985606, -0.541116, 2.241461, 1.042168, 1.000819, -0.512835, 2.075567, 0.966543, 1.012209, -0.483024, 1.919932, 0.895758, 1.035320, -0.459125, 1.807884, 0.825668, 1.052077, -0.432333, 1.695689, 0.760812, 1.070459, -0.406131, 1.595491, 0.699897, 1.088704, -0.379721, 1.508512, 0.640575, 1.103817, -0.352104, 1.428159, 0.583765, 1.131711, -0.328122, 1.366565, 0.528240, 1.156448, -0.302568, 1.306843, 0.473988, 1.181821, -0.276487, 1.252861, 0.422189, 1.211347, -0.250540, 1.205265, 0.372005, 1.243636, -0.224264, 1.165943, 0.324184, 1.283038, -0.198289, 1.137772, 0.278419, 1.316722, -0.170179, 1.115057, 0.235425, 1.342715, -0.140095, 1.092994, 0.195084, 1.363288, -0.108794, 1.071875, 0.155439, 1.380656, -0.076774, 1.052475, 0.114636, 1.394826, -0.044509, 1.032525, 0.072890, 1.408830, -0.011968, 1.015459, 0.031101, 1.422370, 0.020555, 0.999808, -0.011002, 0.000100, -0.001334, 13.377127, 13.342275, 0.000342, -0.004563, 45.758434, 13.342710, 0.002026, -0.027004, 179.672058, 13.331846, 0.004559, -0.060563, 179.294235, 13.314877, 0.008232, -0.108154, 181.242035, 13.222856, 0.013031, -0.167590, 179.684509, 13.153860, 0.019526, -0.242041, 181.004608, 12.986094, 0.026364, -0.309289, 159.606293, 13.247752, 0.037670, -0.409755, 179.468521, 12.368877, 0.051804, -0.512051, 167.955582, 12.981333, 0.068214, -0.601994, 156.278793, 12.704532, 0.088295, -0.686849, 143.096878, 12.316531, 0.111478, -0.758670, 127.423111, 11.793048, 0.138336, -0.821348, 111.763031, 11.157992, 0.168447, -0.873616, 96.887924, 10.447472, 0.201411, -0.916322, 83.225327, 9.696606, 0.237443, -0.953090, 71.403137, 8.949244, 0.274234, -0.977751, 60.739277, 8.225874, 0.314566, -1.003135, 52.115578, 7.547433, 0.353932, -1.016312, 44.341869, 6.910326, 0.393858, -1.024848, 37.827263, 6.324401, 0.433805, -1.028950, 32.380932, 5.790555, 0.475812, -1.034084, 27.955982, 5.312826, 0.513254, -1.026743, 23.977417, 4.866118, 0.549965, -1.016740, 20.628025, 4.468437, 0.590300, -1.012030, 18.036856, 4.105483, 0.626420, -0.998919, 15.669224, 3.780593, 0.658897, -0.979874, 13.603898, 3.482054, 0.687252, -0.955238, 11.788331, 3.211213, 0.718941, -0.935663, 10.355552, 2.962083, 0.749877, -0.915206, 9.131123, 2.741382, 0.772094, -0.884837, 7.973935, 2.536501, 0.799495, -0.861214, 7.086230, 2.347282, 0.820136, -0.830976, 6.240769, 2.179332, 0.846715, -0.807408, 5.604792, 2.018005, 0.865176, -0.776657, 4.975034, 1.877021, 0.881100, -0.744657, 4.442767, 1.743528, 0.907637, -0.722088, 4.035177, 1.621563, 0.922239, -0.690432, 3.633160, 1.506158, 0.936558, -0.659650, 3.281798, 1.403606, 0.950047, -0.629105, 2.974179, 1.304276, 0.961959, -0.598277, 2.704483, 1.213888, 0.987410, -0.576085, 2.510453, 1.125569, 0.999996, -0.546494, 2.304016, 1.045567, 1.014127, -0.518186, 2.127867, 0.970718, 1.036275, -0.494009, 1.985804, 0.897557, 1.049695, -0.465659, 1.845074, 0.830584, 1.064617, -0.438159, 1.725130, 0.766083, 1.077131, -0.409813, 1.613818, 0.705101, 1.101054, -0.385632, 1.528694, 0.644828, 1.122361, -0.360045, 1.447086, 0.587878, 1.147359, -0.335186, 1.377588, 0.532130, 1.169881, -0.309040, 1.313673, 0.478843, 1.200554, -0.284590, 1.257256, 0.426855, 1.232047, -0.259332, 1.208431, 0.376125, 1.275402, -0.235215, 1.174692, 0.326614, 1.306595, -0.207508, 1.141042, 0.281524, 1.334304, -0.178290, 1.111778, 0.238694, 1.364678, -0.148530, 1.090976, 0.198549, 1.387168, -0.117114, 1.069308, 0.158529, 1.408657, -0.084977, 1.050625, 0.118042, 1.426214, -0.052052, 1.031444, 0.076541, 1.444257, -0.018653, 1.014298, 0.034061, 1.460618, 0.015206, 0.999413, -0.008132, 0.000100, -0.002003, 20.052612, 20.032721, 0.000297, -0.005947, 59.540512, 20.033842, 0.002022, -0.040439, 404.848511, 20.032743, 0.004588, -0.090999, 403.741241, 19.910591, 0.008769, -0.169802, 441.471558, 19.572552, 0.013708, -0.253629, 411.667816, 19.145721, 0.020331, -0.349396, 371.322571, 18.591049, 0.030259, -0.468121, 385.816498, 18.331083, 0.045190, -0.611444, 391.924133, 15.807686, 0.058476, -0.676875, 319.638641, 16.947781, 0.079894, -0.781421, 278.804260, 17.512903, 0.103871, -0.855116, 235.999786, 16.290295, 0.131756, -0.915747, 197.168076, 14.956566, 0.163487, -0.966333, 163.452347, 13.608010, 0.198693, -1.008386, 135.632706, 12.299661, 0.236157, -1.039862, 111.919281, 11.088790, 0.274579, -1.059988, 92.136581, 9.983883, 0.317164, -1.084069, 77.063034, 9.008505, 0.357624, -1.092124, 63.963051, 8.127298, 0.399009, -1.097560, 53.483341, 7.347628, 0.441182, -1.100981, 45.052429, 6.658191, 0.481606, -1.097318, 37.932640, 6.047333, 0.524253, -1.096570, 32.395638, 5.505878, 0.564351, -1.088739, 27.679380, 5.018494, 0.600843, -1.073396, 23.611519, 4.580770, 0.635527, -1.055024, 20.207081, 4.194785, 0.672045, -1.039775, 17.469036, 3.847436, 0.698372, -1.009545, 14.928226, 3.532546, 0.729336, -0.987168, 12.953170, 3.248834, 0.761147, -0.966299, 11.346271, 2.994166, 0.782270, -0.932841, 9.813129, 2.762244, 0.811832, -0.910431, 8.672224, 2.549933, 0.832053, -0.878369, 7.578633, 2.363132, 0.849383, -0.844673, 6.648379, 2.189266, 0.866020, -0.811703, 5.850784, 2.031716, 0.893083, -0.789181, 5.273372, 1.884480, 0.909212, -0.757541, 4.700618, 1.750298, 0.923169, -0.725157, 4.196640, 1.627590, 0.937112, -0.693769, 3.764841, 1.514906, 0.961901, -0.670828, 3.444598, 1.406839, 0.975245, -0.640240, 3.120745, 1.307873, 0.989696, -0.611032, 2.840732, 1.216417, 1.002057, -0.581144, 2.591596, 1.132553, 1.014022, -0.551620, 2.373820, 1.051695, 1.025307, -0.522268, 2.177992, 0.977500, 1.052190, -0.500826, 2.042511, 0.904301, 1.064408, -0.472355, 1.891934, 0.837557, 1.077876, -0.444815, 1.761054, 0.773004, 1.088939, -0.416531, 1.638939, 0.713958, 1.118551, -0.395057, 1.555724, 0.652485, 1.134469, -0.368289, 1.465490, 0.596330, 1.162778, -0.345095, 1.390977, 0.539703, 1.185298, -0.319527, 1.321225, 0.486250, 1.208419, -0.293590, 1.259318, 0.434178, 1.261013, -0.273471, 1.219767, 0.382032, 1.297811, -0.248226, 1.176422, 0.334190, 1.326591, -0.220354, 1.139881, 0.289075, 1.357918, -0.191937, 1.111418, 0.246259, 1.387590, -0.162282, 1.086511, 0.205129, 1.415797, -0.131515, 1.067072, 0.165601, 1.440194, -0.099555, 1.047799, 0.125462, 1.465600, -0.066957, 1.030406, 0.084082, 1.487714, -0.033496, 1.013889, 0.041981, 1.509947, 0.000663, 0.998773, -0.000485, 0.000100, -0.004009, 40.102047, 40.087105, 0.000228, -0.009141, 91.431366, 40.074432, 0.001522, -0.060544, 605.651733, 39.918827, 0.004919, -0.188871, 1712.982300, 38.873421, 0.009053, -0.320325, 1583.453125, 39.715633, 0.015375, -0.471415, 1486.033691, 39.162876, 0.029306, -0.735111, 1751.701050, 28.083200, 0.043450, -0.859759, 1392.475220, 24.599945, 0.079075, -1.220033, 1629.972656, 18.507019, 0.090130, -1.091255, 940.347351, 17.961655, 0.098008, -0.945965, 425.901093, 24.478010, 0.138246, -1.084105, 416.823944, 20.003433, 0.174489, -1.133148, 302.730042, 18.550846, 0.207969, -1.138483, 242.853577, 15.923334, 0.249132, -1.168197, 191.649445, 13.940813, 0.291391, -1.187038, 152.910309, 12.263267, 0.332856, -1.192793, 121.905075, 10.822873, 0.377473, -1.202846, 99.145561, 9.618412, 0.422601, -1.208871, 81.343315, 8.591735, 0.465276, -1.204545, 66.742569, 7.692911, 0.504710, -1.190839, 54.787876, 6.915612, 0.544909, -1.178827, 45.507313, 6.242786, 0.582125, -1.160590, 37.819912, 5.651690, 0.620694, -1.145481, 31.926588, 5.123660, 0.659127, -1.130178, 27.147310, 4.669475, 0.684358, -1.093728, 22.650702, 4.258717, 0.719453, -1.074591, 19.454103, 3.901225, 0.751695, -1.051678, 16.735672, 3.576870, 0.775082, -1.017716, 14.281039, 3.287471, 0.796233, -0.982759, 12.261332, 3.023708, 0.827404, -0.961227, 10.767912, 2.787740, 0.848149, -0.928433, 9.371350, 2.570737, 0.864891, -0.892838, 8.142364, 2.379204, 0.880979, -0.858193, 7.118954, 2.204470, 0.910434, -0.837281, 6.389041, 2.041554, 0.925396, -0.803638, 5.643217, 1.893353, 0.942463, -0.772925, 5.031223, 1.757331, 0.955217, -0.739720, 4.486978, 1.633572, 0.968570, -0.708048, 4.014621, 1.520414, 0.981672, -0.677109, 3.617768, 1.412506, 0.992829, -0.645712, 3.258773, 1.317079, 1.021270, -0.625746, 3.006640, 1.222611, 1.031247, -0.594628, 2.733073, 1.137911, 1.043581, -0.565540, 2.498495, 1.058439, 1.055930, -0.536962, 2.289843, 0.984428, 1.066727, -0.508076, 2.108603, 0.912794, 1.081225, -0.481297, 1.951454, 0.845536, 1.088198, -0.451563, 1.801891, 0.782718, 1.123316, -0.433247, 1.704316, 0.721664, 1.133206, -0.404812, 1.586153, 0.662761, 1.152889, -0.379901, 1.490958, 0.606866, 1.188158, -0.359421, 1.415730, 0.550666, 1.217064, -0.336049, 1.344172, 0.496748, 1.257727, -0.314816, 1.283196, 0.443538, 1.286647, -0.289530, 1.225903, 0.394018, 1.308729, -0.262053, 1.173928, 0.346255, 1.351453, -0.237704, 1.139992, 0.300393, 1.380284, -0.209733, 1.105997, 0.256661, 1.414621, -0.181613, 1.082109, 0.215429, 1.453045, -0.152797, 1.063853, 0.177098, 1.481066, -0.121803, 1.043185, 0.137203, 1.514113, -0.090250, 1.027072, 0.096998, 1.547317, -0.057603, 1.012551, 0.055328, 1.577983, -0.023799, 0.999267, 0.013094, 0.000108, -0.124970, 1249.704346, 1249.703491, 0.000140, -0.119585, 1195.855469, 1195.854370, 0.003995, -0.927433, 9274.246094, 232.443573, 0.012013, -1.131580, 11315.999023, 98.211105, 0.023892, -1.216018, 12162.739258, 67.214500, 0.047506, -1.517865, 15186.294922, 42.410069, 0.082523, -1.812564, 18145.718750, 24.421545, 0.112452, -1.805072, 11112.966797, 18.450365, 0.164460, -2.016784, 8086.032715, 14.043465, 0.195870, -1.898199, 4245.658203, 13.178202, 0.197797, -1.556158, 1315.561768, 30.760096, 0.219540, -1.433455, 802.380371, 25.037956, 0.268696, -1.483235, 579.715515, 20.975695, 0.265968, -1.261051, 386.583649, 12.017023, 0.325369, -1.343349, 316.795959, 12.612406, 0.387968, -1.411606, 232.491623, 13.296940, 0.435543, -1.411236, 181.515228, 11.646996, 0.482729, -1.405722, 143.425354, 10.265131, 0.531742, -1.402782, 114.920082, 9.114828, 0.559383, -1.346165, 88.589005, 8.089214, 0.607851, -1.342407, 73.056610, 7.249064, 0.656928, -1.338238, 60.826897, 6.531094, 0.681212, -1.285692, 48.727219, 5.868711, 0.729238, -1.279951, 41.256016, 5.324553, 0.751172, -1.230045, 33.728260, 4.816513, 0.773107, -1.184288, 27.913816, 4.377203, 0.815726, -1.171653, 24.065962, 3.999965, 0.837886, -1.130636, 20.254860, 3.658493, 0.857674, -1.089071, 17.138168, 3.347930, 0.876120, -1.048303, 14.572968, 3.072666, 0.893935, -1.009040, 12.496377, 2.825165, 0.927998, -0.989064, 11.040731, 2.605520, 0.928445, -0.935017, 9.365102, 2.401481, 0.945279, -0.899993, 8.177711, 2.222282, 0.959378, -0.863854, 7.155303, 2.059342, 0.971761, -0.827684, 6.284632, 1.909314, 0.987812, -0.795878, 5.583837, 1.771094, 1.001958, -0.763540, 4.962345, 1.645968, 1.014357, -0.730897, 4.435898, 1.527438, 1.025946, -0.698675, 3.973241, 1.421337, 1.036435, -0.666662, 3.568025, 1.323677, 1.046807, -0.635466, 3.218647, 1.232678, 1.052974, -0.602660, 2.902273, 1.147675, 1.086089, -0.585364, 2.694939, 1.068352, 1.094660, -0.554784, 2.454491, 0.993445, 1.117131, -0.531500, 2.270746, 0.923758, 1.114009, -0.496581, 2.063934, 0.858381, 1.137328, -0.473914, 1.917990, 0.794980, 1.158671, -0.450127, 1.786523, 0.735697, 1.177878, -0.425306, 1.662454, 0.677498, 1.207510, -0.403797, 1.559058, 0.621762, 1.244496, -0.383812, 1.466801, 0.566190, 1.240412, -0.351080, 1.366853, 0.514288, 1.321257, -0.341200, 1.309808, 0.464621, 1.336512, -0.312710, 1.241822, 0.413228, 1.365047, -0.286935, 1.186612, 0.366092, 1.418984, -0.265184, 1.152120, 0.321528, 1.388864, -0.227750, 1.089937, 0.271827, 1.464383, -0.207168, 1.077271, 0.232838, 1.473125, -0.175770, 1.041835, 0.193289, 1.542908, -0.150424, 1.036794, 0.156153, 1.563005, -0.118748, 1.013029, 0.114866, 1.637048, -0.089604, 1.013493, 0.076804, 1.670777, -0.056398, 0.999208, 0.032691};
+static float ltc_mag_ggx[64*64] = {1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999995, 0.999990, 0.999971, 0.999937, 0.999853, 0.999670, 0.999138, 0.996746, 0.979578, 0.979309, 0.978836, 0.977972, 0.976223, 0.972205, 0.962466, 0.953919, 0.949829, 0.942492, 0.929870, 0.921319, 0.911112, 0.896015, 0.885105, 0.869971, 0.855017, 0.838328, 0.821241, 0.802352, 0.783873, 0.763309, 0.743058, 0.721929, 0.699755, 0.677721, 0.655456, 0.632681, 0.609629, 0.586831, 0.564287, 0.541772, 0.519428, 0.497353, 0.475624, 0.454606, 0.434099, 0.414085, 0.394605, 0.375698, 0.357386, 0.339871, 0.323085, 0.306905, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999999, 0.999998, 0.999995, 0.999990, 0.999980, 0.999959, 0.999923, 0.999842, 0.999660, 0.999119, 0.996613, 0.981824, 0.979298, 0.978826, 0.977957, 0.976184, 0.972091, 0.962188, 0.953875, 0.949746, 0.942335, 0.930166, 0.921211, 0.910927, 0.896979, 0.884940, 0.869864, 0.854835, 0.838200, 0.821049, 0.802552, 0.783659, 0.763512, 0.742927, 0.721715, 0.699938, 0.677775, 0.655246, 0.632555, 0.609805, 0.586996, 0.564225, 0.541606, 0.519346, 0.497419, 0.475863, 0.454738, 0.434099, 0.414003, 0.394547, 0.375747, 0.357564, 0.340012, 0.323099, 0.306861, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999998, 0.999995, 0.999991, 0.999979, 0.999959, 0.999917, 0.999839, 0.999648, 0.999074, 0.996168, 0.983770, 0.979279, 0.978800, 0.977905, 0.976058, 0.971727, 0.962120, 0.953901, 0.949485, 0.941859, 0.930911, 0.920853, 0.910394, 0.897600, 0.884427, 0.870101, 0.854522, 0.838325, 0.820754, 0.802707, 0.783223, 0.763605, 0.742872, 0.721565, 0.699935, 0.677726, 0.655242, 0.632580, 0.609766, 0.586946, 0.564275, 0.541759, 0.519467, 0.497478, 0.475886, 0.454794, 0.434233, 0.414207, 0.394751, 0.375892, 0.357683, 0.340146, 0.323287, 0.307095, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999999, 0.999998, 0.999996, 0.999992, 0.999987, 0.999975, 0.999953, 0.999913, 0.999830, 0.999630, 0.998993, 0.995279, 0.985142, 0.979252, 0.978754, 0.977821, 0.975838, 0.971088, 0.962563, 0.954785, 0.949048, 0.941052, 0.931420, 0.920812, 0.909750, 0.897867, 0.883856, 0.870091, 0.854353, 0.838166, 0.820661, 0.802465, 0.783308, 0.763346, 0.742734, 0.721608, 0.699747, 0.677626, 0.655245, 0.632547, 0.609793, 0.587044, 0.564340, 0.541779, 0.519529, 0.497633, 0.476114, 0.455030, 0.434430, 0.414406, 0.394974, 0.376154, 0.357979, 0.340443, 0.323572, 0.307379, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999998, 0.999998, 0.999996, 0.999991, 0.999984, 0.999970, 0.999946, 0.999905, 0.999815, 0.999599, 0.998856, 0.993704, 0.986135, 0.979212, 0.978690, 0.977691, 0.975504, 0.970133, 0.962951, 0.955649, 0.948405, 0.940418, 0.931660, 0.920881, 0.909376, 0.897785, 0.883844, 0.869756, 0.854326, 0.837732, 0.820617, 0.802053, 0.783195, 0.763119, 0.742610, 0.721344, 0.699709, 0.677624, 0.655114, 0.632523, 0.609812, 0.587052, 0.564417, 0.541966, 0.519751, 0.497824, 0.476309, 0.455271, 0.434735, 0.414736, 0.395317, 0.376524, 0.358364, 0.340852, 0.323988, 0.307786, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999999, 0.999997, 0.999996, 0.999994, 0.999989, 0.999980, 0.999965, 0.999940, 0.999895, 0.999796, 0.999559, 0.998638, 0.992774, 0.986878, 0.980297, 0.978602, 0.977514, 0.975026, 0.969169, 0.963214, 0.956267, 0.947689, 0.940054, 0.931637, 0.920678, 0.908990, 0.897349, 0.883905, 0.869139, 0.854177, 0.837476, 0.820295, 0.801977, 0.782798, 0.762978, 0.742418, 0.721193, 0.699560, 0.677402, 0.655108, 0.632543, 0.609804, 0.587158, 0.564557, 0.542096, 0.519908, 0.498088, 0.476632, 0.455623, 0.435104, 0.415161, 0.395783, 0.377005, 0.358843, 0.341345, 0.324529, 0.308355, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999999, 0.999998, 0.999997, 0.999992, 0.999991, 0.999985, 0.999977, 0.999959, 0.999935, 0.999878, 0.999773, 0.999505, 0.998284, 0.992353, 0.987457, 0.981665, 0.978492, 0.977277, 0.974360, 0.968716, 0.963373, 0.956629, 0.947397, 0.939657, 0.931339, 0.920588, 0.908975, 0.896712, 0.883763, 0.868890, 0.853731, 0.837333, 0.819702, 0.801738, 0.782454, 0.762712, 0.742024, 0.721037, 0.699325, 0.677359, 0.655030, 0.632439, 0.609869, 0.587221, 0.564663, 0.542328, 0.520220, 0.498400, 0.476997, 0.456053, 0.435593, 0.415658, 0.396300, 0.377577, 0.359473, 0.342004, 0.325170, 0.308997, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999998, 0.999998, 0.999996, 0.999993, 0.999988, 0.999981, 0.999971, 0.999951, 0.999921, 0.999863, 0.999748, 0.999433, 0.997681, 0.992120, 0.987920, 0.982864, 0.978353, 0.976961, 0.973451, 0.968396, 0.963400, 0.956680, 0.947529, 0.939151, 0.930747, 0.920511, 0.908867, 0.896142, 0.883335, 0.868764, 0.853025, 0.837015, 0.819452, 0.801249, 0.782176, 0.762345, 0.741843, 0.720721, 0.699135, 0.677194, 0.654889, 0.632487, 0.609902, 0.587328, 0.564891, 0.542567, 0.520501, 0.498793, 0.477442, 0.456528, 0.436131, 0.416273, 0.396980, 0.378276, 0.360176, 0.342738, 0.325950, 0.309803, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999998, 0.999999, 0.999997, 0.999995, 0.999991, 0.999985, 0.999978, 0.999963, 0.999942, 0.999907, 0.999844, 0.999715, 0.999332, 0.996612, 0.991974, 0.988297, 0.983843, 0.978349, 0.976540, 0.972351, 0.968109, 0.963280, 0.956464, 0.947779, 0.938754, 0.929952, 0.920253, 0.908530, 0.895785, 0.882679, 0.868456, 0.852669, 0.836406, 0.819138, 0.800708, 0.781803, 0.761855, 0.741534, 0.720405, 0.698959, 0.676964, 0.654827, 0.632411, 0.609922, 0.587477, 0.565051, 0.542829, 0.520889, 0.499225, 0.477951, 0.457148, 0.436792, 0.416963, 0.397723, 0.379068, 0.361025, 0.343608, 0.326842, 0.310718, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999998, 0.999995, 0.999994, 0.999990, 0.999983, 0.999971, 0.999954, 0.999932, 0.999892, 0.999820, 0.999675, 0.999190, 0.995492, 0.991911, 0.988610, 0.984662, 0.979221, 0.975975, 0.971671, 0.967788, 0.963002, 0.955938, 0.947965, 0.938692, 0.929309, 0.919781, 0.908268, 0.895518, 0.882022, 0.867884, 0.852346, 0.835746, 0.818607, 0.800261, 0.781335, 0.761539, 0.741063, 0.720116, 0.698617, 0.676815, 0.654700, 0.632389, 0.610037, 0.587591, 0.565328, 0.543205, 0.521293, 0.499745, 0.478562, 0.457776, 0.437515, 0.417776, 0.398586, 0.379963, 0.361984, 0.344616, 0.327857, 0.311751, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999997, 0.999996, 0.999992, 0.999986, 0.999977, 0.999965, 0.999947, 0.999916, 0.999873, 0.999794, 0.999628, 0.998966, 0.994914, 0.991849, 0.988873, 0.985288, 0.980170, 0.975207, 0.971156, 0.967476, 0.962538, 0.955601, 0.947978, 0.938542, 0.928618, 0.919056, 0.907890, 0.895098, 0.881352, 0.867263, 0.851806, 0.835168, 0.818003, 0.799785, 0.780633, 0.761080, 0.740618, 0.719795, 0.698332, 0.676629, 0.654544, 0.632411, 0.610042, 0.587805, 0.565593, 0.543549, 0.521793, 0.500309, 0.479195, 0.458546, 0.438353, 0.418669, 0.399557, 0.381012, 0.363049, 0.345710, 0.329006, 0.312948, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999997, 0.999993, 0.999990, 0.999984, 0.999972, 0.999960, 0.999939, 0.999906, 0.999853, 0.999765, 0.999567, 0.998603, 0.994519, 0.991794, 0.989089, 0.985781, 0.980956, 0.974161, 0.970688, 0.967064, 0.961890, 0.955292, 0.947848, 0.938359, 0.928226, 0.918214, 0.907361, 0.894702, 0.880834, 0.866500, 0.851209, 0.834627, 0.817211, 0.799250, 0.780131, 0.760512, 0.740218, 0.719264, 0.698063, 0.676325, 0.654450, 0.632316, 0.610170, 0.587988, 0.565891, 0.544013, 0.522305, 0.500958, 0.479971, 0.459376, 0.439271, 0.419699, 0.400620, 0.382126, 0.364246, 0.346967, 0.330273, 0.314236, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999998, 0.999996, 0.999994, 0.999988, 0.999979, 0.999967, 0.999952, 0.999924, 0.999888, 0.999833, 0.999733, 0.999490, 0.997946, 0.994192, 0.991812, 0.989274, 0.986224, 0.981547, 0.974000, 0.970269, 0.966545, 0.961031, 0.954921, 0.947416, 0.938226, 0.928003, 0.917390, 0.906553, 0.894191, 0.880329, 0.865540, 0.850476, 0.834058, 0.816467, 0.798509, 0.779561, 0.759828, 0.739738, 0.718878, 0.697718, 0.676138, 0.654342, 0.632317, 0.610292, 0.588207, 0.566289, 0.544443, 0.522927, 0.501674, 0.480765, 0.460314, 0.440304, 0.420782, 0.401824, 0.383410, 0.365538, 0.348312, 0.331692, 0.315688, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999998, 0.999996, 0.999993, 0.999985, 0.999976, 0.999961, 0.999943, 0.999913, 0.999872, 0.999807, 0.999691, 0.999390, 0.996859, 0.994003, 0.991808, 0.989423, 0.986523, 0.981783, 0.974511, 0.969791, 0.965933, 0.960377, 0.954434, 0.946803, 0.938026, 0.927620, 0.916545, 0.905639, 0.893489, 0.879820, 0.864852, 0.849513, 0.833311, 0.815878, 0.797621, 0.778938, 0.759253, 0.739142, 0.718479, 0.697274, 0.675902, 0.654135, 0.632357, 0.610364, 0.588497, 0.566631, 0.545012, 0.523579, 0.502429, 0.481680, 0.461304, 0.441425, 0.422039, 0.403135, 0.384779, 0.366976, 0.349796, 0.333231, 0.317277, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999998, 0.999996, 0.999991, 0.999983, 0.999974, 0.999956, 0.999932, 0.999901, 0.999852, 0.999780, 0.999646, 0.999248, 0.996193, 0.993784, 0.991782, 0.989539, 0.986694, 0.981765, 0.975135, 0.969309, 0.965128, 0.959788, 0.953831, 0.946255, 0.937664, 0.927351, 0.916044, 0.904715, 0.892528, 0.879111, 0.864256, 0.848452, 0.832434, 0.815129, 0.796806, 0.778118, 0.758668, 0.738466, 0.718024, 0.696958, 0.675642, 0.654067, 0.632325, 0.610546, 0.588786, 0.567123, 0.545617, 0.524312, 0.503348, 0.482637, 0.462418, 0.442657, 0.423338, 0.404564, 0.386277, 0.368545, 0.351448, 0.334906, 0.318961, 1.000000, 1.000000, 1.000000, 0.999999, 0.999999, 0.999998, 0.999994, 0.999989, 0.999979, 0.999968, 0.999949, 0.999921, 0.999886, 0.999833, 0.999747, 0.999596, 0.999029, 0.995749, 0.993677, 0.991724, 0.989620, 0.986723, 0.981515, 0.975767, 0.969056, 0.964124, 0.959142, 0.953036, 0.945650, 0.937022, 0.926971, 0.915515, 0.903584, 0.891603, 0.878212, 0.863472, 0.847652, 0.831398, 0.814299, 0.796105, 0.777231, 0.757977, 0.737895, 0.717415, 0.696595, 0.675317, 0.653980, 0.632343, 0.610735, 0.589076, 0.567620, 0.546251, 0.525165, 0.504255, 0.483759, 0.463666, 0.443987, 0.424783, 0.406042, 0.387891, 0.370293, 0.353221, 0.336715, 0.320806, 1.000000, 1.000000, 1.000000, 0.999999, 0.999998, 0.999998, 0.999993, 0.999987, 0.999977, 0.999964, 0.999943, 0.999911, 0.999867, 0.999807, 0.999714, 0.999531, 0.998645, 0.995399, 0.993512, 0.991717, 0.989661, 0.986652, 0.981559, 0.976183, 0.969411, 0.963317, 0.958457, 0.952091, 0.944951, 0.936307, 0.926454, 0.915043, 0.902668, 0.890462, 0.877245, 0.862672, 0.846823, 0.830201, 0.813293, 0.795306, 0.776393, 0.757199, 0.737324, 0.716808, 0.696187, 0.675094, 0.653814, 0.632453, 0.610885, 0.589483, 0.568099, 0.546975, 0.525953, 0.505268, 0.484936, 0.464988, 0.445458, 0.426314, 0.407750, 0.389670, 0.372098, 0.355105, 0.338682, 0.322825, 1.000000, 1.000000, 1.000000, 1.000000, 0.999999, 0.999996, 0.999992, 0.999983, 0.999976, 0.999959, 0.999933, 0.999898, 0.999849, 0.999780, 0.999676, 0.999454, 0.997884, 0.995166, 0.993394, 0.991723, 0.989654, 0.986389, 0.981632, 0.976607, 0.969701, 0.962555, 0.957605, 0.951232, 0.944099, 0.935556, 0.925699, 0.914492, 0.902027, 0.889116, 0.876093, 0.861649, 0.845956, 0.829238, 0.812220, 0.794420, 0.775657, 0.756265, 0.736673, 0.716372, 0.695669, 0.674886, 0.653728, 0.632568, 0.611217, 0.589929, 0.568783, 0.547752, 0.526931, 0.506425, 0.486238, 0.466425, 0.446945, 0.428026, 0.409536, 0.391551, 0.374087, 0.357155, 0.340787, 0.324974, 1.000000, 1.000000, 1.000000, 1.000000, 0.999998, 0.999996, 0.999990, 0.999984, 0.999970, 0.999952, 0.999925, 0.999886, 0.999831, 0.999757, 0.999633, 0.999356, 0.997017, 0.994868, 0.993337, 0.991710, 0.989580, 0.985848, 0.981640, 0.976711, 0.969755, 0.962166, 0.956609, 0.950365, 0.943026, 0.934693, 0.924880, 0.913729, 0.901350, 0.887966, 0.874726, 0.860474, 0.844905, 0.828269, 0.810905, 0.793364, 0.774812, 0.755478, 0.735886, 0.715847, 0.695231, 0.674537, 0.653667, 0.632527, 0.611475, 0.590363, 0.569462, 0.548571, 0.527976, 0.507634, 0.487632, 0.467901, 0.448680, 0.429833, 0.411467, 0.393568, 0.376197, 0.359374, 0.343034, 0.327273, 1.000000, 1.000000, 1.000000, 0.999999, 0.999998, 0.999993, 0.999989, 0.999980, 0.999965, 0.999945, 0.999913, 0.999869, 0.999810, 0.999723, 0.999583, 0.999213, 0.996540, 0.994740, 0.993244, 0.991671, 0.989411, 0.985533, 0.981616, 0.976847, 0.969968, 0.962315, 0.955468, 0.949420, 0.942016, 0.933617, 0.923949, 0.912899, 0.900495, 0.887022, 0.873283, 0.859153, 0.843830, 0.827325, 0.809888, 0.792172, 0.773832, 0.754686, 0.735035, 0.715297, 0.694955, 0.674242, 0.653660, 0.632752, 0.611804, 0.590993, 0.570154, 0.549539, 0.529087, 0.508974, 0.489030, 0.469599, 0.450466, 0.431761, 0.413508, 0.395761, 0.378480, 0.361679, 0.345465, 0.329752, 1.000000, 1.000000, 1.000000, 1.000000, 0.999997, 0.999994, 0.999987, 0.999978, 0.999961, 0.999936, 0.999903, 0.999855, 0.999786, 0.999689, 0.999527, 0.998988, 0.996137, 0.994527, 0.993108, 0.991599, 0.989084, 0.985308, 0.981527, 0.976677, 0.970079, 0.962535, 0.954490, 0.948271, 0.940942, 0.932422, 0.922836, 0.911896, 0.899632, 0.886118, 0.871864, 0.857719, 0.842536, 0.826163, 0.808849, 0.790860, 0.772802, 0.753860, 0.734335, 0.714582, 0.694543, 0.674071, 0.653544, 0.632922, 0.612153, 0.591573, 0.570951, 0.550520, 0.530352, 0.510311, 0.490707, 0.471359, 0.452396, 0.433837, 0.415736, 0.398052, 0.380874, 0.364232, 0.348023, 0.332368, 1.000000, 1.000000, 1.000000, 0.999999, 0.999998, 0.999994, 0.999988, 0.999976, 0.999957, 0.999928, 0.999891, 0.999837, 0.999759, 0.999650, 0.999463, 0.998551, 0.995879, 0.994366, 0.992964, 0.991479, 0.988521, 0.985101, 0.981482, 0.976168, 0.970242, 0.962585, 0.953950, 0.946973, 0.939686, 0.931248, 0.921614, 0.910765, 0.898617, 0.885183, 0.870772, 0.856138, 0.841120, 0.824962, 0.807732, 0.789813, 0.771638, 0.753008, 0.733686, 0.713927, 0.694082, 0.673967, 0.653549, 0.633135, 0.612702, 0.592200, 0.571904, 0.551679, 0.531678, 0.511898, 0.492437, 0.473239, 0.454451, 0.436067, 0.418054, 0.400542, 0.383486, 0.366848, 0.350781, 0.335182, 1.000000, 1.000000, 1.000000, 0.999999, 0.999997, 0.999993, 0.999985, 0.999972, 0.999951, 0.999919, 0.999877, 0.999817, 0.999733, 0.999608, 0.999380, 0.997685, 0.995603, 0.994264, 0.992911, 0.991287, 0.987923, 0.984871, 0.981239, 0.975933, 0.970149, 0.962511, 0.953824, 0.945699, 0.938285, 0.929907, 0.920343, 0.909537, 0.897435, 0.884056, 0.869626, 0.854490, 0.839459, 0.823511, 0.806511, 0.788752, 0.770440, 0.751995, 0.732962, 0.713424, 0.693525, 0.673798, 0.653622, 0.633301, 0.613224, 0.592938, 0.572833, 0.552904, 0.533030, 0.513556, 0.494215, 0.475279, 0.456673, 0.438411, 0.420583, 0.403178, 0.386178, 0.369728, 0.353688, 0.338147, 1.000000, 1.000000, 1.000000, 0.999999, 0.999997, 0.999991, 0.999984, 0.999967, 0.999944, 0.999912, 0.999863, 0.999796, 0.999703, 0.999563, 0.999279, 0.997104, 0.995394, 0.994111, 0.992825, 0.990979, 0.987529, 0.984661, 0.980774, 0.975758, 0.969866, 0.962465, 0.953678, 0.944489, 0.936886, 0.928356, 0.918820, 0.908073, 0.896092, 0.882833, 0.868463, 0.853212, 0.837744, 0.822048, 0.805333, 0.787643, 0.769414, 0.750830, 0.732178, 0.712972, 0.693227, 0.673569, 0.653744, 0.633739, 0.613735, 0.593822, 0.573916, 0.554158, 0.534652, 0.515248, 0.496233, 0.477436, 0.459009, 0.440929, 0.423259, 0.405951, 0.389136, 0.372690, 0.356789, 0.341329, 1.000000, 1.000000, 1.000000, 0.999999, 0.999996, 0.999991, 0.999981, 0.999966, 0.999939, 0.999903, 0.999847, 0.999771, 0.999666, 0.999510, 0.999131, 0.996690, 0.995147, 0.993882, 0.992696, 0.990474, 0.987227, 0.984334, 0.980153, 0.975438, 0.969406, 0.962238, 0.953598, 0.943868, 0.935356, 0.926721, 0.917122, 0.906430, 0.894550, 0.881354, 0.867131, 0.851954, 0.835972, 0.820331, 0.803911, 0.786452, 0.768420, 0.749821, 0.731298, 0.712393, 0.692979, 0.673418, 0.653859, 0.634232, 0.614327, 0.594732, 0.575131, 0.555584, 0.536346, 0.517175, 0.498323, 0.479744, 0.461485, 0.443645, 0.426061, 0.408969, 0.392155, 0.375921, 0.360060, 0.344677, 1.000000, 1.000000, 1.000000, 0.999999, 0.999997, 0.999991, 0.999979, 0.999960, 0.999931, 0.999891, 0.999832, 0.999748, 0.999629, 0.999449, 0.998880, 0.996305, 0.995024, 0.993812, 0.992508, 0.989721, 0.986936, 0.983936, 0.979629, 0.974979, 0.968928, 0.961970, 0.953291, 0.943458, 0.933644, 0.925007, 0.915388, 0.904755, 0.892932, 0.879831, 0.865794, 0.850672, 0.834591, 0.818398, 0.802304, 0.785151, 0.767450, 0.748987, 0.730325, 0.711758, 0.692761, 0.673417, 0.653908, 0.634686, 0.615168, 0.595707, 0.576393, 0.557198, 0.538018, 0.519253, 0.500555, 0.482220, 0.464197, 0.446414, 0.429106, 0.412035, 0.395508, 0.379284, 0.363538, 0.348220, 1.000000, 1.000000, 1.000000, 0.999999, 0.999995, 0.999989, 0.999977, 0.999955, 0.999924, 0.999879, 0.999813, 0.999722, 0.999590, 0.999381, 0.998335, 0.996088, 0.994814, 0.993709, 0.992220, 0.989209, 0.986575, 0.983383, 0.979084, 0.974272, 0.968359, 0.961275, 0.953025, 0.943098, 0.932434, 0.923101, 0.913477, 0.902861, 0.891059, 0.878072, 0.864118, 0.849188, 0.833281, 0.816808, 0.800596, 0.783745, 0.766331, 0.748123, 0.729686, 0.711078, 0.692527, 0.673491, 0.654296, 0.635113, 0.616048, 0.596847, 0.577720, 0.558879, 0.540028, 0.521371, 0.502996, 0.484858, 0.466997, 0.449477, 0.432217, 0.415426, 0.398924, 0.382890, 0.367206, 0.351955, 1.000000, 1.000000, 1.000000, 0.999998, 0.999996, 0.999988, 0.999974, 0.999953, 0.999918, 0.999865, 0.999791, 0.999690, 0.999542, 0.999293, 0.997535, 0.995790, 0.994609, 0.993557, 0.991766, 0.988767, 0.986255, 0.982544, 0.978541, 0.973528, 0.967700, 0.960596, 0.952299, 0.942684, 0.931653, 0.921211, 0.911489, 0.900818, 0.889018, 0.876245, 0.862406, 0.847517, 0.831852, 0.815367, 0.798719, 0.782224, 0.765167, 0.747304, 0.729133, 0.710485, 0.692196, 0.673589, 0.654770, 0.635717, 0.616986, 0.598119, 0.579298, 0.560560, 0.542163, 0.523669, 0.505564, 0.487642, 0.469991, 0.452658, 0.435620, 0.418937, 0.402612, 0.386633, 0.371091, 0.355949, 1.000000, 1.000000, 0.999999, 0.999998, 0.999995, 0.999986, 0.999973, 0.999948, 0.999909, 0.999852, 0.999769, 0.999656, 0.999490, 0.999186, 0.997059, 0.995624, 0.994510, 0.993327, 0.991020, 0.988379, 0.985771, 0.981971, 0.978051, 0.972892, 0.967020, 0.959965, 0.951625, 0.941902, 0.930951, 0.919370, 0.909285, 0.898562, 0.886809, 0.874251, 0.860597, 0.845808, 0.830365, 0.813972, 0.797260, 0.780597, 0.763854, 0.746401, 0.728519, 0.710203, 0.691882, 0.673687, 0.655275, 0.636621, 0.617909, 0.599473, 0.581032, 0.562560, 0.544295, 0.526228, 0.508293, 0.490652, 0.473242, 0.456004, 0.439212, 0.422663, 0.406476, 0.390647, 0.375204, 0.360129, 1.000000, 1.000000, 1.000000, 0.999999, 0.999994, 0.999984, 0.999969, 0.999940, 0.999898, 0.999837, 0.999746, 0.999617, 0.999438, 0.999016, 0.996703, 0.995302, 0.994356, 0.992993, 0.990390, 0.988072, 0.985152, 0.981447, 0.977273, 0.972234, 0.966113, 0.959033, 0.950869, 0.941217, 0.930175, 0.918279, 0.906941, 0.896201, 0.884509, 0.871920, 0.858420, 0.843906, 0.828730, 0.812524, 0.795978, 0.778979, 0.762450, 0.745459, 0.727966, 0.710046, 0.691808, 0.673739, 0.655756, 0.637574, 0.619153, 0.600887, 0.582796, 0.564748, 0.546636, 0.528904, 0.511252, 0.493791, 0.476563, 0.459695, 0.442942, 0.426632, 0.410558, 0.394895, 0.379517, 0.364560, 1.000000, 1.000000, 1.000000, 0.999998, 0.999994, 0.999984, 0.999966, 0.999934, 0.999887, 0.999819, 0.999720, 0.999578, 0.999367, 0.998696, 0.996353, 0.995201, 0.994115, 0.992665, 0.989948, 0.987633, 0.984331, 0.980827, 0.976390, 0.971327, 0.965201, 0.957977, 0.949712, 0.940128, 0.929187, 0.917237, 0.904645, 0.893711, 0.882112, 0.869516, 0.856236, 0.841929, 0.826924, 0.810991, 0.794686, 0.777761, 0.760980, 0.744384, 0.727314, 0.709877, 0.691988, 0.674098, 0.656243, 0.638603, 0.620606, 0.602574, 0.584694, 0.567018, 0.549311, 0.531673, 0.514403, 0.497148, 0.480177, 0.463439, 0.446998, 0.430743, 0.414943, 0.399304, 0.384121, 0.369251, 1.000000, 1.000000, 1.000000, 0.999997, 0.999992, 0.999981, 0.999962, 0.999927, 0.999874, 0.999798, 0.999691, 0.999533, 0.999291, 0.997909, 0.996117, 0.995029, 0.993880, 0.992142, 0.989576, 0.987185, 0.983587, 0.980055, 0.975487, 0.970172, 0.963998, 0.956738, 0.948637, 0.939083, 0.928169, 0.916144, 0.903147, 0.890916, 0.879389, 0.866895, 0.853826, 0.839729, 0.824957, 0.809472, 0.793341, 0.776743, 0.759808, 0.743277, 0.726643, 0.709685, 0.692249, 0.674639, 0.657008, 0.639576, 0.622114, 0.604471, 0.586851, 0.569340, 0.552135, 0.534806, 0.517599, 0.500765, 0.484035, 0.467440, 0.451212, 0.435240, 0.419399, 0.404083, 0.388944, 0.374182, 1.000000, 1.000000, 1.000000, 0.999998, 0.999993, 0.999979, 0.999958, 0.999919, 0.999861, 0.999774, 0.999656, 0.999482, 0.999195, 0.997307, 0.995837, 0.994722, 0.993707, 0.991391, 0.989169, 0.986461, 0.982904, 0.979062, 0.974536, 0.969035, 0.962653, 0.955486, 0.947243, 0.937747, 0.926861, 0.914936, 0.901835, 0.888472, 0.876571, 0.864223, 0.851252, 0.837374, 0.822985, 0.807788, 0.791927, 0.775702, 0.758928, 0.742347, 0.725914, 0.709495, 0.692569, 0.675363, 0.658085, 0.640639, 0.623698, 0.606505, 0.589267, 0.572008, 0.554939, 0.538132, 0.521211, 0.504487, 0.488048, 0.471807, 0.455651, 0.439858, 0.424332, 0.408983, 0.394071, 0.379402, 1.000000, 1.000000, 1.000000, 0.999997, 0.999992, 0.999978, 0.999954, 0.999913, 0.999844, 0.999753, 0.999618, 0.999424, 0.999067, 0.996875, 0.995659, 0.994603, 0.993420, 0.990874, 0.988713, 0.985585, 0.982193, 0.978145, 0.973416, 0.967801, 0.961483, 0.954069, 0.945704, 0.936138, 0.925374, 0.913395, 0.900339, 0.886675, 0.873512, 0.861326, 0.848513, 0.834956, 0.820820, 0.805943, 0.790574, 0.774677, 0.758279, 0.741807, 0.725271, 0.709231, 0.692874, 0.676189, 0.659352, 0.642296, 0.625250, 0.608700, 0.591823, 0.575012, 0.558143, 0.541491, 0.525075, 0.508558, 0.492277, 0.476270, 0.460459, 0.444740, 0.429400, 0.414309, 0.399421, 0.384907, 1.000000, 1.000000, 1.000000, 0.999997, 0.999990, 0.999977, 0.999947, 0.999902, 0.999832, 0.999730, 0.999577, 0.999359, 0.998845, 0.996554, 0.995328, 0.994442, 0.992919, 0.990393, 0.988170, 0.984855, 0.981312, 0.977149, 0.972137, 0.966207, 0.959967, 0.952454, 0.943873, 0.934434, 0.923813, 0.911942, 0.898928, 0.885120, 0.871043, 0.858248, 0.845666, 0.832346, 0.818482, 0.804029, 0.788982, 0.773571, 0.757700, 0.741484, 0.725186, 0.708915, 0.693244, 0.677028, 0.660656, 0.644079, 0.627377, 0.610804, 0.594542, 0.578112, 0.561650, 0.545163, 0.528962, 0.512926, 0.496893, 0.481007, 0.465397, 0.450042, 0.434740, 0.419831, 0.405156, 0.390692, 1.000000, 1.000000, 0.999999, 0.999997, 0.999989, 0.999973, 0.999942, 0.999891, 0.999813, 0.999698, 0.999532, 0.999285, 0.998286, 0.996295, 0.995215, 0.994182, 0.992032, 0.989855, 0.987415, 0.984047, 0.980050, 0.976017, 0.970845, 0.964767, 0.958269, 0.950600, 0.942033, 0.932501, 0.921807, 0.910017, 0.897149, 0.883414, 0.869182, 0.855055, 0.842687, 0.829548, 0.816162, 0.802072, 0.787436, 0.772533, 0.757043, 0.741263, 0.725330, 0.709262, 0.693497, 0.678038, 0.662128, 0.646068, 0.629824, 0.613437, 0.597334, 0.581401, 0.565372, 0.549288, 0.533182, 0.517405, 0.501765, 0.486143, 0.470675, 0.455465, 0.440532, 0.425630, 0.411113, 0.396887, 1.000000, 1.000000, 0.999999, 0.999996, 0.999989, 0.999970, 0.999934, 0.999879, 0.999793, 0.999665, 0.999481, 0.999192, 0.997506, 0.995926, 0.995009, 0.993736, 0.991298, 0.989326, 0.986371, 0.983199, 0.979032, 0.974596, 0.969364, 0.963198, 0.956385, 0.948509, 0.939993, 0.930421, 0.919590, 0.908140, 0.895349, 0.881699, 0.867456, 0.852784, 0.839500, 0.826629, 0.813602, 0.799983, 0.785873, 0.771340, 0.756480, 0.741190, 0.725687, 0.709997, 0.694192, 0.678975, 0.663673, 0.648135, 0.632442, 0.616477, 0.600565, 0.584772, 0.569202, 0.553595, 0.537881, 0.522193, 0.506784, 0.491554, 0.476349, 0.461278, 0.446419, 0.431913, 0.417443, 0.403271, 1.000000, 1.000000, 0.999999, 0.999995, 0.999986, 0.999966, 0.999927, 0.999867, 0.999772, 0.999629, 0.999423, 0.999075, 0.997024, 0.995773, 0.994651, 0.993353, 0.990822, 0.988569, 0.985596, 0.982182, 0.977871, 0.973140, 0.967584, 0.961408, 0.954294, 0.946398, 0.937603, 0.927937, 0.917305, 0.905833, 0.893138, 0.879770, 0.865720, 0.851023, 0.836801, 0.823784, 0.810909, 0.797886, 0.784177, 0.770243, 0.755925, 0.741144, 0.726214, 0.710971, 0.695563, 0.680212, 0.665304, 0.650297, 0.635168, 0.619796, 0.604217, 0.588692, 0.573254, 0.557998, 0.542839, 0.527470, 0.512162, 0.497115, 0.482296, 0.467477, 0.452812, 0.438310, 0.424184, 0.410163, 1.000000, 1.000000, 0.999999, 0.999996, 0.999984, 0.999962, 0.999920, 0.999852, 0.999745, 0.999586, 0.999354, 0.998894, 0.996686, 0.995485, 0.994493, 0.992573, 0.990323, 0.987772, 0.984692, 0.980887, 0.976446, 0.971625, 0.965717, 0.959421, 0.951975, 0.944086, 0.935066, 0.925403, 0.914814, 0.903208, 0.890958, 0.877817, 0.863828, 0.849289, 0.834872, 0.820889, 0.808183, 0.795660, 0.782556, 0.769066, 0.755386, 0.741229, 0.726726, 0.712170, 0.697209, 0.682170, 0.667203, 0.652689, 0.637938, 0.623262, 0.608190, 0.593002, 0.577817, 0.562737, 0.547836, 0.533036, 0.518052, 0.503135, 0.488422, 0.473986, 0.459552, 0.445282, 0.431149, 0.417407, 1.000000, 1.000000, 0.999999, 0.999994, 0.999983, 0.999957, 0.999914, 0.999835, 0.999718, 0.999538, 0.999275, 0.998454, 0.996341, 0.995246, 0.994222, 0.991844, 0.989829, 0.986688, 0.983562, 0.979638, 0.974932, 0.969827, 0.963621, 0.957146, 0.949365, 0.941398, 0.932245, 0.922556, 0.911949, 0.900627, 0.888440, 0.875544, 0.862005, 0.847810, 0.833372, 0.819134, 0.805508, 0.793339, 0.780916, 0.767837, 0.754858, 0.741307, 0.727496, 0.713386, 0.699131, 0.684542, 0.669878, 0.655261, 0.641035, 0.626685, 0.612377, 0.597625, 0.582805, 0.568030, 0.553204, 0.538684, 0.524269, 0.509662, 0.495119, 0.480735, 0.466634, 0.452593, 0.438748, 0.424915, 1.000000, 1.000000, 0.999998, 0.999994, 0.999982, 0.999956, 0.999901, 0.999818, 0.999683, 0.999487, 0.999185, 0.997584, 0.996004, 0.995050, 0.993715, 0.991212, 0.989057, 0.985879, 0.982243, 0.978206, 0.973119, 0.967919, 0.961343, 0.954603, 0.946712, 0.938378, 0.929266, 0.919443, 0.908911, 0.897725, 0.885589, 0.873254, 0.859889, 0.846123, 0.832094, 0.817898, 0.803866, 0.791061, 0.779235, 0.766885, 0.754292, 0.741565, 0.728331, 0.714861, 0.701179, 0.687166, 0.673012, 0.658716, 0.644442, 0.630472, 0.616519, 0.602514, 0.588172, 0.573689, 0.559281, 0.544768, 0.530543, 0.516485, 0.502303, 0.488100, 0.474095, 0.460245, 0.446598, 0.433169, 1.000000, 1.000000, 0.999997, 0.999993, 0.999980, 0.999947, 0.999891, 0.999794, 0.999647, 0.999425, 0.999062, 0.997049, 0.995778, 0.994652, 0.992778, 0.990482, 0.988004, 0.984893, 0.980881, 0.976605, 0.971199, 0.965610, 0.958925, 0.951746, 0.943791, 0.935200, 0.926018, 0.916028, 0.905724, 0.894528, 0.882914, 0.870740, 0.857802, 0.844552, 0.830857, 0.816921, 0.803102, 0.789625, 0.777480, 0.765891, 0.753908, 0.741795, 0.729390, 0.716440, 0.703411, 0.690068, 0.676438, 0.662586, 0.648697, 0.634732, 0.620997, 0.607451, 0.593765, 0.579748, 0.565661, 0.551594, 0.537396, 0.523433, 0.509708, 0.495972, 0.482082, 0.468427, 0.454890, 0.441623, 1.000000, 1.000000, 0.999999, 0.999991, 0.999977, 0.999940, 0.999875, 0.999769, 0.999605, 0.999352, 0.998882, 0.996665, 0.995459, 0.994380, 0.992014, 0.989912, 0.986796, 0.983537, 0.979326, 0.974792, 0.969140, 0.963160, 0.956222, 0.948807, 0.940518, 0.931755, 0.922452, 0.912319, 0.902227, 0.891142, 0.879838, 0.868047, 0.855745, 0.842718, 0.829827, 0.816398, 0.802786, 0.789396, 0.776581, 0.764901, 0.753710, 0.742102, 0.730448, 0.718337, 0.705768, 0.693172, 0.680153, 0.666882, 0.653401, 0.639837, 0.626152, 0.612676, 0.599435, 0.586109, 0.572473, 0.558715, 0.544964, 0.531112, 0.517416, 0.503992, 0.490653, 0.477162, 0.463832, 0.450645, 1.000000, 1.000000, 0.999999, 0.999992, 0.999973, 0.999933, 0.999861, 0.999741, 0.999554, 0.999267, 0.998411, 0.996303, 0.995191, 0.993945, 0.991406, 0.989019, 0.985720, 0.982057, 0.977501, 0.972605, 0.966697, 0.960340, 0.953031, 0.945347, 0.936866, 0.927917, 0.918562, 0.908598, 0.898486, 0.887794, 0.876545, 0.865379, 0.853428, 0.841167, 0.828649, 0.815967, 0.802957, 0.789865, 0.777077, 0.764695, 0.753544, 0.742694, 0.731571, 0.720304, 0.708490, 0.696351, 0.684134, 0.671470, 0.658541, 0.645376, 0.632209, 0.618776, 0.605511, 0.592527, 0.579546, 0.566310, 0.552860, 0.539492, 0.526005, 0.512564, 0.499340, 0.486360, 0.473357, 0.460306, 1.000000, 1.000000, 0.999998, 0.999991, 0.999970, 0.999926, 0.999842, 0.999710, 0.999498, 0.999164, 0.997464, 0.995870, 0.994917, 0.992911, 0.990682, 0.987816, 0.984410, 0.980551, 0.975693, 0.970263, 0.963946, 0.957248, 0.949765, 0.941571, 0.932941, 0.923873, 0.914332, 0.904560, 0.894394, 0.884127, 0.873294, 0.862503, 0.851335, 0.839566, 0.827776, 0.815708, 0.803370, 0.790821, 0.778386, 0.766121, 0.754193, 0.743420, 0.732975, 0.722326, 0.711376, 0.699992, 0.688180, 0.676354, 0.664004, 0.651449, 0.638600, 0.625776, 0.612660, 0.599603, 0.586719, 0.574078, 0.561273, 0.548129, 0.535155, 0.522015, 0.508851, 0.495837, 0.483190, 0.470624, 1.000000, 1.000000, 0.999998, 0.999988, 0.999965, 0.999916, 0.999823, 0.999669, 0.999425, 0.999025, 0.996874, 0.995670, 0.994415, 0.991991, 0.989766, 0.986646, 0.982812, 0.978356, 0.973317, 0.967612, 0.960820, 0.953603, 0.945969, 0.937323, 0.928661, 0.919507, 0.909833, 0.900245, 0.890390, 0.880252, 0.870000, 0.859518, 0.849163, 0.838101, 0.826960, 0.815688, 0.804126, 0.792234, 0.780356, 0.768474, 0.756678, 0.745159, 0.734601, 0.724624, 0.714339, 0.703751, 0.692766, 0.681267, 0.669799, 0.657871, 0.645577, 0.633102, 0.620560, 0.607737, 0.594890, 0.582143, 0.569779, 0.557360, 0.544651, 0.531942, 0.519228, 0.506467, 0.493710, 0.481143, 1.000000, 1.000000, 0.999998, 0.999988, 0.999961, 0.999902, 0.999798, 0.999622, 0.999341, 0.998801, 0.996397, 0.995225, 0.993927, 0.991338, 0.988500, 0.985327, 0.981195, 0.976383, 0.970726, 0.964471, 0.957386, 0.949813, 0.941694, 0.932681, 0.923974, 0.914755, 0.905026, 0.895649, 0.886178, 0.876277, 0.866629, 0.856890, 0.846934, 0.836887, 0.826373, 0.815885, 0.805169, 0.794133, 0.782812, 0.771547, 0.760175, 0.748896, 0.737687, 0.727152, 0.717601, 0.707670, 0.697425, 0.686788, 0.675664, 0.664513, 0.652962, 0.640965, 0.628851, 0.616551, 0.604168, 0.591559, 0.579009, 0.566648, 0.554597, 0.542382, 0.529999, 0.517655, 0.505254, 0.492894, 1.000000, 1.000000, 0.999997, 0.999986, 0.999956, 0.999889, 0.999766, 0.999562, 0.999240, 0.997952, 0.996094, 0.994979, 0.992773, 0.990536, 0.987214, 0.983322, 0.978938, 0.973714, 0.967681, 0.960981, 0.953144, 0.945475, 0.936909, 0.927734, 0.918826, 0.909590, 0.900085, 0.890867, 0.881801, 0.872565, 0.863236, 0.854239, 0.845060, 0.835686, 0.826251, 0.816284, 0.806586, 0.796419, 0.785914, 0.775210, 0.764461, 0.753599, 0.742805, 0.731872, 0.721370, 0.711898, 0.702337, 0.692383, 0.682137, 0.671365, 0.660479, 0.649314, 0.637685, 0.625899, 0.613898, 0.601865, 0.589582, 0.577285, 0.565013, 0.553106, 0.541280, 0.529367, 0.517320, 0.505411, 1.000000, 1.000000, 0.999997, 0.999983, 0.999948, 0.999869, 0.999732, 0.999499, 0.999111, 0.997167, 0.995720, 0.994349, 0.991727, 0.989197, 0.985883, 0.981483, 0.976618, 0.970597, 0.964122, 0.956994, 0.948639, 0.940500, 0.931606, 0.922385, 0.913291, 0.904205, 0.894938, 0.885890, 0.877334, 0.868754, 0.860053, 0.851683, 0.843447, 0.834889, 0.826304, 0.817441, 0.808285, 0.799141, 0.789570, 0.779600, 0.769510, 0.759155, 0.748882, 0.738346, 0.727629, 0.717273, 0.707467, 0.698283, 0.688609, 0.678748, 0.668371, 0.657739, 0.646951, 0.635765, 0.624254, 0.612647, 0.600900, 0.589061, 0.576998, 0.564991, 0.553102, 0.541517, 0.530027, 0.518495, 1.000000, 1.000000, 0.999997, 0.999983, 0.999939, 0.999851, 0.999684, 0.999412, 0.998925, 0.996597, 0.995207, 0.993603, 0.990903, 0.987594, 0.983814, 0.979016, 0.973647, 0.967048, 0.960109, 0.952123, 0.943560, 0.934900, 0.925747, 0.916566, 0.907305, 0.898441, 0.889629, 0.881042, 0.872874, 0.865064, 0.857225, 0.849446, 0.842063, 0.834561, 0.826814, 0.818875, 0.810748, 0.802316, 0.793699, 0.784704, 0.775198, 0.765643, 0.755735, 0.745873, 0.735526, 0.725229, 0.714892, 0.704807, 0.695502, 0.686241, 0.676633, 0.666688, 0.656384, 0.645871, 0.635174, 0.624113, 0.612788, 0.601426, 0.589925, 0.578399, 0.566612, 0.554931, 0.543383, 0.532065, 1.000000, 1.000000, 0.999996, 0.999977, 0.999928, 0.999824, 0.999633, 0.999306, 0.998429, 0.996133, 0.994890, 0.992316, 0.989752, 0.986095, 0.981564, 0.976234, 0.970081, 0.962779, 0.955232, 0.946702, 0.937716, 0.928604, 0.919281, 0.910167, 0.901046, 0.892446, 0.884183, 0.876253, 0.868619, 0.861545, 0.854673, 0.847885, 0.841074, 0.834610, 0.827984, 0.820945, 0.813648, 0.806232, 0.798444, 0.790232, 0.781853, 0.772897, 0.763648, 0.754227, 0.744542, 0.734689, 0.724526, 0.714204, 0.704152, 0.694222, 0.685143, 0.675860, 0.666319, 0.656415, 0.646273, 0.635902, 0.625399, 0.614563, 0.603490, 0.592413, 0.581217, 0.570000, 0.558608, 0.547242, 1.000000, 0.999999, 0.999995, 0.999972, 0.999915, 0.999790, 0.999562, 0.999168, 0.997237, 0.995672, 0.994074, 0.991220, 0.987792, 0.983822, 0.978599, 0.972804, 0.965718, 0.958053, 0.949460, 0.940503, 0.931011, 0.921608, 0.912409, 0.903378, 0.894606, 0.886369, 0.878756, 0.871573, 0.864862, 0.858421, 0.852541, 0.846802, 0.841027, 0.835206, 0.829628, 0.823730, 0.817415, 0.810655, 0.803873, 0.796659, 0.788887, 0.780940, 0.772537, 0.763507, 0.754487, 0.745163, 0.735572, 0.725687, 0.715611, 0.705398, 0.695418, 0.685592, 0.676518, 0.667304, 0.657875, 0.648182, 0.638235, 0.628062, 0.617813, 0.607283, 0.596552, 0.585770, 0.575033, 0.564153, 1.000000, 1.000000, 0.999995, 0.999970, 0.999898, 0.999748, 0.999472, 0.998969, 0.996528, 0.995102, 0.992701, 0.989963, 0.985981, 0.981194, 0.975183, 0.968501, 0.960502, 0.952012, 0.942861, 0.933376, 0.923506, 0.914042, 0.904921, 0.896282, 0.887987, 0.880341, 0.873536, 0.867293, 0.861556, 0.856148, 0.850987, 0.846352, 0.841684, 0.836880, 0.832036, 0.827091, 0.821900, 0.816206, 0.810042, 0.803629, 0.796918, 0.789653, 0.781915, 0.774014, 0.765530, 0.756526, 0.747669, 0.738342, 0.728770, 0.718942, 0.708942, 0.698855, 0.688933, 0.679131, 0.669855, 0.660811, 0.651549, 0.642127, 0.632454, 0.622651, 0.612709, 0.602606, 0.592344, 0.581877, 1.000000, 0.999999, 0.999993, 0.999963, 0.999874, 0.999691, 0.999350, 0.998431, 0.995873, 0.994456, 0.991327, 0.987798, 0.983232, 0.977500, 0.970828, 0.962815, 0.954228, 0.944752, 0.935126, 0.925179, 0.915102, 0.905763, 0.897087, 0.888933, 0.881452, 0.874687, 0.868716, 0.863585, 0.858931, 0.854662, 0.850569, 0.846719, 0.843151, 0.839426, 0.835588, 0.831443, 0.827004, 0.822395, 0.817254, 0.811630, 0.805464, 0.799124, 0.792382, 0.785091, 0.777315, 0.769360, 0.760908, 0.751957, 0.743128, 0.733917, 0.724340, 0.714713, 0.704721, 0.694835, 0.684862, 0.675099, 0.665570, 0.656644, 0.647651, 0.638581, 0.629337, 0.619926, 0.610358, 0.600707, 1.000000, 1.000000, 0.999990, 0.999953, 0.999843, 0.999613, 0.999186, 0.997025, 0.995317, 0.992850, 0.989760, 0.985270, 0.979807, 0.973049, 0.965228, 0.956248, 0.946394, 0.936324, 0.926124, 0.915808, 0.905942, 0.897060, 0.889001, 0.881755, 0.875351, 0.869688, 0.864736, 0.860745, 0.857305, 0.854190, 0.851261, 0.848484, 0.845642, 0.842948, 0.840060, 0.836901, 0.833379, 0.829393, 0.825103, 0.820431, 0.815288, 0.809575, 0.803326, 0.796949, 0.790174, 0.782873, 0.775048, 0.767139, 0.758772, 0.750019, 0.741120, 0.732127, 0.722743, 0.713225, 0.703637, 0.693768, 0.684016, 0.674277, 0.664703, 0.655328, 0.646550, 0.637812, 0.629036, 0.620129, 1.000000, 1.000000, 0.999988, 0.999933, 0.999800, 0.999508, 0.998917, 0.996236, 0.994617, 0.991176, 0.987089, 0.981880, 0.974966, 0.967156, 0.957914, 0.947585, 0.936937, 0.926318, 0.915662, 0.905567, 0.896223, 0.888166, 0.881117, 0.875079, 0.869981, 0.865675, 0.862091, 0.859183, 0.856981, 0.855065, 0.853273, 0.851572, 0.849782, 0.847768, 0.845668, 0.843345, 0.840703, 0.837646, 0.834094, 0.830030, 0.825631, 0.820873, 0.815619, 0.809856, 0.803578, 0.797096, 0.790359, 0.783152, 0.775507, 0.767504, 0.759411, 0.750982, 0.742208, 0.733383, 0.724445, 0.715190, 0.705827, 0.696440, 0.686773, 0.677242, 0.667735, 0.658471, 0.649236, 0.640305, 1.000000, 0.999999, 0.999984, 0.999918, 0.999737, 0.999350, 0.997576, 0.995476, 0.992614, 0.988817, 0.983601, 0.976880, 0.968694, 0.959092, 0.948297, 0.936831, 0.925592, 0.914494, 0.904159, 0.894643, 0.886417, 0.879620, 0.874023, 0.869533, 0.865967, 0.863238, 0.861113, 0.859527, 0.858367, 0.857594, 0.856882, 0.856172, 0.855316, 0.854197, 0.852818, 0.851062, 0.849046, 0.846747, 0.844043, 0.840842, 0.837164, 0.832985, 0.828344, 0.823544, 0.818276, 0.812543, 0.806374, 0.799838, 0.793170, 0.786246, 0.778956, 0.771297, 0.763278, 0.755252, 0.746984, 0.738445, 0.729688, 0.721045, 0.712189, 0.703099, 0.694045, 0.684930, 0.675601, 0.666480, 1.000000, 0.999999, 0.999978, 0.999888, 0.999639, 0.999093, 0.996310, 0.994405, 0.990527, 0.985186, 0.978518, 0.969748, 0.959597, 0.948104, 0.935724, 0.923704, 0.912023, 0.901356, 0.891850, 0.883847, 0.877280, 0.872289, 0.868583, 0.865913, 0.864098, 0.862993, 0.862356, 0.862125, 0.862107, 0.862168, 0.862359, 0.862490, 0.862430, 0.862063, 0.861431, 0.860386, 0.858950, 0.857090, 0.854848, 0.852381, 0.849503, 0.846167, 0.842399, 0.838194, 0.833566, 0.828579, 0.823464, 0.817951, 0.812079, 0.805873, 0.799320, 0.792533, 0.785715, 0.778636, 0.771260, 0.763618, 0.755719, 0.747815, 0.739825, 0.731602, 0.723212, 0.714845, 0.706465, 0.697933, 1.000000, 0.999998, 0.999969, 0.999836, 0.999475, 0.997943, 0.995219, 0.991760, 0.986663, 0.979592, 0.970218, 0.959155, 0.946575, 0.933047, 0.920022, 0.907749, 0.896801, 0.887506, 0.880077, 0.874322, 0.870126, 0.867481, 0.865949, 0.865293, 0.865287, 0.865746, 0.866502, 0.867439, 0.868442, 0.869382, 0.870161, 0.870782, 0.871303, 0.871511, 0.871427, 0.870978, 0.870136, 0.868892, 0.867248, 0.865209, 0.862775, 0.859944, 0.857004, 0.853671, 0.849984, 0.845927, 0.841518, 0.836774, 0.831750, 0.826407, 0.821001, 0.815333, 0.809412, 0.803238, 0.796802, 0.790204, 0.783457, 0.776713, 0.769749, 0.762596, 0.755239, 0.747690, 0.740127, 0.732595, 1.000000, 0.999997, 0.999950, 0.999744, 0.999162, 0.996124, 0.992844, 0.987757, 0.980062, 0.969642, 0.957087, 0.942735, 0.927747, 0.913622, 0.900889, 0.890115, 0.881584, 0.875288, 0.870926, 0.868307, 0.867033, 0.866972, 0.867692, 0.868950, 0.870549, 0.872320, 0.874144, 0.875947, 0.877674, 0.879192, 0.880478, 0.881539, 0.882307, 0.882739, 0.882902, 0.882847, 0.882461, 0.881725, 0.880636, 0.879197, 0.877422, 0.875296, 0.872849, 0.870076, 0.866988, 0.863637, 0.860159, 0.856475, 0.852525, 0.848328, 0.843883, 0.839198, 0.834322, 0.829221, 0.823907, 0.818461, 0.812972, 0.807316, 0.801474, 0.795459, 0.789276, 0.783025, 0.776615, 0.770223, 0.999999, 0.999994, 0.999909, 0.999536, 0.997195, 0.994123, 0.988168, 0.979344, 0.967003, 0.951763, 0.934724, 0.917948, 0.902918, 0.890432, 0.880902, 0.874401, 0.870394, 0.868503, 0.868209, 0.869062, 0.870725, 0.873006, 0.875558, 0.878230, 0.880893, 0.883445, 0.885832, 0.888059, 0.890058, 0.891782, 0.893247, 0.894460, 0.895397, 0.896023, 0.896380, 0.896433, 0.896198, 0.895673, 0.894865, 0.893908, 0.892700, 0.891224, 0.889501, 0.887539, 0.885336, 0.882903, 0.880244, 0.877373, 0.874296, 0.871019, 0.867549, 0.863933, 0.860153, 0.856355, 0.852395, 0.848277, 0.844006, 0.839587, 0.835045, 0.830378, 0.825579, 0.820649, 0.815592, 0.810432, 0.999998, 0.999988, 0.999795, 0.998892, 0.994635, 0.987290, 0.975397, 0.958508, 0.938352, 0.917733, 0.899800, 0.885878, 0.876516, 0.871200, 0.869099, 0.869317, 0.871112, 0.873870, 0.877160, 0.880682, 0.884228, 0.887737, 0.891076, 0.894161, 0.896981, 0.899543, 0.901847, 0.903882, 0.905672, 0.907188, 0.908451, 0.909480, 0.910289, 0.910878, 0.911259, 0.911430, 0.911396, 0.911154, 0.910712, 0.910081, 0.909266, 0.908264, 0.907094, 0.905752, 0.904244, 0.902577, 0.900799, 0.898931, 0.896923, 0.894782, 0.892513, 0.890117, 0.887600, 0.884968, 0.882222, 0.879369, 0.876408, 0.873345, 0.870183, 0.866926, 0.863575, 0.860160, 0.856672, 0.853098, 0.999991, 0.999947, 0.999158, 0.992842, 0.980107, 0.957230, 0.928231, 0.901539, 0.882688, 0.872588, 0.869394, 0.870671, 0.874458, 0.879378, 0.884639, 0.889770, 0.894601, 0.898972, 0.902930, 0.906456, 0.909568, 0.912329, 0.914750, 0.916893, 0.918774, 0.920429, 0.921868, 0.923110, 0.924185, 0.925089, 0.925842, 0.926457, 0.926934, 0.927285, 0.927522, 0.927639, 0.927650, 0.927553, 0.927356, 0.927061, 0.926671, 0.926187, 0.925617, 0.924962, 0.924224, 0.923409, 0.922519, 0.921555, 0.920521, 0.919419, 0.918252, 0.917021, 0.915729, 0.914377, 0.912967, 0.911503, 0.909984, 0.908414, 0.906791, 0.905122, 0.903401, 0.901637, 0.899826, 0.897972, 0.987461, 0.940121, 0.871507, 0.898572, 0.916705, 0.926425, 0.931922, 0.935265, 0.937431, 0.938899, 0.939950, 0.940717, 0.941301, 0.941754, 0.942111, 0.942397, 0.942631, 0.942823, 0.942983, 0.943117, 0.943231, 0.943329, 0.943412, 0.943484, 0.943545, 0.943599, 0.943644, 0.943682, 0.943716, 0.943744, 0.943766, 0.943785, 0.943799, 0.943808, 0.943815, 0.943818, 0.943818, 0.943814, 0.943807, 0.943797, 0.943784, 0.943769, 0.943751, 0.943730, 0.943707, 0.943681, 0.943652, 0.943623, 0.943589, 0.943554, 0.943518, 0.943479, 0.943438, 0.943396, 0.943351, 0.943305, 0.943257, 0.943207, 0.943156, 0.943104, 0.943049, 0.942993, 0.942936, 0.942877};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __GPU_LUTS_H__ */
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 0d92d22a173..cc3039b558a 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -55,6 +55,9 @@ struct GPUNodeStack;
struct GPUMaterial;
struct GPUTexture;
struct GPULamp;
+struct GPUProbe;
+struct GPUPBR;
+struct GPUPBRSettings;
struct PreviewImage;
struct World;
@@ -98,6 +101,7 @@ typedef enum GPUBuiltin {
GPU_PARTICLE_ANG_VELOCITY = (1 << 12),
GPU_LOC_TO_VIEW_MATRIX = (1 << 13),
GPU_INVERSE_LOC_TO_VIEW_MATRIX = (1 << 14),
+ GPU_PBR = (1 << 15),
} GPUBuiltin;
typedef enum GPUOpenGLBuiltin {
@@ -106,8 +110,10 @@ typedef enum GPUOpenGLBuiltin {
} GPUOpenGLBuiltin;
typedef enum GPUMatType {
- GPU_MATERIAL_TYPE_MESH = 1,
- GPU_MATERIAL_TYPE_WORLD = 2,
+ GPU_MATERIAL_TYPE_MESH = 1,
+ GPU_MATERIAL_TYPE_MESH_REAL_SH = 2,
+ GPU_MATERIAL_TYPE_WORLD = 3,
+ GPU_MATERIAL_TYPE_LAMP = 5,
} GPUMatType;
@@ -169,6 +175,10 @@ typedef enum GPUDynamicType {
GPU_DYNAMIC_LAMP_COEFFCONST = 13 | GPU_DYNAMIC_GROUP_LAMP,
GPU_DYNAMIC_LAMP_COEFFLIN = 14 | GPU_DYNAMIC_GROUP_LAMP,
GPU_DYNAMIC_LAMP_COEFFQUAD = 15 | GPU_DYNAMIC_GROUP_LAMP,
+ GPU_DYNAMIC_LAMP_DYNMAT = 16 | GPU_DYNAMIC_GROUP_LAMP,
+ GPU_DYNAMIC_LAMP_AREASCALE = 17 | GPU_DYNAMIC_GROUP_LAMP,
+ GPU_DYNAMIC_LAMP_SIZEX = 18 | GPU_DYNAMIC_GROUP_LAMP,
+ GPU_DYNAMIC_LAMP_SIZEY = 19 | GPU_DYNAMIC_GROUP_LAMP,
GPU_DYNAMIC_SAMPLER_2DBUFFER = 1 | GPU_DYNAMIC_GROUP_SAMPLER,
GPU_DYNAMIC_SAMPLER_2DIMAGE = 2 | GPU_DYNAMIC_GROUP_SAMPLER,
@@ -199,7 +209,7 @@ typedef enum GPUDynamicType {
GPUNodeLink *GPU_attribute(CustomDataType type, const char *name);
GPUNodeLink *GPU_uniform(float *num);
GPUNodeLink *GPU_dynamic_uniform(float *num, GPUDynamicType dynamictype, void *data);
-GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser, bool is_data);
+GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser, bool is_data, bool is_envmap);
GPUNodeLink *GPU_cube_map(struct Image *ima, struct ImageUser *iuser, bool is_data);
GPUNodeLink *GPU_image_preview(struct PreviewImage *prv);
GPUNodeLink *GPU_texture(int size, float *pixels);
@@ -211,14 +221,24 @@ void GPU_node_link_set_type(GPUNodeLink *link, GPUType type);
bool GPU_link(GPUMaterial *mat, const char *name, ...);
bool GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNodeStack *out, ...);
+void GPU_material_set_lamp_normal_link(GPUMaterial *material, GPUNodeLink *link);
+GPUNodeLink *GPU_material_get_lamp_normal_link(GPUMaterial *material);
+void GPU_material_set_lamp_position_link(GPUMaterial *material, GPUNodeLink *link);
+GPUNodeLink *GPU_material_get_lamp_position_link(GPUMaterial *material);
+void GPU_material_set_lamp_incoming_link(GPUMaterial *material, GPUNodeLink *link);
+GPUNodeLink *GPU_material_get_lamp_incoming_link(GPUMaterial *material);
void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link);
+void GPU_material_empty_output_link(GPUMaterial *material);
+GPUNodeLink *GPU_material_get_output_link(GPUMaterial *material);
void GPU_material_enable_alpha(GPUMaterial *material);
+GPUNodeLink *GPU_get_world_horicol(void);
GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]);
/* High level functions to create and use GPU materials */
GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo);
-GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma, bool use_opensubdiv);
+GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma, bool use_opensubdiv,
+ bool use_realistic_preview, bool use_planar_probe, bool use_alpha_as_depth, bool use_backface_depth, bool use_ssr, bool use_ssao, int parallax_correc);
GPUMaterial *GPU_material_matcap(struct Scene *scene, struct Material *ma, bool use_opensubdiv);
void GPU_material_free(struct ListBase *gpumaterial);
@@ -231,10 +251,12 @@ void GPU_material_bind(
void GPU_material_bind_uniforms(
GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float obcol[4],
float autobumpscale, GPUParticleInfo *pi);
+void GPU_material_bind_uniforms_pbr(GPUMaterial *material, struct GPUProbe *probe, struct GPUPBR *pbr, struct GPUPBRSettings *pbr_settings);
void GPU_material_unbind(GPUMaterial *material);
bool GPU_material_bound(GPUMaterial *material);
struct Scene *GPU_material_scene(GPUMaterial *material);
-GPUMatType GPU_Material_get_type(GPUMaterial *material);
+GPUMatType GPU_material_get_type(GPUMaterial *material);
+void GPU_material_set_type(GPUMaterial *material, GPUMatType type);
void GPU_material_vertex_attributes(GPUMaterial *material,
struct GPUVertexAttribs *attrib);
@@ -243,6 +265,55 @@ bool GPU_material_do_color_management(GPUMaterial *mat);
bool GPU_material_use_new_shading_nodes(GPUMaterial *mat);
bool GPU_material_use_world_space_shading(GPUMaterial *mat);
+/* BRDF Shading */
+
+typedef enum GPUBrdfType {
+ GPU_BRDF_DIFFUSE = 0,
+
+ GPU_BRDF_GLOSSY_SHARP = 1,
+ GPU_BRDF_GLOSSY_GGX = 2,
+ GPU_BRDF_GLOSSY_BECKMANN = 3,
+ GPU_BRDF_GLOSSY_ASHIKHMIN_SHIRLEY = 4,
+
+ GPU_BRDF_ANISO_SHARP = 5,
+ GPU_BRDF_ANISO_GGX = 6,
+ GPU_BRDF_ANISO_BECKMANN = 7,
+ GPU_BRDF_ANISO_ASHIKHMIN_SHIRLEY = 8,
+
+ GPU_BRDF_REFRACT_SHARP = 9,
+ GPU_BRDF_REFRACT_GGX = 10,
+ GPU_BRDF_REFRACT_BECKMANN = 11,
+
+ GPU_BRDF_GLASS_SHARP = 12,
+ GPU_BRDF_GLASS_GGX = 13,
+ GPU_BRDF_GLASS_BECKMANN = 14,
+
+ GPU_BRDF_VELVET = 15,
+ GPU_BRDF_TRANSLUCENT = 16,
+ GPU_BRDF_TRANSPARENT = 17,
+
+ GPU_BRDF_TOON_DIFFUSE = 18,
+ GPU_BRDF_TOON_GLOSSY = 19,
+
+ GPU_BRDF_AMBIENT_OCCLUSION = 20,
+} GPUBrdfType;
+
+typedef struct GPUBrdfInput {
+ GPUMaterial *mat;
+ GPUBrdfType type;
+
+ GPUNodeLink *normal, *color, *roughness, *ior;
+ GPUNodeLink *sigma, *toon_size, *toon_smooth, *anisotropy;
+ GPUNodeLink *aniso_rotation, *aniso_tangent;
+
+ GPUNodeLink *output;
+} GPUBrdfInput;
+
+void GPU_brdf_input_initialize(GPUBrdfInput *brdf);
+void GPU_shade_BRDF(GPUBrdfInput *brdf);
+void GPU_material_set_brdf_link(GPUMaterial *material, GPUBrdfInput *brdf);
+GPUBrdfInput *GPU_material_get_brdf_link(GPUMaterial *material);
+
/* Exported shading */
typedef struct GPUShadeInput {
@@ -311,7 +382,7 @@ void GPU_free_shader_export(GPUShaderExport *shader);
/* Lamps */
-GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Object *par);
+GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Object *par, bool use_realistic_preview);
void GPU_lamp_free(struct Object *ob);
bool GPU_lamp_has_shadow_buffer(GPULamp *lamp);
@@ -323,6 +394,7 @@ int GPU_lamp_shadow_bind_code(GPULamp *lamp);
float *GPU_lamp_dynpersmat(GPULamp *lamp);
void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]);
+void GPU_lamp_update_size(GPULamp *lamp, float sizex, float sizey);
void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy);
void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2,
float coeff_const, float coeff_lin, float coeff_quad);
@@ -333,6 +405,7 @@ GPUNodeLink *GPU_lamp_get_data(
GPUNodeLink **r_col, GPUNodeLink **r_lv, GPUNodeLink **r_dist, GPUNodeLink **r_shadow, GPUNodeLink **r_energy);
/* World */
+
void GPU_mist_update_enable(short enable);
void GPU_mist_update_values(int type, float start, float dist, float inten, float color[3]);
void GPU_horizon_update_color(float color[3]);
diff --git a/source/blender/gpu/GPU_pbr.h b/source/blender/gpu/GPU_pbr.h
new file mode 100644
index 00000000000..1efca5ca68b
--- /dev/null
+++ b/source/blender/gpu/GPU_pbr.h
@@ -0,0 +1,85 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Clement Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file GPU_pbr.h
+ * \ingroup gpu
+ */
+
+#ifndef __GPU_LUTS_H__
+#define __GPU_LUTS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct GPUTexture;
+struct GPUFrameBuffer;
+
+typedef struct GPUScreenBuffer {
+ int type;
+ int w, h;
+ float clipsta, clipend;
+ float pixelprojmat[4][4];
+ struct GPUTexture *tex;
+ struct GPUTexture *depth;
+ struct GPUFrameBuffer *fb;
+ struct GPUFrameBuffer *downsamplingfb;
+} GPUScreenBuffer;
+
+typedef struct GPUPBR {
+ struct GPUTexture *hammersley;
+ struct GPUTexture *jitter;
+ struct GPUTexture *ltc_mat_ggx;
+ struct GPUTexture *ltc_mag_ggx;
+
+ GPUScreenBuffer *scene;
+ GPUScreenBuffer *backface;
+} GPUPBR;
+
+typedef enum GPUScreenBufferType {
+ GPU_COLOR_BUFFER = 0,
+ GPU_BACKFACE_BUFFER = 1,
+} GPUScreenBufferType;
+
+GPUPBR *GPU_pbr_create(void);
+void GPU_pbr_update(GPUPBR *pbr, GPUPBRSettings *pbr_settings, struct Scene *scene, struct View3D *v3d, struct ARegion *ar);
+void GPU_pbr_free(GPUPBR *pbr);
+
+void GPU_scenebuf_free(GPUScreenBuffer *buf);
+GPUScreenBuffer *GPU_pbr_scene_buffer(GPUPBR *pbr, int width, int height);
+GPUScreenBuffer *GPU_pbr_backface_buffer(GPUPBR *pbr, int width, int height);
+void GPU_scenebuf_bind(GPUScreenBuffer* buf, float winmat[4][4], int winsize[2], float clipsta, float clipend);
+void GPU_scenebuf_unbind(GPUScreenBuffer* buf);
+void GPU_scenebuf_filter_texture(GPUScreenBuffer* buf);
+
+void GPU_pbr_settings_validate(struct GPUPBRSettings *pbr_settings);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __GPU_LUTS_H__ */
diff --git a/source/blender/gpu/GPU_probe.h b/source/blender/gpu/GPU_probe.h
new file mode 100644
index 00000000000..2f35677fec3
--- /dev/null
+++ b/source/blender/gpu/GPU_probe.h
@@ -0,0 +1,118 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Clement Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file GPU_probe.h
+ * \ingroup gpu
+ */
+
+#ifndef __GPU_PROBE_H__
+#define __GPU_PROBE_H__
+
+#include "BLI_sys_types.h" /* for bool */
+#include "DNA_listBase.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Object;
+struct World;
+struct Scene;
+
+typedef struct GPUProbe {
+ struct Scene *scene;
+ struct World *wo;
+ struct Object *ob;
+
+ int type;
+ int size, shres;
+ unsigned int lay;
+
+ bool update;
+
+ float clipsta;
+ float clipend;
+
+ float obmat[4][4];
+ float imat[4][4];
+ float winmat[4][4];
+ float viewmat[4][4];
+ float persmat[4][4];
+
+ float co[3], planevec[3];
+ float correctionmat[4][4];
+ float reflectionmat[4][4];
+ float reflectmat[4][4];
+
+ struct GPUTexture *tex;
+ struct GPUTexture *texreflect;
+ struct GPUTexture *texrefract;
+ struct GPUTexture *depthtex;
+ struct GPUFrameBuffer *fb;
+
+ struct GPUTexture *shtex;
+ struct GPUFrameBuffer *fbsh;
+
+ float *shcoefs;
+} GPUProbe;
+
+/* Keep this enum in sync with DNA_object_types.h */
+typedef enum GPUProbeType {
+ GPU_PROBE_CUBE = 2,
+ GPU_PROBE_PLANAR = 3,
+} GPUProbeType;
+
+GPUProbe *GPU_probe_world(struct Scene *scene, struct World *wo);
+GPUProbe *GPU_probe_object(struct Scene *scene, struct Object *ob);
+void GPU_probe_free(ListBase *gpuprobe);
+
+void GPU_probe_buffer_bind(GPUProbe *probe);
+void GPU_probe_switch_fb_cubeface(GPUProbe *probe, int cubeface, float viewmat[4][4], int *winsize, float winmat[4][4]);
+void GPU_probe_attach_planar_fb(GPUProbe *probe, float camviewmat[4][4], float camwinmat[4][4], float viewmat[4][4], int *winsize, bool refraction);
+void GPU_probe_buffer_unbind(GPUProbe *probe);
+void GPU_probe_rebuild_mipmaps(GPUProbe *probe);
+void GPU_probe_sh_compute(GPUProbe *probe);
+void GPU_probe_sh_shader_bind(GPUProbe *probe);
+void GPU_probe_sh_shader_unbind(void);
+void GPU_probe_auto_update(GPUProbe *probe);
+void GPU_probe_set_update(GPUProbe *probe, bool val);
+bool GPU_probe_get_update(GPUProbe *probe);
+struct Object *GPU_probe_get_object(GPUProbe *probe);
+int GPU_probe_get_size(GPUProbe *probe);
+int GPU_probe_get_type(GPUProbe *probe);
+void GPU_probe_update_clip(GPUProbe *probe, float clipsta, float clipend);
+void GPU_probe_update_layers(GPUProbe *probe, unsigned int lay);
+unsigned int GPU_probe_get_layers(GPUProbe *probe);
+void GPU_probe_update_sh_res(GPUProbe *probe, int res);
+void GPU_probe_update_parallax(GPUProbe *probe, float correctionmat[4][4], float obmat[4][4]);
+void GPU_probe_update_ref_plane(GPUProbe *probe, float obmat[4][4]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__GPU_PROBE_H__*/
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 762329ee077..b40a2dbd1ed 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -47,6 +47,13 @@ enum {
GPU_SHADER_FLAGS_NONE = 0,
GPU_SHADER_FLAGS_SPECIAL_OPENSUBDIV = (1 << 0),
GPU_SHADER_FLAGS_NEW_SHADING = (1 << 1),
+ GPU_SHADER_FLAGS_PROBE_BOX_CORREC = (1 << 2),
+ GPU_SHADER_FLAGS_PROBE_ELIPS_CORREC = (1 << 3),
+ GPU_SHADER_FLAGS_PROBE_PLANAR = (1 << 4),
+ GPU_SHADER_FLAGS_ALPHA_DEPTH = (1 << 5),
+ GPU_SHADER_FLAGS_BACKFACE_DEPTH = (1 << 6),
+ GPU_SHADER_FLAGS_SSR = (1 << 7),
+ GPU_SHADER_FLAGS_SSAO = (1 << 8),
};
GPUShader *GPU_shader_create(
@@ -89,8 +96,15 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_SEP_GAUSSIAN_BLUR = 1,
GPU_SHADER_SMOKE = 2,
GPU_SHADER_SMOKE_FIRE = 3,
+ GPU_SHADER_MINZ_DOWNSAMPLE = 4,
+ GPU_SHADER_MAXZ_DOWNSAMPLE = 5,
+ GPU_SHADER_DISPLAY_SH = 6,
+
+ GPU_SHADER_COMPUTE_SH = 7, /* This reserves the MAX_SH_SAMPLES following values */
} GPUBuiltinShader;
+#define MAX_SH_SAMPLES 10
+
GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader);
GPUShader *GPU_shader_get_builtin_fx_shader(int effects, bool persp);
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 756fe79151b..571bd8938a4 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -65,15 +65,27 @@ GPUTexture *GPU_texture_create_1D(int w, const float *pixels, char err_out[256])
GPUTexture *GPU_texture_create_2D(int w, int h, const float *pixels, GPUHDRType hdr, char err_out[256]);
GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const float *fpixels);
GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256]);
+GPUTexture *GPU_texture_create_depth_buffer(int w, int h, char err_out[256]);
GPUTexture *GPU_texture_create_vsm_shadow_map(int size, char err_out[256]);
-GPUTexture *GPU_texture_create_2D_procedural(int w, int h, const float *pixels, bool repeat, char err_out[256]);
-GPUTexture *GPU_texture_create_1D_procedural(int w, const float *pixels, char err_out[256]);
+GPUTexture *GPU_texture_create_2D_procedural(int w, int h, const float *pixels, bool repeat, bool filtering, int channels, char err_out[256]);
+GPUTexture *GPU_texture_create_1D_procedural(int w, const float *pixels, int channels, char err_out[256]);
+GPUTexture *GPU_texture_create_cube_probe(int size, char err_out[256]);
+GPUTexture *GPU_texture_create_planar_probe(int size, char err_out[256]);
+GPUTexture *GPU_texture_create_sh_filter_target(char err_out[256]);
GPUTexture *GPU_texture_create_2D_multisample(
int w, int h, const float *pixels, GPUHDRType hdr, int samples, char err_out[256]);
GPUTexture *GPU_texture_create_depth_multisample(int w, int h, int samples, char err_out[256]);
GPUTexture *GPU_texture_from_blender(
- struct Image *ima, struct ImageUser *iuser, int textarget, bool is_data, double time, int mipmap);
+ struct Image *ima, struct ImageUser *iuser, int textarget, bool is_data, short do_clip, double time, int mipmap);
GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap);
+
+GPUTexture *GPU_create_ltc_mat_ggx_lut_texture(void);
+GPUTexture *GPU_create_ltc_mag_ggx_lut_texture(void);
+GPUTexture *GPU_create_hammersley_sample_texture(int samples);
+GPUTexture *GPU_create_jitter_texture(void);
+GPUTexture *GPU_create_random_texture(void);
+GPUTexture *GPU_create_spiral_sample_texture(int numsamples);
+
void GPU_invalid_tex_init(void);
void GPU_invalid_tex_bind(int mode);
void GPU_invalid_tex_free(void);
@@ -92,6 +104,7 @@ struct GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex);
int GPU_texture_framebuffer_attachment(GPUTexture *tex);
void GPU_texture_framebuffer_set(GPUTexture *tex, struct GPUFrameBuffer *fb, int attachment);
+
int GPU_texture_target(const GPUTexture *tex);
int GPU_texture_width(const GPUTexture *tex);
int GPU_texture_height(const GPUTexture *tex);
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 211394e7932..aeb656b238b 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -56,6 +56,18 @@
#include <stdarg.h>
extern char datatoc_gpu_shader_material_glsl[];
+extern char datatoc_gpu_shader_material_new_shading_glsl[];
+extern char datatoc_gpu_shader_material_bsdf_anisotropic_glsl[];
+extern char datatoc_gpu_shader_material_bsdf_velvet_glsl[];
+extern char datatoc_gpu_shader_material_bsdf_diffuse_glsl[];
+extern char datatoc_gpu_shader_material_bsdf_glossy_glsl[];
+extern char datatoc_gpu_shader_material_bsdf_refraction_glsl[];
+extern char datatoc_gpu_shader_material_bsdf_glass_glsl[];
+extern char datatoc_gpu_shader_material_bsdf_translucent_glsl[];
+extern char datatoc_gpu_shader_material_bsdf_transparent_glsl[];
+extern char datatoc_gpu_shader_material_bsdf_toon_glsl[];
+extern char datatoc_gpu_shader_material_bsdf_ambient_occlusion_glsl[];
+extern char datatoc_gpu_shader_material_utils_glsl[];
extern char datatoc_gpu_shader_vertex_glsl[];
extern char datatoc_gpu_shader_vertex_world_glsl[];
extern char datatoc_gpu_shader_geometry_glsl[];
@@ -410,6 +422,8 @@ const char *GPU_builtin_name(GPUBuiltin builtin)
return "unfparticlevel";
else if (builtin == GPU_PARTICLE_ANG_VELOCITY)
return "unfparticleangvel";
+ else if (builtin == GPU_PBR)
+ return "unfpbr"; /* Placeholder : does not actualy contains data */
else
return "";
}
@@ -430,13 +444,15 @@ static void codegen_set_texid(GHash *bindhash, GPUInput *input, int *texid, void
}
}
-static void codegen_set_unique_ids(ListBase *nodes)
+static void codegen_set_unique_ids(ListBase *nodes, bool reserve_texid)
{
GHash *bindhash, *definehash;
GPUNode *node;
GPUInput *input;
GPUOutput *output;
- int id = 1, texid = 0;
+ /* XXX tex slot (texid) 0-10 are pbr textures */
+ /* TODO : these should reserved on demand not in bulk */
+ int id = 1, texid = (reserve_texid) ? 10 : 0;
bindhash = BLI_ghash_ptr_new("codegen_set_unique_ids1 gh");
definehash = BLI_ghash_ptr_new("codegen_set_unique_ids2 gh");
@@ -503,7 +519,7 @@ static int codegen_print_uniforms_functions(DynStr *ds, ListBase *nodes)
GPUNode *node;
GPUInput *input;
const char *name;
- int builtins = 0;
+ int builtins = 0, pbrbuiltins = 0;
/* print uniforms */
for (node = nodes->first; node; node = node->next) {
@@ -523,7 +539,11 @@ static int codegen_print_uniforms_functions(DynStr *ds, ListBase *nodes)
builtins |= input->builtin;
name = GPU_builtin_name(input->builtin);
- if (gpu_str_prefix(name, "unf")) {
+ if (input->builtin == GPU_VIEW_POSITION) {
+ /* XXX always here */
+ continue;
+ }
+ else if (gpu_str_prefix(name, "unf")) {
BLI_dynstr_appendf(ds, "uniform %s %s;\n",
GPU_DATATYPE_STR[input->type], name);
}
@@ -653,12 +673,19 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
BLI_dynstr_append(ds, ");\n");
}
+ BLI_dynstr_appendf(ds, "\n#ifndef ALPHA_AS_DEPTH\n");
BLI_dynstr_append(ds, "\n\tgl_FragColor = ");
codegen_convert_datatype(ds, finaloutput->type, GPU_VEC4, "tmp", finaloutput->id);
BLI_dynstr_append(ds, ";\n");
+ BLI_dynstr_appendf(ds, "\n#else\n");
+ /* Encode Depth in Alpha if we are capturing for planar reflection / ssr */
+ BLI_dynstr_append(ds, "\n\tgl_FragColor = vec4(");
+ codegen_convert_datatype(ds, finaloutput->type, GPU_VEC3, "tmp", finaloutput->id);
+ BLI_dynstr_append(ds, ", varposition.z);\n");
+ BLI_dynstr_appendf(ds, "\n#endif\n");
}
-static char *code_generate_fragment(ListBase *nodes, GPUOutput *output)
+static char *code_generate_fragment(ListBase *nodes, const GPUMatType type, GPUOutput *output)
{
DynStr *ds = BLI_dynstr_new();
char *code;
@@ -669,12 +696,11 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output)
GPUInput *input;
#endif
-
#if 0
BLI_dynstr_append(ds, FUNCTION_PROTOTYPES);
#endif
- codegen_set_unique_ids(nodes);
+ codegen_set_unique_ids(nodes, (type == GPU_MATERIAL_TYPE_MESH_REAL_SH));
builtins = codegen_print_uniforms_functions(ds, nodes);
#if 0
@@ -682,6 +708,10 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output)
BLI_dynstr_appendf(ds, "/* %s */\n", name);
#endif
+ /* XXX */
+ BLI_dynstr_appendf(ds, "%s vec3 varposition;\n",
+ GLEW_VERSION_3_0 ? "in" : "varying");
+
BLI_dynstr_append(ds, "void main()\n{\n");
if (builtins & GPU_VIEW_NORMAL)
@@ -738,7 +768,7 @@ static char *code_generate_vertex(ListBase *nodes, const GPUMatType type)
GPUInput *input;
char *code;
char *vertcode = NULL;
-
+
for (node = nodes->first; node; node = node->next) {
for (input = node->inputs.first; input; input = input->next) {
if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
@@ -768,6 +798,7 @@ static char *code_generate_vertex(ListBase *nodes, const GPUMatType type)
switch (type) {
case GPU_MATERIAL_TYPE_MESH:
+ case GPU_MATERIAL_TYPE_MESH_REAL_SH:
vertcode = datatoc_gpu_shader_vertex_glsl;
break;
case GPU_MATERIAL_TYPE_WORLD:
@@ -910,8 +941,21 @@ void GPU_code_generate_glsl_lib(void)
ds = BLI_dynstr_new();
+ /* Orders matters : some functions must be initialized for the later files
+ * This is in order to avoid unecessary early declarations */
BLI_dynstr_append(ds, datatoc_gpu_shader_material_glsl);
-
+ BLI_dynstr_append(ds, datatoc_gpu_shader_material_utils_glsl);
+ BLI_dynstr_append(ds, datatoc_gpu_shader_material_bsdf_glossy_glsl);
+ BLI_dynstr_append(ds, datatoc_gpu_shader_material_bsdf_diffuse_glsl);
+ BLI_dynstr_append(ds, datatoc_gpu_shader_material_bsdf_anisotropic_glsl);
+ BLI_dynstr_append(ds, datatoc_gpu_shader_material_bsdf_velvet_glsl);
+ BLI_dynstr_append(ds, datatoc_gpu_shader_material_bsdf_transparent_glsl);
+ BLI_dynstr_append(ds, datatoc_gpu_shader_material_bsdf_refraction_glsl);
+ BLI_dynstr_append(ds, datatoc_gpu_shader_material_bsdf_glass_glsl);
+ BLI_dynstr_append(ds, datatoc_gpu_shader_material_bsdf_translucent_glsl);
+ BLI_dynstr_append(ds, datatoc_gpu_shader_material_bsdf_toon_glsl);
+ BLI_dynstr_append(ds, datatoc_gpu_shader_material_bsdf_ambient_occlusion_glsl);
+ BLI_dynstr_append(ds, datatoc_gpu_shader_material_new_shading_glsl);
glsl_material_library = BLI_dynstr_get_cstring(ds);
@@ -1026,7 +1070,7 @@ void GPU_pass_bind(GPUPass *pass, double time, int mipmap)
/* create the textures */
for (input = inputs->first; input; input = input->next) {
if (input->ima)
- input->tex = GPU_texture_from_blender(input->ima, input->iuser, input->textarget, input->image_isdata, time, mipmap);
+ input->tex = GPU_texture_from_blender(input->ima, input->iuser, input->textarget, input->image_isdata, input->image_isenvmap, time, mipmap);
else if (input->prv)
input->tex = GPU_texture_from_preview(input->prv, mipmap);
}
@@ -1212,6 +1256,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const GPUType
input->ima = link->ptr1;
input->iuser = link->ptr2;
input->image_isdata = link->image_isdata;
+ input->image_isenvmap = link->image_isenvmap;
input->textarget = GL_TEXTURE_2D;
input->textype = GPU_TEX2D;
}
@@ -1366,7 +1411,7 @@ static void gpu_nodes_get_vertex_attributes(ListBase *nodes, GPUVertexAttribs *a
}
}
-static void gpu_nodes_get_builtin_flag(ListBase *nodes, int *builtin)
+static void gpu_nodes_get_builtin_flag(ListBase *nodes, int *builtin, int *pbrbuiltin)
{
GPUNode *node;
GPUInput *input;
@@ -1414,7 +1459,7 @@ GPUNodeLink *GPU_dynamic_uniform(float *num, GPUDynamicType dynamictype, void *d
return link;
}
-GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, bool is_data)
+GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, bool is_data, bool is_envmap)
{
GPUNodeLink *link = GPU_node_link_create();
@@ -1422,6 +1467,7 @@ GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, bool is_data)
link->ptr1 = ima;
link->ptr2 = iuser;
link->image_isdata = is_data;
+ link->image_isenvmap = is_envmap;
return link;
}
@@ -1647,10 +1693,17 @@ static void gpu_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
GPUPass *GPU_generate_pass(
ListBase *nodes, GPUNodeLink *outlink,
- GPUVertexAttribs *attribs, int *builtins,
+ GPUVertexAttribs *attribs, int *builtins, int *pbrbuiltins,
const GPUMatType type, const char *UNUSED(name),
const bool use_opensubdiv,
- const bool use_new_shading)
+ const bool use_new_shading,
+ const bool use_planar_probe,
+ const bool use_box_correction,
+ const bool use_ellipsoid_correction,
+ const bool use_alpha_as_depth,
+ const bool use_backface_depth,
+ const bool use_ssr,
+ const bool use_ssao)
{
GPUShader *shader;
GPUPass *pass;
@@ -1667,10 +1720,10 @@ GPUPass *GPU_generate_pass(
gpu_nodes_prune(nodes, outlink);
gpu_nodes_get_vertex_attributes(nodes, attribs);
- gpu_nodes_get_builtin_flag(nodes, builtins);
+ gpu_nodes_get_builtin_flag(nodes, builtins, pbrbuiltins);
/* generate code and compile with opengl */
- fragmentcode = code_generate_fragment(nodes, outlink->output);
+ fragmentcode = code_generate_fragment(nodes, type, outlink->output);
vertexcode = code_generate_vertex(nodes, type);
geometrycode = code_generate_geometry(nodes, use_opensubdiv);
@@ -1681,6 +1734,28 @@ GPUPass *GPU_generate_pass(
if (use_new_shading) {
flags |= GPU_SHADER_FLAGS_NEW_SHADING;
}
+ if (use_box_correction) {
+ flags |= GPU_SHADER_FLAGS_PROBE_BOX_CORREC;
+ }
+ if (use_ellipsoid_correction) {
+ flags |= GPU_SHADER_FLAGS_PROBE_ELIPS_CORREC;
+ }
+ if (use_planar_probe) {
+ flags |= GPU_SHADER_FLAGS_PROBE_PLANAR;
+ }
+ if (use_alpha_as_depth) {
+ flags |= GPU_SHADER_FLAGS_ALPHA_DEPTH;
+ }
+ if (use_backface_depth) {
+ flags |= GPU_SHADER_FLAGS_BACKFACE_DEPTH;
+ }
+ if (use_ssr) {
+ flags |= GPU_SHADER_FLAGS_SSR;
+ }
+ if (use_ssao) {
+ flags |= GPU_SHADER_FLAGS_SSAO;
+ }
+
shader = GPU_shader_create_ex(vertexcode,
fragmentcode,
geometrycode,
@@ -1699,6 +1774,7 @@ GPUPass *GPU_generate_pass(
MEM_freeN(vertexcode);
memset(attribs, 0, sizeof(*attribs));
memset(builtins, 0, sizeof(*builtins));
+ memset(pbrbuiltins, 0, sizeof(*pbrbuiltins));
gpu_nodes_free(nodes);
return NULL;
}
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index 7af17f9122d..999de1b6218 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -87,6 +87,7 @@ struct GPUNodeLink {
GPUNodeLinkImage image;
bool image_isdata;
+ bool image_isenvmap;
bool texture;
int texturesize;
@@ -138,6 +139,7 @@ typedef struct GPUInput {
struct ImageUser *iuser; /* image user */
struct PreviewImage *prv; /* preview images & icons */
bool image_isdata; /* image does not contain color data */
+ bool image_isenvmap; /* image is envmap and should be clamped */
float *dynamicvec; /* vector data in case it is dynamic */
GPUDynamicType dynamictype; /* origin of the dynamic uniform */
void *dynamicdata; /* data source of the dynamic uniform */
@@ -171,10 +173,17 @@ struct GPUPass {
typedef struct GPUPass GPUPass;
GPUPass *GPU_generate_pass(ListBase *nodes, struct GPUNodeLink *outlink,
- struct GPUVertexAttribs *attribs, int *builtin,
+ struct GPUVertexAttribs *attribs, int *builtins, int *pbrbuiltins,
const GPUMatType type, const char *name,
const bool use_opensubdiv,
- const bool use_new_shading);
+ const bool use_new_shading,
+ const bool use_planar_probe,
+ const bool use_box_correction,
+ const bool use_ellipsoid_correction,
+ const bool use_alpha_as_depth,
+ const bool use_backface_depth,
+ const bool use_ssr,
+ const bool use_ssao);
struct GPUShader *GPU_pass_shader(GPUPass *pass);
diff --git a/source/blender/gpu/intern/gpu_compositing.c b/source/blender/gpu/intern/gpu_compositing.c
index 964c2b5051e..d1c54ea9865 100644
--- a/source/blender/gpu/intern/gpu_compositing.c
+++ b/source/blender/gpu/intern/gpu_compositing.c
@@ -35,12 +35,15 @@
#include "BLI_rect.h"
#include "BLI_math.h"
-#include "BLI_rand.h"
+#include "BKE_colortools.h"
+#include "BKE_scene.h"
#include "DNA_vec_types.h"
#include "DNA_scene_types.h"
#include "DNA_gpu_types.h"
+#include "IMB_colormanagement.h"
+
#include "GPU_compositing.h"
#include "GPU_extensions.h"
#include "GPU_framebuffer.h"
@@ -181,6 +184,8 @@ struct GPUFX {
int ssao_sample_count_cache;
GPUTexture *ssao_spiral_samples_tex;
+ /* 3D Lut for color correction */
+ GPUTexture *colorc_3dLut;
GPUFXSettings settings;
@@ -196,59 +201,64 @@ struct GPUFX {
unsigned int vbuffer;
};
-#if 0
-/* concentric mapping, see "A Low Distortion Map Between Disk and Square" and
- * http://psgraphics.blogspot.nl/2011/01/improved-code-for-concentric-map.html */
-static GPUTexture * create_concentric_sample_texture(int side)
+static GPUTexture *create_3DLUT_from_display_settings(GPUFX *fx, Scene *scene)
{
+ const int LUT3D_EDGE_SIZE = 16;
+ int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE;
+ int offset;
+ int x,y,z;
GPUTexture *tex;
- float midpoint = 0.5f * (side - 1);
- float *texels = (float *)MEM_mallocN(sizeof(float) * 2 * side * side, "concentric_tex");
- int i, j;
-
- for (i = 0; i < side; i++) {
- for (j = 0; j < side; j++) {
- int index = (i * side + j) * 2;
- float a = 1.0f - i / midpoint;
- float b = 1.0f - j / midpoint;
- float phi, r;
- if (a * a > b * b) {
- r = a;
- phi = (M_PI_4) * (b / a);
- }
- else {
- r = b;
- phi = M_PI_2 - (M_PI_4) * (a / b);
+ ColorManagedViewSettings *view_settings = &scene->view_settings;
+ ColorManagedDisplaySettings *display_settings = &scene->display_settings;
+ float tmp_pix[3];
+ char *display_name = "sRGB";
+
+ float *lut3d = MEM_callocN(sizeof(float) * num_3d_entries, "Post-Process GPU 3D LUT");
+ ColorManagedViewSettings *view_settings_mod = MEM_callocN(sizeof(ColorManagedViewSettings), "LUT Modified View Settings");
+ ColorManagedDisplaySettings *display_settings_mod = MEM_callocN(sizeof(ColorManagedDisplaySettings), "LUT Modified Display Settings");
+
+ BKE_color_managed_view_settings_copy(view_settings_mod, view_settings);
+ BKE_color_managed_display_settings_copy(display_settings_mod, display_settings);
+
+ /* Setting this to not affect the LUT
+ * Exposure control and gamma is done in the shader itself for better resolution
+ * Except if we use curve mapping */
+ if ((view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) == 0) {
+ view_settings_mod->exposure = 0.0;
+ view_settings_mod->gamma = 1.0;
+ }
+
+ /* XXX slow, low res ... need to find another way */
+ for (z = 0; z < LUT3D_EDGE_SIZE; z++)
+ {
+ for (y = 0; y < LUT3D_EDGE_SIZE; y++)
+ {
+ for (x = 0; x < LUT3D_EDGE_SIZE; x++)
+ {
+ offset = (x + y * LUT3D_EDGE_SIZE + z * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE) * 3;
+
+ /* Apply Linear color through Color Management to get the LUT+ColorCurve+DisplaySpace */
+ lut3d[offset+0] = (float)x / ((float)LUT3D_EDGE_SIZE - 1.0f); //R
+ lut3d[offset+1] = (float)y / ((float)LUT3D_EDGE_SIZE - 1.0f); //G
+ lut3d[offset+2] = (float)z / ((float)LUT3D_EDGE_SIZE - 1.0f); //B
+
+ IMB_colormanagement_pixel_to_display_space_v3(tmp_pix, &lut3d[offset], view_settings_mod, display_settings_mod);
+
+ lut3d[offset+0] = tmp_pix[0];
+ lut3d[offset+1] = tmp_pix[1];
+ lut3d[offset+2] = tmp_pix[2];
+
}
- texels[index] = r * cos(phi);
- texels[index + 1] = r * sin(phi);
}
}
- tex = GPU_texture_create_1D_procedural(side * side, texels, NULL);
- MEM_freeN(texels);
- return tex;
-}
-#endif
+ tex = GPU_texture_create_3D(LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, 3, lut3d);
-static GPUTexture *create_spiral_sample_texture(int numsaples)
-{
- GPUTexture *tex;
- float (*texels)[2] = MEM_mallocN(sizeof(float[2]) * numsaples, "concentric_tex");
- const float numsaples_inv = 1.0f / numsaples;
- int i;
- /* arbitrary number to ensure we don't get conciding samples every circle */
- const float spirals = 7.357;
-
- for (i = 0; i < numsaples; i++) {
- float r = (i + 0.5f) * numsaples_inv;
- float phi = r * spirals * (float)(2.0 * M_PI);
- texels[i][0] = r * cosf(phi);
- texels[i][1] = r * sinf(phi);
- }
+ MEM_freeN(lut3d);
+ BKE_color_managed_view_settings_free(view_settings_mod);
+ MEM_freeN(view_settings_mod);
+ MEM_freeN(display_settings_mod);
- tex = GPU_texture_create_1D_procedural(numsaples, (float *)texels, NULL);
- MEM_freeN(texels);
return tex;
}
@@ -346,6 +356,11 @@ static void cleanup_fx_gl_data(GPUFX *fx, bool do_fbo)
GPU_framebuffer_free(fx->gbuffer);
fx->gbuffer = NULL;
}
+
+ if (fx->colorc_3dLut) {
+ GPU_texture_free(fx->colorc_3dLut);
+ fx->colorc_3dLut = NULL;
+ }
}
/* destroy a text compositor */
@@ -356,29 +371,15 @@ void GPU_fx_compositor_destroy(GPUFX *fx)
MEM_freeN(fx);
}
-static GPUTexture * create_jitter_texture(void)
-{
- float jitter[64 * 64][2];
- int i;
-
- for (i = 0; i < 64 * 64; i++) {
- jitter[i][0] = 2.0f * BLI_frand() - 1.0f;
- jitter[i][1] = 2.0f * BLI_frand() - 1.0f;
- normalize_v2(jitter[i]);
- }
-
- return GPU_texture_create_2D_procedural(64, 64, &jitter[0][0], true, NULL);
-}
-
-
bool GPU_fx_compositor_initialize_passes(
GPUFX *fx, const rcti *rect, const rcti *scissor_rect,
- const GPUFXSettings *fx_settings)
+ const GPUFXSettings *fx_settings, struct Scene *scene)
{
int w = BLI_rcti_size_x(rect), h = BLI_rcti_size_y(rect);
char err_out[256];
int num_passes = 0;
- char fx_flag;
+ char fx_flag, fx_flag2;
+ bool no_fx;
fx->effects = 0;
@@ -391,6 +392,7 @@ bool GPU_fx_compositor_initialize_passes(
}
fx_flag = fx_settings->fx_flag;
+ fx_flag2 = fx_settings->fx_flag2;
/* disable effects if no options passed for them */
if (!fx_settings->dof) {
@@ -400,7 +402,10 @@ bool GPU_fx_compositor_initialize_passes(
fx_flag &= ~GPU_FX_FLAG_SSAO;
}
- if (!fx_flag) {
+ /* we must test every supported effect in case a non supported fx from the future arrives */
+ no_fx = !(fx_flag || (fx_flag2 & GPU_FX_FLAG_COLORMANAGEMENT));
+
+ if (no_fx) {
cleanup_fx_gl_data(fx, true);
return false;
}
@@ -420,6 +425,9 @@ bool GPU_fx_compositor_initialize_passes(
if (fx_flag & GPU_FX_FLAG_SSAO)
num_passes++;
+ if (fx_flag2 & GPU_FX_FLAG_COLORMANAGEMENT)
+ num_passes++;
+
if (!fx->gbuffer) {
fx->gbuffer = GPU_framebuffer_create();
@@ -430,7 +438,7 @@ bool GPU_fx_compositor_initialize_passes(
/* try creating the jitter texture */
if (!fx->jitter_buffer)
- fx->jitter_buffer = create_jitter_texture();
+ fx->jitter_buffer = GPU_create_jitter_texture();
/* check if color buffers need recreation */
if (!fx->color_buffer || !fx->depth_buffer || w != fx->gbuffer_dim[0] || h != fx->gbuffer_dim[1]) {
@@ -460,7 +468,7 @@ bool GPU_fx_compositor_initialize_passes(
GPU_texture_free(fx->ssao_spiral_samples_tex);
}
- fx->ssao_spiral_samples_tex = create_spiral_sample_texture(fx_settings->ssao->samples);
+ fx->ssao_spiral_samples_tex = GPU_create_spiral_sample_texture(fx_settings->ssao->samples);
}
}
else {
@@ -470,6 +478,25 @@ bool GPU_fx_compositor_initialize_passes(
}
}
+ if (fx_flag2 & GPU_FX_FLAG_COLORMANAGEMENT) {
+ ColorManagedViewSettings *view_settings = &scene->view_settings;;
+ ColorManagedDisplaySettings *display_settings = &scene->display_settings;;
+ if (!fx->colorc_3dLut || view_settings->lut_is_outdated || display_settings->lut_is_outdated) {
+ if (fx->colorc_3dLut) {
+ GPU_texture_free(fx->colorc_3dLut);
+ }
+ fx->colorc_3dLut = create_3DLUT_from_display_settings(fx, scene);
+ view_settings->lut_is_outdated = 0;
+ display_settings->lut_is_outdated = 0;
+ }
+ }
+ else {
+ if (fx->colorc_3dLut) {
+ GPU_texture_free(fx->colorc_3dLut);
+ fx->colorc_3dLut = NULL;
+ }
+ }
+
/* create textures for dof effect */
if (fx_flag & GPU_FX_FLAG_DOF) {
bool dof_high_quality = (fx_settings->dof->high_quality != 0) &&
@@ -502,7 +529,7 @@ bool GPU_fx_compositor_initialize_passes(
return false;
}
if (!(fx->dof_nearfar_coc = GPU_texture_create_2D_procedural(
- fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, false, err_out)))
+ fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, false, false, 2, err_out)))
{
printf("%.256s\n", err_out);
cleanup_fx_gl_data(fx, true);
@@ -610,7 +637,7 @@ bool GPU_fx_compositor_initialize_passes(
fx->restore_stencil = false;
}
- fx->effects = fx_flag;
+ fx->effects = fx_flag | fx_flag2;
if (fx_settings)
fx->settings = *fx_settings;
@@ -1061,6 +1088,7 @@ bool GPU_fx_do_composite_pass(
}
}
+ SWAP(GPUTexture *, target, src);
numslots = 0;
}
}
@@ -1287,6 +1315,62 @@ bool GPU_fx_do_composite_pass(
}
}
+ if (fx->effects & GPU_FX_FLAG_COLORMANAGEMENT) {
+ GPUShader *colormanage_shader;
+ colormanage_shader = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_COLORMANAGE, is_persp);
+ if (colormanage_shader) {
+ int color_uniform, exposure_uniform, gamma_uniform, lut3d_uniform, displayspace_uniform, offscreen_uniform;
+ ColorManagedViewSettings *view_settings = &scene->view_settings;
+ ColorManagedDisplaySettings *display_settings = &scene->display_settings;
+ float one = 1.0f, zero = 0.0f;
+ float displayspace = (BKE_scene_check_color_management_enabled(scene)) ? 1.0f : 0.0f;
+ bool use_curve_mapping = (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) != 0;
+
+ color_uniform = GPU_shader_get_uniform(colormanage_shader, "colorbuffer");
+ lut3d_uniform = GPU_shader_get_uniform(colormanage_shader, "lut3d_texture");
+ exposure_uniform = GPU_shader_get_uniform(colormanage_shader, "exposure");
+ gamma_uniform = GPU_shader_get_uniform(colormanage_shader, "gamma");
+ displayspace_uniform = GPU_shader_get_uniform(colormanage_shader, "displayspace_is_srgb");
+ offscreen_uniform = GPU_shader_get_uniform(colormanage_shader, "is_offscreen");
+
+ GPU_shader_bind(colormanage_shader);
+
+ GPU_shader_uniform_vector(colormanage_shader, exposure_uniform, 1, 1, (use_curve_mapping) ? &zero : &view_settings->exposure);
+ GPU_shader_uniform_vector(colormanage_shader, gamma_uniform, 1, 1, (use_curve_mapping) ? &one : &view_settings->gamma);
+ GPU_shader_uniform_vector(colormanage_shader, displayspace_uniform, 1, 1, &displayspace);
+ GPU_shader_uniform_vector(colormanage_shader, offscreen_uniform, 1, 1, (ofs) ? &one : &zero);
+
+ GPU_texture_bind(src, numslots++);
+ GPU_shader_uniform_texture(colormanage_shader, color_uniform, src);
+
+ GPU_texture_bind(fx->colorc_3dLut, numslots++);
+ GPU_shader_uniform_texture(colormanage_shader, lut3d_uniform, fx->colorc_3dLut);
+
+ /* draw */
+ gpu_fx_bind_render_target(&passes_left, fx, ofs, target);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ /* disable bindings */
+ GPU_texture_unbind(src);
+
+ /* may not be attached, in that case this just returns */
+ if (target) {
+ GPU_framebuffer_texture_detach(target);
+ if (ofs) {
+ GPU_offscreen_bind(ofs, false);
+ }
+ else {
+ GPU_framebuffer_restore();
+ }
+ }
+
+ /* swap here, after src/target have been unbound */
+ SWAP(GPUTexture *, target, src);
+ numslots = 0;
+ }
+ }
+
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -1311,6 +1395,7 @@ void GPU_fx_compositor_init_ssao_settings(GPUSSAOSettings *fx_ssao)
fx_ssao->distance_max = 0.2f;
fx_ssao->attenuation = 1.0f;
fx_ssao->samples = 20;
+ fx_ssao->steps = 2;
}
void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect effect)
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 7936811ab4d..5d4aef59e1d 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -82,6 +82,8 @@
#include "GPU_material.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
+#include "GPU_probe.h"
+#include "GPU_pbr.h"
#include "PIL_time.h"
@@ -285,11 +287,15 @@ void GPU_set_gpu_mipmapping(int gpu_mipmap)
}
}
-static void gpu_generate_mipmap(GLenum target)
+void GPU_generate_mipmap(GLenum target)
{
const bool is_ati = GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY);
int target_enabled = 0;
+ if (GLEW_ARB_seamless_cube_map) {
+ glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
+ }
+
/* work around bug in ATI driver, need to have GL_TEXTURE_2D enabled
* http://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation */
if (is_ati) {
@@ -534,7 +540,8 @@ static void gpu_verify_high_bit_srgb_buffer_slice(float *srgb_frect,
ibuf->x, ibuf->x);
IMB_buffer_float_unpremultiply(current_srgb_frect, ibuf->x, height);
/* Clamp buffer colors to 1.0 to avoid artifacts due to glu for hdr images. */
- IMB_buffer_float_clamp(current_srgb_frect, ibuf->x, height);
+ if (!GTS.gpu_mipmap && ibuf->miptot == 1)
+ IMB_buffer_float_clamp(current_srgb_frect, ibuf->x, height);
}
static void verify_thread_do(void *data_v,
@@ -566,7 +573,7 @@ static void gpu_verify_high_bit_srgb_buffer(float *srgb_frect,
int GPU_verify_image(
Image *ima, ImageUser *iuser,
- int textarget, int tftile, bool compare, bool mipmap, bool is_data)
+ int textarget, int tftile, bool compare, bool mipmap, bool is_data, bool is_envmap)
{
unsigned int *bind = NULL;
int tpx = 0, tpy = 0;
@@ -757,7 +764,7 @@ int GPU_verify_image(
GPU_create_gl_tex_compressed(bind, rect, rectw, recth, textarget, mipmap, ima, ibuf);
else
#endif
- GPU_create_gl_tex(bind, rect, frect, rectw, recth, textarget, mipmap, use_high_bit_depth, ima);
+ GPU_create_gl_tex(bind, rect, frect, rectw, recth, textarget, mipmap, use_high_bit_depth, ima, is_envmap);
/* mark as non-color data texture */
if (*bind) {
@@ -850,7 +857,7 @@ static void gpu_del_cube_map(void **cube_map)
/* Image *ima can be NULL */
void GPU_create_gl_tex(
unsigned int *bind, unsigned int *rect, float *frect, int rectw, int recth,
- int textarget, bool mipmap, bool use_high_bit_depth, Image *ima)
+ int textarget, bool mipmap, bool use_high_bit_depth, Image *ima, bool is_envmap)
{
ImBuf *ibuf = NULL;
@@ -858,7 +865,7 @@ void GPU_create_gl_tex(
int tpy = recth;
/* scale if not a power of two. this is not strictly necessary for newer
- * GPUs (OpenGL version >= 2.0) since they support non-power-of-two-textures
+ * GPUs (OpenGL version >= 2.0) since they support non-power-of-two-textures
* Then don't bother scaling for hardware that supports NPOT textures! */
if (textarget == GL_TEXTURE_2D &&
((!GPU_full_non_power_of_two_support() && !is_power_of_2_resolution(rectw, recth)) ||
@@ -899,7 +906,7 @@ void GPU_create_gl_tex(
if (GPU_get_mipmap() && mipmap) {
if (GTS.gpu_mipmap) {
- gpu_generate_mipmap(GL_TEXTURE_2D);
+ GPU_generate_mipmap(GL_TEXTURE_2D);
}
else {
int i;
@@ -950,7 +957,7 @@ void GPU_create_gl_tex(
if (GPU_get_mipmap() && mipmap) {
if (GTS.gpu_mipmap) {
- gpu_generate_mipmap(GL_TEXTURE_CUBE_MAP);
+ GPU_generate_mipmap(GL_TEXTURE_CUBE_MAP);
}
else {
if (!ibuf) {
@@ -999,6 +1006,11 @@ void GPU_create_gl_tex(
}
}
+ if (is_envmap) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ }
+
if (GLEW_EXT_texture_filter_anisotropic)
glTexParameterf(textarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic());
@@ -1079,14 +1091,14 @@ void GPU_create_gl_tex_compressed(
#ifndef WITH_DDS
(void)ibuf;
/* Fall back to uncompressed if DDS isn't enabled */
- GPU_create_gl_tex(bind, pix, NULL, x, y, textarget, mipmap, 0, ima);
+ GPU_create_gl_tex(bind, pix, NULL, x, y, textarget, mipmap, 0, ima, false);
#else
glGenTextures(1, (GLuint *)bind);
glBindTexture(textarget, *bind);
if (textarget == GL_TEXTURE_2D && GPU_upload_dxt_texture(ibuf) == 0) {
glDeleteTextures(1, (GLuint *)bind);
- GPU_create_gl_tex(bind, pix, NULL, x, y, textarget, mipmap, 0, ima);
+ GPU_create_gl_tex(bind, pix, NULL, x, y, textarget, mipmap, 0, ima, false);
}
#endif
}
@@ -1118,7 +1130,7 @@ int GPU_set_tpage(MTexPoly *mtexpoly, int mipmap, int alphablend)
gpu_verify_alpha_blend(alphablend);
gpu_verify_reflection(ima);
- if (GPU_verify_image(ima, NULL, GL_TEXTURE_2D, mtexpoly->tile, 1, mipmap, false)) {
+ if (GPU_verify_image(ima, NULL, GL_TEXTURE_2D, mtexpoly->tile, 1, mipmap, false, false)) {
GTS.curtile = GTS.tile;
GTS.curima = GTS.ima;
GTS.curtilemode = GTS.tilemode;
@@ -1260,7 +1272,7 @@ static bool GPU_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int x,
}
if (GPU_get_mipmap()) {
- gpu_generate_mipmap(GL_TEXTURE_2D);
+ GPU_generate_mipmap(GL_TEXTURE_2D);
}
else {
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
@@ -1310,7 +1322,7 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i
/* we have already accounted for the case where GTS.gpu_mipmap is false
* so we will be using GPU mipmap generation here */
if (GPU_get_mipmap()) {
- gpu_generate_mipmap(GL_TEXTURE_2D);
+ GPU_generate_mipmap(GL_TEXTURE_2D);
}
else {
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
@@ -1344,7 +1356,7 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i
/* see comment above as to why we are using gpu mipmap generation here */
if (GPU_get_mipmap()) {
- gpu_generate_mipmap(GL_TEXTURE_2D);
+ GPU_generate_mipmap(GL_TEXTURE_2D);
}
else {
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
@@ -1600,7 +1612,7 @@ typedef struct GPUMaterialFixed {
float spec[3];
int hard;
float alpha;
-} GPUMaterialFixed;
+} GPUMaterialFixed;
static struct GPUMaterialState {
GPUMaterialFixed (*matbuf);
@@ -1617,6 +1629,8 @@ static struct GPUMaterialState {
Object *gob;
DupliObject *dob;
Scene *gscene;
+ GPUProbe *gprobe;
+ GPUPBR *gpbr;
int glay;
bool gscenelock;
float (*gviewmat)[4];
@@ -1634,6 +1648,14 @@ static struct GPUMaterialState {
int lastmatnr, lastretval;
GPUBlendMode lastalphablend;
bool is_opensubdiv;
+ bool is_planar_probe;
+ bool is_realistic_mat;
+ bool is_alpha_as_depth;
+ bool use_backface_depth;
+ bool use_ssr;
+ bool use_ssao;
+ int parallax_correc;
+ GPUPBRSettings *gpbrsettings;
} GMS = {NULL};
/* fixed function material, alpha handed by caller */
@@ -1712,7 +1734,7 @@ void GPU_begin_object_materials(
View3D *v3d, RegionView3D *rv3d, Scene *scene, Object *ob,
bool glsl, bool *do_alpha_after)
{
- Material *ma;
+ Material *ma = NULL;
GPUMaterial *gpumat;
GPUBlendMode alphablend;
DupliObject *dob;
@@ -1778,6 +1800,16 @@ void GPU_begin_object_materials(
GMS.gviewmat = rv3d->viewmat;
GMS.gviewinv = rv3d->viewinv;
GMS.gviewcamtexcofac = rv3d->viewcamtexcofac;
+ GMS.is_realistic_mat = (new_shading_nodes && (v3d->pbr_settings.pbr_flag & GPU_PBR_FLAG_ENABLE));
+ GMS.is_alpha_as_depth = (v3d->flag3 & V3D_PROBE_CAPTURE);
+ GMS.gprobe = NULL;
+ GMS.gpbr = NULL;
+ GMS.gpbrsettings = NULL;
+ GMS.use_ssr = false;
+ GMS.use_ssao = false;
+ GMS.use_backface_depth = false;
+ GMS.is_planar_probe = false;
+ GMS.parallax_correc = 0;
/* alpha pass setup. there's various cases to handle here:
* - object transparency on: only solid materials draw in the first pass,
@@ -1811,22 +1843,88 @@ void GPU_begin_object_materials(
GMS.alphablend[0] = GPU_BLEND_SOLID;
}
else {
-
+ if (glsl && new_shading_nodes && GMS.is_realistic_mat && !(v3d->flag2 & V3D_RENDER_SHADOW)) {
+ GMS.use_ssr = (v3d->pbr_settings.pbr_flag & GPU_PBR_FLAG_SSR);
+ GMS.use_ssao = (v3d->pbr_settings.pbr_flag & GPU_PBR_FLAG_SSAO);
+ GMS.use_backface_depth = (v3d->pbr_settings.pbr_flag & GPU_PBR_FLAG_BACKFACE);
+ GMS.gpbrsettings = &v3d->pbr_settings;
+ GMS.gpbr = v3d->pbr;
+
+ /* Layer override */
+ if (v3d->pbr_settings.pbr_flag & GPU_PBR_FLAG_LAYER_OVERRIDE) {
+ SceneRenderLayer *srl = BLI_findlink(&GMS.gscene->r.layers, GMS.gscene->r.actlay);
+ if (srl->mat_override) ma = srl->mat_override;
+ }
+
+ if (v3d->flag3 & V3D_PROBE_CAPTURE) {
+ Object *pro = (ob->probetype == OB_PROBE_OBJECT && ob->probe)
+ ? ob->probe /* probe attached */
+ : ob; /* object itself */
+
+ GMS.use_ssr = false;
+ GMS.use_ssao = false;
+ GMS.use_backface_depth = false;
+
+ /* check if we are not rendering this particular probe to avoid feedback loop */
+ if (pro != v3d->probe_source) {
+ if (pro->probetype == OB_PROBE_CUBEMAP) {
+ GMS.gprobe = GPU_probe_object(scene, pro);
+ GMS.parallax_correc = pro->probeparallax;
+ }
+ else if (pro->probetype == OB_PROBE_PLANAR) {
+ /* fallback to attached probe or world probe */
+ if (pro->probe && pro->probe->probetype == OB_PROBE_CUBEMAP
+ && pro->probe != v3d->probe_source) {
+ GMS.gprobe = GPU_probe_object(scene, pro->probe);
+ GMS.parallax_correc = pro->probe->probeparallax;
+ }
+ }
+ }
+ }
+ else {
+ Object *pro = (ob->probetype == OB_PROBE_OBJECT && ob->probe)
+ ? ob->probe /* probe attached */
+ : ob; /* object itself */
+
+ if (pro->probetype == OB_PROBE_CUBEMAP) {
+ GMS.gprobe = GPU_probe_object(scene, pro);
+ GMS.parallax_correc = pro->probeparallax;
+ }
+ else if (pro->probetype == OB_PROBE_PLANAR) {
+ GMS.is_planar_probe = true;
+ GMS.gprobe = GPU_probe_object(scene, pro);
+ /* Pass the parallax info of the fallback cubemap*/
+ if (pro->probe && pro->probe->probetype == OB_PROBE_CUBEMAP) {
+ GMS.parallax_correc = pro->probe->probeparallax;
+ }
+ }
+ }
+
+ /* Default : use the world probe if it exists */
+ if (!GMS.gprobe && scene->world) {
+ GMS.gprobe = GPU_probe_world(scene, scene->world);
+ }
+ }
+
/* no materials assigned? */
if (ob->totcol == 0) {
- gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob, new_shading_nodes, true);
+ if (ma == NULL) ma = &defmaterial;
+ gpu_material_to_fixed(&GMS.matbuf[0], ma, 0, ob, new_shading_nodes, true);
/* do material 1 too, for displists! */
memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed));
if (glsl) {
- GMS.gmatbuf[0] = &defmaterial;
- GPU_material_from_blender(GMS.gscene, &defmaterial, GMS.is_opensubdiv);
+ GMS.gmatbuf[0] = ma;
+ GPU_material_from_blender(GMS.gscene, ma, GMS.is_opensubdiv,
+ GMS.is_realistic_mat, GMS.is_planar_probe,
+ GMS.is_alpha_as_depth, GMS.use_backface_depth, GMS.use_ssr, GMS.use_ssao,
+ GMS.parallax_correc);
}
GMS.alphablend[0] = GPU_BLEND_SOLID;
}
-
+
/* setup materials */
for (a = 1; a <= ob->totcol; a++) {
/* find a suitable material */
@@ -1834,8 +1932,16 @@ void GPU_begin_object_materials(
if (!glsl && !new_shading_nodes) ma = gpu_active_node_material(ma);
if (ma == NULL) ma = &defmaterial;
+ if (v3d->pbr_settings.pbr_flag & GPU_PBR_FLAG_LAYER_OVERRIDE) {
+ SceneRenderLayer *srl = BLI_findlink(&GMS.gscene->r.layers, GMS.gscene->r.actlay);
+ if (srl->mat_override) ma = srl->mat_override;
+ }
+
/* create glsl material if requested */
- gpumat = glsl ? GPU_material_from_blender(GMS.gscene, ma, GMS.is_opensubdiv) : NULL;
+ gpumat = glsl ? GPU_material_from_blender(GMS.gscene, ma, GMS.is_opensubdiv,
+ GMS.is_realistic_mat, GMS.is_planar_probe,
+ GMS.is_alpha_as_depth, GMS.use_backface_depth, GMS.use_ssr, GMS.use_ssao,
+ GMS.parallax_correc) : NULL;
if (gpumat) {
/* do glsl only if creating it succeed, else fallback */
@@ -1934,7 +2040,10 @@ int GPU_object_material_bind(int nr, void *attribs)
/* unbind glsl material */
if (GMS.gboundmat) {
if (GMS.is_alpha_pass) glDepthMask(0);
- GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.is_opensubdiv));
+ GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.is_opensubdiv,
+ GMS.is_realistic_mat, GMS.is_planar_probe,
+ GMS.is_alpha_as_depth, GMS.use_backface_depth, GMS.use_ssr, GMS.use_ssao,
+ GMS.parallax_correc));
GMS.gboundmat = NULL;
}
@@ -1957,22 +2066,27 @@ int GPU_object_material_bind(int nr, void *attribs)
if (gattribs && GMS.gmatbuf[nr]) {
/* bind glsl material and get attributes */
Material *mat = GMS.gmatbuf[nr];
- GPUParticleInfo partile_info;
+ GPUParticleInfo particle_info;
float auto_bump_scale;
- GPUMaterial *gpumat = GPU_material_from_blender(GMS.gscene, mat, GMS.is_opensubdiv);
+ GPUMaterial *gpumat = GPU_material_from_blender(GMS.gscene, mat, GMS.is_opensubdiv, GMS.is_realistic_mat,
+ GMS.is_planar_probe, GMS.is_alpha_as_depth, GMS.use_backface_depth, GMS.use_ssr,
+ GMS.use_ssao, GMS.parallax_correc);
GPU_material_vertex_attributes(gpumat, gattribs);
if (GMS.dob)
- GPU_get_particle_info(&partile_info);
+ GPU_get_particle_info(&particle_info);
GPU_material_bind(
gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT),
GMS.gviewmat, GMS.gviewinv, GMS.gviewcamtexcofac, GMS.gscenelock);
auto_bump_scale = GMS.gob->derivedFinal != NULL ? GMS.gob->derivedFinal->auto_bump_scale : 1.0f;
- GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gob->col, auto_bump_scale, &partile_info);
+ GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gob->col, auto_bump_scale, &particle_info);
+
+ GPU_material_bind_uniforms_pbr(gpumat, GMS.gprobe, GMS.gpbr, GMS.gpbrsettings);
+
GMS.gboundmat = mat;
/* for glsl use alpha blend mode, unless it's set to solid and
@@ -2060,7 +2174,9 @@ void GPU_object_material_unbind(void)
glDisable(GL_CULL_FACE);
if (GMS.is_alpha_pass) glDepthMask(0);
- GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.is_opensubdiv));
+ GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.is_opensubdiv, GMS.is_realistic_mat,
+ GMS.is_planar_probe, GMS.is_alpha_as_depth, GMS.use_backface_depth, GMS.use_ssr, GMS.use_ssao,
+ GMS.parallax_correc));
GMS.gboundmat = NULL;
}
else
@@ -2355,7 +2471,14 @@ void GPU_draw_update_fvar_offset(DerivedMesh *dm)
gpu_material = GPU_material_from_blender(GMS.gscene,
material,
- GMS.is_opensubdiv);
+ GMS.is_opensubdiv,
+ GMS.is_realistic_mat,
+ GMS.is_planar_probe,
+ GMS.is_alpha_as_depth,
+ GMS.use_backface_depth,
+ GMS.use_ssr,
+ GMS.use_ssao,
+ GMS.parallax_correc);
GPU_material_update_fvar_offset(gpu_material, dm);
}
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index d41573b681b..10cd0452278 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -336,7 +336,6 @@ bool GPU_mem_stats_supported(void)
return (GLEW_NVX_gpu_memory_info || (GLEW_ATI_meminfo)) && (G.debug & G_DEBUG_GPU_MEM);
}
-
void GPU_mem_stats_get(int *totalmem, int *freemem)
{
if (GLEW_NVX_gpu_memory_info) {
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index c0400cdb04c..d0a4d8a0ac0 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -29,6 +29,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_math_base.h"
#include "BKE_global.h"
@@ -126,7 +127,7 @@ GPUFrameBuffer *GPU_framebuffer_create(void)
return fb;
}
-int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, char err_out[256])
+static int gpu_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, int cubeface, char err_out[256])
{
GLenum attachment;
GLenum error;
@@ -157,8 +158,12 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot
/* Clean glError buffer. */
while (glGetError() != GL_NO_ERROR) {}
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
- GPU_texture_target(tex), GPU_texture_opengl_bindcode(tex), 0);
+ if (GPU_texture_target(tex) == GL_TEXTURE_CUBE_MAP)
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubeface, GPU_texture_opengl_bindcode(tex), 0);
+ else
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
+ GPU_texture_target(tex), GPU_texture_opengl_bindcode(tex), 0);
error = glGetError();
@@ -178,6 +183,16 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot
return 1;
}
+int GPU_framebuffer_cubeface_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, int cubeface, char err_out[256])
+{
+ return gpu_framebuffer_texture_attach(fb, tex, slot, cubeface, err_out);
+}
+
+int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, char err_out[256])
+{
+ return gpu_framebuffer_texture_attach(fb, tex, slot, 0, err_out);
+}
+
void GPU_framebuffer_texture_detach(GPUTexture *tex)
{
GLenum attachment;
@@ -341,6 +356,7 @@ bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256])
void GPU_framebuffer_free(GPUFrameBuffer *fb)
{
int i;
+
if (fb->depthtex)
GPU_framebuffer_texture_detach(fb->depthtex);
@@ -443,6 +459,72 @@ void GPU_framebuffer_blur(
GPU_shader_unbind();
}
+void GPU_framebuffer_hiz_construction(GPUFrameBuffer* fb, GPUTexture *tex, const bool max)
+{
+ int current_dim[2] = {GPU_texture_width(tex), GPU_texture_height(tex)};
+ int levels, bindcode;
+ int lowermip_uniform, lowermipsize_uniform;
+ GPUShader *shader = GPU_shader_get_builtin_shader((max) ? GPU_SHADER_MAXZ_DOWNSAMPLE : GPU_SHADER_MINZ_DOWNSAMPLE);
+
+ if (!shader)
+ return;
+
+ GPU_shader_bind(shader);
+ lowermip_uniform = GPU_shader_get_uniform(shader, "lowermip");
+ lowermipsize_uniform = GPU_shader_get_uniform(shader, "lowermipsize");
+
+ GPU_framebuffer_texture_attach(fb, tex, 0, NULL);
+ GPU_texture_bind_as_framebuffer(tex);
+
+ bindcode = GPU_texture_opengl_bindcode(tex);
+
+ levels = 1 + (int)floorf(log2f(fmaxf(current_dim[0], current_dim[1])));
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_ALWAYS);
+
+ /* Avoid warning from GPU_texture_bind */
+ glBindTexture(GL_TEXTURE_2D, bindcode);
+ GPU_shader_uniform_texture(shader, lowermip_uniform, tex);
+
+ for (int i=1; i < levels; i++) {
+ /* Send previous mip size to the shader */
+ GPU_shader_uniform_vector_int(shader, lowermipsize_uniform, 2, 1, current_dim);
+
+ /* calculate next viewport size */
+ current_dim[0] /= 2;
+ current_dim[1] /= 2;
+
+ /* ensure that the viewport size is always at least 1x1 */
+ CLAMP_MIN(current_dim[0], 1);
+ CLAMP_MIN(current_dim[1], 1);
+ glViewport(0, 0, current_dim[0], current_dim[1]);
+
+ /* bind next level for rendering but first restrict fetches only to previous level */
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, i-1);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, i-1);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, bindcode, i);
+
+ /* Drawing quad */
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2d(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0);
+ glTexCoord2d(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0);
+ glTexCoord2d(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0);
+ glTexCoord2d(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0);
+ glEnd();
+ }
+
+ GPU_framebuffer_texture_detach(tex);
+ GPU_framebuffer_texture_unbind(fb, tex);
+
+ /* reset mipmap level range for the depth image */
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, levels - 1);
+
+ GPU_shader_unbind();
+ GPU_texture_unbind(tex);
+}
+
/* GPUOffScreen */
struct GPUOffScreen {
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index ed9718f1a17..afae3b12bf1 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -45,10 +45,12 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_dynstr.h"
#include "BKE_anim.h"
#include "BKE_colortools.h"
#include "BKE_global.h"
+#include "BKE_object.h"
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_node.h"
@@ -63,6 +65,9 @@
#include "GPU_material.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
+#include "GPU_draw.h"
+#include "GPU_pbr.h"
+#include "GPU_probe.h"
#include "gpu_codegen.h"
@@ -77,6 +82,7 @@ typedef enum DynMatProperty {
DYN_LAMP_VEC = 2,
DYN_LAMP_IMAT = 4,
DYN_LAMP_PERSMAT = 8,
+ DYN_LAMP_MAT = 16,
} DynMatProperty;
static struct GPUWorld {
@@ -106,7 +112,7 @@ struct GPUMaterial {
/* for binding the material */
GPUPass *pass;
GPUVertexAttribs attribs;
- int builtins;
+ int builtins, pbrbuiltins;
int alpha, obcolalpha;
int dynproperty;
@@ -122,10 +128,54 @@ struct GPUMaterial {
int partvel;
int partangvel;
+ /* Probe binding */
+ int brdfsamplesloc, lutsamplesloc, jitterloc;
+ int ltcmatloc, ltcmagloc;
+ int probeloc, reflectloc, refractloc;
+ int lodfactorloc;
+ int correcmatloc, planarreflloc, planarobjloc;
+ int probecoloc, planarvecloc;
+ int shloc[9];
+ GPUTexture *bindedcubeprobe;
+ GPUTexture *bindedreflprobe;
+ GPUTexture *bindedrefrprobe;
+ GPUTexture *bindedhammersley;
+ GPUTexture *bindedjitter;
+ GPUTexture *bindedltcmat;
+ GPUTexture *bindedltcmag;
+
+ /* Screen space effects (SSR, SSAO...) */
+ int scenebufloc;
+ int depthbufloc;
+ int backfacebufloc;
+ int ssaoparamsloc;
+ int clipinfoloc;
+ int ssrparamsloc;
+ int pixelprojmatloc;
+ GPUTexture *bindedscenebuffer;
+ GPUTexture *bindeddepthbuffer;
+ GPUTexture *bindedbackfacebuffer;
+
ListBase lamps;
bool bound;
+ /* for passing parameters to the world nodetree */
+ GPUNodeLink *lampNorLink;
+ GPUNodeLink *lampPosLink;
+ GPUNodeLink *lampInLink;
+ GPUBrdfInput *brdf;
+
+ int parallax_correc;
+ bool is_planar_probe;
+ bool is_alpha_as_depth;
+ bool use_backface_depth;
+ bool use_ssr;
+ bool use_ssao;
bool is_opensubdiv;
+
+ /* Keep certain links during the material creation
+ * to do these calculations only once for the whole material */
+ GPUNodeLink *ln_ssao;
};
struct GPULamp {
@@ -144,9 +194,11 @@ struct GPULamp {
float obmat[4][4];
float imat[4][4];
float dynimat[4][4];
+ float dynmat[4][4];
float spotsi, spotbl, k;
float spotvec[2];
+ float areavec[2];
float dyndist, dynatt1, dynatt2;
float dist, att1, att2;
float coeff_const, coeff_lin, coeff_quad;
@@ -155,8 +207,11 @@ struct GPULamp {
float bias, d, clipend;
int size;
+ float area_size, area_size_y;
+
int falloff_type;
struct CurveMapping *curfalloff;
+ bool use_realistic_lighting;
float winmat[4][4];
float viewmat[4][4];
@@ -169,6 +224,14 @@ struct GPULamp {
GPUTexture *depthtex;
GPUTexture *blurtex;
+ /* Keep certain links during the material creation
+ * to do these calculations only once for the whole material */
+ GPUNodeLink *nl_lv;
+ GPUNodeLink *nl_dist;
+ GPUNodeLink *nl_visifac;
+ GPUNodeLink *nl_shadfac;
+ GPUNodeLink *nl_lcol;
+
ListBase materials;
};
@@ -181,11 +244,14 @@ static void texture_rgb_blend(
static GPUMaterial *GPU_material_construct_begin(Material *ma)
{
- GPUMaterial *material = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial");
+ GPUMaterial *material = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial");
+
+ material->ma = ma;
- material->ma = ma;
+ /* Optimisation variables */
+ material->ln_ssao = NULL;
- return material;
+ return material;
}
static void gpu_material_set_attrib_id(GPUMaterial *material)
@@ -229,11 +295,19 @@ static int GPU_material_construct_end(GPUMaterial *material, const char *passnam
{
if (material->outlink) {
GPUNodeLink *outlink = material->outlink;
+
material->pass = GPU_generate_pass(&material->nodes, outlink,
- &material->attribs, &material->builtins, material->type,
+ &material->attribs, &material->builtins, &material->pbrbuiltins, material->type,
passname,
material->is_opensubdiv,
- GPU_material_use_new_shading_nodes(material));
+ GPU_material_use_new_shading_nodes(material),
+ material->is_planar_probe,
+ material->parallax_correc & OB_PROBE_PARRALAX_BOX,
+ material->parallax_correc & OB_PROBE_PARRALAX_ELLIPSOID,
+ material->is_alpha_as_depth,
+ material->use_backface_depth,
+ material->use_ssr,
+ material->use_ssao);
if (!material->pass)
return 0;
@@ -268,6 +342,39 @@ static int GPU_material_construct_end(GPUMaterial *material, const char *passnam
material->partvel = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_VELOCITY));
if (material->builtins & GPU_PARTICLE_ANG_VELOCITY)
material->partangvel = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_ANG_VELOCITY));
+
+ if (material->builtins & GPU_PBR) {
+ material->brdfsamplesloc = GPU_shader_get_uniform(shader, "unfbsdfsamples");
+ material->ltcmatloc = GPU_shader_get_uniform(shader, "unfltcmat");
+ material->ltcmagloc = GPU_shader_get_uniform(shader, "unfltcmag");
+ material->jitterloc = GPU_shader_get_uniform(shader, "unfjitter");
+ material->lutsamplesloc = GPU_shader_get_uniform(shader, "unflutsamples");
+ material->probeloc = GPU_shader_get_uniform(shader, "unfprobe");
+ material->reflectloc = GPU_shader_get_uniform(shader, "unfreflect");
+ material->refractloc = GPU_shader_get_uniform(shader, "unfrefract");
+ material->lodfactorloc = GPU_shader_get_uniform(shader, "unflodfactor");
+ material->shloc[0] = GPU_shader_get_uniform(shader, "unfsh0");
+ material->shloc[1] = GPU_shader_get_uniform(shader, "unfsh1");
+ material->shloc[2] = GPU_shader_get_uniform(shader, "unfsh2");
+ material->shloc[3] = GPU_shader_get_uniform(shader, "unfsh3");
+ material->shloc[4] = GPU_shader_get_uniform(shader, "unfsh4");
+ material->shloc[5] = GPU_shader_get_uniform(shader, "unfsh5");
+ material->shloc[6] = GPU_shader_get_uniform(shader, "unfsh6");
+ material->shloc[7] = GPU_shader_get_uniform(shader, "unfsh7");
+ material->shloc[8] = GPU_shader_get_uniform(shader, "unfsh8");
+ material->correcmatloc = GPU_shader_get_uniform(shader, "unfprobecorrectionmat");
+ material->planarreflloc = GPU_shader_get_uniform(shader, "unfplanarreflectmat");
+ material->probecoloc = GPU_shader_get_uniform(shader, "unfprobepos");
+ material->planarvecloc = GPU_shader_get_uniform(shader, "unfplanarvec");
+ material->scenebufloc = GPU_shader_get_uniform(shader, "unfscenebuf");
+ material->depthbufloc = GPU_shader_get_uniform(shader, "unfdepthbuf");
+ material->backfacebufloc = GPU_shader_get_uniform(shader, "unfbackfacebuf");
+ material->ssrparamsloc = GPU_shader_get_uniform(shader, "unfssrparam");
+ material->pixelprojmatloc = GPU_shader_get_uniform(shader, "unfpixelprojmat");
+ material->ssaoparamsloc = GPU_shader_get_uniform(shader, "unfssaoparam");
+ material->clipinfoloc = GPU_shader_get_uniform(shader, "unfclip");
+ }
+
return 1;
}
else {
@@ -330,7 +437,7 @@ void GPU_material_bind(
viewlay &= srl->lay;
/* handle layer lamps */
- if (material->type == GPU_MATERIAL_TYPE_MESH) {
+ if (material->type == GPU_MATERIAL_TYPE_MESH || material->type == GPU_MATERIAL_TYPE_MESH_REAL_SH) {
for (LinkData *nlink = material->lamps.first; nlink; nlink = nlink->next) {
GPULamp *lamp = nlink->data;
@@ -360,6 +467,10 @@ void GPU_material_bind(
if (material->dynproperty & DYN_LAMP_IMAT) {
mul_m4_m4m4(lamp->dynimat, lamp->imat, viewinv);
}
+
+ if (material->dynproperty & DYN_LAMP_MAT) {
+ mul_m4_m4m4(lamp->dynmat, viewmat, lamp->obmat);
+ }
if (material->dynproperty & DYN_LAMP_PERSMAT) {
/* The lamp matrices are already updated if we're using shadow buffers */
@@ -395,6 +506,17 @@ void GPU_material_bind(
GPU_pass_update_uniforms(material->pass);
material->bound = 1;
+ /* XXX */
+ material->bindedcubeprobe = NULL;
+ material->bindedreflprobe = NULL;
+ material->bindedrefrprobe = NULL;
+ material->bindedhammersley = NULL;
+ material->bindedscenebuffer = NULL;
+ material->bindeddepthbuffer = NULL;
+ material->bindedbackfacebuffer = NULL;
+ material->bindedjitter = NULL;
+ material->bindedltcmat = NULL;
+ material->bindedltcmag = NULL;
}
}
@@ -449,13 +571,185 @@ void GPU_material_bind_uniforms(
if (material->builtins & GPU_PARTICLE_ANG_VELOCITY) {
GPU_shader_uniform_vector(shader, material->partangvel, 3, 1, pi->angular_velocity);
}
+ }
+}
+
+void GPU_material_bind_uniforms_pbr(GPUMaterial *material, GPUProbe *probe, GPUPBR *pbr, GPUPBRSettings *pbr_settings)
+{
+ if (material->pass && material->builtins & GPU_PBR) {
+ GPUShader *shader = GPU_pass_shader(material->pass);
+
+ if (pbr) {
+ material->bindedhammersley = pbr->hammersley;
+ GPU_texture_bind(material->bindedhammersley, 0);
+ GPU_shader_uniform_texture(shader, material->lutsamplesloc, material->bindedhammersley);
+
+ material->bindedjitter = pbr->jitter;
+ GPU_texture_bind(material->bindedjitter, 1);
+ GPU_shader_uniform_texture(shader, material->jitterloc, material->bindedjitter);
+
+ material->bindedltcmat = pbr->ltc_mat_ggx;
+ GPU_texture_bind(material->bindedltcmat, 2);
+ GPU_shader_uniform_texture(shader, material->ltcmatloc, material->bindedltcmat);
+
+ material->bindedltcmag = pbr->ltc_mag_ggx;
+ GPU_texture_bind(material->bindedltcmag, 3);
+ GPU_shader_uniform_texture(shader, material->ltcmagloc, material->bindedltcmag);
+ }
+ if (probe) {
+ /* Spherical Harmonics */
+ for (int i = 0; i < 9; ++i) {
+ GPU_shader_uniform_vector(shader, material->shloc[i], 3, 1, &probe->shcoefs[i*3]);
+ }
+
+ /* BSDF Samples */
+ float samples[2];
+ samples[0] = pbr_settings->brdf->samples;
+ samples[1] = 1.0f / samples[0];
+ GPU_shader_uniform_vector(shader, material->brdfsamplesloc, 2, 1, samples);
+
+ /* Lod factor for importance sampling */
+ float lodfactor = 0.5f * log( ( (float)(probe->size * probe->size) * samples[1] ) ) / log(2);
+ lodfactor -= pbr_settings->brdf->lodbias;
+ GPU_shader_uniform_vector(shader, material->lodfactorloc, 1, 1, &lodfactor);
+
+ /* Probe Cube */
+ if (probe->type == GPU_PROBE_PLANAR) {
+ GPUProbe *fallbackprobe = NULL;
+ /* XXX : this should be moved elsewhere */
+ if (probe->ob->probe && probe->ob->probe->probetype == OB_PROBE_CUBEMAP)
+ fallbackprobe = GPU_probe_object(material->scene, probe->ob->probe);
+ else if (material->scene->world)
+ fallbackprobe = GPU_probe_world(material->scene, material->scene->world);
+
+ if (fallbackprobe)
+ material->bindedcubeprobe = fallbackprobe->tex;
+ }
+ else {
+ /* XXX : save the probe for unbinding */
+ material->bindedcubeprobe = probe->tex;
+ }
+ if (material->bindedcubeprobe) {
+ GPU_texture_bind(material->bindedcubeprobe, 4);
+ GPU_shader_uniform_texture(shader, material->probeloc, material->bindedcubeprobe);
+ }
+
+ /* Probe Planar */
+ if (probe->type == GPU_PROBE_PLANAR) {
+ /* XXX : save the reflection for unbinding */
+ material->bindedreflprobe = probe->texreflect;
+ material->bindedrefrprobe = probe->texrefract;
+ GPU_texture_bind(material->bindedreflprobe, 5);
+ GPU_shader_uniform_texture(shader, material->reflectloc, material->bindedreflprobe);
+ GPU_texture_bind(material->bindedrefrprobe, 6);
+ GPU_shader_uniform_texture(shader, material->refractloc, material->bindedrefrprobe);
+ }
+
+ /* Planar reflection matrix */
+ GPU_shader_uniform_vector(shader, material->planarreflloc, 16, 1, (float *)probe->reflectionmat);
+
+ /* Parallax Correction Matrix */
+ GPU_shader_uniform_vector(shader, material->correcmatloc, 16, 1, (float *)probe->correctionmat);
+
+ /* Probe Position */
+ GPU_shader_uniform_vector(shader, material->probecoloc, 3, 1, probe->co);
+
+ /* Planar vector */
+ GPU_shader_uniform_vector(shader, material->planarvecloc, 3, 1, probe->planevec);
+ }
+ else {
+ /* avoid objects with the same material and no probe attached to have the same SH binded */
+ float black[3] = {0.0f, 0.0f, 0.0f};
+ for (int i = 0; i < 9; ++i) {
+ GPU_shader_uniform_vector(shader, material->shloc[i], 3, 1, black);
+ }
+ }
+
+ if (pbr_settings->pbr_flag & (GPU_PBR_FLAG_SSR | GPU_PBR_FLAG_SSAO)) {
+ /* Scene Buffer */
+ material->bindedscenebuffer = pbr->scene->tex;
+ GPU_texture_bind(material->bindedscenebuffer, 7);
+ GPU_shader_uniform_texture(shader, material->scenebufloc, material->bindedscenebuffer);
+
+ /* Depth Buffer */
+ material->bindeddepthbuffer = pbr->scene->depth;
+ GPU_texture_bind(material->bindeddepthbuffer, 8);
+ GPU_shader_uniform_texture(shader, material->depthbufloc, material->bindeddepthbuffer);
+
+ /* Pixel proj matrix */
+ GPU_shader_uniform_vector(shader, material->pixelprojmatloc, 16, 1, (float *)pbr->scene->pixelprojmat);
+
+ float clipinfo[4];
+ clipinfo[0] = pbr->scene->clipsta;
+ clipinfo[1] = pbr->scene->clipend;
+ clipinfo[2] = (float)pbr->scene->w;
+ clipinfo[3] = (float)pbr->scene->h;
+ GPU_shader_uniform_vector(shader, material->clipinfoloc, 4, 1, clipinfo);
+
+ if (pbr_settings->pbr_flag & GPU_PBR_FLAG_BACKFACE) {
+ /* Backface Buffer */
+ material->bindedbackfacebuffer = pbr->backface->tex;
+ GPU_texture_bind(material->bindedbackfacebuffer, 9);
+ GPU_shader_uniform_texture(shader, material->backfacebufloc, material->bindedbackfacebuffer);
+ }
+ }
+
+ if (pbr_settings->pbr_flag & GPU_PBR_FLAG_SSR) {
+ /* SSR Parameters */
+ /* x : steps : Maximum number of iteration when raymarching
+ * y : offset : Step between samples.
+ * z : attenuation : fallof exponent
+ * w : thickness : pixel thickness */
+ float ssrparams[3];
+ ssrparams[0] = (float)pbr_settings->ssr->steps;
+ ssrparams[1] = pbr_settings->ssr->attenuation;
+ ssrparams[2] = pbr_settings->ssr->thickness;
+ GPU_shader_uniform_vector(shader, material->ssrparamsloc, 3, 1, ssrparams);
+ }
+
+ if (pbr_settings->pbr_flag & GPU_PBR_FLAG_SSAO) {
+ World *wo = material->scene->world;
+ /* SSAO Parameters */
+ /* x : sample : Number of samples
+ * y : steps : Steps for the raymarching
+ * z : distance : Max distance
+ * w : factor : Blend intensity */
+ float ssaoparams[4];
+ ssaoparams[0] = pbr_settings->ssao->samples;
+ ssaoparams[1] = pbr_settings->ssao->steps;
+ ssaoparams[2] = (wo) ? wo->aodist : 1.0;
+ ssaoparams[3] = pbr_settings->ssao->factor;
+ GPU_shader_uniform_vector(shader, material->ssaoparamsloc, 4, 1, ssaoparams);
+ }
}
}
void GPU_material_unbind(GPUMaterial *material)
{
if (material->pass) {
+ /* XXX */
+ if (material->bindedcubeprobe)
+ GPU_texture_unbind(material->bindedcubeprobe);
+ if (material->bindedreflprobe)
+ GPU_texture_unbind(material->bindedreflprobe);
+ if (material->bindedrefrprobe)
+ GPU_texture_unbind(material->bindedrefrprobe);
+ if (material->bindedscenebuffer)
+ GPU_texture_unbind(material->bindedscenebuffer);
+ if (material->bindeddepthbuffer)
+ GPU_texture_unbind(material->bindeddepthbuffer);
+ if (material->bindedbackfacebuffer)
+ GPU_texture_unbind(material->bindedbackfacebuffer);
+ if (material->bindedhammersley)
+ GPU_texture_unbind(material->bindedhammersley);
+ if (material->bindedjitter)
+ GPU_texture_unbind(material->bindedjitter);
+ if (material->bindedltcmat)
+ GPU_texture_unbind(material->bindedltcmat);
+ if (material->bindedltcmag)
+ GPU_texture_unbind(material->bindedltcmag);
+
material->bound = 0;
GPU_pass_unbind(material->pass);
}
@@ -471,11 +765,15 @@ Scene *GPU_material_scene(GPUMaterial *material)
return material->scene;
}
-GPUMatType GPU_Material_get_type(GPUMaterial *material)
+GPUMatType GPU_material_get_type(GPUMaterial *material)
{
return material->type;
}
+void GPU_material_set_type(GPUMaterial *material, GPUMatType type)
+{
+ material->type = type;
+}
void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs)
{
@@ -488,6 +786,61 @@ void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link)
material->outlink = link;
}
+void GPU_material_empty_output_link(GPUMaterial *material)
+{
+ material->outlink = NULL;
+}
+
+GPUNodeLink *GPU_material_get_output_link(GPUMaterial *material)
+{
+ return material->outlink;
+}
+
+void GPU_material_set_lamp_normal_link(GPUMaterial *material, GPUNodeLink *link)
+{
+ material->lampNorLink = link;
+}
+
+GPUNodeLink *GPU_material_get_lamp_normal_link(GPUMaterial *material)
+{
+ return material->lampNorLink;
+}
+
+void GPU_material_set_lamp_position_link(GPUMaterial *material, GPUNodeLink *link)
+{
+ material->lampPosLink = link;
+}
+
+GPUNodeLink *GPU_material_get_lamp_position_link(GPUMaterial *material)
+{
+ return material->lampPosLink;
+}
+
+void GPU_material_set_lamp_incoming_link(GPUMaterial *material, GPUNodeLink *link)
+{
+ material->lampInLink = link;
+}
+
+GPUNodeLink *GPU_material_get_lamp_incoming_link(GPUMaterial *material)
+{
+ return material->lampInLink;
+}
+
+void GPU_material_set_brdf_link(GPUMaterial *material, GPUBrdfInput *brdf)
+{
+ material->brdf = brdf;
+}
+
+GPUBrdfInput *GPU_material_get_brdf_link(GPUMaterial *material)
+{
+ return material->brdf;
+}
+
+GPUNodeLink *GPU_get_world_horicol(void)
+{
+ return GPU_dynamic_uniform(GPUWorld.horicol, GPU_DYNAMIC_HORIZON_COLOR, NULL);
+}
+
void GPU_material_enable_alpha(GPUMaterial *material)
{
material->alpha = 1;
@@ -526,96 +879,249 @@ bool GPU_material_use_world_space_shading(GPUMaterial *mat)
return BKE_scene_use_world_space_shading(mat->scene);
}
-static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **lv, GPUNodeLink **dist)
+static GPUNodeLink *lamp_get_lightcolor(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink *lv)
{
- GPUNodeLink *visifac;
+ // if (lamp->use_realistic_lighting) {
- /* from get_lamp_visibility */
- if (lamp->type == LA_SUN || lamp->type == LA_HEMI) {
- mat->dynproperty |= DYN_LAMP_VEC;
- GPU_link(mat, "lamp_visibility_sun_hemi",
- GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), lv, dist, &visifac);
- return visifac;
- }
- else {
- mat->dynproperty |= DYN_LAMP_CO;
- GPU_link(mat, "lamp_visibility_other",
- GPU_builtin(GPU_VIEW_POSITION),
- GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), lv, dist, &visifac);
+ /* Optimisation only run once */
+ if (lamp->nl_lcol)
+ return lamp->nl_lcol;
- if (lamp->type == LA_AREA)
- return visifac;
+ if (lamp->la->use_nodes) {
+ GPUNodeLink *lamp_normal, *lamp_position, *lamp_incoming;
+ GPUMatType type = GPU_material_get_type(mat);
- switch (lamp->falloff_type) {
- case LA_FALLOFF_CONSTANT:
- break;
- case LA_FALLOFF_INVLINEAR:
- GPU_link(mat, "lamp_falloff_invlinear",
- GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac);
- break;
- case LA_FALLOFF_INVSQUARE:
- GPU_link(mat, "lamp_falloff_invsquare",
- GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac);
- break;
- case LA_FALLOFF_SLIDERS:
- GPU_link(mat, "lamp_falloff_sliders",
- GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob),
- GPU_dynamic_uniform(&lamp->att1, GPU_DYNAMIC_LAMP_ATT1, lamp->ob),
- GPU_dynamic_uniform(&lamp->att2, GPU_DYNAMIC_LAMP_ATT2, lamp->ob), *dist, &visifac);
- break;
- case LA_FALLOFF_INVCOEFFICIENTS:
- GPU_link(mat, "lamp_falloff_invcoefficients",
- GPU_dynamic_uniform(&lamp->coeff_const, GPU_DYNAMIC_LAMP_COEFFCONST, lamp->ob),
- GPU_dynamic_uniform(&lamp->coeff_lin, GPU_DYNAMIC_LAMP_COEFFLIN, lamp->ob),
- GPU_dynamic_uniform(&lamp->coeff_quad, GPU_DYNAMIC_LAMP_COEFFQUAD, lamp->ob), *dist, &visifac);
- break;
- case LA_FALLOFF_CURVE:
- {
- float *array;
- int size;
+ /* Position */
+ if (lamp->type == LA_SUN || lamp->type == LA_HEMI) {
+ float zero = 0.0f;
+ GPU_link(mat, "convert_vec3_to_vec4", lv, GPU_uniform(&zero), &lamp_position);
+ }
+ else {
+ float one = 1.0f;
+ GPU_link(mat, "convert_vec3_to_vec4", GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), GPU_uniform(&one), &lamp_position);
+ }
- curvemapping_initialize(lamp->curfalloff);
- curvemapping_table_RGBA(lamp->curfalloff, &array, &size);
- GPU_link(mat, "lamp_falloff_curve",
- GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob),
- GPU_texture(size, array), *dist, &visifac);
+ /* Normal */
+ if (lamp->type == LA_AREA) {
+ float vec_z[3] = {0.0f, 0.0f, -1.0f};
+ GPU_link(mat, "direction_transform_m4v3", GPU_uniform(vec_z), GPU_dynamic_uniform((float*)lamp->dynmat, GPU_DYNAMIC_LAMP_DYNMAT, lamp->ob), &lamp_normal);
+ }
+ else {
+ GPU_link(mat, "set_rgb", lv, &lamp_normal);
+ }
- break;
+ /* Incoming */
+ GPU_link(mat, "set_rgb", lv, &lamp_incoming);
+
+ /* to pass the lamp coordinates to the lamp shadertree */
+ GPU_material_set_lamp_normal_link(mat, lamp_normal);
+ GPU_material_set_lamp_position_link(mat, lamp_position);
+ GPU_material_set_lamp_incoming_link(mat, lamp_incoming);
+
+ GPU_material_set_type(mat, GPU_MATERIAL_TYPE_LAMP);
+
+ ntreeGPUMaterialNodes(lamp->la->nodetree, mat, NODE_NEW_SHADING);
+ lamp->nl_lcol = GPU_material_get_output_link(mat);
+ GPU_material_empty_output_link(mat);
+
+ /* Correct sun Intensity */
+ if (lamp->type == LA_SUN || lamp->type == LA_HEMI) {
+ float factor = 100.0f;
+ GPU_link(mat, "shade_mul_value_v3", GPU_uniform(&factor), lamp->nl_lcol, &lamp->nl_lcol);
}
+
+ /* to switch light on and off */
+ GPU_link(mat, "shade_mul_value_v3", GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob), lamp->nl_lcol, &lamp->nl_lcol);
+
+ GPU_material_set_type(mat, type);
+ }
+ else {
+ GPU_link(mat, "set_rgb", GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), &lamp->nl_lcol);
}
- if (lamp->mode & LA_SPHERE)
- GPU_link(mat, "lamp_visibility_sphere",
- GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob),
- *dist, visifac, &visifac);
+ return lamp->nl_lcol;
+ // }
+}
- if (lamp->type == LA_SPOT) {
- GPUNodeLink *inpr;
+static GPUNodeLink *lamp_get_shadowfac(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink *vn, GPUNodeLink *lv)
+{
+ // if (lamp->use_realistic_lighting) {
- if (lamp->mode & LA_SQUARE) {
- mat->dynproperty |= DYN_LAMP_VEC | DYN_LAMP_IMAT;
- GPU_link(mat, "lamp_visibility_spot_square",
- GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob),
- GPU_dynamic_uniform((float *)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob),
- GPU_dynamic_uniform((float *)lamp->spotvec, GPU_DYNAMIC_LAMP_SPOTSCALE, lamp->ob), *lv, &inpr);
+ /* Optimisation only run once */
+ if (lamp->nl_shadfac)
+ return lamp->nl_shadfac;
+
+ if (GPU_lamp_has_shadow_buffer(lamp)) {
+ GPUNodeLink *inp;
+
+ mat->dynproperty |= DYN_LAMP_PERSMAT;
+ GPU_link(mat, "shade_inp", vn, lv, &inp);
+
+ if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
+ GPU_link(mat, "test_shadowbuf_vsm", GPU_builtin(GPU_VIEW_POSITION),
+ GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
+ GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
+ GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias), inp, &lamp->nl_shadfac);
}
else {
+ GPU_link(mat, "test_shadowbuf", GPU_builtin(GPU_VIEW_POSITION),
+ GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
+ GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
+ GPU_uniform(&lamp->bias), inp, &lamp->nl_shadfac);
+ }
+ }
+ else {
+ float one = 1.0f;
+ GPU_link(mat, "set_value", GPU_uniform(&one), &lamp->nl_shadfac);
+ }
+
+ return lamp->nl_shadfac;
+ // }
+}
+
+static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **lv, GPUNodeLink **dist)
+{
+ if (lamp->use_realistic_lighting) {
+
+ /* Optimisation only run once */
+ if (lamp->nl_lv)
+ *lv = lamp->nl_lv;
+ if (lamp->nl_dist)
+ *dist = lamp->nl_dist;
+ if (lamp->nl_visifac)
+ return lamp->nl_visifac;
+
+ /* Cycles Lamp */
+ if (lamp->type == LA_SUN || lamp->type == LA_HEMI) {
+ float sun_fac = 1.0f;
+ mat->dynproperty |= DYN_LAMP_VEC;
+ GPU_link(mat, "lamp_visibility_sun_hemi", GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), &lamp->nl_lv, &lamp->nl_dist, &lamp->nl_visifac);
+ GPU_link(mat, "set_value", GPU_uniform(&sun_fac), &lamp->nl_visifac);
+ *lv = lamp->nl_lv;
+ *dist = lamp->nl_dist;
+ return lamp->nl_visifac;
+ }
+ else {
+ mat->dynproperty |= DYN_LAMP_CO;
+ GPU_link(mat, "lamp_visibility_other", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), &lamp->nl_lv, &lamp->nl_dist, &lamp->nl_visifac);
+
+ if (lamp->type == LA_AREA) {
+ mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_CO|DYN_LAMP_MAT;
+ *lv = lamp->nl_lv;
+ *dist = lamp->nl_dist;
+ return lamp->nl_visifac;
+ }
+
+ if (lamp->type == LA_SPOT) {
+ GPUNodeLink *inpr;
+
mat->dynproperty |= DYN_LAMP_VEC | DYN_LAMP_IMAT;
GPU_link(mat, "lamp_visibility_spot_circle",
GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob),
- GPU_dynamic_uniform((float *)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob),
- GPU_dynamic_uniform((float *)lamp->spotvec, GPU_DYNAMIC_LAMP_SPOTSCALE, lamp->ob), *lv, &inpr);
+ GPU_dynamic_uniform((float *)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob),
+ GPU_dynamic_uniform((float *)lamp->spotvec, GPU_DYNAMIC_LAMP_SPOTSCALE, lamp->ob), lamp->nl_lv, &inpr);
+ GPU_link(mat, "lamp_visibility_spot",
+ GPU_dynamic_uniform(&lamp->spotsi, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob),
+ GPU_dynamic_uniform(&lamp->spotbl, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob),
+ inpr, lamp->nl_visifac, &lamp->nl_visifac);
}
-
- GPU_link(mat, "lamp_visibility_spot",
- GPU_dynamic_uniform(&lamp->spotsi, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob),
- GPU_dynamic_uniform(&lamp->spotbl, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob),
- inpr, visifac, &visifac);
+
+
+ *lv = lamp->nl_lv;
+ *dist = lamp->nl_dist;
+ return lamp->nl_visifac;
}
+ }
+ else {
+ GPUNodeLink *visifac;
+
+ /* BI Lamp */
+ if (lamp->type == LA_SUN || lamp->type == LA_HEMI) {
+ mat->dynproperty |= DYN_LAMP_VEC;
+ GPU_link(mat, "lamp_visibility_sun_hemi",
+ GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), lv, dist, &visifac);
+ return visifac;
+ }
+ else {
+ mat->dynproperty |= DYN_LAMP_CO;
+ GPU_link(mat, "lamp_visibility_other",
+ GPU_builtin(GPU_VIEW_POSITION),
+ GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), lv, dist, &visifac);
+
+ if (lamp->type == LA_AREA)
+ return visifac;
+
+ switch (lamp->falloff_type) {
+ case LA_FALLOFF_CONSTANT:
+ break;
+ case LA_FALLOFF_INVLINEAR:
+ GPU_link(mat, "lamp_falloff_invlinear",
+ GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac);
+ break;
+ case LA_FALLOFF_INVSQUARE:
+ GPU_link(mat, "lamp_falloff_invsquare",
+ GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac);
+ break;
+ case LA_FALLOFF_SLIDERS:
+ GPU_link(mat, "lamp_falloff_sliders",
+ GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob),
+ GPU_dynamic_uniform(&lamp->att1, GPU_DYNAMIC_LAMP_ATT1, lamp->ob),
+ GPU_dynamic_uniform(&lamp->att2, GPU_DYNAMIC_LAMP_ATT2, lamp->ob), *dist, &visifac);
+ break;
+ case LA_FALLOFF_INVCOEFFICIENTS:
+ GPU_link(mat, "lamp_falloff_invcoefficients",
+ GPU_dynamic_uniform(&lamp->coeff_const, GPU_DYNAMIC_LAMP_COEFFCONST, lamp->ob),
+ GPU_dynamic_uniform(&lamp->coeff_lin, GPU_DYNAMIC_LAMP_COEFFLIN, lamp->ob),
+ GPU_dynamic_uniform(&lamp->coeff_quad, GPU_DYNAMIC_LAMP_COEFFQUAD, lamp->ob), *dist, &visifac);
+ break;
+ case LA_FALLOFF_CURVE:
+ {
+ float *array;
+ int size;
+
+ curvemapping_initialize(lamp->curfalloff);
+ curvemapping_table_RGBA(lamp->curfalloff, &array, &size);
+ GPU_link(mat, "lamp_falloff_curve",
+ GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob),
+ GPU_texture(size, array), *dist, &visifac);
+
+ break;
+ }
+ }
+
+ if (lamp->mode & LA_SPHERE)
+ GPU_link(mat, "lamp_visibility_sphere",
+ GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob),
+ *dist, visifac, &visifac);
+
+ if (lamp->type == LA_SPOT) {
+ GPUNodeLink *inpr;
- GPU_link(mat, "lamp_visibility_clamp", visifac, &visifac);
+ if (lamp->mode & LA_SQUARE) {
+ mat->dynproperty |= DYN_LAMP_VEC | DYN_LAMP_IMAT;
+ GPU_link(mat, "lamp_visibility_spot_square",
+ GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob),
+ GPU_dynamic_uniform((float *)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob),
+ GPU_dynamic_uniform((float *)lamp->spotvec, GPU_DYNAMIC_LAMP_SPOTSCALE, lamp->ob), *lv, &inpr);
+ }
+ else {
+ mat->dynproperty |= DYN_LAMP_VEC | DYN_LAMP_IMAT;
+ GPU_link(mat, "lamp_visibility_spot_circle",
+ GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob),
+ GPU_dynamic_uniform((float *)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob),
+ GPU_dynamic_uniform((float *)lamp->spotvec, GPU_DYNAMIC_LAMP_SPOTSCALE, lamp->ob), *lv, &inpr);
+ }
+
+ GPU_link(mat, "lamp_visibility_spot",
+ GPU_dynamic_uniform(&lamp->spotsi, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob),
+ GPU_dynamic_uniform(&lamp->spotbl, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob),
+ inpr, visifac, &visifac);
+ }
+
+ GPU_link(mat, "lamp_visibility_clamp", visifac, &visifac);
- return visifac;
+ return visifac;
+ }
}
}
@@ -812,7 +1318,7 @@ static void shade_light_textures(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **
GPU_link(mat, "shade_light_texture",
GPU_builtin(GPU_VIEW_POSITION),
- GPU_image(mtex->tex->ima, &mtex->tex->iuser, false),
+ GPU_image(mtex->tex->ima, &mtex->tex->iuser, false, false),
GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
&tex_rgb);
texture_rgb_blend(mat, tex_rgb, *rgb, GPU_uniform(&one), GPU_uniform(&mtex->colfac), mtex->blendtype, rgb);
@@ -858,9 +1364,9 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
GPU_builtin(GPU_VIEW_POSITION),
GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob),
GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), vn,
- GPU_uniform((float *)area),
- GPU_uniform(&areasize),
- GPU_uniform(&lamp->k), &inp);
+ GPU_dynamic_uniform((float*)lamp->dynmat, GPU_DYNAMIC_LAMP_DYNMAT, lamp->ob),
+ GPU_dynamic_uniform(&lamp->area_size, GPU_DYNAMIC_LAMP_SIZEX, lamp->ob),
+ GPU_dynamic_uniform(&lamp->area_size_y, GPU_DYNAMIC_LAMP_SIZEY, lamp->ob), &inp);
}
is = inp; /* Lambert */
@@ -992,8 +1498,6 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
GPU_uniform(&ma->param[2]), GPU_uniform(&ma->param[3]), &specfac);
}
- if (lamp->type == LA_AREA)
- GPU_link(mat, "shade_spec_area_inp", specfac, inp, &specfac);
GPU_link(mat, "shade_spec_t", shadfac, shi->spec, visifac, specfac, &t);
@@ -1018,12 +1522,13 @@ static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr)
{
Base *base;
Scene *sce_iter;
-
+ bool use_realistic_preview = BKE_scene_use_new_shading_nodes(shi->gpumat->scene);
+
for (SETLOOPER(shi->gpumat->scene, sce_iter, base)) {
Object *ob = base->object;
if (ob->type == OB_LAMP) {
- GPULamp *lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob, NULL);
+ GPULamp *lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob, NULL, use_realistic_preview);
if (lamp)
shade_one_light(shi, shr, lamp);
}
@@ -1039,7 +1544,7 @@ static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr)
copy_m4_m4(omat, ob_iter->obmat);
copy_m4_m4(ob_iter->obmat, dob->mat);
- GPULamp *lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob_iter, ob);
+ GPULamp *lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob_iter, ob, use_realistic_preview);
if (lamp)
shade_one_light(shi, shr, lamp);
@@ -1245,7 +1750,7 @@ static void do_material_tex(GPUShadeInput *shi)
((tex->type == TEX_ENVMAP) && (mtex->texco == TEXCO_REFL))))
{
if (tex->type == TEX_IMAGE) {
- GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false), &tin, &trgb);
+ GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false, false), &tin, &trgb);
}
else {
GPU_link(mat, "mtex_cube_map_refl",
@@ -1345,7 +1850,7 @@ static void do_material_tex(GPUShadeInput *shi)
if (tex->imaflag & TEX_NORMALMAP) {
/* normalmap image */
- GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser, true), &tnor);
+ GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser, true, false), &tnor);
if (mtex->norfac < 0.0f)
GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor);
@@ -1492,27 +1997,27 @@ static void do_material_tex(GPUShadeInput *shi)
if (found_deriv_map) {
GPU_link(mat, "mtex_bump_deriv",
- texco, GPU_image(tex->ima, &tex->iuser, true),
+ texco, GPU_image(tex->ima, &tex->iuser, true, false),
GPU_uniform(&ima_x), GPU_uniform(&ima_y), tnorfac,
&dBs, &dBt);
}
else if (mtex->texflag & MTEX_3TAP_BUMP)
GPU_link(mat, "mtex_bump_tap3",
- texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
+ texco, GPU_image(tex->ima, &tex->iuser, true, false), tnorfac,
&dBs, &dBt);
else if (mtex->texflag & MTEX_5TAP_BUMP)
GPU_link(mat, "mtex_bump_tap5",
- texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
+ texco, GPU_image(tex->ima, &tex->iuser, true, false), tnorfac,
&dBs, &dBt);
else if (mtex->texflag & MTEX_BICUBIC_BUMP) {
if (GPU_bicubic_bump_support()) {
GPU_link(mat, "mtex_bump_bicubic",
- texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
+ texco, GPU_image(tex->ima, &tex->iuser, true, false), tnorfac,
&dBs, &dBt);
}
else {
GPU_link(mat, "mtex_bump_tap5",
- texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
+ texco, GPU_image(tex->ima, &tex->iuser, true, false), tnorfac,
&dBs, &dBt);
}
}
@@ -1522,7 +2027,7 @@ static void do_material_tex(GPUShadeInput *shi)
float imag_tspace_dimension_y = aspect * imag_tspace_dimension_x;
GPU_link(mat, "mtex_bump_apply_texspace",
fDet, dBs, dBt, vR1, vR2,
- GPU_image(tex->ima, &tex->iuser, true), texco,
+ GPU_image(tex->ima, &tex->iuser, true, false), texco,
GPU_uniform(&imag_tspace_dimension_x),
GPU_uniform(&imag_tspace_dimension_y), vNacc,
&vNacc, &shi->vn);
@@ -1824,6 +2329,464 @@ void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr)
}
}
+/* PBR Viewport Material Mode */
+
+void GPU_brdf_input_initialize(GPUBrdfInput *brdf)
+{
+ memset(brdf, 0, sizeof(*brdf));
+}
+
+static void prep_brdf_input(GPUBrdfInput *brdf)
+{
+ GPUNodeLink *normal = NULL;
+ GPUNodeLink *color = NULL;
+ GPUNodeLink *roughness = NULL;
+ GPUNodeLink *ior = NULL;
+ GPUNodeLink *sigma = NULL;
+ GPUNodeLink *toon_size = NULL;
+ GPUNodeLink *toon_smooth = NULL;
+ GPUNodeLink *anisotropy = NULL;
+ GPUNodeLink *aniso_rotation = NULL;
+ GPUNodeLink *aniso_tangent = NULL;
+
+ /* Normal & Tangent can't be NULL */
+ if (brdf->normal)
+ GPU_link(brdf->mat, "set_rgb", brdf->normal, &normal);
+ else
+ GPU_link(brdf->mat, "set_rgb", GPU_builtin(GPU_VIEW_NORMAL), &normal);
+
+ if (brdf->aniso_tangent)
+ GPU_link(brdf->mat, "set_rgb", brdf->aniso_tangent, &aniso_tangent);
+ else
+ GPU_link(brdf->mat, "default_tangent", GPU_builtin(GPU_VIEW_NORMAL), GPU_attribute(CD_ORCO, ""),
+ GPU_builtin(GPU_OBJECT_MATRIX), GPU_builtin(GPU_VIEW_MATRIX),
+ GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &aniso_tangent);
+
+ if (brdf->color)
+ GPU_link(brdf->mat, "set_rgba", brdf->color, &color);
+ else
+ GPU_link(brdf->mat, "set_rgba_zero", &color);
+
+ if (brdf->roughness)
+ GPU_link(brdf->mat, "set_value", brdf->roughness, &roughness);
+ else
+ GPU_link(brdf->mat, "set_value_zero", &roughness);
+
+ if (brdf->ior)
+ GPU_link(brdf->mat, "set_value", brdf->ior, &ior);
+ else
+ GPU_link(brdf->mat, "set_value_zero", &ior);
+
+ if (brdf->sigma)
+ GPU_link(brdf->mat, "set_value", brdf->sigma, &sigma);
+ else
+ GPU_link(brdf->mat, "set_value_zero", &sigma);
+
+ if (brdf->toon_size)
+ GPU_link(brdf->mat, "set_value", brdf->toon_size, &toon_size);
+ else
+ GPU_link(brdf->mat, "set_value_zero", &toon_size);
+
+ if (brdf->toon_smooth)
+ GPU_link(brdf->mat, "set_value", brdf->toon_smooth, &toon_smooth);
+ else
+ GPU_link(brdf->mat, "set_value_zero", &toon_smooth);
+
+ if (brdf->anisotropy)
+ GPU_link(brdf->mat, "set_value", brdf->anisotropy, &anisotropy);
+ else
+ GPU_link(brdf->mat, "set_value_zero", &anisotropy);
+
+ if (brdf->aniso_rotation)
+ GPU_link(brdf->mat, "set_value", brdf->aniso_rotation, &aniso_rotation);
+ else
+ GPU_link(brdf->mat, "set_value_zero", &aniso_rotation);
+
+ GPU_link(brdf->mat, "set_rgba_zero", &brdf->output);
+
+ brdf->normal = normal;
+ brdf->color = color;
+ brdf->roughness = roughness;
+ brdf->ior = ior;
+ brdf->sigma = sigma;
+ brdf->toon_size = toon_size;
+ brdf->toon_smooth = toon_smooth;
+ brdf->anisotropy = anisotropy;
+ brdf->aniso_rotation = aniso_rotation;
+ brdf->aniso_tangent = aniso_tangent;
+}
+
+static bool do_light(GPUBrdfInput *brdf, GPULamp *lamp)
+{
+ if (lamp->mode & LA_NO_DIFF)
+ if (brdf->type == GPU_BRDF_DIFFUSE || brdf->type == GPU_BRDF_TRANSLUCENT)
+ return false;
+
+ if (lamp->mode & LA_NO_SPEC)
+ if (!(brdf->type == GPU_BRDF_DIFFUSE || brdf->type == GPU_BRDF_TRANSLUCENT))
+ return false;
+
+ return true;
+}
+
+static const char *brdf_light_function(GPUBrdfType brdftype, int lamptype)
+{
+ if (brdftype == GPU_BRDF_ANISO_GGX) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_anisotropic_ggx_sun_light";
+ case LA_AREA : return "bsdf_anisotropic_ggx_area_light";
+ default : return "bsdf_anisotropic_ggx_sphere_light";
+ }
+ }
+ else if (brdftype == GPU_BRDF_ANISO_BECKMANN) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_anisotropic_beckmann_sun_light";
+ case LA_AREA : return "bsdf_anisotropic_beckmann_area_light";
+ default : return "bsdf_anisotropic_beckmann_sphere_light";
+ }
+ }
+ else if (brdftype == GPU_BRDF_ANISO_ASHIKHMIN_SHIRLEY) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_anisotropic_ashikhmin_shirley_sun_light";
+ case LA_AREA : return "bsdf_anisotropic_ashikhmin_shirley_area_light";
+ default : return "bsdf_anisotropic_ashikhmin_shirley_sphere_light";
+ }
+ }
+ else if (brdftype == GPU_BRDF_GLOSSY_GGX) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_glossy_ggx_sun_light";
+ case LA_AREA : return "bsdf_glossy_ggx_area_light";
+ default : return "bsdf_glossy_ggx_sphere_light";
+ }
+ }
+ else if (brdftype == GPU_BRDF_GLOSSY_BECKMANN) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_glossy_beckmann_sun_light";
+ case LA_AREA : return "bsdf_glossy_beckmann_area_light";
+ default : return "bsdf_glossy_beckmann_sphere_light";
+ }
+ }
+ else if (brdftype == GPU_BRDF_GLOSSY_ASHIKHMIN_SHIRLEY) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_glossy_ashikhmin_shirley_sun_light";
+ case LA_AREA : return "bsdf_glossy_ashikhmin_shirley_area_light";
+ default : return "bsdf_glossy_ashikhmin_shirley_sphere_light";
+ }
+ }
+ else if (brdftype == GPU_BRDF_GLOSSY_SHARP) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_glossy_sharp_sun_light";
+ case LA_AREA : return "bsdf_glossy_sharp_area_light";
+ default : return "bsdf_glossy_sharp_sphere_light";
+ }
+ }
+ else if (brdftype == GPU_BRDF_REFRACT_GGX) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_refract_ggx_sun_light";
+ case LA_AREA : return "bsdf_refract_ggx_area_light";
+ default : return "bsdf_refract_ggx_sphere_light";
+ }
+ }
+ else if (brdftype == GPU_BRDF_REFRACT_BECKMANN) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_refract_beckmann_sun_light";
+ case LA_AREA : return "bsdf_refract_beckmann_area_light";
+ default : return "bsdf_refract_beckmann_sphere_light";
+ }
+ }
+ else if (brdftype == GPU_BRDF_REFRACT_SHARP) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_refract_sharp_sun_light";
+ case LA_AREA : return "bsdf_refract_sharp_area_light";
+ default : return "bsdf_refract_sharp_sphere_light";
+ }
+ }
+ else if (brdftype == GPU_BRDF_GLASS_GGX) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_glass_ggx_sun_light";
+ case LA_AREA : return "bsdf_glass_ggx_area_light";
+ default : return "bsdf_glass_ggx_sphere_light";
+ }
+ }
+ else if (brdftype == GPU_BRDF_GLASS_BECKMANN) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_glass_beckmann_sun_light";
+ case LA_AREA : return "bsdf_glass_beckmann_area_light";
+ default : return "bsdf_glass_beckmann_sphere_light";
+ }
+ }
+ else if (brdftype == GPU_BRDF_GLASS_SHARP) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_glass_sharp_sun_light";
+ case LA_AREA : return "bsdf_glass_sharp_area_light";
+ default : return "bsdf_glass_sharp_sphere_light";
+ }
+ }
+ else if (brdftype == GPU_BRDF_VELVET) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_velvet_sun_light";
+ case LA_AREA : return "bsdf_velvet_area_light";
+ default : return "bsdf_velvet_sphere_light";
+ }
+ }
+ else if (brdftype == GPU_BRDF_TRANSLUCENT) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_translucent_sun_light";
+ case LA_AREA : return "bsdf_translucent_area_light";
+ default : return "bsdf_translucent_sphere_light";
+ }
+ }
+ else if (brdftype == GPU_BRDF_TOON_DIFFUSE) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_toon_diffuse_sun_light";
+ case LA_AREA : return "bsdf_toon_diffuse_area_light";
+ default : return "bsdf_toon_diffuse_sphere_light";
+ }
+ }
+ else if (brdftype == GPU_BRDF_TOON_GLOSSY) {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_toon_glossy_sun_light";
+ case LA_AREA : return "bsdf_toon_glossy_area_light";
+ default : return "bsdf_toon_glossy_sphere_light";
+ }
+ }
+ else /* (brdftype == GPU_BRDF_DIFFUSE) */ {
+ switch (lamptype) {
+ case LA_SUN :
+ case LA_HEMI : return "bsdf_diffuse_sun_light";
+ case LA_AREA : return "bsdf_diffuse_area_light";
+ default : return "bsdf_diffuse_sphere_light";
+ }
+ }
+}
+
+static void shade_one_brdf_light(GPUBrdfInput *brdf, GPULamp *lamp)
+{
+ GPUMaterial *mat = brdf->mat;
+ GPUNodeLink *lv = NULL, *dist = NULL, *visifac = NULL, *vn = NULL, *view = NULL;
+ GPUNodeLink *shadfac = NULL, *lcol, *output;
+ float one = 1.0f;
+
+ /* Early out */
+ if (!do_light(brdf, lamp)) return;
+
+ /* Lamp vector, distance and visibility factor */
+ visifac = lamp_get_visibility(mat, lamp, &lv, &dist);
+
+ /* View Position */
+ if (((brdf->type == GPU_BRDF_TRANSLUCENT ||
+ brdf->type == GPU_BRDF_DIFFUSE ||
+ brdf->type == GPU_BRDF_GLOSSY_GGX ||
+ brdf->type == GPU_BRDF_GLOSSY_ASHIKHMIN_SHIRLEY ||
+ brdf->type == GPU_BRDF_GLOSSY_BECKMANN) && (lamp->type == LA_AREA)) ||
+ ((brdf->type == GPU_BRDF_GLOSSY_GGX ||
+ brdf->type == GPU_BRDF_REFRACT_GGX ||
+ brdf->type == GPU_BRDF_GLASS_GGX) && (lamp->type == LA_LOCAL || lamp->type == LA_SPOT)))
+ GPU_link(mat, "set_rgb", GPU_builtin(GPU_VIEW_POSITION), &view);
+ else
+ GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &view);
+
+ /* View normal */
+ GPU_link(mat, "viewN_to_shadeN", brdf->normal, &vn);
+
+ /* Lamp Color */
+ lcol = lamp_get_lightcolor(mat, lamp, lv);
+
+ /* BRDF evaluation */
+ GPU_link(mat, brdf_light_function(brdf->type, lamp->type),
+ vn, brdf->aniso_tangent, lv, view,
+ GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), dist,
+ GPU_dynamic_uniform(&lamp->area_size, GPU_DYNAMIC_LAMP_SIZEX, lamp->ob),
+ GPU_dynamic_uniform(&lamp->area_size_y, GPU_DYNAMIC_LAMP_SIZEY, lamp->ob),
+ GPU_dynamic_uniform((float *)lamp->areavec, GPU_DYNAMIC_LAMP_AREASCALE, lamp->ob),
+ GPU_dynamic_uniform((float *)lamp->dynmat, GPU_DYNAMIC_LAMP_DYNMAT, lamp->ob),
+ brdf->roughness, brdf->ior, brdf->sigma, brdf->toon_size, brdf->toon_smooth, brdf->anisotropy, brdf->aniso_rotation, &output);
+
+
+ /* Shadowing */
+ if (brdf->type != GPU_BRDF_REFRACT_GGX &&
+ brdf->type != GPU_BRDF_GLASS_GGX &&
+ brdf->type != GPU_BRDF_REFRACT_SHARP &&
+ brdf->type != GPU_BRDF_GLASS_SHARP &&
+ brdf->type != GPU_BRDF_TRANSLUCENT) {
+ shadfac = lamp_get_shadowfac(mat, lamp, vn, lv);
+ }
+ else {
+ float one = 1.0f;
+ GPU_link(mat, "set_value", GPU_uniform(&one), &shadfac);
+ }
+
+ /* Applying shadow and lamp color */
+ GPU_link(mat, "shade_mul_value", shadfac, lcol, &lcol);
+ GPU_link(mat, "shade_mul_value", visifac, lcol, &lcol);
+ GPU_link(mat, "shade_madd_clamped", brdf->output, output, lcol, &brdf->output);
+
+ add_user_list(&mat->lamps, lamp);
+ add_user_list(&lamp->materials, mat->ma);
+}
+
+static const char *brdf_env_sampling_function(GPUBrdfType brdftype)
+{
+ if (brdftype == GPU_BRDF_ANISO_GGX)
+ return "env_sampling_aniso_ggx";
+ else if (brdftype == GPU_BRDF_ANISO_BECKMANN)
+ return "env_sampling_aniso_beckmann";
+ else if (brdftype == GPU_BRDF_ANISO_ASHIKHMIN_SHIRLEY)
+ return "env_sampling_aniso_ashikhmin_shirley";
+ else if (brdftype == GPU_BRDF_GLOSSY_GGX)
+ return "env_sampling_glossy_ggx";
+ else if (brdftype == GPU_BRDF_GLOSSY_BECKMANN)
+ return "env_sampling_glossy_beckmann";
+ else if (brdftype == GPU_BRDF_GLOSSY_ASHIKHMIN_SHIRLEY)
+ return "env_sampling_glossy_ashikhmin_shirley";
+ else if (brdftype == GPU_BRDF_GLOSSY_SHARP)
+ return "env_sampling_glossy_sharp";
+ else if (brdftype == GPU_BRDF_REFRACT_GGX)
+ return "env_sampling_refract_ggx";
+ else if (brdftype == GPU_BRDF_REFRACT_BECKMANN)
+ return "env_sampling_refract_beckmann";
+ else if (brdftype == GPU_BRDF_REFRACT_SHARP)
+ return "env_sampling_refract_sharp";
+ else if (brdftype == GPU_BRDF_GLASS_GGX)
+ return "env_sampling_glass_ggx";
+ else if (brdftype == GPU_BRDF_GLASS_BECKMANN)
+ return "env_sampling_glass_beckmann";
+ else if (brdftype == GPU_BRDF_GLASS_SHARP)
+ return "env_sampling_glass_sharp";
+ else if (brdftype == GPU_BRDF_VELVET)
+ return "env_sampling_velvet";
+ else if (brdftype == GPU_BRDF_TRANSLUCENT)
+ return "env_sampling_translucent";
+ else if (brdftype == GPU_BRDF_TRANSPARENT)
+ return "env_sampling_transparent";
+ else if (brdftype == GPU_BRDF_TOON_DIFFUSE)
+ return "env_sampling_toon_diffuse";
+ else if (brdftype == GPU_BRDF_TOON_GLOSSY)
+ return "env_sampling_toon_glossy";
+ else if (brdftype == GPU_BRDF_AMBIENT_OCCLUSION)
+ return "env_sampling_ambient_occlusion";
+ else /* (brdftype == GPU_BRDF_DIFFUSE) */
+ return "env_sampling_diffuse";
+}
+
+static GPUNodeLink *brdf_sample_env(GPUBrdfInput *brdf)
+{
+ GPUMaterial *mat = brdf->mat;
+ GPUMatType type = GPU_material_get_type(mat);
+ GPUNodeLink *envlight, *ambient_occlusion;
+
+ GPU_link(mat, "direction_transform_m4v3", brdf->normal, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &brdf->normal);
+ GPU_link(mat, "vect_normalize", brdf->normal, &brdf->normal);
+ GPU_link(mat, "direction_transform_m4v3", brdf->aniso_tangent, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &brdf->aniso_tangent);
+ GPU_link(mat, "vect_normalize", brdf->aniso_tangent, &brdf->aniso_tangent);
+
+ /* Ambient Occlusion */
+ if (!mat->ln_ssao)
+ GPU_link(mat, "ssao", GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL), &mat->ln_ssao);
+ GPU_link(mat, "set_value", mat->ln_ssao, &ambient_occlusion);
+
+ /* Environment Sampling */
+ GPU_link(mat, brdf_env_sampling_function(brdf->type),
+ GPU_builtin(GPU_PBR), GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_VIEW_MATRIX),
+ brdf->normal, brdf->aniso_tangent, brdf->roughness, brdf->ior, brdf->sigma,
+ brdf->toon_size, brdf->toon_smooth, brdf->anisotropy, brdf->aniso_rotation,
+ ambient_occlusion, &envlight);
+
+ /* prevent undefined result (eg dividing by 0) giving infinity inside HDR images */
+ GPU_link(mat, "shade_clamp_positive", envlight, &envlight);
+
+ return envlight;
+}
+
+void GPU_shade_BRDF(GPUBrdfInput *brdf)
+{
+ Scene *scene = GPU_material_scene(brdf->mat);
+ GPUMaterial *mat = brdf->mat;
+ World *wo = scene->world;
+ Base *base;
+ Object *ob;
+ Scene *sce_iter;
+ GPULamp *lamp;
+ GPUNodeLink *envlight;
+ float one = 1.0f;
+ int i = 0;
+ bool real_shading = GPU_material_use_new_shading_nodes(mat);
+
+ prep_brdf_input(brdf);
+
+ /* Early out
+ * If there is already a valid output do not attempt to do the world sampling.
+ * Because the output would be overwriten when sampling the world.
+ * This save also some steps. */
+ if (GPU_material_get_output_link(mat))
+ return;
+
+ /* Lamps */
+ if ((brdf->type != GPU_BRDF_TRANSPARENT) && (brdf->type != GPU_BRDF_AMBIENT_OCCLUSION)) {
+ for (SETLOOPER(mat->scene, sce_iter, base)) {
+ ob = base->object;
+
+ if (ob->type == OB_LAMP) {
+ lamp = GPU_lamp_from_blender(mat->scene, ob, NULL, real_shading);
+ if (lamp)
+ shade_one_brdf_light(brdf, lamp);
+ }
+
+ if (ob->transflag & OB_DUPLI) {
+ DupliObject *dob;
+ ListBase *lb = object_duplilist(G.main->eval_ctx, mat->scene, ob);
+
+ for (dob = lb->first; dob; dob = dob->next) {
+ Object *ob_iter = dob->ob;
+
+ if (ob_iter->type == OB_LAMP) {
+ float omat[4][4];
+ copy_m4_m4(omat, ob_iter->obmat);
+ copy_m4_m4(ob_iter->obmat, dob->mat);
+
+ lamp = GPU_lamp_from_blender(mat->scene, ob_iter, ob, real_shading);
+ if (lamp)
+ shade_one_brdf_light(brdf, lamp);
+
+ copy_m4_m4(ob_iter->obmat, omat);
+ }
+ }
+
+ free_object_duplilist(lb);
+ }
+ }
+ }
+
+ /* prevent only shadow lamps from producing negative colors.*/
+ GPU_link(mat, "shade_clamp_positive", brdf->output, &brdf->output);
+
+ /* Environement Light */
+ envlight = brdf_sample_env(brdf);
+
+ /* Combine Lighting */
+ if (brdf->type == GPU_BRDF_TRANSPARENT)
+ GPU_link(mat, "node_bsdf_transparent", brdf->color, envlight, &brdf->output);
+ else
+ GPU_link(mat, "node_bsdf_opaque", brdf->color, envlight, brdf->output, &brdf->output);
+}
+
static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma)
{
GPUShadeInput shi;
@@ -1838,10 +2801,28 @@ static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma)
static GPUNodeLink *gpu_material_diffuse_bsdf(GPUMaterial *mat, Material *ma)
{
static float roughness = 0.0f;
+ static float ambient[4] = {0.2f, 0.2f, 0.2f, 1.0f};
GPUNodeLink *outlink;
- GPU_link(mat, "node_bsdf_diffuse",
- GPU_uniform(&ma->r), GPU_uniform(&roughness), GPU_builtin(GPU_VIEW_NORMAL), &outlink);
+ if (GPU_material_get_type(mat) == GPU_MATERIAL_TYPE_MESH_REAL_SH) {
+ GPUBrdfInput brdf;
+
+ GPU_brdf_input_initialize(&brdf);
+
+ brdf.mat = mat;
+ brdf.type = GPU_BRDF_DIFFUSE;
+ brdf.color = GPU_uniform(&ma->r);
+ brdf.roughness = GPU_uniform(&roughness);
+ brdf.normal = GPU_builtin(GPU_VIEW_NORMAL);
+
+ GPU_shade_BRDF(&brdf);
+
+ outlink = brdf.output;
+ }
+ else
+ GPU_link(mat, "node_bsdf_diffuse_lights",
+ GPU_uniform(&ma->r), GPU_uniform(&roughness), GPU_builtin(GPU_VIEW_NORMAL),
+ GPU_builtin(GPU_VIEW_POSITION), GPU_uniform((float *)ambient), &outlink);
return outlink;
}
@@ -1881,6 +2862,8 @@ GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma, bool use_opensubdiv
mat->scene = scene;
mat->type = GPU_MATERIAL_TYPE_MESH;
mat->is_opensubdiv = use_opensubdiv;
+ mat->is_planar_probe = false;
+ mat->parallax_correc = 0;
if (ma->preview && ma->preview->rect[0]) {
outlink = gpu_material_preview_matcap(mat, ma);
@@ -1960,16 +2943,16 @@ static void do_world_tex(GPUShadeInput *shi, struct World *wo, GPUNodeLink **hor
if (ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f)
GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco);
if (mtex->texco == TEXCO_EQUIRECTMAP) {
- GPU_link(mat, "node_tex_environment_equirectangular", texco, GPU_image(tex->ima, &tex->iuser, false), &trgb);
+ GPU_link(mat, "node_tex_environment_equirectangular", texco, GPU_image(tex->ima, &tex->iuser, false, true), &trgb);
}
else if (mtex->texco == TEXCO_ANGMAP) {
- GPU_link(mat, "node_tex_environment_mirror_ball", texco, GPU_image(tex->ima, &tex->iuser, false), &trgb);
+ GPU_link(mat, "node_tex_environment_mirror_ball", texco, GPU_image(tex->ima, &tex->iuser, false, true), &trgb);
}
else {
if (tex->type == TEX_ENVMAP)
GPU_link(mat, "mtex_cube_map", texco, GPU_cube_map(tex->ima, &tex->iuser, false), &tin, &trgb);
else if (tex->type == TEX_IMAGE)
- GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false), &tin, &trgb);
+ GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false, false), &tin, &trgb);
}
rgbnor = TEX_RGB;
if (tex->type == TEX_IMAGE || tex->type == TEX_ENVMAP)
@@ -2110,7 +3093,7 @@ GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo)
mat = GPU_material_construct_begin(NULL);
mat->scene = scene;
mat->type = GPU_MATERIAL_TYPE_WORLD;
-
+
/* create nodes */
if (BKE_scene_use_new_shading_nodes(scene) && wo->nodetree && wo->use_nodes)
ntreeGPUMaterialNodes(wo->nodetree, mat, NODE_NEW_SHADING);
@@ -2135,17 +3118,26 @@ GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo)
return mat;
}
-
-GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma, bool use_opensubdiv)
+GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma, bool use_opensubdiv, bool use_realistic_preview, bool use_planar_probe,
+ bool use_alpha_as_depth, bool use_backface_depth, bool use_ssr, bool use_ssao, int parallax_correc)
{
GPUMaterial *mat;
GPUNodeLink *outlink;
LinkData *link;
+ int type = (use_realistic_preview)? GPU_MATERIAL_TYPE_MESH_REAL_SH : GPU_MATERIAL_TYPE_MESH;
+ bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene);
for (link = ma->gpumaterial.first; link; link = link->next) {
GPUMaterial *current_material = (GPUMaterial *)link->data;
if (current_material->scene == scene &&
- current_material->is_opensubdiv == use_opensubdiv)
+ current_material->is_opensubdiv == use_opensubdiv &&
+ current_material->type == type &&
+ current_material->is_alpha_as_depth == use_alpha_as_depth &&
+ current_material->is_planar_probe == use_planar_probe &&
+ current_material->use_backface_depth == use_backface_depth &&
+ current_material->use_ssr == use_ssr &&
+ current_material->use_ssao == use_ssao &&
+ current_material->parallax_correc == parallax_correc)
{
return current_material;
}
@@ -2154,16 +3146,43 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma, bool use_open
/* allocate material */
mat = GPU_material_construct_begin(ma);
mat->scene = scene;
- mat->type = GPU_MATERIAL_TYPE_MESH;
+ mat->type = type;
mat->is_opensubdiv = use_opensubdiv;
+ mat->parallax_correc = parallax_correc;
+ mat->is_planar_probe = use_planar_probe;
+ mat->is_alpha_as_depth = use_alpha_as_depth;
+ mat->use_backface_depth = use_backface_depth;
+ mat->use_ssr = use_ssr;
+ mat->use_ssao = use_ssao;
/* render pipeline option */
- bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene);
if (!new_shading_nodes && (ma->mode & MA_TRANSP))
GPU_material_enable_alpha(mat);
else if (new_shading_nodes && ma->alpha < 1.0f)
GPU_material_enable_alpha(mat);
+ /* Resetting all light optimisation nodelinks */
+ {
+ Base *base;
+ Scene *sce_iter;
+ Object *ob;
+ GPULamp *lamp;
+
+ for (SETLOOPER(mat->scene, sce_iter, base)) {
+ ob = base->object;
+ if (ob->type == OB_LAMP) {
+ lamp = GPU_lamp_from_blender(mat->scene, ob, NULL, new_shading_nodes);
+ if (lamp) {
+ lamp->nl_lv = NULL;
+ lamp->nl_dist = NULL;
+ lamp->nl_visifac = NULL;
+ lamp->nl_shadfac = NULL;
+ lamp->nl_lcol = NULL;
+ }
+ }
+ }
+ }
+
if (!(scene->gm.flag & GAME_GLSL_NO_NODES) && ma->nodetree && ma->use_nodes) {
/* create nodes */
if (new_shading_nodes)
@@ -2224,12 +3243,23 @@ void GPU_materials_free(void)
static void gpu_lamp_calc_winmat(GPULamp *lamp)
{
- float temp, angle, pixsize, wsize;
+ float temp, angle, pixsize, wsize, hsize;
if (lamp->type == LA_SUN) {
wsize = lamp->la->shadow_frustum_size;
orthographic_m4(lamp->winmat, -wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
}
+ else if (lamp->type == LA_AREA) {
+ wsize = hsize = lamp->area_size;
+
+ if (lamp->la->area_shape != LA_AREA_SQUARE)
+ hsize = lamp->area_size_y;
+
+ wsize *= lamp->areavec[0];
+ hsize *= lamp->areavec[1];
+
+ perspective_m4(lamp->winmat, -wsize, wsize, -hsize, hsize, lamp->d, lamp->d + lamp->clipend);
+ }
else if (lamp->type == LA_SPOT) {
angle = saacos(lamp->spotsi);
temp = 0.5f * lamp->size * cosf(angle) / sinf(angle);
@@ -2265,16 +3295,26 @@ void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4])
lamp->spotvec[1] = obmat_scale[1] / obmat_scale[2];
}
+ lamp->areavec[0] = obmat_scale[0];
+ lamp->areavec[1] = obmat_scale[1];
+
if (GPU_lamp_has_shadow_buffer(lamp)) {
/* makeshadowbuf */
gpu_lamp_calc_winmat(lamp);
}
}
+void GPU_lamp_update_size(GPULamp *lamp, float sizex, float sizey)
+{
+ lamp->area_size = sizex;
+ lamp->area_size_y = sizey;
+}
+
void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy)
{
lamp->energy = energy;
if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy;
+ if (BKE_scene_use_new_shading_nodes(lamp->scene)) lamp->energy = 1.0f;
lamp->col[0] = r;
lamp->col[1] = g;
@@ -2298,7 +3338,7 @@ void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend)
lamp->spotbl = (1.0f - lamp->spotsi) * spotblend;
}
-static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp)
+static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp, bool use_realistic_preview)
{
lamp->scene = scene;
lamp->ob = ob;
@@ -2309,6 +3349,9 @@ static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *l
lamp->mode = la->mode;
lamp->type = la->type;
+ lamp->area_size = la->area_size;
+ lamp->area_size_y = la->area_sizey;
+
lamp->energy = la->energy;
if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy;
@@ -2343,6 +3386,15 @@ static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *l
/* arbitrary correction for the fact we do no soft transition */
lamp->bias *= 0.25f;
+
+ if (use_realistic_preview) {
+ lamp->mode &= ~(LA_HALO | LA_NEG | LA_SPHERE | LA_SQUARE);
+ lamp->energy = 1.0f;
+ lamp->use_realistic_lighting = true;
+
+ if (la->area_shape == LA_AREA_SQUARE)
+ lamp->area_size_y = la->area_size;
+ }
}
static void gpu_lamp_shadow_free(GPULamp *lamp)
@@ -2369,7 +3421,7 @@ static void gpu_lamp_shadow_free(GPULamp *lamp)
}
}
-GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
+GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par, bool use_realistic_preview)
{
Lamp *la;
GPULamp *lamp;
@@ -2389,9 +3441,10 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
BLI_addtail(&ob->gpulamp, link);
la = ob->data;
- gpu_lamp_from_blender(scene, ob, par, la, lamp);
+ gpu_lamp_from_blender(scene, ob, par, la, lamp, use_realistic_preview);
- if ((la->type == LA_SPOT && (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY))) ||
+ if (((la->mode & (LA_SHAD_BUF | LA_SHAD_RAY)) && use_realistic_preview && (la->type == LA_SUN || la->type == LA_SPOT || la->type == LA_AREA)) ||
+ (la->type == LA_SPOT && (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY))) ||
(la->type == LA_SUN && (la->mode & LA_SHAD_RAY)))
{
/* opengl */
@@ -2402,6 +3455,7 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
}
if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
+
/* Shadow depth map */
lamp->depthtex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
if (!lamp->depthtex) {
@@ -2473,8 +3527,9 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
gpu_lamp_shadow_free(lamp);
- return lamp;
- }
+ return lamp;
+ }
+
}
GPU_framebuffer_restore();
@@ -2528,10 +3583,14 @@ bool GPU_lamp_has_shadow_buffer(GPULamp *lamp)
void GPU_lamp_update_buffer_mats(GPULamp *lamp)
{
- float rangemat[4][4], persmat[4][4];
+ float rangemat[4][4], persmat[4][4], tempmat[4][4];
/* initshadowbuf */
- invert_m4_m4(lamp->viewmat, lamp->obmat);
+ copy_m4_m4(tempmat, lamp->obmat);
+ if (lamp->type == LA_AREA) {
+ translate_m4(tempmat, 0.0, 0.0, lamp->d);
+ }
+ invert_m4_m4(lamp->viewmat, tempmat);
normalize_v3(lamp->viewmat[0]);
normalize_v3(lamp->viewmat[1]);
normalize_v3(lamp->viewmat[2]);
@@ -2572,6 +3631,10 @@ void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
GPU_shader_unbind();
GPU_framebuffer_blur(lamp->fb, lamp->tex, lamp->blurfb, lamp->blurtex);
+ if (lamp->use_realistic_lighting) {
+ /* XXX Second blur to hide artifacts */
+ GPU_framebuffer_blur(lamp->fb, lamp->tex, lamp->blurfb, lamp->blurtex);
+ }
}
GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex);
@@ -2673,7 +3736,7 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
int liblen, fraglen;
/* TODO(sergey): How to determine whether we need OSD or not here? */
- GPUMaterial *mat = GPU_material_from_blender(scene, ma, false);
+ GPUMaterial *mat = GPU_material_from_blender(scene, ma, false, false, false, false, false, false, false, 0);
GPUPass *pass = (mat) ? mat->pass : NULL;
if (pass && pass->fragmentcode && pass->vertexcode) {
diff --git a/source/blender/gpu/intern/gpu_pbr.c b/source/blender/gpu/intern/gpu_pbr.c
new file mode 100644
index 00000000000..de22739db4a
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_pbr.c
@@ -0,0 +1,327 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Clement Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/gpu/intern/gpu_pbr.c
+ * \ingroup gpu
+ *
+ * Manages lut textures and render passes for pbr rendering
+ */
+
+
+#include <math.h>
+#include <string.h>
+#include "MEM_guardedalloc.h"
+
+#include "DNA_gpu_types.h"
+
+#include "BLI_math.h"
+
+#include "GPU_texture.h"
+#include "GPU_framebuffer.h"
+#include "GPU_pbr.h"
+#include "GPU_draw.h"
+
+#include "gpu_codegen.h"
+
+#include <string.h>
+
+/* Structs */
+
+/* Functions */
+
+void GPU_scenebuf_free(GPUScreenBuffer *buf)
+{
+ if (buf->fb) {
+ GPU_framebuffer_free(buf->fb);
+ buf->fb = NULL;
+ }
+ if (buf->tex) {
+ GPU_texture_free(buf->tex);
+ buf->tex = NULL;
+ }
+ if (buf->depth) {
+ GPU_texture_free(buf->depth);
+ buf->depth = NULL;
+ }
+ if (buf->downsamplingfb) {
+ GPU_framebuffer_free(buf->downsamplingfb);
+ buf->downsamplingfb = NULL;
+ }
+
+ MEM_freeN(buf);
+}
+
+static GPUScreenBuffer *gpu_scenebuf_create(int width, int height, bool depth_only)
+{
+ GPUScreenBuffer *buf = MEM_callocN(sizeof(GPUScreenBuffer), "GPUScreenBuffer");
+
+ buf->w = width;
+ buf->h = height;
+ buf->depth = NULL;
+
+ buf->fb = GPU_framebuffer_create();
+ if (!buf->fb) {
+ GPU_scenebuf_free(buf);
+ return NULL;
+ }
+
+ /* DOWNSAMPLING FB */
+ buf->downsamplingfb = GPU_framebuffer_create();
+ if (!buf->downsamplingfb) {
+ GPU_scenebuf_free(buf);
+ return NULL;
+ }
+
+ if (depth_only) {
+ buf->tex = GPU_texture_create_depth_buffer(width, height, NULL);
+ if (!buf->tex) {
+ GPU_scenebuf_free(buf);
+ return NULL;
+ }
+
+ if (!GPU_framebuffer_texture_attach(buf->fb, buf->tex, 0, NULL)) {
+ GPU_scenebuf_free(buf);
+ return NULL;
+ }
+
+ /* check validity at the very end! */
+ if (!GPU_framebuffer_check_valid(buf->fb, NULL)) {
+ GPU_scenebuf_free(buf);
+ return NULL;
+ }
+ }
+ else {
+ buf->depth = GPU_texture_create_depth_buffer(width, height, NULL);
+ if (!buf->depth) {
+ GPU_scenebuf_free(buf);
+ return NULL;
+ }
+
+ if (!GPU_framebuffer_texture_attach(buf->fb, buf->depth, 0, NULL)) {
+ GPU_scenebuf_free(buf);
+ return NULL;
+ }
+
+ buf->tex = GPU_texture_create_2D(width, height, NULL, 1, NULL);
+ if (!buf->tex) {
+ GPU_scenebuf_free(buf);
+ return NULL;
+ }
+
+ if (!GPU_framebuffer_texture_attach(buf->fb, buf->tex, 0, NULL)) {
+ GPU_scenebuf_free(buf);
+ return NULL;
+ }
+
+ /* check validity at the very end! */
+ if (!GPU_framebuffer_check_valid(buf->fb, NULL)) {
+ GPU_scenebuf_free(buf);
+ return NULL;
+ }
+ }
+
+
+ GPU_framebuffer_restore();
+
+ return buf;
+}
+
+GPUScreenBuffer *GPU_pbr_scene_buffer(GPUPBR *pbr, int width, int height)
+{
+ if (pbr->scene) {
+ if ((pbr->scene->w == width) && (pbr->scene->h == height))
+ return pbr->scene;
+ else
+ GPU_scenebuf_free(pbr->scene);
+ }
+
+ pbr->scene = gpu_scenebuf_create(width, height, false);
+
+ return pbr->scene;
+}
+
+GPUScreenBuffer *GPU_pbr_backface_buffer(GPUPBR *pbr, int width, int height)
+{
+ if (pbr->backface) {
+ if ((pbr->backface->w == width) && (pbr->backface->h == height))
+ return pbr->backface;
+ else
+ GPU_scenebuf_free(pbr->backface);
+ }
+
+ pbr->backface = gpu_scenebuf_create(width, height, true);
+
+ return pbr->backface;
+}
+
+void GPU_scenebuf_bind(GPUScreenBuffer* buf, float winmat[4][4], int winsize[2], float clipsta, float clipend)
+{
+ glDisable(GL_SCISSOR_TEST);
+
+ GPU_texture_bind_as_framebuffer(buf->tex);
+
+ winsize[0] = buf->w;
+ winsize[1] = buf->h;
+
+ buf->clipsta = clipsta;
+ buf->clipend = clipend;
+
+ {
+ float uvpix[4][4], ndcuv[4][4], tmp[4][4];
+
+ /* NDC to UVs */
+ unit_m4(ndcuv);
+ ndcuv[0][0] = ndcuv[1][1] = ndcuv[3][0] = ndcuv[3][1] = 0.5f;
+
+ /* UVs to pixels */
+ unit_m4(uvpix);
+ uvpix[0][0] = buf->w;
+ uvpix[1][1] = buf->h;
+
+ mul_m4_m4m4(tmp, uvpix, ndcuv);
+ mul_m4_m4m4(buf->pixelprojmat, tmp, winmat);
+ }
+}
+
+void GPU_scenebuf_unbind(GPUScreenBuffer* buf)
+{
+ GPU_framebuffer_texture_unbind(buf->fb, buf->tex);
+ GPU_framebuffer_restore();
+ glEnable(GL_SCISSOR_TEST);
+}
+
+void GPU_scenebuf_filter_texture(GPUScreenBuffer* buf)
+{
+ /* MinZ Pyramid for depth */
+ if (buf->depth) {
+ GPU_texture_bind(buf->depth, 0);
+ GPU_generate_mipmap(GL_TEXTURE_2D);
+ GPU_texture_unbind(buf->depth);
+ GPU_framebuffer_hiz_construction(buf->downsamplingfb, buf->depth, false);
+ GPU_framebuffer_texture_attach(buf->fb, buf->depth, 0, NULL);
+ }
+ else {
+ GPU_texture_bind(buf->tex, 0);
+ GPU_generate_mipmap(GL_TEXTURE_2D);
+ GPU_texture_unbind(buf->tex);
+ GPU_framebuffer_hiz_construction(buf->downsamplingfb, buf->tex, true);
+ GPU_framebuffer_texture_attach(buf->fb, buf->tex, 0, NULL);
+ }
+
+ GPU_framebuffer_restore();
+}
+
+/* PBR core */
+
+GPUPBR *GPU_pbr_create(void)
+{
+ GPUPBR *pbr = MEM_callocN(sizeof(GPUPBR), "GPUPBR");
+
+ pbr->hammersley = GPU_create_hammersley_sample_texture(1024);
+ pbr->jitter = GPU_create_random_texture();
+ pbr->ltc_mat_ggx = GPU_create_ltc_mat_ggx_lut_texture();
+ pbr->ltc_mag_ggx = GPU_create_ltc_mag_ggx_lut_texture();
+
+ return pbr;
+}
+
+void GPU_pbr_free(GPUPBR *pbr)
+{
+ if (pbr->hammersley) {
+ GPU_texture_free(pbr->hammersley);
+ pbr->hammersley = NULL;
+ }
+ if (pbr->jitter) {
+ GPU_texture_free(pbr->jitter);
+ pbr->jitter = NULL;
+ }
+ if (pbr->ltc_mat_ggx) {
+ GPU_texture_free(pbr->ltc_mat_ggx);
+ pbr->ltc_mat_ggx = NULL;
+ }
+ if (pbr->ltc_mag_ggx) {
+ GPU_texture_free(pbr->ltc_mag_ggx);
+ pbr->ltc_mag_ggx = NULL;
+ }
+
+ if (pbr->scene) {
+ GPU_scenebuf_free(pbr->scene);
+ }
+
+ if (pbr->backface) {
+ GPU_scenebuf_free(pbr->backface);
+ }
+
+ MEM_freeN(pbr);
+}
+
+/* Settings */
+
+static void gpu_pbr_init_ssr_settings(GPUSSRSettings *ssr_settings)
+{
+ ssr_settings->attenuation = 6.0f;
+ ssr_settings->thickness = 0.2f;
+ ssr_settings->steps = 32;
+}
+
+static void gpu_pbr_init_ssao_settings(GPUSSAOSettings *ssao_settings)
+{
+ ssao_settings->factor = 1.0f;
+ ssao_settings->attenuation = 1.0f;
+ ssao_settings->distance_max = 0.2f;
+ ssao_settings->samples = 16;
+ ssao_settings->steps = 2;
+}
+
+static void gpu_pbr_init_brdf_settings(GPUBRDFSettings *brdf_settings)
+{
+ brdf_settings->lodbias = -0.5f;
+ brdf_settings->samples = 32;
+}
+
+void GPU_pbr_settings_validate(GPUPBRSettings *pbr_settings)
+{
+ if (pbr_settings->pbr_flag & GPU_PBR_FLAG_ENABLE) {
+ if (pbr_settings->brdf == NULL) {
+ GPUBRDFSettings *brdf_settings;
+ brdf_settings = pbr_settings->brdf = MEM_callocN(sizeof(GPUBRDFSettings), __func__);
+ gpu_pbr_init_brdf_settings(brdf_settings);
+ }
+
+ if ((pbr_settings->pbr_flag & GPU_PBR_FLAG_SSAO) && (pbr_settings->ssao == NULL)) {
+ GPUSSAOSettings *ssao_settings;
+ ssao_settings = pbr_settings->ssao = MEM_callocN(sizeof(GPUSSAOSettings), __func__);
+ gpu_pbr_init_ssao_settings(ssao_settings);
+ }
+
+ if ((pbr_settings->pbr_flag & GPU_PBR_FLAG_SSR) && (pbr_settings->ssr == NULL)) {
+ GPUSSRSettings *ssr_settings;
+ ssr_settings = pbr_settings->ssr = MEM_callocN(sizeof(GPUSSRSettings), __func__);
+ gpu_pbr_init_ssr_settings(ssr_settings);
+ }
+ }
+} \ No newline at end of file
diff --git a/source/blender/gpu/intern/gpu_probe.c b/source/blender/gpu/intern/gpu_probe.c
new file mode 100644
index 00000000000..e1f5583bccb
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_probe.c
@@ -0,0 +1,685 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Clement Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/gpu/intern/gpu_probe.c
+ * \ingroup gpu
+ *
+ * Manages screen space effects inside materials and
+ * the necessary buffers:
+ * - Screen space reflection
+ *
+ * NOTICE : These are not post process effects
+ */
+
+
+#include <math.h>
+#include <string.h>
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+#include "BLI_blenlib.h"
+
+#include "DNA_object_types.h"
+#include "DNA_world_types.h"
+#include "DNA_scene_types.h"
+
+#include "GPU_extensions.h"
+#include "GPU_framebuffer.h"
+#include "GPU_material.h"
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+#include "GPU_draw.h"
+#include "GPU_probe.h"
+
+#include "gpu_codegen.h"
+
+#include <string.h>
+
+/* Structs */
+
+
+/* Functions */
+
+static void gpu_probe_buffers_free(GPUProbe *probe)
+{
+ if (probe->shtex) {
+ GPU_texture_free(probe->shtex);
+ probe->shtex = NULL;
+ }
+ if (probe->fbsh) {
+ GPU_framebuffer_free(probe->fbsh);
+ probe->fbsh = NULL;
+ }
+ if (probe->tex) {
+ GPU_texture_free(probe->tex);
+ probe->tex = NULL;
+ }
+ if (probe->texreflect) {
+ GPU_texture_free(probe->texreflect);
+ probe->texreflect = NULL;
+ }
+ if (probe->texrefract) {
+ GPU_texture_free(probe->texrefract);
+ probe->texrefract = NULL;
+ }
+ if (probe->depthtex) {
+ GPU_texture_free(probe->depthtex);
+ probe->depthtex = NULL;
+ }
+ if (probe->fb) {
+ GPU_framebuffer_free(probe->fb);
+ probe->fb = NULL;
+ }
+}
+
+void GPU_probe_free(ListBase *gpuprobe)
+{
+ GPUProbe *probe;
+ LinkData *link;
+
+ for (link = gpuprobe->first; link; link = link->next) {
+ probe = (GPUProbe *)link->data;
+
+ gpu_probe_buffers_free(probe);
+
+ if (probe->shcoefs) {
+ MEM_freeN(probe->shcoefs);
+ }
+
+ MEM_freeN(probe);
+ }
+
+ BLI_freelistN(gpuprobe);
+}
+
+static void gpu_probe_from_blender(Scene *scene, World *wo, Object *ob, GPUProbe *probe)
+{
+ probe->scene = scene;
+ probe->wo = wo;
+ probe->ob = ob;
+ probe->clipsta = 0.01f;
+ probe->clipend = 1000.0f;
+
+ if (ob) {
+ probe->type = (ob->probetype == OB_PROBE_CUBEMAP) ? GPU_PROBE_CUBE : GPU_PROBE_PLANAR;
+ probe->size = ob->probesize;
+ }
+ else {
+ probe->type = GPU_PROBE_CUBE;
+ probe->size = wo->probesize;
+ }
+
+ /* prevent from having an invalid framebuffer */
+ CLAMP(probe->size, 4, 10240);
+
+ if (probe->type == GPU_PROBE_CUBE) {
+
+ /* Cubemap */
+ probe->fb = GPU_framebuffer_create();
+ if (!probe->fb) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+ probe->tex = GPU_texture_create_cube_probe(probe->size, NULL);
+ if (!probe->tex) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+ if (!GPU_framebuffer_cubeface_attach(probe->fb, probe->tex, 0, 0, NULL)) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+ /* depth texture */
+ probe->depthtex = GPU_texture_create_depth(probe->size, probe->size, NULL);
+ if (!probe->depthtex) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+ if (!GPU_framebuffer_texture_attach(probe->fb, probe->depthtex, 0, NULL)) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+ if (!GPU_framebuffer_check_valid(probe->fb, NULL)) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+
+ /* Spherical harmonic texture */
+ probe->fbsh = GPU_framebuffer_create();
+ if (!probe->fbsh) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+ probe->shtex = GPU_texture_create_sh_filter_target(NULL);
+ if (!probe->shtex) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+ if (!GPU_framebuffer_texture_attach(probe->fbsh, probe->shtex, 0, NULL)) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+ GPU_texture_bind_as_framebuffer(probe->shtex);
+
+ if (!GPU_framebuffer_check_valid(probe->fbsh, NULL)) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+ GPU_framebuffer_texture_unbind(probe->fbsh, probe->shtex);
+
+ }
+ else {
+
+ probe->fb = GPU_framebuffer_create();
+ if (!probe->fb) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+ /* Refraction */
+ probe->texrefract = GPU_texture_create_planar_probe(probe->size, NULL);
+ if (!probe->texrefract) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+ if (!GPU_framebuffer_texture_attach(probe->fb, probe->texrefract, 0, NULL)) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+ GPU_framebuffer_texture_detach(probe->texrefract);
+
+ /* Reflection */
+ probe->texreflect = GPU_texture_create_planar_probe(probe->size, NULL);
+ if (!probe->texreflect) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+ if (!GPU_framebuffer_texture_attach(probe->fb, probe->texreflect, 0, NULL)) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+ /* depth texture */
+ probe->depthtex = GPU_texture_create_depth(probe->size, probe->size, NULL);
+ if (!probe->depthtex) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+ if (!GPU_framebuffer_texture_attach(probe->fb, probe->depthtex, 0, NULL)) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+
+ if (!GPU_framebuffer_check_valid(probe->fb, NULL)) {
+ gpu_probe_buffers_free(probe);
+ return;
+ }
+ }
+
+ /* Setting up spherical harmonics coefs */
+ probe->shcoefs = MEM_mallocN(sizeof(float) * 9 * 3, "Probe Spherical Harmonics");
+ memset(probe->shcoefs, 0, sizeof(float) * 9 * 3); /* Avoid funky colors in the first reflection pass */
+
+ GPU_framebuffer_restore();
+
+ GPU_probe_set_update(probe, true);
+}
+
+GPUProbe *GPU_probe_world(Scene *scene, World *wo)
+{
+ GPUProbe *probe;
+ LinkData *link;
+
+ for (link = wo->gpuprobe.first; link; link = link->next)
+ if (((GPUProbe *)link->data)->scene == scene)
+ return link->data;
+
+ probe = MEM_callocN(sizeof(GPUProbe), "GPUProbe");
+
+ link = MEM_callocN(sizeof(LinkData), "GPUProbeLink");
+ link->data = probe;
+ BLI_addtail(&wo->gpuprobe, link);
+
+ gpu_probe_from_blender(scene, wo, NULL, probe);
+
+ return probe;
+}
+
+GPUProbe *GPU_probe_object(Scene *scene, Object *ob)
+{
+ GPUProbe *probe;
+ LinkData *link;
+
+ for (link = ob->gpuprobe.first; link; link = link->next) {
+ probe = (GPUProbe *)link->data;
+ if (probe->scene == scene)
+ return link->data;
+ }
+
+ probe = MEM_callocN(sizeof(GPUProbe), "GPUProbe");
+
+ link = MEM_callocN(sizeof(LinkData), "GPUProbeLink");
+ link->data = probe;
+ BLI_addtail(&ob->gpuprobe, link);
+
+ gpu_probe_from_blender(scene, NULL, ob, probe);
+
+ return probe;
+}
+
+static void envmap_transmatrix(float mat[4][4], int part)
+{
+ float tmat[4][4], tmat2[4][4], eul1[3], eul2[3], rotmat1[4][4], rotmat2[4][4];
+
+ eul1[0] = eul1[1] = eul1[2] = 0.0;
+ eul2[0] = eul2[1] = eul2[2] = 0.0;
+
+ if (part == 0){ /* pos x */
+ eul1[1] = -M_PI / 2.0;
+ eul2[2] = M_PI;
+ }
+ else if (part == 1) { /* neg x */
+ eul1[1] = M_PI / 2.0;
+ eul2[2] = M_PI;
+ }
+ else if (part == 2) { /* pos y */
+ eul1[0] = M_PI / 2.0;
+ }
+ else if (part == 3) { /* neg y */
+ eul1[0] = -M_PI / 2.0;
+ }
+ else if (part == 4) { /* pos z */
+ eul1[0] = M_PI;
+ }
+ else { /* neg z */
+ eul1[2] = M_PI;
+ }
+
+ copy_m4_m4(tmat, mat);
+ eul_to_mat4(rotmat1, eul1);
+ eul_to_mat4(rotmat2, eul2);
+ mul_m4_m4m4(tmat2, rotmat1, rotmat2);
+ mul_m4_m4m4(mat, tmat, tmat2);
+}
+
+static void gpu_probe_cube_update_buffer_mats(GPUProbe *probe, int cubeface)
+{
+ float tempmat[4][4];
+
+ perspective_m4(probe->winmat, -probe->clipsta, probe->clipsta, -probe->clipsta, probe->clipsta, probe->clipsta, probe->clipend);
+ unit_m4(probe->obmat);
+
+ /* Local Capture */
+ if (probe->ob)
+ translate_m4(probe->obmat, probe->ob->obmat[3][0], probe->ob->obmat[3][1], probe->ob->obmat[3][2]);
+
+ /* Rotating towards the right face */
+ envmap_transmatrix(probe->obmat, cubeface);
+
+ copy_m4_m4(tempmat, probe->obmat);
+ invert_m4_m4(probe->viewmat, tempmat);
+ normalize_v3(probe->viewmat[0]);
+ normalize_v3(probe->viewmat[1]);
+ normalize_v3(probe->viewmat[2]);
+
+ mul_m4_m4m4(probe->persmat, probe->winmat, probe->viewmat);
+}
+
+void GPU_probe_buffer_bind(GPUProbe *probe)
+{
+ glDisable(GL_SCISSOR_TEST);
+ if (probe->type == GPU_PROBE_PLANAR) {
+ GPU_texture_bind_as_framebuffer(probe->texreflect);
+ }
+ else
+ GPU_texture_bind_as_framebuffer(probe->tex);
+}
+
+void GPU_probe_switch_fb_cubeface(GPUProbe *probe, int cubeface, float viewmat[4][4], int *winsize, float winmat[4][4])
+{
+ gpu_probe_cube_update_buffer_mats(probe, cubeface);
+ GPU_framebuffer_cubeface_attach(probe->fb, probe->tex, 0, cubeface, NULL);
+
+ /* set matrices */
+ copy_m4_m4(viewmat, probe->viewmat);
+ copy_m4_m4(winmat, probe->winmat);
+ *winsize = probe->size;
+}
+
+static float point_plane_dist(float point[3], float plane[3], float normal[3])
+{
+ float tmp[3];
+ sub_v3_v3v3(tmp, plane, point);
+ return fabsf(dot_v3v3(normal, tmp));
+}
+
+void GPU_probe_attach_planar_fb(GPUProbe *probe, float camviewmat[4][4], float camwinmat[4][4], float viewmat[4][4], int *winsize, bool refraction)
+{
+ float rangemat[4][4];
+ float plane[4] = {0.0f, 0.0f, -1.0f, 0.0f};
+
+ if (refraction)
+ GPU_framebuffer_texture_attach(probe->fb, probe->texrefract, 0, NULL);
+ else
+ GPU_framebuffer_texture_attach(probe->fb, probe->texreflect, 0, NULL);
+
+ /* opengl buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */
+ unit_m4(rangemat);
+ rangemat[0][0] = 0.5f;
+ rangemat[1][1] = 0.5f;
+ rangemat[2][2] = 0.5f;
+ rangemat[3][0] = 0.5f;
+ rangemat[3][1] = 0.5f;
+ rangemat[3][2] = 0.5f;
+
+ /* set matrices */
+ if (!refraction)
+ mul_m4_m4m4(probe->viewmat, camviewmat, probe->reflectmat);
+ else
+ copy_m4_m4(probe->viewmat, camviewmat);
+
+ mul_m4_m4m4(probe->persmat, camwinmat, probe->viewmat);
+
+ if (!refraction)
+ mul_m4_m4m4(probe->reflectionmat, rangemat, probe->persmat);
+
+ copy_m4_m4(viewmat, probe->viewmat);
+ *winsize = probe->size;
+
+ /* setup clip plane */
+ {
+ float camco[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ float planevec[4] = {0.0f, 0.0f, -1.0f, 0.0f};
+ float planeco[3];
+ double dplane[4];
+ float dist_to_plane;
+ float planetocam[3];
+ float invmat[4][4];
+
+ if (refraction)
+ planevec[2] = 1.0f;
+
+ /* finding cam position */
+ invert_m4_m4(invmat, camviewmat);
+ mul_v4_m4v4(camco, invmat, camco);
+
+ /* mirror plane coordinates and normal vector */
+ copy_v3_v3(planeco, probe->obmat[3]);
+ mul_v4_m4v4(planevec, probe->obmat, planevec);
+ normalize_v3(planevec);
+
+ /* flipping the plane if the cam is below it */
+ sub_v3_v3v3(planetocam, camco, planeco);
+ if (dot_v3v3(planetocam, planevec) < 0) {
+ planevec[0] = planevec[1] = planevec[3] = 0.0f;
+ planevec[2] = (refraction) ? -1.0f : 1.0f;
+ mul_v4_m4v4(planevec, probe->obmat, planevec);
+ normalize_v3(planevec);
+ }
+
+ /* saved to use when shading */
+ if (!refraction)
+ copy_v3_v3(probe->planevec, planevec);
+
+ /* finding the distance to the clip plane */
+ dist_to_plane = point_plane_dist(camco, planeco, planevec);
+
+ /* finding the orientation of the clip plane in camera space */
+ mul_v4_m4v4(planevec, camviewmat, planevec);
+
+ planevec[3] = dist_to_plane - probe->clipsta;
+
+ negate_v4(planevec);
+
+ copy_v4db_v4fl(dplane, planevec);
+ glClipPlane(GL_CLIP_PLANE0, dplane);
+ glEnable(GL_CLIP_PLANE0);
+ }
+}
+
+void GPU_probe_buffer_unbind(GPUProbe *probe)
+{
+ glDisable(GL_CLIP_PLANE0);
+ GPU_framebuffer_texture_unbind(probe->fb, probe->tex);
+ GPU_framebuffer_restore();
+ glEnable(GL_SCISSOR_TEST);
+}
+
+void GPU_probe_rebuild_mipmaps(GPUProbe *probe)
+{
+ if (probe->type == GPU_PROBE_CUBE) {
+ GPU_texture_bind(probe->tex, 0);
+ GPU_generate_mipmap(GL_TEXTURE_CUBE_MAP);
+ GPU_texture_unbind(probe->tex);
+ }
+ else if (probe->type == GPU_PROBE_PLANAR) {
+ GPU_texture_bind(probe->texreflect, 0);
+ GPU_generate_mipmap(GL_TEXTURE_2D);
+ GPU_texture_unbind(probe->texreflect);
+
+ GPU_texture_bind(probe->texrefract, 0);
+ GPU_generate_mipmap(GL_TEXTURE_2D);
+ GPU_texture_unbind(probe->texrefract);
+ }
+}
+
+void GPU_probe_auto_update(GPUProbe *probe)
+{
+ if ((probe->ob && probe->ob->probeflags & OB_PROBE_AUTO_UPDATE) ||
+ (probe->wo && probe->wo->probeflags & WO_PROBE_AUTO_UPDATE))
+ probe->update = true;
+}
+
+void GPU_probe_set_update(GPUProbe *probe, bool val)
+{
+ probe->update = val;
+}
+
+bool GPU_probe_get_update(GPUProbe *probe)
+{
+ return probe->update;
+}
+
+Object *GPU_probe_get_object(GPUProbe *probe)
+{
+ return probe->ob;
+}
+
+int GPU_probe_get_size(GPUProbe *probe)
+{
+ return probe->size;
+}
+
+int GPU_probe_get_type(GPUProbe *probe)
+{
+ return (int)(probe->type);
+}
+
+void GPU_probe_update_clip(GPUProbe *probe, float clipsta, float clipend)
+{
+ probe->clipsta = clipsta;
+ probe->clipend = clipend;
+}
+
+void GPU_probe_update_layers(GPUProbe *probe, unsigned int lay)
+{
+ probe->lay = lay;
+}
+
+unsigned int GPU_probe_get_layers(GPUProbe *probe)
+{
+ if (probe->ob && (probe->ob->probeflags & OB_PROBE_USE_LAYERS))
+ return probe->lay;
+ else
+ return -1;
+}
+
+void GPU_probe_update_sh_res(GPUProbe *probe, int shres)
+{
+ CLAMP(shres, 1, (1 << MAX_SH_SAMPLES));
+ /* Finding the exponent and taking care of the float imprecision */
+ probe->shres = (int)round(log((float)shres) / log(2));
+}
+
+void GPU_probe_update_parallax(GPUProbe *probe, float correctionmat[4][4], float obmat[4][4])
+{
+ copy_v3_v3(probe->co, obmat[3]);
+ invert_m4_m4(probe->correctionmat, correctionmat);
+}
+
+void GPU_probe_update_ref_plane(GPUProbe *probe, float obmat[4][4])
+{
+ float mtx[4][4];
+ float obmat_scale[3];
+
+ /* mtx is the mirror transformation */
+ unit_m4(mtx);
+ mtx[2][2] = -1.0f; /* XY reflection plane */
+
+ normalize_m4_m4_ex(probe->obmat, obmat, obmat_scale);
+ invert_m4_m4(probe->imat, probe->obmat);
+
+ mul_m4_m4m4(mtx, mtx, probe->imat);
+ mul_m4_m4m4(probe->reflectmat, probe->obmat, mtx);
+}
+
+
+/* Spherical Harmonics : Diffuse lighting */
+
+void gpu_compute_sh(GPUProbe *probe)
+{
+ int probe_source_uniform;
+ GPUShader *sh_shader = GPU_shader_get_builtin_shader(GPU_SHADER_COMPUTE_SH + probe->shres);
+
+ if (!sh_shader)
+ return;
+
+ GPU_shader_bind(sh_shader);
+
+ probe_source_uniform = GPU_shader_get_uniform(sh_shader, "probe");
+
+ GPU_texture_bind(probe->tex, 0);
+ GPU_shader_uniform_texture(sh_shader, probe_source_uniform, probe->tex);
+
+ /* Drawing quad */
+ glBegin(GL_TRIANGLE_STRIP);
+ glVertex3f(-1.0, -1.0, 1.0);
+ glVertex3f(1.0, -1.0, 1.0);
+ glVertex3f(-1.0, 1.0, 1.0);
+ glVertex3f(1.0, 1.0, 1.0);
+ glEnd();
+
+ GPU_texture_unbind(probe->tex);
+
+ GPU_shader_unbind();
+}
+
+void GPU_probe_sh_compute(GPUProbe *probe)
+{
+ bool computesh = false;
+
+ if (probe->ob && (probe->ob->probeflags & OB_PROBE_COMPUTE_SH))
+ computesh = true;
+
+ if (probe->wo && (probe->wo->probeflags & WO_PROBE_COMPUTE_SH))
+ computesh = true;
+
+ if (computesh && probe->type == GPU_PROBE_CUBE) {
+ glDisable(GL_SCISSOR_TEST);
+ GPU_texture_bind_as_framebuffer(probe->shtex);
+ gpu_compute_sh(probe);
+
+ GPU_framebuffer_texture_unbind(probe->fbsh, probe->shtex);
+
+ /* Only read the 9 pixels containing the coefs */
+ glReadPixels(0, 0, 3, 3, GL_RGB, GL_FLOAT, probe->shcoefs);
+ GPU_framebuffer_restore();
+ glEnable(GL_SCISSOR_TEST);
+ }
+ else if (computesh && (probe->type == GPU_PROBE_PLANAR)) {
+ GPUProbe *srcprobe;
+ /* Copy sh from other probe */
+ if (probe->ob->probe)
+ srcprobe = GPU_probe_object(probe->scene, probe->ob->probe);
+ else if (probe->scene->world)
+ srcprobe = GPU_probe_world(probe->scene, probe->scene->world);
+ else {
+ memset(probe->shcoefs, 0, sizeof(float) * 9 * 3);
+ return;
+ }
+
+ memcpy(probe->shcoefs, srcprobe->shcoefs, sizeof(float) * 9 * 3);
+ }
+ else {
+ memset(probe->shcoefs, 0, sizeof(float) * 9 * 3);
+ }
+}
+
+void GPU_probe_sh_shader_bind(GPUProbe *probe)
+{
+ int uniformloc[9], i;
+ GPUShader *sh_shader = GPU_shader_get_builtin_shader(GPU_SHADER_DISPLAY_SH);
+
+ if (!sh_shader)
+ return;
+
+ GPU_shader_bind(sh_shader);
+
+ uniformloc[0] = GPU_shader_get_uniform(sh_shader, "sh0");
+ uniformloc[1] = GPU_shader_get_uniform(sh_shader, "sh1");
+ uniformloc[2] = GPU_shader_get_uniform(sh_shader, "sh2");
+ uniformloc[3] = GPU_shader_get_uniform(sh_shader, "sh3");
+ uniformloc[4] = GPU_shader_get_uniform(sh_shader, "sh4");
+ uniformloc[5] = GPU_shader_get_uniform(sh_shader, "sh5");
+ uniformloc[6] = GPU_shader_get_uniform(sh_shader, "sh6");
+ uniformloc[7] = GPU_shader_get_uniform(sh_shader, "sh7");
+ uniformloc[8] = GPU_shader_get_uniform(sh_shader, "sh8");
+
+ for (i = 0; i < 9; ++i) {
+ GPU_shader_uniform_vector(sh_shader, uniformloc[i], 3, 1, &probe->shcoefs[i*3]);
+ }
+}
+
+void GPU_probe_sh_shader_unbind(void)
+{
+ GPU_shader_unbind();
+} \ No newline at end of file
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index 5cfb323bc4b..226595200ca 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -61,6 +61,13 @@ extern char datatoc_gpu_shader_fx_dof_hq_vert_glsl[];
extern char datatoc_gpu_shader_fx_dof_hq_geo_glsl[];
extern char datatoc_gpu_shader_fx_depth_resolve_glsl[];
extern char datatoc_gpu_shader_fx_lib_glsl[];
+extern char datatoc_gpu_shader_fx_colormanage_frag_glsl[];
+extern char datatoc_gpu_shader_probe_sh_compute_frag_glsl[];
+extern char datatoc_gpu_shader_probe_sh_compute_vert_glsl[];
+extern char datatoc_gpu_shader_display_sh_frag_glsl[];
+extern char datatoc_gpu_shader_display_sh_vert_glsl[];
+extern char datatoc_gpu_shader_downsample_maxz_frag_glsl[];
+extern char datatoc_gpu_shader_downsample_maxz_vert_glsl[];
static struct GPUShadersGlobal {
struct {
@@ -68,6 +75,10 @@ static struct GPUShadersGlobal {
GPUShader *sep_gaussian_blur;
GPUShader *smoke;
GPUShader *smoke_fire;
+ GPUShader *compute_sh[MAX_SH_SAMPLES];
+ GPUShader *display_sh;
+ GPUShader *maxz_downsample;
+ GPUShader *minz_downsample;
/* cache for shader fx. Those can exist in combinations so store them here */
GPUShader *fx_shaders[MAX_FX_SHADERS * 2];
} shaders;
@@ -165,6 +176,10 @@ static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH],
strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n");
}
+ if (GLEW_ARB_shader_texture_lod) {
+ strcat(defines, "#extension GL_ARB_shader_texture_lod: enable\n");
+ }
+
if (use_geometry_shader && GPU_geometry_shader_support_via_extension()) {
strcat(defines, "#extension GL_EXT_geometry_shader4: enable\n");
}
@@ -187,7 +202,14 @@ static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH],
static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH],
bool use_opensubdiv,
- bool use_new_shading)
+ bool use_new_shading,
+ bool use_box_correction,
+ bool use_ellipsoid_correction,
+ bool use_planar_probe,
+ bool use_alpha_as_depth,
+ bool use_backface_depth,
+ bool use_ssr,
+ bool use_ssao)
{
/* some useful defines to detect GPU type */
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) {
@@ -230,9 +252,35 @@ static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH],
UNUSED_VARS(use_opensubdiv);
#endif
- if (use_new_shading) {
+ if (use_new_shading)
strcat(defines, "#define USE_NEW_SHADING\n");
- }
+
+ if (use_box_correction)
+ strcat(defines, "#define CORRECTION_BOX\n");
+ else if (use_ellipsoid_correction)
+ strcat(defines, "#define CORRECTION_ELLIPSOID\n");
+ else
+ strcat(defines, "#define CORRECTION_NONE\n");
+
+ if (use_planar_probe)
+ strcat(defines, "#define PLANAR_PROBE\n");
+
+ if (use_ssr && !use_planar_probe)
+ strcat(defines, "#define USE_SSR\n");
+
+ if (use_ssao)
+ strcat(defines, "#define USE_SSAO\n");
+
+ if (use_backface_depth)
+ strcat(defines, "#define USE_BACKFACE\n");
+
+ if (use_alpha_as_depth)
+ strcat(defines, "#define ALPHA_AS_DEPTH\n");
+
+ /* XXX : this must be here for the BSDF_SAMPLES to work */
+ strcat(defines, "#if __VERSION__ < 130\n"
+ "#define uint unsigned int\n"
+ "#endif\n");
return;
}
@@ -310,7 +358,14 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
gpu_shader_standard_defines(standard_defines,
use_opensubdiv,
- (flags & GPU_SHADER_FLAGS_NEW_SHADING) != 0);
+ (flags & GPU_SHADER_FLAGS_NEW_SHADING) != 0,
+ (flags & GPU_SHADER_FLAGS_PROBE_BOX_CORREC) != 0,
+ (flags & GPU_SHADER_FLAGS_PROBE_ELIPS_CORREC) != 0,
+ (flags & GPU_SHADER_FLAGS_PROBE_PLANAR) != 0,
+ (flags & GPU_SHADER_FLAGS_ALPHA_DEPTH) != 0,
+ (flags & GPU_SHADER_FLAGS_BACKFACE_DEPTH) != 0,
+ (flags & GPU_SHADER_FLAGS_SSR) != 0,
+ (flags & GPU_SHADER_FLAGS_SSAO) != 0);
gpu_shader_standard_extensions(standard_extensions, geocode != NULL);
if (vertexcode) {
@@ -593,36 +648,73 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
{
GPUShader *retval = NULL;
- switch (shader) {
- case GPU_SHADER_VSM_STORE:
- if (!GG.shaders.vsm_store)
- GG.shaders.vsm_store = GPU_shader_create(
- datatoc_gpu_shader_vsm_store_vert_glsl, datatoc_gpu_shader_vsm_store_frag_glsl,
- NULL, NULL, NULL, 0, 0, 0);
- retval = GG.shaders.vsm_store;
- break;
- case GPU_SHADER_SEP_GAUSSIAN_BLUR:
- if (!GG.shaders.sep_gaussian_blur)
- GG.shaders.sep_gaussian_blur = GPU_shader_create(
- datatoc_gpu_shader_sep_gaussian_blur_vert_glsl,
- datatoc_gpu_shader_sep_gaussian_blur_frag_glsl,
- NULL, NULL, NULL, 0, 0, 0);
- retval = GG.shaders.sep_gaussian_blur;
- break;
- case GPU_SHADER_SMOKE:
- if (!GG.shaders.smoke)
- GG.shaders.smoke = GPU_shader_create(
- datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_smoke_frag_glsl,
- NULL, NULL, NULL, 0, 0, 0);
- retval = GG.shaders.smoke;
- break;
- case GPU_SHADER_SMOKE_FIRE:
- if (!GG.shaders.smoke_fire)
- GG.shaders.smoke_fire = GPU_shader_create(
- datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_fire_frag_glsl,
- NULL, NULL, NULL, 0, 0, 0);
- retval = GG.shaders.smoke_fire;
- break;
+ if (shader >= GPU_SHADER_COMPUTE_SH && shader < GPU_SHADER_COMPUTE_SH + MAX_SH_SAMPLES) {
+ int shadn = shader - GPU_SHADER_COMPUTE_SH;
+
+ if (!GG.shaders.compute_sh[shadn]) {
+ char buf[32];
+ int samples = (1 << shadn);
+
+ CLAMP_MIN(samples, 1);
+ sprintf(buf, "#define CUBEMAP_RES %d \n", samples);
+
+ GG.shaders.compute_sh[shadn] = GPU_shader_create(
+ datatoc_gpu_shader_probe_sh_compute_vert_glsl, datatoc_gpu_shader_probe_sh_compute_frag_glsl,
+ NULL, NULL, buf, 0, 0, 0);
+ }
+ retval = GG.shaders.compute_sh[shadn];
+ }
+ else {
+ switch (shader) {
+ case GPU_SHADER_VSM_STORE:
+ if (!GG.shaders.vsm_store)
+ GG.shaders.vsm_store = GPU_shader_create(
+ datatoc_gpu_shader_vsm_store_vert_glsl, datatoc_gpu_shader_vsm_store_frag_glsl,
+ NULL, NULL, NULL, 0, 0, 0);
+ retval = GG.shaders.vsm_store;
+ break;
+ case GPU_SHADER_SEP_GAUSSIAN_BLUR:
+ if (!GG.shaders.sep_gaussian_blur)
+ GG.shaders.sep_gaussian_blur = GPU_shader_create(
+ datatoc_gpu_shader_sep_gaussian_blur_vert_glsl,
+ datatoc_gpu_shader_sep_gaussian_blur_frag_glsl,
+ NULL, NULL, NULL, 0, 0, 0);
+ retval = GG.shaders.sep_gaussian_blur;
+ break;
+ case GPU_SHADER_SMOKE:
+ if (!GG.shaders.smoke)
+ GG.shaders.smoke = GPU_shader_create(
+ datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_smoke_frag_glsl,
+ NULL, NULL, NULL, 0, 0, 0);
+ retval = GG.shaders.smoke;
+ break;
+ case GPU_SHADER_SMOKE_FIRE:
+ if (!GG.shaders.smoke_fire)
+ GG.shaders.smoke_fire = GPU_shader_create(
+ datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_fire_frag_glsl,
+ NULL, NULL, NULL, 0, 0, 0);
+ retval = GG.shaders.smoke_fire;
+ break;
+ case GPU_SHADER_DISPLAY_SH:
+ if (!GG.shaders.display_sh)
+ GG.shaders.display_sh = GPU_shader_create(
+ datatoc_gpu_shader_display_sh_vert_glsl, datatoc_gpu_shader_display_sh_frag_glsl,
+ NULL, NULL, NULL, 0, 0, 0);
+ retval = GG.shaders.display_sh;
+ break;
+ case GPU_SHADER_MAXZ_DOWNSAMPLE:
+ if (!GG.shaders.maxz_downsample)
+ GG.shaders.maxz_downsample = GPU_shader_create(
+ datatoc_gpu_shader_downsample_maxz_vert_glsl, datatoc_gpu_shader_downsample_maxz_frag_glsl,
+ NULL, NULL, NULL, 0, 0, 0);
+ case GPU_SHADER_MINZ_DOWNSAMPLE:
+ if (!GG.shaders.minz_downsample)
+ GG.shaders.minz_downsample = GPU_shader_create(
+ datatoc_gpu_shader_downsample_maxz_vert_glsl, datatoc_gpu_shader_downsample_maxz_frag_glsl,
+ NULL, NULL, "#define MIN;\n", 0, 0, 0);
+ retval = GG.shaders.minz_downsample;
+ break;
+ }
}
if (retval == NULL)
@@ -700,6 +792,10 @@ GPUShader *GPU_shader_get_builtin_fx_shader(int effect, bool persp)
case GPU_SHADER_FX_DEPTH_RESOLVE:
shader = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_depth_resolve_glsl, NULL, NULL, defines, 0, 0, 0);
break;
+
+ case GPU_SHADER_FX_COLORMANAGE:
+ shader = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_colormanage_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
+ break;
}
GG.shaders.fx_shaders[offset] = shader;
@@ -734,6 +830,28 @@ void GPU_shader_free_builtin_shaders(void)
GG.shaders.smoke_fire = NULL;
}
+ for (i = 0; i < MAX_SH_SAMPLES; ++i) {
+ if (GG.shaders.compute_sh[i]) {
+ GPU_shader_free(GG.shaders.compute_sh[i]);
+ GG.shaders.compute_sh[i] = NULL;
+ }
+ }
+
+ if (GG.shaders.display_sh) {
+ GPU_shader_free(GG.shaders.display_sh);
+ GG.shaders.display_sh = NULL;
+ }
+
+ if (GG.shaders.maxz_downsample) {
+ GPU_shader_free(GG.shaders.maxz_downsample);
+ GG.shaders.maxz_downsample = NULL;
+ }
+
+ if (GG.shaders.minz_downsample) {
+ GPU_shader_free(GG.shaders.minz_downsample);
+ GG.shaders.minz_downsample = NULL;
+ }
+
for (i = 0; i < 2 * MAX_FX_SHADERS; ++i) {
if (GG.shaders.fx_shaders[i]) {
GPU_shader_free(GG.shaders.fx_shaders[i]);
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 54f0003c086..e6a9db5059a 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -32,6 +32,8 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_math_base.h"
+#include "BLI_math_vector.h"
+#include "BLI_rand.h"
#include "BKE_global.h"
@@ -41,6 +43,7 @@
#include "GPU_framebuffer.h"
#include "GPU_glew.h"
#include "GPU_texture.h"
+#include "GPU_ltc.h"
static struct GPUTextureGlobal {
GPUTexture *invalid_tex_1D; /* texture used in place of invalid textures (not loaded correctly, missing) */
@@ -161,6 +164,23 @@ static GPUTexture *GPU_texture_create_nD(
break;
}
}
+ else if (components == 3) {
+ format = GL_RGB;
+ switch (hdr_type) {
+ case GPU_HDR_NONE:
+ internalformat = GL_RGB8;
+ break;
+ /* the following formats rely on ARB_texture_float or OpenGL 3.0 */
+ case GPU_HDR_HALF_FLOAT:
+ internalformat = GL_RGB16F_ARB;
+ break;
+ case GPU_HDR_FULL_FLOAT:
+ internalformat = GL_RGB32F_ARB;
+ break;
+ default:
+ break;
+ }
+ }
else if (components == 2) {
/* these formats rely on ARB_texture_rg or OpenGL 3.0 */
format = GL_RG;
@@ -178,6 +198,22 @@ static GPUTexture *GPU_texture_create_nD(
break;
}
}
+ else if (components == 1) {
+ format = GL_RED;
+ switch (hdr_type) {
+ case GPU_HDR_NONE:
+ internalformat = GL_R8;
+ break;
+ case GPU_HDR_HALF_FLOAT:
+ internalformat = GL_R16F;
+ break;
+ case GPU_HDR_FULL_FLOAT:
+ internalformat = GL_R32F;
+ break;
+ default:
+ break;
+ }
+ }
if (fpixels && hdr_type == GPU_HDR_NONE) {
type = GL_UNSIGNED_BYTE;
@@ -242,6 +278,76 @@ static GPUTexture *GPU_texture_create_nD(
return tex;
}
+static GPUTexture *GPU_texture_create_cube(int w, GPUHDRType hdr_type, char err_out[256])
+{
+ GLenum type, format, internalformat;
+
+ GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
+ tex->w = w;
+ tex->h = w;
+ tex->number = -1;
+ tex->refcount = 1;
+ tex->target = GL_TEXTURE_CUBE_MAP;
+ tex->target_base = GL_TEXTURE_CUBE_MAP;
+ tex->depth = 0;
+ tex->fb_attachment = -1;
+
+ glGenTextures(1, &tex->bindcode);
+
+ if (!tex->bindcode) {
+ if (err_out) {
+ BLI_snprintf(err_out, 256, "GPUTexture: texture create failed: %d",
+ (int)glGetError());
+ }
+ else {
+ fprintf(stderr, "GPUTexture: texture create failed: %d\n",
+ (int)glGetError());
+ }
+ GPU_texture_free(tex);
+ return NULL;
+ }
+
+ if (!GPU_full_non_power_of_two_support()) {
+ tex->w = power_of_2_max_i(tex->w);
+ tex->h = power_of_2_max_i(tex->h);
+ }
+
+ tex->number = 0;
+ glBindTexture(tex->target, tex->bindcode);
+
+ type = GL_FLOAT;
+
+ format = GL_RGBA;
+ switch (hdr_type) {
+ case GPU_HDR_NONE:
+ internalformat = GL_RGBA8;
+ break;
+ /* the following formats rely on ARB_texture_float or OpenGL 3.0 */
+ case GPU_HDR_HALF_FLOAT:
+ internalformat = GL_RGBA16F_ARB;
+ break;
+ case GPU_HDR_FULL_FLOAT:
+ internalformat = GL_RGBA32F_ARB;
+ break;
+ default:
+ break;
+ }
+
+ for (int i = 0; i < 6; i++)
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internalformat ,tex->w, tex->h, 0,
+ format, type, NULL);
+
+ /* TODO : use global parameters */
+ glTexParameteri(tex->target_base, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(tex->target_base, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(tex->target_base, GL_GENERATE_MIPMAP, GL_TRUE);
+
+ glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+
+ return tex;
+}
GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const float *fpixels)
{
@@ -276,6 +382,10 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const f
format = GL_RGBA;
internalformat = GL_RGBA8;
}
+ else if (channels == 3) {
+ format = GL_RGB;
+ internalformat = GL_RGB16F; //For 3DLUT
+ }
else {
format = GL_RED;
internalformat = GL_INTENSITY8;
@@ -368,11 +478,11 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const f
return tex;
}
-GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget, bool is_data, double time, int mipmap)
+GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget, bool is_data, short do_clip, double time, int mipmap)
{
int gputt;
/* this binds a texture, so that's why to restore it to 0 */
- GLint bindcode = GPU_verify_image(ima, iuser, textarget, 0, 0, mipmap, is_data);
+ GLint bindcode = GPU_verify_image(ima, iuser, textarget, 0, 0, mipmap, is_data, do_clip);
GPU_update_image_time(ima, time);
/* see GPUInput::textarget: it can take two values - GL_TEXTURE_2D and GL_TEXTURE_CUBE_MAP
@@ -436,7 +546,7 @@ GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
/* this binds a texture, so that's why we restore it to 0 */
if (bindcode == 0) {
- GPU_create_gl_tex(&bindcode, prv->rect[0], NULL, prv->w[0], prv->h[0], GL_TEXTURE_2D, mipmap, 0, NULL);
+ GPU_create_gl_tex(&bindcode, prv->rect[0], NULL, prv->w[0], prv->h[0], GL_TEXTURE_2D, mipmap, 0, NULL, false);
}
if (tex) {
tex->bindcode = bindcode;
@@ -512,6 +622,22 @@ GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256])
return tex;
}
+
+
+GPUTexture *GPU_texture_create_depth_buffer(int w, int h, char err_out[256])
+{
+ GPUTexture *tex = GPU_texture_create_nD(w, h, 2, NULL, 1, GPU_HDR_NONE, 1, 0, err_out);
+
+ if (tex) {
+ /* Now we tweak some of the settings */
+ glTexParameteri(tex->target_base, GL_TEXTURE_COMPARE_MODE, GL_NONE);
+
+ GPU_texture_unbind(tex);
+ }
+ return tex;
+}
+
+
GPUTexture *GPU_texture_create_depth_multisample(int w, int h, int samples, char err_out[256])
{
GPUTexture *tex = GPU_texture_create_nD(w, h, 2, NULL, 1, GPU_HDR_NONE, 1, samples, err_out);
@@ -540,9 +666,9 @@ GPUTexture *GPU_texture_create_vsm_shadow_map(int size, char err_out[256])
return tex;
}
-GPUTexture *GPU_texture_create_2D_procedural(int w, int h, const float *pixels, bool repeat, char err_out[256])
+GPUTexture *GPU_texture_create_2D_procedural(int w, int h, const float *pixels, bool repeat, bool filtering, int channels, char err_out[256])
{
- GPUTexture *tex = GPU_texture_create_nD(w, h, 2, pixels, 0, GPU_HDR_HALF_FLOAT, 2, 0, err_out);
+ GPUTexture *tex = GPU_texture_create_nD(w, h, 2, pixels, 0, GPU_HDR_HALF_FLOAT, channels, 0, err_out);
if (tex) {
/* Now we tweak some of the settings */
@@ -550,8 +676,10 @@ GPUTexture *GPU_texture_create_2D_procedural(int w, int h, const float *pixels,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ if (!filtering) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
GPU_texture_unbind(tex);
}
@@ -559,9 +687,9 @@ GPUTexture *GPU_texture_create_2D_procedural(int w, int h, const float *pixels,
return tex;
}
-GPUTexture *GPU_texture_create_1D_procedural(int w, const float *pixels, char err_out[256])
+GPUTexture *GPU_texture_create_1D_procedural(int w, const float *pixels, int channels, char err_out[256])
{
- GPUTexture *tex = GPU_texture_create_nD(w, 0, 1, pixels, 0, GPU_HDR_HALF_FLOAT, 2, 0, err_out);
+ GPUTexture *tex = GPU_texture_create_nD(w, 0, 1, pixels, 0, GPU_HDR_HALF_FLOAT, channels, 0, err_out);
if (tex) {
/* Now we tweak some of the settings */
@@ -575,6 +703,168 @@ GPUTexture *GPU_texture_create_1D_procedural(int w, const float *pixels, char er
return tex;
}
+GPUTexture *GPU_texture_create_cube_probe(int size, char err_out[256])
+{
+ GPUTexture *tex = GPU_texture_create_cube(size, GPU_HDR_HALF_FLOAT, err_out);
+
+ if (tex)
+ GPU_texture_unbind(tex);
+
+ return tex;
+}
+
+GPUTexture *GPU_texture_create_planar_probe(int size, char err_out[256])
+{
+ GPUTexture *tex = GPU_texture_create_nD(size, size, 2, NULL, 0, GPU_HDR_HALF_FLOAT, 4, 0, err_out);
+
+ if (tex) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
+
+ GPU_texture_unbind(tex);
+ }
+
+ return tex;
+}
+
+GPUTexture *GPU_texture_create_sh_filter_target(char err_out[256])
+{
+ GPUTexture *tex = GPU_texture_create_nD(4, 4, 2, NULL, 0, GPU_HDR_HALF_FLOAT, 3, 0, err_out);
+
+ if (tex)
+ GPU_texture_unbind(tex);
+
+ return tex;
+}
+
+/* ********** Utility Lut textures ********** */
+
+/* Linearly Transformed Cosines */
+/* From https://eheitzresearch.wordpress.com/415-2/ */
+GPUTexture *GPU_create_ltc_mat_ggx_lut_texture(void)
+{
+ return GPU_texture_create_2D_procedural(64, 64, &ltc_mat_ggx[0], true, true, 4, NULL);
+}
+
+GPUTexture *GPU_create_ltc_mag_ggx_lut_texture(void)
+{
+ return GPU_texture_create_2D_procedural(64, 64, &ltc_mag_ggx[0], true, true, 1, NULL);
+}
+
+/* Van der Corput sequence */
+ /* From http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html */
+static float radical_inverse(int i) {
+ unsigned int bits = (unsigned int)i;
+ bits = (bits << 16u) | (bits >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ return (float)bits * 2.3283064365386963e-10f;
+}
+
+GPUTexture *GPU_create_hammersley_sample_texture(int samples)
+{
+ GPUTexture *tex;
+ float (*texels)[2] = MEM_mallocN(sizeof(float[2]) * samples, "hammersley_tex");
+ const float samples_inv = 1.0f / samples;
+ int i;
+
+ for (i = 0; i < samples; i++) {
+ float phi = radical_inverse(i) * 2.0f * M_PI;
+ texels[i][0] = cos(phi);
+ texels[i][1] = sinf(phi);
+ }
+
+ tex = GPU_texture_create_1D_procedural(samples, (float *)texels, 2, NULL);
+ MEM_freeN(texels);
+ return tex;
+}
+
+GPUTexture *GPU_create_random_texture(void)
+{
+ float random[64 * 64][2];
+ int i;
+
+ for (i = 0; i < 64 * 64; i++) {
+ random[i][0] = BLI_frand();
+ random[i][1] = BLI_frand();
+ }
+
+ return GPU_texture_create_2D_procedural(64, 64, &random[0][0], true, false, 2, NULL);
+}
+
+GPUTexture *GPU_create_jitter_texture(void)
+{
+ float jitter[64 * 64][2];
+ int i;
+
+ for (i = 0; i < 64 * 64; i++) {
+ jitter[i][0] = 2.0f * BLI_frand() - 1.0f;
+ jitter[i][1] = 2.0f * BLI_frand() - 1.0f;
+ normalize_v2(jitter[i]);
+ }
+
+ return GPU_texture_create_2D_procedural(64, 64, &jitter[0][0], true, false, 2, NULL);
+}
+
+#if 0
+/* concentric mapping, see "A Low Distortion Map Between Disk and Square" and
+ * http://psgraphics.blogspot.nl/2011/01/improved-code-for-concentric-map.html */
+static GPUTexture * create_concentric_sample_texture(int side)
+{
+ GPUTexture *tex;
+ float midpoint = 0.5f * (side - 1);
+ float *texels = (float *)MEM_mallocN(sizeof(float) * 2 * side * side, "concentric_tex");
+ int i, j;
+
+ for (i = 0; i < side; i++) {
+ for (j = 0; j < side; j++) {
+ int index = (i * side + j) * 2;
+ float a = 1.0f - i / midpoint;
+ float b = 1.0f - j / midpoint;
+ float phi, r;
+ if (a * a > b * b) {
+ r = a;
+ phi = (M_PI_4) * (b / a);
+ }
+ else {
+ r = b;
+ phi = M_PI_2 - (M_PI_4) * (a / b);
+ }
+ texels[index] = r * cos(phi);
+ texels[index + 1] = r * sin(phi);
+ }
+ }
+
+ tex = GPU_texture_create_1D_procedural(side * side, texels, 2, NULL);
+ MEM_freeN(texels);
+ return tex;
+}
+#endif
+
+GPUTexture *GPU_create_spiral_sample_texture(int numsamples)
+{
+ GPUTexture *tex;
+ float (*texels)[2] = MEM_mallocN(sizeof(float[2]) * numsamples, "concentric_tex");
+ const float numsamples_inv = 1.0f / numsamples;
+ int i;
+ /* arbitrary number to ensure we don't get conciding samples every circle */
+ const float spirals = 7.357;
+
+ for (i = 0; i < numsamples; i++) {
+ float r = (i + 0.5f) * numsamples_inv;
+ float phi = r * spirals * (float)(2.0 * M_PI);
+ texels[i][0] = r * cosf(phi);
+ texels[i][1] = r * sinf(phi);
+ }
+
+ tex = GPU_texture_create_1D_procedural(numsamples, (float *)texels, 2, NULL);
+ MEM_freeN(texels);
+ return tex;
+}
+
void GPU_invalid_tex_init(void)
{
const float color[4] = {1.0f, 0.0f, 1.0f, 1.0f};
diff --git a/source/blender/gpu/shaders/gpu_shader_display_sh_frag.glsl b/source/blender/gpu/shaders/gpu_shader_display_sh_frag.glsl
new file mode 100644
index 00000000000..c578e25e482
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_display_sh_frag.glsl
@@ -0,0 +1,58 @@
+uniform vec3 sh0;
+uniform vec3 sh1;
+uniform vec3 sh2;
+uniform vec3 sh3;
+uniform vec3 sh4;
+uniform vec3 sh5;
+uniform vec3 sh6;
+uniform vec3 sh7;
+uniform vec3 sh8;
+
+
+varying vec3 varposition;
+varying vec3 varnormal;
+
+float linearrgb_to_srgb(float c)
+{
+ if(c < 0.0031308)
+ return (c < 0.0) ? 0.0: c * 12.92;
+ else
+ return 1.055 * pow(c, 1.0/2.4) - 0.055;
+}
+
+void linearrgb_to_srgb(vec4 col_from, out vec4 col_to)
+{
+ col_to.r = linearrgb_to_srgb(col_from.r);
+ col_to.g = linearrgb_to_srgb(col_from.g);
+ col_to.b = linearrgb_to_srgb(col_from.b);
+ col_to.a = col_from.a;
+}
+
+void main()
+{
+ vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(varposition, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
+ vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
+
+ vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
+ vec3 worldvec = normalize( (gl_ModelViewMatrixInverse * co).xyz );
+
+ /* Second order Spherical Harmonics */
+ /* http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/ */
+ vec3 sh = vec3(0.0);
+
+ sh += 0.282095 * sh0;
+
+ sh += -0.488603 * worldvec.z * sh1;
+ sh += 0.488603 * worldvec.y * sh2;
+ sh += -0.488603 * worldvec.x * sh3;
+
+ sh += 1.092548 * worldvec.x * worldvec.z * sh4;
+ sh += -1.092548 * worldvec.z * worldvec.y * sh5;
+ sh += 0.315392 * (3.0 * worldvec.y * worldvec.y - 1.0) * sh6;
+ sh += -1.092548 * worldvec.x * worldvec.y * sh7;
+ sh += 0.546274 * (worldvec.x * worldvec.x - worldvec.z * worldvec.z) * sh8;
+
+ vec4 shcolor = vec4(sh, 1.0);
+ linearrgb_to_srgb(shcolor, shcolor);
+ gl_FragColor = shcolor;
+} \ No newline at end of file
diff --git a/source/blender/gpu/shaders/gpu_shader_display_sh_vert.glsl b/source/blender/gpu/shaders/gpu_shader_display_sh_vert.glsl
new file mode 100644
index 00000000000..02f627f0f21
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_display_sh_vert.glsl
@@ -0,0 +1,13 @@
+
+varying vec3 varposition;
+varying vec3 varnormal;
+
+void main()
+{
+ /* position does not need to be transformed, we already have it */
+ gl_Position = gl_Vertex;
+
+ varposition = gl_Vertex.xyz;
+
+ varnormal = normalize(-varposition);
+} \ No newline at end of file
diff --git a/source/blender/gpu/shaders/gpu_shader_downsample_maxz_frag.glsl b/source/blender/gpu/shaders/gpu_shader_downsample_maxz_frag.glsl
new file mode 100644
index 00000000000..3279023670c
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_downsample_maxz_frag.glsl
@@ -0,0 +1,74 @@
+/* From http://rastergrid.com/blog/2010/10/hierarchical-z-map-based-occlusion-culling/ */
+#extension GL_EXT_gpu_shader4 : enable
+
+uniform sampler2D lowermip;
+uniform ivec2 lowermipsize;
+
+float minmax(float a, float b, float c, float d)
+{
+#ifdef MIN
+ return min(min(a, b), min(c, d));
+#else
+ return max(max(a, b), max(c, d));
+#endif
+}
+
+float minmax(float a, float b, float c)
+{
+#ifdef MIN
+ return min(min(a, b), c);
+#else
+ return max(max(a, b), c);
+#endif
+}
+
+float minmax(float a, float b)
+{
+#ifdef MIN
+ return min(a, b);
+#else
+ return max(a, b);
+#endif
+}
+
+float texelFetchLowermip(ivec2 texelPos)
+{
+#if __VERSION__ < 130
+ return texture2DLod(lowermip, (texelPos * lowermipsize + 0.5) / lowermipsize, 0.0).r;
+#else
+ return texelFetch(lowermip, texelPos, 0).r;
+#endif
+}
+
+void main()
+{
+ vec4 texels;
+ ivec2 texelPos = ivec2(gl_FragCoord.xy) * 2;
+ texels.x = texelFetchLowermip(texelPos);
+ texels.y = texelFetchLowermip(texelPos + ivec2(1, 0));
+ texels.z = texelFetchLowermip(texelPos + ivec2(1, 1));
+ texels.w = texelFetchLowermip(texelPos + ivec2(0, 1));
+
+ float minmaxz = minmax(texels.x, texels.y, texels.z, texels.w);
+ vec3 extra;
+ /* if we are reducing an odd-width texture then fetch the edge texels */
+ if (((lowermipsize.x & 1) != 0) && (int(gl_FragCoord.x) == lowermipsize.x-3)) {
+ /* if both edges are odd, fetch the top-left corner texel */
+ if (((lowermipsize.y & 1) != 0) && (int(gl_FragCoord.y) == lowermipsize.y-3)) {
+ extra.z = texelFetchLowermip(texelPos + ivec2(-1, -1));
+ minmaxz = minmax(minmaxz, extra.z);
+ }
+ extra.x = texelFetchLowermip(texelPos + ivec2(0, -1));
+ extra.y = texelFetchLowermip(texelPos + ivec2(1, -1));
+ minmaxz = minmax(minmaxz, extra.x, extra.y);
+ }
+ /* if we are reducing an odd-height texture then fetch the edge texels */
+ else if (((lowermipsize.y & 1) != 0) && (int(gl_FragCoord.y) == lowermipsize.y-3)) {
+ extra.x = texelFetchLowermip(texelPos + ivec2(0, -1));
+ extra.y = texelFetchLowermip(texelPos + ivec2(1, -1));
+ minmaxz = minmax(minmaxz, extra.x, extra.y);
+ }
+
+ gl_FragDepth = minmaxz;
+ gl_FragColor = vec4(1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_downsample_maxz_vert.glsl b/source/blender/gpu/shaders/gpu_shader_downsample_maxz_vert.glsl
new file mode 100644
index 00000000000..203d5322cee
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_downsample_maxz_vert.glsl
@@ -0,0 +1,6 @@
+
+void main()
+{
+ gl_Position = gl_Vertex;
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_colormanage_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_colormanage_frag.glsl
new file mode 100644
index 00000000000..0d06e808891
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_colormanage_frag.glsl
@@ -0,0 +1,99 @@
+// color buffer
+uniform sampler2D colorbuffer;
+uniform sampler3D lut3d_texture;
+
+uniform float exposure;
+uniform float gamma;
+
+uniform float lut_size = 16.0;
+
+uniform float displayspace_is_srgb;
+uniform float is_offscreen;
+
+// coordinates on framebuffer in normalized (0.0-1.0) uv space
+varying vec4 uvcoordsvar;
+
+float srgb_to_linearrgb(float c)
+{
+ if(c < 0.04045)
+ return (c < 0.0) ? 0.0: c * (1.0 / 12.92);
+ else
+ return pow((c + 0.055)*(1.0/1.055), 2.4);
+}
+
+float linearrgb_to_srgb(float c)
+{
+ if(c < 0.0031308)
+ return (c < 0.0) ? 0.0: c * 12.92;
+ else
+ return 1.055 * pow(c, 1.0/2.4) - 0.055;
+}
+
+void srgb_to_linearrgb(vec4 col_from, out vec4 col_to)
+{
+ col_to.r = srgb_to_linearrgb(col_from.r);
+ col_to.g = srgb_to_linearrgb(col_from.g);
+ col_to.b = srgb_to_linearrgb(col_from.b);
+ col_to.a = col_from.a;
+}
+
+void linearrgb_to_srgb(vec4 col_from, out vec4 col_to)
+{
+ col_to.r = linearrgb_to_srgb(col_from.r);
+ col_to.g = linearrgb_to_srgb(col_from.g);
+ col_to.b = linearrgb_to_srgb(col_from.b);
+ col_to.a = col_from.a;
+}
+
+float computeLuminance(vec3 color)
+{
+ return max(dot(vec3(0.30, 0.59, 0.11), color), 1e-16);
+}
+
+vec3 computeExposedColor(vec3 color, float exposure)
+{
+ return exp2(exposure) * color;
+}
+
+// Reinhard operator
+vec3 tonemapReinhard(vec3 color, float saturation)
+{
+ float lum = computeLuminance(color);
+ float toneMappedLuminance = lum / (lum + 1.0);
+ return toneMappedLuminance * (color / lum);
+}
+
+vec3 applyGamma(vec3 color, float gamma)
+{
+ gamma = max(gamma, 1e-8);
+ return vec3( pow(color.r, 1/gamma), pow(color.g, 1/gamma), pow(color.b, 1/gamma) );
+}
+
+void main()
+{
+ //float depth = texture2D(depthbuffer, uvcoordsvar.xy).r;
+ vec4 scene_col = texture2D(colorbuffer, uvcoordsvar.xy);
+
+ if (is_offscreen == 1.0) {
+ // early out for Ofs. Color management is done later by OCIO
+ gl_FragColor = scene_col;
+ return;
+ }
+
+ if (displayspace_is_srgb == 1.0)
+ srgb_to_linearrgb(scene_col, scene_col);
+
+ /* Esposure */
+ scene_col = vec4( computeExposedColor(scene_col.rgb, exposure), scene_col.a);
+
+ /* LUT 3D in linear space */
+ /* TODO find a way to apply it in gamma space to gain accuracy in the black areas */
+ //linearrgb_to_srgb(scene_col, scene_col);
+ scene_col = vec4( texture3D(lut3d_texture, scene_col.rgb * ((lut_size + 1.0f) / lut_size) + (0.5f / lut_size) ).rgb, scene_col.a);
+ //srgb_to_linearrgb(scene_col, scene_col);
+
+ /* Gamma */
+ scene_col = vec4( applyGamma(scene_col.rgb, gamma), scene_col.a);
+
+ gl_FragColor = vec4(scene_col.rgb, scene_col.a);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 119bfb61fec..2b506acabef 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -9,6 +9,11 @@ float convert_rgba_to_float(vec4 color)
#endif
}
+void convert_vec3_to_vec4(vec3 invec, float val, out vec4 outvec)
+{
+ outvec = vec4(invec, val);
+}
+
float exp_blender(float f)
{
return pow(2.71828182846, f);
@@ -157,7 +162,13 @@ void color_to_blender_normal_new_shading(vec3 color, out vec3 normal)
}
#define M_PI 3.14159265358979323846
+#define M_PI_2 1.57079632679489661923
+#define M_2PI 6.28318530717958647
+#define M_PI2 9.86960440108935861
#define M_1_PI 0.31830988618379069
+#define M_1_PI2 0.10132118364233777
+#define M_2_PI 0.63661977236758134
+#define M_1_2PI 0.15915494309189533
/*********** SHADER NODES ***************/
@@ -267,7 +278,7 @@ void camera(vec3 co, out vec3 outview, out float outdepth, out float outdist)
{
outdepth = abs(co.z);
outdist = length(co);
- outview = normalize(co);
+ outview = normalize(co*vec3(1.0,1.0,-1.0));
}
void lamp(
@@ -2376,1234 +2387,6 @@ void shade_alpha_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
outcol = vec4(col.rgb, col.a * obcol.a);
}
-/*********** NEW SHADER UTILITIES **************/
-
-float fresnel_dielectric(vec3 Incoming, vec3 Normal, float eta)
-{
- /* compute fresnel reflectance without explicitly computing
- * the refracted direction */
- float c = abs(dot(Incoming, Normal));
- float g = eta * eta - 1.0 + c * c;
- float result;
-
- if (g > 0.0) {
- g = sqrt(g);
- float A = (g - c) / (g + c);
- float B = (c * (g + c) - 1.0) / (c * (g - c) + 1.0);
- result = 0.5 * A * A * (1.0 + B * B);
- }
- else {
- result = 1.0; /* TIR (no refracted component) */
- }
-
- return result;
-}
-
-float hypot(float x, float y)
-{
- return sqrt(x * x + y * y);
-}
-
-void generated_from_orco(vec3 orco, out vec3 generated)
-{
- generated = orco * 0.5 + vec3(0.5);
-}
-
-int floor_to_int(float x)
-{
- return int(floor(x));
-}
-
-int quick_floor(float x)
-{
- return int(x) - ((x < 0) ? 1 : 0);
-}
-
-#ifdef BIT_OPERATIONS
-float integer_noise(int n)
-{
- int nn;
- n = (n + 1013) & 0x7fffffff;
- n = (n >> 13) ^ n;
- nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
- return 0.5 * (float(nn) / 1073741824.0);
-}
-
-uint hash(uint kx, uint ky, uint kz)
-{
-#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
-#define final(a, b, c) \
-{ \
- c ^= b; c -= rot(b, 14); \
- a ^= c; a -= rot(c, 11); \
- b ^= a; b -= rot(a, 25); \
- c ^= b; c -= rot(b, 16); \
- a ^= c; a -= rot(c, 4); \
- b ^= a; b -= rot(a, 14); \
- c ^= b; c -= rot(b, 24); \
-}
- // now hash the data!
- uint a, b, c, len = 3u;
- a = b = c = 0xdeadbeefu + (len << 2u) + 13u;
-
- c += kz;
- b += ky;
- a += kx;
- final (a, b, c);
-
- return c;
-#undef rot
-#undef final
-}
-
-uint hash(int kx, int ky, int kz)
-{
- return hash(uint(kx), uint(ky), uint(kz));
-}
-
-float bits_to_01(uint bits)
-{
- float x = float(bits) * (1.0 / float(0xffffffffu));
- return x;
-}
-
-float cellnoise(vec3 p)
-{
- int ix = quick_floor(p.x);
- int iy = quick_floor(p.y);
- int iz = quick_floor(p.z);
-
- return bits_to_01(hash(uint(ix), uint(iy), uint(iz)));
-}
-
-vec3 cellnoise_color(vec3 p)
-{
- float r = cellnoise(p);
- float g = cellnoise(vec3(p.y, p.x, p.z));
- float b = cellnoise(vec3(p.y, p.z, p.x));
-
- return vec3(r, g, b);
-}
-#endif // BIT_OPERATIONS
-
-float floorfrac(float x, out int i)
-{
- i = floor_to_int(x);
- return x - i;
-}
-
-/*********** NEW SHADER NODES ***************/
-
-#define NUM_LIGHTS 3
-
-/* bsdfs */
-
-void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result)
-{
- /* ambient light */
- vec3 L = vec3(0.2);
-
- /* directional lights */
- for (int i = 0; i < NUM_LIGHTS; i++) {
- vec3 light_position = gl_LightSource[i].position.xyz;
- vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
-
- float bsdf = max(dot(N, light_position), 0.0);
- L += light_diffuse * bsdf;
- }
-
- result = vec4(L * color.rgb, 1.0);
-}
-
-void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result)
-{
- /* ambient light */
- vec3 L = vec3(0.2);
-
- /* directional lights */
- for (int i = 0; i < NUM_LIGHTS; i++) {
- vec3 light_position = gl_LightSource[i].position.xyz;
- vec3 H = gl_LightSource[i].halfVector.xyz;
- vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
- vec3 light_specular = gl_LightSource[i].specular.rgb;
-
- /* we mix in some diffuse so low roughness still shows up */
- float bsdf = 0.5 * pow(max(dot(N, H), 0.0), 1.0 / roughness);
- bsdf += 0.5 * max(dot(N, light_position), 0.0);
- L += light_specular * bsdf;
- }
-
- result = vec4(L * color.rgb, 1.0);
-}
-
-void node_bsdf_anisotropic(
- vec4 color, float roughness, float anisotropy, float rotation, vec3 N, vec3 T,
- out vec4 result)
-{
- node_bsdf_diffuse(color, 0.0, N, result);
-}
-
-void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, out vec4 result)
-{
- node_bsdf_diffuse(color, 0.0, N, result);
-}
-
-void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out vec4 result)
-{
- node_bsdf_diffuse(color, 0.0, N, result);
-}
-
-void node_bsdf_translucent(vec4 color, vec3 N, out vec4 result)
-{
- node_bsdf_diffuse(color, 0.0, N, result);
-}
-
-void node_bsdf_transparent(vec4 color, out vec4 result)
-{
- /* this isn't right */
- result.r = color.r;
- result.g = color.g;
- result.b = color.b;
- result.a = 0.0;
-}
-
-void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out vec4 result)
-{
- node_bsdf_diffuse(color, 0.0, N, result);
-}
-
-void node_subsurface_scattering(
- vec4 color, float scale, vec3 radius, float sharpen, float texture_blur, vec3 N,
- out vec4 result)
-{
- node_bsdf_diffuse(color, 0.0, N, result);
-}
-
-void node_bsdf_hair(vec4 color, float offset, float roughnessu, float roughnessv, vec3 tangent, out vec4 result)
-{
- result = color;
-}
-
-void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out vec4 result)
-{
- node_bsdf_diffuse(color, 0.0, N, result);
-}
-
-void node_ambient_occlusion(vec4 color, out vec4 result)
-{
- result = color;
-}
-
-/* emission */
-
-void node_emission(vec4 color, float strength, vec3 N, out vec4 result)
-{
- result = color * strength;
-}
-
-/* background */
-
-void background_transform_to_world(vec3 viewvec, out vec3 worldvec)
-{
- vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
- vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
-
- vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
- worldvec = (gl_ModelViewMatrixInverse * co).xyz;
-}
-
-void node_background(vec4 color, float strength, vec3 N, out vec4 result)
-{
- result = color * strength;
-}
-
-/* closures */
-
-void node_mix_shader(float fac, vec4 shader1, vec4 shader2, out vec4 shader)
-{
- shader = mix(shader1, shader2, fac);
-}
-
-void node_add_shader(vec4 shader1, vec4 shader2, out vec4 shader)
-{
- shader = shader1 + shader2;
-}
-
-/* fresnel */
-
-void node_fresnel(float ior, vec3 N, vec3 I, out float result)
-{
- /* handle perspective/orthographic */
- vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
-
- float eta = max(ior, 0.00001);
- result = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? eta : 1.0 / eta);
-}
-
-/* layer_weight */
-
-void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float facing)
-{
- /* fresnel */
- float eta = max(1.0 - blend, 0.00001);
- vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
-
- fresnel = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? 1.0 / eta : eta);
-
- /* facing */
- facing = abs(dot(I_view, N));
- if (blend != 0.5) {
- blend = clamp(blend, 0.0, 0.99999);
- blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend);
- facing = pow(facing, blend);
- }
- facing = 1.0 - facing;
-}
-
-/* gamma */
-
-void node_gamma(vec4 col, float gamma, out vec4 outcol)
-{
- outcol = col;
-
- if (col.r > 0.0)
- outcol.r = compatible_pow(col.r, gamma);
- if (col.g > 0.0)
- outcol.g = compatible_pow(col.g, gamma);
- if (col.b > 0.0)
- outcol.b = compatible_pow(col.b, gamma);
-}
-
-/* geometry */
-
-void node_attribute(vec3 attr, out vec4 outcol, out vec3 outvec, out float outf)
-{
- outcol = vec4(attr, 1.0);
- outvec = attr;
- outf = (attr.x + attr.y + attr.z) / 3.0;
-}
-
-void node_uvmap(vec3 attr_uv, out vec3 outvec)
-{
- outvec = attr_uv;
-}
-
-void node_geometry(
- vec3 I, vec3 N, mat4 toworld,
- out vec3 position, out vec3 normal, out vec3 tangent,
- out vec3 true_normal, out vec3 incoming, out vec3 parametric,
- out float backfacing, out float pointiness)
-{
- position = (toworld * vec4(I, 1.0)).xyz;
- normal = (toworld * vec4(N, 0.0)).xyz;
- tangent = vec3(0.0);
- true_normal = normal;
-
- /* handle perspective/orthographic */
- vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
- incoming = -(toworld * vec4(I_view, 0.0)).xyz;
-
- parametric = vec3(0.0);
- backfacing = (gl_FrontFacing) ? 0.0 : 1.0;
- pointiness = 0.0;
-}
-
-void node_tex_coord(
- vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
- vec3 attr_orco, vec3 attr_uv,
- out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
- out vec3 camera, out vec3 window, out vec3 reflection)
-{
- generated = attr_orco * 0.5 + vec3(0.5);
- normal = normalize((obinvmat * (viewinvmat * vec4(N, 0.0))).xyz);
- uv = attr_uv;
- object = (obinvmat * (viewinvmat * vec4(I, 1.0))).xyz;
- camera = vec3(I.xy, -I.z);
- vec4 projvec = gl_ProjectionMatrix * vec4(I, 1.0);
- window = vec3(mtex_2d_mapping(projvec.xyz / projvec.w).xy * camerafac.xy + camerafac.zw, 0.0);
-
- vec3 shade_I;
- shade_view(I, shade_I);
- vec3 view_reflection = reflect(shade_I, normalize(N));
- reflection = (viewinvmat * vec4(view_reflection, 0.0)).xyz;
-}
-
-void node_tex_coord_background(
- vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
- vec3 attr_orco, vec3 attr_uv,
- out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
- out vec3 camera, out vec3 window, out vec3 reflection)
-{
- vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
- vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
-
- vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
-
- co = normalize(co);
- vec3 coords = (gl_ModelViewMatrixInverse * co).xyz;
-
- generated = coords;
- normal = -coords;
- uv = vec3(attr_uv.xy, 0.0);
- object = coords;
-
- camera = vec3(co.xy, -co.z);
- window = (gl_ProjectionMatrix[3][3] == 0.0) ?
- vec3(mtex_2d_mapping(I).xy * camerafac.xy + camerafac.zw, 0.0) :
- vec3(vec2(0.5) * camerafac.xy + camerafac.zw, 0.0);
-
- reflection = -coords;
-}
-
-/* textures */
-
-float calc_gradient(vec3 p, int gradient_type)
-{
- float x, y, z;
- x = p.x;
- y = p.y;
- z = p.z;
- if (gradient_type == 0) { /* linear */
- return x;
- }
- else if (gradient_type == 1) { /* quadratic */
- float r = max(x, 0.0);
- return r * r;
- }
- else if (gradient_type == 2) { /* easing */
- float r = min(max(x, 0.0), 1.0);
- float t = r * r;
- return (3.0 * t - 2.0 * t * r);
- }
- else if (gradient_type == 3) { /* diagonal */
- return (x + y) * 0.5;
- }
- else if (gradient_type == 4) { /* radial */
- return atan(y, x) / (M_PI * 2) + 0.5;
- }
- else {
- float r = max(1.0 - sqrt(x * x + y * y + z * z), 0.0);
- if (gradient_type == 5) { /* quadratic sphere */
- return r * r;
- }
- else if (gradient_type == 6) { /* sphere */
- return r;
- }
- }
- return 0.0;
-}
-
-void node_tex_gradient(vec3 co, float gradient_type, out vec4 color, out float fac)
-{
- float f = calc_gradient(co, int(gradient_type));
- f = clamp(f, 0.0, 1.0);
-
- color = vec4(f, f, f, 1.0);
- fac = f;
-}
-
-void node_tex_checker(vec3 co, vec4 color1, vec4 color2, float scale, out vec4 color, out float fac)
-{
- vec3 p = co * scale;
-
- /* Prevent precision issues on unit coordinates. */
- p.x = (p.x + 0.000001) * 0.999999;
- p.y = (p.y + 0.000001) * 0.999999;
- p.z = (p.z + 0.000001) * 0.999999;
-
- int xi = int(abs(floor(p.x)));
- int yi = int(abs(floor(p.y)));
- int zi = int(abs(floor(p.z)));
-
- bool check = ((mod(xi, 2) == mod(yi, 2)) == bool(mod(zi, 2)));
-
- color = check ? color1 : color2;
- fac = check ? 1.0 : 0.0;
-}
-
-#ifdef BIT_OPERATIONS
-vec2 calc_brick_texture(vec3 p, float mortar_size, float bias,
- float brick_width, float row_height,
- float offset_amount, int offset_frequency,
- float squash_amount, int squash_frequency)
-{
- int bricknum, rownum;
- float offset = 0.0;
- float x, y;
-
- rownum = floor_to_int(p.y / row_height);
-
- if (offset_frequency != 0 && squash_frequency != 0) {
- brick_width *= (rownum % squash_frequency != 0) ? 1.0 : squash_amount; /* squash */
- offset = (rownum % offset_frequency != 0) ? 0.0 : (brick_width * offset_amount); /* offset */
- }
-
- bricknum = floor_to_int((p.x + offset) / brick_width);
-
- x = (p.x + offset) - brick_width * bricknum;
- y = p.y - row_height * rownum;
-
- return vec2(clamp((integer_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias), 0.0, 1.0),
- (x < mortar_size || y < mortar_size ||
- x > (brick_width - mortar_size) ||
- y > (row_height - mortar_size)) ? 1.0 : 0.0);
-}
-#endif
-
-void node_tex_brick(vec3 co,
- vec4 color1, vec4 color2,
- vec4 mortar, float scale,
- float mortar_size, float bias,
- float brick_width, float row_height,
- float offset_amount, float offset_frequency,
- float squash_amount, float squash_frequency,
- out vec4 color, out float fac)
-{
-#ifdef BIT_OPERATIONS
- vec2 f2 = calc_brick_texture(co * scale,
- mortar_size, bias,
- brick_width, row_height,
- offset_amount, int(offset_frequency),
- squash_amount, int(squash_frequency));
- float tint = f2.x;
- float f = f2.y;
- if (f != 1.0) {
- float facm = 1.0 - tint;
- color1 = facm * color1 + tint * color2;
- }
- color = (f == 1.0) ? mortar : color1;
- fac = f;
-#else
- color = vec4(1.0);
- fac = 1.0;
-#endif
-}
-
-void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac)
-{
- color = vec4(1.0);
- fac = 1.0;
-}
-
-void node_tex_environment_equirectangular(vec3 co, sampler2D ima, out vec4 color)
-{
- vec3 nco = normalize(co);
- float u = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5;
- float v = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5;
-
- color = texture2D(ima, vec2(u, v));
-}
-
-void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color)
-{
- vec3 nco = normalize(co);
-
- nco.y -= 1.0;
-
- float div = 2.0 * sqrt(max(-0.5 * nco.y, 0.0));
- if (div > 0.0)
- nco /= div;
-
- float u = 0.5 * (nco.x + 1.0);
- float v = 0.5 * (nco.z + 1.0);
-
- color = texture2D(ima, vec2(u, v));
-}
-
-void node_tex_environment_empty(vec3 co, out vec4 color)
-{
- color = vec4(1.0, 0.0, 1.0, 1.0);
-}
-
-void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha)
-{
- color = texture2D(ima, co.xy);
- alpha = color.a;
-}
-
-void node_tex_image_box(vec3 texco,
- vec3 nob,
- sampler2D ima,
- float blend,
- out vec4 color,
- out float alpha)
-{
- /* project from direction vector to barycentric coordinates in triangles */
- nob = vec3(abs(nob.x), abs(nob.y), abs(nob.z));
- nob /= (nob.x + nob.y + nob.z);
-
- /* basic idea is to think of this as a triangle, each corner representing
- * one of the 3 faces of the cube. in the corners we have single textures,
- * in between we blend between two textures, and in the middle we a blend
- * between three textures.
- *
- * the Nxyz values are the barycentric coordinates in an equilateral
- * triangle, which in case of blending, in the middle has a smaller
- * equilateral triangle where 3 textures blend. this divides things into
- * 7 zones, with an if () test for each zone */
-
- vec3 weight = vec3(0.0, 0.0, 0.0);
- float limit = 0.5 * (1.0 + blend);
-
- /* first test for corners with single texture */
- if (nob.x > limit * (nob.x + nob.y) && nob.x > limit * (nob.x + nob.z)) {
- weight.x = 1.0;
- }
- else if (nob.y > limit * (nob.x + nob.y) && nob.y > limit * (nob.y + nob.z)) {
- weight.y = 1.0;
- }
- else if (nob.z > limit * (nob.x + nob.z) && nob.z > limit * (nob.y + nob.z)) {
- weight.z = 1.0;
- }
- else if (blend > 0.0) {
- /* in case of blending, test for mixes between two textures */
- if (nob.z < (1.0 - limit) * (nob.y + nob.x)) {
- weight.x = nob.x / (nob.x + nob.y);
- weight.x = clamp((weight.x - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
- weight.y = 1.0 - weight.x;
- }
- else if (nob.x < (1.0 - limit) * (nob.y + nob.z)) {
- weight.y = nob.y / (nob.y + nob.z);
- weight.y = clamp((weight.y - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
- weight.z = 1.0 - weight.y;
- }
- else if (nob.y < (1.0 - limit) * (nob.x + nob.z)) {
- weight.x = nob.x / (nob.x + nob.z);
- weight.x = clamp((weight.x - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
- weight.z = 1.0 - weight.x;
- }
- else {
- /* last case, we have a mix between three */
- weight.x = ((2.0 - limit) * nob.x + (limit - 1.0)) / (2.0 * limit - 1.0);
- weight.y = ((2.0 - limit) * nob.y + (limit - 1.0)) / (2.0 * limit - 1.0);
- weight.z = ((2.0 - limit) * nob.z + (limit - 1.0)) / (2.0 * limit - 1.0);
- }
- }
- else {
- /* Desperate mode, no valid choice anyway, fallback to one side.*/
- weight.x = 1.0;
- }
- color = vec4(0);
- if (weight.x > 0.0) {
- color += weight.x * texture2D(ima, texco.yz);
- }
- if (weight.y > 0.0) {
- color += weight.y * texture2D(ima, texco.xz);
- }
- if (weight.z > 0.0) {
- color += weight.z * texture2D(ima, texco.yx);
- }
-
- alpha = color.a;
-}
-
-void node_tex_image_empty(vec3 co, out vec4 color, out float alpha)
-{
- color = vec4(0.0);
- alpha = 0.0;
-}
-
-void node_tex_magic(vec3 co, float scale, float distortion, float depth, out vec4 color, out float fac)
-{
- vec3 p = co * scale;
- float x = sin((p.x + p.y + p.z) * 5.0);
- float y = cos((-p.x + p.y - p.z) * 5.0);
- float z = -cos((-p.x - p.y + p.z) * 5.0);
-
- if (depth > 0) {
- x *= distortion;
- y *= distortion;
- z *= distortion;
- y = -cos(x - y + z);
- y *= distortion;
- if (depth > 1) {
- x = cos(x - y - z);
- x *= distortion;
- if (depth > 2) {
- z = sin(-x - y - z);
- z *= distortion;
- if (depth > 3) {
- x = -cos(-x + y - z);
- x *= distortion;
- if (depth > 4) {
- y = -sin(-x + y + z);
- y *= distortion;
- if (depth > 5) {
- y = -cos(-x + y + z);
- y *= distortion;
- if (depth > 6) {
- x = cos(x + y + z);
- x *= distortion;
- if (depth > 7) {
- z = sin(x + y - z);
- z *= distortion;
- if (depth > 8) {
- x = -cos(-x - y + z);
- x *= distortion;
- if (depth > 9) {
- y = -sin(x - y + z);
- y *= distortion;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- if (distortion != 0.0) {
- distortion *= 2.0;
- x /= distortion;
- y /= distortion;
- z /= distortion;
- }
-
- color = vec4(0.5 - x, 0.5 - y, 0.5 - z, 1.0);
- fac = (color.x + color.y + color.z) / 3.0;
-}
-
-#ifdef BIT_OPERATIONS
-float noise_fade(float t)
-{
- return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
-}
-
-float noise_scale3(float result)
-{
- return 0.9820 * result;
-}
-
-float noise_nerp(float t, float a, float b)
-{
- return (1.0 - t) * a + t * b;
-}
-
-float noise_grad(uint hash, float x, float y, float z)
-{
- uint h = hash & 15u;
- float u = h < 8u ? x : y;
- float vt = ((h == 12u) || (h == 14u)) ? x : z;
- float v = h < 4u ? y : vt;
- return (((h & 1u) != 0u) ? -u : u) + (((h & 2u) != 0u) ? -v : v);
-}
-
-float noise_perlin(float x, float y, float z)
-{
- int X; float fx = floorfrac(x, X);
- int Y; float fy = floorfrac(y, Y);
- int Z; float fz = floorfrac(z, Z);
-
- float u = noise_fade(fx);
- float v = noise_fade(fy);
- float w = noise_fade(fz);
-
- float result;
-
- result = noise_nerp(w, noise_nerp(v, noise_nerp(u, noise_grad(hash(X, Y, Z), fx, fy, fz),
- noise_grad(hash(X + 1, Y, Z), fx - 1.0, fy, fz)),
- noise_nerp(u, noise_grad(hash(X, Y + 1, Z), fx, fy - 1.0, fz),
- noise_grad(hash(X + 1, Y + 1, Z), fx - 1.0, fy - 1.0, fz))),
- noise_nerp(v, noise_nerp(u, noise_grad(hash(X, Y, Z + 1), fx, fy, fz - 1.0),
- noise_grad(hash(X + 1, Y, Z + 1), fx - 1.0, fy, fz - 1.0)),
- noise_nerp(u, noise_grad(hash(X, Y + 1, Z + 1), fx, fy - 1.0, fz - 1.0),
- noise_grad(hash(X + 1, Y + 1, Z + 1), fx - 1.0, fy - 1.0, fz - 1.0))));
- return noise_scale3(result);
-}
-
-float noise(vec3 p)
-{
- return 0.5 * noise_perlin(p.x, p.y, p.z) + 0.5;
-}
-
-float snoise(vec3 p)
-{
- return noise_perlin(p.x, p.y, p.z);
-}
-
-float noise_turbulence(vec3 p, float octaves, int hard)
-{
- float fscale = 1.0;
- float amp = 1.0;
- float sum = 0.0;
- int i, n;
- octaves = clamp(octaves, 0.0, 16.0);
- n = int(octaves);
- for (i = 0; i <= n; i++) {
- float t = noise(fscale * p);
- if (hard != 0) {
- t = abs(2.0 * t - 1.0);
- }
- sum += t * amp;
- amp *= 0.5;
- fscale *= 2.0;
- }
- float rmd = octaves - floor(octaves);
- if (rmd != 0.0) {
- float t = noise(fscale * p);
- if (hard != 0) {
- t = abs(2.0 * t - 1.0);
- }
- float sum2 = sum + t * amp;
- sum *= (float(1 << n) / float((1 << (n + 1)) - 1));
- sum2 *= (float(1 << (n + 1)) / float((1 << (n + 2)) - 1));
- return (1.0 - rmd) * sum + rmd * sum2;
- }
- else {
- sum *= (float(1 << n) / float((1 << (n + 1)) - 1));
- return sum;
- }
-}
-#endif // BIT_OPERATIONS
-
-void node_tex_noise(vec3 co, float scale, float detail, float distortion, out vec4 color, out float fac)
-{
-#ifdef BIT_OPERATIONS
- vec3 p = co * scale;
- int hard = 0;
- if (distortion != 0.0) {
- vec3 r, offset = vec3(13.5, 13.5, 13.5);
- r.x = noise(p + offset) * distortion;
- r.y = noise(p) * distortion;
- r.z = noise(p - offset) * distortion;
- p += r;
- }
-
- fac = noise_turbulence(p, detail, hard);
- color = vec4(fac,
- noise_turbulence(vec3(p.y, p.x, p.z), detail, hard),
- noise_turbulence(vec3(p.y, p.z, p.x), detail, hard),
- 1);
-#else // BIT_OPERATIONS
- color = vec4(1.0);
- fac = 1.0;
-#endif // BIT_OPERATIONS
-}
-
-
-#ifdef BIT_OPERATIONS
-
-/* Musgrave fBm
- *
- * H: fractal increment parameter
- * lacunarity: gap between successive frequencies
- * octaves: number of frequencies in the fBm
- *
- * from "Texturing and Modelling: A procedural approach"
- */
-
-float noise_musgrave_fBm(vec3 p, float H, float lacunarity, float octaves)
-{
- float rmd;
- float value = 0.0;
- float pwr = 1.0;
- float pwHL = pow(lacunarity, -H);
- int i;
-
- for (i = 0; i < int(octaves); i++) {
- value += snoise(p) * pwr;
- pwr *= pwHL;
- p *= lacunarity;
- }
-
- rmd = octaves - floor(octaves);
- if (rmd != 0.0)
- value += rmd * snoise(p) * pwr;
-
- return value;
-}
-
-/* Musgrave Multifractal
- *
- * H: highest fractal dimension
- * lacunarity: gap between successive frequencies
- * octaves: number of frequencies in the fBm
- */
-
-float noise_musgrave_multi_fractal(vec3 p, float H, float lacunarity, float octaves)
-{
- float rmd;
- float value = 1.0;
- float pwr = 1.0;
- float pwHL = pow(lacunarity, -H);
- int i;
-
- for (i = 0; i < int(octaves); i++) {
- value *= (pwr * snoise(p) + 1.0);
- pwr *= pwHL;
- p *= lacunarity;
- }
-
- rmd = octaves - floor(octaves);
- if (rmd != 0.0)
- value *= (rmd * pwr * snoise(p) + 1.0); /* correct? */
-
- return value;
-}
-
-/* Musgrave Heterogeneous Terrain
- *
- * H: fractal dimension of the roughest area
- * lacunarity: gap between successive frequencies
- * octaves: number of frequencies in the fBm
- * offset: raises the terrain from `sea level'
- */
-
-float noise_musgrave_hetero_terrain(vec3 p, float H, float lacunarity, float octaves, float offset)
-{
- float value, increment, rmd;
- float pwHL = pow(lacunarity, -H);
- float pwr = pwHL;
- int i;
-
- /* first unscaled octave of function; later octaves are scaled */
- value = offset + snoise(p);
- p *= lacunarity;
-
- for (i = 1; i < int(octaves); i++) {
- increment = (snoise(p) + offset) * pwr * value;
- value += increment;
- pwr *= pwHL;
- p *= lacunarity;
- }
-
- rmd = octaves - floor(octaves);
- if (rmd != 0.0) {
- increment = (snoise(p) + offset) * pwr * value;
- value += rmd * increment;
- }
-
- return value;
-}
-
-/* Hybrid Additive/Multiplicative Multifractal Terrain
- *
- * H: fractal dimension of the roughest area
- * lacunarity: gap between successive frequencies
- * octaves: number of frequencies in the fBm
- * offset: raises the terrain from `sea level'
- */
-
-float noise_musgrave_hybrid_multi_fractal(vec3 p, float H, float lacunarity, float octaves, float offset, float gain)
-{
- float result, signal, weight, rmd;
- float pwHL = pow(lacunarity, -H);
- float pwr = pwHL;
- int i;
-
- result = snoise(p) + offset;
- weight = gain * result;
- p *= lacunarity;
-
- for (i = 1; (weight > 0.001f) && (i < int(octaves)); i++) {
- if (weight > 1.0)
- weight = 1.0;
-
- signal = (snoise(p) + offset) * pwr;
- pwr *= pwHL;
- result += weight * signal;
- weight *= gain * signal;
- p *= lacunarity;
- }
-
- rmd = octaves - floor(octaves);
- if (rmd != 0.0)
- result += rmd * ((snoise(p) + offset) * pwr);
-
- return result;
-}
-
-/* Ridged Multifractal Terrain
- *
- * H: fractal dimension of the roughest area
- * lacunarity: gap between successive frequencies
- * octaves: number of frequencies in the fBm
- * offset: raises the terrain from `sea level'
- */
-
-float noise_musgrave_ridged_multi_fractal(vec3 p, float H, float lacunarity, float octaves, float offset, float gain)
-{
- float result, signal, weight;
- float pwHL = pow(lacunarity, -H);
- float pwr = pwHL;
- int i;
-
- signal = offset - abs(snoise(p));
- signal *= signal;
- result = signal;
- weight = 1.0;
-
- for (i = 1; i < int(octaves); i++) {
- p *= lacunarity;
- weight = clamp(signal * gain, 0.0, 1.0);
- signal = offset - abs(snoise(p));
- signal *= signal;
- signal *= weight;
- result += signal * pwr;
- pwr *= pwHL;
- }
-
- return result;
-}
-
-float svm_musgrave(int type,
- float dimension,
- float lacunarity,
- float octaves,
- float offset,
- float intensity,
- float gain,
- vec3 p)
-{
- if (type == 0 /*NODE_MUSGRAVE_MULTIFRACTAL*/)
- return intensity * noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves);
- else if (type == 1 /*NODE_MUSGRAVE_FBM*/)
- return intensity * noise_musgrave_fBm(p, dimension, lacunarity, octaves);
- else if (type == 2 /*NODE_MUSGRAVE_HYBRID_MULTIFRACTAL*/)
- return intensity * noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
- else if (type == 3 /*NODE_MUSGRAVE_RIDGED_MULTIFRACTAL*/)
- return intensity * noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
- else if (type == 4 /*NODE_MUSGRAVE_HETERO_TERRAIN*/)
- return intensity * noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, offset);
- return 0.0;
-}
-#endif // #ifdef BIT_OPERATIONS
-
-void node_tex_musgrave(vec3 co,
- float scale,
- float detail,
- float dimension,
- float lacunarity,
- float offset,
- float gain,
- float type,
- out vec4 color,
- out float fac)
-{
-#ifdef BIT_OPERATIONS
- fac = svm_musgrave(int(type),
- dimension,
- lacunarity,
- detail,
- offset,
- 1.0,
- gain,
- co * scale);
-#else
- fac = 1.0;
-#endif
-
- color = vec4(fac, fac, fac, 1.0);
-}
-
-void node_tex_sky(vec3 co, out vec4 color)
-{
- color = vec4(1.0);
-}
-
-void node_tex_voronoi(vec3 co, float scale, float coloring, out vec4 color, out float fac)
-{
-#ifdef BIT_OPERATIONS
- vec3 p = co * scale;
- int xx, yy, zz, xi, yi, zi;
- float da[4];
- vec3 pa[4];
-
- xi = floor_to_int(p[0]);
- yi = floor_to_int(p[1]);
- zi = floor_to_int(p[2]);
-
- da[0] = 1e+10;
- da[1] = 1e+10;
- da[2] = 1e+10;
- da[3] = 1e+10;
-
- for (xx = xi - 1; xx <= xi + 1; xx++) {
- for (yy = yi - 1; yy <= yi + 1; yy++) {
- for (zz = zi - 1; zz <= zi + 1; zz++) {
- vec3 ip = vec3(xx, yy, zz);
- vec3 vp = cellnoise_color(ip);
- vec3 pd = p - (vp + ip);
- float d = dot(pd, pd);
- vp += vec3(xx, yy, zz);
- if (d < da[0]) {
- da[3] = da[2];
- da[2] = da[1];
- da[1] = da[0];
- da[0] = d;
- pa[3] = pa[2];
- pa[2] = pa[1];
- pa[1] = pa[0];
- pa[0] = vp;
- }
- else if (d < da[1]) {
- da[3] = da[2];
- da[2] = da[1];
- da[1] = d;
-
- pa[3] = pa[2];
- pa[2] = pa[1];
- pa[1] = vp;
- }
- else if (d < da[2]) {
- da[3] = da[2];
- da[2] = d;
-
- pa[3] = pa[2];
- pa[2] = vp;
- }
- else if (d < da[3]) {
- da[3] = d;
- pa[3] = vp;
- }
- }
- }
- }
-
- if (coloring == 0.0) {
- fac = abs(da[0]);
- color = vec4(fac, fac, fac, 1);
- }
- else {
- color = vec4(cellnoise_color(pa[0]), 1);
- fac = (color.x + color.y + color.z) * (1.0 / 3.0);
- }
-#else // BIT_OPERATIONS
- color = vec4(1.0);
- fac = 1.0;
-#endif // BIT_OPERATIONS
-}
-
-#ifdef BIT_OPERATIONS
-float calc_wave(vec3 p, float distortion, float detail, float detail_scale, int wave_type, int wave_profile)
-{
- float n;
-
- if (wave_type == 0) /* type bands */
- n = (p.x + p.y + p.z) * 10.0;
- else /* type rings */
- n = length(p) * 20.0;
-
- if (distortion != 0.0)
- n += distortion * noise_turbulence(p * detail_scale, detail, 0);
-
- if (wave_profile == 0) { /* profile sin */
- return 0.5 + 0.5 * sin(n);
- }
- else { /* profile saw */
- n /= 2.0 * M_PI;
- n -= int(n);
- return (n < 0.0) ? n + 1.0 : n;
- }
-}
-#endif // BIT_OPERATIONS
-
-void node_tex_wave(
- vec3 co, float scale, float distortion, float detail, float detail_scale, float wave_type, float wave_profile,
- out vec4 color, out float fac)
-{
-#ifdef BIT_OPERATIONS
- float f;
- f = calc_wave(co * scale, distortion, detail, detail_scale, int(wave_type), int(wave_profile));
-
- color = vec4(f, f, f, 1.0);
- fac = f;
-#else // BIT_OPERATIONS
- color = vec4(1.0);
- fac = 1;
-#endif // BIT_OPERATIONS
-}
-
-/* light path */
-
-void node_light_path(
- out float is_camera_ray,
- out float is_shadow_ray,
- out float is_diffuse_ray,
- out float is_glossy_ray,
- out float is_singular_ray,
- out float is_reflection_ray,
- out float is_transmission_ray,
- out float ray_length,
- out float ray_depth,
- out float transparent_depth,
- out float transmission_depth)
-{
- is_camera_ray = 1.0;
- is_shadow_ray = 0.0;
- is_diffuse_ray = 0.0;
- is_glossy_ray = 0.0;
- is_singular_ray = 0.0;
- is_reflection_ray = 0.0;
- is_transmission_ray = 0.0;
- ray_length = 1.0;
- ray_depth = 1.0;
- transparent_depth = 1.0;
- transmission_depth = 1.0;
-}
-
-void node_light_falloff(float strength, float tsmooth, out float quadratic, out float linear, out float constant)
-{
- quadratic = strength;
- linear = strength;
- constant = strength;
-}
-
-void node_object_info(out vec3 location, out float object_index, out float material_index, out float random)
-{
- location = vec3(0.0);
- object_index = 0.0;
- material_index = 0.0;
- random = 0.0;
-}
-
-void node_normal_map(vec4 tangent, vec3 normal, vec3 texnormal, out vec3 outnormal)
-{
- vec3 B = tangent.w * cross(normal, tangent.xyz);
-
- outnormal = texnormal.x * tangent.xyz + texnormal.y * B + texnormal.z * normal;
- outnormal = normalize(outnormal);
-}
-
-void node_bump(float strength, float dist, float height, vec3 N, vec3 surf_pos, float invert, out vec3 result)
-{
- if (invert != 0.0) {
- dist *= -1.0;
- }
- vec3 dPdx = dFdx(surf_pos);
- vec3 dPdy = dFdy(surf_pos);
-
- /* Get surface tangents from normal. */
- vec3 Rx = cross(dPdy, N);
- vec3 Ry = cross(N, dPdx);
-
- /* Compute surface gradient and determinant. */
- float det = dot(dPdx, Rx);
- float absdet = abs(det);
-
- float dHdx = dFdx(height);
- float dHdy = dFdy(height);
- vec3 surfgrad = dHdx * Rx + dHdy * Ry;
-
- strength = max(strength, 0.0);
-
- result = normalize(absdet * N - dist * sign(det) * surfgrad);
- result = normalize(strength * result + (1.0 - strength) * N);
-}
-
-/* output */
-
-void node_output_material(vec4 surface, vec4 volume, float displacement, out vec4 result)
-{
- result = surface;
-}
-
-void node_output_world(vec4 surface, vec4 volume, out vec4 result)
-{
- result = surface;
-}
-
/* ********************** matcap style render ******************** */
void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out vec4 result)
diff --git a/source/blender/gpu/shaders/gpu_shader_material_bsdf_ambient_occlusion.glsl b/source/blender/gpu/shaders/gpu_shader_material_bsdf_ambient_occlusion.glsl
new file mode 100644
index 00000000000..a7f594a29f5
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_material_bsdf_ambient_occlusion.glsl
@@ -0,0 +1,160 @@
+/* -------- Utils Functions --------- */
+vec2 sample_disk(float nsample, float invsamplenbr)
+{
+ vec3 Xi = hammersley_3d(nsample, invsamplenbr);
+
+ float x = Xi.x * Xi.y;
+ float y = Xi.x * Xi.z;
+
+ return vec2(x, y);
+}
+
+vec3 sample_hemisphere(float nsample, float invsamplenbr, vec3 N, vec3 T, vec3 B)
+{
+ vec3 Xi = hammersley_3d(nsample, invsamplenbr);
+
+ float z = Xi.x; /* cos theta */
+ float r = sqrt( 1.0f - z*z ); /* sin theta */
+ float x = r * Xi.y;
+ float y = r * Xi.z;
+
+ Ht = vec3(x, y, z); /* Global variable */
+
+ return from_tangent_to_world(Ht, N, T, B);
+}
+
+#ifdef USE_SSAO
+
+#if 0 /* Cheap */
+
+float ssao(vec3 viewpos, vec3 viewnor, out float result)
+{
+ float dist = unfssaoparam.z;
+ setup_noise(gl_FragCoord.xy); /* Noise to dither the samples */
+
+ /* get uv of the shading point */
+ vec4 projvec = gl_ProjectionMatrix * vec4(viewpos, 1.0);
+ vec2 uv = (projvec.xy / projvec.w) * 0.5 + 0.5;
+
+ vec2 offset;
+ offset.x = gl_ProjectionMatrix[0][0] * dist / projvec.w;
+ offset.y = gl_ProjectionMatrix[1][1] * dist / projvec.w;
+ /* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */
+ offset *= 0.5;
+
+ float factor = 0.0;
+ /* We don't need as much samples for ssao */
+ for (float i = 0; i < unfssaoparam.x; i++) {
+ vec2 Xi = sample_disk(i, 1/unfssaoparam.x);
+ vec2 uvsample = uv + Xi * offset;
+
+ if (uvsample.x > 1.0 || uvsample.x < 0.0 || uvsample.y > 1.0 || uvsample.y < 0.0)
+ continue;
+
+ float sampledepth = frontface_depth_linear(ivec2(uvsample * unfclip.zw));
+
+ /* Background Case */
+ if (sampledepth == 1.0)
+ continue;
+
+ vec3 samplepos = position_from_depth(uvsample, sampledepth);
+
+ vec3 dir = samplepos - viewpos;
+ float len = length(dir);
+ float f = dot(dir, viewnor);
+
+ /* use minor bias here to cancel self shadowing */
+ if (f > 0.05 * len + 0.0001)
+ factor += f / (len + len * len * len);
+ }
+
+ result = saturate(1.0 - factor / unfssaoparam.x);
+}
+
+#else /* Expensive */
+
+void ssao(vec3 viewpos, vec3 viewnor, out float result)
+{
+ float dist = unfssaoparam.z;
+ setup_noise(gl_FragCoord.xy); /* Noise to dither the samples */
+
+ vec3 T;
+ make_orthonormals(viewnor, T, B); /* Generate tangent space */
+
+ float homcoord = (gl_ProjectionMatrix[3][3] == 0.0) ? gl_ProjectionMatrix[2][3] * viewpos.z : dist;
+
+ float factor = 0.0;
+ float weight = 0.0;
+
+ for (float i = 0; i < unfssaoparam.x; i++) {
+ vec3 Xi = sample_hemisphere(i, 1/unfssaoparam.x, viewnor, T, B);
+
+ float pdf = dot(Xi, viewnor);
+ weight += pdf;
+
+ /* Raymarch */
+ /* We jitter the starting position by a percentage of the normal
+ * offset to a v o i d banding artifact for thin objects but
+ * we still finish at the same final position to a v o i d
+ * less sampling at the edges of the occlusion effect */
+ vec3 offset = dist * Xi / unfssaoparam.y;
+ vec3 ray = (jitternoise.y - 0.5) * -offset;
+ vec3 endoffset = offset - ray;
+
+ for (float j = unfssaoparam.y; j > 0.0; j--) {
+
+ ray += (j == 1) ? endoffset : offset;
+
+ vec4 co = unfpixelprojmat * vec4(ray + viewpos, 1.0);
+ co.xy /= co.w;
+
+ /* Discard ray leaving screen */
+ if (co.x > unfclip.z || co.x < 0.0 || co.y > unfclip.w || co.y < 0.0)
+ break;
+
+ float sampledepth = frontface_depth_linear(ivec2(co.xy), 0);
+
+ /* Background Case */
+ if (sampledepth == 1.0)
+ continue;
+
+ /* We have a hit */
+ if (sampledepth > ray.z + viewpos.z + homcoord * 0.002
+#ifdef USE_BACKFACE
+ && backface_depth_linear(ivec2(co.xy), 0) < ray.z + viewpos.z
+#endif
+ )
+ {
+ factor += pdf;
+ break;
+ }
+ }
+ }
+
+ result = saturate(1.0 - (factor / weight) * unfssaoparam.w);
+}
+#endif
+#else
+void ssao(vec3 viewpos, vec3 viewnor, out float result)
+{
+ result = 1.0;
+}
+#endif
+
+
+/* -------- BSDF --------- */
+
+/* -------- Preview Lights --------- */
+
+/* -------- Physical Lights --------- */
+
+/* -------- Image Based Lighting --------- */
+
+void env_sampling_ambient_occlusion(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ result = vec3(ao_factor);
+} \ No newline at end of file
diff --git a/source/blender/gpu/shaders/gpu_shader_material_bsdf_anisotropic.glsl b/source/blender/gpu/shaders/gpu_shader_material_bsdf_anisotropic.glsl
new file mode 100644
index 00000000000..cad9e28037a
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_material_bsdf_anisotropic.glsl
@@ -0,0 +1,772 @@
+/* -------- Utils Functions --------- */
+
+/* From
+ * Importance Sampling Microfacet-Based BSDFs with the Distribution of Visible Normals
+ * Supplemental Material 2/2 */
+vec3 sample_ggx_aniso(float nsample, float ax, float ay, vec3 N, vec3 T, vec3 B)
+{
+ vec3 Xi = hammersley_3d(nsample);
+
+ float tmp = sqrt( Xi.x / (1.0 - Xi.x) );
+
+ float x = ax * tmp * Xi.y;
+ float y = ay * tmp * Xi.z;
+
+ Ht = normalize(vec3(x, y, 1.0)); /* Global variable */
+
+ return from_tangent_to_world(Ht, N, T, B);
+}
+
+vec3 sample_beckmann_aniso(float nsample, float ax, float ay, vec3 N, vec3 T, vec3 B)
+{
+ vec3 Xi = hammersley_3d(nsample);
+
+ float tmp = sqrt( -log(Xi.x) );
+
+ float x = ax * tmp * Xi.y;
+ float y = ay * tmp * Xi.z;
+
+ Ht = normalize(vec3(x, y, 1.0)); /* Global variable */
+
+ return from_tangent_to_world(Ht, N, T, B);
+}
+
+float bsdf_ashikhmin_shirley_sample_first_quadrant(float n_x, float n_y, inout vec3 Xi, out float phi)
+{
+ phi = atan(sqrt((n_x + 1.0) / (n_y + 1.0)) * (Xi.z / Xi.y));
+ Xi.y = cos(phi);
+ Xi.z = sin(phi);
+ return pow(Xi.x, 1.0 / (n_x * Xi.y*Xi.y + n_y * Xi.z*Xi.z + 1.0));
+}
+
+vec3 sample_ashikhmin_shirley_aniso(float nsample, float n_x, float n_y, vec3 N, vec3 T, vec3 B)
+{
+ vec3 Xi = hammersley_3d(nsample);
+ float phi, z;
+
+ if(Xi.x < 0.25) { /* first quadrant */
+ Xi.x = 4.0 * Xi.x;
+ z = bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, Xi, phi);
+ }
+ else if(Xi.x < 0.5) { /* second quadrant */
+ Xi.x = 4.0 * (.5 - Xi.x);
+ z = bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, Xi, phi);
+ phi = M_PI - phi;
+ Xi.y = cos(phi);
+ Xi.z = sin(phi);
+ }
+ else if(Xi.x < 0.75) { /* third quadrant */
+ Xi.x = 4.0 * (Xi.x - 0.5);
+ z = bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, Xi, phi);
+ phi = M_PI + phi;
+ Xi.y = cos(phi);
+ Xi.z = sin(phi);
+ }
+ else { /* fourth quadrant */
+ Xi.x = 4.0 * (1.0 - Xi.x);
+ z = bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, Xi, phi);
+ phi = M_2PI - phi;
+ Xi.y = cos(phi);
+ Xi.z = sin(phi);
+ }
+
+ float r = sqrt( 1.0 - z * z ); /* sin theta */
+ float x = r * Xi.y;
+ float y = r * Xi.z;
+
+ Ht = vec3(x, y, z); /* Global variable */
+
+ return from_tangent_to_world(Ht, N, T, B);
+}
+
+float D_ggx_aniso_opti(float NH, float XH2, float YH2, float a2, float ax2, float ay2)
+{
+ float tmp = NH*NH + XH2/ax2 + YH2/ay2; /* Distributing NH² */
+ return M_PI * a2 * tmp*tmp; /* Doing RCP at the end */
+}
+
+float D_beckmann_aniso(float NH, float XH, float YH, float a2, float ax, float ay)
+{
+ float sx = -XH / (NH * ax);
+ float sy = -YH / (NH * ay);
+
+ float NH2 = NH * NH;
+
+ return exp(-sx*sx - sy*sy) / (M_PI * a2 * NH2 * NH2);
+}
+
+float pdf_ggx_aniso(float NH, float XH2, float YH2, float a2, float ax2, float ay2)
+{
+ float D = D_ggx_aniso_opti(NH, XH2, YH2, a2, ax2, ay2);
+ return NH / D;
+}
+
+float pdf_beckmann_aniso(float NH, float XH, float YH, float a2, float ax, float ay)
+{
+ float D = D_beckmann_aniso(NH, XH, YH, a2, ax, ay);
+ return NH / D;
+}
+
+float pdf_ashikhmin_shirley_aniso(float NH, float VH, float XH2, float YH2, float n_x, float n_y)
+{
+ float e = (n_x * XH2 + n_y * YH2) / (1.0 - NH*NH);
+ float lobe = pow(NH, e);
+ float norm = sqrt((n_x + 1.0)*(n_y + 1.0)) * 0.125 * M_1_PI;
+
+ return norm * lobe / VH;
+}
+
+/* TODO : this could be precomputed */
+void prepare_aniso(vec3 N, float roughness, float rotation, inout vec3 T, inout float anisotropy, out float rough_x, out float rough_y)
+{
+ anisotropy = clamp(anisotropy, -0.99, 0.99);
+
+ if (anisotropy < 0.0) {
+ rough_x = roughness / (1.0 + anisotropy);
+ rough_y = roughness * (1.0 + anisotropy);
+ }
+ else {
+ rough_x = roughness * (1.0 - anisotropy);
+ rough_y = roughness / (1.0 - anisotropy);
+ }
+
+ T = axis_angle_rotation(T, N, rotation * M_2PI); /* rotate tangent around normal */
+}
+
+/* -------- BSDF --------- */
+
+float bsdf_ggx_aniso(vec3 N, vec3 T, vec3 L, vec3 V, float roughness_x, float roughness_y)
+{
+ /* GGX Spec Anisotropic */
+ /* A few note about notations :
+ * I is the cycles term for Incoming Light, Noted L here (light vector)
+ * Omega (O) is the cycles term for the Outgoing Light, Noted V here (View vector) */
+ N = normalize(N);
+ vec3 X = T, Y, Z = N; /* Inside cycles Z=Normal; X=Tangent; Y=Bitangent; */
+ make_orthonormals_tangent(Z, X, Y);
+ vec3 H = normalize(L + V);
+
+ float ax, ax2; prepare_glossy(roughness_x, ax, ax2);
+ float ay, ay2; prepare_glossy(roughness_y, ay, ay2);
+ float a2 = ax*ay;
+
+ float NH = max(1e-8, dot(N, H));
+ float NL = max(1e-8, dot(N, L));
+ float NV = max(1e-8, dot(N, V));
+ float VX2 = pow(dot(V, X), 2); /* cosPhiO² */
+ float VY2 = pow(dot(V, Y), 2); /* sinPhiO² */
+ float LX2 = pow(dot(L, X), 2); /* cosPhiI² */
+ float LY2 = pow(dot(L, Y), 2); /* sinPhiI² */
+ float XH2 = pow(dot(X, H), 2);
+ float YH2 = pow(dot(Y, H), 2);
+
+ /* G_Smith_GGX */
+ float alphaV2 = (VX2 * ax2 + VY2 * ay2) / (VX2 + VY2);
+ float alphaL2 = (LX2 * ax2 + LY2 * ay2) / (LX2 + LY2);
+ float G = G1_Smith_GGX(NV, alphaV2) * G1_Smith_GGX(NL, alphaL2); /* Doing RCP at the end */
+
+ /* D_GGX */
+ float D = D_ggx_aniso_opti(NH, XH2, YH2, a2, ax2, ay2);
+
+ /* Denominator is canceled by G1_Smith */
+ /* bsdf = D * G / (4.0 * NL * NV); /* Reference function */
+ return NL / (D * G); /* NL to Fit cycles Equation : line. 345 in bsdf_microfacet.h */
+}
+
+/* This one returns the brdf already divided by the pdf */
+float bsdf_ggx_aniso_pdf(float ax2, float ay2, float LX2, float LY2, float NH, float NV, float NL, float VH, float G1_V)
+{
+ float alphaL2 = (LX2 * ax2 + LY2 * ay2) / (LX2 + LY2);
+ float G = G1_V * G1_Smith_GGX(NL, alphaL2);
+
+ /* Denominator is canceled by G1_Smith
+ * brdf = D * G / (4.0 * NL * NV)
+ * pdf = D * NH / (4 * VH) [D canceled later by D in brdf] */
+ return 4.0 * VH / (NH * G); /* brdf / pdf */
+}
+
+float bsdf_beckmann_aniso(vec3 N, vec3 T, vec3 L, vec3 V, float roughness_x, float roughness_y)
+{
+ /* Beckmann Spec Anisotropic */
+ /* A few note about notations :
+ * I is the cycles term for Incoming Light, Noted L here (light vector)
+ * Omega (O) is the cycles term for the Outgoing Light, Noted V here (View vector) */
+ N = normalize(N);
+ vec3 X = T, Y, Z = N; /* Inside cycles Z=Normal; X=Tangent; Y=Bitangent; */
+ make_orthonormals_tangent(Z, X, Y);
+ vec3 H = normalize(L + V);
+
+ float ax, ax2; prepare_glossy(roughness_x, ax, ax2);
+ float ay, ay2; prepare_glossy(roughness_y, ay, ay2);
+ float a2 = ax*ay;
+
+ float NH = max(1e-8, dot(N, H));
+ float NL = max(1e-8, dot(N, L));
+ float NV = max(1e-8, dot(N, V));
+ float VX2 = pow(dot(V, X), 2); /* cosPhiO² */
+ float VY2 = pow(dot(V, Y), 2); /* sinPhiO² */
+ float LX2 = pow(dot(L, X), 2); /* cosPhiI² */
+ float LY2 = pow(dot(L, Y), 2); /* sinPhiI² */
+ float XH = dot(X, H);
+ float YH = dot(Y, H);
+
+ float alphaV2 = (VX2 * ax2 + VY2 * ay2) / (VX2 + VY2);
+ float alphaL2 = (LX2 * ax2 + LY2 * ay2) / (LX2 + LY2);
+ float G = G1_Smith_beckmann(NV, alphaV2) * G1_Smith_beckmann(NL, alphaL2);
+
+ float D = D_beckmann_aniso(NH, XH, YH, a2, ax, ay);
+
+ return NL * D * G * 0.25 / (NL * NV);
+}
+
+/* This one returns the brdf already divided by the pdf */
+float bsdf_beckmann_aniso_pdf(float ax2, float ay2, float LX2, float LY2, float NH, float NV, float NL, float VH, float G1_V)
+{
+ float alphaL2 = (LX2 * ax2 + LY2 * ay2) / (LX2 + LY2);
+ float G = G1_V * G1_Smith_beckmann(NL, alphaL2);
+
+ /* brdf = D * G / (4.0 * NL * NV)
+ * pdf = D * NH / (4 * VH) [D canceled later by D in brdf] */
+ return G * VH / (NH * NV * NL); /* brdf / pdf */
+}
+
+float bsdf_ashikhmin_shirley_aniso(vec3 N, vec3 T, vec3 L, vec3 V, float roughness_x, float roughness_y)
+{
+ /* Ashikmin Shirley Spec Anisotropic */
+ /* A few note about notations :
+ * I is the cycles term for Incoming Light, Noted L here (light vector)
+ * Omega (O) is the cycles term for the Outgoing Light, Noted V here (View vector) */
+ N = normalize(N);
+ vec3 X = T, Y, Z = N; /* Inside cycles Z=Normal; X=Tangent; Y=Bitangent; */
+ make_orthonormals_tangent(Z, X, Y);
+ vec3 H = normalize(L + V);
+
+ float ax, ax2; prepare_glossy(roughness_x, ax, ax2);
+ float ay, ay2; prepare_glossy(roughness_y, ay, ay2);
+ float a2 = ax*ay;
+ float n_x = 2.0 / ax2 - 2.0;
+ float n_y = 2.0 / ay2 - 2.0;
+
+ float NL = max(dot(N, L), 1e-6);
+ float NV = max(dot(N, V), 1e-6);
+ float NH = max(dot(N, H), 1e-6);
+ float VH = max(abs(dot(V, H)), 1e-6);
+ float XH2 = max(pow(dot(X, H), 2), 1e-6);
+ float YH2 = max(pow(dot(Y, H), 2), 1e-6);
+
+ float pump = 1.0 / max(1e-6, VH * max(NL, NV));
+
+ float e = max(n_x * XH2 + n_y * YH2, 1e-4) / max(1.0 - NH*NH, 1e-4); /* Precision problem here */
+ float lobe = pow(NH, e);
+ float norm = sqrt((n_x + 1.0)*(n_y + 1.0)) * 0.125 * M_1_PI;
+
+ return NL * norm * lobe * pump;
+}
+
+/* -------- Preview Lights --------- */
+
+void node_bsdf_anisotropic_lights(vec4 color, float roughness, float anisotropy, float rotation, vec3 N, vec3 T, vec3 V, vec4 ambient_light, out vec4 result)
+{
+ N = normalize(N);
+ shade_view(V, V); V = -V;
+
+ float rough_x, rough_y;
+ prepare_aniso(N, roughness, rotation, T, anisotropy, rough_x, rough_y);
+ vec3 accumulator = ambient_light.rgb;
+
+ if (max(rough_x, rough_y) <= 1e-4) {
+ result = vec4(accumulator * color.rgb, 1.0); //Should take roughness into account -> waiting LUT
+ return;
+ }
+
+ /* directional lights */
+ for(int i = 0; i < NUM_LIGHTS; i++) {
+ vec3 L = gl_LightSource[i].position.xyz;
+ vec3 light_color = gl_LightSource[i].specular.rgb;
+
+ accumulator += light_color * bsdf_ggx_aniso(N, T, L, V, rough_x, rough_y);
+ }
+
+ result = vec4(accumulator * color.rgb, 1.0);
+}
+
+
+/* -------- Physical Lights --------- */
+
+/* ANISOTROPIC GGX */
+
+void bsdf_anisotropic_ggx_sphere_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+
+ float rough_x, rough_y;
+ prepare_aniso(N, roughness, aniso_rotation, T, anisotropy, rough_x, rough_y);
+
+ if (max(rough_x, rough_y) < 1e-4 && l_areasizex == 0) {
+ bsdf = 0.0;
+ return;
+ }
+
+ float l_radius = l_areasizex;
+
+ vec3 R = reflect(V, N);
+ float energy_conservation = 1.0;
+ most_representative_point(l_radius, 0.0, vec3(0.0), l_distance, R, L, roughness, energy_conservation);
+ bsdf = bsdf_ggx_aniso(N, T, L, V, rough_x, rough_y);
+
+ bsdf *= energy_conservation / (l_distance * l_distance);
+ bsdf *= sphere_energy(l_radius) * max(l_radius * l_radius, 1e-16); /* l_radius is already inside energy_conservation */
+ bsdf *= M_PI; /* XXX : !!! Very Empirical, Fit cycles power */
+}
+
+void bsdf_anisotropic_ggx_area_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ if (max(l_areasizex, l_areasizey) < 1e-6) {
+ bsdf = 0.0;
+ return;
+ }
+
+
+ float rough_x, rough_y;
+ prepare_aniso(N, roughness, aniso_rotation, T, anisotropy, rough_x, rough_y);
+
+ l_areasizex *= l_areascale.x;
+ l_areasizey *= l_areascale.y;
+
+ /* Used later for Masking : Use the real Light Vector */
+ vec3 lampz = normalize( (l_mat * vec4(0.0,0.0,1.0,0.0) ).xyz );
+ float masking = max(dot( normalize(-L), lampz), 0.0);
+
+ vec3 R = reflect(V, N);
+
+ float energy_conservation = 1.0;
+ float max_size = max(l_areasizex, l_areasizey);
+ float min_size = min(l_areasizex, l_areasizey);
+ vec3 lampVec = (l_areasizex > l_areasizey) ? normalize( (l_mat * vec4(1.0,0.0,0.0,0.0) ).xyz ) : normalize( (l_mat * vec4(0.0,1.0,0.0,0.0) ).xyz );
+
+ most_representative_point(min_size/2, max_size-min_size, lampVec, l_distance, R, L, roughness, energy_conservation);
+ bsdf = bsdf_ggx_aniso(N, T, L, V, rough_x, rough_y);
+
+ /* energy_conservation */
+ float LineAngle = clamp( (max_size-min_size) / l_distance, 0.0, 1.0);
+ float energy_conservation_line = energy_conservation * ( roughness / clamp(roughness + 0.5 * LineAngle, 0.0, 1.1));
+
+ /* XXX : Empirical modification for low roughness matching */
+ float energy_conservation_mod = energy_conservation * (1 + roughness) / ( max_size/min_size );
+ energy_conservation = mix(energy_conservation_mod, energy_conservation_line, min(roughness/0.3, 0.9*(1.1-roughness)/0.1));
+
+ /* As we represent the Area Light by a tube light we must use a custom energy conservation */
+ bsdf *= energy_conservation / (l_distance * l_distance);
+ bsdf *= masking;
+ bsdf *= 23.2; /* XXX : !!! Very Empirical, Fit cycles power */
+}
+
+void bsdf_anisotropic_ggx_sun_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float rough_x, rough_y;
+ prepare_aniso(N, roughness, aniso_rotation, T, anisotropy, rough_x, rough_y);
+
+ /* Correct ligth shape but uniform intensity
+ * Does not take into account the division by costheta^3 */
+ if (roughness < 1e-4 && l_areasizex == 0) {
+ bsdf = 0.0;
+ return;
+ }
+
+ vec3 R = reflect(V, N);
+
+ float l_radius = l_areasizex;
+ float angle = atan(l_radius);
+
+ float costheta = dot(-L, R);
+ float cosangle = cos(angle);
+
+ float energy_conservation = 1.0;
+ most_representative_point_disk(l_radius, 1.0, R, L, roughness, energy_conservation);
+
+ bsdf = bsdf_ggx_aniso(N, T, L, V, rough_x, rough_y);
+ bsdf *= energy_conservation;
+}
+
+/* ANISOTROPIC BECKMANN */
+
+void bsdf_anisotropic_beckmann_sphere_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+
+ float rough_x, rough_y;
+ prepare_aniso(N, roughness, aniso_rotation, T, anisotropy, rough_x, rough_y);
+
+ if (max(rough_x, rough_y) < 1e-4 && l_areasizex == 0) {
+ bsdf = 0.0;
+ return;
+ }
+
+ float l_radius = l_areasizex;
+
+ vec3 R = reflect(V, N);
+ float energy_conservation = 1.0;
+ most_representative_point(l_radius, 0.0, vec3(0.0), l_distance, R, L, roughness, energy_conservation);
+ bsdf = bsdf_beckmann_aniso(N, T, L, V, rough_x, rough_y);
+
+ bsdf *= energy_conservation / (l_distance * l_distance);
+ bsdf *= sphere_energy(l_radius) * max(l_radius * l_radius, 1e-16); /* l_radius is already inside energy_conservation */
+ bsdf *= M_PI; /* XXX : !!! Very Empirical, Fit cycles power */
+}
+
+void bsdf_anisotropic_beckmann_area_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ if (max(l_areasizex, l_areasizey) < 1e-6) {
+ bsdf = 0.0;
+ return;
+ }
+
+ float rough_x, rough_y;
+ prepare_aniso(N, roughness, aniso_rotation, T, anisotropy, rough_x, rough_y);
+
+ l_areasizex *= l_areascale.x;
+ l_areasizey *= l_areascale.y;
+
+ /* Used later for Masking : Use the real Light Vector */
+ vec3 lampz = normalize( (l_mat * vec4(0.0,0.0,1.0,0.0) ).xyz );
+ float masking = max(dot( normalize(-L), lampz), 0.0);
+
+ vec3 R = reflect(V, N);
+
+ float energy_conservation = 1.0;
+ float max_size = max(l_areasizex, l_areasizey);
+ float min_size = min(l_areasizex, l_areasizey);
+ vec3 lampVec = (l_areasizex > l_areasizey) ? normalize( (l_mat * vec4(1.0,0.0,0.0,0.0) ).xyz ) : normalize( (l_mat * vec4(0.0,1.0,0.0,0.0) ).xyz );
+
+ most_representative_point(min_size/2, max_size-min_size, lampVec, l_distance, R, L, roughness, energy_conservation);
+ bsdf = bsdf_beckmann_aniso(N, T, L, V, rough_x, rough_y);
+
+ /* energy_conservation */
+ float LineAngle = clamp( (max_size-min_size) / l_distance, 0.0, 1.0);
+ float energy_conservation_line = energy_conservation * ( roughness / clamp(roughness + 0.5 * LineAngle, 0.0, 1.1));
+
+ /* XXX : Empirical modification for low roughness matching */
+ float energy_conservation_mod = energy_conservation * (1 + roughness) / ( max_size/min_size );
+ energy_conservation = mix(energy_conservation_mod, energy_conservation_line, min(roughness/0.3, 0.9*(1.1-roughness)/0.1));
+
+ /* As we represent the Area Light by a tube light we must use a custom energy conservation */
+ bsdf *= energy_conservation / (l_distance * l_distance);
+ bsdf *= masking;
+ bsdf *= 23.2; /* XXX : !!! Very Empirical, Fit cycles power */
+}
+
+void bsdf_anisotropic_beckmann_sun_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float rough_x, rough_y;
+ prepare_aniso(N, roughness, aniso_rotation, T, anisotropy, rough_x, rough_y);
+
+ /* Correct ligth shape but uniform intensity
+ * Does not take into account the division by costheta^3 */
+ if (roughness < 1e-4 && l_areasizex == 0) {
+ bsdf = 0.0;
+ return;
+ }
+
+ vec3 R = reflect(V, N);
+
+ float l_radius = l_areasizex;
+ float angle = atan(l_radius);
+
+ float costheta = dot(-L, R);
+ float cosangle = cos(angle);
+
+ float energy_conservation = 1.0;
+ most_representative_point_disk(l_radius, 1.0, R, L, roughness, energy_conservation);
+
+ bsdf = bsdf_beckmann_aniso(N, T, L, V, rough_x, rough_y);
+ bsdf *= energy_conservation;
+}
+
+/* ANISOTROPIC ASHIKHMIN SHIRLEY */
+
+void bsdf_anisotropic_ashikhmin_shirley_sphere_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+
+ float rough_x, rough_y;
+ prepare_aniso(N, roughness, aniso_rotation, T, anisotropy, rough_x, rough_y);
+
+ if (max(rough_x, rough_y) < 1e-4 && l_areasizex == 0) {
+ bsdf = 0.0;
+ return;
+ }
+
+ float l_radius = l_areasizex;
+
+ vec3 R = reflect(V, N);
+ float energy_conservation = 1.0;
+ most_representative_point(l_radius, 0.0, vec3(0.0), l_distance, R, L, roughness, energy_conservation);
+ bsdf = bsdf_ashikhmin_shirley_aniso(N, T, L, V, rough_x, rough_y);
+
+ bsdf *= energy_conservation / (l_distance * l_distance);
+ bsdf *= sphere_energy(l_radius) * max(l_radius * l_radius, 1e-16); /* l_radius is already inside energy_conservation */
+ bsdf *= M_PI; /* XXX : !!! Very Empirical, Fit cycles power */
+}
+
+void bsdf_anisotropic_ashikhmin_shirley_area_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ if (max(l_areasizex, l_areasizey) < 1e-6) {
+ bsdf = 0.0;
+ return;
+ }
+
+ float rough_x, rough_y;
+ prepare_aniso(N, roughness, aniso_rotation, T, anisotropy, rough_x, rough_y);
+
+ l_areasizex *= l_areascale.x;
+ l_areasizey *= l_areascale.y;
+
+ /* Used later for Masking : Use the real Light Vector */
+ vec3 lampz = normalize( (l_mat * vec4(0.0,0.0,1.0,0.0) ).xyz );
+ float masking = max(dot( normalize(-L), lampz), 0.0);
+
+ vec3 R = reflect(V, N);
+
+ float energy_conservation = 1.0;
+ float max_size = max(l_areasizex, l_areasizey);
+ float min_size = min(l_areasizex, l_areasizey);
+ vec3 lampVec = (l_areasizex > l_areasizey) ? normalize( (l_mat * vec4(1.0,0.0,0.0,0.0) ).xyz ) : normalize( (l_mat * vec4(0.0,1.0,0.0,0.0) ).xyz );
+
+ most_representative_point(min_size/2, max_size-min_size, lampVec, l_distance, R, L, roughness, energy_conservation);
+ bsdf = bsdf_ashikhmin_shirley_aniso(N, T, L, V, rough_x, rough_y);
+
+ /* energy_conservation */
+ float LineAngle = clamp( (max_size-min_size) / l_distance, 0.0, 1.0);
+ float energy_conservation_line = energy_conservation * ( roughness / clamp(roughness + 0.5 * LineAngle, 0.0, 1.1));
+
+ /* XXX : Empirical modification for low roughness matching */
+ float energy_conservation_mod = energy_conservation * (1 + roughness) / ( max_size/min_size );
+ energy_conservation = mix(energy_conservation_mod, energy_conservation_line, min(roughness/0.3, 0.9*(1.1-roughness)/0.1));
+
+ /* As we represent the Area Light by a tube light we must use a custom energy conservation */
+ bsdf *= energy_conservation / (l_distance * l_distance);
+ bsdf *= masking;
+ bsdf *= 23.2; /* XXX : !!! Very Empirical, Fit cycles power */
+}
+
+void bsdf_anisotropic_ashikhmin_shirley_sun_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float rough_x, rough_y;
+ prepare_aniso(N, roughness, aniso_rotation, T, anisotropy, rough_x, rough_y);
+
+ /* Correct ligth shape but uniform intensity
+ * Does not take into account the division by costheta^3 */
+ if (roughness < 1e-4 && l_areasizex == 0) {
+ bsdf = 0.0;
+ return;
+ }
+
+ vec3 R = reflect(V, N);
+
+ float l_radius = l_areasizex;
+ float angle = atan(l_radius);
+
+ float costheta = dot(-L, R);
+ float cosangle = cos(angle);
+
+ float energy_conservation = 1.0;
+ most_representative_point_disk(l_radius, 1.0, R, L, roughness, energy_conservation);
+
+ bsdf = bsdf_ashikhmin_shirley_aniso(N, T, L, V, rough_x, rough_y);
+ bsdf *= energy_conservation;
+}
+
+/* -------- Image Based Lighting --------- */
+
+void env_sampling_aniso_ggx(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ /* Setup */
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+ float rough_x, rough_y; prepare_aniso(N, roughness, -aniso_rotation, T, anisotropy, rough_x, rough_y);
+ float ax, ax2; prepare_glossy(rough_x, ax, ax2);
+ float ay, ay2; prepare_glossy(rough_y, ay, ay2);
+ make_orthonormals_tangent(N, T, B);
+ setup_noise(gl_FragCoord.xy); /* Noise to dither the samples */
+
+ /* Precomputation */
+ float max_a = min(1.0, max(ax, ay));
+ float min_a = min(1.0, min(ax, ay));
+ float a2 = ax*ay;
+ float NV = max(1e-8, abs(dot(I, N)));
+ float VX2 = pow(dot(I, T), 2); /* cosPhiO² */
+ float VY2 = pow(dot(I, B), 2); /* sinPhiO² */
+ float alphaV2 = (VX2 * ax2 + VY2 * ay2) / (VX2 + VY2);
+ float G1_V = G1_Smith_GGX(NV, alphaV2);
+
+ /* Integrating Envmap */
+ vec4 out_radiance = vec4(0.0);
+ for (float i = 0; i < unfbsdfsamples.x; i++) {
+ vec3 H = sample_ggx_aniso(i, ax, ay, N, T, B); /* Microfacet normal */
+ vec3 L = reflect(I, H);
+ float NL = dot(N, L);
+
+ if (NL > 0.0) {
+ /* Step 1 : Sampling Environment */
+ float NH = Ht.z;
+ float XH2 = Ht.x * Ht.x;
+ float YH2 = Ht.y * Ht.y;
+
+ float pdf = pdf_ggx_aniso(NH, XH2, YH2, a2, ax, ay);
+
+ vec4 sample = sample_reflect_pdf(L, roughness, pdf);
+
+ /* Step 2 : Integrating BRDF */
+ float VH = max(1e-8, -dot(I, H));
+ float LX2 = pow(dot(L, T), 2); /* cosPhiI² */
+ float LY2 = pow(dot(L, B), 2); /* sinPhiI² */
+ float brdf_pdf = bsdf_ggx_aniso_pdf(ax2, ay2, LX2, LY2, NH, NV, NL, VH, G1_V);
+
+ out_radiance += NL * sample * brdf_pdf;
+ }
+ }
+
+ result = out_radiance.rgb * unfbsdfsamples.y * specular_occlusion(NV, ao_factor, a2);
+}
+
+void env_sampling_aniso_beckmann(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ /* Setup */
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+ float rough_x, rough_y; prepare_aniso(N, roughness, -aniso_rotation, T, anisotropy, rough_x, rough_y);
+ float ax, ax2; prepare_glossy(rough_x, ax, ax2);
+ float ay, ay2; prepare_glossy(rough_y, ay, ay2);
+ make_orthonormals_tangent(N, T, B);
+ setup_noise(gl_FragCoord.xy); /* Noise to dither the samples */
+
+ /* Precomputation */
+ float a2 = ax*ay;
+ float NV = max(1e-8, abs(dot(I, N)));
+ float VX2 = pow(dot(I, T), 2); /* cosPhiO² */
+ float VY2 = pow(dot(I, B), 2); /* sinPhiO² */
+ float alphaV2 = (VX2 * ax2 + VY2 * ay2) / (VX2 + VY2);
+ float G1_V = G1_Smith_beckmann(NV, alphaV2);
+
+ /* Integrating Envmap */
+ vec4 out_radiance = vec4(0.0);
+ for (float i = 0; i < unfbsdfsamples.x; i++) {
+ vec3 H = sample_beckmann_aniso(i, ax, ay, N, T, B); /* Microfacet normal */
+ vec3 L = reflect(I, H);
+ float NL = dot(N, L);
+
+ if (NL > 0.0) {
+ /* Step 1 : Sampling Environment */
+ float NH = Ht.z;
+ float XH = Ht.x;
+ float YH = Ht.y;
+
+ float pdf = pdf_beckmann_aniso(NH, XH, YH, a2, ax, ay);
+
+ vec4 sample = sample_reflect_pdf(L, roughness, pdf);
+
+ /* Step 2 : Integrating BRDF */
+ float VH = max(1e-8, -dot(I, H));
+ float LX2 = pow(dot(L, T), 2); /* cosPhiI² */
+ float LY2 = pow(dot(L, B), 2); /* sinPhiI² */
+ float brdf_pdf = bsdf_beckmann_aniso_pdf(ax2, ay2, LX2, LY2, NH, NV, NL, VH, G1_V);
+
+ out_radiance += NL * sample * brdf_pdf;
+ }
+ }
+
+ result = out_radiance.rgb * unfbsdfsamples.y * specular_occlusion(NV, ao_factor, a2);
+}
+
+void env_sampling_aniso_ashikhmin_shirley(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ /* Setup */
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+ float rough_x, rough_y; prepare_aniso(N, roughness, -aniso_rotation, T, anisotropy, rough_x, rough_y);
+ float ax, ax2; prepare_glossy(rough_x, ax, ax2);
+ float ay, ay2; prepare_glossy(rough_y, ay, ay2);
+ make_orthonormals_tangent(N, T, B);
+ setup_noise(gl_FragCoord.xy); /* Noise to dither the samples */
+
+ /* Precomputation */
+ float a2 = ax*ay;
+ float NV = max(1e-8, abs(dot(I, N)));
+ float VX2 = pow(dot(I, T), 2); /* cosPhiO² */
+ float VY2 = pow(dot(I, B), 2); /* sinPhiO² */
+
+ float n_x = 2.0 / ax2 - 2.0;
+ float n_y = 2.0 / ay2 - 2.0;
+
+ /* Integrating Envmap */
+ vec4 out_radiance = vec4(0.0);
+ for (float i = 0; i < unfbsdfsamples.x; i++) {
+ vec3 H = sample_ashikhmin_shirley_aniso(i, n_x, n_y, N, T, B); /* Microfacet normal */
+ float VH = dot(H, -I);
+ if (VH < 0.0) H = -H;
+ /* reflect I on H to get omega_in */
+ vec3 L = I + (2.0 * VH) * H;
+ float NL = dot(N, L);
+
+ if (NL > 0.0) {
+ /* Step 1 : Sampling Environment */
+ float NH = Ht.z;
+ float XH2 = Ht.x * Ht.x;
+ float YH2 = Ht.y * Ht.y;
+ float VH = max(1e-8, -dot(I, H));
+
+ float pdf = pdf_ashikhmin_shirley_aniso(NH, VH, XH2, YH2, n_x, n_y);
+
+ vec4 sample = sample_reflect_pdf(L, roughness, pdf);
+
+ /* Step 2 : Integrating BRDF */
+ float brdf_pdf = bsdf_ashikhmin_shirley_pdf(NV, NL, VH); /* Same as isotropic */
+
+ out_radiance += NL * sample * brdf_pdf;
+ }
+ }
+
+ result = out_radiance.rgb * unfbsdfsamples.y * specular_occlusion(NV, ao_factor, a2);
+} \ No newline at end of file
diff --git a/source/blender/gpu/shaders/gpu_shader_material_bsdf_diffuse.glsl b/source/blender/gpu/shaders/gpu_shader_material_bsdf_diffuse.glsl
new file mode 100644
index 00000000000..a2d6b42a57c
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_material_bsdf_diffuse.glsl
@@ -0,0 +1,263 @@
+/* -------- Utils Functions --------- */
+
+vec3 sample_hemisphere(float nsample, vec3 N, vec3 T, vec3 B)
+{
+ vec3 Xi = hammersley_3d(nsample);
+
+ float z = Xi.x; /* cos theta */
+ float r = sqrt( 1.0f - z*z ); /* sin theta */
+ float x = r * Xi.y;
+ float y = r * Xi.z;
+
+ Ht = vec3(x, y, z); /* Global variable */
+
+ return from_tangent_to_world(Ht, N, T, B);
+}
+
+float pdf_hemisphere()
+{
+ return 0.5 * M_1_PI;
+}
+
+/* Second order Spherical Harmonics */
+/* http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/ */
+vec3 spherical_harmonics_L2(vec3 N)
+{
+ vec3 sh = vec3(0.0);
+
+ sh += 0.282095 * unfsh0;
+
+ sh += -0.488603 * N.z * unfsh1;
+ sh += 0.488603 * N.y * unfsh2;
+ sh += -0.488603 * N.x * unfsh3;
+
+ sh += 1.092548 * N.x * N.z * unfsh4;
+ sh += -1.092548 * N.z * N.y * unfsh5;
+ sh += 0.315392 * (3.0 * N.y * N.y - 1.0) * unfsh6;
+ sh += -1.092548 * N.x * N.y * unfsh7;
+ sh += 0.546274 * (N.x * N.x - N.z * N.z) * unfsh8;
+
+ return sh;
+}
+
+/* -------- BSDF --------- */
+
+float bsdf_lambert(float NL)
+{
+ return NL * M_1_PI;
+}
+
+float bsdf_oren_nayar(float NL, float LV, float NV, float sigma)
+{
+ float div = 1.0 / (M_PI + ((3.0 * M_PI - 4.0) / 6.0) * sigma);
+
+ float A = 1.0 * div;
+ float B = sigma * div;
+
+ float s = LV - NL * NV;
+ float t = mix(1.0, max(NL, NV), step(0.0, s));
+ return NL * (A + B * s / t);
+}
+
+float bsdf_oren_nayar(vec3 N, vec3 L, vec3 V, float sigma)
+{
+ float NL = max(0.0, dot(N, L));
+ float LV = max(0.0, dot(L, V));
+ float NV = max(1e-8, dot(N, V));
+ return bsdf_oren_nayar(NL, LV, NV, sigma);
+}
+
+
+/* -------- Preview Lights --------- */
+
+void node_bsdf_diffuse_lights(vec4 color, float roughness, vec3 N, vec3 V, vec4 ambient_light, out vec4 result)
+{
+ shade_view(V, V); V = -V;
+
+ /* ambient light */
+ vec3 accumulator = ambient_light.rgb;
+
+ /* oren_nayar approximation for ambient */
+ float NV = clamp(dot(N, V), 0.0, 0.999);
+ float fac = 1.0 - pow(1.0 - NV, 1.3);
+ accumulator *= mix(1.0, 0.78, fac*roughness);
+
+ /* directional lights */
+ for(int i = 0; i < NUM_LIGHTS; i++) {
+ vec3 L = gl_LightSource[i].position.xyz;
+ vec3 light_color = gl_LightSource[i].diffuse.rgb;
+
+ float NL = saturate(dot(N,L));
+ float lambert = bsdf_lambert(NL);
+ float oren_nayar = bsdf_oren_nayar(N, L, V, roughness);
+
+ accumulator += light_color * mix(lambert, oren_nayar, roughness) * M_PI; /* M_PI to make preview brighter */
+ }
+
+ result = vec4(accumulator*color.rgb, 1.0);
+}
+
+
+/* -------- Physical Lights --------- */
+/* from Sebastien Lagarde
+ * course_notes_moving_frostbite_to_pbr.pdf */
+
+void bsdf_diffuse_sphere_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float l_radius = max(l_areasizex, 0.0001);
+ float costheta = clamp(dot(N, L), -0.999, 0.999);
+ float h = min(l_radius / l_distance , 0.9999);
+ float h2 = h*h;
+
+ bsdf = 0.0;
+ if ( costheta * costheta > h2 ) {
+ bsdf = M_PI * h2 * clamp(costheta, 0.0, 1.0);
+ }
+ else {
+ float sintheta = sqrt(1.0 - costheta * costheta);
+ float x = sqrt(1.0 / h2 - 1.0);
+ float y = -x * ( costheta / sintheta );
+ float sinthetasqrty = sintheta * sqrt(1.0 - y * y);
+ bsdf = (costheta * acos(y) - x * sinthetasqrty ) * h2 + atan(sinthetasqrty / x);
+ }
+
+ /* Energy conservation + cycle matching */
+ bsdf = max(bsdf, 0.0);
+ bsdf *= M_1_PI;
+ bsdf *= sphere_energy(l_radius);
+}
+
+void bsdf_diffuse_area_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ if (min(l_areasizex, l_areasizey) < 1e-6) {
+ bsdf = 0.0;
+ return;
+ }
+
+ vec3 pos = V;
+ V = -normalize(V);
+ N = -N;
+
+ vec3 lampx, lampy, lampz;
+ vec2 halfsize = area_light_prepass(l_mat, l_areasizex, l_areasizey, l_areascale, lampx, lampy, lampz);
+
+ vec3 points[4];
+ area_light_points(l_coords, halfsize, lampx, lampy, points);
+
+ bsdf = ltc_evaluate(N, V, pos, mat3(1), points);
+ bsdf *= step(0.0, -dot(L, lampz));
+
+ /* Energy conservation + cycle matching */
+ bsdf *= M_1_2PI;
+ bsdf *= rectangle_energy(l_areasizex, l_areasizey);
+}
+float cot(float x){ return cos(x) / sin(x);}
+float acot(float x){ return atan(1 / x);}
+void bsdf_diffuse_sun_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float l_radius = max(l_areasizex, 0.0001);
+ float costheta = clamp(dot(N, L), -0.999, 0.999);
+ float sintheta = sqrt(1.0 - costheta * costheta);
+ float h = 1 / l_radius;
+ float h2 = h * h;
+
+ if (acos(costheta) < atan(h)) {
+ bsdf = M_PI * (1 / (1 + h2)) * costheta;
+ }
+ else {
+ float cottheta = costheta / sintheta;
+ float x = sqrt(1 - h2 * cottheta * cottheta);
+ bsdf = (-h * x + costheta * (M_PI - acos(h * cottheta))) / (1 + h2) + atan(x / h);
+ }
+ /* Energy conservation + cycle matching */
+ float disk_energy = disk_energy(l_radius);
+ bsdf = max(bsdf, 0.0) * disk_energy;
+ /* TODO Refine this :
+ * We can try to add contribution of infinitely many point lights at the border of the disk if we know their intensity
+ * Border intensity should be added to the above uniform disk calculation and should be complementary */
+ //bsdf += sqrt(1.0 - abs(costheta * costheta * costheta)) * saturate(M_1_2PI - disk_energy);
+ bsdf *= M_1_PI;
+
+}
+
+
+/* -------- Image Based Lighting --------- */
+
+void env_sampling_oren_nayar(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ /* Setup */
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+ make_orthonormals(N, T, B); /* Generate tangent space */
+ setup_noise(gl_FragCoord.xy); /* Noise to dither the samples */
+
+ /* Precomputation */
+ float NV = max(1e-8, abs(dot(I, N)));
+
+ /* Integrating Envmap */
+ vec4 out_radiance = vec4(0.0);
+ for (float i = 0; i < unfbsdfsamples.x; i++) {
+ vec3 L = sample_hemisphere(i, N, T, B);
+ vec3 H = normalize(L - I);
+
+ float NL = max(0.0, dot(N, L));
+
+ if (NL != 0.0) {
+ /* Step 1 : Sampling Environment */
+ float pdf = pdf_hemisphere();
+ vec4 irradiance = sample_probe_pdf(L, pdf);
+
+ /* Step 2 : Integrating BRDF*/
+ float LV = max(0.0, dot(L, -I) );
+ float brdf = bsdf_oren_nayar(NL, LV, NV, roughness);
+
+ out_radiance += irradiance * brdf / pdf;
+ }
+ }
+
+ result = out_radiance.rgb * unfbsdfsamples.y;
+}
+
+void env_sampling_diffuse(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ /* Lambert */
+ vec3 lambert_diff = spherical_harmonics_L2(N);
+
+ /* early out */
+ if (roughness < 1e-5) {
+ result = lambert_diff * ao_factor;
+ return;
+ }
+
+ /* Oren Nayar */
+ vec3 oren_nayar_diff;
+ env_sampling_oren_nayar(
+ pbr, viewpos, invviewmat, viewmat,
+ N, T, roughness, ior, sigma,
+ toon_size, toon_smooth, anisotropy, aniso_rotation,
+ ao_factor, oren_nayar_diff);
+
+ result = mix(lambert_diff, oren_nayar_diff, roughness);
+
+ /* Apply ambient occlusion */
+ result *= ao_factor;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_material_bsdf_glass.glsl b/source/blender/gpu/shaders/gpu_shader_material_bsdf_glass.glsl
new file mode 100644
index 00000000000..7e51aeb5ff5
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_material_bsdf_glass.glsl
@@ -0,0 +1,345 @@
+/* -------- Utils Functions --------- */
+
+float fresnel_blend(float transmit_bsdf, float reflect_bsdf, vec3 V, vec3 N, float ior)
+{
+ /* Fresnel Blend */
+ float eta = (gl_FrontFacing) ? ior : 1.0/ior;
+ float fresnel = fresnel_dielectric(V, N, eta);
+
+ return mix(max(0.0, transmit_bsdf), reflect_bsdf, fresnel);
+}
+
+vec3 fresnel_blend(vec3 transmit_bsdf, vec3 reflect_bsdf, vec3 V, vec3 N, float ior)
+{
+ /* Fresnel Blend */
+ float eta = (gl_FrontFacing) ? ior : 1.0/ior;
+ float fresnel = fresnel_dielectric(V, N, eta);
+
+ return mix(transmit_bsdf, reflect_bsdf, fresnel);
+}
+
+
+/* -------- BSDF --------- */
+
+/* -------- Preview Lights --------- */
+
+void node_bsdf_glass_lights(vec4 color, float roughness, float ior, vec3 N, vec3 V, vec4 ambient_light, out vec4 result)
+{
+ node_bsdf_glossy_lights(color, roughness, N, V, ambient_light, result);
+}
+
+/* -------- Physical Lights --------- */
+
+/* GLASS GGX */
+
+void bsdf_glass_ggx_sphere_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float transmit_bsdf, reflect_bsdf;
+
+ bsdf_refract_ggx_sphere_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, transmit_bsdf);
+ bsdf_glossy_ggx_sphere_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, reflect_bsdf);
+
+ bsdf = fresnel_blend(transmit_bsdf, reflect_bsdf, V, N, ior);
+}
+
+void bsdf_glass_ggx_area_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float transmit_bsdf, reflect_bsdf;
+
+ bsdf_refract_ggx_area_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, transmit_bsdf);
+ bsdf_glossy_ggx_area_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, reflect_bsdf);
+
+ bsdf = fresnel_blend(transmit_bsdf, reflect_bsdf, V, N, ior);
+}
+
+void bsdf_glass_ggx_sun_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float transmit_bsdf, reflect_bsdf;
+
+ bsdf_refract_ggx_sun_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, transmit_bsdf);
+ bsdf_glossy_ggx_sun_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, reflect_bsdf);
+
+ bsdf = fresnel_blend(transmit_bsdf, reflect_bsdf, V, N, ior);
+}
+
+/* GLASS BECKMANN */
+
+void bsdf_glass_beckmann_sphere_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float transmit_bsdf, reflect_bsdf;
+
+ bsdf_refract_beckmann_sphere_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, transmit_bsdf);
+ bsdf_glossy_beckmann_sphere_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, reflect_bsdf);
+
+ bsdf = fresnel_blend(transmit_bsdf, reflect_bsdf, V, N, ior);
+}
+
+void bsdf_glass_beckmann_area_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float transmit_bsdf, reflect_bsdf;
+
+ bsdf_refract_beckmann_area_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, transmit_bsdf);
+ bsdf_glossy_beckmann_area_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, reflect_bsdf);
+
+ bsdf = fresnel_blend(transmit_bsdf, reflect_bsdf, V, N, ior);
+}
+
+void bsdf_glass_beckmann_sun_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float transmit_bsdf, reflect_bsdf;
+
+ bsdf_refract_beckmann_sun_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, transmit_bsdf);
+ bsdf_glossy_beckmann_sun_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, reflect_bsdf);
+
+ bsdf = fresnel_blend(transmit_bsdf, reflect_bsdf, V, N, ior);
+}
+
+/* GLASS SHARP */
+
+void bsdf_glass_sharp_sphere_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float transmit_bsdf, reflect_bsdf;
+
+ bsdf_refract_sharp_sphere_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, transmit_bsdf);
+ bsdf_glossy_sharp_sphere_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, reflect_bsdf);
+
+ bsdf = fresnel_blend(transmit_bsdf, reflect_bsdf, V, N, ior);
+}
+
+void bsdf_glass_sharp_area_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float transmit_bsdf, reflect_bsdf;
+
+ bsdf_refract_sharp_area_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, transmit_bsdf);
+ bsdf_glossy_sharp_area_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, reflect_bsdf);
+
+ bsdf = fresnel_blend(transmit_bsdf, reflect_bsdf, V, N, ior);
+}
+
+void bsdf_glass_sharp_sun_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float transmit_bsdf, reflect_bsdf;
+
+ bsdf_refract_sharp_sun_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, transmit_bsdf);
+ bsdf_glossy_sharp_sun_light(N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, roughness, ior,
+ sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, reflect_bsdf);
+
+ bsdf = fresnel_blend(transmit_bsdf, reflect_bsdf, V, N, ior);
+}
+
+
+/* -------- Image Based Lighting --------- */
+
+void env_sampling_glass_sharp(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+
+ /* reflection */
+ vec3 R = reflect(I, N);
+ vec4 reflect_bsdf = sample_reflect(R);
+
+ /* transmission */
+ float eta = (gl_FrontFacing) ? 1.0/ior : ior;
+ vec3 Tr = refract(I, N, eta);
+ vec4 transmit_bsdf = sample_refract(Tr);
+
+ result = fresnel_blend(transmit_bsdf.rgb, reflect_bsdf.rgb, I, N, ior) * specular_occlusion(dot(N,-I), ao_factor, 0.0);
+}
+
+void env_sampling_glass_ggx(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ /* Setup */
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+ make_orthonormals(N, T, B); /* Generate tangent space */
+ setup_noise(gl_FragCoord.xy); /* Noise to dither the samples */
+ float a, a2; prepare_glossy(roughness, a, a2);
+ ior = max(ior, 1e-5);
+
+ /* Precomputation */
+ float NV = max(1e-8, abs(dot(I, N)));
+ float G1_V = G1_Smith_GGX(NV, a2);
+
+ /* Integrating Envmap */
+ vec4 out_radiance = vec4(0.0);
+ for (float i = 0; i < unfbsdfsamples.x; i++) {
+ vec3 H = sample_ggx(i, a2, N, T, B); /* Microfacet normal */
+
+ /* TODO : For ior < 1.0 && roughness > 0.0 fresnel becomes not accurate.*/
+ float fresnel = fresnel_dielectric(I, H, (dot(H, -I) < 0.0) ? 1.0/ior : ior );
+
+ /* reflection */
+ vec3 R = reflect(I, H);
+ float NL = dot(N, R);
+ if (NL > 0.0) {
+ /* Step 1 : Sampling Environment */
+ float NH = max(1e-8, dot(N, H)); /* cosTheta */
+ float VH = max(1e-8, -dot(I, H));
+
+ float pdf = pdf_ggx_reflect(NH, a2);
+
+ vec4 sample = sample_reflect_pdf(R, roughness, pdf);
+
+ /* Step 2 : Integrating BRDF */
+ float brdf_pdf = bsdf_ggx_pdf(a2, NH, NL, VH, G1_V);
+
+ /* See reflect glossy */
+ out_radiance += NL * sample * brdf_pdf * fresnel;
+ }
+
+ /* transmission */
+ float eta = 1.0/ior;
+ if (dot(H, -I) < 0.0) {
+ H = -H;
+ eta = ior;
+ }
+
+ vec3 Tr = refract(I, H, eta);
+ NL = -dot(N, Tr);
+ if (NL > 0.0 && fresnel != 1.0) {
+ /* Step 1 : Sampling Environment */
+ float NH = dot(N, H); /* cosTheta */
+ float VH = dot(-I, H);
+ float LH = dot(Tr, H);
+ float tmp = ior * VH + LH;
+ float Ht2 = tmp * tmp;
+
+ float pdf = pdf_ggx_refract(Ht2, NH, NV, VH, LH, G1_V, a2, eta);
+
+ vec4 sample = sample_refract_pdf(Tr, roughness, pdf);
+
+ /* Step 2 : Integrating BRDF */
+ float brdf_pdf = bsdf_ggx_refract_pdf(a2, LH, NL, VH);
+
+ out_radiance += sample * brdf_pdf * (1 - fresnel);
+ }
+ }
+
+ result = out_radiance.rgb * unfbsdfsamples.y * specular_occlusion(NV, ao_factor, a2);
+}
+
+void env_sampling_glass_beckmann(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ /* Setup */
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+ make_orthonormals(N, T, B); /* Generate tangent space */
+ setup_noise(gl_FragCoord.xy); /* Noise to dither the samples */
+ float a, a2; prepare_glossy(roughness, a, a2);
+ ior = max(ior, 1e-5);
+
+ /* Precomputation */
+ float NV = max(1e-8, abs(dot(I, N)));
+ float G1_V = G1_Smith_GGX(NV, a2);
+
+ /* Integrating Envmap */
+ vec4 out_radiance = vec4(0.0);
+ for (float i = 0; i < unfbsdfsamples.x; i++) {
+ vec3 H = sample_beckmann(i, a2, N, T, B); /* Microfacet normal */
+
+ /* TODO : For ior < 1.0 && roughness > 0.0 fresnel becomes not accurate.*/
+ float fresnel = fresnel_dielectric(I, H, (dot(H, -I) < 0.0) ? 1.0/ior : ior );
+
+ /* reflection */
+ vec3 R = reflect(I, H);
+ float NL = dot(N, R);
+ if (NL > 0.0) {
+ /* Step 1 : Sampling Environment */
+ float NH = max(1e-8, dot(N, H)); /* cosTheta */
+ float VH = max(1e-8, -dot(I, H));
+
+ float pdf = pdf_beckmann_reflect(NH, a2);
+
+ vec4 sample = sample_reflect_pdf(R, roughness, pdf);
+
+ /* Step 2 : Integrating BRDF */
+ float brdf_pdf = bsdf_beckmann_pdf(a2, NH, NV, NL, VH, G1_V);
+
+ /* See reflect glossy */
+ out_radiance += NL * sample * brdf_pdf * fresnel;
+ }
+
+ /* transmission */
+ float eta = 1.0/ior;
+ if (dot(H, -I) < 0.0) {
+ H = -H;
+ eta = ior;
+ }
+
+ vec3 Tr = refract(I, H, eta);
+ NL = -dot(N, Tr);
+ if (NL > 0.0 && fresnel != 1.0) {
+ /* Step 1 : Sampling Environment */
+ float NH = dot(N, H); /* cosTheta */
+ float VH = dot(-I, H);
+ float LH = dot(Tr, H);
+ float tmp = ior * VH + LH;
+ float Ht2 = tmp * tmp;
+
+ float pdf = pdf_beckmann_refract(Ht2, NH, NV, VH, LH, G1_V, a2, eta);
+
+ vec4 sample = sample_refract_pdf(Tr, roughness, pdf);
+
+ /* Step 2 : Integrating BRDF */
+ float brdf_pdf = bsdf_beckmann_refract_pdf(a2, LH, NL, VH);
+
+ out_radiance += sample * brdf_pdf * (1 - fresnel);
+ }
+ }
+
+ result = out_radiance.rgb * unfbsdfsamples.y * specular_occlusion(NV, ao_factor, a2);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_material_bsdf_glossy.glsl b/source/blender/gpu/shaders/gpu_shader_material_bsdf_glossy.glsl
new file mode 100644
index 00000000000..612f5a3fc13
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_material_bsdf_glossy.glsl
@@ -0,0 +1,710 @@
+/* -------- Utils Functions --------- */
+
+vec3 sample_ggx(float nsample, float a2, vec3 N, vec3 T, vec3 B)
+{
+ vec3 Xi = hammersley_3d(nsample);
+
+ float z = sqrt( (1.0 - Xi.x) / ( 1.0 + a2 * Xi.x - Xi.x ) ); /* cos theta */
+ float r = sqrt( 1.0 - z * z ); /* sin theta */
+ float x = r * Xi.y;
+ float y = r * Xi.z;
+
+ /* Global variable */
+ Ht = vec3(x, y, z);
+
+ return from_tangent_to_world(Ht, N, T, B);
+}
+
+vec3 sample_beckmann(float nsample, float a2, vec3 N, vec3 T, vec3 B)
+{
+ vec3 Xi = hammersley_3d(nsample);
+
+ float z = sqrt( 1.0 / ( 1.0 - a2 * log(1.0 - Xi.x) ) ); /* cos theta */
+ float r = sqrt( 1.0 - z * z ); /* sin theta */
+ float x = r * Xi.y;
+ float y = r * Xi.z;
+
+ /* Global variable */
+ Ht = vec3(x, y, z);
+
+ return from_tangent_to_world(Ht, N, T, B);
+}
+
+vec3 sample_ashikhmin_shirley(float nsample, float n_x, vec3 N, vec3 T, vec3 B)
+{
+ vec3 Xi = hammersley_3d(nsample);
+
+ float z = pow( Xi.x, 1.0 / (n_x + 1.0) ); /* cos theta */
+ float r = sqrt( 1.0 - z * z ); /* sin theta */
+ float x = r * Xi.y;
+ float y = r * Xi.z;
+
+ /* Global variable */
+ Ht = vec3(x, y, z);
+
+ return from_tangent_to_world(Ht, N, T, B);
+}
+
+float D_ggx_opti(float NH, float a2)
+{
+ float tmp = (NH * a2 - NH) * NH + 1.0;
+ return M_PI * tmp*tmp; /* Doing RCP and mul a2 at the end */
+}
+
+float D_beckman(float NH, float a2)
+{
+ float NH2 = NH * NH;
+ return exp((NH2 - 1) / (NH2 * a2)) / (M_PI * a2 * NH2 * NH2);
+}
+
+float pdf_ggx_reflect(float NH, float a2)
+{
+ return NH * a2 / D_ggx_opti(NH, a2);
+}
+
+float pdf_beckmann_reflect(float NH, float a2)
+{
+ return NH * D_beckman(NH, a2);
+}
+
+float pdf_ashikhmin_shirley_reflect(float NH, float VH, float n_x)
+{
+ float lobe = pow(NH, n_x);
+ float norm = (n_x + 1.0) * 0.125 * M_1_PI;
+
+ return norm * lobe / VH;
+}
+
+void prepare_glossy(float roughness, out float a, out float a2)
+{
+ /* Artifacts appear with roughness below this threshold */
+ /* XXX TODO : find why flooring is necessary */
+ a = clamp(roughness, 2e-4, 0.9999999);
+ a2 = max(1e-8, a*a);
+}
+
+float G1_Smith_GGX(float NX, float a2)
+{
+ /* Using Brian Karis approach and refactoring by NX/NX
+ * this way the (2*NL)*(2*NV) in G = G1(V) * G1(L) gets canceled by the brdf denominator 4*NL*NV
+ * Rcp is done on the whole G later
+ * Note that this is not convenient for the transmition formula */
+ return NX + sqrt( NX * (NX - NX * a2) + a2 );
+ /* return 2 / (1 + sqrt(1 + a2 * (1 - NX*NX) / (NX*NX) ) ); /* Reference function */
+}
+
+float G1_Smith_beckmann(float NX, float a2)
+{
+ float tmp = 1 / (sqrt(a2 * (1 - NX * NX) / (NX * NX)));
+ return (tmp < 1.6) ? (3.535 * tmp + 2.181 * tmp * tmp) / (1 + 2.276 * tmp + 2.577 * tmp * tmp) : 1.0;
+}
+
+/* -------- BSDF --------- */
+
+float bsdf_ggx(vec3 N, vec3 L, vec3 V, float roughness)
+{
+ float a, a2; prepare_glossy(roughness, a, a2);
+
+ vec3 H = normalize(L + V);
+ float NH = max(dot(N, H), 1e-8);
+ float NL = max(dot(N, L), 1e-8);
+ float NV = max(dot(N, V), 1e-8);
+
+ float G = G1_Smith_GGX(NV, a2) * G1_Smith_GGX(NL, a2); /* Doing RCP at the end */
+ float D = D_ggx_opti(NH, a2);
+
+ /* Denominator is canceled by G1_Smith */
+ /* bsdf = D * G / (4.0 * NL * NV); /* Reference function */
+ return NL * a2 / (D * G); /* NL to Fit cycles Equation : line. 345 in bsdf_microfacet.h */
+}
+
+/* This one returns the brdf already divided by the pdf */
+float bsdf_ggx_pdf(float a2, float NH, float NL, float VH, float G1_V)
+{
+ float G = G1_V * G1_Smith_GGX(NL, a2); /* Doing RCP at the end */
+
+ /* Denominator is canceled by G1_Smith
+ * brdf = D * G / (4.0 * NL * NV) [denominator canceled by G]
+ * pdf = D * NH / (4 * VH) [D canceled later by D in brdf] */
+ return 4.0 * VH / (NH * G); /* brdf / pdf */
+}
+
+float bsdf_beckmann(vec3 N, vec3 L, vec3 V, float roughness)
+{
+ float a, a2; prepare_glossy(roughness, a, a2);
+
+ vec3 H = normalize(L + V);
+ float NH = max(dot(N, H), 1e-8);
+ float NL = max(dot(N, L), 1e-8);
+ float NV = max(dot(N, V), 1e-8);
+
+ float G = G1_Smith_beckmann(NV, a2) * G1_Smith_beckmann(NL, a2);
+ float D = D_beckman(NH, a2);
+
+ return NL * D * G * 0.25 / (NL * NV);
+}
+
+/* This one returns the brdf already divided by the pdf */
+float bsdf_beckmann_pdf(float a2, float NH, float NV, float NL, float VH, float G1_V)
+{
+ float G = G1_V * G1_Smith_beckmann(NL, a2);
+
+ /* brdf = D * G / (4.0 * NL * NV)
+ * pdf = D * NH / (4 * VH) [D canceled later by D in brdf] */
+ return G * VH / (NH * NV * NL); /* brdf / pdf */
+}
+
+float bsdf_ashikhmin_shirley(vec3 N, vec3 L, vec3 V, float roughness)
+{
+ float a, a2; prepare_glossy(roughness, a, a2);
+
+ vec3 H = normalize(L + V);
+ float NL = max(dot(N, L), 1e-6);
+ float NV = max(dot(N, V), 1e-6);
+ float NH = max(dot(N, H), 1e-6);
+ float VH = max(abs(dot(V, H)), 1e-6);
+
+ float pump = 1.0 / max(1e-6, VH * max(NL, NV));
+ float n_x = 2.0 / a2 - 2.0;
+ float lobe = pow(NH, n_x);
+ float norm = (n_x + 1.0f) * 0.125 * M_1_PI;
+
+ return NL * norm * lobe * pump;
+}
+
+/* This one returns the brdf already divided by the pdf */
+float bsdf_ashikhmin_shirley_pdf(float NV, float NL, float VH)
+{
+ float pump = 1.0 / max(1e-6, VH * max(NL, NV));
+
+ return VH * pump;
+}
+
+/* -------- Preview Lights --------- */
+
+void node_bsdf_glossy_lights(vec4 color, float roughness, vec3 N, vec3 V, vec4 ambient_light, out vec4 result)
+{
+ vec3 accumulator = ambient_light.rgb;
+
+ if (roughness <= 1e-4) {
+ result = vec4(accumulator * color.rgb, 1.0);
+ return;
+ }
+
+ shade_view(V, V); V = -V;
+ N = normalize(N);
+
+ /* directional lights */
+ for(int i = 0; i < NUM_LIGHTS; i++) {
+ vec3 L = gl_LightSource[i].position.xyz;
+ vec3 light_color = gl_LightSource[i].specular.rgb;
+
+ accumulator += light_color * bsdf_ggx(N, L, V, roughness);
+ }
+
+ result = vec4(accumulator * color.rgb, 1.0);
+}
+
+/* -------- Physical Lights --------- */
+
+/* GLOSSY SHARP */
+
+void bsdf_glossy_sharp_sphere_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float l_radius = l_areasizex;
+ L = l_distance * L;
+ vec3 R = -reflect(V, N);
+
+ vec3 P = line_aligned_plane_intersect(vec3(0.0), R, L);
+ bsdf = (distance_squared(P, L) < l_radius * l_radius) ? 1.0 : 0.0;
+
+ /* Energy conservation + cycle matching */
+ bsdf *= sphere_energy(l_radius);
+}
+
+void bsdf_glossy_sharp_area_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ if (max(l_areasizex, l_areasizey) < 1e-6) {
+ bsdf = 0.0;
+ return;
+ }
+
+ L = l_distance * L;
+
+ vec3 lampx, lampy, lampz;
+ vec2 halfsize = area_light_prepass(l_mat, l_areasizex, l_areasizey, l_areascale, lampx, lampy, lampz);
+
+ /* Find the intersection point E between the reflection vector and the light plane */
+ vec3 R = reflect(V, N);
+ vec3 E = line_plane_intersect(vec3(0.0), R, L, lampz);
+
+ /* Project it onto the light plane */
+ vec3 projection = E - L;
+ float A = dot(lampx, projection);
+ float B = dot(lampy, projection);
+
+ bsdf = (abs(A) < halfsize.x && abs(B) < halfsize.y) ? 1.0 : 0.0;
+
+ /* Masking */
+ bsdf *= (dot(-L, lampz) > 0.0) ? 1.0 : 0.0;
+ bsdf *= (dot(R, lampz) > 0.0) ? 1.0 : 0.0;
+
+ /* Energy conservation + cycle matching */
+ bsdf *= rectangle_energy(l_areasizex, l_areasizey);
+}
+
+void bsdf_glossy_sharp_sun_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ vec3 R = reflect(V, N);
+
+ float l_radius = l_areasizex;
+ float angle = atan(l_radius);
+
+ float costheta = dot(-L, R);
+ float cosangle = cos(angle);
+
+ bsdf = (costheta > cosangle) ? 1.0 : 0.0;
+
+ /* Energy conservation + cycle matching */
+ bsdf *= disk_energy(l_radius);
+ bsdf /= costheta * costheta * costheta;
+ bsdf *= M_PI;
+}
+
+/* GLOSSY GGX */
+
+void bsdf_glossy_ggx_sphere_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ if (roughness < 1e-4 && l_areasizex == 0) {
+ bsdf = 0.0;
+ return;
+ }
+
+#if 1
+ /* MRP is twice as fast as LTC, does not exhibit crucial artifacts and is better looking */
+ float l_radius = l_areasizex;
+
+ shade_view(V, V);
+ vec3 R = reflect(V, N);
+
+ float energy_conservation = 1.0;
+ most_representative_point(l_radius, 0.0, vec3(0.0), l_distance, R, L, roughness, energy_conservation);
+ bsdf = bsdf_ggx(N, L, V, roughness);
+
+ bsdf *= energy_conservation / (l_distance * l_distance);
+ bsdf *= sphere_energy(l_radius) * max(l_radius * l_radius, 1e-16); /* l_radius is already inside energy_conservation */
+ bsdf *= M_PI;
+#else
+ /* LTC */
+ float l_radius = max(0.007, l_areasizex);
+
+ vec3 pos = V;
+ shade_view(V, V);
+ vec3 R = -reflect(V, N);
+ L = l_distance * L;
+ V = -V;
+ N = -N;
+
+ vec3 P = line_aligned_plane_intersect(vec3(0.0), R, L);
+ vec3 Px = normalize(P - L) * l_radius;
+ vec3 Py = axis_angle_rotation(Px, R, M_PI_2);
+
+ vec3 points[4];
+ points[0] = l_coords + Px;
+ points[1] = l_coords - Py;
+ points[2] = l_coords - Px;
+ points[3] = l_coords + Py;
+
+ float NV = max(dot(N, V), 1e-8);
+ vec2 uv = ltc_coords(NV, sqrt(roughness));
+ mat3 ltcmat = ltc_matrix(uv);
+
+ bsdf = ltc_evaluate(N, V, pos, ltcmat, points);
+ bsdf *= texture2D(unfltcmag, uv).r; /* Bsdf matching */
+
+ bsdf *= M_1_2PI;
+ bsdf *= sphere_energy(l_radius);
+#endif
+}
+
+void bsdf_glossy_ggx_area_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ if (min(l_areasizex, l_areasizey) < 1e-6) {
+ bsdf = 0.0;
+ return;
+ }
+
+ vec3 pos = V;
+ shade_view(V, V);
+ V = -V;
+ N = -N;
+
+ vec3 lampx, lampy, lampz;
+ vec2 halfsize = area_light_prepass(l_mat, l_areasizex, l_areasizey, l_areascale, lampx, lampy, lampz);
+
+ vec3 points[4];
+ area_light_points(l_coords, halfsize, lampx, lampy, points);
+
+ float NV = max(dot(N, V), 1e-8);
+ vec2 uv = ltc_coords(NV, sqrt(roughness));
+ mat3 ltcmat = ltc_matrix(uv);
+
+ bsdf = ltc_evaluate(N, V, pos, ltcmat, points);
+ bsdf *= texture2D(unfltcmag, uv).r; /* Bsdf matching */
+
+ bsdf *= step(0.0, -dot(L, lampz));
+ bsdf *= M_1_2PI;
+ bsdf *= rectangle_energy(l_areasizex, l_areasizey);
+}
+
+void bsdf_glossy_ggx_sun_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ /* Correct ligth shape but uniform intensity
+ * Does not take into account the division by costheta^3 */
+ if (roughness < 1e-4 && l_areasizex == 0) {
+ bsdf = 0.0;
+ return;
+ }
+
+ vec3 R = reflect(V, N);
+
+ float l_radius = l_areasizex;
+ float angle = atan(l_radius);
+
+ float costheta = dot(-L, R);
+ float cosangle = cos(angle);
+
+ float energy_conservation = 1.0;
+ most_representative_point_disk(l_radius, 1.0, R, L, roughness, energy_conservation);
+
+ bsdf = bsdf_ggx(N, L, V, roughness);
+ bsdf *= energy_conservation;
+}
+
+/* GLOSSY BECKMANN */
+
+void bsdf_glossy_beckmann_sphere_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ if (roughness < 1e-4 && l_areasizex == 0) {
+ bsdf = 0.0;
+ return;
+ }
+
+ /* MRP is twice as fast as LTC, does not exhibit crucial artifacts and is better looking */
+ float l_radius = l_areasizex;
+
+ shade_view(V, V);
+ vec3 R = reflect(V, N);
+
+ float energy_conservation = 1.0; /* XXX TODO : Energy conservation is done for GGX */
+ most_representative_point(l_radius, 0.0, vec3(0.0), l_distance, R, L, roughness, energy_conservation);
+ bsdf = bsdf_beckmann(N, L, V, roughness);
+
+ bsdf *= energy_conservation / (l_distance * l_distance);
+ bsdf *= sphere_energy(l_radius) * max(l_radius * l_radius, 1e-16); /* l_radius is already inside energy_conservation */
+ bsdf *= M_PI;
+}
+
+void bsdf_glossy_beckmann_area_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ /* TODO Make the other ltc luts */
+ bsdf_glossy_ggx_area_light( N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale,
+ l_mat, roughness, ior, sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, bsdf);
+}
+
+void bsdf_glossy_beckmann_sun_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ /* Correct ligth shape but uniform intensity
+ * Does not take into account the division by costheta^3 */
+ if (roughness < 1e-4 && l_areasizex == 0) {
+ bsdf = 0.0;
+ return;
+ }
+
+ vec3 R = reflect(V, N);
+
+ float l_radius = l_areasizex;
+ float angle = atan(l_radius);
+
+ float costheta = dot(-L, R);
+ float cosangle = cos(angle);
+
+ float energy_conservation = 1.0;
+ most_representative_point_disk(l_radius, 1.0, R, L, roughness, energy_conservation);
+
+ bsdf = bsdf_beckmann(N, L, V, roughness);
+ bsdf *= energy_conservation;
+}
+
+/* GLOSSY ASHIKhMIN SHIRLEY */
+
+void bsdf_glossy_ashikhmin_shirley_sphere_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ if (roughness < 1e-4 && l_areasizex == 0) {
+ bsdf = 0.0;
+ return;
+ }
+
+ /* MRP is twice as fast as LTC, does not exhibit crucial artifacts and is better looking */
+ float l_radius = l_areasizex;
+
+ shade_view(V, V);
+ vec3 R = reflect(V, N);
+
+ float energy_conservation = 1.0; /* XXX TODO : Energy conservation is done for GGX */
+ most_representative_point(l_radius, 0.0, vec3(0.0), l_distance, R, L, roughness, energy_conservation);
+ bsdf = bsdf_ashikhmin_shirley(N, L, V, roughness);
+
+ bsdf *= energy_conservation / (l_distance * l_distance);
+ bsdf *= sphere_energy(l_radius) * max(l_radius * l_radius, 1e-16); /* l_radius is already inside energy_conservation */
+ bsdf *= M_PI;
+}
+
+void bsdf_glossy_ashikhmin_shirley_area_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ /* TODO Make the other ltc luts */
+ bsdf_glossy_ggx_area_light( N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale,
+ l_mat, roughness, ior, sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, bsdf);
+}
+
+void bsdf_glossy_ashikhmin_shirley_sun_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ /* Correct ligth shape but uniform intensity
+ * Does not take into account the division by costheta^3 */
+ if (roughness < 1e-4 && l_areasizex == 0) {
+ bsdf = 0.0;
+ return;
+ }
+
+ vec3 R = reflect(V, N);
+
+ float l_radius = l_areasizex;
+ float angle = atan(l_radius);
+
+ float costheta = dot(-L, R);
+ float cosangle = cos(angle);
+
+ float energy_conservation = 1.0;
+ most_representative_point_disk(l_radius, 1.0, R, L, roughness, energy_conservation);
+
+ bsdf = bsdf_ashikhmin_shirley(N, L, V, roughness);
+ bsdf *= energy_conservation;
+}
+
+/* -------- Image Based Lighting --------- */
+
+void env_sampling_glossy_sharp(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ /* Setup */
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+
+ /* Precomputation */
+ vec3 L = reflect(I, N);
+ vec3 vL = (viewmat * vec4(L, 0.0)).xyz;
+
+ /* Probe */
+ vec4 sample_probe = sample_reflect(L) * specular_occlusion(dot(N, -I), ao_factor, 0.0);
+
+#ifdef USE_SSR
+ /* SSR */
+ vec2 hitpixel; vec3 hitco; float hitstep;
+
+ bool hit = raycast(viewpos, vL, hitstep, hitpixel, hitco);
+ float contrib = ssr_contribution(viewpos, hitstep, hit, hitco);
+
+ vec4 sample_ssr = bufferFetch(unfscenebuf, ivec2(hitpixel), 0);
+ srgb_to_linearrgb(sample_ssr, sample_ssr);
+
+ result = mix(sample_probe.rgb, sample_ssr.rgb, contrib);
+ //result = mix(vec3(1.0,0.0,0.0), vec3(0.0,1.0,0.0), hit);
+ //result = sample_ssr.rgb * float(hit);
+ // result = hitco;
+//result = vL.rgb;
+ //result = vec3(frontface_depth(ivec2(gl_FragCoord.xy), 0));
+#else
+ result = sample_probe.rgb;
+#endif
+}
+
+void env_sampling_glossy_ggx(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ /* Setup */
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+ make_orthonormals(N, T, B); /* Generate tangent space */
+ setup_noise(gl_FragCoord.xy); /* Noise to dither the samples */
+ float a, a2; prepare_glossy(roughness, a, a2);
+
+ /* Precomputation */
+ float NV = max(1e-8, abs(dot(I, N)));
+ float G1_V = G1_Smith_GGX(NV, a2);
+
+ /* Integrating Envmap */
+ vec4 out_radiance = vec4(0.0);
+ for (float i = 0; i < unfbsdfsamples.x; i++) {
+ vec3 H = sample_ggx(i, a2, N, T, B); /* Microfacet normal */
+ vec3 L = reflect(I, H);
+ float NL = dot(N, L);
+
+ if (NL > 0.0) {
+ /* Step 1 : Sampling Environment */
+ float NH = max(1e-8, dot(N, H)); /* cosTheta */
+ float VH = max(1e-8, -dot(I, H));
+
+ float pdf = pdf_ggx_reflect(NH, a2);
+
+ vec4 sample = sample_reflect_pdf(L, roughness, pdf);
+
+ /* Step 2 : Integrating BRDF */
+ float brdf_pdf = bsdf_ggx_pdf(a2, NH, NL, VH, G1_V);
+
+ out_radiance += NL * sample * brdf_pdf;
+ }
+ }
+
+ result = out_radiance.rgb * unfbsdfsamples.y * specular_occlusion(NV, ao_factor, a2);
+}
+
+void env_sampling_glossy_beckmann(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ /* Setup */
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+ make_orthonormals(N, T, B); /* Generate tangent space */
+ setup_noise(gl_FragCoord.xy); /* Noise to dither the samples */
+ float a, a2; prepare_glossy(roughness, a, a2);
+
+ /* Precomputation */
+ float NV = max(1e-8, abs(dot(I, N)));
+ float G1_V = G1_Smith_beckmann(NV, a2);
+
+ /* Integrating Envmap */
+ vec4 out_radiance = vec4(0.0);
+ for (float i = 0; i < unfbsdfsamples.x; i++) {
+ vec3 H = sample_beckmann(i, a2, N, T, B); /* Microfacet normal */
+ vec3 L = reflect(I, H);
+ float NL = dot(N, L);
+
+ if (NL > 0.0) {
+ /* Step 1 : Sampling Environment */
+ float NH = max(1e-8, dot(N, H)); /* cosTheta */
+ float VH = max(1e-8, -dot(I, H));
+
+ float pdf = pdf_beckmann_reflect(NH, a2);
+
+ vec4 sample = sample_reflect_pdf(L, roughness, pdf);
+
+ /* Step 2 : Integrating BRDF */
+ float brdf_pdf = bsdf_beckmann_pdf(a2, NH, NV, NL, VH, G1_V);
+
+ out_radiance += NL * sample * brdf_pdf;
+ }
+ }
+
+ result = out_radiance.rgb * unfbsdfsamples.y * specular_occlusion(NV, ao_factor, a2);
+}
+
+void env_sampling_glossy_ashikhmin_shirley(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ /* Setup */
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+ make_orthonormals(N, T, B); /* Generate tangent space */
+ setup_noise(gl_FragCoord.xy); /* Noise to dither the samples */
+ float a, a2; prepare_glossy(roughness, a, a2);
+
+ /* Precomputation */
+ float NV = max(1e-8, abs(dot(I, N)));
+ float n_x = 2.0 / a2 - 2.0;
+
+ /* Integrating Envmap */
+ vec4 out_radiance = vec4(0.0);
+ for (float i = 0; i < unfbsdfsamples.x; i++) {
+ vec3 H = sample_ashikhmin_shirley(i, n_x, N, T, B); /* Microfacet normal */
+ float VH = dot(H, -I);
+ if (VH < 0.0) H = -H;
+ /* reflect I on H to get omega_in */
+ vec3 L = I + (2.0 * VH) * H;
+ float NL = dot(N, L);
+
+ if (NL > 0.0) {
+ /* Step 1 : Sampling Environment */
+ float NH = max(1e-8, dot(N, H)); /* cosTheta */
+ VH = max(1e-8, abs(VH));
+ NL = max(1e-8, NL);
+
+ float pdf = pdf_ashikhmin_shirley_reflect(NH, VH, n_x);
+
+ vec4 sample = sample_reflect_pdf(L, roughness, pdf);
+
+ /* Step 2 : Integrating BRDF */
+ float brdf_pdf = bsdf_ashikhmin_shirley_pdf(NV, NL, VH);
+
+ out_radiance += NL * sample * brdf_pdf;
+ }
+ }
+
+ result = out_radiance.rgb * unfbsdfsamples.y * specular_occlusion(NV, ao_factor, a2);
+}
+
diff --git a/source/blender/gpu/shaders/gpu_shader_material_bsdf_refraction.glsl b/source/blender/gpu/shaders/gpu_shader_material_bsdf_refraction.glsl
new file mode 100644
index 00000000000..aeecb56696a
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_material_bsdf_refraction.glsl
@@ -0,0 +1,490 @@
+/* -------- Utils Functions --------- */
+
+float pdf_ggx_refract(float Ht2, float NH, float NV, float VH, float LH, float G1_V, float a2, float eta)
+{
+ return (VH * abs(LH)) * (eta*eta) * a2 * G1_V / (Ht2 * NV * D_ggx_opti(NH, a2));
+}
+
+float pdf_beckmann_refract(float Ht2, float NH, float NV, float VH, float LH, float G1_V, float a2, float eta)
+{
+ /* pdf = (VH * abs(LH)) * (ior*ior) * D * G(V) / (Ht2 * NV) */
+ return (VH * abs(LH)) * (eta*eta) * D_beckman(NH, a2) * G1_V / (Ht2 * NV);
+}
+
+/* -------- BSDF --------- */
+
+float bsdf_ggx_refract(float Ht2, float NH, float NL, float NV, float VH, float LH, float a2, float eta)
+{
+ float G = G1_Smith_GGX(NV, a2) * G1_Smith_GGX(NL, a2);
+ float D = D_ggx_opti(NH, a2); /* Doing RCP and mul a2 at the end */
+
+ /* bsdf = abs(LH * VH) * (eta*eta) * G * D / (NV * Ht2); /* Reference function */
+ return abs(LH * VH) * (NV * NL * 4.0) * a2 * (eta*eta) / (D * G * NV * Ht2); /* Balancing the adjustments made in G1_Smith with (NV * NL * 4.0)*/
+}
+
+float bsdf_ggx_refract(vec3 N, vec3 L, vec3 V, float eta, float roughness)
+{
+ /* GGX Spec Isotropic Transmited */
+ float a, a2; prepare_glossy(roughness, a, a2);
+
+ vec3 ht = -(eta * L + V);
+ vec3 Ht = normalize(ht);
+ float Ht2 = dot(ht, ht);
+ float NH = dot(N, Ht);
+ float NL = dot(N, -L);
+ float NV = dot(N, V);
+ float VH = dot(V, Ht);
+ float LH = dot(-L, Ht);
+
+ return bsdf_ggx_refract(Ht2, NH, NL, NV, VH, LH, a2, eta);
+}
+
+/* This one returns the brdf already divided by the pdf */
+float bsdf_ggx_refract_pdf(float a2, float LH, float NL, float VH)
+{
+ float G1_L = NL * 2.0 / G1_Smith_GGX(NL, a2); /* Balancing the adjustments made in G1_Smith */
+
+ /* brdf = abs(VH*LH) * (ior*ior) * D * G(V) * G(L) / (Ht2 * NV)
+ * pdf = (VH * abs(LH)) * (ior*ior) * D * G(V) / (Ht2 * NV) */
+ return G1_L * abs(VH*LH) / (VH * abs(LH));
+}
+
+float bsdf_beckmann_refract(float Ht2, float NH, float NL, float NV, float VH, float LH, float a, float a2, float eta)
+{
+ float G = G1_Smith_beckmann(NV, a2) * G1_Smith_beckmann(NL, a2);
+ float D = D_beckman(NH, a2);
+
+ return abs(LH * VH) * D * G * (eta*eta) / (NV * Ht2);
+}
+
+float bsdf_beckmann_refract(vec3 N, vec3 L, vec3 V, float eta, float roughness)
+{
+ float a, a2; prepare_glossy(roughness, a, a2);
+
+ vec3 ht = -(eta * L + V);
+ vec3 Ht = normalize(ht);
+ float Ht2 = dot(ht, ht);
+ float NH = dot(N, Ht);
+ float NL = dot(N, -L);
+ float NV = dot(N, V);
+ float VH = dot(V, Ht);
+ float LH = dot(-L, Ht);
+
+ return bsdf_beckmann_refract(Ht2, NH, NL, NV, VH, LH, a, a2, eta);
+}
+
+/* This one returns the brdf already divided by the pdf */
+float bsdf_beckmann_refract_pdf(float a2, float LH, float NL, float VH)
+{
+ /* brdf = abs(VH*LH) * (ior*ior) * D * G(V) * G(L) / (Ht2 * NV)
+ * pdf = (VH * abs(LH)) * (ior*ior) * D * G(V) / (Ht2 * NV) */
+ return G1_Smith_beckmann(NL, a2) * abs(VH*LH) / (VH * abs(LH));
+}
+
+/* -------- Preview Lights --------- */
+
+void node_bsdf_refraction_lights(vec4 color, float roughness, float ior, vec3 N, vec3 V, vec4 ambient_light, out vec4 result)
+{
+ node_bsdf_glossy_lights(color, roughness, N, V, ambient_light, result);
+}
+
+/* -------- Physical Lights --------- */
+
+/* REFRACT SHARP */
+
+void bsdf_refract_sharp_sphere_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float l_radius = l_areasizex;
+ L = l_distance * L;
+ vec3 R = -refract(-V, N, (gl_FrontFacing) ? 1.0/ior : ior);
+
+ vec3 P = line_aligned_plane_intersect(vec3(0.0), R, L);
+ bsdf = (distance_squared(P, L) < l_radius * l_radius) ? 1.0 : 0.0;
+
+ /* Energy conservation + cycle matching */
+ bsdf *= sphere_energy(l_radius);
+}
+
+void bsdf_refract_sharp_area_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ if (max(l_areasizex, l_areasizey) < 1e-6) {
+ bsdf = 0.0;
+ return;
+ }
+
+ L = l_distance * L;
+
+ vec3 lampx, lampy, lampz;
+ vec2 halfsize = area_light_prepass(l_mat, l_areasizex, l_areasizey, l_areascale, lampx, lampy, lampz);
+
+ /* Find the intersection point E between the reflection vector and the light plane */
+ float eta = (gl_FrontFacing) ? ior : 1.0/ior;
+ vec3 R = refract(-V, N, 1.0/eta);
+ vec3 E = line_plane_intersect(vec3(0.0), R, L, lampz);
+
+ /* Project it onto the light plane */
+ vec3 projection = E - L;
+ float A = dot(lampx, projection);
+ float B = dot(lampy, projection);
+
+ bsdf = (abs(A) < halfsize.x && abs(B) < halfsize.y) ? 1.0 : 0.0;
+
+ /* Masking */
+ bsdf *= (dot(-L, lampz) > 0.0) ? 1.0 : 0.0;
+ bsdf *= (dot(-R, lampz) > 0.0) ? 1.0 : 0.0;
+
+ /* Energy conservation + cycle matching */
+ bsdf *= rectangle_energy(l_areasizex, l_areasizey);
+}
+
+void bsdf_refract_sharp_sun_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float eta = (gl_FrontFacing) ? ior : 1.0/ior;
+ vec3 R = refract(-V, N, 1.0/eta);
+
+ float l_radius = l_areasizex;
+ float angle = atan(l_radius);
+
+ float costheta = dot(L, R);
+ float cosangle = cos(angle);
+
+ bsdf = (costheta > cosangle) ? 1.0 : 0.0;
+
+ /* Energy conservation + cycle matching */
+ bsdf *= disk_energy(l_radius);
+ bsdf /= costheta * costheta * costheta;
+ bsdf *= M_PI;
+}
+
+/* REFRACT GGX */
+
+void bsdf_refract_ggx_sphere_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ if (roughness < 1e-4 && l_areasizex == 0) {
+ bsdf = 0.0;
+ return;
+ }
+
+ float l_radius = l_areasizex;
+
+ shade_view(V, V);
+ float eta = (gl_FrontFacing) ? ior : 1.0/ior;
+ vec3 R = refract(-V, N, 1.0/eta);
+
+ float energy_conservation = 1.0;
+ most_representative_point(l_radius, 0.0, vec3(0.0), l_distance, R, L, roughness, energy_conservation);
+ bsdf = bsdf_ggx_refract(N, L, V, eta, roughness);
+
+ bsdf *= energy_conservation / (l_distance * l_distance);
+ bsdf *= sphere_energy(l_radius) * max(l_radius * l_radius, 1e-16); /* l_radius is already inside energy_conservation */
+ bsdf *= M_PI; /* XXX : !!! Very Empirical, Fit cycles power */
+}
+
+void bsdf_refract_ggx_area_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ if (min(l_areasizex, l_areasizey) < 1e-6) {
+ bsdf = 0.0;
+ return;
+ }
+
+ l_areasizex *= l_areascale.x;
+ l_areasizey *= l_areascale.y;
+
+ /* Used later for Masking : Use the real Light Vector */
+ vec3 lampz = normalize( (l_mat * vec4(0.0,0.0,1.0,0.0) ).xyz ); //lamp projection axis
+ float masking = max(dot( normalize(-L), lampz), 0.0);
+
+ float max_size = max(l_areasizex, l_areasizey);
+ float min_size = min(l_areasizex, l_areasizey);
+ vec3 lampVec = (l_areasizex > l_areasizey) ? normalize( (l_mat * vec4(1.0,0.0,0.0,0.0) ).xyz ) : normalize( (l_mat * vec4(0.0,1.0,0.0,0.0) ).xyz );
+
+
+ float eta = (gl_FrontFacing) ? ior : 1.0/ior;
+ vec3 R = refract(-V, N, 1.0/eta);
+ float energy_conservation = 1.0;
+ most_representative_point(min_size/2, max_size-min_size, lampVec, l_distance, R, L, roughness, energy_conservation);
+ bsdf = bsdf_ggx_refract(N, L, V, eta, roughness);
+
+ /* energy_conservation */
+ float LineAngle = clamp( (max_size-min_size) / l_distance, 0.0, 1.0);
+ float energy_conservation_line = energy_conservation * ( roughness / clamp(roughness + 0.5 * LineAngle, 0.0, 1.1));
+
+ /* XXX : Empirical modification for low roughness matching */
+ float energy_conservation_mod = energy_conservation * (1 + roughness) / ( max_size/min_size );
+ energy_conservation = mix(energy_conservation_mod, energy_conservation_line, min(roughness/0.3, 0.9*(1.1-roughness)/0.1));
+
+ /* As we represent the Area Light by a tube light we must use a custom energy conservation */
+ bsdf *= energy_conservation / (l_distance * l_distance);
+ bsdf *= masking;
+ bsdf *= 23.2; /* XXX : !!! Very Empirical, Fit cycles power */
+}
+
+void bsdf_refract_ggx_sun_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ /* Correct ligth shape but uniform intensity
+ * Does not take into account the division by costheta^3 */
+ if (roughness < 1e-4 && l_areasizex == 0) {
+ bsdf = 0.0;
+ return;
+ }
+
+ float eta = (gl_FrontFacing) ? ior : 1.0/ior;
+ vec3 R = refract(-V, N, 1.0/eta);
+
+ float l_radius = l_areasizex;
+
+ float energy_conservation = 1.0;
+ most_representative_point_disk(l_radius, 1.0, R, L, roughness, energy_conservation);
+
+ bsdf = bsdf_ggx_refract(N, L, V, eta, roughness);
+ bsdf *= energy_conservation;
+}
+
+/* REFRACT BECKMANN */
+
+void bsdf_refract_beckmann_sphere_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ if (roughness < 1e-4 && l_areasizex == 0) {
+ bsdf = 0.0;
+ return;
+ }
+
+ float l_radius = l_areasizex;
+
+ shade_view(V, V);
+ float eta = (gl_FrontFacing) ? ior : 1.0/ior;
+ vec3 R = refract(-V, N, 1.0/eta);
+
+ float energy_conservation = 1.0;
+ most_representative_point(l_radius, 0.0, vec3(0.0), l_distance, R, L, roughness, energy_conservation);
+ bsdf = bsdf_beckmann_refract(N, L, V, eta, roughness);
+
+ bsdf *= energy_conservation / (l_distance * l_distance);
+ bsdf *= sphere_energy(l_radius) * max(l_radius * l_radius, 1e-16); /* l_radius is already inside energy_conservation */
+ bsdf *= M_PI; /* XXX : !!! Very Empirical, Fit cycles power */
+ bsdf *= step(0.0, dot(-L, N));
+}
+
+void bsdf_refract_beckmann_area_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ if (min(l_areasizex, l_areasizey) < 1e-6) {
+ bsdf = 0.0;
+ return;
+ }
+
+ l_areasizex *= l_areascale.x;
+ l_areasizey *= l_areascale.y;
+
+ /* Used later for Masking : Use the real Light Vector */
+ vec3 lampz = normalize( (l_mat * vec4(0.0,0.0,1.0,0.0) ).xyz ); //lamp projection axis
+ float masking = max(dot( normalize(-L), lampz), 0.0);
+
+ float max_size = max(l_areasizex, l_areasizey);
+ float min_size = min(l_areasizex, l_areasizey);
+ vec3 lampVec = (l_areasizex > l_areasizey) ? normalize( (l_mat * vec4(1.0,0.0,0.0,0.0) ).xyz ) : normalize( (l_mat * vec4(0.0,1.0,0.0,0.0) ).xyz );
+
+
+ float eta = (gl_FrontFacing) ? ior : 1.0/ior;
+ vec3 R = refract(-V, N, 1.0/eta);
+ float energy_conservation = 1.0;
+ most_representative_point(min_size/2, max_size-min_size, lampVec, l_distance, R, L, roughness, energy_conservation);
+ bsdf = bsdf_beckmann_refract(N, L, V, eta, roughness);
+
+ /* energy_conservation */
+ float LineAngle = clamp( (max_size-min_size) / l_distance, 0.0, 1.0);
+ float energy_conservation_line = energy_conservation * ( roughness / clamp(roughness + 0.5 * LineAngle, 0.0, 1.1));
+
+ /* XXX : Empirical modification for low roughness matching */
+ float energy_conservation_mod = energy_conservation * (1 + roughness) / ( max_size/min_size );
+ energy_conservation = mix(energy_conservation_mod, energy_conservation_line, min(roughness/0.3, 0.9*(1.1-roughness)/0.1));
+
+ /* As we represent the Area Light by a tube light we must use a custom energy conservation */
+ bsdf *= energy_conservation / (l_distance * l_distance);
+ bsdf *= masking;
+ bsdf *= step(0.0, dot( normalize(-L), N));
+ bsdf *= 23.2; /* XXX : !!! Very Empirical, Fit cycles power */
+}
+
+void bsdf_refract_beckmann_sun_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ /* Correct ligth shape but uniform intensity
+ * Does not take into account the division by costheta^3 */
+ if (roughness < 1e-4 && l_areasizex == 0) {
+ bsdf = 0.0;
+ return;
+ }
+
+ float eta = (gl_FrontFacing) ? ior : 1.0/ior;
+ vec3 R = refract(-V, N, 1.0/eta);
+
+ float l_radius = l_areasizex;
+
+ float energy_conservation = 1.0;
+ most_representative_point_disk(l_radius, 1.0, R, L, roughness, energy_conservation);
+
+ bsdf = bsdf_beckmann_refract(N, L, V, eta, roughness);
+ bsdf *= energy_conservation;
+ bsdf *= step(0.0, dot(-L, N));
+}
+
+/* -------- Image Based Lighting --------- */
+
+void env_sampling_refract_sharp(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ /* Setup */
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+ float eta = (gl_FrontFacing) ? 1.0/ior : ior;
+
+ vec3 L = refract(I, N, eta);
+
+ result = sample_refract(L).rgb;
+}
+
+void env_sampling_refract_ggx(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ /* Setup */
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+ make_orthonormals(N, T, B); /* Generate tangent space */
+ setup_noise(gl_FragCoord.xy); /* Noise to dither the samples */
+ float a, a2; prepare_glossy(roughness, a, a2);
+ ior = max(ior, 1e-5);
+
+ /* Precomputation */
+ float NV = max(1e-8, abs(dot(I, N)));
+ float G1_V = G1_Smith_GGX(NV, a2);
+
+ /* Early out */
+ if (abs(ior - 1.0) < 1e-4) {
+ result = sample_transparent();
+ return;
+ }
+
+ /* Integrating Envmap */
+ vec4 out_radiance = vec4(0.0);
+ for (float i = 0; i < unfbsdfsamples.x; i++) {
+ vec3 H = sample_ggx(i, a2, N, T, B); /* Microfacet normal */
+ float eta = 1.0/ior;
+ float fresnel = fresnel_dielectric(I, H, ior);
+
+ if (dot(H, -I) < 0.0) {
+ H = -H;
+ eta = ior;
+ }
+
+ vec3 L = refract(I, H, eta);
+ float NL = -dot(N, L);
+ if (NL > 0.0 && fresnel != 1.0) {
+ /* Step 1 : Sampling Environment */
+ float NH = dot(N, H); /* cosTheta */
+ float VH = dot(-I, H);
+ float LH = dot(L, H);
+ float tmp = ior * VH + LH;
+ float Ht2 = tmp * tmp;
+
+ float pdf = pdf_ggx_refract(Ht2, NH, NV, VH, LH, G1_V, a2, eta);
+
+ vec4 sample = sample_refract_pdf(L, roughness, pdf);
+
+ /* Step 2 : Integrating BRDF */
+ float brdf_pdf = bsdf_ggx_refract_pdf(a2, LH, NL, VH);
+
+ out_radiance += sample * brdf_pdf;
+ }
+ }
+
+ result = out_radiance.rgb * unfbsdfsamples.y;
+}
+
+void env_sampling_refract_beckmann(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ /* Setup */
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+ make_orthonormals(N, T, B); /* Generate tangent space */
+ setup_noise(gl_FragCoord.xy); /* Noise to dither the samples */
+ float a, a2; prepare_glossy(roughness, a, a2);
+ ior = max(ior, 1e-5);
+
+ /* Precomputation */
+ float NV = max(1e-8, abs(dot(I, N)));
+ float G1_V = G1_Smith_GGX(NV, a2);
+
+ /* Early out */
+ if (abs(ior - 1.0) < 1e-4) {
+ result = sample_transparent();
+ return;
+ }
+
+ /* Integrating Envmap */
+ vec4 out_radiance = vec4(0.0);
+ for (float i = 0; i < unfbsdfsamples.x; i++) {
+ vec3 H = sample_beckmann(i, a2, N, T, B); /* Microfacet normal */
+ float eta = 1.0/ior;
+ float fresnel = fresnel_dielectric(I, H, ior);
+
+ if (dot(H, -I) < 0.0) {
+ H = -H;
+ eta = ior;
+ }
+
+ vec3 L = refract(I, H, eta);
+ float NL = -dot(N, L);
+ if (NL > 0.0 && fresnel != 1.0) {
+ /* Step 1 : Sampling Environment */
+ float NH = dot(N, H); /* cosTheta */
+ float VH = dot(-I, H);
+ float LH = dot(L, H);
+ float tmp = ior * VH + LH;
+ float Ht2 = tmp * tmp;
+
+ float pdf = pdf_beckmann_refract(Ht2, NH, NV, VH, LH, G1_V, a2, eta);
+
+ vec4 sample = sample_refract_pdf(L, roughness, pdf);
+
+ /* Step 2 : Integrating BRDF */
+ float brdf_pdf = bsdf_beckmann_refract_pdf(a2, LH, NL, VH);
+
+ out_radiance += sample * brdf_pdf;
+ }
+ }
+
+ result = out_radiance.rgb * unfbsdfsamples.y;
+} \ No newline at end of file
diff --git a/source/blender/gpu/shaders/gpu_shader_material_bsdf_toon.glsl b/source/blender/gpu/shaders/gpu_shader_material_bsdf_toon.glsl
new file mode 100644
index 00000000000..7976429b3a4
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_material_bsdf_toon.glsl
@@ -0,0 +1,273 @@
+/* -------- Utils Functions --------- */
+
+vec3 sample_uniform_cone(float nsample, float angle, vec3 N, vec3 T, vec3 B)
+{
+ vec3 Xi = hammersley_3d(nsample);
+
+ float z = cos(angle * Xi.x);
+ float r = sqrt(1.0 - z*z);
+ float x = r * Xi.y;
+ float y = r * Xi.z;
+
+ Ht = vec3(x, y, z); /* Global variable */
+
+ return from_tangent_to_world(Ht, N, T, B);
+}
+
+float pdf_uniform_cone(float angle)
+{
+ return 0.5 * M_1_PI / (1.0 - cos(angle));
+}
+
+void prepare_toon(inout float tsize, inout float tsmooth, out float sample_angle)
+{
+ tsize = saturate(tsize) * M_PI_2;
+ tsmooth = saturate(tsmooth) * M_PI_2;
+ sample_angle = min(tsize + tsmooth, M_PI_2);
+}
+
+float bsdf_toon_get_intensity(float max_angle, float tsmooth, float angle)
+{
+ if(angle < max_angle)
+ return 1.0;
+ else if(angle < (max_angle + tsmooth) && tsmooth != 0.0)
+ return (1.0 - (angle - max_angle)/tsmooth);
+ else
+ return 0.0;
+}
+
+/* -------- BSDF --------- */
+
+float bsdf_toon(float cosangle, float pdf, float max_angle, float tsmooth)
+{
+ float angle = acos(min(0.9999999, cosangle));
+ float eval = bsdf_toon_get_intensity(max_angle, tsmooth, angle);
+ return pdf * eval;
+}
+
+float bsdf_toon_diffuse(vec3 N, vec3 L, float sample_angle, float max_angle, float tsmooth)
+{
+ float NL = max(0.0, dot(N, L));
+
+ if(NL > 0.0) {
+ float pdf = pdf_uniform_cone(sample_angle);
+ return bsdf_toon(NL, pdf, max_angle, tsmooth);
+ }
+
+ return 0.0;
+}
+
+float bsdf_toon_glossy(vec3 N, vec3 L, vec3 V, float sample_angle, float max_angle, float tsmooth)
+{
+ float NL = max(0.0, dot(N, L));
+ float NV = max(0.0, dot(N, V));
+
+ if(NV > 0.0 && NL > 0.0) {
+ vec3 R = -reflect(V, N);
+ float RL = max(0.0, dot(R, L));
+ float pdf = pdf_uniform_cone(sample_angle);
+ return bsdf_toon(RL, pdf, max_angle, tsmooth);
+ }
+
+ return 0.0;
+}
+
+
+/* -------- Preview Lights --------- */
+
+void node_bsdf_toon_diffuse_lights(vec4 color, float size, float tsmooth, vec3 N, vec3 V, vec4 ambient_light, out vec4 result)
+{
+ shade_view(V, V); V = -V;
+ N = normalize(N);
+ float sample_angle; prepare_toon(size, tsmooth, sample_angle);
+
+ /* ambient light */
+ vec3 accumulator = ambient_light.rgb;
+
+ /* directional lights */
+ for(int i = 0; i < NUM_LIGHTS; i++) {
+ vec3 L = gl_LightSource[i].position.xyz;
+ vec3 light_color = gl_LightSource[i].diffuse.rgb;
+
+ accumulator += light_color * bsdf_toon_diffuse(N, L, sample_angle, size, tsmooth) * M_PI; /* M_PI to make preview brighter */
+ }
+
+ result = vec4(accumulator*color.rgb, 1.0);
+}
+
+void node_bsdf_toon_glossy_lights(vec4 color, float size, float tsmooth, vec3 N, vec3 V, vec4 ambient_light, out vec4 result)
+{
+ shade_view(V, V); V = -V;
+ N = normalize(N);
+ float sample_angle; prepare_toon(size, tsmooth, sample_angle);
+
+ /* ambient light */
+ vec3 accumulator = ambient_light.rgb;
+
+ /* directional lights */
+ for(int i = 0; i < NUM_LIGHTS; i++) {
+ vec3 L = gl_LightSource[i].position.xyz;
+ vec3 light_color = gl_LightSource[i].specular.rgb;
+
+ accumulator += light_color * bsdf_toon_glossy(N, L, V, sample_angle, size, tsmooth) * M_PI; /* M_PI to make preview brighter */
+ }
+
+ result = vec4(accumulator*color.rgb, 1.0);
+}
+
+
+/* -------- Physical Lights --------- */
+
+/* TOON DIFFUSE */
+
+void bsdf_toon_diffuse_sphere_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float sample_angle; prepare_toon(toon_size, toon_smooth, sample_angle);
+ bsdf = bsdf_toon_diffuse(N, L, sample_angle, toon_size, toon_smooth);
+
+ /* Energy conservation + cycle matching */
+ bsdf *= 8.0 / (l_distance * l_distance);
+}
+
+void bsdf_toon_diffuse_area_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float sample_angle; prepare_toon(toon_size, toon_smooth, sample_angle);
+ bsdf = bsdf_toon_diffuse(N, L, sample_angle, toon_size, toon_smooth);
+
+ /* Energy conservation + cycle matching */
+ bsdf *= 8.0 / (l_distance * l_distance);
+}
+
+void bsdf_toon_diffuse_sun_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float sample_angle; prepare_toon(toon_size, toon_smooth, sample_angle);
+ bsdf = bsdf_toon_diffuse(N, L, sample_angle, toon_size, toon_smooth);
+}
+
+/* TOON GLOSSY */
+
+void bsdf_toon_glossy_sphere_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float sample_angle; prepare_toon(toon_size, toon_smooth, sample_angle);
+ bsdf = bsdf_toon_glossy(N, L, V, sample_angle, toon_size, toon_smooth);
+}
+
+void bsdf_toon_glossy_area_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float sample_angle; prepare_toon(toon_size, toon_smooth, sample_angle);
+ bsdf = bsdf_toon_glossy(N, L, V, sample_angle, toon_size, toon_smooth);
+
+ /* Energy conservation + cycle matching */
+ bsdf *= 8.0 / (l_distance * l_distance);
+}
+
+void bsdf_toon_glossy_sun_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float sample_angle; prepare_toon(toon_size, toon_smooth, sample_angle);
+ bsdf = bsdf_toon_glossy(N, L, V, sample_angle, toon_size, toon_smooth);
+}
+
+
+/* -------- Image Based Lighting --------- */
+
+void env_sampling_toon_diffuse(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ /* Setup */
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+ make_orthonormals(N, T, B); /* Generate tangent space */
+ float sample_angle; prepare_toon(toon_size, toon_smooth, sample_angle);
+ setup_noise(gl_FragCoord.xy); /* Noise to dither the samples */
+
+ /* Precomputation */
+ float NV = max(0.0, dot(I, N));
+
+ /* Integrating Envmap */
+ vec4 out_radiance = vec4(0.0);
+ for (float i = 0; i < unfbsdfsamples.x; i++) {
+ vec3 L = sample_uniform_cone(i, sample_angle, N, T, B);
+ float NL = dot(N, L);
+
+ if (NL > 0.0) {
+ /* Step 1 : Sampling Environment */
+ float pdf = pdf_uniform_cone(sample_angle);
+ vec4 irradiance = sample_probe_pdf(L, pdf);
+
+ /* Step 2 : Integrating BRDF*/
+ float brdf = bsdf_toon(NL, pdf, toon_size, toon_smooth);
+
+ out_radiance += irradiance * brdf / pdf;
+ }
+ }
+
+ result = out_radiance.rgb * unfbsdfsamples.y * ao_factor;
+}
+
+void env_sampling_toon_glossy(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ /* Setup */
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+ float sample_angle; prepare_toon(toon_size, toon_smooth, sample_angle);
+ setup_noise(gl_FragCoord.xy); /* Noise to dither the samples */
+
+ /* Precomputation */
+ float NV = max(1e-8, dot(I, N));
+ vec3 R = reflect(I, N);
+
+ /* We are sampling aroung R so generate basis with it */
+ make_orthonormals(R, T, B); /* Generate tangent space */
+
+ /* Integrating Envmap */
+ vec4 out_radiance = vec4(0.0);
+ for (float i = 0; i < unfbsdfsamples.x; i++) {
+ vec3 L = sample_uniform_cone(i, sample_angle, R, T, B);
+
+ float NL = dot(N, L);
+
+ if (NL > 0.0) {
+ float RL = max(0.0, dot(R, L));
+
+ /* Step 1 : Sampling Environment */
+ float pdf = pdf_uniform_cone(sample_angle);
+ vec4 irradiance = sample_reflect_pdf(L, 0.0, pdf);
+
+ /* Step 2 : Integrating BRDF*/
+ float brdf = bsdf_toon(RL, pdf, toon_size, toon_smooth);
+
+ out_radiance += irradiance * brdf / pdf;
+ }
+ }
+
+ result = out_radiance.rgb * unfbsdfsamples.y * specular_occlusion(NV, ao_factor, roughness);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_material_bsdf_translucent.glsl b/source/blender/gpu/shaders/gpu_shader_material_bsdf_translucent.glsl
new file mode 100644
index 00000000000..4cec442da9a
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_material_bsdf_translucent.glsl
@@ -0,0 +1,55 @@
+/* -------- Utils Functions --------- */
+
+/* -------- BSDF --------- */
+
+/* -------- Preview Lights --------- */
+
+void node_bsdf_translucent_lights(vec4 color, vec3 N, vec3 V, vec4 ambient_light, out vec4 result)
+{
+ node_bsdf_diffuse_lights(color, 0.0, -N, V, ambient_light, result);
+}
+
+
+/* -------- Physical Lights --------- */
+
+void bsdf_translucent_sphere_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ bsdf_diffuse_sphere_light(-N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, 0.0, ior, sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, bsdf);
+}
+
+void bsdf_translucent_area_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ bsdf_diffuse_area_light(-N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, 0.0, ior, sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, bsdf);
+}
+
+void bsdf_translucent_sun_light(
+ vec3 N, vec3 T, vec3 L, vec3 V,
+ vec3 l_coords, float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ bsdf_diffuse_sun_light(-N, T, L, V, l_coords, l_distance, l_areasizex, l_areasizey, l_areascale, l_mat, 0.0, ior, sigma, toon_size, toon_smooth, anisotropy, aniso_rotation, bsdf);
+}
+
+/* -------- Image Based Lighting --------- */
+
+void env_sampling_translucent(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ env_sampling_diffuse(
+ pbr, viewpos, invviewmat, viewmat,
+ -N, T, 0.0, ior, sigma,
+ toon_size, toon_smooth, anisotropy, aniso_rotation,
+ ao_factor, result);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_material_bsdf_transparent.glsl b/source/blender/gpu/shaders/gpu_shader_material_bsdf_transparent.glsl
new file mode 100644
index 00000000000..a4f1725bbf7
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_material_bsdf_transparent.glsl
@@ -0,0 +1,30 @@
+/* -------- Utils Functions --------- */
+
+vec3 sample_transparent()
+{
+#ifndef PLANAR_PROBE
+ vec4 sample = textureCube(unfprobe, I);
+#else
+ vec4 sample = texture2D(unfrefract, refpos.xy);
+#endif
+ srgb_to_linearrgb(sample, sample);
+ return sample.rgb;
+}
+
+/* -------- BSDF --------- */
+
+/* -------- Preview Lights --------- */
+
+/* -------- Physical Lights --------- */
+
+/* -------- Image Based Lighting --------- */
+
+void env_sampling_transparent(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+ result = sample_transparent();
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_material_bsdf_velvet.glsl b/source/blender/gpu/shaders/gpu_shader_material_bsdf_velvet.glsl
new file mode 100644
index 00000000000..553627edead
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_material_bsdf_velvet.glsl
@@ -0,0 +1,156 @@
+/* -------- Utils Functions --------- */
+
+void prepare_velvet(float sigma, out float m_1_sig2)
+{
+ sigma = max(sigma, 1e-2);
+ m_1_sig2 = 1 / (sigma * sigma);
+}
+
+/* -------- BSDF --------- */
+
+float bsdf_ashikhmin_velvet(float NL, float NV, float NH, float VH, float m_1_sig2)
+{
+ float NHdivVH = NH / VH;
+ NHdivVH = max(NHdivVH, 1e-5);
+
+ float fac1 = 2 * abs(NHdivVH * NV);
+ float fac2 = 2 * abs(NHdivVH * NL);
+
+ float sinNH2 = 1 - NH * NH;
+ float sinNH4 = sinNH2 * sinNH2;
+ float cotan2 = (NH * NH) / sinNH2;
+
+ float D = exp(-cotan2 * m_1_sig2) * m_1_sig2 * M_1_PI / sinNH4;
+ float G = min(1.0, min(fac1, fac2)); // TODO: derive G from D analytically
+
+ return 0.25 * (D * G) / NV;
+}
+
+float bsdf_ashikhmin_velvet(vec3 N, vec3 L, vec3 V, float m_1_sig2)
+{
+ vec3 H = normalize(L + V);
+
+ float NL = max(dot(N, L), 0.0);
+ float NV = max(dot(N, V), 1e-5);
+ float NH = dot(N, H);
+ float VH = max(abs(dot(V, H)), 1e-5);
+
+ if(abs(NH) < 1.0-1e-5) {
+ return bsdf_ashikhmin_velvet(NL, NV, NH, VH, m_1_sig2);
+ }
+
+ return 0.0;
+}
+
+/* -------- Preview Lights --------- */
+
+void node_bsdf_velvet_lights(vec4 color, float sigma, vec3 N, vec3 V, vec4 ambient_light, out vec4 result)
+{
+ shade_view(V, V); V = -V;
+ float m_1_sig2; prepare_velvet(sigma, m_1_sig2);
+
+ /* ambient light */
+ vec3 accumulator = ambient_light.rgb;
+
+ /* directional lights */
+ for(int i = 0; i < NUM_LIGHTS; i++) {
+ vec3 L = gl_LightSource[i].position.xyz;
+ vec3 light_color = gl_LightSource[i].specular.rgb;
+
+ accumulator += light_color * bsdf_ashikhmin_velvet(N, L, V, m_1_sig2);
+ }
+
+ result = vec4(accumulator * color.rgb, 1.0);
+}
+
+/* -------- Physical Lights --------- */
+
+/* VELVET */
+
+void bsdf_velvet_sphere_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float m_1_sig2; prepare_velvet(sigma, m_1_sig2);
+
+ bsdf = bsdf_ashikhmin_velvet(N, L, V, m_1_sig2);
+
+ /* Energy conservation + cycle matching */
+ bsdf *= 8.0 / (l_distance * l_distance);
+ /* bsdf *= sphere_energy(l_radius); Velvet is using only point lights for now */
+}
+
+void bsdf_velvet_area_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ if (max(l_areasizex, l_areasizey) < 1e-6) {
+ bsdf = 0.0;
+ return;
+ }
+
+ float m_1_sig2; prepare_velvet(sigma, m_1_sig2);
+
+ bsdf = bsdf_ashikhmin_velvet(N, L, V, m_1_sig2);
+
+ /* Energy conservation + cycle matching */
+ bsdf *= 8.0 / (l_distance * l_distance);
+
+ /* l_areasizex *= scale.x;
+ * l_areasizey *= scale.y;
+ * bsdf *= rectangle_energy(l_areasizex, l_areasizey); Velvet is using only point lights for now*/
+}
+
+void bsdf_velvet_sun_light(vec3 N, vec3 T, vec3 L, vec3 V, vec3 l_coords,
+ float l_distance, float l_areasizex, float l_areasizey, vec2 l_areascale, mat4 l_mat,
+ float roughness, float ior, float sigma, float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ out float bsdf)
+{
+ float m_1_sig2; prepare_velvet(sigma, m_1_sig2);
+
+ bsdf = bsdf_ashikhmin_velvet(N, L, V, m_1_sig2);
+}
+
+
+/* -------- Image Based Lighting --------- */
+
+void env_sampling_velvet(
+ float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat,
+ vec3 N, vec3 T, float roughness, float ior, float sigma,
+ float toon_size, float toon_smooth, float anisotropy, float aniso_rotation,
+ float ao_factor, out vec3 result)
+{
+ vector_prepass(viewpos, N, invviewmat, viewmat);
+ make_orthonormals(N, T, B); /* Generate tangent space */
+ setup_noise(gl_FragCoord.xy); /* Noise to dither the samples */
+
+ /* Precomputation */
+ float m_1_sig2; prepare_velvet(sigma, m_1_sig2);
+ float NV = max(1e-5, abs(dot(I, N)));
+
+ /* Integrating Envmap */
+ vec4 out_radiance = vec4(0.0);
+ for (float i = 0; i < unfbsdfsamples.x; i++) {
+ vec3 L = sample_hemisphere(i, N, T, B);
+ vec3 H = normalize(L - I);
+
+ float NL = dot(N, L);
+ float NH = dot(N, H); /* cosTheta */
+
+ if (NL > 0.0 && abs(NH) < 1.0-1e-5) {
+ /* Step 1 : Sampling Environment */
+ float pdf = pdf_hemisphere();
+ vec4 irradiance = sample_probe_pdf(L, pdf);
+
+ /* Step 2 : Integrating BRDF*/
+ float VH = max(abs(dot(I, H)), 1e-5);
+ float brdf = bsdf_ashikhmin_velvet(NL, NV, NH, VH, m_1_sig2);
+
+ out_radiance += irradiance * brdf / pdf;
+ }
+ }
+
+ result = out_radiance.rgb * unfbsdfsamples.y * ao_factor;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_material_new_shading.glsl b/source/blender/gpu/shaders/gpu_shader_material_new_shading.glsl
new file mode 100644
index 00000000000..c5b2e1f0b81
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_material_new_shading.glsl
@@ -0,0 +1,1207 @@
+/*********** NEW SHADER NODES ***************/
+
+/* Blending */
+void node_bsdf_opaque(vec4 color, vec4 ambient_light, vec4 direct_light, out vec4 result)
+{
+ result = vec4( (ambient_light.rgb + direct_light.rgb) * color.rgb, 1.0);
+}
+
+void node_bsdf_transparent(vec4 color, vec4 background, out vec4 result)
+{
+ result = vec4( background.rgb * color.rgb, color.a);
+}
+
+/* Others Bsdfs */
+
+void node_subsurface_scattering(vec4 color, float scale, vec3 radius, float sharpen, float texture_blur, vec3 N, out vec4 result)
+{
+ node_bsdf_diffuse_lights(color, 0.0, N, vec3(0.0), vec4(0.2), result);
+}
+
+void node_bsdf_hair(vec4 color, float offset, float roughnessu, float roughnessv, vec3 tangent, out vec4 result)
+{
+ result = color;
+}
+
+void node_ambient_occlusion(vec4 color, out vec4 result)
+{
+ result = color;
+}
+
+void node_holdout(out vec4 result)
+{
+ result = vec4(0.0);
+}
+
+/* emission */
+
+void node_emission(vec4 color, float strength, vec3 N, out vec4 result)
+{
+ result = color*strength;
+}
+
+/* blackbody */
+
+void node_blackbody(float T, out vec4 col)
+{
+ float u = ( 0.860117757 + 1.54118254e-4 * T + 1.28641212e-7 * T*T ) / ( 1.0 + 8.42420235e-4 * T + 7.08145163e-7 * T*T );
+ float v = ( 0.317398726 + 4.22806245e-5 * T + 4.20481691e-8 * T*T ) / ( 1.0 - 2.89741816e-5 * T + 1.61456053e-7 * T*T );
+
+ float x = 3*u / ( 2*u - 8*v + 4 );
+ float y = 2*v / ( 2*u - 8*v + 4 );
+ float z = 1 - x - y;
+
+ float Y = 1;
+ float X = Y/y * x;
+ float Z = Y/y * z;
+
+ mat3 XYZtoRGB = mat3(
+ 3.2404542, -0.9692660, 0.0556434,
+ -1.5371385, 1.8760108, -0.2040259,
+ -0.4985314, 0.0415560, 1.0572252
+ );
+
+ col = vec4(( XYZtoRGB * vec3( X, Y, Z ) ), 1.0);
+}
+
+vec3 xyz_to_rgb(float x, float y, float z)
+{
+ return vec3( 3.240479 * x + -1.537150 * y + -0.498535 * z,
+ -0.969256 * x + 1.875991 * y + 0.041556 * z,
+ 0.055648 * x + -0.204043 * y + 1.057311 * z);
+}
+
+// CIE colour matching functions xBar, yBar, and zBar for
+// wavelengths from 380 through 780 nanometers, every 5
+// nanometers. For a wavelength lambda in this range:
+// cie_colour_match[(lambda - 380) / 5][0] = xBar
+// cie_colour_match[(lambda - 380) / 5][1] = yBar
+// cie_colour_match[(lambda - 380) / 5][2] = zBar
+uniform vec3 node_wavelength_LUT[81] = vec3[81](
+ vec3(0.0014,0.0000,0.0065), vec3(0.0022,0.0001,0.0105), vec3(0.0042,0.0001,0.0201),
+ vec3(0.0076,0.0002,0.0362), vec3(0.0143,0.0004,0.0679), vec3(0.0232,0.0006,0.1102),
+ vec3(0.0435,0.0012,0.2074), vec3(0.0776,0.0022,0.3713), vec3(0.1344,0.0040,0.6456),
+ vec3(0.2148,0.0073,1.0391), vec3(0.2839,0.0116,1.3856), vec3(0.3285,0.0168,1.6230),
+ vec3(0.3483,0.0230,1.7471), vec3(0.3481,0.0298,1.7826), vec3(0.3362,0.0380,1.7721),
+ vec3(0.3187,0.0480,1.7441), vec3(0.2908,0.0600,1.6692), vec3(0.2511,0.0739,1.5281),
+ vec3(0.1954,0.0910,1.2876), vec3(0.1421,0.1126,1.0419), vec3(0.0956,0.1390,0.8130),
+ vec3(0.0580,0.1693,0.6162), vec3(0.0320,0.2080,0.4652), vec3(0.0147,0.2586,0.3533),
+ vec3(0.0049,0.3230,0.2720), vec3(0.0024,0.4073,0.2123), vec3(0.0093,0.5030,0.1582),
+ vec3(0.0291,0.6082,0.1117), vec3(0.0633,0.7100,0.0782), vec3(0.1096,0.7932,0.0573),
+ vec3(0.1655,0.8620,0.0422), vec3(0.2257,0.9149,0.0298), vec3(0.2904,0.9540,0.0203),
+ vec3(0.3597,0.9803,0.0134), vec3(0.4334,0.9950,0.0087), vec3(0.5121,1.0000,0.0057),
+ vec3(0.5945,0.9950,0.0039), vec3(0.6784,0.9786,0.0027), vec3(0.7621,0.9520,0.0021),
+ vec3(0.8425,0.9154,0.0018), vec3(0.9163,0.8700,0.0017), vec3(0.9786,0.8163,0.0014),
+ vec3(1.0263,0.7570,0.0011), vec3(1.0567,0.6949,0.0010), vec3(1.0622,0.6310,0.0008),
+ vec3(1.0456,0.5668,0.0006), vec3(1.0026,0.5030,0.0003), vec3(0.9384,0.4412,0.0002),
+ vec3(0.8544,0.3810,0.0002), vec3(0.7514,0.3210,0.0001), vec3(0.6424,0.2650,0.0000),
+ vec3(0.5419,0.2170,0.0000), vec3(0.4479,0.1750,0.0000), vec3(0.3608,0.1382,0.0000),
+ vec3(0.2835,0.1070,0.0000), vec3(0.2187,0.0816,0.0000), vec3(0.1649,0.0610,0.0000),
+ vec3(0.1212,0.0446,0.0000), vec3(0.0874,0.0320,0.0000), vec3(0.0636,0.0232,0.0000),
+ vec3(0.0468,0.0170,0.0000), vec3(0.0329,0.0119,0.0000), vec3(0.0227,0.0082,0.0000),
+ vec3(0.0158,0.0057,0.0000), vec3(0.0114,0.0041,0.0000), vec3(0.0081,0.0029,0.0000),
+ vec3(0.0058,0.0021,0.0000), vec3(0.0041,0.0015,0.0000), vec3(0.0029,0.0010,0.0000),
+ vec3(0.0020,0.0007,0.0000), vec3(0.0014,0.0005,0.0000), vec3(0.0010,0.0004,0.0000),
+ vec3(0.0007,0.0002,0.0000), vec3(0.0005,0.0002,0.0000), vec3(0.0003,0.0001,0.0000),
+ vec3(0.0002,0.0001,0.0000), vec3(0.0002,0.0001,0.0000), vec3(0.0001,0.0000,0.0000),
+ vec3(0.0001,0.0000,0.0000), vec3(0.0001,0.0000,0.0000), vec3(0.0000,0.0000,0.0000)
+);
+
+void node_wavelength(float w, out vec4 col)
+{
+ float ii = (w-380.0) * (1.0/5.0); // scaled 0..80
+ int i = int(ii);
+ vec3 color;
+
+ if(i < 0 || i >= 80) {
+ color = vec3(0.0, 0.0, 0.0);
+ }
+ else {
+ ii -= i;
+ color = mix(node_wavelength_LUT[i], node_wavelength_LUT[i+1], ii);
+ }
+
+ color = xyz_to_rgb(color.x, color.y, color.z);
+ color *= 1.0/2.52; // Empirical scale from lg to make all comps <= 1
+
+ /* Clamp to zero if values are smaller */
+ col = vec4(max(color, vec3(0.0, 0.0, 0.0)), 1.0);
+
+ // srgb_to_linearrgb(col, col);
+}
+
+/* background */
+
+void background_transform_to_world(vec3 viewvec, out vec3 worldvec)
+{
+ vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
+ vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
+
+ vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
+ worldvec = (gl_ModelViewMatrixInverse * co).xyz;
+}
+
+void node_background(vec4 color, float strength, vec3 N, out vec4 result)
+{
+ result = color * strength;
+}
+
+/* closures */
+
+void node_mix_shader(float fac, vec4 shader1, vec4 shader2, out vec4 shader)
+{
+ shader = mix(shader1, shader2, saturate(fac));
+}
+
+void node_add_shader(vec4 shader1, vec4 shader2, out vec4 shader)
+{
+ shader = shader1 + shader2;
+}
+
+/* fresnel */
+
+void node_fresnel(float ior, vec3 N, vec3 I, out float result)
+{
+ /* handle perspective/orthographic */
+ vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
+
+ float eta = max(ior, 0.00001);
+ result = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? eta : 1.0/eta);
+}
+
+/* layer_weight */
+
+void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float facing)
+{
+ /* fresnel */
+ float eta = max(1.0 - blend, 0.00001);
+ vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
+
+ fresnel = fresnel_dielectric(I_view, N, (gl_FrontFacing)? 1.0/eta : eta );
+
+ /* facing */
+ facing = abs(dot(I_view, N));
+ if (blend != 0.5) {
+ blend = clamp(blend, 0.0, 0.99999);
+ blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend);
+ facing = pow(facing, blend);
+ }
+ facing = 1.0 - facing;
+}
+
+/* gamma */
+
+void node_gamma(vec4 col, float gamma, out vec4 outcol)
+{
+ outcol = col;
+
+ if (col.r > 0.0)
+ outcol.r = compatible_pow(col.r, gamma);
+ if (col.g > 0.0)
+ outcol.g = compatible_pow(col.g, gamma);
+ if (col.b > 0.0)
+ outcol.b = compatible_pow(col.b, gamma);
+}
+
+/* geometry */
+
+void node_attribute(vec3 attr, out vec4 outcol, out vec3 outvec, out float outf)
+{
+ outcol = vec4(attr, 1.0);
+ outvec = attr;
+ outf = (attr.x + attr.y + attr.z) / 3.0;
+}
+
+void node_uvmap(vec3 attr_uv, out vec3 outvec)
+{
+ outvec = attr_uv;
+}
+
+void tangent_orco_x(vec3 orco_in, out vec3 orco_out)
+{
+ orco_out = vec3(0.0, orco_in.z * -0.5, orco_in.y * 0.5);
+}
+
+void tangent_orco_y(vec3 orco_in, out vec3 orco_out)
+{
+ orco_out = vec3(orco_in.z * -0.5, 0.0, orco_in.x * 0.5);
+}
+
+void tangent_orco_z(vec3 orco_in, out vec3 orco_out)
+{
+ orco_out = vec3(orco_in.y * -0.5, orco_in.x * 0.5, 0.0);
+}
+
+void node_tangent(vec3 N, vec3 orco, mat4 objmat, mat4 invviewmat, out vec3 T)
+{
+ N = (invviewmat*vec4(N, 0.0)).xyz;
+ T = (objmat*vec4(orco, 0.0)).xyz;
+ T = cross(N, normalize(cross(T, N)));
+}
+
+void node_tangentmap(vec4 attr_tangent, mat4 toworld, out vec3 tangent)
+{
+ tangent = (toworld * vec4(attr_tangent.xyz, 0.0)).xyz;
+}
+
+void default_tangent(vec3 N, vec3 orco, mat4 objmat, mat4 viewmat, mat4 invviewmat, out vec3 T)
+{
+ orco = vec3(orco.y * -0.5, orco.x * 0.5, 0.0);
+ node_tangent(N, orco, objmat, invviewmat, T);
+ T = (viewmat * vec4(T, 0.0)).xyz;
+}
+
+void node_geometry(vec3 I, vec3 N, vec3 attr_orco, mat4 toworld, mat4 fromobj,
+ out vec3 position, out vec3 normal, out vec3 tangent,
+ out vec3 true_normal, out vec3 incoming, out vec3 parametric,
+ out float backfacing, out float pointiness)
+{
+ position = (toworld * vec4(I, 1.0)).xyz;
+ normal = (toworld * vec4(N, 0.0)).xyz;
+ attr_orco = vec3(attr_orco.y * -0.5, attr_orco.x * 0.5, 0.0);
+ node_tangent(N, attr_orco, fromobj, toworld, tangent);
+ true_normal = normal;
+
+ /* handle perspective/orthographic */
+ vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
+ incoming = -(toworld * vec4(I_view, 0.0)).xyz;
+
+ parametric = vec3(0.0);
+ backfacing = (gl_FrontFacing) ? 0.0 : 1.0;
+ pointiness = 0.5;
+}
+
+void node_geometry_lamp(vec3 N, vec4 P, vec3 I, mat4 toworld,
+ out vec3 position, out vec3 normal, out vec3 tangent,
+ out vec3 true_normal, out vec3 incoming, out vec3 parametric,
+ out float backfacing, out float pointiness)
+{
+ position = (toworld*P).xyz;
+ normal = normalize(toworld*vec4(N, 0.0)).xyz;
+ tangent = vec3(0.0);
+ true_normal = normal;
+ incoming = normalize(toworld*vec4(I, 0.0)).xyz;
+
+ parametric = vec3(0.0);
+ backfacing = 0.0;
+ pointiness = 0.0;
+}
+
+void node_tex_coord(
+ vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
+ vec3 attr_orco, vec3 attr_uv,
+ out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
+ out vec3 camera, out vec3 window, out vec3 reflection)
+{
+ generated = attr_orco * 0.5 + vec3(0.5);
+ normal = normalize((obinvmat * (viewinvmat * vec4(N, 0.0))).xyz);
+ uv = attr_uv;
+ object = (obinvmat * (viewinvmat * vec4(I, 1.0))).xyz;
+ camera = vec3(I.xy, -I.z);
+ vec4 projvec = gl_ProjectionMatrix * vec4(I, 1.0);
+ window = vec3(mtex_2d_mapping(projvec.xyz / projvec.w).xy * camerafac.xy + camerafac.zw, 0.0);
+
+ vec3 shade_I;
+ shade_view(I, shade_I);
+ vec3 view_reflection = reflect(shade_I, normalize(N));
+ reflection = (viewinvmat * vec4(view_reflection, 0.0)).xyz;
+}
+
+void node_tex_coord_background(
+ vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
+ vec3 attr_orco, vec3 attr_uv,
+ out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
+ out vec3 camera, out vec3 window, out vec3 reflection)
+{
+ vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
+ vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
+
+ vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
+
+ co = normalize(co);
+ vec3 coords = (gl_ModelViewMatrixInverse * co).xyz;
+
+ generated = coords;
+ normal = -coords;
+ uv = vec3(attr_uv.xy, 0.0);
+ object = coords;
+
+ camera = vec3(co.xy, -co.z);
+ window = (gl_ProjectionMatrix[3][3] == 0.0) ?
+ vec3(mtex_2d_mapping(I).xy * camerafac.xy + camerafac.zw, 0.0) :
+ vec3(vec2(0.5) * camerafac.xy + camerafac.zw, 0.0);
+
+ reflection = -coords;
+}
+
+/* textures */
+
+float calc_gradient(vec3 p, int gradient_type)
+{
+ float x, y, z;
+ x = p.x;
+ y = p.y;
+ z = p.z;
+ if (gradient_type == 0) { /* linear */
+ return x;
+ }
+ else if (gradient_type == 1) { /* quadratic */
+ float r = max(x, 0.0);
+ return r * r;
+ }
+ else if (gradient_type == 2) { /* easing */
+ float r = min(max(x, 0.0), 1.0);
+ float t = r * r;
+ return (3.0 * t - 2.0 * t * r);
+ }
+ else if (gradient_type == 3) { /* diagonal */
+ return (x + y) * 0.5;
+ }
+ else if (gradient_type == 4) { /* radial */
+ return atan(y, x) / (M_PI * 2) + 0.5;
+ }
+ else {
+ float r = max(1.0 - sqrt(x * x + y * y + z * z), 0.0);
+ if (gradient_type == 5) { /* quadratic sphere */
+ return r * r;
+ }
+ else if (gradient_type == 6) { /* sphere */
+ return r;
+ }
+ }
+ return 0.0;
+}
+
+void node_tex_gradient(vec3 co, float gradient_type, out vec4 color, out float fac)
+{
+ float f = calc_gradient(co, int(gradient_type));
+ f = clamp(f, 0.0, 1.0);
+
+ color = vec4(f, f, f, 1.0);
+ fac = f;
+}
+
+void node_tex_checker(vec3 co, vec4 color1, vec4 color2, float scale, out vec4 color, out float fac)
+{
+ vec3 p = co * scale;
+
+ /* Prevent precision issues on unit coordinates. */
+ p.x = (p.x + 0.000001) * 0.999999;
+ p.y = (p.y + 0.000001) * 0.999999;
+ p.z = (p.z + 0.000001) * 0.999999;
+
+ int xi = int(abs(floor(p.x)));
+ int yi = int(abs(floor(p.y)));
+ int zi = int(abs(floor(p.z)));
+
+ bool check = ((mod(xi, 2) == mod(yi, 2)) == bool(mod(zi, 2)));
+
+ color = check ? color1 : color2;
+ fac = check ? 1.0 : 0.0;
+}
+
+#ifdef BIT_OPERATIONS
+vec2 calc_brick_texture(vec3 p, float mortar_size, float bias,
+ float brick_width, float row_height,
+ float offset_amount, int offset_frequency,
+ float squash_amount, int squash_frequency)
+{
+ int bricknum, rownum;
+ float offset = 0.0;
+ float x, y;
+
+ rownum = floor_to_int(p.y / row_height);
+
+ if (offset_frequency != 0 && squash_frequency != 0) {
+ brick_width *= (rownum % squash_frequency != 0) ? 1.0 : squash_amount; /* squash */
+ offset = (rownum % offset_frequency != 0) ? 0.0 : (brick_width * offset_amount); /* offset */
+ }
+
+ bricknum = floor_to_int((p.x + offset) / brick_width);
+
+ x = (p.x + offset) - brick_width * bricknum;
+ y = p.y - row_height * rownum;
+
+ return vec2(clamp((integer_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias), 0.0, 1.0),
+ (x < mortar_size || y < mortar_size ||
+ x > (brick_width - mortar_size) ||
+ y > (row_height - mortar_size)) ? 1.0 : 0.0);
+}
+#endif
+
+void node_tex_brick(vec3 co,
+ vec4 color1, vec4 color2,
+ vec4 mortar, float scale,
+ float mortar_size, float bias,
+ float brick_width, float row_height,
+ float offset_amount, float offset_frequency,
+ float squash_amount, float squash_frequency,
+ out vec4 color, out float fac)
+{
+#ifdef BIT_OPERATIONS
+ vec2 f2 = calc_brick_texture(co * scale,
+ mortar_size, bias,
+ brick_width, row_height,
+ offset_amount, int(offset_frequency),
+ squash_amount, int(squash_frequency));
+ float tint = f2.x;
+ float f = f2.y;
+ if (f != 1.0) {
+ float facm = 1.0 - tint;
+ color1 = facm * color1 + tint * color2;
+ }
+ color = (f == 1.0) ? mortar : color1;
+ fac = f;
+#else
+ color = vec4(1.0);
+ fac = 1.0;
+#endif
+}
+
+void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac)
+{
+ color = vec4(1.0);
+ fac = 1.0;
+}
+
+void node_tex_environment_equirectangular(vec3 co, sampler2D ima, out vec4 color)
+{
+ vec3 nco = normalize(co);
+ float u = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5;
+ float v = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5;
+
+ color = texture2D(ima, vec2(u, v));
+}
+
+void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color)
+{
+ vec3 nco = normalize(co);
+
+ nco.y -= 1.0;
+
+ float div = 2.0 * sqrt(max(-0.5 * nco.y, 0.0));
+ if(div > 0.0)
+ nco /= div;
+
+ float u = 0.5 * (nco.x + 1.0);
+ float v = 0.5 * (nco.z + 1.0);
+
+ color = texture2D(ima, vec2(u, v));
+}
+
+void node_tex_environment_empty(vec3 co, out vec4 color)
+{
+ color = vec4(1.0, 0.0, 1.0, 1.0);
+}
+
+void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha)
+{
+ color = texture2D(ima, co.xy);
+ alpha = color.a;
+}
+
+void node_tex_image_closest(vec3 co, sampler2D ima, vec2 res, out vec4 color, out float alpha)
+{
+#if __VERSION__ < 130
+ color = texture2DLod(ima, (floor(co.xy * res) + 0.5) / res, 0.0);
+#else
+ color = texelFetch(ima, ivec2(fract(co.xy) * res), 0);
+#endif
+ alpha = color.a;
+}
+
+void node_tex_image_box(vec3 texco,
+ vec3 nob,
+ sampler2D ima,
+ float blend,
+ out vec4 color,
+ out float alpha)
+{
+ /* project from direction vector to barycentric coordinates in triangles */
+ nob = vec3(abs(nob.x), abs(nob.y), abs(nob.z));
+ nob /= (nob.x + nob.y + nob.z);
+
+ /* basic idea is to think of this as a triangle, each corner representing
+ * one of the 3 faces of the cube. in the corners we have single textures,
+ * in between we blend between two textures, and in the middle we a blend
+ * between three textures.
+ *
+ * the Nxyz values are the barycentric coordinates in an equilateral
+ * triangle, which in case of blending, in the middle has a smaller
+ * equilateral triangle where 3 textures blend. this divides things into
+ * 7 zones, with an if () test for each zone */
+
+ vec3 weight = vec3(0.0, 0.0, 0.0);
+ float limit = 0.5 * (1.0 + blend);
+
+ /* first test for corners with single texture */
+ if (nob.x > limit * (nob.x + nob.y) && nob.x > limit * (nob.x + nob.z)) {
+ weight.x = 1.0;
+ }
+ else if (nob.y > limit * (nob.x + nob.y) && nob.y > limit * (nob.y + nob.z)) {
+ weight.y = 1.0;
+ }
+ else if (nob.z > limit * (nob.x + nob.z) && nob.z > limit * (nob.y + nob.z)) {
+ weight.z = 1.0;
+ }
+ else if (blend > 0.0) {
+ /* in case of blending, test for mixes between two textures */
+ if (nob.z < (1.0 - limit) * (nob.y + nob.x)) {
+ weight.x = nob.x / (nob.x + nob.y);
+ weight.x = clamp((weight.x - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
+ weight.y = 1.0 - weight.x;
+ }
+ else if (nob.x < (1.0 - limit) * (nob.y + nob.z)) {
+ weight.y = nob.y / (nob.y + nob.z);
+ weight.y = clamp((weight.y - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
+ weight.z = 1.0 - weight.y;
+ }
+ else if (nob.y < (1.0 - limit) * (nob.x + nob.z)) {
+ weight.x = nob.x / (nob.x + nob.z);
+ weight.x = clamp((weight.x - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
+ weight.z = 1.0 - weight.x;
+ }
+ else {
+ /* last case, we have a mix between three */
+ weight.x = ((2.0 - limit) * nob.x + (limit - 1.0)) / (2.0 * limit - 1.0);
+ weight.y = ((2.0 - limit) * nob.y + (limit - 1.0)) / (2.0 * limit - 1.0);
+ weight.z = ((2.0 - limit) * nob.z + (limit - 1.0)) / (2.0 * limit - 1.0);
+ }
+ }
+ else {
+ /* Desperate mode, no valid choice anyway, fallback to one side.*/
+ weight.x = 1.0;
+ }
+
+ color = vec4(0);
+ if (weight.x > 0.0) {
+ color += weight.x * texture2D(ima, texco.yz);
+ }
+ if (weight.y > 0.0) {
+ color += weight.y * texture2D(ima, texco.xz);
+ }
+ if (weight.z > 0.0) {
+ color += weight.z * texture2D(ima, texco.yx);
+ }
+
+ alpha = color.a;
+}
+
+void node_tex_image_empty(vec3 co, out vec4 color, out float alpha)
+{
+ color = vec4(0.0);
+ alpha = 0.0;
+}
+
+void node_tex_magic(vec3 co, float scale, float distortion, float depth, out vec4 color, out float fac)
+{
+ vec3 p = co * scale;
+ float x = sin((p.x + p.y + p.z) * 5.0);
+ float y = cos((-p.x + p.y - p.z) * 5.0);
+ float z = -cos((-p.x - p.y + p.z) * 5.0);
+
+ if (depth > 0) {
+ x *= distortion;
+ y *= distortion;
+ z *= distortion;
+ y = -cos(x - y + z);
+ y *= distortion;
+ if (depth > 1) {
+ x = cos(x - y - z);
+ x *= distortion;
+ if (depth > 2) {
+ z = sin(-x - y - z);
+ z *= distortion;
+ if (depth > 3) {
+ x = -cos(-x + y - z);
+ x *= distortion;
+ if (depth > 4) {
+ y = -sin(-x + y + z);
+ y *= distortion;
+ if (depth > 5) {
+ y = -cos(-x + y + z);
+ y *= distortion;
+ if (depth > 6) {
+ x = cos(x + y + z);
+ x *= distortion;
+ if (depth > 7) {
+ z = sin(x + y - z);
+ z *= distortion;
+ if (depth > 8) {
+ x = -cos(-x - y + z);
+ x *= distortion;
+ if (depth > 9) {
+ y = -sin(x - y + z);
+ y *= distortion;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (distortion != 0.0) {
+ distortion *= 2.0;
+ x /= distortion;
+ y /= distortion;
+ z /= distortion;
+ }
+
+ color = vec4(0.5 - x, 0.5 - y, 0.5 - z, 1.0);
+ fac = (color.x + color.y + color.z) / 3.0;
+}
+
+#ifdef BIT_OPERATIONS
+float noise_fade(float t)
+{
+ return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
+}
+
+float noise_scale3(float result)
+{
+ return 0.9820 * result;
+}
+
+float noise_nerp(float t, float a, float b)
+{
+ return (1.0 - t) * a + t * b;
+}
+
+float noise_grad(uint hash, float x, float y, float z)
+{
+ uint h = hash & 15u;
+ float u = h < 8u ? x : y;
+ float vt = ((h == 12u) || (h == 14u)) ? x : z;
+ float v = h < 4u ? y : vt;
+ return (((h & 1u) != 0u) ? -u : u) + (((h & 2u) != 0u) ? -v : v);
+}
+
+float noise_perlin(float x, float y, float z)
+{
+ int X; float fx = floorfrac(x, X);
+ int Y; float fy = floorfrac(y, Y);
+ int Z; float fz = floorfrac(z, Z);
+
+ float u = noise_fade(fx);
+ float v = noise_fade(fy);
+ float w = noise_fade(fz);
+
+ float result;
+
+ result = noise_nerp(w, noise_nerp(v, noise_nerp(u, noise_grad(hash(X, Y, Z), fx, fy, fz),
+ noise_grad(hash(X + 1, Y, Z), fx - 1.0, fy, fz)),
+ noise_nerp(u, noise_grad(hash(X, Y + 1, Z), fx, fy - 1.0, fz),
+ noise_grad(hash(X + 1, Y + 1, Z), fx - 1.0, fy - 1.0, fz))),
+ noise_nerp(v, noise_nerp(u, noise_grad(hash(X, Y, Z + 1), fx, fy, fz - 1.0),
+ noise_grad(hash(X + 1, Y, Z + 1), fx - 1.0, fy, fz - 1.0)),
+ noise_nerp(u, noise_grad(hash(X, Y + 1, Z + 1), fx, fy - 1.0, fz - 1.0),
+ noise_grad(hash(X + 1, Y + 1, Z + 1), fx - 1.0, fy - 1.0, fz - 1.0))));
+ return noise_scale3(result);
+}
+
+float noise(vec3 p)
+{
+ return 0.5 * noise_perlin(p.x, p.y, p.z) + 0.5;
+}
+
+float snoise(vec3 p)
+{
+ return noise_perlin(p.x, p.y, p.z);
+}
+
+float noise_turbulence(vec3 p, float octaves, int hard)
+{
+ float fscale = 1.0;
+ float amp = 1.0;
+ float sum = 0.0;
+ int i, n;
+ octaves = clamp(octaves, 0.0, 16.0);
+ n = int(octaves);
+ for (i = 0; i <= n; i++) {
+ float t = noise(fscale * p);
+ if (hard != 0) {
+ t = abs(2.0 * t - 1.0);
+ }
+ sum += t * amp;
+ amp *= 0.5;
+ fscale *= 2.0;
+ }
+ float rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ float t = noise(fscale * p);
+ if (hard != 0) {
+ t = abs(2.0 * t - 1.0);
+ }
+ float sum2 = sum + t * amp;
+ sum *= (float(1 << n) / float((1 << (n + 1)) - 1));
+ sum2 *= (float(1 << (n + 1)) / float((1 << (n + 2)) - 1));
+ return (1.0 - rmd) * sum + rmd * sum2;
+ }
+ else {
+ sum *= (float(1 << n) / float((1 << (n + 1)) - 1));
+ return sum;
+ }
+}
+#endif // BIT_OPERATIONS
+
+void node_tex_noise(vec3 co, float scale, float detail, float distortion, out vec4 color, out float fac)
+{
+#ifdef BIT_OPERATIONS
+ vec3 p = co * scale;
+ int hard = 0;
+ if (distortion != 0.0) {
+ vec3 r, offset = vec3(13.5, 13.5, 13.5);
+ r.x = noise(p + offset) * distortion;
+ r.y = noise(p) * distortion;
+ r.z = noise(p - offset) * distortion;
+ p += r;
+ }
+
+ fac = noise_turbulence(p, detail, hard);
+ color = vec4(fac,
+ noise_turbulence(vec3(p.y, p.x, p.z), detail, hard),
+ noise_turbulence(vec3(p.y, p.z, p.x), detail, hard),
+ 1);
+#else // BIT_OPERATIONS
+ color = vec4(1.0);
+ fac = 1.0;
+#endif // BIT_OPERATIONS
+}
+
+
+#ifdef BIT_OPERATIONS
+
+/* Musgrave fBm
+ *
+ * H: fractal increment parameter
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ *
+ * from "Texturing and Modelling: A procedural approach"
+ */
+
+float noise_musgrave_fBm(vec3 p, float H, float lacunarity, float octaves)
+{
+ float rmd;
+ float value = 0.0;
+ float pwr = 1.0;
+ float pwHL = pow(lacunarity, -H);
+ int i;
+
+ for (i = 0; i < int(octaves); i++) {
+ value += snoise(p) * pwr;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ rmd = octaves - floor(octaves);
+ if (rmd != 0.0)
+ value += rmd * snoise(p) * pwr;
+
+ return value;
+}
+
+/* Musgrave Multifractal
+ *
+ * H: highest fractal dimension
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ */
+
+float noise_musgrave_multi_fractal(vec3 p, float H, float lacunarity, float octaves)
+{
+ float rmd;
+ float value = 1.0;
+ float pwr = 1.0;
+ float pwHL = pow(lacunarity, -H);
+ int i;
+
+ for (i = 0; i < int(octaves); i++) {
+ value *= (pwr * snoise(p) + 1.0);
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ rmd = octaves - floor(octaves);
+ if (rmd != 0.0)
+ value *= (rmd * pwr * snoise(p) + 1.0); /* correct? */
+
+ return value;
+}
+
+/* Musgrave Heterogeneous Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float noise_musgrave_hetero_terrain(vec3 p, float H, float lacunarity, float octaves, float offset)
+{
+ float value, increment, rmd;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+ int i;
+
+ /* first unscaled octave of function; later octaves are scaled */
+ value = offset + snoise(p);
+ p *= lacunarity;
+
+ for (i = 1; i < int(octaves); i++) {
+ increment = (snoise(p) + offset) * pwr * value;
+ value += increment;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ rmd = octaves - floor(octaves);
+ if (rmd != 0.0) {
+ increment = (snoise(p) + offset) * pwr * value;
+ value += rmd * increment;
+ }
+
+ return value;
+}
+
+/* Hybrid Additive/Multiplicative Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float noise_musgrave_hybrid_multi_fractal(vec3 p, float H, float lacunarity, float octaves, float offset, float gain)
+{
+ float result, signal, weight, rmd;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+ int i;
+
+ result = snoise(p) + offset;
+ weight = gain * result;
+ p *= lacunarity;
+
+ for (i = 1; (weight > 0.001f) && (i < int(octaves)); i++) {
+ if (weight > 1.0)
+ weight = 1.0;
+
+ signal = (snoise(p) + offset) * pwr;
+ pwr *= pwHL;
+ result += weight * signal;
+ weight *= gain * signal;
+ p *= lacunarity;
+ }
+
+ rmd = octaves - floor(octaves);
+ if (rmd != 0.0)
+ result += rmd * ((snoise(p) + offset) * pwr);
+
+ return result;
+}
+
+/* Ridged Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float noise_musgrave_ridged_multi_fractal(vec3 p, float H, float lacunarity, float octaves, float offset, float gain)
+{
+ float result, signal, weight;
+ float pwHL = pow(lacunarity, -H);
+ float pwr = pwHL;
+ int i;
+
+ signal = offset - abs(snoise(p));
+ signal *= signal;
+ result = signal;
+ weight = 1.0;
+
+ for (i = 1; i < int(octaves); i++) {
+ p *= lacunarity;
+ weight = clamp(signal * gain, 0.0, 1.0);
+ signal = offset - abs(snoise(p));
+ signal *= signal;
+ signal *= weight;
+ result += signal * pwr;
+ pwr *= pwHL;
+ }
+
+ return result;
+}
+
+float svm_musgrave(int type,
+ float dimension,
+ float lacunarity,
+ float octaves,
+ float offset,
+ float intensity,
+ float gain,
+ vec3 p)
+{
+ if (type == 0 /*NODE_MUSGRAVE_MULTIFRACTAL*/)
+ return intensity * noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves);
+ else if (type == 1 /*NODE_MUSGRAVE_FBM*/)
+ return intensity * noise_musgrave_fBm(p, dimension, lacunarity, octaves);
+ else if (type == 2 /*NODE_MUSGRAVE_HYBRID_MULTIFRACTAL*/)
+ return intensity * noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
+ else if (type == 3 /*NODE_MUSGRAVE_RIDGED_MULTIFRACTAL*/)
+ return intensity * noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
+ else if (type == 4 /*NODE_MUSGRAVE_HETERO_TERRAIN*/)
+ return intensity * noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, offset);
+ return 0.0;
+}
+#endif // #ifdef BIT_OPERATIONS
+
+void node_tex_musgrave(vec3 co,
+ float scale,
+ float detail,
+ float dimension,
+ float lacunarity,
+ float offset,
+ float gain,
+ float type,
+ out vec4 color,
+ out float fac)
+{
+#ifdef BIT_OPERATIONS
+ fac = svm_musgrave(int(type),
+ dimension,
+ lacunarity,
+ detail,
+ offset,
+ 1.0,
+ gain,
+ co * scale);
+#else
+ fac = 1.0;
+#endif
+
+ color = vec4(fac, fac, fac, 1.0);
+}
+
+void node_tex_sky(vec3 co, out vec4 color)
+{
+ color = vec4(1.0);
+}
+
+void node_tex_voronoi(vec3 co, float scale, float coloring, out vec4 color, out float fac)
+{
+#ifdef BIT_OPERATIONS
+ vec3 p = co * scale;
+ int xx, yy, zz, xi, yi, zi;
+ float da[4];
+ vec3 pa[4];
+
+ xi = floor_to_int(p[0]);
+ yi = floor_to_int(p[1]);
+ zi = floor_to_int(p[2]);
+
+ da[0] = 1e+10;
+ da[1] = 1e+10;
+ da[2] = 1e+10;
+ da[3] = 1e+10;
+
+ for (xx = xi - 1; xx <= xi + 1; xx++) {
+ for (yy = yi - 1; yy <= yi + 1; yy++) {
+ for (zz = zi - 1; zz <= zi + 1; zz++) {
+ vec3 ip = vec3(xx, yy, zz);
+ vec3 vp = cellnoise_color(ip);
+ vec3 pd = p - (vp + ip);
+ float d = dot(pd, pd);
+ vp += vec3(xx, yy, zz);
+ if (d < da[0]) {
+ da[3] = da[2];
+ da[2] = da[1];
+ da[1] = da[0];
+ da[0] = d;
+ pa[3] = pa[2];
+ pa[2] = pa[1];
+ pa[1] = pa[0];
+ pa[0] = vp;
+ }
+ else if (d < da[1]) {
+ da[3] = da[2];
+ da[2] = da[1];
+ da[1] = d;
+
+ pa[3] = pa[2];
+ pa[2] = pa[1];
+ pa[1] = vp;
+ }
+ else if (d < da[2]) {
+ da[3] = da[2];
+ da[2] = d;
+
+ pa[3] = pa[2];
+ pa[2] = vp;
+ }
+ else if (d < da[3]) {
+ da[3] = d;
+ pa[3] = vp;
+ }
+ }
+ }
+ }
+
+ if (coloring == 0.0) {
+ fac = abs(da[0]);
+ color = vec4(fac, fac, fac, 1);
+ }
+ else {
+ color = vec4(cellnoise_color(pa[0]), 1);
+ fac = (color.x + color.y + color.z) * (1.0 / 3.0);
+ }
+#else // BIT_OPERATIONS
+ color = vec4(1.0);
+ fac = 1.0;
+#endif // BIT_OPERATIONS
+}
+
+#ifdef BIT_OPERATIONS
+float calc_wave(vec3 p, float distortion, float detail, float detail_scale, int wave_type, int wave_profile)
+{
+ float n;
+
+ if (wave_type == 0) /* type bands */
+ n = (p.x + p.y + p.z) * 10.0;
+ else /* type rings */
+ n = length(p) * 20.0;
+
+ if (distortion != 0.0)
+ n += distortion * noise_turbulence(p * detail_scale, detail, 0);
+
+ if (wave_profile == 0) { /* profile sin */
+ return 0.5 + 0.5 * sin(n);
+ }
+ else { /* profile saw */
+ n /= 2.0 * M_PI;
+ n -= int(n);
+ return (n < 0.0) ? n + 1.0 : n;
+ }
+}
+#endif // BIT_OPERATIONS
+
+void node_tex_wave(
+ vec3 co, float scale, float distortion, float detail, float detail_scale, float wave_type, float wave_profile,
+ out vec4 color, out float fac)
+{
+#ifdef BIT_OPERATIONS
+ float f;
+ f = calc_wave(co * scale, distortion, detail, detail_scale, int(wave_type), int(wave_profile));
+
+ color = vec4(f, f, f, 1.0);
+ fac = f;
+#else // BIT_OPERATIONS
+ color = vec4(1.0);
+ fac = 1;
+#endif // BIT_OPERATIONS
+}
+
+/* light path */
+
+void node_light_path(
+ out float is_camera_ray,
+ out float is_shadow_ray,
+ out float is_diffuse_ray,
+ out float is_glossy_ray,
+ out float is_singular_ray,
+ out float is_reflection_ray,
+ out float is_transmission_ray,
+ out float ray_length,
+ out float ray_depth,
+ out float transparent_depth,
+ out float transmission_depth)
+{
+ is_camera_ray = 1.0;
+ is_shadow_ray = 0.0;
+ is_diffuse_ray = 0.0;
+ is_glossy_ray = 0.0;
+ is_singular_ray = 0.0;
+ is_reflection_ray = 0.0;
+ is_transmission_ray = 0.0;
+ ray_length = 1.0;
+ ray_depth = 1.0;
+ transparent_depth = 1.0;
+ transmission_depth = 1.0;
+}
+
+void node_light_falloff(float strength, float tsmooth, vec4 lamppos, vec3 pos, out float quadratic, out float linear, out float constant)
+{
+ float ray_length = length(lamppos.xyz - pos);
+
+ if (tsmooth > 0.0) {
+ float squared = ray_length * ray_length;
+ strength *= squared / (tsmooth + squared);
+ }
+
+ quadratic = strength;
+ linear = (strength * ray_length);
+ constant = (strength * ray_length * ray_length);
+}
+
+void node_object_info(mat4 objmat, out vec3 location, out float object_index, out float material_index, out float random)
+{
+ location = objmat[3].xyz;
+ object_index = 0.0;
+ material_index = 0.0;
+ random = 0.0;
+}
+
+void node_normal_map(vec4 tangent, vec3 normal, vec3 texnormal, out vec3 outnormal)
+{
+ vec3 B = tangent.w * cross(normal, tangent.xyz);
+
+ outnormal = texnormal.x * tangent.xyz + texnormal.y * B + texnormal.z * normal;
+ outnormal = normalize(outnormal);
+}
+
+void node_bump(float strength, float dist, float height, vec3 N, vec3 surf_pos, float invert, out vec3 result)
+{
+ if (invert != 0.0) {
+ dist *= -1.0;
+ }
+ vec3 dPdx = dFdx(surf_pos);
+ vec3 dPdy = dFdy(surf_pos);
+
+ /* Get surface tangents from normal. */
+ vec3 Rx = cross(dPdy, N);
+ vec3 Ry = cross(N, dPdx);
+
+ /* Compute surface gradient and determinant. */
+ float det = dot(dPdx, Rx);
+ float absdet = abs(det);
+
+ float dHdx = dFdx(height);
+ float dHdy = dFdy(height);
+ vec3 surfgrad = dHdx * Rx + dHdy * Ry;
+
+ strength = max(strength, 0.0);
+
+ result = normalize(absdet * N - dist * sign(det) * surfgrad);
+ result = normalize(strength * result + (1.0 - strength) * N);
+}
+
+/* output */
+
+void node_output_material(vec4 surface, vec4 volume, float displacement, out vec4 result)
+{
+ result = surface;
+}
+
+void node_output_world(vec4 surface, vec4 volume, out vec4 result)
+{
+ result = surface;
+}
+
+void node_output_lamp(vec4 surface, out vec4 result)
+{
+ result = surface;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_material_utils.glsl b/source/blender/gpu/shaders/gpu_shader_material_utils.glsl
new file mode 100644
index 00000000000..dd7cabfb0cd
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_material_utils.glsl
@@ -0,0 +1,1113 @@
+/* ------- Defines -------- */
+
+/* Number of default opengl lights */
+#define NUM_LIGHTS 3
+
+/* SSR Maximum iterations */
+#define MAX_SSR_REFINE_STEPS 8
+
+/* Importance sampling Max iterations */
+#define BSDF_SAMPLES 1024
+
+/* Linearly Transformed Cosines */
+#define LTC_LUT_SIZE 64
+
+/* needed for uint type and bitwise operation */
+#extension GL_EXT_gpu_shader4: enable
+
+/* ------- PBR Uniform --------- */
+
+uniform samplerCube unfprobe;
+uniform sampler2D unfreflect;
+uniform sampler2D unfrefract;
+uniform sampler2D unfltcmat;
+uniform sampler2D unfltcmag;
+uniform sampler2D unfscenebuf;
+uniform sampler2D unfdepthbuf;
+uniform sampler2D unfbackfacebuf;
+uniform sampler2D unfjitter;
+uniform sampler1D unflutsamples;
+uniform float unflodfactor;
+uniform vec2 unfbsdfsamples;
+uniform vec3 unfsh0;
+uniform vec3 unfsh1;
+uniform vec3 unfsh2;
+uniform vec3 unfsh3;
+uniform vec3 unfsh4;
+uniform vec3 unfsh5;
+uniform vec3 unfsh6;
+uniform vec3 unfsh7;
+uniform vec3 unfsh8;
+uniform vec3 unfprobepos;
+uniform vec3 unfplanarvec;
+uniform vec3 unfssrparam;
+uniform vec4 unfssaoparam;
+uniform vec4 unfclip;
+uniform mat4 unfprobecorrectionmat;
+uniform mat4 unfplanarreflectmat;
+uniform mat4 unfpixelprojmat;
+
+/* ------- Global Variables -------- */
+
+vec3 worldpos, refpos;
+vec3 viewnor, viewi;
+vec3 planarfac, planarvec;
+vec3 I, B, Ht;
+vec2 jitternoise = vec2(0.0);
+
+/* ------- Convenience functions --------- */
+
+vec3 mul(mat3 m, vec3 v) { return m * v; }
+mat3 mul(mat3 m1, mat3 m2) { return m1 * m2; }
+
+float saturate(float a) { return clamp(a, 0.0, 1.0); }
+vec2 saturate(vec2 a) { return vec2(saturate(a.x), saturate(a.y)); }
+vec3 saturate(vec3 a) { return vec3(saturate(a.x), saturate(a.y), saturate(a.z)); }
+vec4 saturate(vec4 a) { return vec4(saturate(a.x), saturate(a.y), saturate(a.z), saturate(a.w)); }
+
+float distance_squared(vec2 a, vec2 b) { a -= b; return dot(a, a); }
+float distance_squared(vec3 a, vec3 b) { a -= b; return dot(a, a); }
+
+float hypot(float x, float y) { return sqrt(x*x + y*y); }
+
+float inverse_distance(vec3 V) { return max( 1 / length(V), 1e-8); }
+
+vec4 bufferFetch(sampler2D buf, ivec2 texelpos, int lod)
+{
+#if __VERSION__ < 130
+ return texture2DLod(buf, (vec2(texelpos) + 0.5) / (unfclip.zw / exp2(float(lod))), float(lod));
+#else
+ return texelFetch(buf, texelpos, lod);
+#endif
+}
+
+/* --------- Noise Utils Functions --------- */
+
+void generated_from_orco(vec3 orco, out vec3 generated)
+{
+ generated = orco * 0.5 + vec3(0.5);
+}
+
+int floor_to_int(float x)
+{
+ return int(floor(x));
+}
+
+int quick_floor(float x)
+{
+ return int(x) - ((x < 0) ? 1 : 0);
+}
+
+#ifdef BIT_OPERATIONS
+float integer_noise(int n)
+{
+ int nn;
+ n = (n + 1013) & 0x7fffffff;
+ n = (n >> 13) ^ n;
+ nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
+ return 0.5 * (float(nn) / 1073741824.0);
+}
+
+uint hash(uint kx, uint ky, uint kz)
+{
+#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
+#define final(a, b, c) \
+{ \
+ c ^= b; c -= rot(b, 14); \
+ a ^= c; a -= rot(c, 11); \
+ b ^= a; b -= rot(a, 25); \
+ c ^= b; c -= rot(b, 16); \
+ a ^= c; a -= rot(c, 4); \
+ b ^= a; b -= rot(a, 14); \
+ c ^= b; c -= rot(b, 24); \
+}
+ // now hash the data!
+ uint a, b, c, len = 3u;
+ a = b = c = 0xdeadbeefu + (len << 2u) + 13u;
+
+ c += kz;
+ b += ky;
+ a += kx;
+ final (a, b, c);
+
+ return c;
+#undef rot
+#undef final
+}
+
+uint hash(int kx, int ky, int kz)
+{
+ return hash(uint(kx), uint(ky), uint(kz));
+}
+
+float bits_to_01(uint bits)
+{
+ float x = float(bits) * (1.0 / float(0xffffffffu));
+ return x;
+}
+
+float cellnoise(vec3 p)
+{
+ int ix = quick_floor(p.x);
+ int iy = quick_floor(p.y);
+ int iz = quick_floor(p.z);
+
+ return bits_to_01(hash(uint(ix), uint(iy), uint(iz)));
+}
+
+vec3 cellnoise_color(vec3 p)
+{
+ float r = cellnoise(p);
+ float g = cellnoise(vec3(p.y, p.x, p.z));
+ float b = cellnoise(vec3(p.y, p.z, p.x));
+
+ return vec3(r, g, b);
+}
+#endif // BIT_OPERATIONS
+
+float floorfrac(float x, out int i)
+{
+ i = floor_to_int(x);
+ return x - i;
+}
+
+/* --------- Geometric Utils Functions --------- */
+
+float linear_depth(float z)
+{
+ if (gl_ProjectionMatrix[3][3] == 0.0) {
+ float zn = unfclip.x; // camera z near
+ float zf = unfclip.y; // camera z far
+ return (zn * zf) / (z * (zn - zf) + zf);
+ }
+ else {
+ float zf = unfclip.y; // camera z far
+ return (z * 2.0 - 1.0) * zf;
+ }
+}
+
+float backface_depth(ivec2 texelpos, int lod)
+{
+ return bufferFetch(unfbackfacebuf, texelpos, lod).r;
+}
+
+float frontface_depth(ivec2 texelpos, int lod)
+{
+ return bufferFetch(unfdepthbuf, texelpos, lod).r;
+}
+
+float backface_depth_linear(ivec2 texelpos, int lod)
+{
+ float depth = linear_depth(bufferFetch(unfbackfacebuf, texelpos, lod).r);
+
+ /* background case */
+ if (depth == 1.0)
+ return -1e16;
+ else
+ return -depth;
+}
+
+float frontface_depth_linear(ivec2 texelpos, int lod)
+{
+ float depth = linear_depth(bufferFetch(unfdepthbuf, texelpos, lod).r);
+
+ /* background case */
+ if (depth == 1.0)
+ return -1e16;
+ else
+ return -depth;
+}
+
+vec3 position_from_depth(vec2 uv, float depth)
+{
+ vec3 pos;
+ float homcoord = gl_ProjectionMatrix[2][3] * depth + gl_ProjectionMatrix[3][3];
+ pos.x = gl_ProjectionMatrixInverse[0][0] * (uv.x * 2.0 - 1.0) * homcoord;
+ pos.y = gl_ProjectionMatrixInverse[1][1] * (uv.y * 2.0 - 1.0) * homcoord;
+ pos.z = depth;
+ return pos;
+}
+
+vec2 uv_from_position(vec3 position)
+{
+ vec4 projvec = gl_ProjectionMatrix * vec4(position, 1.0);
+ return (projvec.xy / projvec.w) * 0.5 + 0.5;
+}
+
+vec3 axis_angle_rotation(vec3 point, vec3 axis, float angle)
+{
+ axis = normalize(axis);
+ float s = sin(angle);
+ float c = cos(angle);
+ float oc = 1.0 - c;
+
+ mat3 mat = mat3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
+ oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
+ oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c);
+
+ return mat * point;
+}
+
+void viewN_to_shadeN(vec3 N, out vec3 shadeN)
+{
+ shadeN = normalize(-N);
+}
+
+void make_orthonormals(vec3 N, out vec3 T, out vec3 B)
+{
+ vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0,0.0,1.0) : vec3(1.0,0.0,0.0);
+ T = normalize( cross(UpVector, N) );
+ B = cross(N, T);
+}
+
+void make_orthonormals_tangent(vec3 N, inout vec3 T, out vec3 B)
+{
+ B = normalize( cross(N, T) );
+ T = cross(B, N);
+}
+
+void default_coordinates(vec3 attr_orco, out vec3 generated)
+{
+ generated = attr_orco * 0.5 + vec3(0.5);
+}
+
+vec3 from_tangent_to_world( vec3 vector, vec3 N, vec3 T, vec3 B)
+{
+ return T * vector.x + B * vector.y + N * vector.z;
+}
+
+vec3 from_world_to_tangent( vec3 vector, vec3 N, vec3 T, vec3 B)
+{
+ return vec3( dot(T, vector), dot(B, vector), dot(N, vector));
+}
+
+float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal)
+{
+ return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection);
+}
+
+vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal)
+{
+ float dist = line_plane_intersect_dist(lineorigin, linedirection, planeorigin, planenormal);
+ return lineorigin + linedirection * dist;
+}
+
+/* from cycles ray_aligned_disk_intersect */
+float line_aligned_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
+{
+ /* aligned plane normal */
+ vec3 L = planeorigin - lineorigin;
+ float diskdist = length(L);
+ vec3 planenormal = -normalize(L);
+ return -diskdist / dot(planenormal, linedirection);
+}
+
+vec3 line_aligned_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
+{
+ float dist = line_aligned_plane_intersect_dist(lineorigin, linedirection, planeorigin);
+ if (dist < 0) {
+ /* if intersection is behind we fake the intersection to be
+ * really far and (hopefully) not inside the radius of interest */
+ dist = 1e16;
+ }
+ return lineorigin + linedirection * dist;
+}
+
+void most_representative_point(float l_radius, float l_lenght, vec3 l_Y,
+ float l_distance, vec3 R, inout vec3 L,
+ inout float roughness, inout float energy_conservation)
+{
+ L = l_distance * L;
+
+ /* Tube Light */
+ if(l_lenght>0){
+ roughness = max(3e-3, roughness); /* Artifacts appear with roughness below this threshold */
+
+ // Use Tube Light specular instead of a plane.
+ // Energy conservation
+ // asin(x) is angle to sphere, atan(x) is angle to disk, saturate(x) is free and in the middle
+ //float LineAngle = clamp( l_lenght / l_distance, 0.0, 1.0);
+
+ //energy_conservation *= roughness / clamp(roughness + 0.5 * LineAngle, 0.0, 1.0);
+
+ /* Closest point on line segment to ray */
+ vec3 L01 = l_Y * l_lenght;
+ vec3 L0 = L - 0.5 * L01;
+ vec3 L1 = L + 0.5 * L01;
+
+ /* Shortest distance */
+ float a = l_lenght * l_lenght;
+ float b = dot(R, L01);
+ float t = saturate(dot( L0, b*R - L01 ) / (a - b*b));
+ L = L0 + t * L01;
+ }
+
+ /* Sphere Light */
+ if(l_radius>0){
+ roughness = max(3e-3, roughness); /* Artifacts appear with roughness below this threshold */
+
+ /* energy preservation */
+ float SphereAngle = saturate(l_radius / l_distance);
+ energy_conservation *= pow(roughness / saturate(roughness + 0.5 * SphereAngle), 2.0);
+
+ /* sphere light */
+ //float dist = line_aligned_plane_intersect_dist(vec3(0.0), R, L);
+ float dist = dot(L, R);
+ vec3 closest_point_on_ray = dist * R;
+ vec3 center_to_ray = closest_point_on_ray - L;
+ /* closest point on sphere */
+ L = L + center_to_ray * saturate(l_radius * inverse_distance(center_to_ray));
+ }
+
+ L = normalize(L);
+}
+
+void most_representative_point_disk(float l_radius, float l_distance, vec3 R, inout vec3 L,
+ inout float roughness, inout float energy_conservation)
+{
+ L = l_distance * L;
+
+ /* Sphere Light */
+ if(l_radius>0){
+ roughness = max(3e-3, roughness); /* Artifacts appear with roughness below this threshold */
+
+ /* energy preservation */
+ float SphereAngle = saturate(l_radius / l_distance);
+ energy_conservation *= pow(roughness / saturate(roughness + 0.5 * SphereAngle), 2.0);
+
+ /* sphere light */
+ vec3 closest_point_on_ray = line_plane_intersect(vec3(0.0), R, L, -normalize(L));
+ vec3 center_to_ray = closest_point_on_ray - L;
+ /* closest point on sphere */
+ L = L + center_to_ray * saturate(l_radius * inverse_distance(center_to_ray));
+ }
+
+ L = normalize(L);
+}
+
+vec2 area_light_prepass(mat4 lmat, inout float areasizex, inout float areasizey, vec2 areascale, out vec3 lampx, out vec3 lampy, out vec3 lampz)
+{
+ lampx = normalize( (lmat * vec4(1.0,0.0,0.0,0.0) ).xyz ); //lamp right axis
+ lampy = normalize( (lmat * vec4(0.0,1.0,0.0,0.0) ).xyz ); //lamp up axis
+ lampz = normalize( (lmat * vec4(0.0,0.0,1.0,0.0) ).xyz ); //lamp projection axis
+
+ areasizex *= areascale.x;
+ areasizey *= areascale.y;
+
+ return vec2(areasizex / 2.0, areasizey / 2.0);
+}
+
+
+/* ------ Linearly Transformed Cosines ------ */
+/* From https://eheitzresearch.wordpress.com/415-2/ */
+
+void area_light_points(vec3 lco, vec2 halfsize, vec3 lampx, vec3 lampy, out vec3 points[4])
+{
+ vec3 ex = lampx * halfsize.x;
+ vec3 ey = lampy * halfsize.y;
+
+ points[0] = lco - ex + ey;
+ points[1] = lco + ex + ey;
+ points[2] = lco + ex - ey;
+ points[3] = lco - ex - ey;
+}
+
+float integrate_edge(vec3 v1, vec3 v2)
+{
+ float cosTheta = dot(v1, v2);
+ cosTheta = clamp(cosTheta, -0.9999, 0.9999);
+
+ float theta = acos(cosTheta);
+ float res = cross(v1, v2).z * theta / sin(theta);
+
+ return res;
+}
+
+int clip_quad_to_horizon(inout vec3 L[5])
+{
+ /* detect clipping config */
+ int config = 0;
+ if (L[0].z > 0.0) config += 1;
+ if (L[1].z > 0.0) config += 2;
+ if (L[2].z > 0.0) config += 4;
+ if (L[3].z > 0.0) config += 8;
+
+ /* clip */
+ int n = 0;
+
+ if (config == 0)
+ {
+ /* clip all */
+ }
+ else if (config == 1) /* V1 clip V2 V3 V4 */
+ {
+ n = 3;
+ L[1] = -L[1].z * L[0] + L[0].z * L[1];
+ L[2] = -L[3].z * L[0] + L[0].z * L[3];
+ }
+ else if (config == 2) /* V2 clip V1 V3 V4 */
+ {
+ n = 3;
+ L[0] = -L[0].z * L[1] + L[1].z * L[0];
+ L[2] = -L[2].z * L[1] + L[1].z * L[2];
+ }
+ else if (config == 3) /* V1 V2 clip V3 V4 */
+ {
+ n = 4;
+ L[2] = -L[2].z * L[1] + L[1].z * L[2];
+ L[3] = -L[3].z * L[0] + L[0].z * L[3];
+ }
+ else if (config == 4) /* V3 clip V1 V2 V4 */
+ {
+ n = 3;
+ L[0] = -L[3].z * L[2] + L[2].z * L[3];
+ L[1] = -L[1].z * L[2] + L[2].z * L[1];
+ }
+ else if (config == 5) /* V1 V3 clip V2 V4) impossible */
+ {
+ n = 0;
+ }
+ else if (config == 6) /* V2 V3 clip V1 V4 */
+ {
+ n = 4;
+ L[0] = -L[0].z * L[1] + L[1].z * L[0];
+ L[3] = -L[3].z * L[2] + L[2].z * L[3];
+ }
+ else if (config == 7) /* V1 V2 V3 clip V4 */
+ {
+ n = 5;
+ L[4] = -L[3].z * L[0] + L[0].z * L[3];
+ L[3] = -L[3].z * L[2] + L[2].z * L[3];
+ }
+ else if (config == 8) /* V4 clip V1 V2 V3 */
+ {
+ n = 3;
+ L[0] = -L[0].z * L[3] + L[3].z * L[0];
+ L[1] = -L[2].z * L[3] + L[3].z * L[2];
+ L[2] = L[3];
+ }
+ else if (config == 9) /* V1 V4 clip V2 V3 */
+ {
+ n = 4;
+ L[1] = -L[1].z * L[0] + L[0].z * L[1];
+ L[2] = -L[2].z * L[3] + L[3].z * L[2];
+ }
+ else if (config == 10) /* V2 V4 clip V1 V3) impossible */
+ {
+ n = 0;
+ }
+ else if (config == 11) /* V1 V2 V4 clip V3 */
+ {
+ n = 5;
+ L[4] = L[3];
+ L[3] = -L[2].z * L[3] + L[3].z * L[2];
+ L[2] = -L[2].z * L[1] + L[1].z * L[2];
+ }
+ else if (config == 12) /* V3 V4 clip V1 V2 */
+ {
+ n = 4;
+ L[1] = -L[1].z * L[2] + L[2].z * L[1];
+ L[0] = -L[0].z * L[3] + L[3].z * L[0];
+ }
+ else if (config == 13) /* V1 V3 V4 clip V2 */
+ {
+ n = 5;
+ L[4] = L[3];
+ L[3] = L[2];
+ L[2] = -L[1].z * L[2] + L[2].z * L[1];
+ L[1] = -L[1].z * L[0] + L[0].z * L[1];
+ }
+ else if (config == 14) /* V2 V3 V4 clip V1 */
+ {
+ n = 5;
+ L[4] = -L[0].z * L[3] + L[3].z * L[0];
+ L[0] = -L[0].z * L[1] + L[1].z * L[0];
+ }
+ else if (config == 15) /* V1 V2 V3 V4 */
+ {
+ n = 4;
+ }
+
+ if (n == 3)
+ L[3] = L[0];
+ if (n == 4)
+ L[4] = L[0];
+
+ return n;
+}
+
+vec2 ltc_coords(float cosTheta, float roughness)
+{
+ float theta = acos(cosTheta);
+ vec2 coords = vec2(roughness, theta/(0.5*3.14159));
+
+ /* scale and bias coordinates, for correct filtered lookup */
+ return coords * (LTC_LUT_SIZE - 1.0) / LTC_LUT_SIZE + 0.5 / LTC_LUT_SIZE;
+}
+
+mat3 ltc_matrix(vec2 coord)
+{
+ /* load inverse matrix */
+ vec4 t = texture2D(unfltcmat, coord);
+ mat3 Minv = mat3(
+ vec3( 1, 0, t.y),
+ vec3( 0, t.z, 0),
+ vec3(t.w, 0, t.x)
+ );
+
+ return Minv;
+}
+
+float ltc_evaluate(vec3 N, vec3 V, vec3 P, mat3 Minv, vec3 points[4])
+{
+ /* construct orthonormal basis around N */
+ vec3 T1, T2;
+ T1 = normalize(V - N*dot(V, N));
+ T2 = cross(N, T1);
+
+ /* rotate area light in (T1, T2, R) basis */
+ Minv = mul(Minv, transpose(mat3(T1, T2, N)));
+
+ /* polygon (allocate 5 vertices for clipping) */
+ vec3 L[5];
+ L[0] = mul(Minv, points[0] - P);
+ L[1] = mul(Minv, points[1] - P);
+ L[2] = mul(Minv, points[2] - P);
+ L[3] = mul(Minv, points[3] - P);
+
+ int n = clip_quad_to_horizon(L);
+
+ if (n == 0)
+ return 0.0;
+
+ /* project onto sphere */
+ L[0] = normalize(L[0]);
+ L[1] = normalize(L[1]);
+ L[2] = normalize(L[2]);
+ L[3] = normalize(L[3]);
+ L[4] = normalize(L[4]);
+
+ /* integrate */
+ float sum = 0.0;
+
+ sum += integrate_edge(L[0], L[1]);
+ sum += integrate_edge(L[1], L[2]);
+ sum += integrate_edge(L[2], L[3]);
+ if (n >= 4)
+ sum += integrate_edge(L[3], L[4]);
+ if (n == 5)
+ sum += integrate_edge(L[4], L[0]);
+
+ return abs(sum);
+}
+
+/* ------- Fresnel ---------*/
+
+float fresnel_dielectric(vec3 Incoming, vec3 Normal, float eta)
+{
+ /* compute fresnel reflectance without explicitly computing
+ * the refracted direction */
+ float c = abs(dot(Incoming, Normal));
+ float g = eta * eta - 1.0 + c * c;
+ float result;
+
+ if(g > 0.0) {
+ g = sqrt(g);
+ float A =(g - c)/(g + c);
+ float B =(c *(g + c)- 1.0)/(c *(g - c)+ 1.0);
+ result = 0.5 * A * A *(1.0 + B * B);
+ }
+ else {
+ result = 1.0; /* TIR (no refracted component) */
+ }
+
+ return result;
+}
+
+
+/* ------- Energy Conversion for lights ------- */
+/* from Sebastien Lagarde
+ * course_notes_moving_frostbite_to_pbr.pdf */
+
+float sphere_energy(float radius)
+{
+ radius = max(radius, 1e-8);
+ return 0.25 * M_1_PI2 / (radius*radius) /* 1/(4*r²*Pi²) */
+ * M_PI2 * 10.0; /* XXX : Empirical, Fit cycles power */
+}
+
+float disk_energy(float radius)
+{
+ radius = max(radius, 1e-8);
+ return M_1_PI2 / (radius*radius); /* 1/(r²*Pi²) */
+}
+
+float tube_energy(float radius, float width)
+{
+ radius = max(radius, 1e-8);
+ return 0.5 * M_1_PI2 / (radius * (width + 2 * radius)); /* 1/(4*r²*Pi²) + 1/(2*r*w*Pi²) */
+}
+
+float rectangle_energy(float width, float height)
+{
+ return M_1_PI / (width*height) /* 1/(w*h*Pi) */
+ * 80.0; /* XXX : Empirical, Fit cycles power */
+}
+
+/* ------- Ambient Occlusion ------- */
+/* from Sebastien Lagarde
+ * course_notes_moving_frostbite_to_pbr.pdf */
+
+float specular_occlusion(float NV, float AO, float roughness)
+{
+#ifdef USE_SSAO
+ return saturate(pow(NV + AO, roughness) - 1.0 + AO);
+#else
+ return 1.0;
+#endif
+}
+
+/* ----------- Parallax Correction -------------- */
+
+void parallax_correct_ray(inout vec3 L)
+{
+#ifdef CORRECTION_NONE
+ return;
+#else
+ vec3 localray = (unfprobecorrectionmat * vec4(L, 0.0)).xyz;
+ vec3 localpos = (unfprobecorrectionmat * vec4(worldpos, 1.0)).xyz;
+
+#ifdef CORRECTION_BOX
+ /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ */
+ vec3 firstplane = (vec3( 1.0) - localpos) / localray;
+ vec3 secondplane = (vec3(-1.0) - localpos) / localray;
+ vec3 furthestplane = max(firstplane, secondplane);
+ float dist = min(furthestplane.x, min(furthestplane.y, furthestplane.z));
+#endif
+
+#ifdef CORRECTION_ELLIPSOID
+ /* ray sphere intersection */
+ float a = dot(localray, localray);
+ float b = dot(localray, localpos);
+ float c = dot(localpos, localpos) - 1;
+
+ float dist = 1e15;
+ float determinant = b * b - a * c;
+ if (determinant >= 0)
+ dist = (sqrt(determinant) - b) / a;
+#endif
+
+ /* Use Distance in WS directly to recover intersection */
+ vec3 intersection = worldpos + L * dist;
+ L = intersection - unfprobepos;
+#endif
+}
+
+/* ----------- Probe sampling wrappers -------------- */
+
+void vector_prepass(vec3 viewpos, vec3 worldnor, mat4 invviewmat, mat4 viewmat)
+{
+ worldpos = (invviewmat * vec4(viewpos, 1.0)).xyz;
+
+ shade_view(viewpos, viewi);
+ direction_transform_m4v3(viewi, invviewmat, I);
+
+#ifdef PLANAR_PROBE
+ /* View Normals */
+ direction_transform_m4v3(worldnor, viewmat, viewnor);
+
+ /* transposing plane orientation to view space */
+ direction_transform_m4v3(unfplanarvec, viewmat, planarvec);
+
+ planarfac.x = dot(planarvec, vec3(1.0, 0.0, 0.0));
+ planarfac.y = dot(planarvec, vec3(0.0, 1.0, 0.0));
+ planarfac.z = -viewpos.z + 1.0;
+
+ vec4 proj = unfplanarreflectmat * vec4(worldpos, 1.0);
+ refpos = proj.xyz/proj.w;
+#endif
+}
+
+#if 0
+float distance_based_roughness(float dist_intersection_to_shaded, float dist_intersection_to_reflectioncam, float roughness)
+{
+ /* from Sebastien Lagarde
+ * course_notes_moving_frostbite_to_pbr.pdf */
+ float newroughness = clamp(roughness * dist_intersection_to_shaded / dist_intersection_to_reflectioncam, 0, roughness);
+ return mix(newroughness, roughness, roughness);
+}
+#endif
+
+vec2 get_distorded_refl_uv(sampler2D planarprobe, vec2 Xi)
+{
+ vec2 distortion = vec2(dot(viewnor, vec3(1.0, 0.0, 0.0)) - planarfac.x,
+ dot(viewnor, vec3(0.0, 1.0, 0.0)) - planarfac.y);
+ distortion += Xi;
+
+ /* modulate intensity by distance to the viewer and by distance to the reflected object */
+ float dist_view_to_shaded = planarfac.z;
+ float dist_intersection_to_reflectioncam = texture2D(planarprobe, refpos.xy + Xi / dist_view_to_shaded).a;
+ float dist_intersection_to_shaded = dist_intersection_to_reflectioncam - dist_view_to_shaded; /* depth in alpha */
+
+ /* test in case of background */
+ if (dist_intersection_to_shaded > 0.0) {
+ float distortion_scale = abs(dot(viewi * dist_intersection_to_shaded, -planarvec));
+ distortion *= distortion_scale / (dist_view_to_shaded + 1.0);
+ }
+
+ return refpos.xy + distortion;
+}
+
+vec4 sample_probe_pdf(vec3 cubevec, float pdf)
+{
+ vec4 sample;
+
+ float lod = unflodfactor - 0.5 * log2(pdf);
+
+ parallax_correct_ray(cubevec);
+ sample = textureCubeLod(unfprobe, cubevec, lod);
+
+ srgb_to_linearrgb(sample, sample);
+ return sample;
+}
+
+vec4 sample_probe_pdf(sampler2D planarprobe, vec3 cubevec, float roughness, float pdf)
+{
+ vec4 sample;
+
+ float lod = unflodfactor - 0.5 * log2(pdf);
+
+ parallax_correct_ray(cubevec);
+ sample = textureCubeLod(unfprobe, cubevec, lod);
+
+#ifdef PLANAR_PROBE
+ vec4 sample_plane = vec4(0.0);
+ vec2 co = get_distorded_refl_uv(planarprobe, Ht.xy);
+ if (co.x > 0.0 && co.x < 1.0 && co.y > 0.0 && co.y < 1.0)
+ sample_plane = texture2DLod(planarprobe, co, lod);
+ else
+ sample_plane = sample;
+ sample = mix(sample_plane, sample, clamp(roughness * 2.0 - 0.5, 0.0, 1.0));
+#endif
+
+ srgb_to_linearrgb(sample, sample);
+ return sample;
+}
+
+vec4 sample_reflect_pdf(vec3 L, float roughness, float pdf)
+{
+ return sample_probe_pdf(unfreflect, L, roughness, pdf);
+}
+
+vec4 sample_refract_pdf(vec3 L, float roughness, float pdf)
+{
+ return sample_probe_pdf(unfrefract, L, roughness, pdf);
+}
+
+vec4 sample_probe(sampler2D planarprobe, vec3 cubevec)
+{
+ vec4 sample;
+
+ /* Cubemap */
+ parallax_correct_ray(cubevec);
+ sample = textureCube(unfprobe, cubevec);
+
+#ifdef PLANAR_PROBE
+ /* Planar */
+ vec2 co = get_distorded_refl_uv(planarprobe, vec2(0.0));
+ if (co.x > 0.0 && co.x < 1.0 && co.y > 0.0 && co.y < 1.0)
+ sample = texture2D(planarprobe, co);
+#endif
+
+ srgb_to_linearrgb(sample, sample);
+ return sample;
+}
+
+vec4 sample_reflect(vec3 L)
+{
+ return sample_probe(unfreflect, L);
+}
+
+vec4 sample_refract(vec3 L)
+{
+ return sample_probe(unfrefract, L);
+}
+
+/* ------- Sampling Random Ray -------- */
+
+void setup_noise(vec2 fragcoord)
+{
+ const int NOISE_SIZE = 64;
+ ivec2 texel = ivec2(mod(fragcoord.x, NOISE_SIZE), mod(fragcoord.y, NOISE_SIZE));
+#if __VERSION__ < 130
+ jitternoise = texture2DLod(unfjitter, (vec2(texel) + 0.5) / float(NOISE_SIZE), 0.0).rg; /* Global variable */
+#else
+ jitternoise = texelFetch(unfjitter, texel, 0).rg; /* Global variable */
+#endif
+}
+
+vec3 hammersley_3d(float i, float invsamplenbr)
+{
+ vec3 Xi; /* Theta, cos(Phi), sin(Phi) */
+
+ Xi.x = i * invsamplenbr; /* i/samples */
+ Xi.x = fract(Xi.x + jitternoise.x);
+
+ int u = int(mod(i + jitternoise.y * BSDF_SAMPLES, BSDF_SAMPLES));
+
+#if __VERSION__ < 130
+ Xi.yz = texture1DLod(unflutsamples, (float(u) + 0.5) / float(BSDF_SAMPLES), 0.0).rg; /* Global variable */
+#else
+ Xi.yz = texelFetch(unflutsamples, u, 0).rg; /* Global variable */
+#endif
+ return Xi;
+}
+
+vec3 hammersley_3d(float i)
+{
+ return hammersley_3d(i, unfbsdfsamples.y);
+}
+
+/* ------- Screen Space Raycasting ---------*/
+
+/* By Morgan McGuire and Michael Mara at Williams College 2014
+ * Released as open source under the BSD 2-Clause License
+ * http://opensource.org/licenses/BSD-2-Clause
+ * http://casual-effects.blogspot.fr/2014/08/screen-space-ray-tracing.html */
+void swapIfBigger(inout float a, inout float b)
+{
+ if (a > b) {
+ float temp = a;
+ a = b;
+ b = temp;
+ }
+}
+
+#if 1 /* Linear 2D raymarching */
+
+/* 2D raycast */
+bool raycast(vec3 ray_origin, vec3 ray_dir, out float hitstep, out vec2 hitpixel, out vec3 hitco)
+{
+ /* ssr_parameters */
+ float nearz = -unfclip.x; /* Near plane distance (Negative number) */
+ float farz = -unfclip.y; /* Far plane distance (Negative number) */
+
+ /* Clip ray to a near plane in 3D */
+ float ray_length = 1e16;
+ if ((ray_origin.z + ray_dir.z * ray_length) > nearz)
+ ray_length = (nearz - ray_origin.z) / ray_dir.z;
+
+ vec3 ray_end = ray_dir * ray_length + ray_origin;
+
+ /* Project into screen space */
+ vec4 H0 = unfpixelprojmat * vec4(ray_origin, 1.0);
+ vec4 H1 = unfpixelprojmat * vec4(ray_end, 1.0);
+
+ /* There are a lot of divisions by w that can be turned into multiplications
+ * at some minor precision loss...and we need to interpolate these 1/w values
+ * anyway. */
+ float k0 = 1.0 / H0.w;
+ float k1 = 1.0 / H1.w;
+
+ /* Switch the original points to values that interpolate linearly in 2D */
+ vec3 Q0 = ray_origin * k0;
+ vec3 Q1 = ray_end * k1;
+
+ /* Screen-space endpoints */
+ vec2 P0 = H0.xy * k0;
+ vec2 P1 = H1.xy * k1;
+
+ /* [Optional clipping to frustum sides here] */
+
+ /* Initialize to off screen */
+ hitpixel = vec2(-1.0, -1.0);
+
+ /* If the line is degenerate, make it cover at least one pixel
+ * to not have to handle zero-pixel extent as a special case later */
+ P1 += vec2((distance_squared(P0, P1) < 0.0001) ? 0.01 : 0.0);
+
+ vec2 delta = P1 - P0;
+
+ /* Permute so that the primary iteration is in x to reduce large branches later.
+ * After this, "x" is the primary iteration direction and "y" is the secondary one
+ * If it is a more-vertical line, create a permutation that swaps x and y in the output
+ * and directly swizzle the inputs. */
+ bool permute = false;
+ if (abs(delta.x) < abs(delta.y)) {
+ permute = true;
+ delta = delta.yx;
+ P1 = P1.yx;
+ P0 = P0.yx;
+ }
+
+ /* Track the derivatives */
+ float step_sign = sign(delta.x);
+ float invdx = step_sign / delta.x;
+ vec2 dP = vec2(step_sign, invdx * delta.y);
+ vec3 dQ = (Q1 - Q0) * invdx;
+ float dk = (k1 - k0) * invdx;
+
+ /* Slide each value from the start of the ray to the end */
+ vec4 pqk = vec4(P0, Q0.z, k0);
+
+ /* Scale derivatives by the desired pixel stride */
+ vec4 dPQK = vec4(dP, dQ.z, dk) * 1.0;
+
+ bool hit = false;
+
+ /* We track the ray depth at +/- 1/2 pixel to treat pixels as clip-space solid
+ * voxels. Because the depth at -1/2 for a given pixel will be the same as at
+ * +1/2 for the previous iteration, we actually only have to compute one value
+ * per iteration. */
+ float prev_zmax = ray_origin.z;
+ float zmax, zmin;
+
+ /* P1.x is never modified after this point, so pre-scale it by
+ * the step direction for a signed comparison */
+ float end = P1.x * step_sign;
+
+ for (hitstep = 0.0; hitstep < unfssrparam.x && !hit; hitstep++)
+ {
+ /* Ray finished & no hit*/
+ if ((pqk.x * step_sign) > end) break;
+
+ /* step through current cell */
+ pqk += dPQK;
+
+ hitpixel = permute ? pqk.yx : pqk.xy;
+ zmin = prev_zmax;
+ zmax = (dPQK.z * 0.5 + pqk.z) / (dPQK.w * 0.5 + pqk.w);
+ prev_zmax = zmax;
+ swapIfBigger(zmin, zmax);
+
+ float frontface = frontface_depth_linear(ivec2(hitpixel), 0);
+
+ if (zmax < frontface) {
+ /* Below surface */
+#ifdef USE_BACKFACE
+ float backface = backface_depth_linear(ivec2(hitpixel), 0);
+#else
+ float backface = frontface - unfssrparam.z;
+#endif
+ hit = (zmin > backface);
+ }
+ }
+
+ /* Hit coordinate in 3D */
+ hitco = (Q0 + dQ * hitstep) / pqk.w;
+
+ return hit;
+}
+
+#else /* Hierarchical raymarching */
+
+vec3 point_on_line(vec3 origin, vec3 direction, float dist)
+{
+ return origin + direction * dist;
+}
+
+vec2 get_cell(vec2 ray, vec2 cellcount)
+{
+ return floor(ray * cellcount);
+}
+
+vec3 intersect_cell_boundary(vec3 o, vec3 d, vec2 cell, vec2 cellcount, vec2 crossstep, vec2 crossoffset)
+{
+ vec2 newcell = ((cell + crossstep) / cellcount) + crossoffset;
+ vec2 delta = (newcell - o.xy) / d.xy;
+ float t = min(delta.x, delta.y);
+
+ return point_on_line(o, d, t);
+}
+
+vec2 get_cell_count(float level)
+{
+ return floor(unfclip.zw / exp2(level));
+}
+
+bool crossed_cell_boundary(vec2 a, vec2 b)
+{
+ return (a.x != b.x) || (a.y != b.y);
+}
+
+#define HIZ_MAX_LEVEL 8.0
+
+bool raycast(vec3 ray_origin, vec3 ray_dir, out float hitstep, out vec2 hitpixel, out vec3 hitco)
+{
+ float miplvl = 0.0; /* Start level */
+ vec2 cellcount = get_cell_count(0.0);
+
+ /* Invert Z component so we can work with the raw depth buffer which is positive */
+ ray_dir.z *= -1;
+
+ /* scale vector such that z is 1.0f (maximum depth) */
+ ray_dir = ray_dir.xyz / abs(ray_dir.z);
+
+ vec2 crossstep, crossoffset;
+ vec2 cross_epsilon = vec2(0.2) / cellcount; /* Enough to get to the next cell */
+ crossstep.x = (ray_dir.x > 0.0) ? 1.0 : -1.0;
+ crossstep.y = (ray_dir.y > 0.0) ? 1.0 : -1.0;
+ crossoffset = crossstep * cross_epsilon;
+ crossstep = saturate(crossstep);
+
+ /* set current ray to original screen coordinate and depth */
+ vec3 ray;
+ ray.xy = uv_from_position(ray_origin);
+ ray.z = frontface_depth(ivec2(ray.xy * cellcount), int(miplvl));
+
+ /* project ray origin to the near clip plane */
+ vec3 o = point_on_line(ray, ray_dir, -ray.z);
+
+ /* Cross first cell (texel) to not get self-intersection */
+ vec2 cell = get_cell(ray.xy, cellcount);
+ ray = intersect_cell_boundary(o, ray_dir, cell, cellcount, crossstep, crossoffset);
+
+ for (hitstep = 0.0; hitstep < unfssrparam.x && miplvl >= 0.0; hitstep++)
+ {
+ cellcount = get_cell_count(miplvl);
+ cell = get_cell(ray.xy, cellcount);
+
+ float frontface = frontface_depth(ivec2(cell), int(miplvl));
+
+ /* Try intersecting the depth plane
+ * or stay in place if there is an intersection */
+ vec3 raytmp = point_on_line(o, ray_dir, max(ray.z, frontface));
+ /* Go to the next cell and go up a level */
+ vec2 celltmp = get_cell(raytmp.xy, cellcount);
+
+ /* If ray crossed a cell then it's not blocked */
+ if (crossed_cell_boundary(cell, celltmp)) {
+ /* Go to the next cell and go up a level */
+ raytmp = intersect_cell_boundary(o, ray_dir, cell, cellcount, crossstep, crossoffset);
+ miplvl = min(HIZ_MAX_LEVEL, miplvl + 2.0);
+ }
+
+ ray = raytmp;
+ --miplvl;
+ }
+
+ hitpixel = ray.xy * unfclip.zw;
+ hitco = position_from_depth(ray.xy, linear_depth(ray.z));
+
+ return (miplvl < 0.0 && ray.z < 1.0 && ray.z > 0.0 && ray_dir.z > 0 && ray.x > 0 && ray.x < 1 && ray.y > 0 && ray.y < 1);
+}
+#endif
+
+float ssr_contribution(vec3 ray_origin, float hitstep, bool hit, inout vec3 hitco)
+{
+ /* ssr_parameters */
+ float maxstep = unfssrparam.x; /* Maximum number of iteration when raymarching */
+ float attenuation = unfssrparam.y; /* Attenuation factor for screen edges and ray step fading */
+
+ /* ray step fade */
+ float stepfade = saturate((1.0 - hitstep / maxstep) * attenuation);
+
+ /* screen edges fade */
+ vec4 co = gl_ProjectionMatrix * vec4(hitco, 1.0);
+ co.xy /= co.w;
+ hitco.xy = co.xy * 0.5 + 0.5;
+ float maxdimension = saturate(max(abs(co.x), abs(co.y)));
+ float screenfade = saturate((0.999999 - maxdimension) * attenuation);
+
+ return smoothstep(0.0, 1.0, stepfade * screenfade) * float(hit);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_probe_sh_compute_frag.glsl b/source/blender/gpu/shaders/gpu_shader_probe_sh_compute_frag.glsl
new file mode 100644
index 00000000000..6bf60407f57
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_probe_sh_compute_frag.glsl
@@ -0,0 +1,108 @@
+uniform samplerCube probe;
+
+#define M_4PI 12.5663706143591729
+
+const mat3 CUBE_ROTATIONS[6] = mat3[](
+ mat3(vec3( 0.0, 0.0, -1.0),
+ vec3( 0.0, -1.0, 0.0),
+ vec3(-1.0, 0.0, 0.0)),
+ mat3(vec3( 0.0, 0.0, 1.0),
+ vec3( 0.0, -1.0, 0.0),
+ vec3( 1.0, 0.0, 0.0)),
+ mat3(vec3( 1.0, 0.0, 0.0),
+ vec3( 0.0, 0.0, 1.0),
+ vec3( 0.0, -1.0, 0.0)),
+ mat3(vec3( 1.0, 0.0, 0.0),
+ vec3( 0.0, 0.0, -1.0),
+ vec3( 0.0, 1.0, 0.0)),
+ mat3(vec3( 1.0, 0.0, 0.0),
+ vec3( 0.0, -1.0, 0.0),
+ vec3( 0.0, 0.0, -1.0)),
+ mat3(vec3(-1.0, 0.0, 0.0),
+ vec3( 0.0, -1.0, 0.0),
+ vec3( 0.0, 0.0, 1.0)));
+
+float srgb_to_linearrgb(float c)
+{
+ if(c < 0.04045)
+ return (c < 0.0) ? 0.0: c * (1.0 / 12.92);
+ else
+ return pow((c + 0.055)*(1.0/1.055), 2.4);
+}
+
+void srgb_to_linearrgb(vec4 col_from, out vec4 col_to)
+{
+ col_to.r = srgb_to_linearrgb(col_from.r);
+ col_to.g = srgb_to_linearrgb(col_from.g);
+ col_to.b = srgb_to_linearrgb(col_from.b);
+ col_to.a = col_from.a;
+}
+
+vec3 get_cubemap_vector(vec2 co, int face)
+{
+ return normalize(CUBE_ROTATIONS[face] * vec3(co * 2.0 - 1.0, 1.0));
+}
+
+float area_element(float x, float y)
+{
+ return atan(x * y, sqrt(x * x + y * y + 1));
+}
+
+float texel_solid_angle(vec2 co, float halfpix)
+{
+ vec2 v1 = (co - vec2(halfpix)) * 2.0 - 1.0;
+ vec2 v2 = (co + vec2(halfpix)) * 2.0 - 1.0;
+
+ return area_element(v1.x, v1.y) - area_element(v1.x, v2.y) - area_element(v2.x, v1.y) + area_element(v2.x, v2.y);
+}
+
+void main()
+{
+ const float pixstep = 1.0 / CUBEMAP_RES;
+ const float halfpix = pixstep / 2.0;
+
+ vec2 pos = ceil(gl_FragCoord.xy);
+
+ if (pos.x > 3.0 || pos.y > 3.0) {
+ gl_FragColor = vec4(0.0);
+ return;
+ }
+
+ int shnbr = int(pos.x + (pos.y - 1) * 3);
+ float accum = 0.0;
+ vec3 sh = vec3(0.0);
+
+ for (int face = 0; face < 6; ++face)
+ {
+ for (float x = halfpix; x < 1.0; x += pixstep)
+ {
+ for (float y = halfpix; y < 1.0; y += pixstep)
+ {
+ float shcoef;
+
+ vec2 facecoord = vec2(x,y);
+ vec3 cubevec = get_cubemap_vector(facecoord, face);
+ float weight = texel_solid_angle(facecoord, halfpix);
+
+ if (shnbr == 1) shcoef = 0.282095;
+ else if (shnbr == 2) shcoef = -0.488603 * cubevec.z * 2.0 / 3.0;
+ else if (shnbr == 3) shcoef = 0.488603 * cubevec.y * 2.0 / 3.0;
+ else if (shnbr == 4) shcoef = -0.488603 * cubevec.x * 2.0 / 3.0;
+ else if (shnbr == 5) shcoef = 1.092548 * cubevec.x * cubevec.z * 1.0 / 4.0;
+ else if (shnbr == 6) shcoef = -1.092548 * cubevec.z * cubevec.y * 1.0 / 4.0;
+ else if (shnbr == 7) shcoef = 0.315392 * (3.0 * cubevec.y * cubevec.y - 1.0) * 1.0 / 4.0;
+ else if (shnbr == 8) shcoef = 1.092548 * cubevec.x * cubevec.y * 1.0 / 4.0;
+ else /* (shnbr == 9) */ shcoef = 0.546274 * (cubevec.x * cubevec.x - cubevec.z * cubevec.z) * 1.0 / 4.0;
+
+ vec4 sample = textureCubeLod(probe, cubevec, 0.0);
+ srgb_to_linearrgb(sample, sample);
+ sh += sample.rgb * shcoef * weight;
+ accum += weight;
+ }
+ }
+ }
+
+ sh *= M_4PI / accum;
+
+ gl_FragColor = vec4(sh, 1.0);
+} \ No newline at end of file
diff --git a/source/blender/gpu/shaders/gpu_shader_probe_sh_compute_vert.glsl b/source/blender/gpu/shaders/gpu_shader_probe_sh_compute_vert.glsl
new file mode 100644
index 00000000000..9f5e788d902
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_probe_sh_compute_vert.glsl
@@ -0,0 +1,5 @@
+void main()
+{
+ /* We are using gl_FragCoord inside the fragment shader so nothing fancy here */
+ gl_Position = gl_Vertex;
+}
diff --git a/source/blender/makesdna/DNA_color_types.h b/source/blender/makesdna/DNA_color_types.h
index f7ee1ff3915..e518f250aa8 100644
--- a/source/blender/makesdna/DNA_color_types.h
+++ b/source/blender/makesdna/DNA_color_types.h
@@ -165,7 +165,7 @@ typedef struct Scopes {
#define SCOPES_WAVEFRM_RGB 5
typedef struct ColorManagedViewSettings {
- int flag, pad;
+ int flag, lut_is_outdated;
char look[64]; /* look which is being applied when displaying buffer on the screen (prior to view transform) */
char view_transform[64]; /* view transform which is being applied when displaying buffer on the screen */
float exposure; /* fstop exposure */
@@ -176,6 +176,7 @@ typedef struct ColorManagedViewSettings {
typedef struct ColorManagedDisplaySettings {
char display_device[64];
+ int lut_is_outdated, pad;
} ColorManagedDisplaySettings;
typedef struct ColorManagedColorspaceSettings {
diff --git a/source/blender/makesdna/DNA_gpu_types.h b/source/blender/makesdna/DNA_gpu_types.h
index 967cb7284dc..1e82fdcd10d 100644
--- a/source/blender/makesdna/DNA_gpu_types.h
+++ b/source/blender/makesdna/DNA_gpu_types.h
@@ -32,6 +32,8 @@
#ifndef __DNA_GPU_TYPES_H__
#define __DNA_GPU_TYPES_H__
+/* ********** GPU POST FX *********** */
+
/* properties for dof effect */
typedef struct GPUDOFSettings {
float focus_distance; /* focal distance for depth of field */
@@ -49,20 +51,57 @@ typedef struct GPUSSAOSettings {
float distance_max;
float attenuation;
int samples; /* ray samples, we use presets here for easy control instead of */
- int pad;
+ int steps;
} GPUSSAOSettings;
typedef struct GPUFXSettings {
GPUDOFSettings *dof;
GPUSSAOSettings *ssao;
char fx_flag; /* eGPUFXFlags */
- char pad[7];
+ char fx_flag2; /* eGPUFXFlags */
+ char pad[6];
} GPUFXSettings;
/* shaderfx enables */
typedef enum eGPUFXFlags {
- GPU_FX_FLAG_DOF = (1 << 0),
- GPU_FX_FLAG_SSAO = (1 << 1),
+ GPU_FX_FLAG_DOF = (1 << 0),
+ GPU_FX_FLAG_SSAO = (1 << 1),
+ GPU_FX_FLAG_COLORMANAGEMENT = (1 << 2),
} eGPUFXFlags;
+/* ********** GPU PBR *********** */
+
+/* Screen space reflection settings */
+typedef struct GPUSSRSettings {
+ float attenuation;
+ float thickness;
+ int steps;
+ int pad;
+} GPUSSRSettings;
+
+/* Material surfaces and sampling settings */
+typedef struct GPUBRDFSettings {
+ float lodbias;
+ float pad;
+ int samples;
+ int pad2;
+} GPUBRDFSettings;
+
+typedef struct GPUPBRSettings {
+ GPUBRDFSettings *brdf;
+ GPUSSRSettings *ssr;
+ GPUSSAOSettings *ssao;
+ char pbr_flag; /* eGPUPBRFlags */
+ char pad[7];
+} GPUPBRSettings;
+
+/* pbrshader enables */
+typedef enum eGPUPBRFlags {
+ GPU_PBR_FLAG_ENABLE = (1 << 0),
+ GPU_PBR_FLAG_SSR = (1 << 1),
+ GPU_PBR_FLAG_SSAO = (1 << 2),
+ GPU_PBR_FLAG_BACKFACE = (1 << 3),
+ GPU_PBR_FLAG_LAYER_OVERRIDE = (1 << 4),
+} eGPUPBRFlags;
+
#endif /* __DNA_GPU_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index b4bc26f45cd..47a41212996 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -156,6 +156,10 @@ typedef struct Image {
struct Stereo3dFormat *stereo3d_format;
RenderSlot render_slots[8]; /* 8 = IMA_MAX_RENDER_SLOT */
+
+ short last_projection;
+ short is_envmap;
+ float SH_Coefs[9][3];
} Image;
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 46b30f41f5b..3a76c7f1063 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -752,6 +752,7 @@ typedef struct NodeTexEnvironment {
ImageUser iuser;
int color_space;
int projection;
+ struct GPUNodeLink *normal_transform_link;
int interpolation;
int pad;
} NodeTexEnvironment;
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index d24c7faa9f5..85903cabd1a 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -286,9 +286,10 @@ typedef struct Object {
unsigned int init_state; /* bit masks of initial state as recorded by the users */
ListBase gpulamp; /* runtime, for glsl lamp display only */
+ ListBase gpuprobe; /* runtime, for glsl reflections */
ListBase pc_ids;
ListBase *duplilist; /* for temporary dupli list storage, only for use by RNA API */
-
+
struct RigidBodyOb *rigidbody_object; /* settings for Bullet rigid body */
struct RigidBodyCon *rigidbody_constraint; /* settings for Bullet constraint */
@@ -299,6 +300,23 @@ typedef struct Object {
LodLevel *currentlod;
struct PreviewImage *preview;
+
+ /* Probe options */
+ struct Object *probe; /* the probe object used for rendering it's materials */
+ struct Object *parallaxcorrect; /* the parallax bounding object used for rendering */
+ struct Object *reflectionplane;
+
+ char probeparallax;
+ char probeflags;
+ short probetype;
+
+ float probeclipsta;
+ float probeclipend;
+ unsigned int probesize;
+ unsigned int probeshres;
+
+ float probeclipbias;
+ int pad3[2];
} Object;
/* Warning, this is not used anymore because hooks are now modifiers */
@@ -489,6 +507,27 @@ enum {
OB_LOD_USE_HYST = 1 << 2,
};
+/* (short) probe type */
+enum {
+ OB_PROBE_OBJECT = 1,
+ OB_PROBE_CUBEMAP = 2,
+ OB_PROBE_PLANAR = 3,
+};
+
+/* (short) probe parallax */
+enum {
+ OB_PROBE_PARRALAX_ELLIPSOID = 1,
+ OB_PROBE_PARRALAX_BOX = 2,
+};
+
+/* (short) probeflags */
+enum {
+ OB_PROBE_AUTO_UPDATE = 1 << 0,
+ OB_PROBE_DOUBLE_UPDATE = 1 << 1,
+ OB_PROBE_COMPUTE_SH = 1 << 2,
+ OB_PROBE_USE_LAYERS = 1 << 3,
+};
+
/* **************** BASE ********************* */
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 4c243507e82..dbb5f102d14 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -45,6 +45,7 @@ struct SmoothView3DStore;
struct wmTimer;
struct Material;
struct GPUFX;
+struct GPUSSR;
/* This is needed to not let VC choke on near and far... old
* proprietary MS extensions... */
@@ -238,6 +239,11 @@ typedef struct View3D {
float stereo3d_volume_alpha;
float stereo3d_convergence_alpha;
+ /* Pbr */
+ struct Object *probe_source; /* runtime : the probe that is being updated when V3D_PROBE_CAPTURE */
+ struct GPUPBRSettings pbr_settings;
+ struct GPUPBR *pbr; /* holds all pbr specific textures */
+
/* Previous viewport draw type.
* Runtime-only, set in the rendered viewport toggle operator.
*/
@@ -319,6 +325,10 @@ typedef struct View3D {
/* View3d->flag3 (short) */
#define V3D_SHOW_WORLD (1 << 0)
+#define V3D_SHOW_WORLD_DIFFUSE (1 << 1)
+/*#define V3D_REALISTIC_MAT (1 << 2)*/ /* UNUSED */
+#define V3D_PROBE_CAPTURE (1 << 3) /* runtime flag */
+#define V3D_FLIP_NORMALS (1 << 4) /* invert culling during reflection pass */
/* View3D->around */
enum {
diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h
index 5fd4c9fd407..ecfe53cae12 100644
--- a/source/blender/makesdna/DNA_world_types.h
+++ b/source/blender/makesdna/DNA_world_types.h
@@ -129,6 +129,12 @@ typedef struct World {
struct bNodeTree *nodetree;
ListBase gpumaterial; /* runtime */
+ ListBase gpuprobe; /* runtime */
+
+ char probeflags, pad2[3];
+
+ unsigned int probesize, probeshres;
+ float pad3;
} World;
/* **************** WORLD ********************* */
@@ -200,5 +206,11 @@ enum {
*/
#define WO_DS_SHOW_TEXS (1<<2)
+/* (short) probeflags */
+enum {
+ WO_PROBE_AUTO_UPDATE = 1 << 0,
+ WO_PROBE_COMPUTE_SH = 1 << 1,
+};
+
#endif
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 24f2d8174af..6351b4ebeeb 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -434,10 +434,13 @@ static EnumPropertyItem *rna_ColorManagedDisplaySettings_display_device_itemf(
return items;
}
-static void rna_ColorManagedDisplaySettings_display_device_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+static void rna_ColorManagedDisplaySettings_display_device_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
{
ID *id = ptr->id.data;
+ ColorManagedDisplaySettings *display_settings = &scene->display_settings;
+ display_settings->lut_is_outdated = 1;
+
if (!id)
return;
@@ -655,9 +658,12 @@ static char *rna_ColorManagedInputColorspaceSettings_path(PointerRNA *UNUSED(ptr
return BLI_sprintfN("colorspace_settings");
}
-static void rna_ColorManagement_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+static void rna_ColorManagement_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
{
ID *id = ptr->id.data;
+
+ ColorManagedViewSettings *view_settings = &scene->view_settings;
+ view_settings->lut_is_outdated = 1;
if (!id)
return;
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index 6530e0938f6..2d967e544d6 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -246,7 +246,7 @@ static int rna_Image_gl_load(Image *image, ReportList *reports, int frame, int f
}
GPU_create_gl_tex(bind, ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y, GL_TEXTURE_2D,
- (filter != GL_NEAREST && filter != GL_LINEAR), false, image);
+ (filter != GL_NEAREST && filter != GL_LINEAR), false, image, false);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLint)filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLint)mag);
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 2cbf23973c2..194bb1eaa14 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -53,6 +53,7 @@
#include "RNA_enum_types.h"
#include "rna_internal.h"
+#include "GPU_shader.h" /* needed for MAX_SH_SAMPLES */
#include "BLI_sys_types.h" /* needed for intptr_t used in ED_mesh.h */
#include "ED_mesh.h"
@@ -197,11 +198,88 @@ EnumPropertyItem rna_enum_object_axis_items[] = {
#include "ED_curve.h"
#include "ED_lattice.h"
+
static void rna_Object_internal_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
DAG_id_tag_update(ptr->id.data, OB_RECALC_OB);
}
+static int rna_Object_probe_object_poll(PointerRNA *ptr, PointerRNA value)
+{
+ Object *ob = (Object *)ptr->id.data;
+ Object *probe = (Object *)value.data;
+
+ if (probe) {
+ if (probe->probetype == OB_PROBE_CUBEMAP || probe->probetype == OB_PROBE_PLANAR) {
+ if (probe != ob) {
+ if (ob->probetype == OB_PROBE_PLANAR) {
+ if (probe->probetype == OB_PROBE_CUBEMAP)
+ return 1;
+ }
+ else {
+ return 1;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static PointerRNA rna_Object_probe_object_get(PointerRNA *ptr)
+{
+ Object *ob = (Object *)ptr->id.data;
+ Object *probe = ob->probe;
+
+ if (probe)
+ return rna_pointer_inherit_refine(ptr, &RNA_Object, probe);
+
+ return rna_pointer_inherit_refine(ptr, NULL, NULL);
+}
+
+static void rna_Object_probe_object_set(PointerRNA *ptr, PointerRNA value)
+{
+ Object *ob = (Object *)ptr->id.data;
+ Object *probe = (Object *)value.data;
+
+ if (probe) {
+ if (probe->probetype == OB_PROBE_CUBEMAP || probe->probetype == OB_PROBE_PLANAR) {
+ if (probe != ob) {
+ ob->probe = probe;
+ id_lib_extern((ID *)probe);
+ }
+ }
+ }
+ else {
+ ob->probe = NULL;
+ }
+}
+
+static void rna_Object_probe_sh_res_set(PointerRNA *ptr, int value)
+{
+ Object *ob = (Object *)ptr->id.data;
+
+ CLAMP(value, 1, (1 << MAX_SH_SAMPLES));
+ CLAMP_MAX(value, ob->probesize);
+ /* Jumping to next value based on difference so user can use UI */
+ if (value < ob->probeshres)
+ ob->probeshres = power_of_2_min_u(value);
+ else
+ ob->probeshres = power_of_2_max_u(value);
+}
+
+static void rna_Object_probe_size_set(PointerRNA *ptr, int value)
+{
+ Object *ob = (Object *)ptr->id.data;
+
+ CLAMP(value, 16, 10240);
+ ob->probesize = value;
+ ob->probesize &= (~15); /* round to multiple of 16 */
+
+ if (ob->probeshres > ob->probesize)
+ rna_Object_probe_sh_res_set(ptr, ob->probesize);
+}
+
static void rna_Object_matrix_world_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
/* don't use compat so we get predictable rotation */
@@ -2200,7 +2278,22 @@ static void rna_def_object(BlenderRNA *brna)
"Axis Angle (W+XYZ), defines a rotation around some axis defined by 3D-Vector"},
{0, NULL, 0, NULL, NULL}
};
+
+ static EnumPropertyItem probemode_items[] = {
+ {0, "NONE", 0, "None", "No probe capture"},
+ {OB_PROBE_OBJECT, "OBJECT", 0, "Object", "Use another object as probe"},
+ {OB_PROBE_CUBEMAP, "CUBE", 0, "Cubemap", "Capture environment in all direction from the object center"},
+ {OB_PROBE_PLANAR, "PLANE", 0, "Planar", "Capture environment from the symmetry camera to the XY axis plane of the object"},
+ {0, NULL, 0, NULL, NULL}
+ };
+ static EnumPropertyItem probeparallaxmode_items[] = {
+ {0, "NONE", 0, "None", "No parallax correction"},
+ {OB_PROBE_PARRALAX_ELLIPSOID, "ELLIPSOID", 0, "Ellipsoid", "Use object bounding ellipsoid for parallax correction"},
+ {OB_PROBE_PARRALAX_BOX, "BOX", 0, "Cube", "Use object bounding box for parallax correction"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
static float default_quat[4] = {1, 0, 0, 0}; /* default quaternion values */
static float default_axisAngle[4] = {0, 0, 1, 0}; /* default axis-angle rotation values */
static float default_scale[3] = {1, 1, 1}; /* default scale values */
@@ -2837,6 +2930,97 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Level of Detail Levels", "A collection of detail levels to automatically switch between");
RNA_def_property_update(prop, NC_OBJECT | ND_LOD, NULL);
+ /* Viewport Probe */
+ prop = RNA_def_property(srna, "probe_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "probetype");
+ RNA_def_property_enum_items(prop, probemode_items);
+ RNA_def_property_ui_text(prop, "Probe Capture Type", "Type of capture for to use for the BSDFs");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+
+ prop = RNA_def_property(srna, "probe_object", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_pointer_sdna(prop, NULL, "probe");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Probe Object",
+ "Probe object that defines the environment for the BSDFs of this object's materials");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
+ RNA_def_property_pointer_funcs(prop, "rna_Object_probe_object_get", "rna_Object_probe_object_set", NULL,
+ "rna_Object_probe_object_poll");
+
+ prop = RNA_def_property(srna, "probe_reflection_plane", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_pointer_sdna(prop, NULL, "reflectionplane");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Reflection Plane",
+ "Use this object XY plane as the symmetry plane for the reflected camera");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
+
+ prop = RNA_def_property(srna, "probe_parallax_volume", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_pointer_sdna(prop, NULL, "parallaxcorrect");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Parallax Volume",
+ "Use object bounds to correct reflection & refraction rays");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
+
+ prop = RNA_def_property(srna, "probe_parallax_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "probeparallax");
+ RNA_def_property_enum_items(prop, probeparallaxmode_items);
+ RNA_def_property_ui_text(prop, "Probe Parallax Type", "Parallax correction to apply to the rays");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
+
+ prop = RNA_def_property(srna, "probe_refresh_auto", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "probeflags", OB_PROBE_AUTO_UPDATE);
+ RNA_def_property_ui_text(prop, "Probe Auto Refresh", "Cube Only : Auto update when a change in the scene occurs");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
+
+ prop = RNA_def_property(srna, "probe_refresh_double", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "probeflags", OB_PROBE_DOUBLE_UPDATE);
+ RNA_def_property_ui_text(prop, "Probe Double Refresh", "Update the probe another time after all other probes have been updated");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
+
+ prop = RNA_def_property(srna, "probe_compute_sh", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "probeflags", OB_PROBE_COMPUTE_SH);
+ RNA_def_property_ui_text(prop, "Compute Diffuse", "Cube Only : Enable computation of diffuse lighting");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
+
+ prop = RNA_def_property(srna, "probe_use_layers", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "probeflags", OB_PROBE_USE_LAYERS);
+ RNA_def_property_ui_text(prop, "Use Object Layers", "Render only the objects in the same layers");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
+
+ prop = RNA_def_property(srna, "probe_size", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "probesize");
+ RNA_def_property_range(prop, 16, 2048);
+ RNA_def_property_ui_text(prop, "Reflection Quality", "Resolution of the probe buffer texture");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
+ RNA_def_property_int_funcs(prop, NULL, "rna_Object_probe_size_set", NULL);
+
+ prop = RNA_def_property(srna, "probe_sh_quality", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "probeshres");
+ RNA_def_property_range(prop, 1, (1 << MAX_SH_SAMPLES));
+ RNA_def_property_ui_text(prop, "Diffuse Quality", "Cube Only : Resolution of the diffuse precomputation.");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
+ RNA_def_property_int_funcs(prop, NULL, "rna_Object_probe_sh_res_set", NULL);
+
+ prop = RNA_def_property(srna, "probe_clip_start", PROP_FLOAT, PROP_NONE | PROP_UNIT_LENGTH);
+ RNA_def_property_float_sdna(prop, NULL, "probeclipsta");
+ RNA_def_property_range(prop, 0.0001f, 999999.9f);
+ RNA_def_property_ui_text(prop, "Clip Start", "Capture camera near clip plane");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
+
+ prop = RNA_def_property(srna, "probe_clip_end", PROP_FLOAT, PROP_NONE | PROP_UNIT_LENGTH);
+ RNA_def_property_float_sdna(prop, NULL, "probeclipend");
+ RNA_def_property_range(prop, 0.0001f, 999999.9f);
+ RNA_def_property_ui_text(prop, "Clip End", "Capture camera end clip plane");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
+
+ prop = RNA_def_property(srna, "probe_clip_bias", PROP_FLOAT, PROP_NONE | PROP_UNIT_LENGTH);
+ RNA_def_property_float_sdna(prop, NULL, "probeclipbias");
+ RNA_def_property_range(prop, 0.0f, 999999.9f);
+ RNA_def_property_ui_text(prop, "Clip Bias", "Bias applied to the clip plane");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
+
RNA_api_object(srna);
}
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index f2a1e0a50ab..fef9435b567 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -4842,8 +4842,12 @@ static void rna_def_gpu_ssao_fx(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Color", "Color for screen space ambient occlusion effect");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-}
+ prop = RNA_def_property(srna, "steps", PROP_INT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Steps", "Number of steps per samples. Helps detecting thin objects when using a large occlusion distance.");
+ RNA_def_property_range(prop, 1, 16);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+}
static void rna_def_gpu_fx(BlenderRNA *brna)
{
@@ -4878,6 +4882,12 @@ static void rna_def_gpu_fx(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "fx_flag", GPU_FX_FLAG_SSAO);
RNA_def_property_ui_text(prop, "SSAO", "Use screen space ambient occlusion of field on viewport");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPUFXSettings_fx_update");
+
+
+ prop = RNA_def_property(srna, "use_colormanagement", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "fx_flag2", GPU_FX_FLAG_COLORMANAGEMENT);
+ RNA_def_property_ui_text(prop, "Color Management", "Use color management on viewport");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPUFXSettings_fx_update");
}
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 1c8d4a4c818..074fc9f68bd 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -46,6 +46,8 @@
#include "DNA_mask_types.h"
#include "DNA_view3d_types.h"
+#include "GPU_pbr.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
@@ -526,6 +528,23 @@ static void rna_SpaceView3D_viewport_shade_update(Main *bmain, Scene *scene, Poi
ED_view3d_shade_update(bmain, scene, v3d, sa);
}
+static void rna_SpaceView3D_viewport_real_shading_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ View3D *v3d = (View3D *)(ptr->data);
+ ScrArea *sa = rna_area_from_space(ptr);
+ GPU_materials_free();
+ ED_view3d_shade_update(bmain, scene, v3d, sa);
+}
+
+static void rna_SpaceView3D_world_background_shader_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ View3D *v3d = (View3D *)(ptr->data);
+ ScrArea *sa = rna_area_from_space(ptr);
+ World *world = scene->world;
+ GPU_material_free(&world->gpumaterial);
+ ED_view3d_shade_update(bmain, scene, v3d, sa);
+}
+
static void rna_SpaceView3D_matcap_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
View3D *v3d = (View3D *)(ptr->data);
@@ -733,6 +752,15 @@ static EnumPropertyItem *rna_SpaceView3D_stereo3d_camera_itemf(bContext *UNUSED(
return stereo3d_camera_items;
}
+
+static void rna_GPUPBRSettings_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ GPUPBRSettings *pbr_settings = ptr->data;
+
+ GPU_pbr_settings_validate(pbr_settings);
+}
+
+
/* Space Image Editor */
static PointerRNA rna_SpaceImageEditor_uvedit_get(PointerRNA *ptr)
@@ -2297,6 +2325,108 @@ static void rna_def_backgroundImages(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_ui_description(func, "Remove all background images");
}
+static void rna_def_gpu_pbr_brdf(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "GPUBRDFSettings", NULL);
+ RNA_def_struct_ui_text(srna, "GPU Sampling", "Settings for GLSL materials and lights sampling");
+ RNA_def_struct_ui_icon(srna, ICON_MATERIAL);
+
+ prop = RNA_def_property(srna, "lodbias", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Bias", "Bias the LOD sampled by the ray. Higher values give more correct but noisy results.");
+ RNA_def_property_range(prop, -100.0f, 100.0f);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Quality", "Define the quality of brdfs sampling.");
+ RNA_def_property_range(prop, 1, 1024);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+}
+
+static void rna_def_gpu_pbr_ssr(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "GPUSSRSettings", NULL);
+ RNA_def_struct_ui_text(srna, "GPU SSR", "Settings for GPU based screen space reflections");
+ RNA_def_struct_ui_icon(srna, ICON_MATERIAL);
+
+ prop = RNA_def_property(srna, "attenuation", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Attenuation", "Attenuation for distance and screen border fade");
+ RNA_def_property_range(prop, 1.0f, 20.0f);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "thickness", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Thickness", "If Backface Buffer is off, tells how thick a pixel is when searching for intersections.");
+ RNA_def_property_range(prop, 0.00001f, 100000.0f);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "steps", PROP_INT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Steps", "Number of pixels to travel for searching intersections");
+ RNA_def_property_range(prop, 1, 256);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+}
+
+static void rna_def_gpu_pbr(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ rna_def_gpu_pbr_brdf(brna);
+ rna_def_gpu_pbr_ssr(brna);
+
+ srna = RNA_def_struct(brna, "GPUPBRSettings", NULL);
+ RNA_def_struct_ui_text(srna, "GPU PBR Settings", "Settings for GLSL PBR materials");
+ RNA_def_struct_ui_icon(srna, ICON_MATERIAL);
+
+ /* BRDF */
+ prop = RNA_def_property(srna, "brdf", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "GPUBRDFSettings");
+ RNA_def_property_ui_text(prop, "PBR Sampling settings", "");
+
+ prop = RNA_def_property(srna, "use_realistic_mat", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "pbr_flag", GPU_PBR_FLAG_ENABLE);
+ RNA_def_property_ui_text(prop, "Realistic Material Preview", "Use a more accurate preview of the shaders in the viewport");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPUPBRSettings_update");
+
+ /* SSR */
+ prop = RNA_def_property(srna, "ssr", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "GPUSSRSettings");
+ RNA_def_property_ui_text(prop, "Screen Space Reflections settings", "");
+
+ prop = RNA_def_property(srna, "use_ssr", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "pbr_flag", GPU_PBR_FLAG_SSR);
+ RNA_def_property_ui_text(prop, "Screen Space Reflections", "Use screen data to reflect objects");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPUPBRSettings_update");
+
+ /* SSAO */
+ prop = RNA_def_property(srna, "ssao", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "GPUSSAOSettings");
+ RNA_def_property_ui_text(prop, "Screen Space Ambient Occlusion settings", "");
+
+ prop = RNA_def_property(srna, "use_ssao", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "pbr_flag", GPU_PBR_FLAG_SSAO);
+ RNA_def_property_ui_text(prop, "Material Ambient Occlusion", "Use Material Ambient Occlusion");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPUPBRSettings_update");
+
+ /* Backface buffer */
+ prop = RNA_def_property(srna, "use_backface", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "pbr_flag", GPU_PBR_FLAG_BACKFACE);
+ RNA_def_property_ui_text(prop, "Use Backface Buffer", "Enable the calculation of pixel thickness");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPUPBRSettings_update");
+
+ /* Material Override */
+ prop = RNA_def_property(srna, "use_layer_override", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "pbr_flag", GPU_PBR_FLAG_LAYER_OVERRIDE);
+ RNA_def_property_ui_text(prop, "Render Layer Override", "Use render layer override");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPUPBRSettings_update");
+}
static void rna_def_space_view3d(BlenderRNA *brna)
{
@@ -2567,6 +2697,11 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "World Background", "Display world colors in the background");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ prop = RNA_def_property(srna, "show_world_sh", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag3", V3D_SHOW_WORLD_DIFFUSE);
+ RNA_def_property_ui_text(prop, "Use Diffuse Background", "Show diffuse world lighting in the background");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_world_background_shader_update");
+
prop = RNA_def_property(srna, "use_occlude_geometry", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_ZBUF_SELECT);
RNA_def_property_ui_text(prop, "Occlude Geometry", "Limit selection to visible (clipped with depth buffer)");
@@ -2706,6 +2841,10 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "FX Options", "Options used for real time compositing");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ prop = RNA_def_property(srna, "pbr_settings", PROP_POINTER, PROP_NONE);
+ RNA_def_property_ui_text(prop, "PBR Options", "Options used for advance glsl shading");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
/* Stereo Settings */
prop = RNA_def_property(srna, "stereo_3d_eye", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "multiview_eye");
@@ -4737,6 +4876,8 @@ static void rna_def_space_clip(BlenderRNA *brna)
void RNA_def_space(BlenderRNA *brna)
{
+ rna_def_gpu_pbr(brna);
+
rna_def_space(brna);
rna_def_space_image(brna);
rna_def_space_sequencer(brna);
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index 7c1ef6b0d87..2f9d21106cd 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -36,6 +36,8 @@
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
+#include "GPU_shader.h" /* needed for MAX_SH_SAMPLES */
+
#include "WM_types.h"
#ifdef RNA_RUNTIME
@@ -47,6 +49,8 @@
#include "BKE_main.h"
#include "BKE_texture.h"
+#include "BLI_math_base.h"
+
#include "ED_node.h"
#include "WM_api.h"
@@ -56,6 +60,30 @@ static PointerRNA rna_World_lighting_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_WorldLighting, ptr->id.data);
}
+static void rna_World_probe_sh_res_set(PointerRNA *ptr, int value)
+{
+ World *wo = (World *)ptr->id.data;
+
+ CLAMP(value, 1, (1 << MAX_SH_SAMPLES));
+ CLAMP_MAX(value, wo->probesize);
+ /* Jumping to next value based on difference so user can use UI */
+ if (value < wo->probeshres)
+ wo->probeshres = power_of_2_min_u(value);
+ else
+ wo->probeshres = power_of_2_max_u(value);
+}
+
+static void rna_World_probe_size_set(PointerRNA *ptr, int value)
+{
+ World *wo = (World *)ptr->id.data;
+
+ CLAMP(value, 16, 10240);
+ wo->probesize = value;
+ wo->probesize &= (~15); /* round to multiple of 16 */
+
+ if (wo->probeshres > wo->probesize)
+ rna_World_probe_sh_res_set(ptr, wo->probesize);
+}
static PointerRNA rna_World_mist_get(PointerRNA *ptr)
{
@@ -529,6 +557,31 @@ void RNA_def_world(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Use Nodes", "Use shader nodes to render the world");
RNA_def_property_update(prop, 0, "rna_World_use_nodes_update");
+ /* viewport probes */
+ prop = RNA_def_property(srna, "probe_refresh_auto", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "probeflags", WO_PROBE_AUTO_UPDATE);
+ RNA_def_property_ui_text(prop, "Probe Auto Refresh", "Auto update");
+ RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update");
+
+ prop = RNA_def_property(srna, "probe_compute_sh", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "probeflags", WO_PROBE_COMPUTE_SH);
+ RNA_def_property_ui_text(prop, "Compute Diffuse", "Enable computation of diffuse lighting");
+ RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update");
+
+ prop = RNA_def_property(srna, "probe_size", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "probesize");
+ RNA_def_property_range(prop, 16, 2048);
+ RNA_def_property_ui_text(prop, "Buffer Size", "Resolution of the probe buffer texture");
+ RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update");
+ RNA_def_property_int_funcs(prop, NULL, "rna_World_probe_size_set", NULL);
+
+ prop = RNA_def_property(srna, "probe_sh_quality", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "probeshres");
+ RNA_def_property_range(prop, 1, (1 << MAX_SH_SAMPLES));
+ RNA_def_property_ui_text(prop, "Irradiance Precision", "Resolution of the diffuse precomputation. Should not be higher than the buffer size");
+ RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update");
+ RNA_def_property_int_funcs(prop, NULL, "rna_World_probe_sh_res_set", NULL);
+
rna_def_lighting(brna);
rna_def_world_mist(brna);
rna_def_world_mtex(brna);
diff --git a/source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.c b/source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.c
index 878f8562619..a3e3b97be2e 100644
--- a/source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.c
+++ b/source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.c
@@ -39,9 +39,37 @@ static bNodeSocketTemplate sh_node_ambient_occlusion_out[] = {
{ -1, 0, "" }
};
+#define IN_COLOR 0
+
+/* XXX this is also done as a local static function in gpu_codegen.c,
+ * but we need this to hack around the crappy material node.
+ */
+static GPUNodeLink *gpu_get_input_link(GPUNodeStack *in)
+{
+ if (in->link)
+ return in->link;
+ else
+ return GPU_uniform(in->vec);
+}
+
static int node_shader_gpu_ambient_occlusion(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- return GPU_stack_link(mat, "node_ambient_occlusion", in, out, GPU_builtin(GPU_VIEW_NORMAL));
+ if (GPU_material_get_type(mat) == GPU_MATERIAL_TYPE_MESH_REAL_SH) {
+ GPUBrdfInput brdf;
+
+ GPU_brdf_input_initialize(&brdf);
+
+ brdf.mat = mat;
+ brdf.color = gpu_get_input_link(&in[IN_COLOR]);
+ brdf.type = GPU_BRDF_AMBIENT_OCCLUSION;
+
+ GPU_shade_BRDF(&brdf);
+
+ out[0].link = brdf.output;
+ return 1;
+ }
+ else
+ return GPU_stack_link(mat, "node_ambient_occlusion", in, out);
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_blackbody.c b/source/blender/nodes/shader/nodes/node_shader_blackbody.c
index af89a959554..449709c6825 100644
--- a/source/blender/nodes/shader/nodes/node_shader_blackbody.c
+++ b/source/blender/nodes/shader/nodes/node_shader_blackbody.c
@@ -38,6 +38,11 @@ static bNodeSocketTemplate sh_node_blackbody_out[] = {
{ -1, 0, "" }
};
+static int node_gpu_blackbody(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ return GPU_stack_link(mat, "node_blackbody", in, out);
+}
+
/* node type definition */
void register_node_type_sh_blackbody(void)
{
@@ -49,6 +54,7 @@ void register_node_type_sh_blackbody(void)
node_type_socket_templates(&ntype, sh_node_blackbody_in, sh_node_blackbody_out);
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
+ node_type_gpu(&ntype, node_gpu_blackbody);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c
index 01ca0bd6512..ba53ec3d3ec 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c
@@ -44,21 +44,73 @@ static bNodeSocketTemplate sh_node_bsdf_anisotropic_out[] = {
{ -1, 0, "" }
};
+#define IN_COLOR 0
+#define IN_ROUGHNESS 1
+#define IN_ANISOTROPY 2
+#define IN_ROTATION 3
+#define IN_NORMAL 4
+#define IN_TANGENT 5
+
static void node_shader_init_anisotropic(bNodeTree *UNUSED(ntree), bNode *node)
{
node->custom1 = SHD_GLOSSY_GGX;
}
-static int node_shader_gpu_bsdf_anisotropic(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+/* XXX this is also done as a local static function in gpu_codegen.c,
+ * but we need this to hack around the crappy material node.
+ */
+static GPUNodeLink *gpu_get_input_link(GPUNodeStack *in)
{
- if (!in[4].link)
- in[4].link = GPU_builtin(GPU_VIEW_NORMAL);
+ if (in->link)
+ return in->link;
else
- GPU_link(mat, "direction_transform_m4v3", in[4].link, GPU_builtin(GPU_VIEW_MATRIX), &in[4].link);
-
- return GPU_stack_link(mat, "node_bsdf_anisotropic", in, out);
+ return GPU_uniform(in->vec);
}
+static int node_shader_gpu_bsdf_anisotropic(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ if (!in[IN_NORMAL].link)
+ in[IN_NORMAL].link = GPU_builtin(GPU_VIEW_NORMAL);
+ else {
+ /* Convert to view space normal in case a Normal is plugged. This is because cycles uses world normals */
+ GPU_link(mat, "direction_transform_m4v3", in[IN_NORMAL].link, GPU_builtin(GPU_VIEW_MATRIX), &in[IN_NORMAL].link);
+ }
+
+ if (!in[IN_TANGENT].link)
+ GPU_link(mat, "default_tangent", GPU_builtin(GPU_VIEW_NORMAL), GPU_attribute(CD_ORCO, ""), GPU_builtin(GPU_OBJECT_MATRIX), GPU_builtin(GPU_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &in[IN_TANGENT].link);
+ else {
+ GPU_link(mat, "direction_transform_m4v3", in[IN_TANGENT].link, GPU_builtin(GPU_VIEW_MATRIX), &in[IN_TANGENT].link);
+ }
+
+ if (GPU_material_get_type(mat) == GPU_MATERIAL_TYPE_MESH_REAL_SH) {
+ GPUBrdfInput brdf;
+
+ GPU_brdf_input_initialize(&brdf);
+
+ brdf.mat = mat;
+ brdf.type = GPU_BRDF_ANISO_GGX;
+ brdf.color = gpu_get_input_link(&in[IN_COLOR]);
+ brdf.roughness = gpu_get_input_link(&in[IN_ROUGHNESS]);
+ brdf.anisotropy = gpu_get_input_link(&in[IN_ANISOTROPY]);
+ brdf.aniso_rotation = gpu_get_input_link(&in[IN_ROTATION]);
+ brdf.normal = gpu_get_input_link(&in[IN_NORMAL]);
+ brdf.aniso_tangent = gpu_get_input_link(&in[IN_TANGENT]);
+
+ if (node->custom1 == SHD_GLOSSY_BECKMANN)
+ brdf.type = GPU_BRDF_ANISO_BECKMANN;
+ else if (node->custom1 == SHD_GLOSSY_ASHIKHMIN_SHIRLEY)
+ brdf.type = GPU_BRDF_ANISO_ASHIKHMIN_SHIRLEY;
+ else
+ brdf.type = GPU_BRDF_ANISO_GGX;
+
+ GPU_shade_BRDF(&brdf);
+
+ out[0].link = brdf.output;
+ return 1;
+ }
+ else
+ return GPU_stack_link(mat, "node_bsdf_anisotropic_lights", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_get_world_horicol());}
+
/* node type definition */
void register_node_type_sh_bsdf_anisotropic(void)
{
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c
index e86d2677a61..e1b1df743e7 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c
@@ -26,6 +26,10 @@
*/
#include "../node_shader_util.h"
+#include "BKE_node.h"
+#include "BKE_scene.h"
+#include "GPU_material.h"
+
/* **************** OUTPUT ******************** */
@@ -36,19 +40,53 @@ static bNodeSocketTemplate sh_node_bsdf_diffuse_in[] = {
{ -1, 0, "" }
};
+#define IN_COLOR 0
+#define IN_ROUGHNESS 1
+#define IN_NORMAL 2
+
static bNodeSocketTemplate sh_node_bsdf_diffuse_out[] = {
{ SOCK_SHADER, 0, N_("BSDF")},
{ -1, 0, "" }
};
-static int node_shader_gpu_bsdf_diffuse(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+/* XXX this is also done as a local static function in gpu_codegen.c,
+ * but we need this to hack around the crappy material node.
+ */
+static GPUNodeLink *gpu_get_input_link(GPUNodeStack *in)
{
- if (!in[2].link)
- in[2].link = GPU_builtin(GPU_VIEW_NORMAL);
+ if (in->link)
+ return in->link;
else
- GPU_link(mat, "direction_transform_m4v3", in[2].link, GPU_builtin(GPU_VIEW_MATRIX), &in[2].link);
+ return GPU_uniform(in->vec);
+}
- return GPU_stack_link(mat, "node_bsdf_diffuse", in, out);
+static int node_shader_gpu_bsdf_diffuse(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ if (!in[IN_NORMAL].link)
+ in[IN_NORMAL].link = GPU_builtin(GPU_VIEW_NORMAL);
+ else {
+ /* Convert to view space normal in case a Normal is plugged. This is because cycles uses world normals */
+ GPU_link(mat, "direction_transform_m4v3", in[IN_NORMAL].link, GPU_builtin(GPU_VIEW_MATRIX), &in[IN_NORMAL].link);
+ }
+
+ if (GPU_material_get_type(mat) == GPU_MATERIAL_TYPE_MESH_REAL_SH) {
+ GPUBrdfInput brdf;
+
+ GPU_brdf_input_initialize(&brdf);
+
+ brdf.mat = mat;
+ brdf.type = GPU_BRDF_DIFFUSE;
+ brdf.color = gpu_get_input_link(&in[IN_COLOR]);
+ brdf.roughness = gpu_get_input_link(&in[IN_ROUGHNESS]);
+ brdf.normal = gpu_get_input_link(&in[IN_NORMAL]);
+
+ GPU_shade_BRDF(&brdf);
+
+ out[0].link = brdf.output;
+ return 1;
+ }
+ else
+ return GPU_stack_link(mat, "node_bsdf_diffuse_lights", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_get_world_horicol());
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c
index 5569fe85489..009f3b984d0 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c
@@ -26,6 +26,10 @@
*/
#include "../node_shader_util.h"
+#include "BKE_node.h"
+#include "BKE_scene.h"
+#include "GPU_material.h"
+#include "DNA_material_types.h"
/* **************** OUTPUT ******************** */
@@ -42,19 +46,62 @@ static bNodeSocketTemplate sh_node_bsdf_glass_out[] = {
{ -1, 0, "" }
};
+#define IN_COLOR 0
+#define IN_ROUGHNESS 1
+#define IN_IOR 2
+#define IN_NORMAL 3
+
static void node_shader_init_glass(bNodeTree *UNUSED(ntree), bNode *node)
{
node->custom1 = SHD_GLOSSY_BECKMANN;
}
-static int node_shader_gpu_bsdf_glass(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+/* XXX this is also done as a local static function in gpu_codegen.c,
+ * but we need this to hack around the crappy material node.
+ */
+static GPUNodeLink *gpu_get_input_link(GPUNodeStack *in)
{
- if (!in[3].link)
- in[3].link = GPU_builtin(GPU_VIEW_NORMAL);
+ if (in->link)
+ return in->link;
else
- GPU_link(mat, "direction_transform_m4v3", in[3].link, GPU_builtin(GPU_VIEW_MATRIX), &in[3].link);
+ return GPU_uniform(in->vec);
+}
+
+static int node_shader_gpu_bsdf_glass(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ if (!in[IN_NORMAL].link)
+ in[IN_NORMAL].link = GPU_builtin(GPU_VIEW_NORMAL);
+ else {
+ /* Convert to view space normal in case a Normal is plugged. This is because cycles uses world normals */
+ GPU_link(mat, "direction_transform_m4v3", in[IN_NORMAL].link, GPU_builtin(GPU_VIEW_MATRIX), &in[IN_NORMAL].link);
+ }
+
+ if (GPU_material_get_type(mat) == GPU_MATERIAL_TYPE_MESH_REAL_SH) {
+ GPUBrdfInput brdf;
- return GPU_stack_link(mat, "node_bsdf_glass", in, out);
+ GPU_brdf_input_initialize(&brdf);
+
+ /* Refraction */
+ brdf.mat = mat;
+ brdf.color = gpu_get_input_link(&in[IN_COLOR]);
+ brdf.roughness = gpu_get_input_link(&in[IN_ROUGHNESS]);
+ brdf.ior = gpu_get_input_link(&in[IN_IOR]);
+ brdf.normal = gpu_get_input_link(&in[IN_NORMAL]);
+
+ if (node->custom1 == SHD_GLOSSY_BECKMANN)
+ brdf.type = GPU_BRDF_GLASS_BECKMANN;
+ else if (node->custom1 == SHD_GLOSSY_GGX)
+ brdf.type = GPU_BRDF_GLASS_GGX;
+ else
+ brdf.type = GPU_BRDF_GLASS_SHARP;
+
+ GPU_shade_BRDF(&brdf);
+
+ out[0].link = brdf.output;
+ return 1;
+ }
+ else
+ return GPU_stack_link(mat, "node_bsdf_glass_lights", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_get_world_horicol());
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c
index 7e1bc971c73..c0a0231305b 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c
@@ -26,6 +26,10 @@
*/
#include "../node_shader_util.h"
+#include "BKE_node.h"
+#include "BKE_scene.h"
+#include "GPU_material.h"
+#include "DNA_material_types.h"
/* **************** OUTPUT ******************** */
@@ -36,6 +40,10 @@ static bNodeSocketTemplate sh_node_bsdf_glossy_in[] = {
{ -1, 0, "" }
};
+#define IN_COLOR 0
+#define IN_ROUGHNESS 1
+#define IN_NORMAL 2
+
static bNodeSocketTemplate sh_node_bsdf_glossy_out[] = {
{ SOCK_SHADER, 0, N_("BSDF")},
{ -1, 0, "" }
@@ -46,14 +54,52 @@ static void node_shader_init_glossy(bNodeTree *UNUSED(ntree), bNode *node)
node->custom1 = SHD_GLOSSY_GGX;
}
-static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+/* XXX this is also done as a local static function in gpu_codegen.c,
+ * but we need this to hack around the crappy material node.
+ */
+static GPUNodeLink *gpu_get_input_link(GPUNodeStack *in)
{
- if (!in[2].link)
- in[2].link = GPU_builtin(GPU_VIEW_NORMAL);
+ if (in->link)
+ return in->link;
else
- GPU_link(mat, "direction_transform_m4v3", in[2].link, GPU_builtin(GPU_VIEW_MATRIX), &in[2].link);
+ return GPU_uniform(in->vec);
+}
+
+static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ if (!in[IN_NORMAL].link)
+ in[IN_NORMAL].link = GPU_builtin(GPU_VIEW_NORMAL);
+ else {
+ /* Convert to view space normal in case a Normal is plugged. This is because cycles uses world normals */
+ GPU_link(mat, "direction_transform_m4v3", in[IN_NORMAL].link, GPU_builtin(GPU_VIEW_MATRIX), &in[IN_NORMAL].link);
+ }
+
+ if (GPU_material_get_type(mat) == GPU_MATERIAL_TYPE_MESH_REAL_SH) {
+ GPUBrdfInput brdf;
+
+ GPU_brdf_input_initialize(&brdf);
+
+ brdf.mat = mat;
+ brdf.color = gpu_get_input_link(&in[IN_COLOR]);
+ brdf.roughness = gpu_get_input_link(&in[IN_ROUGHNESS]);
+ brdf.normal = gpu_get_input_link(&in[IN_NORMAL]);
+
+ if (node->custom1 == SHD_GLOSSY_BECKMANN)
+ brdf.type = GPU_BRDF_GLOSSY_BECKMANN;
+ else if (node->custom1 == SHD_GLOSSY_ASHIKHMIN_SHIRLEY)
+ brdf.type = GPU_BRDF_GLOSSY_ASHIKHMIN_SHIRLEY;
+ else if (node->custom1 == SHD_GLOSSY_GGX)
+ brdf.type = GPU_BRDF_GLOSSY_GGX;
+ else
+ brdf.type = GPU_BRDF_GLOSSY_SHARP;
+
+ GPU_shade_BRDF(&brdf);
- return GPU_stack_link(mat, "node_bsdf_glossy", in, out);
+ out[0].link = brdf.output;
+ return 1;
+ }
+ else
+ return GPU_stack_link(mat, "node_bsdf_glossy_lights", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_get_world_horicol());
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c
index c447f5de219..a282b3a1c74 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c
@@ -26,6 +26,10 @@
*/
#include "../node_shader_util.h"
+#include "BKE_node.h"
+#include "BKE_scene.h"
+#include "GPU_material.h"
+#include "DNA_material_types.h"
/* **************** OUTPUT ******************** */
@@ -42,19 +46,61 @@ static bNodeSocketTemplate sh_node_bsdf_refraction_out[] = {
{ -1, 0, "" }
};
+#define IN_COLOR 0
+#define IN_ROUGHNESS 1
+#define IN_IOR 2
+#define IN_NORMAL 3
+
static void node_shader_init_refraction(bNodeTree *UNUSED(ntree), bNode *node)
{
node->custom1 = SHD_GLOSSY_BECKMANN;
}
-static int node_shader_gpu_bsdf_refraction(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+/* XXX this is also done as a local static function in gpu_codegen.c,
+ * but we need this to hack around the crappy material node.
+ */
+static GPUNodeLink *gpu_get_input_link(GPUNodeStack *in)
{
- if (!in[3].link)
- in[3].link = GPU_builtin(GPU_VIEW_NORMAL);
+ if (in->link)
+ return in->link;
else
- GPU_link(mat, "direction_transform_m4v3", in[3].link, GPU_builtin(GPU_VIEW_MATRIX), &in[3].link);
+ return GPU_uniform(in->vec);
+}
+
+static int node_shader_gpu_bsdf_refraction(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ if (!in[IN_NORMAL].link)
+ in[IN_NORMAL].link = GPU_builtin(GPU_VIEW_NORMAL);
+ else {
+ /* Convert to view space normal in case a Normal is plugged. This is because cycles uses world normals */
+ GPU_link(mat, "direction_transform_m4v3", in[IN_NORMAL].link, GPU_builtin(GPU_VIEW_MATRIX), &in[IN_NORMAL].link);
+ }
+
+ if (GPU_material_get_type(mat) == GPU_MATERIAL_TYPE_MESH_REAL_SH) {
+ GPUBrdfInput brdf;
- return GPU_stack_link(mat, "node_bsdf_refraction", in, out);
+ GPU_brdf_input_initialize(&brdf);
+
+ brdf.mat = mat;
+ brdf.color = gpu_get_input_link(&in[IN_COLOR]);
+ brdf.roughness = gpu_get_input_link(&in[IN_ROUGHNESS]);
+ brdf.ior = gpu_get_input_link(&in[IN_IOR]);
+ brdf.normal = gpu_get_input_link(&in[IN_NORMAL]);
+
+ if (node->custom1 == SHD_GLOSSY_BECKMANN)
+ brdf.type = GPU_BRDF_REFRACT_BECKMANN;
+ else if (node->custom1 == SHD_GLOSSY_GGX)
+ brdf.type = GPU_BRDF_REFRACT_GGX;
+ else
+ brdf.type = GPU_BRDF_REFRACT_SHARP;
+
+ GPU_shade_BRDF(&brdf);
+
+ out[0].link = brdf.output;
+ return 1;
+ }
+ else
+ return GPU_stack_link(mat, "node_bsdf_refraction_lights", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_get_world_horicol());
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_toon.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_toon.c
index c3510beb470..8af3fe055e1 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_toon.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_toon.c
@@ -42,14 +42,54 @@ static bNodeSocketTemplate sh_node_bsdf_toon_out[] = {
{ -1, 0, "" }
};
-static int node_shader_gpu_bsdf_toon(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+#define IN_COLOR 0
+#define IN_SIZE 1
+#define IN_SMOOTH 2
+#define IN_NORMAL 3
+
+/* XXX this is also done as a local static function in gpu_codegen.c,
+ * but we need this to hack around the crappy material node.
+ */
+static GPUNodeLink *gpu_get_input_link(GPUNodeStack *in)
{
- if (!in[3].link)
- in[3].link = GPU_builtin(GPU_VIEW_NORMAL);
+ if (in->link)
+ return in->link;
else
- GPU_link(mat, "direction_transform_m4v3", in[3].link, GPU_builtin(GPU_VIEW_MATRIX), &in[3].link);
+ return GPU_uniform(in->vec);
+}
+
+static int node_shader_gpu_bsdf_toon(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ if (!in[IN_NORMAL].link)
+ in[IN_NORMAL].link = GPU_builtin(GPU_VIEW_NORMAL);
+ else {
+ /* Convert to view space normal in case a Normal is plugged. This is because cycles uses world normals */
+ GPU_link(mat, "direction_transform_m4v3", in[IN_NORMAL].link, GPU_builtin(GPU_VIEW_MATRIX), &in[IN_NORMAL].link);
+ }
+
+ if (GPU_material_get_type(mat) == GPU_MATERIAL_TYPE_MESH_REAL_SH) {
+ GPUBrdfInput brdf;
+
+ GPU_brdf_input_initialize(&brdf);
+
+ brdf.mat = mat;
+ brdf.type = (node->custom1 == SHD_TOON_DIFFUSE) ? GPU_BRDF_TOON_DIFFUSE : GPU_BRDF_TOON_GLOSSY;
+ brdf.color = gpu_get_input_link(&in[IN_COLOR]);
+ brdf.toon_size = gpu_get_input_link(&in[IN_SIZE]);
+ brdf.toon_smooth = gpu_get_input_link(&in[IN_SMOOTH]);
+ brdf.normal = gpu_get_input_link(&in[IN_NORMAL]);
+
+ GPU_shade_BRDF(&brdf);
- return GPU_stack_link(mat, "node_bsdf_toon", in, out);
+ out[0].link = brdf.output;
+ return 1;
+ }
+ else {
+ if (node->custom1 == SHD_TOON_DIFFUSE)
+ return GPU_stack_link(mat, "node_bsdf_toon_diffuse_lights", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_get_world_horicol());
+ else
+ return GPU_stack_link(mat, "node_bsdf_toon_glossy_lights", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_get_world_horicol());
+ }
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c
index 3b88d609cdb..5b8511e6df4 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c
@@ -26,6 +26,10 @@
*/
#include "../node_shader_util.h"
+#include "BKE_node.h"
+#include "BKE_scene.h"
+#include "GPU_material.h"
+#include "DNA_material_types.h"
/* **************** OUTPUT ******************** */
@@ -40,14 +44,49 @@ static bNodeSocketTemplate sh_node_bsdf_translucent_out[] = {
{ -1, 0, "" }
};
-static int node_shader_gpu_bsdf_translucent(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+#define IN_COLOR 0
+#define IN_NORMAL 1
+
+/* XXX this is also done as a local static function in gpu_codegen.c,
+ * but we need this to hack around the crappy material node.
+ */
+static GPUNodeLink *gpu_get_input_link(GPUNodeStack *in)
+{
+ if (in->link)
+ return in->link;
+ else
+ return GPU_uniform(in->vec);
+}
+
+static int node_shader_gpu_bsdf_translucent(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- if (!in[1].link)
- in[1].link = GPU_builtin(GPU_VIEW_NORMAL);
+ if (!in[IN_NORMAL].link)
+ in[IN_NORMAL].link = GPU_builtin(GPU_VIEW_NORMAL);
+ else {
+ /* Convert to view space normal in case a Normal is plugged. This is because cycles uses world normals */
+ GPU_link(mat, "direction_transform_m4v3", in[IN_NORMAL].link, GPU_builtin(GPU_VIEW_MATRIX), &in[IN_NORMAL].link);
+ }
+
+ if (GPU_material_get_type(mat) == GPU_MATERIAL_TYPE_MESH_REAL_SH) {
+ GPUBrdfInput brdf;
+ float zero = 0.0f;
+
+ GPU_brdf_input_initialize(&brdf);
+
+ brdf.mat = mat;
+ brdf.type = GPU_BRDF_TRANSLUCENT;
+ brdf.color = gpu_get_input_link(&in[IN_COLOR]);
+ brdf.normal = gpu_get_input_link(&in[IN_NORMAL]);
+ brdf.roughness = GPU_uniform(&zero);
+
+ GPU_shade_BRDF(&brdf);
+
+ out[0].link = brdf.output;
+ return 1;
+ }
else
- GPU_link(mat, "direction_transform_m4v3", in[1].link, GPU_builtin(GPU_VIEW_MATRIX), &in[1].link);
+ return GPU_stack_link(mat, "node_bsdf_translucent_lights", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_get_world_horicol());
- return GPU_stack_link(mat, "node_bsdf_translucent", in, out);
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.c
index 5cb50b00e1a..377ebeabd43 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.c
@@ -39,9 +39,38 @@ static bNodeSocketTemplate sh_node_bsdf_transparent_out[] = {
{ -1, 0, "" }
};
+#define IN_COLOR 0
+
+/* XXX this is also done as a local static function in gpu_codegen.c,
+ * but we need this to hack around the crappy material node.
+ */
+static GPUNodeLink *gpu_get_input_link(GPUNodeStack *in)
+{
+ if (in->link)
+ return in->link;
+ else
+ return GPU_uniform(in->vec);
+}
+
static int node_shader_gpu_bsdf_transparent(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- return GPU_stack_link(mat, "node_bsdf_transparent", in, out);
+ if (GPU_material_get_type(mat) == GPU_MATERIAL_TYPE_MESH_REAL_SH) {
+ GPUBrdfInput brdf;
+
+ GPU_brdf_input_initialize(&brdf);
+
+ brdf.mat = mat;
+ brdf.type = GPU_BRDF_TRANSPARENT;
+ brdf.color = gpu_get_input_link(&in[IN_COLOR]);
+
+ GPU_shade_BRDF(&brdf);
+
+ out[0].link = brdf.output;
+ return 1;
+ }
+ else {
+ return GPU_stack_link(mat, "node_bsdf_transparent", in, out, GPU_get_world_horicol());
+ }
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c
index ef3d52ecbce..46c0025f2f0 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c
@@ -41,14 +41,47 @@ static bNodeSocketTemplate sh_node_bsdf_velvet_out[] = {
{ -1, 0, "" }
};
-static int node_shader_gpu_bsdf_velvet(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+#define IN_COLOR 0
+#define IN_SIGMA 1
+#define IN_NORMAL 2
+
+/* XXX this is also done as a local static function in gpu_codegen.c,
+ * but we need this to hack around the crappy material node.
+ */
+static GPUNodeLink *gpu_get_input_link(GPUNodeStack *in)
{
- if (!in[2].link)
- in[2].link = GPU_builtin(GPU_VIEW_NORMAL);
+ if (in->link)
+ return in->link;
else
- GPU_link(mat, "direction_transform_m4v3", in[2].link, GPU_builtin(GPU_VIEW_MATRIX), &in[2].link);
+ return GPU_uniform(in->vec);
+}
- return GPU_stack_link(mat, "node_bsdf_velvet", in, out);
+static int node_shader_gpu_bsdf_velvet(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ if (!in[IN_NORMAL].link)
+ in[IN_NORMAL].link = GPU_builtin(GPU_VIEW_NORMAL);
+ else {
+ /* Convert to view space normal in case a Normal is plugged. This is because cycles uses world normals */
+ GPU_link(mat, "direction_transform_m4v3", in[IN_NORMAL].link, GPU_builtin(GPU_VIEW_MATRIX), &in[IN_NORMAL].link);
+ }
+ if (GPU_material_get_type(mat) == GPU_MATERIAL_TYPE_MESH_REAL_SH) {
+ GPUBrdfInput brdf;
+
+ GPU_brdf_input_initialize(&brdf);
+
+ brdf.mat = mat;
+ brdf.type = GPU_BRDF_VELVET;
+ brdf.color = gpu_get_input_link(&in[IN_COLOR]);
+ brdf.sigma = gpu_get_input_link(&in[IN_SIGMA]);
+ brdf.normal = gpu_get_input_link(&in[IN_NORMAL]);
+
+ GPU_shade_BRDF(&brdf);
+
+ out[0].link = brdf.output;
+ return 1;
+ }
+ else
+ return GPU_stack_link(mat, "node_bsdf_velvet_lights", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_get_world_horicol());
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_emission.c b/source/blender/nodes/shader/nodes/node_shader_emission.c
index 51b3d5740a7..df4771f2107 100644
--- a/source/blender/nodes/shader/nodes/node_shader_emission.c
+++ b/source/blender/nodes/shader/nodes/node_shader_emission.c
@@ -42,6 +42,14 @@ static bNodeSocketTemplate sh_node_emission_out[] = {
static int node_shader_gpu_emission(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
+ float factor = 0.01f;
+
+ if (!in[0].link)
+ in[0].link = GPU_uniform(in[0].vec);
+
+ if ( GPU_material_get_type(mat) == GPU_MATERIAL_TYPE_LAMP )
+ GPU_link(mat, "shade_mul_value", GPU_uniform(&factor), in[0].link, &in[0].link);
+
return GPU_stack_link(mat, "node_emission", in, out, GPU_builtin(GPU_VIEW_NORMAL));
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_fresnel.c b/source/blender/nodes/shader/nodes/node_shader_fresnel.c
index b50f722c71b..46c296717a4 100644
--- a/source/blender/nodes/shader/nodes/node_shader_fresnel.c
+++ b/source/blender/nodes/shader/nodes/node_shader_fresnel.c
@@ -43,8 +43,10 @@ static int node_shader_gpu_fresnel(GPUMaterial *mat, bNode *UNUSED(node), bNodeE
{
if (!in[1].link)
in[1].link = GPU_builtin(GPU_VIEW_NORMAL);
- else
+ else {
+ /* Convert to view space normal in case a Normal is plugged. This is because cycles uses world normals */
GPU_link(mat, "direction_transform_m4v3", in[1].link, GPU_builtin(GPU_VIEW_MATRIX), &in[1].link);
+ }
return GPU_stack_link(mat, "node_fresnel", in, out, GPU_builtin(GPU_VIEW_POSITION));
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_geometry.c b/source/blender/nodes/shader/nodes/node_shader_geometry.c
index 553ea65154f..4616d726617 100644
--- a/source/blender/nodes/shader/nodes/node_shader_geometry.c
+++ b/source/blender/nodes/shader/nodes/node_shader_geometry.c
@@ -26,6 +26,7 @@
*/
#include "../node_shader_util.h"
+ #include "GPU_material.h"
/* **************** OUTPUT ******************** */
@@ -43,9 +44,19 @@ static bNodeSocketTemplate sh_node_geometry_out[] = {
static int node_shader_gpu_geometry(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- return GPU_stack_link(mat, "node_geometry", in, out,
- GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
- GPU_builtin(GPU_INVERSE_VIEW_MATRIX));
+ if (GPU_material_get_type(mat) == GPU_MATERIAL_TYPE_LAMP) {
+ GPUNodeLink *lamp_normal = GPU_material_get_lamp_normal_link(mat);
+ GPUNodeLink *lamp_position = GPU_material_get_lamp_position_link(mat);
+ GPUNodeLink *lamp_incoming = GPU_material_get_lamp_incoming_link(mat);
+
+ return GPU_stack_link(mat, "node_geometry_lamp", in, out,
+ lamp_normal, lamp_position, lamp_incoming,
+ GPU_builtin(GPU_INVERSE_VIEW_MATRIX));
+ }
+ else
+ return GPU_stack_link(mat, "node_geometry", in, out,
+ GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
+ GPU_attribute(CD_ORCO, ""), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_OBJECT_MATRIX));
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_holdout.c b/source/blender/nodes/shader/nodes/node_shader_holdout.c
index ac28a2fa11b..bb14156ff4a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_holdout.c
+++ b/source/blender/nodes/shader/nodes/node_shader_holdout.c
@@ -38,7 +38,6 @@ static bNodeSocketTemplate sh_node_holdout_out[] = {
{ -1, 0, "" }
};
-
/* node type definition */
void register_node_type_sh_holdout(void)
{
diff --git a/source/blender/nodes/shader/nodes/node_shader_lamp.c b/source/blender/nodes/shader/nodes/node_shader_lamp.c
index 2c96c91958e..d3483c8c826 100644
--- a/source/blender/nodes/shader/nodes/node_shader_lamp.c
+++ b/source/blender/nodes/shader/nodes/node_shader_lamp.c
@@ -63,7 +63,7 @@ static void node_shader_exec_lamp(void *data, int UNUSED(thread), bNode *node, b
static int gpu_shader_lamp(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
if (node->id) {
- GPULamp *lamp = GPU_lamp_from_blender(GPU_material_scene(mat), (Object *)node->id, NULL);
+ GPULamp *lamp = GPU_lamp_from_blender(GPU_material_scene(mat), (Object *)node->id, NULL, false);
GPUNodeLink *col, *lv, *dist, *visifac, *shadow, *energy;
visifac = GPU_lamp_get_data(mat, lamp, &col, &lv, &dist, &shadow, &energy);
diff --git a/source/blender/nodes/shader/nodes/node_shader_layer_weight.c b/source/blender/nodes/shader/nodes/node_shader_layer_weight.c
index 8cbc587e339..f54145d8e66 100644
--- a/source/blender/nodes/shader/nodes/node_shader_layer_weight.c
+++ b/source/blender/nodes/shader/nodes/node_shader_layer_weight.c
@@ -45,8 +45,10 @@ static int node_shader_gpu_layer_weight(GPUMaterial *mat, bNode *UNUSED(node), b
{
if (!in[1].link)
in[1].link = GPU_builtin(GPU_VIEW_NORMAL);
- else
+ else {
+ /* Convert to view space normal in case a Normal is plugged. This is because cycles uses world normals */
GPU_link(mat, "direction_transform_m4v3", in[1].link, GPU_builtin(GPU_VIEW_MATRIX), &in[1].link);
+ }
return GPU_stack_link(mat, "node_layer_weight", in, out, GPU_builtin(GPU_VIEW_POSITION));
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_light_falloff.c b/source/blender/nodes/shader/nodes/node_shader_light_falloff.c
index 3aad476ea05..a08a554bb4e 100644
--- a/source/blender/nodes/shader/nodes/node_shader_light_falloff.c
+++ b/source/blender/nodes/shader/nodes/node_shader_light_falloff.c
@@ -26,6 +26,7 @@
*/
#include "../node_shader_util.h"
+#include "GPU_material.h"
/* **************** INPUT ********************* */
@@ -46,7 +47,17 @@ static bNodeSocketTemplate sh_node_light_falloff_out[] = {
static int node_shader_gpu_light_falloff(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- return GPU_stack_link(mat, "node_light_falloff", in, out);
+ if (GPU_material_get_type(mat) == GPU_MATERIAL_TYPE_LAMP) {
+ GPUNodeLink *lampposlink = GPU_material_get_lamp_position_link(mat);
+ if (lampposlink)
+ return GPU_stack_link(mat, "node_light_falloff", in, out, lampposlink, GPU_builtin(GPU_VIEW_POSITION));
+ else
+ return 0;
+ }
+ else {
+ float lamppos[4] = {0.0f};
+ return GPU_stack_link(mat, "node_light_falloff", in, out, GPU_uniform((float *)lamppos), GPU_builtin(GPU_VIEW_POSITION));
+ }
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_object_info.c b/source/blender/nodes/shader/nodes/node_shader_object_info.c
index d1905246fd4..c7cb2f63b28 100644
--- a/source/blender/nodes/shader/nodes/node_shader_object_info.c
+++ b/source/blender/nodes/shader/nodes/node_shader_object_info.c
@@ -39,7 +39,7 @@ static bNodeSocketTemplate sh_node_object_info_out[] = {
static int node_shader_gpu_object_info(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- return GPU_stack_link(mat, "node_object_info", in, out);
+ return GPU_stack_link(mat, "node_object_info", in, out, GPU_builtin(GPU_OBJECT_MATRIX));
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_lamp.c b/source/blender/nodes/shader/nodes/node_shader_output_lamp.c
index c1903facb8c..0f4571eb740 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output_lamp.c
+++ b/source/blender/nodes/shader/nodes/node_shader_output_lamp.c
@@ -34,6 +34,16 @@ static bNodeSocketTemplate sh_node_output_lamp_in[] = {
{ -1, 0, "" }
};
+static int node_shader_gpu_output_lamp(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ GPUNodeLink *outlink;
+
+ GPU_stack_link(mat, "node_output_lamp", in, out, &outlink);
+ GPU_material_output_link(mat, outlink);
+
+ return 1;
+}
+
/* node type definition */
void register_node_type_sh_output_lamp(void)
{
@@ -44,6 +54,7 @@ void register_node_type_sh_output_lamp(void)
node_type_socket_templates(&ntype, sh_node_output_lamp_in, NULL);
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
+ node_type_gpu(&ntype, node_shader_gpu_output_lamp);
/* Do not allow muting output node. */
node_type_internal_links(&ntype, NULL);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tangent.c b/source/blender/nodes/shader/nodes/node_shader_tangent.c
index 7aa7fb43221..bbcb55a027b 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tangent.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tangent.c
@@ -41,6 +41,29 @@ static void node_shader_init_tangent(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = attr;
}
+static int node_shader_gpu_tangent(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ NodeShaderTangent *attr = node->storage;
+ float vec[3] = {0.0f};
+
+ if(attr->direction_type == SHD_TANGENT_UVMAP){
+ return GPU_stack_link(mat, "node_tangentmap", in, out, GPU_attribute(CD_TANGENT, ""), GPU_builtin(GPU_INVERSE_VIEW_MATRIX));
+ }
+ else{
+ GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
+
+ if (attr->axis == SHD_TANGENT_AXIS_X)
+ GPU_link(mat, "tangent_orco_x", orco, &orco);
+ else if (attr->axis == SHD_TANGENT_AXIS_Y)
+ GPU_link(mat, "tangent_orco_y", orco, &orco);
+ else
+ GPU_link(mat, "tangent_orco_z", orco, &orco);
+
+ return GPU_stack_link(mat, "node_tangent", in, out, GPU_builtin(GPU_VIEW_NORMAL), orco,
+ GPU_builtin(GPU_OBJECT_MATRIX), GPU_builtin(GPU_INVERSE_VIEW_MATRIX));
+ }
+}
+
/* node type definition */
void register_node_type_sh_tangent(void)
{
@@ -52,6 +75,7 @@ void register_node_type_sh_tangent(void)
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
node_type_init(&ntype, node_shader_init_tangent);
node_type_storage(&ntype, "NodeShaderTangent", node_free_standard_storage, node_copy_standard_storage);
+ node_type_gpu(&ntype, node_shader_gpu_tangent);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
index be393582a42..c4f5a974b8e 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
@@ -46,9 +46,9 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat, bNode *UNUSED(node), bNod
{
GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
GPUNodeLink *mtface = GPU_attribute(CD_MTFACE, "");
- GPUMatType type = GPU_Material_get_type(mat);
-
- if (type == GPU_MATERIAL_TYPE_MESH) {
+ GPUMatType type = GPU_material_get_type(mat);
+
+ if (type == GPU_MATERIAL_TYPE_MESH || type == GPU_MATERIAL_TYPE_MESH_REAL_SH) {
return GPU_stack_link(mat, "node_tex_coord", in, out,
GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
@@ -57,7 +57,7 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat, bNode *UNUSED(node), bNod
else {
return GPU_stack_link(mat, "node_tex_coord_background", in, out,
GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
- GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
+ GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
GPU_builtin(GPU_CAMERA_TEXCO_FACTORS), orco, mtface);
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
index 2f8f95b0675..4e431374490 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -58,31 +58,29 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node, bNodeE
{
Image *ima = (Image *)node->id;
ImageUser *iuser = NULL;
- NodeTexImage *tex = node->storage;
+ NodeTexEnvironment *tex = node->storage;
int isdata = tex->color_space == SHD_COLORSPACE_NONE;
+ GPUMatType type = GPU_material_get_type(mat);
if (!ima)
return GPU_stack_link(mat, "node_tex_environment_empty", in, out);
if (!in[0].link) {
- GPUMatType type = GPU_Material_get_type(mat);
-
- if (type == GPU_MATERIAL_TYPE_MESH)
+ if (type == GPU_MATERIAL_TYPE_MESH || type == GPU_MATERIAL_TYPE_MESH_REAL_SH)
in[0].link = GPU_builtin(GPU_VIEW_POSITION);
else
GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &in[0].link);
}
-
+
node_shader_gpu_tex_mapping(mat, node, in, out);
if (tex->projection == SHD_PROJ_EQUIRECTANGULAR)
- GPU_stack_link(mat, "node_tex_environment_equirectangular", in, out, GPU_image(ima, iuser, isdata));
+ GPU_stack_link(mat, "node_tex_environment_equirectangular", in, out, GPU_image(ima, iuser, isdata, true));
else
- GPU_stack_link(mat, "node_tex_environment_mirror_ball", in, out, GPU_image(ima, iuser, isdata));
+ GPU_stack_link(mat, "node_tex_environment_mirror_ball", in, out, GPU_image(ima, iuser, isdata, false));
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
- if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
- GPU_material_do_color_management(mat))
+ if (!isdata)
{
GPU_link(mat, "srgb_to_linearrgb", out[0].link, &out[0].link);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
index 71200dfe9d3..d04dad484e9 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
@@ -59,10 +59,9 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat
Image *ima = (Image *)node->id;
ImageUser *iuser = NULL;
NodeTexImage *tex = node->storage;
-
GPUNodeLink *norm;
-
int isdata = tex->color_space == SHD_COLORSPACE_NONE;
+ bool do_clip = tex->extension == SHD_IMAGE_EXTENSION_CLIP;
float blend = tex->projection_blend;
if (!ima)
@@ -74,9 +73,6 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat
node_shader_gpu_tex_mapping(mat, node, in, out);
switch (tex->projection) {
- case SHD_PROJ_FLAT:
- GPU_stack_link(mat, "node_tex_image", in, out, GPU_image(ima, iuser, isdata));
- break;
case SHD_PROJ_BOX:
GPU_link(mat, "direction_transform_m4v3", GPU_builtin(GPU_VIEW_NORMAL),
GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
@@ -84,33 +80,47 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat
GPU_link(mat, "direction_transform_m4v3", norm,
GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
&norm);
- GPU_link(mat, "node_tex_image_box", in[0].link,
- norm,
- GPU_image(ima, iuser, isdata),
- GPU_uniform(&blend),
- &out[0].link,
- &out[1].link);
break;
case SHD_PROJ_SPHERE:
GPU_link(mat, "point_texco_remap_square", in[0].link, &in[0].link);
GPU_link(mat, "point_map_to_sphere", in[0].link, &in[0].link);
- GPU_stack_link(mat, "node_tex_image", in, out, GPU_image(ima, iuser, isdata));
break;
case SHD_PROJ_TUBE:
GPU_link(mat, "point_texco_remap_square", in[0].link, &in[0].link);
GPU_link(mat, "point_map_to_tube", in[0].link, &in[0].link);
- GPU_stack_link(mat, "node_tex_image", in, out, GPU_image(ima, iuser, isdata));
break;
+ case SHD_PROJ_FLAT:
+ break;
+ }
+
+ if (tex->projection == SHD_PROJ_BOX) {
+ GPU_link(mat, "node_tex_image_box", in[0].link,
+ norm,
+ GPU_image(ima, iuser, isdata, do_clip),
+ GPU_uniform(&blend),
+ &out[0].link,
+ &out[1].link);
+ }
+ else {
+ if (tex->interpolation == SHD_INTERP_CLOSEST) {
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
+
+ if (!ibuf)
+ return GPU_stack_link(mat, "node_tex_image_empty", in, out);
+
+ float dim[2] = {(float)ibuf->x, (float)ibuf->y};
+ GPU_stack_link(mat, "node_tex_image_closest", in, out, GPU_image(ima, iuser, isdata, do_clip), GPU_uniform(dim));
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+ else {
+ GPU_stack_link(mat, "node_tex_image", in, out, GPU_image(ima, iuser, isdata, do_clip));
+ }
}
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
- if ((tex->color_space == SHD_COLORSPACE_COLOR) &&
- ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
- GPU_material_do_color_management(mat))
+ if (!isdata)
{
GPU_link(mat, "srgb_to_linearrgb", out[0].link, &out[0].link);
}
- BKE_image_release_ibuf(ima, ibuf, NULL);
return true;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c
index b0b25a4878b..799c2436e17 100644
--- a/source/blender/nodes/shader/nodes/node_shader_texture.c
+++ b/source/blender/nodes/shader/nodes/node_shader_texture.c
@@ -125,7 +125,7 @@ static int gpu_shader_texture(GPUMaterial *mat, bNode *node, bNodeExecData *UNUS
if (tex && tex->ima && (tex->type == TEX_IMAGE || tex->type == TEX_ENVMAP)) {
if (tex->type == TEX_IMAGE) {
- GPUNodeLink *texlink = GPU_image(tex->ima, &tex->iuser, false);
+ GPUNodeLink *texlink = GPU_image(tex->ima, &tex->iuser, false, false);
GPU_stack_link(mat, "texture_image", in, out, texlink);
}
else { /* TEX_ENVMAP */
diff --git a/source/blender/nodes/shader/nodes/node_shader_wavelength.c b/source/blender/nodes/shader/nodes/node_shader_wavelength.c
index 182769e2b32..5641de9d990 100644
--- a/source/blender/nodes/shader/nodes/node_shader_wavelength.c
+++ b/source/blender/nodes/shader/nodes/node_shader_wavelength.c
@@ -38,6 +38,12 @@ static bNodeSocketTemplate sh_node_wavelength_out[] = {
{ -1, 0, "" }
};
+static int node_shader_gpu_wavelength(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ return GPU_stack_link(mat, "node_wavelength", in, out);
+}
+
+
/* node type definition */
void register_node_type_sh_wavelength(void)
{
@@ -49,6 +55,7 @@ void register_node_type_sh_wavelength(void)
node_type_socket_templates(&ntype, sh_node_wavelength_in, sh_node_wavelength_out);
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
+ node_type_gpu(&ntype, node_shader_gpu_wavelength);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/python/intern/gpu_offscreen.c b/source/blender/python/intern/gpu_offscreen.c
index c4863b2a92f..2941806b761 100644
--- a/source/blender/python/intern/gpu_offscreen.c
+++ b/source/blender/python/intern/gpu_offscreen.c
@@ -222,7 +222,7 @@ static PyObject *pygpu_offscreen_draw_view3d(BPy_GPUOffScreen *self, PyObject *a
fx_settings = v3d->fx_settings; /* full copy */
- ED_view3d_draw_offscreen_init(scene, v3d);
+ ED_view3d_draw_offscreen_init(scene, v3d, ar);
rv3d_mats = ED_view3d_mats_rv3d_backup(ar->regiondata);
@@ -231,7 +231,7 @@ static PyObject *pygpu_offscreen_draw_view3d(BPy_GPUOffScreen *self, PyObject *a
ED_view3d_draw_offscreen(
scene, v3d, ar, GPU_offscreen_width(self->ofs), GPU_offscreen_height(self->ofs),
(float(*)[4])py_mat_modelview->matrix, (float(*)[4])py_mat_projection->matrix,
- false, true, true, "",
+ false, true, true, true, "",
fx, &fx_settings,
self->ofs);
diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp
index 95679b5d3a6..f112ec54e8a 100644
--- a/source/gameengine/Ketsji/BL_BlenderShader.cpp
+++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp
@@ -62,7 +62,7 @@ BL_BlenderShader::~BL_BlenderShader()
void BL_BlenderShader::ReloadMaterial()
{
- mGPUMat = (mMat) ? GPU_material_from_blender(mBlenderScene, mMat, false) : NULL;
+ mGPUMat = (mMat) ? GPU_material_from_blender(mBlenderScene, mMat, false, false, false, false, false, false, false, 0) : NULL;
}
void BL_BlenderShader::SetProg(bool enable, double time, RAS_IRasterizer* rasty)
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp
index fff988a07c5..9190e8f2338 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp
@@ -161,7 +161,7 @@ GPULamp *RAS_OpenGLLight::GetGPULamp()
KX_LightObject* kxlight = (KX_LightObject*)m_light;
if (m_glsl)
- return GPU_lamp_from_blender(kxlight->GetScene()->GetBlenderScene(), kxlight->GetBlenderObject(), kxlight->GetBlenderGroupObject());
+ return GPU_lamp_from_blender(kxlight->GetScene()->GetBlenderScene(), kxlight->GetBlenderObject(), kxlight->GetBlenderGroupObject(), false);
else
return NULL;
}
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
index 3f82c513f7d..66c2fde908b 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -832,7 +832,7 @@ void RAS_OpenGLRasterizer::DrawDerivedMesh(class RAS_MeshSlot &ms)
Material* blmat = current_polymat->GetBlenderMaterial();
Scene* blscene = current_polymat->GetBlenderScene();
if (!current_wireframe && blscene && blmat)
- GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat, false), &current_gpu_attribs);
+ GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat, false, false, false, false, false, false, false, 0), &current_gpu_attribs);
else
memset(&current_gpu_attribs, 0, sizeof(current_gpu_attribs));
// DM draw can mess up blending mode, restore at the end