GPv3: Curve to Mesh node #113659

Manually merged
Dalai Felinto merged 86 commits from dfelinto/blender:grease-nodes-curve-to-mesh into main 2023-10-16 11:49:25 +02:00
230 changed files with 3624 additions and 1460 deletions

View File

@ -52,6 +52,18 @@
/* Logging, use `ghost.wl.*` prefix. */
#include "CLG_log.h"
/**
* NOTE(@ideasman42): Workaround a bug with fractional scaling with LIBDECOR.
* When fractional scaling is used the GHOST window uses a buffer-scale of 1
* with the actual scale compensated for by a #wp_viewport.
*
* This causes various glitches between the GHOST window and LIBDECOR.
* While this hack doesn't resolve all of them it does fix the problem where a new windows
* decorations don't match the window, sometimes causing a delayed decrease in the windows size.
* See #109194 for related issues.
*/
#define USE_LIBDECOR_FRACTIONAL_SCALE_HACK
static const xdg_activation_token_v1_listener *xdg_activation_listener_get();
static constexpr size_t base_dpi = 96;
@ -519,6 +531,20 @@ static bool gwl_window_viewport_set(GWL_Window *win,
else {
wl_surface_commit(win->wl.surface);
}
#if defined(WITH_GHOST_WAYLAND_LIBDECOR) && defined(USE_LIBDECOR_FRACTIONAL_SCALE_HACK)
/* NOTE(@ideasman42): it's important this only runs when enabling the viewport
* since there is a bug with LIBDECOR not supporting the switch from non-fractional
* to fractional scaled surfaces. */
if (use_libdecor) {
WGL_LibDecor_Window &decor = *win->libdecor;
libdecor_state *state = libdecor_state_new(
gwl_window_fractional_from_viewport_round(win->frame, win->frame.size[0]),
gwl_window_fractional_from_viewport_round(win->frame, win->frame.size[1]));
libdecor_frame_commit(decor.frame, state, nullptr);
libdecor_state_free(state);
}
#endif
}
return true;
@ -1215,9 +1241,9 @@ static void libdecor_frame_handle_commit(libdecor_frame * /*frame*/, void *data)
/* NOTE: cannot be `const` because of the LIBDECOR API. */
static libdecor_frame_interface libdecor_frame_iface = {
libdecor_frame_handle_configure,
libdecor_frame_handle_close,
libdecor_frame_handle_commit,
/*configure*/ libdecor_frame_handle_configure,
/*close*/ libdecor_frame_handle_close,
/*commit*/ libdecor_frame_handle_commit,
};
# undef LOG
@ -1390,14 +1416,18 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
* known once #surface_enter callback runs (which isn't guaranteed to run at all).
*
* Using the maximum scale is best as it results in the window first being smaller,
* avoiding a large window flashing before it's made smaller. */
int fractional_scale = 0;
* avoiding a large window flashing before it's made smaller.
*
* For fractional scaling the buffer will eventually be 1. Setting it to 1 now
* (to avoid window size rounding and buffer size switching) has some down-sides.
* It means the window will be drawn larger for a moment then smaller once fractional scaling
* is detected and enabled. Unfortunately, it doesn't seem possible to receive the
* #wp_fractional_scale_v1_listener::preferred_scale information before the window is created
* So leave the buffer scaled up because there is no *guarantee* the fractional scaling support
* will run which could result in an incorrect buffer scale.
* Leaving the buffer scale is necessary for #USE_LIBDECOR_FRACTIONAL_SCALE_HACK to work too. */
window_->frame.buffer_scale = outputs_uniform_scale_or_default(
system_->outputs_get(), 1, &fractional_scale);
if (fractional_scale / FRACTIONAL_DENOMINATOR != window_->frame.buffer_scale) {
window_->frame.buffer_scale = 1;
}
system_->outputs_get(), 1, nullptr);
window_->frame_pending.buffer_scale = window_->frame.buffer_scale;
window_->frame.size[0] = int32_t(width);

View File

@ -7,6 +7,46 @@ __all__ = (
)
def find_base_socket_type(socket):
"""
Find the base class of the socket.
Sockets can have a subtype such as NodeSocketFloatFactor,
but only the base type is allowed, e. g. NodeSocketFloat
"""
if socket.type == 'CUSTOM':
# Custom socket types are used directly
return socket.bl_idname
if socket.type == 'VALUE':
return 'NodeSocketFloat'
if socket.type == 'INT':
return 'NodeSocketInt'
if socket.type == 'BOOLEAN':
return 'NodeSocketBoolean'
if socket.type == 'VECTOR':
return 'NodeSocketVector'
if socket.type == 'ROTATION':
return 'NodeSocketRotation'
if socket.type == 'STRING':
return 'NodeSocketString'
if socket.type == 'RGBA':
return 'NodeSocketColor'
if socket.type == 'SHADER':
return 'NodeSocketShader'
if socket.type == 'OBJECT':
return 'NodeSocketObject'
if socket.type == 'IMAGE':
return 'NodeSocketImage'
if socket.type == 'GEOMETRY':
return 'NodeSocketGeometry'
if socket.type == 'COLLECTION':
return 'NodeSocketCollection'
if socket.type == 'TEXTURE':
return 'NodeSocketTexture'
if socket.type == 'MATERIAL':
return 'NodeSocketMaterial'
def connect_sockets(input, output):
"""
Connect sockets in a node tree.
@ -35,14 +75,16 @@ def connect_sockets(input, output):
return
if output_node.type == 'GROUP_OUTPUT' and type(input) == bpy.types.NodeSocketVirtual:
output_node.id_data.interface.new_socket(
name=output.name, socket_type=type(output).__name__, in_out='OUTPUT'
output_type = find_base_socket_type(output)
socket_interface = output_node.id_data.interface.new_socket(
name=output.name, socket_type=output_type, in_out='OUTPUT'
)
input = output_node.inputs[-2]
if input_node.type == 'GROUP_INPUT' and type(output) == bpy.types.NodeSocketVirtual:
input_node.id_data.interface.new_socket(
name=input.name, socket_type=type(input).__name__, in_out='INPUT'
input_type = find_base_socket_type(input)
socket_interface = input_node.id_data.interface.new_socket(
name=input.name, socket_type=input_type, in_out='INPUT'
)
output = input_node.outputs[-2]

View File

@ -45,7 +45,7 @@ class NODE_MT_category_compositor_input_constant(Menu):
node_add_menu.add_node_type(layout, "CompositorNodeRGB")
node_add_menu.add_node_type(layout, "CompositorNodeValue")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
node_add_menu.draw_assets_for_catalog(layout, "Input/Constant")
class NODE_MT_category_compositor_input_scene(Menu):
@ -58,7 +58,7 @@ class NODE_MT_category_compositor_input_scene(Menu):
node_add_menu.add_node_type(layout, "CompositorNodeSceneTime")
node_add_menu.add_node_type(layout, "CompositorNodeTime")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
node_add_menu.draw_assets_for_catalog(layout, "Input/Scene")
class NODE_MT_category_compositor_output(Menu):
@ -120,7 +120,7 @@ class NODE_MT_category_compositor_color_adjust(Menu):
node_add_menu.add_node_type(layout, "CompositorNodeCurveRGB")
node_add_menu.add_node_type(layout, "CompositorNodeTonemap")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
node_add_menu.draw_assets_for_catalog(layout, "Color/Adjust")
class NODE_MT_category_compositor_color_mix(Menu):
@ -138,7 +138,7 @@ class NODE_MT_category_compositor_color_mix(Menu):
layout, "CompositorNodeMixRGB",
label=iface_("Mix Color"))
node_add_menu.add_node_type(layout, "CompositorNodeZcombine")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
node_add_menu.draw_assets_for_catalog(layout, "Color/Mix")
class NODE_MT_category_compositor_filter(Menu):
@ -179,7 +179,7 @@ class NODE_MT_category_compositor_filter_blur(Menu):
node_add_menu.add_node_type(layout, "CompositorNodeDBlur")
node_add_menu.add_node_type(layout, "CompositorNodeVecBlur")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
node_add_menu.draw_assets_for_catalog(layout, "Filter/Blur")
class NODE_MT_category_compositor_group(Menu):

View File

@ -57,9 +57,8 @@ class OBJECT_MT_modifier_add(ModifierAddMenu, Menu):
def draw(self, context):
layout = self.layout
ob_type = context.object.type
geometry_nodes_supported = ob_type in {'MESH', 'CURVE', 'CURVES',
'FONT', 'SURFACE', 'VOLUME', 'POINTCLOUD', 'GREASEPENCIL'}
'FONT', 'VOLUME', 'POINTCLOUD', 'GREASEPENCIL'}
if layout.operator_context == 'EXEC_REGION_WIN':
layout.operator_context = 'INVOKE_REGION_WIN'

View File

@ -870,7 +870,7 @@ class RENDER_PT_eevee_next_sampling_viewport(RenderButtonsPanel, Panel):
col.prop(props, "taa_samples", text="Samples")
col.prop(props, "use_taa_reprojection", text="Temporal Reprojection")
# Add sss sample count here
# Add SSS sample count here.
class RENDER_PT_eevee_next_sampling_render(RenderButtonsPanel, Panel):
@ -893,7 +893,7 @@ class RENDER_PT_eevee_next_sampling_render(RenderButtonsPanel, Panel):
col = layout.column(align=True)
col.prop(props, "taa_render_samples", text="Samples")
# Add sss sample count here
# Add SSS sample count here.
class RENDER_PT_eevee_indirect_lighting(RenderButtonsPanel, Panel):

View File

@ -5752,6 +5752,7 @@ class VIEW3D_MT_gpencil_animation(Menu):
layout.operator("gpencil.delete", text="Delete Active Keyframe (Active Layer)").type = 'FRAME'
layout.operator("gpencil.active_frames_delete_all", text="Delete Active Keyframes (All Layers)")
class VIEW3D_MT_edit_greasepencil_animation(Menu):
bl_label = "Animation"

View File

@ -5,7 +5,7 @@
/** \file
* \ingroup animrig
*
* \brief Functions to work with the visal keying system.
* \brief Functions to work with the visual keying system.
*/
struct PointerRNA;

View File

@ -122,7 +122,7 @@ AssetLibrary *AssetLibraryService::get_asset_library_on_disk(eAssetLibraryType l
std::string normalized_root_path = utils::normalize_directory_path(root_path);
std::unique_ptr<AssetLibrary> *lib_uptr_ptr = on_disk_libraries_.lookup_ptr(
normalized_root_path);
{library_type, normalized_root_path});
if (lib_uptr_ptr != nullptr) {
CLOG_INFO(&LOG, 2, "get \"%s\" (cached)", normalized_root_path.c_str());
AssetLibrary *lib = lib_uptr_ptr->get();
@ -139,7 +139,7 @@ AssetLibrary *AssetLibraryService::get_asset_library_on_disk(eAssetLibraryType l
/* Reload catalogs on refresh. */
lib->on_refresh_ = [](AssetLibrary &self) { self.catalog_service->reload_catalogs(); };
on_disk_libraries_.add_new(normalized_root_path, std::move(lib_uptr));
on_disk_libraries_.add_new({library_type, normalized_root_path}, std::move(lib_uptr));
CLOG_INFO(&LOG, 2, "get \"%s\" (loaded)", normalized_root_path.c_str());
return lib;
}

View File

@ -9,6 +9,7 @@
#pragma once
#include <optional>
#include <utility>
#include "AS_asset_library.hh"
@ -38,9 +39,12 @@ namespace blender::asset_system {
class AssetLibraryService {
static std::unique_ptr<AssetLibraryService> instance_;
/* Mapping absolute path of the library's root path (normalize with #normalize_directory_path()!)
* the AssetLibrary instance. */
Map<std::string, std::unique_ptr<AssetLibrary>> on_disk_libraries_;
/** Identify libraries with the library type, and the absolute path of the library's root path
* (normalize with #normalize_directory_path()!). The type is relevant since the current file
* library may point to the same path as a custom library. */
using OnDiskLibraryIdentifier = std::pair<eAssetLibraryType, std::string>;
/* Mapping of a (type, root path) pair to the AssetLibrary instance. */
Map<OnDiskLibraryIdentifier, std::unique_ptr<AssetLibrary>> on_disk_libraries_;
/** Library without a known path, i.e. the "Current File" library if the file isn't saved yet. If
* the file was saved, a valid path for the library can be determined and #on_disk_libraries_
* above should be used. */

View File

@ -672,13 +672,34 @@ void blf_font_draw_buffer(FontBLF *font, const char *str, const size_t str_len,
* - #BLF_width_to_rstrlen
* \{ */
static bool blf_font_width_to_strlen_glyph_process(
FontBLF *font, GlyphBLF *g_prev, GlyphBLF *g, ft_pix *pen_x, const int width_i)
static bool blf_font_width_to_strlen_glyph_process(FontBLF *font,
GlyphCacheBLF *gc,
GlyphBLF *g_prev,
GlyphBLF *g,
ft_pix *pen_x,
const int width_i)
{
if (UNLIKELY(g == nullptr)) {
return false; /* continue the calling loop. */
}
*pen_x += blf_kerning(font, g_prev, g) + g->advance_x;
if (g && pen_x && !(font->flags & BLF_MONOSPACED)) {
*pen_x += blf_kerning(font, g_prev, g);
#ifdef BLF_SUBPIXEL_POSITION
if (!(font->flags & BLF_RENDER_SUBPIXELAA)) {
*pen_x = FT_PIX_ROUND(*pen_x);
}
#else
*pen_x = FT_PIX_ROUND(*pen_x);
#endif
#ifdef BLF_SUBPIXEL_AA
g = blf_glyph_ensure_subpixel(font, gc, g, *pen_x);
#endif
}
*pen_x += g->advance_x;
/* When true, break the calling loop. */
return (ft_pix_to_int(*pen_x) >= width_i);
@ -699,7 +720,7 @@ size_t blf_font_width_to_strlen(
i_prev = i, width_new = pen_x, g_prev = g)
{
g = blf_glyph_from_utf8_and_step(font, gc, nullptr, str, str_len, &i, nullptr);
if (blf_font_width_to_strlen_glyph_process(font, g_prev, g, &pen_x, width_i)) {
if (blf_font_width_to_strlen_glyph_process(font, gc, g_prev, g, &pen_x, width_i)) {
break;
}
}
@ -742,7 +763,7 @@ size_t blf_font_width_to_rstrlen(
BLI_assert(i_tmp == i);
}
if (blf_font_width_to_strlen_glyph_process(font, g_prev, g, &pen_x, width)) {
if (blf_font_width_to_strlen_glyph_process(font, gc, g_prev, g, &pen_x, width)) {
break;
}
}
@ -1344,6 +1365,176 @@ static void blf_font_fill(FontBLF *font)
font->buf_info.col_init[3] = 0;
}
/* Note that the data the following function creates is not yet used.
* But do not remove it as it will be used in the near future - Harley */
static void blf_font_metrics(FT_Face face, FontMetrics *metrics)
{
/* Members with non-zero defaults. */
metrics->weight = 400;
metrics->width = 1.0f;
metrics->spacing = 1.0f;
TT_OS2 *os2_table = (TT_OS2 *)FT_Get_Sfnt_Table(face, FT_SFNT_OS2);
if (os2_table) {
/* The default (resting) font weight. */
if (os2_table->usWeightClass >= 1 && os2_table->usWeightClass <= 1000) {
metrics->weight = short(os2_table->usWeightClass);
}
/* Width value is one of integers 1-9 with known values. */
if (os2_table->usWidthClass >= 1 && os2_table->usWidthClass <= 9) {
switch (os2_table->usWidthClass) {
case 1:
metrics->width = 0.5f;
break;
case 2:
metrics->width = 0.625f;
break;
case 3:
metrics->width = 0.75f;
break;
case 4:
metrics->width = 0.875f;
break;
case 5:
metrics->width = 1.0f;
break;
case 6:
metrics->width = 1.125f;
break;
case 7:
metrics->width = 1.25f;
break;
case 8:
metrics->width = 1.5f;
break;
case 9:
metrics->width = 2.0f;
break;
}
}
metrics->strikeout_position = short(os2_table->yStrikeoutPosition);
metrics->strikeout_thickness = short(os2_table->yStrikeoutSize);
metrics->subscript_size = short(os2_table->ySubscriptYSize);
metrics->subscript_xoffset = short(os2_table->ySubscriptXOffset);
metrics->subscript_yoffset = short(os2_table->ySubscriptYOffset);
metrics->superscript_size = short(os2_table->ySuperscriptYSize);
metrics->superscript_xoffset = short(os2_table->ySuperscriptXOffset);
metrics->superscript_yoffset = short(os2_table->ySuperscriptYOffset);
metrics->family_class = short(os2_table->sFamilyClass);
metrics->selection_flags = short(os2_table->fsSelection);
metrics->first_charindex = short(os2_table->usFirstCharIndex);
metrics->last_charindex = short(os2_table->usLastCharIndex);
if (os2_table->version > 1) {
metrics->cap_height = short(os2_table->sCapHeight);
metrics->x_height = short(os2_table->sxHeight);
}
}
/* The Post table usually contains a slant value, but in counter-clockwise degrees. */
TT_Postscript *post_table = (TT_Postscript *)FT_Get_Sfnt_Table(face, FT_SFNT_POST);
if (post_table) {
if (post_table->italicAngle != 0) {
metrics->slant = float(post_table->italicAngle) / -65536.0f;
}
}
/* Metrics copied from those gathered by FreeType. */
metrics->units_per_EM = short(face->units_per_EM);
metrics->ascender = short(face->ascender);
metrics->descender = short(face->descender);
metrics->line_height = short(face->height);
metrics->max_advance_width = short(face->max_advance_width);
metrics->max_advance_height = short(face->max_advance_height);
metrics->underline_position = short(face->underline_position);
metrics->underline_thickness = short(face->underline_thickness);
metrics->num_glyphs = int(face->num_glyphs);
metrics->bounding_box.xmin = int(face->bbox.xMin);
metrics->bounding_box.xmax = int(face->bbox.xMax);
metrics->bounding_box.ymin = int(face->bbox.yMin);
metrics->bounding_box.ymax = int(face->bbox.yMax);
if (metrics->cap_height == 0) {
/* Calculate or guess cap height if it is not set in the font. */
FT_UInt gi = FT_Get_Char_Index(face, uint('H'));
if (gi && FT_Load_Glyph(face, gi, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP) == FT_Err_Ok) {
metrics->cap_height = short(face->glyph->metrics.height);
}
else {
metrics->cap_height = short(float(metrics->units_per_EM) * 0.7f);
}
}
if (metrics->x_height == 0) {
/* Calculate or guess x-height if it is not set in the font. */
FT_UInt gi = FT_Get_Char_Index(face, uint('x'));
if (gi && FT_Load_Glyph(face, gi, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP) == FT_Err_Ok) {
metrics->x_height = short(face->glyph->metrics.height);
}
else {
metrics->x_height = short(float(metrics->units_per_EM) * 0.5f);
}
}
FT_UInt gi = FT_Get_Char_Index(face, uint('o'));
if (gi && FT_Load_Glyph(face, gi, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP) == FT_Err_Ok) {
metrics->o_proportion = float(face->glyph->metrics.width) / float(face->glyph->metrics.height);
}
if (metrics->ascender == 0) {
/* Set a sane value for ascender if not set in the font. */
metrics->ascender = short(float(metrics->units_per_EM) * 0.8f);
}
if (metrics->descender == 0) {
/* Set a sane value for descender if not set in the font. */
metrics->descender = metrics->ascender - metrics->units_per_EM;
}
if (metrics->weight == 400 && face->style_flags & FT_STYLE_FLAG_BOLD) {
/* Normal weight yet this is an bold font, so set a sane weight value. */
metrics->weight = 700;
}
if (metrics->slant == 0.0f && face->style_flags & FT_STYLE_FLAG_ITALIC) {
/* No slant yet this is an italic font, so set a sane slant value. */
metrics->slant = 8.0f;
}
if (metrics->underline_position == 0) {
metrics->underline_position = short(float(metrics->units_per_EM) * -0.2f);
}
if (metrics->underline_thickness == 0) {
metrics->underline_thickness = short(float(metrics->units_per_EM) * 0.07f);
}
if (metrics->strikeout_position == 0) {
metrics->strikeout_position = short(float(metrics->x_height) * 0.6f);
}
if (metrics->strikeout_thickness == 0) {
metrics->strikeout_thickness = metrics->underline_thickness;
}
if (metrics->subscript_size == 0) {
metrics->subscript_size = short(float(metrics->units_per_EM) * 0.6f);
}
if (metrics->subscript_yoffset == 0) {
metrics->subscript_yoffset = short(float(metrics->units_per_EM) * 0.075f);
}
if (metrics->superscript_size == 0) {
metrics->superscript_size = short(float(metrics->units_per_EM) * 0.6f);
}
if (metrics->superscript_yoffset == 0) {
metrics->superscript_yoffset = short(float(metrics->units_per_EM) * 0.35f);
}
}
bool blf_ensure_face(FontBLF *font)
{
if (font->face) {
@ -1431,6 +1622,9 @@ bool blf_ensure_face(FontBLF *font)
FT_Get_MM_Var(font->face, &(font->variations));
}
blf_ensure_size(font);
blf_font_metrics(font->face, &font->metrics);
/* Save TrueType table with bits to quickly test most unicode block coverage. */
TT_OS2 *os2_table = (TT_OS2 *)FT_Get_Sfnt_Table(font->face, FT_SFNT_OS2);
if (os2_table) {

View File

@ -209,6 +209,75 @@ typedef struct FontBufInfoBLF {
} FontBufInfoBLF;
typedef struct FontMetrics {
/** This font's default weight, 100-900, 400 is normal. */
short weight;
/** This font's default width, 1 is normal, 2 is twice as wide. */
float width;
/** This font's slant in clockwise degrees, 0 being upright. */
float slant;
/** This font's default spacing, 1 is normal. */
float spacing;
/** Number of font units in an EM square. 2048, 1024, 1000 are typical. */
short units_per_EM; /* */
/** Design classification from OS/2 sFamilyClass. */
short family_class;
/** Style classification from OS/2 fsSelection. */
short selection_flags;
/** Total number of glyphs in the font. */
int num_glyphs;
/** Minimum Unicode index, typically 0x0020. */
short first_charindex;
/** Maximum Unicode index, or 0xFFFF if greater than. */
short last_charindex;
/**
* Bounds that can contain every glyph in the font when in default positions. Can be used for
* maximum ascender, minimum descender. Can be out by a pixel when hinting. Does not change with
* variation axis changes. */
rcti bounding_box;
/**
* Positive number of font units from baseline to top of typical capitals. Can be slightly more
* than cap height when head serifs, terminals, or apexes extend above cap line. */
short ascender;
/** Negative (!) number of font units from baseline to bottom of letters like `gjpqy`. */
short descender;
/** Positive number of font units between consecutive baselines. */
short line_height;
/** Font units from baseline to lowercase mean line, typically to top of "x". */
short x_height;
/** Font units from baseline to top of capital letters, specifically "H". */
short cap_height;
/** Ratio width to height of lowercase "O". Reliable indication of font proportion. */
float o_proportion;
/** Font unit maximum horizontal advance for all glyphs in font. Can help with wrapping. */
short max_advance_width;
/** As above but only for vertical layout fonts, otherwise is set to line_height value. */
short max_advance_height;
/** Negative (!) number of font units below baseline to center (!) of underlining stem. */
short underline_position;
/** thickness of the underline in font units. */
short underline_thickness;
/** Positive number of font units above baseline to the top (!) of strikeout stroke. */
short strikeout_position;
/** thickness of the strikeout line in font units. */
short strikeout_thickness;
/** EM size font units of recommended subscript letters. */
short subscript_size;
/** Horizontal offset before first subscript character, typically 0. */
short subscript_xoffset;
/** Positive number of font units above baseline for subscript characters. */
short subscript_yoffset;
/** EM size font units of recommended superscript letters. */
short superscript_size;
/** Horizontal offset before first superscript character, typically 0. */
short superscript_xoffset;
/** Positive (!) number of font units below baseline for subscript characters. */
short superscript_yoffset;
} FontMetrics;
typedef struct FontBLF {
/** Full path to font file or NULL if from memory. */
char *filepath;
@ -307,6 +376,9 @@ typedef struct FontBLF {
/** Copy of the font->face->face_flags, in case we don't have a face loaded. */
FT_Long face_flags;
/** Details about the font's design and style and sizes (in un-sized font units). */
FontMetrics metrics;
/** Data for buffer usage (drawing into a texture buffer) */
FontBufInfoBLF buf_info;

View File

@ -362,17 +362,22 @@ typedef struct bNodeType {
/* Execute a geometry node. */
NodeGeometryExecFunction geometry_node_execute;
/* Declares which sockets the node has. */
NodeDeclareFunction declare;
/**
* Declare which sockets the node has for declarations that aren't static per node type.
* In other words, defining this callback means that different nodes of this type can have
* different declarations and different sockets.
* Declares which sockets and panels the node has. It has to be able to generate a declaration
* with and without a specific node context. If the declaration depends on the node, but the node
* is not provided, then the declaration should be generated as much as possible and everything
* that depends on the node context should be skipped.
*/
NodeDeclareDynamicFunction declare_dynamic;
NodeDeclareFunction declare;
/* Declaration to be used when it is not dynamic. */
NodeDeclarationHandle *fixed_declaration;
/**
* Declaration of the node outside of any context. If the node declaration is never dependent on
* the node context, this declaration is also shared with the corresponding node instances.
* Otherwise, it mainly allows checking what sockets a node will have, without having to create
* the node. In this case, the static declaration is mostly just a hint, and does not have to
* match with the final node.
*/
NodeDeclarationHandle *static_declaration;
/**
* Add to the list of search names and operations gathered by node link drag searching.

View File

@ -706,6 +706,15 @@ static void mesh_calc_modifiers(Depsgraph *depsgraph,
mesh_final = BKE_mesh_copy_for_eval(mesh_input);
ASSERT_IS_VALID_MESH(mesh_final);
}
if (mti->required_data_mask) {
CustomData_MeshMasks mask{};
mti->required_data_mask(md, &mask);
if (mask.vmask & CD_MASK_ORCO) {
add_orco_mesh(ob, nullptr, mesh_final, nullptr, CD_ORCO);
}
}
BKE_modifier_deform_verts(
md,
&mectx,

View File

@ -303,7 +303,7 @@ GVArray CurvesFieldInput::get_varray_for_context(const fn::FieldContext &context
if (const GeometryFieldContext *geometry_context = dynamic_cast<const GeometryFieldContext *>(
&context))
{
if (const CurvesGeometry *curves = geometry_context->curves()) {
if (const CurvesGeometry *curves = geometry_context->curves_or_strokes()) {
return this->get_varray_for_context(*curves, geometry_context->domain(), mask);
}
}
@ -529,7 +529,7 @@ GVArray NormalFieldInput::get_varray_for_context(const GeometryFieldContext &con
if (const Mesh *mesh = context.mesh()) {
return mesh_normals_varray(*mesh, mask, context.domain());
}
if (const CurvesGeometry *curves = context.curves()) {
if (const CurvesGeometry *curves = context.curves_or_strokes()) {
return curve_normals_varray(*curves, context.domain());
}
return {};

View File

@ -79,7 +79,7 @@
#include "RNA_prototypes.h"
#include "NOD_common.h"
#include "NOD_composite.h"
#include "NOD_composite.hh"
#include "NOD_geometry.hh"
#include "NOD_geometry_nodes_lazy_function.hh"
#include "NOD_node_declaration.hh"
@ -1153,7 +1153,7 @@ namespace blender::bke {
static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype)
{
if (ntype->declare || ntype->declare_dynamic) {
if (ntype->declare) {
node_verify_sockets(ntree, node, true);
return;
}
@ -1455,8 +1455,8 @@ static void node_free_type(void *nodetype_v)
* or we'd want to update *all* active Mains, which we cannot do anyway currently. */
blender::bke::update_typeinfo(G_MAIN, nullptr, nullptr, nodetype, nullptr, true);
delete nodetype->fixed_declaration;
nodetype->fixed_declaration = nullptr;
delete nodetype->static_declaration;
nodetype->static_declaration = nullptr;
/* Can be null when the type is not dynamically allocated. */
if (nodetype->free_self) {
@ -1470,11 +1470,9 @@ void nodeRegisterType(bNodeType *nt)
BLI_assert(nt->idname[0] != '\0');
BLI_assert(nt->poll != nullptr);
if (nt->declare && !nt->declare_dynamic) {
if (nt->fixed_declaration == nullptr) {
nt->fixed_declaration = new blender::nodes::NodeDeclaration();
blender::nodes::build_node_declaration(*nt, *nt->fixed_declaration);
}
if (nt->declare) {
nt->static_declaration = new blender::nodes::NodeDeclaration();
blender::nodes::build_node_declaration(*nt, *nt->static_declaration, nullptr, nullptr);
}
BLI_ghash_insert(blender::bke::nodetypes_hash, nt->idname, nt);
@ -3268,8 +3266,12 @@ void node_free_node(bNodeTree *ntree, bNode *node)
MEM_freeN(node->prop);
}
if (node->typeinfo->declare_dynamic) {
delete node->runtime->declaration;
if (node->runtime->declaration) {
/* Only free if this declaration is not shared with the node type, which can happen if it does
* not depend on any context. */
if (node->runtime->declaration != node->typeinfo->static_declaration) {
delete node->runtime->declaration;
}
}
MEM_delete(node->runtime);
@ -3734,18 +3736,20 @@ bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree *ntree, bNode *node)
if (node->runtime->declaration != nullptr) {
return false;
}
if (node->typeinfo->declare_dynamic) {
if (node->typeinfo->declare) {
if (node->typeinfo->static_declaration) {
if (!node->typeinfo->static_declaration->is_context_dependent) {
node->runtime->declaration = node->typeinfo->static_declaration;
return true;
}
}
}
if (node->typeinfo->declare) {
BLI_assert(ntree != nullptr);
BLI_assert(node != nullptr);
blender::nodes::update_node_declaration_and_sockets(*ntree, *node);
return true;
}
if (node->typeinfo->declare) {
/* Declaration should have been created in #nodeRegisterType. */
BLI_assert(node->typeinfo->fixed_declaration != nullptr);
node->runtime->declaration = node->typeinfo->fixed_declaration;
return true;
}
return false;
}

View File

@ -563,8 +563,12 @@ class NodeTreeMainUpdater {
if (ntype.updatefunc) {
ntype.updatefunc(&ntree, node);
}
if (ntype.declare_dynamic) {
nodes::update_node_declaration_and_sockets(ntree, *node);
if (ntype.declare) {
/* Should have been created when the node was registered. */
BLI_assert(ntype.static_declaration != nullptr);
if (ntype.static_declaration->is_context_dependent) {
nodes::update_node_declaration_and_sockets(ntree, *node);
}
}
}
}

View File

@ -632,6 +632,54 @@ template<typename T> [[nodiscard]] inline int dominant_axis(const VecBase<T, 3>
return ((b.x > b.y) ? ((b.x > b.z) ? 0 : 2) : ((b.y > b.z) ? 1 : 2));
}
/**
* \return the maximum component of a vector.
*/
template<typename T, int Size> [[nodiscard]] inline T reduce_max(const VecBase<T, Size> &a)
{
T result = a[0];
for (int i = 1; i < Size; i++) {
if (a[i] > result) {
result = a[i];
}
}
return result;
}
/**
* \return the minimum component of a vector.
*/
template<typename T, int Size> [[nodiscard]] inline T reduce_min(const VecBase<T, Size> &a)
{
T result = a[0];
for (int i = 1; i < Size; i++) {
if (a[i] < result) {
result = a[i];
}
}
return result;
}
/**
* \return the sum of the components of a vector.
*/
template<typename T, int Size> [[nodiscard]] inline T reduce_add(const VecBase<T, Size> &a)
{
T result = a[0];
for (int i = 1; i < Size; i++) {
result += a[i];
}
return result;
}
/**
* \return the average of the components of a vector.
*/
template<typename T, int Size> [[nodiscard]] inline T average(const VecBase<T, Size> &a)
{
return reduce_add(a) * (T(1) / T(Size));
}
/**
* Calculates a perpendicular vector to \a v.
* \note Returned vector can be in any perpendicular direction.

View File

@ -78,7 +78,7 @@
#include "IMB_imbuf.h" /* for proxy / time-code versioning stuff. */
#include "NOD_common.h"
#include "NOD_composite.h"
#include "NOD_composite.hh"
#include "NOD_texture.h"
#include "BLO_readfile.h"

View File

@ -74,7 +74,7 @@
#include "BLO_readfile.h"
#include "NOD_common.h"
#include "NOD_composite.h"
#include "NOD_composite.hh"
#include "NOD_socket.hh"
#include "readfile.hh"

View File

@ -619,7 +619,13 @@ static void version_principled_bsdf_subsurface(bNodeTree *ntree)
bNodeSocket *subsurf = nodeFindSocket(node, SOCK_IN, "Subsurface");
float *subsurf_val = version_cycles_node_socket_float_value(subsurf);
*version_cycles_node_socket_float_value(scale_in) = *subsurf_val;
if (!subsurf->link && *subsurf_val == 0.0f) {
*version_cycles_node_socket_float_value(scale_in) = 0.05f;
}
else {
*version_cycles_node_socket_float_value(scale_in) = *subsurf_val;
}
if (subsurf->link == nullptr && *subsurf_val == 0.0f) {
/* Node doesn't use Subsurf, we're done here. */

View File

@ -33,7 +33,7 @@ if(WITH_COMPOSITOR_CPU)
)
set(SRC
COM_compositor.h
COM_compositor.hh
COM_defines.h
intern/COM_BufferArea.h

View File

@ -7,10 +7,6 @@
#include "DNA_color_types.h"
#include "DNA_node_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct Render;
/* Keep ascii art. */
@ -349,7 +345,3 @@ void COM_deinitialize(void);
* To deinitialize the compositor use the COM_deinitialize method.
*/
// void COM_clear_caches(void); // NOT YET WRITTEN
#ifdef __cplusplus
}
#endif

View File

@ -12,7 +12,7 @@
#include "COM_ExecutionSystem.h"
#include "COM_WorkScheduler.h"
#include "COM_compositor.h"
#include "COM_compositor.hh"
#include "RE_compositor.hh"

View File

@ -6,7 +6,7 @@
#include "BKE_node.hh"
#include "NOD_composite.h"
#include "NOD_composite.hh"
#include "COM_ConvertOperation.h"
#include "COM_CryptomatteNode.h"

View File

@ -669,8 +669,13 @@ set(GLSL_SRC
intern/shaders/draw_debug_info.hh
intern/shaders/draw_debug_print_display_frag.glsl
intern/shaders/draw_debug_print_display_vert.glsl
intern/shaders/draw_intersect_lib.glsl
intern/shaders/draw_math_geom_lib.glsl
intern/shaders/draw_model_lib.glsl
intern/shaders/draw_resource_finalize_comp.glsl
intern/shaders/draw_view_finalize_comp.glsl
intern/shaders/draw_view_lib.glsl
intern/shaders/draw_view_reconstruction_lib.glsl
intern/shaders/draw_visibility_comp.glsl
intern/draw_command_shared.hh

View File

@ -331,7 +331,7 @@ static inline float film_filter_weight(float filter_radius, float sample_distanc
float weight = expf(fac * r);
#else
/* Blackman-Harris filter. */
float r = M_2PI * saturate(0.5 + sqrtf(sample_distance_sqr) / (2.0 * filter_radius));
float r = M_TAU * saturate(0.5 + sqrtf(sample_distance_sqr) / (2.0 * filter_radius));
float weight = 0.35875 - 0.48829 * cosf(r) + 0.14128 * cosf(2.0 * r) - 0.01168 * cosf(3.0 * r);
#endif
return weight;
@ -520,12 +520,12 @@ static inline float view_z_to_volume_z(
}
}
static inline float3 ndc_to_volume(float4x4 projection_matrix,
float near,
float far,
float distribution,
float2 coord_scale,
float3 coord)
static inline float3 screen_to_volume(float4x4 projection_matrix,
float near,
float far,
float distribution,
float2 coord_scale,
float3 coord)
{
bool is_persp = projection_matrix[3][3] == 0.0;

View File

@ -22,9 +22,9 @@
namespace blender::eevee {
bool VolumeModule::GridAABB::init(Object *ob, const Camera &camera, const VolumesInfoData &data)
VolumeModule::GridAABB::GridAABB(Object *ob, const Camera &camera, const VolumesInfoData &data)
{
/* Returns the unified volume grid cell index of a world space coordinate. */
/* Returns the unified volume grid cell corner of a world space coordinate. */
auto to_global_grid_coords = [&](float3 wP) -> int3 {
const float4x4 &view_matrix = camera.data_get().viewmat;
const float4x4 &projection_matrix = camera.data_get().winmat;
@ -32,47 +32,38 @@ bool VolumeModule::GridAABB::init(Object *ob, const Camera &camera, const Volume
float3 ndc_coords = math::project_point(projection_matrix * view_matrix, wP);
ndc_coords = (ndc_coords * 0.5f) + float3(0.5f);
float3 grid_coords = ndc_to_volume(projection_matrix,
data.depth_near,
data.depth_far,
data.depth_distribution,
data.coord_scale,
ndc_coords);
return int3(grid_coords * float3(data.tex_size));
float3 grid_coords = screen_to_volume(projection_matrix,
data.depth_near,
data.depth_far,
data.depth_distribution,
data.coord_scale,
ndc_coords);
/* Round to nearest grid corner. */
return int3(grid_coords * float3(data.tex_size) + 0.5);
};
const BoundBox &bbox = *BKE_object_boundbox_get(ob);
min = int3(INT32_MAX);
max = int3(INT32_MIN);
for (float3 corner : bbox.vec) {
corner = math::transform_point(float4x4(ob->object_to_world), corner);
int3 grid_coord = to_global_grid_coords(corner);
min = math::min(min, grid_coord);
max = math::max(max, grid_coord);
for (float3 l_corner : bbox.vec) {
float3 w_corner = math::transform_point(float4x4(ob->object_to_world), l_corner);
/* Note that this returns the nearest cell corner coordinate.
* So sub-froxel AABB will effectively return the same coordinate
* for each corner (making it empty and skipped) unless it
* cover the center of the froxel. */
math::min_max(to_global_grid_coords(w_corner), min, max);
}
bool is_visible = false;
for (int i : IndexRange(3)) {
is_visible = is_visible || (min[i] >= 0 && min[i] < data.tex_size[i]);
is_visible = is_visible || (max[i] >= 0 && max[i] < data.tex_size[i]);
}
min = math::clamp(min, int3(0), data.tex_size);
max = math::clamp(max, int3(0), data.tex_size);
return is_visible;
}
bool VolumeModule::GridAABB::overlaps(const GridAABB &aabb)
bool VolumeModule::GridAABB::is_empty() const
{
for (int i : IndexRange(3)) {
if (min[i] > aabb.max[i] || max[i] < aabb.min[i]) {
return false;
}
}
return true;
return math::reduce_min(max - min) <= 0;
}
VolumeModule::GridAABB VolumeModule::GridAABB::intersect(const GridAABB &other) const
{
return {math::min(this->max, other.max), math::max(this->min, other.min)};
}
void VolumeModule::init()
@ -180,8 +171,11 @@ void VolumeModule::sync_object(Object *ob,
return;
}
GridAABB aabb;
if (!aabb.init(ob, inst_.camera, data_)) {
GridAABB object_aabb(ob, inst_.camera, data_);
/* Remember that these are cells corners, so this extents to `tex_size`. */
GridAABB view_aabb(int3(0), data_.tex_size);
if (object_aabb.intersect(view_aabb).is_empty()) {
/* Skip invisible object with respect to raster grid and bounds density. */
return;
}
@ -191,27 +185,25 @@ void VolumeModule::sync_object(Object *ob,
enabled_ = true;
/* Add a barrier at the start of a subpass or when 2 volumes overlaps. */
if (!subpass_aabbs_.contains_as(shader)) {
if (!subpass_aabbs_.contains_as(shader) == false) {
object_pass->barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS);
subpass_aabbs_.add(shader, {aabb});
subpass_aabbs_.add(shader, {object_aabb});
}
else {
Vector<GridAABB> &aabbs = subpass_aabbs_.lookup(shader);
for (GridAABB &_aabb : aabbs) {
if (aabb.overlaps(_aabb)) {
for (GridAABB &other_aabb : aabbs) {
if (object_aabb.intersect(other_aabb).is_empty() == false) {
object_pass->barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS);
aabbs.clear();
break;
}
}
aabbs.append(aabb);
aabbs.append(object_aabb);
}
int3 grid_size = aabb.max - aabb.min + int3(1);
object_pass->push_constant("drw_ResourceID", int(res_handle.resource_index()));
object_pass->push_constant("grid_coords_min", aabb.min);
object_pass->dispatch(math::divide_ceil(grid_size, int3(VOLUME_GROUP_SIZE)));
object_pass->push_constant("grid_coords_min", object_aabb.min);
object_pass->dispatch(math::divide_ceil(object_aabb.extent(), int3(VOLUME_GROUP_SIZE)));
}
}

View File

@ -79,12 +79,25 @@ class VolumeModule {
/* Axis aligned bounding box in the volume grid.
* Used for frustum culling and volumes overlapping detection. */
struct GridAABB {
/* Represent min and max grid corners covered by a volume.
* So a volume covering the first froxel will have min={0,0,0} and max={1,1,1}.
* A volume with min={0,0,0} and max={0,0,0} covers nothing. */
int3 min, max;
/* Returns true if visible. */
bool init(Object *ob, const Camera &camera, const VolumesInfoData &data);
GridAABB(int3 min_, int3 max_) : min(min_), max(max_){};
GridAABB(Object *ob, const Camera &camera, const VolumesInfoData &data);
bool overlaps(const GridAABB &aabb);
/** Returns the intersection between this AABB and the \a other AABB. */
GridAABB intersect(const GridAABB &other) const;
/** Returns true if volume covers no froxel. */
bool is_empty() const;
/** Returns the extent of the volume. */
int3 extent() const
{
return max - min;
}
};
/* Stores a vector of volume AABBs for each material pass,
* so we can detect overlapping volumes and place GPU barriers where needed

View File

@ -2,8 +2,11 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_base_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_fast_lib.glsl)
#pragma BLENDER_REQUIRE(draw_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_ray_types_lib.glsl)
@ -93,14 +96,14 @@ float ambient_ambient_occlusion_search_horizon(vec3 vI,
if (ssray.max_time <= 2.0) {
/* Produces self shadowing under this threshold. */
return fast_acos(h);
return acos_fast(h);
}
float prev_time, time = 0.0;
for (float iter = 0.0; time < ssray.max_time && iter < sample_count; iter++) {
prev_time = time;
/* Gives us good precision at center and ensure we cross at least one pixel per iteration. */
time = 1.0 + iter + sqr((iter + noise) / sample_count) * ssray.max_time;
time = 1.0 + iter + square((iter + noise) / sample_count) * ssray.max_time;
float stride = time - prev_time;
float lod = (log2(stride) - noise) / (1.0 + uniform_buf.ao.quality);
@ -116,7 +119,7 @@ float ambient_ambient_occlusion_search_horizon(vec3 vI,
const float bias = 2.0 * 2.4e-7;
depth += (inverted != 0.0) ? -bias : bias;
vec3 s = get_view_space_from_depth(uv, depth);
vec3 s = drw_point_screen_to_view(vec3(uv, depth));
vec3 omega_s = s - vP;
float len = length(omega_s);
/* Sample's horizon angle cosine. */
@ -124,7 +127,7 @@ float ambient_ambient_occlusion_search_horizon(vec3 vI,
/* Blend weight to fade artifacts. */
float dist_ratio = abs(len) / radius;
/* Sphere falloff. */
float dist_fac = sqr(saturate(dist_ratio));
float dist_fac = square(saturate(dist_ratio));
/* Unbiased, gives too much hard cut behind objects */
// float dist_fac = step(0.999, dist_ratio);
@ -135,7 +138,7 @@ float ambient_ambient_occlusion_search_horizon(vec3 vI,
h = mix(max(h, s_h), h, dist_fac);
}
}
return fast_acos(h);
return acos_fast(h);
}
OcclusionData ambient_occlusion_search(vec3 vP,
@ -147,8 +150,8 @@ OcclusionData ambient_occlusion_search(vec3 vP,
{
vec2 noise = ambient_occlusion_get_noise(texel);
vec2 dir = ambient_occlusion_get_dir(noise.x);
vec2 uv = get_uvs_from_view(vP);
vec3 vI = ((ProjectionMatrix[3][3] == 0.0) ? normalize(-vP) : vec3(0.0, 0.0, 1.0));
vec2 uv = drw_point_view_to_screen(vP).xy;
vec3 vI = (drw_view_is_perspective() ? normalize(-vP) : vec3(0.0, 0.0, 1.0));
vec3 avg_dir = vec3(0.0);
float avg_apperture = 0.0;
@ -211,8 +214,8 @@ void ambient_occlusion_eval(OcclusionData data,
/* No error by default. */
visibility_error = 1.0;
bool early_out = (inverted != 0.0) ? (max_v4(abs(data.horizons)) == 0.0) :
(min_v4(abs(data.horizons)) == M_PI);
bool early_out = (inverted != 0.0) ? (reduce_max(abs(data.horizons)) == 0.0) :
(reduce_min(abs(data.horizons)) == M_PI);
if (early_out) {
visibility = saturate(dot(N, Ng) * 0.5 + 0.5);
visibility = min(visibility, data.custom_occlusion);
@ -234,13 +237,13 @@ void ambient_occlusion_eval(OcclusionData data,
bent_normal = N * 0.001;
for (int i = 0; i < 2; i++) {
vec3 T = transform_direction(ViewMatrixInverse, vec3(dir, 0.0));
vec3 T = drw_normal_view_to_world(vec3(dir, 0.0));
/* Setup integration domain around V. */
vec3 B = normalize(cross(V, T));
T = normalize(cross(B, V));
float proj_N_len;
vec3 proj_N = normalize_len(N - B * dot(N, B), proj_N_len);
vec3 proj_N = normalize_and_get_length(N - B * dot(N, B), proj_N_len);
vec3 proj_Ng = normalize(Ng - B * dot(Ng, B));
vec2 h = (i == 0) ? data.horizons.xy : data.horizons.zw;
@ -250,8 +253,8 @@ void ambient_occlusion_eval(OcclusionData data,
float N_cos = saturate(dot(proj_N, V));
float Ng_cos = saturate(dot(proj_Ng, V));
/* Gamma, angle between normalized projected normal and view vector. */
float angle_Ng = sign(Ng_sin) * fast_acos(Ng_cos);
float angle_N = sign(N_sin) * fast_acos(N_cos);
float angle_Ng = sign(Ng_sin) * acos_fast(Ng_cos);
float angle_N = sign(N_sin) * acos_fast(N_cos);
/* Clamp horizons to hemisphere around shading normal. */
h = ambient_occlusion_clamp_horizons_to_hemisphere(h, angle_N, inverted);
@ -285,7 +288,7 @@ void ambient_occlusion_eval(OcclusionData data,
if (AO_BENT_NORMALS) {
/* NOTE: using pow(visibility, 6.0) produces NaN (see #87369). */
float tmp = saturate(pow6(visibility));
float tmp = saturate(pow6f(visibility));
bent_normal = normalize(mix(bent_normal, N, tmp));
}
else {
@ -379,14 +382,14 @@ float ambient_occlusion_specular(
specular_dir = normalize(mix(specular_dir, visibility_dir, roughness * (1.0 - visibility)));
/* Visibility to cone angle (eq. 18). */
float vis_angle = fast_acos(sqrt(1 - visibility));
float vis_angle = acos_fast(sqrt(1 - visibility));
/* Roughness to cone angle (eq. 26). */
/* A 0.001 min_angle can generate NaNs on Intel GPUs. See D12508. */
const float min_angle = 0.00990998744964599609375;
float spec_angle = max(min_angle, fast_acos(ambient_occlusion_cone_cosine(roughness)));
float spec_angle = max(min_angle, acos_fast(ambient_occlusion_cone_cosine(roughness)));
/* Angle between cone axes. */
float cone_cone_dist = fast_acos(saturate(dot(visibility_dir, specular_dir)));
float cone_nor_dist = fast_acos(saturate(dot(N, specular_dir)));
float cone_cone_dist = acos_fast(saturate(dot(visibility_dir, specular_dir)));
float cone_nor_dist = acos_fast(saturate(dot(N, specular_dir)));
float isect_solid_angle = ambient_occlusion_spherical_cap_intersection(
vis_angle, spec_angle, cone_cone_dist);
@ -394,7 +397,7 @@ float ambient_occlusion_specular(
M_PI_2, spec_angle, cone_nor_dist);
float specular_occlusion = isect_solid_angle / specular_solid_angle;
/* Mix because it is unstable in unoccluded areas. */
float tmp = saturate(pow8(visibility));
float tmp = saturate(pow8f(visibility));
visibility = mix(specular_occlusion, 1.0, tmp);
return saturate(visibility);

View File

@ -2,64 +2,10 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_vector_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_reconstruction_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_ambient_occlusion_lib.glsl)
/* Similar to https://atyuwen.github.io/posts/normal-reconstruction/.
* This samples the depth buffer 4 time for each direction to get the most correct
* implicit normal reconstruction out of the depth buffer. */
vec3 view_position_derivative_from_depth(
sampler2D depth_tx, ivec2 extent, vec2 uv, ivec2 offset, vec3 vP, float depth_center)
{
vec4 H;
H.x = texelFetch(depth_tx, ivec2(uv * vec2(extent)) - offset * 2, 0).r;
H.y = texelFetch(depth_tx, ivec2(uv * vec2(extent)) - offset, 0).r;
H.z = texelFetch(depth_tx, ivec2(uv * vec2(extent)) + offset, 0).r;
H.w = texelFetch(depth_tx, ivec2(uv * vec2(extent)) + offset * 2, 0).r;
vec2 uv_offset = vec2(offset) / vec2(extent);
vec2 uv1 = uv - uv_offset * 2.0;
vec2 uv2 = uv - uv_offset;
vec2 uv3 = uv + uv_offset;
vec2 uv4 = uv + uv_offset * 2.0;
/* Fix issue with depth precision. Take even larger diff. */
vec4 diff = abs(vec4(depth_center, H.yzw) - H.x);
if (max_v4(diff) < 2.4e-7 && all(lessThan(diff.xyz, diff.www))) {
return 0.25 * (get_view_space_from_depth(uv3, H.w) - get_view_space_from_depth(uv1, H.x));
}
/* Simplified (H.xw + 2.0 * (H.yz - H.xw)) - depth_center */
vec2 deltas = abs((2.0 * H.yz - H.xw) - depth_center);
if (deltas.x < deltas.y) {
return vP - get_view_space_from_depth(uv2, H.y);
}
else {
return get_view_space_from_depth(uv3, H.z) - vP;
}
}
/* TODO(Miguel Pozo): This should be in common_view_lib,
* but moving it there results in dependency hell. */
bool reconstruct_view_position_and_normal_from_depth(
sampler2D depth_tx, ivec2 extent, vec2 uv, out vec3 vP, out vec3 vNg)
{
float depth_center = texelFetch(depth_tx, ivec2(uv * vec2(extent)), 0).r;
vP = get_view_space_from_depth(uv, depth_center);
vec3 dPdx = view_position_derivative_from_depth(
depth_tx, extent, uv, ivec2(1, 0), vP, depth_center);
vec3 dPdy = view_position_derivative_from_depth(
depth_tx, extent, uv, ivec2(0, 1), vP, depth_center);
vNg = safe_normalize(cross(dPdx, dPdy));
/* Background case. */
return depth_center != 1.0;
}
void main()
{
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
@ -68,29 +14,26 @@ void main()
return;
}
vec2 uv = (vec2(texel) + vec2(0.5)) / vec2(extent);
vec3 vP, vNg;
if (!reconstruct_view_position_and_normal_from_depth(hiz_tx, extent, uv, vP, vNg)) {
SurfaceReconstructResult surf = view_reconstruct_from_depth(hiz_tx, extent, texel);
if (surf.is_background) {
/* Do not trace for background */
imageStore(out_ao_img, ivec3(texel, out_ao_img_layer_index), vec4(0.0));
return;
}
vec3 P = transform_point(ViewMatrixInverse, vP);
vec3 V = cameraVec(P);
vec3 Ng = transform_direction(ViewMatrixInverse, vNg);
vec3 P = drw_point_view_to_world(surf.vP);
vec3 V = drw_world_incident_vector(P);
vec3 Ng = drw_normal_view_to_world(surf.vNg);
vec3 N = imageLoad(in_normal_img, ivec3(texel, in_normal_img_layer_index)).xyz;
OcclusionData data = ambient_occlusion_search(
vP, hiz_tx, texel, uniform_buf.ao.distance, 0.0, 8.0);
surf.vP, hiz_tx, texel, uniform_buf.ao.distance, 0.0, 8.0);
float visibility;
float visibility_error_out;
vec3 bent_normal_out;
float unused_visibility_error_out;
vec3 unused_bent_normal_out;
ambient_occlusion_eval(
data, texel, V, N, Ng, 0.0, visibility, visibility_error_out, bent_normal_out);
/* Scale by user factor */
visibility = saturate(visibility);
data, texel, V, N, Ng, 0.0, visibility, unused_visibility_error_out, unused_bent_normal_out);
imageStore(out_ao_img, ivec3(texel, out_ao_img_layer_index), vec4(visibility));
imageStore(out_ao_img, ivec3(texel, out_ao_img_layer_index), vec4(saturate(visibility)));
}

View File

@ -2,8 +2,8 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(draw_model_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_vector_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_codegen_lib.glsl)
#define EEVEE_ATTRIBUTE_LIB
@ -33,7 +33,7 @@ vec3 attr_load_orco(vec4 orco)
# endif
vec4 attr_load_tangent(vec4 tangent)
{
tangent.xyz = safe_normalize(normal_object_to_world(tangent.xyz));
tangent.xyz = safe_normalize(drw_normal_object_to_world(tangent.xyz));
return tangent;
}
vec4 attr_load_vec4(vec4 attr)

View File

@ -6,6 +6,7 @@
* BxDF evaluation functions.
*/
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_base_lib.glsl)
/* -------------------------------------------------------------------- */

View File

@ -7,7 +7,7 @@
*/
#pragma BLENDER_REQUIRE(eevee_bxdf_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(draw_math_geom_lib.glsl)
/* -------------------------------------------------------------------- */
/** \name Microfacet GGX distribution
@ -17,7 +17,7 @@
float sample_pdf_ggx_reflect(float NH, float NV, float VH, float G1_V, float alpha)
{
float a2 = sqr(alpha);
float a2 = square(alpha);
#if GGX_USE_VISIBLE_NORMAL
return 0.25 * bxdf_ggx_D(NH, a2) * G1_V / NV;
#else
@ -28,10 +28,10 @@ float sample_pdf_ggx_reflect(float NH, float NV, float VH, float G1_V, float alp
float sample_pdf_ggx_refract(
float NH, float NV, float VH, float LH, float G1_V, float alpha, float eta)
{
float a2 = sqr(alpha);
float a2 = square(alpha);
float D = bxdf_ggx_D(NH, a2);
float Ht2 = sqr(eta * LH + VH);
return (D * G1_V * abs(VH * LH) * sqr(eta)) / (NV * Ht2);
float Ht2 = square(eta * LH + VH);
return (D * G1_V * abs(VH * LH) * square(eta)) / (NV * Ht2);
}
/**
@ -70,8 +70,8 @@ vec3 sample_ggx(vec3 rand, float alpha, vec3 Vt, out float G1_V)
return Ht;
#else
/* Theta is the cone angle. */
float z = sqrt((1.0 - rand.x) / (1.0 + sqr(alpha) * rand.x - rand.x)); /* cos theta */
float r = sqrt(max(0.0, 1.0 - z * z)); /* sin theta */
float z = sqrt((1.0 - rand.x) / (1.0 + square(alpha) * rand.x - rand.x)); /* cos theta */
float r = sqrt(max(0.0, 1.0 - z * z)); /* sin theta */
float x = r * rand.y;
float y = r * rand.z;
/* Microfacet Normal */

View File

@ -6,7 +6,7 @@
* Camera projection / uv functions and utils.
*/
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_base_lib.glsl)
/* -------------------------------------------------------------------- */
/** \name Panoramic Projections
@ -68,10 +68,10 @@ vec3 camera_mirror_ball_to_direction(CameraData cam, vec2 uv)
uv = uv * cam.uv_scale + cam.uv_bias;
vec3 dir;
dir.xy = uv * 2.0 - 1.0;
if (len_squared(dir.xy) > 1.0) {
if (length_squared(dir.xy) > 1.0) {
return vec3(0.0);
}
dir.z = -safe_sqrt(1.0 - sqr(dir.x) - sqr(dir.y));
dir.z = -safe_sqrt(1.0 - square(dir.x) - square(dir.y));
const vec3 I = vec3(0.0, 0.0, 1.0);
return reflect(I, dir);
}

View File

@ -38,3 +38,16 @@ vec4 colorspace_scene_linear_from_YCoCg(vec4 ycocg_color)
}
/** \} */
/**
* Clamp components to avoid black square artifacts if a pixel goes NaN or negative.
* Threshold is arbitrary.
*/
vec4 colorspace_safe_color(vec4 c)
{
return clamp(c, vec4(0.0), vec4(1e20));
}
vec3 colorspace_safe_color(vec3 c)
{
return clamp(c, vec3(0.0), vec3(1e20));
}

View File

@ -2,8 +2,8 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_lightprobe_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
void main()
{
@ -49,7 +49,7 @@ void main()
}
}
gl_Position = point_world_to_ndc(P);
gl_Position = drw_point_world_to_homogenous(P);
gl_Position.z -= 2.5e-5;
gl_PointSize = 3.0;
}

View File

@ -2,8 +2,8 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(gpu_shader_debug_gradients_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
vec3 debug_random_color(int v)
{

View File

@ -2,8 +2,8 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_matrix_lib.glsl)
void main()
{
@ -37,17 +37,15 @@ void main()
break;
}
vec3 N = surfel.normal;
vec3 T, B;
make_orthonormal_basis(N, T, B);
mat3x3 TBN = from_up_axis(surfel.normal);
mat4 model_matrix = mat4(vec4(T * debug_surfel_radius, 0),
vec4(B * debug_surfel_radius, 0),
vec4(N * debug_surfel_radius, 0),
mat4 model_matrix = mat4(vec4(TBN[0] * debug_surfel_radius, 0),
vec4(TBN[1] * debug_surfel_radius, 0),
vec4(TBN[2] * debug_surfel_radius, 0),
vec4(surfel.position, 1));
P = (model_matrix * vec4(lP, 1)).xyz;
gl_Position = point_world_to_ndc(P);
gl_Position = drw_point_world_to_homogenous(P);
gl_Position.z -= 2.5e-5;
}

View File

@ -6,8 +6,8 @@
* Compute light objects lighting contribution using captured Gbuffer data.
*/
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_gbuffer_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_light_eval_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_lightprobe_eval_lib.glsl)
@ -24,10 +24,10 @@ void main()
stack.cl[0].ltc_mat = LTC_LAMBERT_MAT;
stack.cl[0].type = LIGHT_DIFFUSE;
vec3 P = get_world_space_from_depth(uvcoordsvar.xy, depth);
vec3 P = drw_point_screen_to_world(vec3(uvcoordsvar.xy, depth));
vec3 Ng = stack.cl[0].N;
vec3 V = cameraVec(P);
float vPz = dot(cameraForward, P) - dot(cameraForward, cameraPos);
vec3 V = drw_world_incident_vector(P);
float vPz = dot(drw_view_forward(), P) - dot(drw_view_forward(), drw_view_position());
/* Direct light. */
light_eval(stack, P, Ng, V, vPz, gbuf.thickness);

View File

@ -6,12 +6,12 @@
* Compute light objects lighting contribution using Gbuffer data.
*/
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_gbuffer_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_renderpass_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_light_eval_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_thickness_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_subsurface_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
void main()
{
@ -20,8 +20,12 @@ void main()
float depth = texelFetch(hiz_tx, texel, 0).r;
GBufferData gbuf = gbuffer_read(gbuf_header_tx, gbuf_closure_tx, gbuf_color_tx, texel);
vec3 P = get_world_space_from_depth(uvcoordsvar.xy, depth);
vec3 V = cameraVec(P);
vec3 P = drw_point_screen_to_world(vec3(uvcoordsvar.xy, depth));
/* Assume reflection closure normal is always somewhat representative of the geometric normal.
* Ng is only used for shadow biases and subsurface check in this case. */
vec3 Ng = gbuf.has_reflection ? gbuf.reflection.N : gbuf.diffuse.N;
vec3 V = drw_world_incident_vector(P);
float vPz = dot(drw_view_forward(), P) - dot(drw_view_forward(), drw_view_position());
ClosureLightStack stack;
@ -45,11 +49,6 @@ void main()
stack.cl[2] = cl_sss;
#endif
/* Assume reflection closure normal is always somewhat representative of the geometric normal.
* Ng is only used for shadow biases and subsurface check in this case. */
vec3 Ng = gbuf.has_reflection ? gbuf.reflection.N : gbuf.diffuse.N;
float vPz = dot(cameraForward, P) - dot(cameraForward, cameraPos);
#ifdef SSS_TRANSMITTANCE
float shadow_thickness = thickness_from_shadow(P, Ng, vPz);
float thickness = (shadow_thickness != THICKNESS_NO_VALUE) ?
@ -90,7 +89,7 @@ void main()
/* TODO(fclem): Change shadow pass to be colored. */
vec3 shadows = radiance_shadowed * safe_rcp(radiance_unshadowed);
output_renderpass_value(uniform_buf.render_pass.shadow_id, avg(shadows));
output_renderpass_value(uniform_buf.render_pass.shadow_id, average(shadows));
imageStore(direct_diffuse_img, texel, vec4(radiance_diffuse, 1.0));
imageStore(direct_reflect_img, texel, vec4(radiance_specular, 1.0));

View File

@ -6,8 +6,8 @@
* Compute light objects lighting contribution using captured Gbuffer data.
*/
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_gbuffer_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_light_eval_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_lightprobe_eval_lib.glsl)
@ -19,10 +19,10 @@ void main()
GBufferData gbuf = gbuffer_read(gbuf_header_tx, gbuf_closure_tx, gbuf_color_tx, texel);
vec3 P = get_world_space_from_depth(uvcoordsvar.xy, depth);
vec3 P = drw_point_screen_to_world(vec3(uvcoordsvar.xy, depth));
vec3 Ng = gbuf.diffuse.N;
vec3 V = cameraVec(P);
float vPz = dot(cameraForward, P) - dot(cameraForward, cameraPos);
vec3 V = drw_world_incident_vector(P);
float vPz = dot(drw_view_forward(), P) - dot(drw_view_forward(), drw_view_position());
ClosureLightStack stack;
stack.cl[0].N = gbuf.diffuse.N;

View File

@ -8,10 +8,12 @@
* One is for the half-resolution gather passes and the other one for slight in focus regions.
*/
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_debug_gradients_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_matrix_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_colorspace_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_depth_of_field_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
/* -------------------------------------------------------------------- */
/** \name Options.
@ -316,7 +318,7 @@ void dof_gather_accumulate_center_sample(DofGatherData center_data,
if (is_foreground && !is_resolve) {
/* Reduce issue with closer foreground over distant foreground. */
float ring_area = sqr(bordering_radius);
float ring_area = square(bordering_radius);
dof_gather_ammend_weight(center_data, ring_area);
}
@ -468,7 +470,7 @@ void dof_gather_accumulator(sampler2D color_tx,
int sample_pair_count = gather_ring_density * ring;
float step_rot = M_PI / float(sample_pair_count);
mat2 step_rot_mat = rot2_from_angle(step_rot);
mat2 step_rot_mat = from_rotation(Angle(step_rot));
float angle_offset = noise.y * step_rot;
vec2 offset = vec2(cos(angle_offset), sin(angle_offset));
@ -516,9 +518,9 @@ void dof_gather_accumulator(sampler2D color_tx,
if (is_foreground) {
/* Reduce issue with closer foreground over distant foreground. */
/* TODO(fclem) this seems to not be completely correct as the issue remains. */
float ring_area = (sqr(float(ring) + 0.5 + coc_radius_error) -
sqr(float(ring) - 0.5 + coc_radius_error)) *
sqr(base_radius * unit_sample_radius);
float ring_area = (square(float(ring) + 0.5 + coc_radius_error) -
square(float(ring) - 0.5 + coc_radius_error)) *
square(base_radius * unit_sample_radius);
dof_gather_ammend_weight(ring_data, ring_area);
}
@ -574,13 +576,13 @@ void dof_gather_accumulator(sampler2D color_tx,
if (debug_gather_perf && density_change > 0) {
float fac = saturate(float(density_change) / float(10.0));
out_color.rgb = avg(out_color.rgb) * neon_gradient(fac);
out_color.rgb = average(out_color.rgb) * neon_gradient(fac);
}
if (debug_gather_perf && do_fast_gather) {
out_color.rgb = avg(out_color.rgb) * vec3(0.0, 1.0, 0.0);
out_color.rgb = average(out_color.rgb) * vec3(0.0, 1.0, 0.0);
}
if (debug_scatter_perf) {
out_color.rgb = avg(out_color.rgb) * vec3(0.0, 1.0, 0.0);
out_color.rgb = average(out_color.rgb) * vec3(0.0, 1.0, 0.0);
}
/* Output premultiplied color so we can use bilinear sampler in resolve pass. */
@ -616,7 +618,7 @@ void dof_slight_focus_gather(depth2D depth_tx,
const float sample_count_max = float(DOF_SLIGHT_FOCUS_SAMPLE_MAX);
/* Scale by search area. */
float sample_count = sample_count_max * saturate(sqr(radius) / sqr(dof_layer_threshold));
float sample_count = sample_count_max * saturate(square(radius) / square(dof_layer_threshold));
bool first_ring = true;
@ -632,7 +634,7 @@ void dof_slight_focus_gather(depth2D depth_tx,
vec2 sample_uv = (frag_coord + sample_offset) / vec2(textureSize(depth_tx, 0));
float depth = textureLod(depth_tx, sample_uv, 0.0).r;
pair_data[i].coc = dof_coc_from_depth(dof_buf, sample_uv, depth);
pair_data[i].color = safe_color(textureLod(color_tx, sample_uv, 0.0));
pair_data[i].color = colorspace_safe_color(textureLod(color_tx, sample_uv, 0.0));
pair_data[i].dist = ring_dist;
if (DOF_BOKEH_TEXTURE) {
/* Contains sub-pixel distance to bokeh shape. */
@ -668,7 +670,7 @@ void dof_slight_focus_gather(depth2D depth_tx,
/* Center sample. */
vec2 sample_uv = frag_coord / vec2(textureSize(depth_tx, 0));
DofGatherData center_data;
center_data.color = safe_color(textureLod(color_tx, sample_uv, 0.0));
center_data.color = colorspace_safe_color(textureLod(color_tx, sample_uv, 0.0));
center_data.coc = dof_coc_from_depth(dof_buf, sample_uv, textureLod(depth_tx, sample_uv, 0.0).r);
center_data.coc = clamp(center_data.coc, -dof_buf.coc_abs_max, dof_buf.coc_abs_max);
center_data.dist = 0.0;

View File

@ -24,7 +24,7 @@ void main()
if (dof_buf.bokeh_blades > 0.0) {
/* NOTE: atan(y,x) has output range [-M_PI..M_PI], so add 2pi to avoid negative angles. */
float theta = atan(gather_uv.y, gather_uv.x) + M_2PI;
float theta = atan(gather_uv.y, gather_uv.x) + M_TAU;
float r = length(gather_uv);
radius /= circle_to_polygon_radius(dof_buf.bokeh_blades, theta - dof_buf.bokeh_rotation);
@ -39,7 +39,7 @@ void main()
{
/* Slight focus distance */
slight_focus_texel *= dof_buf.bokeh_anisotropic_scale_inv;
float theta = atan(slight_focus_texel.y, -slight_focus_texel.x) + M_2PI;
float theta = atan(slight_focus_texel.y, -slight_focus_texel.x) + M_TAU;
slight_focus_texel /= circle_to_polygon_radius(dof_buf.bokeh_blades,
theta + dof_buf.bokeh_rotation);
}

View File

@ -9,6 +9,7 @@
* Also does not weight luma for the bilateral weights.
*/
#pragma BLENDER_REQUIRE(gpu_shader_math_vector_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_depth_of_field_lib.glsl)
void main()
@ -27,7 +28,7 @@ void main()
vec4 weights = dof_bilateral_coc_weights(cocs);
/* Normalize so that the sum is 1. */
weights *= safe_rcp(sum(weights));
weights *= safe_rcp(reduce_add(weights));
vec4 out_color = weighted_sum_array(colors, weights);

View File

@ -6,8 +6,9 @@
* Depth of Field utils.
*/
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_base_lib.glsl)
/* -------------------------------------------------------------------- */
/** \name Constants.
@ -114,10 +115,10 @@ float dof_coc_from_depth(DepthOfFieldData dof_data, vec2 uv, float depth)
{
if (is_panoramic(dof_data.camera_type)) {
/* Use radial depth. */
depth = -length(get_view_space_from_depth(uv, depth));
depth = -length(drw_point_screen_to_view(vec3(uv, depth)));
}
else {
depth = get_view_z_from_depth(depth);
depth = drw_depth_screen_to_view(depth);
}
return coc_radius_from_camera_depth(dof_data, depth);
}
@ -153,7 +154,7 @@ vec4 dof_layer_weight(vec4 coc)
float dof_sample_weight(float coc)
{
#if 1 /* Optimized */
return min(1.0, 1.0 / sqr(coc));
return min(1.0, 1.0 / square(coc));
#else
/* Full intensity if CoC radius is below the pixel footprint. */
const float min_coc = 1.0;
@ -164,7 +165,7 @@ float dof_sample_weight(float coc)
vec4 dof_sample_weight(vec4 coc)
{
#if 1 /* Optimized */
return min(vec4(1.0), 1.0 / sqr(coc));
return min(vec4(1.0), 1.0 / square(coc));
#else
/* Full intensity if CoC radius is below the pixel footprint. */
const float min_coc = 1.0;

View File

@ -16,6 +16,7 @@
*/
#pragma BLENDER_REQUIRE(eevee_depth_of_field_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_vector_lib.glsl)
/* NOTE: Do not compare alpha as it is not scattered by the scatter pass. */
float dof_scatter_neighborhood_rejection(vec3 color)
@ -34,7 +35,7 @@ float dof_scatter_neighborhood_rejection(vec3 color)
vec3 ref = textureLod(downsample_tx, sample_uv, 0.0).rgb;
ref = min(vec3(dof_buf.scatter_neighbor_max_color), ref);
float diff = max_v3(max(vec3(0.0), abs(ref - color)));
float diff = reduce_max(max(vec3(0.0), abs(ref - color)));
const float rejection_threshold = 0.7;
diff = saturate(diff / rejection_threshold - 1.0);
@ -51,7 +52,7 @@ float dof_scatter_screen_border_rejection(float coc, ivec2 texel)
vec2 screen_size = vec2(imageSize(inout_color_lod0_img));
vec2 uv = (vec2(texel) + 0.5) / screen_size;
vec2 screen_pos = uv * screen_size;
float min_screen_border_distance = min_v2(min(screen_pos, screen_size - screen_pos));
float min_screen_border_distance = reduce_min(min(screen_pos, screen_size - screen_pos));
/* Full-resolution to half-resolution CoC. */
coc *= 0.5;
/* Allow 10px transition. */
@ -62,7 +63,7 @@ float dof_scatter_screen_border_rejection(float coc, ivec2 texel)
float dof_scatter_luminosity_rejection(vec3 color)
{
const float rejection_hardness = 1.0;
return saturate(max_v3(color - dof_buf.scatter_color_threshold) * rejection_hardness);
return saturate(reduce_max(color - dof_buf.scatter_color_threshold) * rejection_hardness);
}
float dof_scatter_coc_radius_rejection(float coc)
@ -118,7 +119,7 @@ void main()
do_scatter4.w = do_scatter[LOCAL_OFFSET(0, 0)];
if (any(greaterThan(do_scatter4, vec4(0.0)))) {
/* Apply energy conservation to anamorphic scattered bokeh. */
do_scatter4 *= max_v2(dof_buf.bokeh_anisotropic_scale_inv);
do_scatter4 *= reduce_max(dof_buf.bokeh_anisotropic_scale_inv);
/* Circle of Confusion. */
vec4 coc4;
@ -132,7 +133,7 @@ void main()
vec2 offset = vec2(gl_GlobalInvocationID.xy) + 1;
/* Add 2.5 to max_coc because the max_coc may not be centered on the sprite origin
* and because we smooth the bokeh shape a bit in the pixel shader. */
vec2 half_extent = max_v4(abs(coc4)) * dof_buf.bokeh_anisotropic_scale + 2.5;
vec2 half_extent = reduce_max(abs(coc4)) * dof_buf.bokeh_anisotropic_scale + 2.5;
/* Issue a sprite for each field if any CoC matches. */
if (any(lessThan(do_scatter4 * sign(coc4), vec4(0.0)))) {
/* Same value for all threads. Not an issue if we don't sync access to it. */
@ -226,7 +227,7 @@ void main()
vec4 weights = dof_bilateral_coc_weights(coc4);
weights *= dof_bilateral_color_weights(colors);
/* Normalize so that the sum is 1. */
weights *= safe_rcp(sum(weights));
weights *= safe_rcp(reduce_add(weights));
color_cache[LOCAL_INDEX] = weighted_sum_array(colors, weights);
coc_cache[LOCAL_INDEX] = dot(coc4, weights);

View File

@ -72,11 +72,11 @@ vec3 dof_neighborhood_clamp(vec2 frag_coord, vec3 color, float center_coc, float
neighbor_max = (i == 0) ? ycocg_sample : max(neighbor_max, ycocg_sample);
}
/* Pad the bounds in the near in focus region to get back a bit of detail. */
float padding = 0.125 * saturate(1.0 - sqr(center_coc) / sqr(8.0));
float padding = 0.125 * saturate(1.0 - square(center_coc) / square(8.0));
neighbor_max += abs(neighbor_min) * padding;
neighbor_min -= abs(neighbor_min) * padding;
/* Progressively apply the clamp to avoid harsh transition. Also mask by weight. */
float fac = saturate(sqr(center_coc) * 4.0) * weight;
float fac = saturate(square(center_coc) * 4.0) * weight;
/* Clamp in YCoCg space to avoid too much color drift. */
color = colorspace_YCoCg_from_scene_linear(color);
color = mix(color, clamp(color, neighbor_min, neighbor_max), fac);
@ -154,7 +154,7 @@ void main()
}
if (!no_focus_pass && prediction.do_focus) {
layer_color = safe_color(textureLod(color_tx, uv, 0.0));
layer_color = colorspace_safe_color(textureLod(color_tx, uv, 0.0));
layer_weight = 1.0;
/* Composite in focus. */
out_color = out_color * (1.0 - layer_weight) + layer_color;

View File

@ -10,6 +10,7 @@
*/
#pragma BLENDER_REQUIRE(eevee_depth_of_field_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_vector_lib.glsl)
#define linearstep(p0, p1, v) (clamp(((v) - (p0)) / abs((p1) - (p0)), 0.0, 1.0))
@ -38,7 +39,7 @@ void main()
/* Smooth the edges a bit to fade out the undersampling artifacts. */
shapes = saturate(1.0 - linearstep(-0.8, 0.8, shapes));
/* Outside of bokeh shape. Try to avoid overloading ROPs. */
if (max_v4(shapes) == 0.0) {
if (reduce_max(shapes) == 0.0) {
discard;
return;
}
@ -52,7 +53,7 @@ void main()
/* Occlude the sprite with geometry from the same field using a chebychev test (slide 85). */
float mean = occlusion_data.x;
float variance = occlusion_data.y;
shapes *= variance * safe_rcp(variance + sqr(max(coc4 * correction_fac - mean, 0.0)));
shapes *= variance * safe_rcp(variance + square(max(coc4 * correction_fac - mean, 0.0)));
}
out_color = (interp_flat.color_and_coc1 * shapes[0] + interp_flat.color_and_coc2 * shapes[1] +
@ -61,6 +62,6 @@ void main()
out_color.a = 0.0;
if (debug_scatter_perf) {
out_color.rgb = avg(out_color.rgb) * vec3(1.0, 0.0, 0.0);
out_color.rgb = average(out_color.rgb) * vec3(1.0, 0.0, 0.0);
}
}

View File

@ -10,6 +10,7 @@
*/
#pragma BLENDER_REQUIRE(eevee_depth_of_field_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_vector_lib.glsl)
void main()
{
@ -36,7 +37,7 @@ void main()
interp_noperspective.rect_uv3 = ((uv + quad_offsets[2]) * uv_div) * 0.5 + 0.5;
interp_noperspective.rect_uv4 = ((uv + quad_offsets[3]) * uv_div) * 0.5 + 0.5;
/* Only for sampling. */
interp_flat.distance_scale *= max_v2(abs(rect.half_extent));
interp_flat.distance_scale *= reduce_max(abs(rect.half_extent));
}
else {
interp_flat.distance_scale = 1.0;

View File

@ -14,9 +14,10 @@
* Half-resolution Color, signed CoC (out_coc.x), and max slight focus abs CoC (out_coc.y).
*/
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_depth_of_field_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_colorspace_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_vector_lib.glsl)
void main()
{
@ -29,7 +30,7 @@ void main()
for (int i = 0; i < 4; i++) {
vec2 sample_uv = quad_center + quad_offsets[i] * fullres_texel_size;
/* NOTE: We use samplers without filtering. */
colors[i] = safe_color(textureLod(color_tx, sample_uv, 0.0));
colors[i] = colorspace_safe_color(textureLod(color_tx, sample_uv, 0.0));
cocs[i] = dof_coc_from_depth(dof_buf, sample_uv, textureLod(depth_tx, sample_uv, 0.0).r);
}
@ -38,7 +39,7 @@ void main()
vec4 weights = dof_bilateral_coc_weights(cocs);
weights *= dof_bilateral_color_weights(colors);
/* Normalize so that the sum is 1. */
weights *= safe_rcp(sum(weights));
weights *= safe_rcp(reduce_add(weights));
ivec2 out_texel = ivec2(gl_GlobalInvocationID.xy);
vec4 out_color = weighted_sum_array(colors, weights);

View File

@ -17,7 +17,6 @@
* - Stabilized Color and CoC (half-resolution).
*/
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_colorspace_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_depth_of_field_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_velocity_lib.glsl)
@ -263,7 +262,7 @@ DofSample dof_sample_history(vec2 input_texel)
color += textureLod(in_history_tx, vec2(uv_3.x, uv_12.y), 0.0) * weight_cross.z;
color += textureLod(in_history_tx, vec2(uv_12.x, uv_3.y), 0.0) * weight_cross.w;
/* Re-normalize for the removed corners. */
color /= (weight_center + sum(weight_cross));
color /= (weight_center + reduce_add(weight_cross));
#endif
/* NOTE(fclem): Opacity is wrong on purpose. Final Opacity does not rely on history. */
return DofSample(color.xyzz, color.w);
@ -306,7 +305,7 @@ float dof_history_blend_factor(
* "High Quality Temporal Supersampling" by Brian Karis at Siggraph 2014 (Slide 43)
* Bias towards history if incoming pixel is near clamping. Reduces flicker.
*/
float distance_to_luma_clip = min_v2(vec2(luma_history - luma_min, luma_max - luma_history));
float distance_to_luma_clip = reduce_min(vec2(luma_history - luma_min, luma_max - luma_history));
/* Divide by bbox size to get a factor. 2 factor to compensate the line above. */
distance_to_luma_clip *= 2.0 * safe_rcp(luma_max - luma_min);
/* Linearly blend when history gets below to 25% of the bbox size. */

View File

@ -3,8 +3,8 @@
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(eevee_spherical_harmonics_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_matrix_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
void main()
{
@ -24,7 +24,7 @@ void main()
float validity = texelFetch(validity_tx, cell, 0).r;
vec3 vN = vec3(lP, sqrt(max(0.0, 1.0 - dist_sqr)));
vec3 N = normal_view_to_world(vN);
vec3 N = drw_normal_view_to_world(vN);
vec3 lN = transform_direction(world_to_grid, N);
vec3 irradiance = spherical_harmonics_evaluate_lambert(lN, sh);

View File

@ -2,7 +2,7 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_lightprobe_lib.glsl)
void main()
@ -35,9 +35,9 @@ void main()
}
vec3 vs_offset = vec3(lP, 0.0) * sphere_radius_final;
vec3 vP = (ViewMatrix * vec4(ws_cell_pos, 1.0)).xyz + vs_offset;
vec3 vP = drw_point_world_to_view(ws_cell_pos) + vs_offset;
gl_Position = ProjectionMatrix * vec4(vP, 1.0);
gl_Position = drw_point_view_to_homogenous(vP);
/* Small bias to let the icon draw without Z-fighting. */
gl_Position.z += 0.0001;
}

View File

@ -2,7 +2,6 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_film_lib.glsl)
void main()

View File

@ -2,7 +2,7 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_base_lib.glsl)
#define CRYPTOMATTE_LEVELS_MAX 16

View File

@ -2,7 +2,6 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_film_lib.glsl)
void main()
@ -33,7 +32,7 @@ void main()
film_process_data(texel_film, out_color, out_depth);
}
gl_FragDepth = get_depth_from_view_z(-out_depth);
gl_FragDepth = drw_depth_view_to_screen(-out_depth);
gl_FragDepth = film_display_depth_ammend(texel_film, gl_FragDepth);
}

View File

@ -6,12 +6,12 @@
* Film accumulation utils functions.
*/
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_camera_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_velocity_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_colorspace_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_cryptomatte_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_vector_lib.glsl)
#pragma BLENDER_REQUIRE(draw_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_velocity_lib.glsl)
/* Return scene linear Z depth from the camera or radial depth for panoramic cameras. */
float film_depth_convert_to_scene(float depth)
@ -20,7 +20,7 @@ float film_depth_convert_to_scene(float depth)
/* TODO */
return 1.0;
}
return abs(get_view_z_from_depth(depth));
return abs(drw_depth_screen_to_view(depth));
}
/* Load a texture sample in a specific format. Combined pass needs to use this. */
@ -70,7 +70,7 @@ FilmSample film_sample_get(int sample_n, ivec2 texel_film)
* can be used by many final pixel. */
vec2 offset = uniform_buf.film.subpixel_offset -
vec2(texel_film % uniform_buf.film.scaling_factor);
film_sample.weight = film_filter_weight(uniform_buf.film.filter_size, len_squared(offset));
film_sample.weight = film_filter_weight(uniform_buf.film.filter_size, length_squared(offset));
# endif
#endif /* PANORAMIC */
@ -119,7 +119,7 @@ void film_sample_accum_mist(FilmSample samp, inout float accum)
}
float depth = texelFetch(depth_tx, samp.texel, 0).x;
vec2 uv = (vec2(samp.texel) + 0.5) / vec2(textureSize(depth_tx, 0).xy);
vec3 vP = get_view_space_from_depth(uv, depth);
vec3 vP = drw_point_screen_to_view(vec3(uv, depth));
bool is_persp = ProjectionMatrix[3][3] == 0.0;
float mist = (is_persp) ? length(vP) : abs(vP.z);
/* Remap to 0..1 range. */
@ -312,7 +312,7 @@ vec4 film_sample_catmull_rom(sampler2D color_tx, vec2 input_texel)
color += textureLod(color_tx, vec2(uv_3.x, uv_12.y), 0.0) * weight_cross.z;
color += textureLod(color_tx, vec2(uv_12.x, uv_3.y), 0.0) * weight_cross.w;
/* Re-normalize for the removed corners. */
return color / (weight_center + sum(weight_cross));
return color / (weight_center + reduce_add(weight_cross));
#else /* Nearest interpolation for debugging. 1 Tap. */
ivec2 texel = ivec2(center_texel) + ivec2(greaterThan(inter_texel, vec2(0.5)));
@ -343,7 +343,7 @@ void film_combined_neighbor_boundbox(ivec2 texel, out vec4 min_c, out vec4 max_c
for (int i = 0; i < 5; i++) {
vec4 color = film_texelfetch_as_YCoCg_opacity(combined_tx, texel + plus_offsets[i]);
mu1 += color;
mu2 += sqr(color);
mu2 += square(color);
}
mu1 *= (1.0 / 5.0);
mu2 *= (1.0 / 5.0);
@ -352,7 +352,7 @@ void film_combined_neighbor_boundbox(ivec2 texel, out vec4 min_c, out vec4 max_c
* Balance between more flickering (0.75) or more ghosting (1.25). */
const float gamma = 1.25;
/* Standard deviation. */
vec4 sigma = sqrt(abs(mu2 - sqr(mu1)));
vec4 sigma = sqrt(abs(mu2 - square(mu1)));
/* eq. 6 in "A Survey of Temporal Anti-aliasing Techniques". */
min_c = mu1 - gamma * sigma;
max_c = mu1 + gamma * sigma;
@ -425,7 +425,7 @@ float film_history_blend_factor(float velocity,
* "High Quality Temporal Supersampling" by Brian Karis at Siggraph 2014 (Slide 43)
* Bias towards history if incoming pixel is near clamping. Reduces flicker.
*/
float distance_to_luma_clip = min_v2(vec2(luma_history - luma_min, luma_max - luma_history));
float distance_to_luma_clip = reduce_min(vec2(luma_history - luma_min, luma_max - luma_history));
/* Divide by bbox size to get a factor. 2 factor to compensate the line above. */
distance_to_luma_clip *= 2.0 * safe_rcp(luma_max - luma_min);
/* Linearly blend when history gets below to 25% of the bbox size. */

View File

@ -2,13 +2,12 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_hair_lib.glsl) /* TODO rename to curve. */
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(draw_model_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_attributes_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_nodetree_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_surf_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_velocity_lib.glsl)
#pragma BLENDER_REQUIRE(common_hair_lib.glsl) /* TODO rename to curve. */
void main()
{
@ -58,5 +57,5 @@ void main()
clip_interp.clip_distance = dot(clip_plane.plane, vec4(interp.P, 1.0));
#endif
gl_Position = point_world_to_ndc(interp.P);
gl_Position = drw_point_world_to_homogenous(interp.P);
}

View File

@ -2,8 +2,9 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_gpencil_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(draw_model_lib.glsl)
/* Grease pencil includes commmon_view_lib. */
// #pragma BLENDER_REQUIRE(common_gpencil_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_attributes_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_surf_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_velocity_lib.glsl)
@ -38,7 +39,7 @@ void main()
hardness);
#ifdef MAT_VELOCITY
/* GPencil do not support deformation motion blur. */
vec3 lP_curr = transform_point(ModelMatrixInverse, interp.P);
vec3 lP_curr = drw_point_world_to_object(interp.P);
/* FIXME(fclem): Evaluating before displacement avoid displacement being treated as motion but
* ignores motion from animated displacement. Supporting animated displacement motion vectors
* would require evaluating the node-tree multiple time with different node-tree UBOs evaluated

View File

@ -2,7 +2,7 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(draw_model_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_attributes_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_nodetree_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_surf_lib.glsl)
@ -17,8 +17,8 @@ void main()
init_interface();
interp.P = point_object_to_world(pos);
interp.N = normal_object_to_world(nor);
interp.P = drw_point_object_to_world(pos);
interp.N = drw_normal_object_to_world(nor);
#ifdef MAT_VELOCITY
vec3 prv, nxt;
velocity_local_pos_get(pos, gl_VertexID, prv, nxt);
@ -39,5 +39,5 @@ void main()
clip_interp.clip_distance = dot(clip_plane.plane, vec4(interp.P, 1.0));
#endif
gl_Position = point_world_to_ndc(interp.P);
gl_Position = drw_point_world_to_homogenous(interp.P);
}

View File

@ -2,13 +2,13 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(draw_model_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_rotation_lib.glsl)
#pragma BLENDER_REQUIRE(common_pointcloud_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_attributes_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_nodetree_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_surf_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_velocity_lib.glsl)
#pragma BLENDER_REQUIRE(common_pointcloud_lib.glsl)
void main()
{
@ -27,11 +27,11 @@ void main()
* Apply a bias to avoid self-shadow issues. */
/* TODO(fclem): remove multiplication here. Here only for keeping the size correct for now. */
float actual_radius = point_cloud_interp.radius * 0.01;
interp.P -= cameraVec(interp.P) * actual_radius;
interp.P -= drw_world_incident_vector(interp.P) * actual_radius;
#endif
#ifdef MAT_VELOCITY
vec3 lP = point_world_to_object(point_cloud_interp.position);
vec3 lP = drw_point_world_to_object(point_cloud_interp.position);
vec3 prv, nxt;
velocity_local_pos_get(lP, point_cloud_interp_flat.id, prv, nxt);
/* FIXME(fclem): Evaluating before displacement avoid displacement being treated as motion but
@ -51,5 +51,5 @@ void main()
clip_interp.clip_distance = dot(clip_plane.plane, vec4(interp.P, 1.0));
#endif
gl_Position = point_world_to_ndc(interp.P);
gl_Position = drw_point_world_to_homogenous(interp.P);
}

View File

@ -6,7 +6,7 @@
* Custom full-screen triangle with placeholders varyings.
*/
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_nodetree_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_surf_lib.glsl)
@ -19,6 +19,6 @@ void main()
gl_Position = vec4(x, y, 1.0, 1.0);
/* Pass view position to keep accuracy. */
interp.P = project_point(ProjectionMatrixInverse, gl_Position.xyz);
interp.P = drw_point_ndc_to_view(gl_Position.xyz);
interp.N = vec3(1);
}

View File

@ -17,7 +17,7 @@
* downsample to max level.
*/
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_vector_lib.glsl)
shared float local_depths[gl_WorkGroupSize.y][gl_WorkGroupSize.x];
@ -59,7 +59,7 @@ void main()
}
/* Level 1. (No load) */
float max_depth = max_v4(samp);
float max_depth = reduce_max(samp);
ivec2 dst_px = ivec2(kernel_origin + local_px);
imageStore(out_mip_1, dst_px, vec4(max_depth));
store_local_depth(local_px, max_depth);
@ -72,7 +72,7 @@ void main()
active_thread = all(lessThan(uvec2(local_px), gl_WorkGroupSize.xy >> uint(mask_shift))); \
barrier(); /* Wait for previous writes to finish. */ \
if (active_thread) { \
max_depth = max_v4(load_local_depths(local_px)); \
max_depth = reduce_max(load_local_depths(local_px)); \
dst_px = ivec2((kernel_origin >> mask_shift) + local_px); \
imageStore(out_mip__, dst_px, vec4(max_depth)); \
} \
@ -109,7 +109,7 @@ void main()
samp.z = imageLoad(out_mip_5, min(src_px + ivec2(1, 0), image_border)).x;
samp.w = imageLoad(out_mip_5, min(src_px + ivec2(0, 0), image_border)).x;
/* Level 6. */
float max_depth = max_v4(samp);
float max_depth = reduce_max(samp);
ivec2 dst_px = ivec2(kernel_origin + local_px);
imageStore(out_mip_6, dst_px, vec4(max_depth));
store_local_depth(local_px, max_depth);

View File

@ -8,8 +8,8 @@
* pass is not conservative enough).
*/
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_debug_gradients_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_light_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_light_iter_lib.glsl)
@ -18,8 +18,8 @@ void main()
ivec2 texel = ivec2(gl_FragCoord.xy);
float depth = texelFetch(hiz_tx, texel, 0).r;
float vP_z = get_view_z_from_depth(depth);
vec3 P = get_world_space_from_depth(uvcoordsvar.xy, depth);
float vP_z = drw_depth_screen_to_view(depth);
vec3 P = drw_point_screen_to_world(vec3(uvcoordsvar.xy, depth));
float light_count = 0.0;
uint light_cull = 0u;

View File

@ -6,9 +6,9 @@
* Select the visible items inside the active view and put them inside the sorting buffer.
*/
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(common_intersect_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(draw_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(draw_intersect_lib.glsl)
void main()
{
@ -62,7 +62,9 @@ void main()
if (intersect_view(sphere)) {
uint index = atomicAdd(light_cull_buf.visible_count, 1u);
out_zdist_buf[index] = dot(cameraForward, light._position) - dot(cameraForward, cameraPos);
float z_dist = dot(drw_view_forward(), light._position) -
dot(drw_view_forward(), drw_view_position());
out_zdist_buf[index] = z_dist;
out_key_buf[index] = l_idx;
}
}

View File

@ -8,7 +8,7 @@
* One thread processes one Light entity.
*/
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_base_lib.glsl)
shared float zdists_cache[gl_WorkGroupSize.x];

View File

@ -8,7 +8,7 @@
* Dispatch one thread per word.
*/
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_intersect_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_light_iter_lib.glsl)
@ -148,10 +148,10 @@ void main()
LightData light = light_buf[l_idx];
/* Culling in view space for precision and simplicity. */
vec3 vP = transform_point(ViewMatrix, light._position);
vec3 v_right = transform_direction(ViewMatrix, light._right);
vec3 v_up = transform_direction(ViewMatrix, light._up);
vec3 v_back = transform_direction(ViewMatrix, light._back);
vec3 vP = drw_point_world_to_view(light._position);
vec3 v_right = drw_normal_world_to_view(light._right);
vec3 v_up = drw_normal_world_to_view(light._up);
vec3 v_back = drw_normal_world_to_view(light._back);
float radius = light.influence_radius_max;
Sphere sphere = shape_sphere(vP, radius);

View File

@ -8,7 +8,8 @@
* For this reason, we only dispatch 1 thread group.
*/
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_base_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_light_iter_lib.glsl)
/* Fits the limit of 32KB. */
@ -37,7 +38,7 @@ void main()
vec3 P = light_buf[index]._position;
/* TODO(fclem): Could have better bounds for spot and area lights. */
float radius = light_buf[index].influence_radius_max;
float z_dist = dot(cameraForward, P) - dot(cameraForward, cameraPos);
float z_dist = dot(drw_view_forward(), P) - dot(drw_view_forward(), drw_view_position());
int z_min = culling_z_to_zbin(
light_cull_buf.zbin_scale, light_cull_buf.zbin_bias, z_dist + radius);
int z_max = culling_z_to_zbin(

View File

@ -2,7 +2,12 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
uint bitfield_mask(uint bit_width, uint bit_min)
{
/* Cannot bit shift more than 31 positions. */
uint mask = (bit_width > 31u) ? 0x0u : (0xFFFFFFFFu << bit_width);
return ~mask << bit_min;
}
uint zbin_mask(uint word_index, uint zbin_min, uint zbin_max)
{
@ -11,7 +16,7 @@ uint zbin_mask(uint word_index, uint zbin_min, uint zbin_max)
uint local_min = max(zbin_min, word_start);
uint local_max = min(zbin_max, word_end);
uint mask_width = local_max - local_min + 1;
return bit_field_mask(mask_width, local_min);
return bitfield_mask(mask_width, local_min);
}
int culling_z_to_zbin(float scale, float bias, float z)

View File

@ -2,7 +2,7 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(draw_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_ltc_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_light_iter_lib.glsl)
@ -29,7 +29,7 @@ LightVector light_vector_get(LightData light, const bool is_directional, vec3 P)
}
else {
lv.L = light._position - P;
float inv_distance = inversesqrt(len_squared(lv.L));
float inv_distance = inversesqrt(length_squared(lv.L));
lv.L *= inv_distance;
lv.dist = 1.0 / inv_distance;
}
@ -56,7 +56,7 @@ LightVector light_shape_vector_get(LightData light, const bool is_directional, v
vec3 L_prime = light._right * closest_point.x + light._up * closest_point.y;
L = L_prime - L;
float inv_distance = inversesqrt(len_squared(L));
float inv_distance = inversesqrt(length_squared(L));
LightVector lv;
lv.L = L * inv_distance;
lv.dist = 1.0 / inv_distance;
@ -89,15 +89,15 @@ vec3 light_local_position_to_world(LightData light, vec3 lP)
* http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf */
float light_influence_attenuation(float dist, float inv_sqr_influence)
{
float factor = sqr(dist) * inv_sqr_influence;
float fac = saturate(1.0 - sqr(factor));
return sqr(fac);
float factor = square(dist) * inv_sqr_influence;
float fac = saturate(1.0 - square(factor));
return square(fac);
}
float light_spot_attenuation(LightData light, vec3 L)
{
vec3 lL = light_world_to_local(light, L);
float ellipse = inversesqrt(1.0 + len_squared(lL.xy * light.spot_size_inv / lL.z));
float ellipse = inversesqrt(1.0 + length_squared(lL.xy * light.spot_size_inv / lL.z));
float spotmask = smoothstep(0.0, 1.0, ellipse * light._spot_mul + light._spot_bias);
return spotmask * step(0.0, -dot(L, -light._back));
}
@ -156,7 +156,7 @@ float light_point_light(LightData light, const bool is_directional, LightVector
* http://www.cemyuksel.com/research/pointlightattenuation/pointlightattenuation.pdf
* http://www.cemyuksel.com/research/pointlightattenuation/
*/
float d_sqr = sqr(lv.dist);
float d_sqr = square(lv.dist);
float r_sqr = light.radius_squared;
/* Using reformulation that has better numerical precision. */
float power = 2.0 / (d_sqr + r_sqr + lv.dist * sqrt(d_sqr + r_sqr));
@ -177,7 +177,7 @@ float light_sphere_disk_radius(float sphere_radius, float distance_to_sphere)
{
/* The sine of the half-angle spanned by a sphere light is equal to the tangent of the
* half-angle spanned by a disk light with the same radius. */
return sphere_radius * inversesqrt(1.0 - sqr(sphere_radius / distance_to_sphere));
return sphere_radius * inversesqrt(1.0 - square(sphere_radius / distance_to_sphere));
}
float light_ltc(

View File

@ -13,7 +13,7 @@
#pragma BLENDER_REQUIRE(eevee_lightprobe_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_spherical_harmonics_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_reflection_probe_eval_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_base_lib.glsl)
/**
* Return the brick coordinate inside the grid.
@ -300,7 +300,6 @@ vec3 lightprobe_eval(
LightProbeSample samp, ClosureReflection reflection, vec3 P, vec3 V, vec2 noise)
{
vec3 L = lightprobe_specular_dominant_dir(reflection.N, V, reflection.roughness);
/* TODO: Right now generate a dependency hell. */
// vec3 L = ray_generate_direction(noise, reflection, V, pdf);
float lod = lightprobe_roughness_to_lod(reflection.roughness);

View File

@ -10,8 +10,7 @@
*/
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_intersect_lib.glsl)
#pragma BLENDER_REQUIRE(draw_intersect_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_light_iter_lib.glsl)

View File

@ -16,7 +16,6 @@
#pragma BLENDER_REQUIRE(eevee_surfel_list_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_lightprobe_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_reflection_probe_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
void irradiance_capture(vec3 L, vec3 irradiance, float visibility, inout SphericalHarmonicL1 sh)
{
@ -39,7 +38,7 @@ void irradiance_capture_surfel(Surfel surfel, vec3 P, inout SphericalHarmonicL1
irradiance_vis += facing ? surfel.radiance_direct.front : surfel.radiance_direct.back;
/* Clamped brightness. */
float luma = max(1e-8, max_v3(irradiance_vis.rgb));
float luma = max(1e-8, reduce_max(irradiance_vis.rgb));
irradiance_vis.rgb *= 1.0 - max(0.0, luma - capture_info_buf.clamp_direct) / luma;
/* NOTE: The indirect radiance is already normalized and this is wanted, because we are not
@ -74,7 +73,7 @@ void irradiance_capture_world(vec3 L, inout SphericalHarmonicL1 sh)
radiance = reflection_probes_sample(L, 0.0, atlas_coord).rgb;
/* Clamped brightness. */
float luma = max(1e-8, max_v3(radiance));
float luma = max(1e-8, reduce_max(radiance));
radiance *= 1.0 - max(0.0, luma - capture_info_buf.clamp_direct) / luma;
}
@ -117,7 +116,7 @@ void main()
surfel_prev = surfel_next;
}
vec3 sky_L = cameraVec(P);
vec3 sky_L = drw_world_incident_vector(P);
SphericalHarmonicL1 sh;
sh.L0.M0 = imageLoad(irradiance_L0_img, grid_coord);

View File

@ -2,6 +2,7 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_vector_lib.glsl)
vec3 lightprobe_irradiance_grid_sample_position(mat4 grid_local_to_world_mat,
@ -54,8 +55,7 @@ float lightprobe_planar_score(ProbePlanarData planar, vec3 P, vec3 V, vec3 L)
}
/* Return how much the ray is lined up with the captured ray. */
vec3 R = -reflect(V, planar.normal);
/* TODO: Use saturate (dependency hell). */
return clamp(dot(L, R), 0.0, 1.0);
return saturate(dot(L, R));
}
#ifdef PLANAR_PROBES
@ -65,8 +65,7 @@ float lightprobe_planar_score(ProbePlanarData planar, vec3 P, vec3 V, vec3 L)
int lightprobe_planar_select(vec3 P, vec3 V, vec3 L)
{
/* Initialize to the score of a camera ray. */
/* TODO: Use saturate (dependency hell). */
float best_score = clamp(dot(L, -V), 0.0, 1.0);
float best_score = saturate(dot(L, -V));
int best_index = -1;
for (int index = 0; index < PLANAR_PROBES_MAX; index++) {

View File

@ -10,6 +10,8 @@
* Project page: https://eheitzresearch.wordpress.com/415-2/
*/
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#define LTC_LAMBERT_MAT vec4(1.0, 0.0, 0.0, 1.0)
#define LTC_GGX_MAT(cos_theta, roughness) \
utility_tx_sample_lut(utility_tx, cos_theta, roughness, UTIL_LTC_MAT_LAYER)
@ -206,9 +208,9 @@ float ltc_evaluate_disk(sampler2DArray utility_tx, vec3 N, vec3 V, mat3 Minv, ve
/* Intermediate step: init ellipse. */
vec3 L_[3];
L_[0] = mul(R, disk_points[0]);
L_[1] = mul(R, disk_points[1]);
L_[2] = mul(R, disk_points[2]);
L_[0] = R * disk_points[0];
L_[1] = R * disk_points[1];
L_[2] = R * disk_points[2];
vec3 C = 0.5 * (L_[0] + L_[2]);
vec3 V1 = 0.5 * (L_[1] - L_[2]);

View File

@ -7,7 +7,7 @@
* Outputs the largest intersecting motion vector in the neighborhood.
*/
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(draw_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_motion_blur_lib.glsl)
#define DEBUG_BYPASS_DILATION 0

View File

@ -14,7 +14,7 @@
* Adapted from G3D Innovation Engine implementation.
*/
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(draw_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_velocity_lib.glsl)
shared uint payload_prev;

View File

@ -13,8 +13,7 @@
* by Jorge Jimenez
*/
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_velocity_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_motion_blur_lib.glsl)
@ -86,7 +85,7 @@ void gather_sample(vec2 screen_uv,
float sample_depth = texture(depth_tx, sample_uv).r;
vec4 sample_color = textureLod(in_color_tx, sample_uv, 0.0);
sample_depth = get_view_z_from_depth(sample_depth);
sample_depth = drw_depth_screen_to_view(sample_depth);
vec3 weights;
weights.xy = sample_weights(
@ -161,7 +160,7 @@ void main()
}
/* Data of the center pixel of the gather (target). */
float center_depth = get_view_z_from_depth(texelFetch(depth_tx, texel, 0).r);
float center_depth = drw_depth_screen_to_view(texelFetch(depth_tx, texel, 0).r);
vec4 center_motion = motion_blur_sample_velocity(velocity_tx, uv);
vec4 center_color = textureLod(in_color_tx, uv, 0.0);

View File

@ -2,8 +2,9 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_base_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_codegen_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_renderpass_lib.glsl)
@ -231,12 +232,12 @@ float ambient_occlusion_eval(vec3 normal,
// clang-format off
#if defined(GPU_FRAGMENT_SHADER) && defined(MAT_AMBIENT_OCCLUSION) && !defined(MAT_DEPTH) && !defined(MAT_SHADOW)
// clang-format on
vec3 vP = transform_point(ViewMatrix, g_data.P);
vec3 vP = drw_point_world_to_view(g_data.P);
ivec2 texel = ivec2(gl_FragCoord.xy);
OcclusionData data = ambient_occlusion_search(
vP, hiz_tx, texel, max_distance, inverted, sample_count);
vec3 V = cameraVec(g_data.P);
vec3 V = drw_world_incident_vector(g_data.P);
vec3 N = g_data.N;
vec3 Ng = g_data.Ng;
@ -339,7 +340,7 @@ vec3 lut_coords_bsdf(float cos_theta, float roughness, float ior)
float critical_cos = sqrt(1.0 - ior * ior);
vec3 coords;
coords.x = sqr(ior);
coords.x = square(ior);
coords.y = cos_theta;
coords.y -= critical_cos;
coords.y /= (coords.y > 0.0) ? (1.0 - critical_cos) : critical_cos;
@ -507,9 +508,9 @@ vec3 coordinate_camera(vec3 P)
}
else {
#ifdef MAT_WORLD
vP = transform_direction(ViewMatrix, P);
vP = drw_normal_world_to_view(P);
#else
vP = transform_point(ViewMatrix, P);
vP = drw_point_world_to_view(P);
#endif
}
vP.z = -vP.z;
@ -525,7 +526,7 @@ vec3 coordinate_screen(vec3 P)
}
else {
/* TODO(fclem): Actual camera transform. */
window.xy = project_point(ProjectionMatrix, transform_point(ViewMatrix, P)).xy * 0.5 + 0.5;
window.xy = drw_point_world_to_screen(P).xy;
window.xy = window.xy * uniform_buf.camera.uv_scale + uniform_buf.camera.uv_bias;
}
return window;
@ -536,7 +537,7 @@ vec3 coordinate_reflect(vec3 P, vec3 N)
#ifdef MAT_WORLD
return N;
#else
return -reflect(cameraVec(P), N);
return -reflect(drw_world_incident_vector(P), N);
#endif
}
@ -545,7 +546,7 @@ vec3 coordinate_incoming(vec3 P)
#ifdef MAT_WORLD
return -P;
#else
return cameraVec(P);
return drw_world_incident_vector(P);
#endif
}

View File

@ -15,11 +15,10 @@
* https://www.ea.com/seed/news/seed-dd18-presentation-slides-raytracing
*/
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_vector_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_codegen_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_gbuffer_lib.glsl)
@ -30,7 +29,7 @@ float bilateral_depth_weight(vec3 center_N, vec3 center_P, vec3 sample_P)
float depth_delta = dot(center_plane_eq, vec4(sample_P, 1.0));
/* TODO(fclem): Scene parameter. This is dependent on scene scale. */
const float scale = 10000.0;
float weight = exp2(-scale * sqr(depth_delta));
float weight = exp2(-scale * square(depth_delta));
return weight;
}
@ -105,7 +104,7 @@ void main()
vec2 center_uv = vec2(texel_fullres) * uniform_buf.raytrace.full_resolution_inv;
float center_depth = texelFetch(depth_tx, texel_fullres, 0).r;
vec3 center_P = get_world_space_from_depth(center_uv, center_depth);
vec3 center_P = drw_point_screen_to_world(vec3(center_uv, center_depth));
#if defined(RAYTRACE_DIFFUSE)
ClosureDiffuse sample_closure, center_closure;
@ -165,7 +164,7 @@ void main()
float sample_depth = texelFetch(depth_tx, sample_texel, 0).r;
vec2 sample_uv = vec2(sample_texel) * uniform_buf.raytrace.full_resolution_inv;
vec3 sample_P = get_world_space_from_depth(sample_uv, sample_depth);
vec3 sample_P = drw_point_screen_to_world(vec3(sample_uv, sample_depth));
/* Background case. */
if (sample_depth == 0.0) {

View File

@ -15,12 +15,12 @@
* https://www.ea.com/seed/news/seed-dd18-presentation-slides-raytracing
*/
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_codegen_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_gbuffer_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_bxdf_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
float bxdf_eval(ClosureDiffuse closure, vec3 L, vec3 V)
{
@ -104,7 +104,9 @@ void main()
}
vec2 uv = (vec2(texel_fullres) + 0.5) * uniform_buf.raytrace.full_resolution_inv;
vec3 V = transform_direction(ViewMatrixInverse, get_view_vector_from_screen_uv(uv));
vec3 P = drw_point_screen_to_world(vec3(uv, 0.5));
vec3 V = drw_world_incident_vector(P);
GBufferData gbuf = gbuffer_read(gbuf_header_tx, gbuf_closure_tx, gbuf_color_tx, texel_fullres);
@ -132,7 +134,7 @@ void main()
sample_count = max(sample_count, 5u);
}
/* NOTE: Roughness is squared now. */
closure.roughness = max(1e-3, sqr(closure.roughness));
closure.roughness = max(1e-3, square(closure.roughness));
#endif
vec2 noise = utility_tx_fetch(utility_tx, vec2(texel_fullres), UTIL_BLUE_NOISE_LAYER).ba;
@ -176,7 +178,7 @@ void main()
radiance_accum += ray_radiance.rgb * weight;
weight_accum += weight;
rgb_moment += sqr(ray_radiance.rgb) * weight;
rgb_moment += square(ray_radiance.rgb) * weight;
}
float inv_weight = safe_rcp(weight_accum);
@ -185,11 +187,11 @@ void main()
vec3 rgb_mean = radiance_accum;
rgb_moment *= inv_weight;
vec3 rgb_variance = abs(rgb_moment - sqr(rgb_mean));
float hit_variance = max_v3(rgb_variance);
vec3 rgb_variance = abs(rgb_moment - square(rgb_mean));
float hit_variance = reduce_max(rgb_variance);
float scene_z = get_view_z_from_depth(texelFetch(depth_tx, texel_fullres, 0).r);
float hit_depth = get_depth_from_view_z(scene_z - closest_hit_time);
float scene_z = drw_depth_screen_to_view(texelFetch(depth_tx, texel_fullres, 0).r);
float hit_depth = drw_depth_view_to_screen(scene_z - closest_hit_time);
imageStore(out_radiance_img, texel_fullres, vec4(radiance_accum, 0.0));
imageStore(out_variance_img, texel_fullres, vec4(hit_variance));

View File

@ -15,13 +15,12 @@
* https://www.ea.com/seed/news/seed-dd18-presentation-slides-raytracing
*/
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_codegen_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_matrix_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_gbuffer_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_colorspace_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
struct LocalStatistics {
vec3 mean;
@ -183,11 +182,11 @@ void main()
/* Surface reprojection. */
/* TODO(fclem): Use per pixel velocity. Is this worth it? */
float scene_depth = texelFetch(depth_tx, texel_fullres, 0).r;
vec3 P = get_world_space_from_depth(uv, scene_depth);
vec3 P = drw_point_screen_to_world(vec3(uv, scene_depth));
vec4 history_radiance = radiance_history_sample(P, local);
/* Reflection reprojection. */
float hit_depth = imageLoad(hit_depth_img, texel_fullres).r;
vec3 P_hit = get_world_space_from_depth(uv, hit_depth);
vec3 P_hit = drw_point_screen_to_world(vec3(uv, hit_depth));
history_radiance += radiance_history_sample(P_hit, local);
/* Finalize accumulation. */
history_radiance *= safe_rcp(history_radiance.w);
@ -199,7 +198,8 @@ void main()
float mix_fac = (history_radiance.w > 1e-3) ? 0.97 : 0.0;
/* Reduce blend factor to improve low roughness reflections. Use variance instead for speed. */
mix_fac *= mix(0.75, 1.0, saturate(in_variance * 20.0));
vec3 out_radiance = mix(safe_color(in_radiance), safe_color(history_radiance.rgb), mix_fac);
vec3 out_radiance = mix(
colorspace_safe_color(in_radiance), colorspace_safe_color(history_radiance.rgb), mix_fac);
/* This is feedback next frame as radiance_history_tx. */
imageStore(out_radiance_img, texel_fullres, vec4(out_radiance, 0.0));

View File

@ -38,7 +38,8 @@ void main()
}
vec2 uv = (vec2(texel_fullres) + 0.5) / vec2(textureSize(gbuf_header_tx, 0).xy);
vec3 V = transform_direction(ViewMatrixInverse, get_view_vector_from_screen_uv(uv));
vec3 P = drw_point_screen_to_world(vec3(uv, 0.5));
vec3 V = drw_world_incident_vector(P);
vec2 noise = utility_tx_fetch(utility_tx, vec2(texel), UTIL_BLUE_NOISE_LAYER).rg;
#if defined(RAYTRACE_DIFFUSE)

View File

@ -8,7 +8,6 @@
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_vector_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_bxdf_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_gbuffer_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_ray_types_lib.glsl)
@ -28,7 +27,7 @@ vec3 ray_generate_direction(vec2 noise, ClosureReflection reflection, vec3 V, ou
/* Bias the rays so we never get really high energy rays almost parallel to the surface. */
Xi.x = Xi.x * (1.0 - RAY_BIAS_REFLECTION) + RAY_BIAS_REFLECTION;
float roughness_sqr = max(1e-3, sqr(reflection.roughness));
float roughness_sqr = max(1e-3, square(reflection.roughness));
/* Gives *perfect* reflection for very small roughness. */
if (reflection.roughness < 0.0016) {
Xi = vec3(0.0);
@ -47,7 +46,7 @@ vec3 ray_generate_direction(vec2 noise, ClosureRefraction refraction, vec3 V, ou
/* Bias the rays so we never get really high energy rays almost parallel to the surface. */
Xi.x = Xi.x * (1.0 - RAY_BIAS_REFRACTION) + RAY_BIAS_REFRACTION;
float roughness_sqr = max(1e-3, sqr(refraction.roughness));
float roughness_sqr = max(1e-3, square(refraction.roughness));
/* Gives *perfect* refraction for very small roughness. */
if (refraction.roughness < 0.0016) {
Xi = vec3(0.0);

View File

@ -11,8 +11,6 @@
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_ray_types_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_ray_trace_screen_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
void main()
{
@ -36,13 +34,13 @@ void main()
return;
}
vec3 P = get_world_space_from_depth(uv, depth);
vec3 P = drw_point_screen_to_world(vec3(uv, depth));
vec3 V = drw_world_incident_vector(P);
Ray ray;
ray.origin = P;
ray.direction = ray_data.xyz;
vec3 V = cameraVec(P);
/* Using ray direction as geometric normal to bias the sampling position.
* This is faster than loading the gbuffer again and averages between reflected and normal
* direction over many rays. */
@ -52,7 +50,7 @@ void main()
/* Set point really far for correct reprojection of background. */
float hit_time = 1000.0;
float luma = max(1e-8, max_v3(radiance));
float luma = max(1e-8, reduce_max(radiance));
radiance *= 1.0 - max(0.0, luma - uniform_buf.raytrace.brightness_clamp) / luma;
imageStore(ray_time_img, texel, vec4(hit_time));

View File

@ -14,8 +14,6 @@
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_ray_types_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_ray_trace_screen_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
void main()
{
@ -39,8 +37,8 @@ void main()
float depth = texelFetch(depth_tx, texel_fullres, 0).r;
vec2 uv = (vec2(texel_fullres) + 0.5) * uniform_buf.raytrace.full_resolution_inv;
vec3 P = get_world_space_from_depth(uv, depth);
vec3 V = cameraVec(P);
vec3 P = drw_point_screen_to_world(vec3(uv, depth));
vec3 V = drw_world_incident_vector(P);
int planar_id = lightprobe_planar_select(P, V, ray_data.xyz);
if (planar_id == -1) {
@ -95,7 +93,7 @@ void main()
hit.time = 10000.0;
}
float luma = max(1e-8, max_v3(radiance));
float luma = max(1e-8, reduce_max(radiance));
radiance *= 1.0 - max(0.0, luma - uniform_buf.raytrace.brightness_clamp) / luma;
imageStore(ray_time_img, texel, vec4(hit.time));

View File

@ -11,8 +11,6 @@
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_ray_types_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_ray_trace_screen_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
void main()
{
@ -41,8 +39,8 @@ void main()
float depth = texelFetch(depth_tx, texel_fullres, 0).r;
vec2 uv = (vec2(texel_fullres) + 0.5) * uniform_buf.raytrace.full_resolution_inv;
vec3 P = get_world_space_from_depth(uv, depth);
vec3 V = cameraVec(P);
vec3 P = drw_point_screen_to_world(vec3(uv, depth));
vec3 V = drw_world_incident_vector(P);
Ray ray;
ray.origin = P;
ray.direction = ray_data.xyz;
@ -104,7 +102,7 @@ void main()
hit.time = 10000.0;
}
float luma = max(1e-8, max_v3(radiance));
float luma = max(1e-8, reduce_max(radiance));
radiance *= 1.0 - max(0.0, luma - uniform_buf.raytrace.brightness_clamp) / luma;
imageStore(ray_time_img, texel, vec4(hit.time));

View File

@ -12,12 +12,15 @@
* Many modifications were made for our own usage.
*/
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_matrix_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_fast_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_ray_types_lib.glsl)
/* Inputs expected to be in view-space. */
void raytrace_clip_ray_to_near_plane(inout Ray ray)
{
float near_dist = get_view_z_from_depth(0.0);
float near_dist = drw_view_near();
if ((ray.origin.z + ray.direction.z * ray.max_time) > near_dist) {
ray.max_time = abs((near_dist - ray.origin.z) / ray.direction.z);
}
@ -76,7 +79,7 @@ METAL_ATTR ScreenTraceHitData raytrace_screen(RayTraceData rt_data,
if (!allow_self_intersection && ssray.max_time < 1.1) {
/* Still output the clipped ray. */
vec3 hit_ssP = ssray.origin.xyz + ssray.direction.xyz * ssray.max_time;
vec3 hit_P = get_world_space_from_depth(hit_ssP.xy, saturate(hit_ssP.z));
vec3 hit_P = drw_point_screen_to_world(vec3(hit_ssP.xy, saturate(hit_ssP.z)));
ray.direction = hit_P - ray.origin;
ScreenTraceHitData no_hit;
@ -88,10 +91,10 @@ METAL_ATTR ScreenTraceHitData raytrace_screen(RayTraceData rt_data,
ssray.max_time = max(1.1, ssray.max_time);
float prev_delta = 0.0, prev_time = 0.0;
float depth_sample = get_depth_from_view_z(ray.origin.z);
float depth_sample = drw_depth_view_to_screen(ray.origin.z);
float delta = depth_sample - ssray.origin.z;
float lod_fac = saturate(fast_sqrt(roughness) * 2.0 - 0.4);
float lod_fac = saturate(sqrt_fast(roughness) * 2.0 - 0.4);
/* Cross at least one pixel. */
float t = 1.001, time = 1.001;
@ -142,7 +145,7 @@ METAL_ATTR ScreenTraceHitData raytrace_screen(RayTraceData rt_data,
ScreenTraceHitData result;
result.valid = hit;
result.ss_hit_P = ssray.origin.xyz + ssray.direction.xyz * time;
result.v_hit_P = project_point(drw_view.wininv, result.ss_hit_P * 2.0 - 1.0);
result.v_hit_P = drw_point_screen_to_view(result.ss_hit_P);
/* Convert to world space ray time. */
result.time = length(result.v_hit_P - ray.origin) / length(ray.direction);
@ -211,7 +214,7 @@ ScreenTraceHitData raytrace_planar(RayTraceData rt_data,
result.ss_hit_P = ssray.origin.xyz + ssray.direction.xyz * time;
/* TODO(@fclem): This uses the main view's projection matrix, not the planar's one.
* This works fine for reflection, but this prevent the use of any other projection capture. */
result.v_hit_P = project_point(drw_view.wininv, result.ss_hit_P * 2.0 - 1.0);
result.v_hit_P = drw_point_screen_to_view(result.ss_hit_P);
/* Convert to world space ray time. */
result.time = length(result.v_hit_P - ray.origin) / length(ray.direction);
return result;

View File

@ -2,8 +2,7 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
/**
* General purpose 3D ray.
@ -37,17 +36,17 @@ void raytrace_screenspace_ray_finalize(inout ScreenSpaceRay ray, vec2 pixel_size
ray.direction -= ray.origin;
/* 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 */
if (len_squared(ray.direction.xy) < 0.00001) {
if (length_squared(ray.direction.xy) < 0.00001) {
ray.direction.xy = vec2(0.0, 0.00001);
}
float ray_len_sqr = len_squared(ray.direction.xyz);
float ray_len_sqr = length_squared(ray.direction.xyz);
/* Make ray.direction cover one pixel. */
bool is_more_vertical = abs(ray.direction.x / pixel_size.x) <
abs(ray.direction.y / pixel_size.y);
ray.direction /= (is_more_vertical) ? abs(ray.direction.y) : abs(ray.direction.x);
ray.direction *= (is_more_vertical) ? pixel_size.y : pixel_size.x;
/* Clip to segment's end. */
ray.max_time = sqrt(ray_len_sqr * safe_rcp(len_squared(ray.direction.xyz)));
ray.max_time = sqrt(ray_len_sqr * safe_rcp(length_squared(ray.direction.xyz)));
/* Clipping to frustum sides. */
float clip_dist = line_unit_box_intersect_dist_safe(ray.origin.xyz, ray.direction.xyz);
ray.max_time = min(ray.max_time, clip_dist);
@ -59,8 +58,8 @@ void raytrace_screenspace_ray_finalize(inout ScreenSpaceRay ray, vec2 pixel_size
ScreenSpaceRay raytrace_screenspace_ray_create(Ray ray, vec2 pixel_size)
{
ScreenSpaceRay ssray;
ssray.origin.xyz = project_point(ProjectionMatrix, ray.origin);
ssray.direction.xyz = project_point(ProjectionMatrix, ray.origin + ray.direction * ray.max_time);
ssray.origin.xyz = drw_point_view_to_ndc(ray.origin);
ssray.direction.xyz = drw_point_view_to_ndc(ray.origin + ray.direction * ray.max_time);
raytrace_screenspace_ray_finalize(ssray, pixel_size);
return ssray;
@ -69,12 +68,12 @@ ScreenSpaceRay raytrace_screenspace_ray_create(Ray ray, vec2 pixel_size)
ScreenSpaceRay raytrace_screenspace_ray_create(Ray ray, vec2 pixel_size, float thickness)
{
ScreenSpaceRay ssray;
ssray.origin.xyz = project_point(ProjectionMatrix, ray.origin);
ssray.direction.xyz = project_point(ProjectionMatrix, ray.origin + ray.direction * ray.max_time);
ssray.origin.xyz = drw_point_view_to_ndc(ray.origin);
ssray.direction.xyz = drw_point_view_to_ndc(ray.origin + ray.direction * ray.max_time);
/* Interpolate thickness in screen space.
* Calculate thickness further away to avoid near plane clipping issues. */
ssray.origin.w = get_depth_from_view_z(ray.origin.z - thickness);
ssray.direction.w = get_depth_from_view_z(ray.origin.z + ray.direction.z - thickness);
ssray.origin.w = drw_depth_view_to_screen(ray.origin.z - thickness);
ssray.direction.w = drw_depth_view_to_screen(ray.origin.z + ray.direction.z - thickness);
ssray.origin.w = ssray.origin.w * 2.0 - 1.0;
ssray.direction.w = ssray.direction.w * 2.0 - 1.0;

View File

@ -7,7 +7,7 @@
* Also contains some sample mapping functions.
*/
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_base_lib.glsl)
/* -------------------------------------------------------------------- */
/** \name Sampling data.
@ -114,9 +114,9 @@ vec2 hammersley_2d(int i, int sample_count)
/* Given 1 random number in [0..1] range, return a random unit circle sample. */
vec2 sample_circle(float rand)
{
float phi = (rand - 0.5) * M_2PI;
float phi = (rand - 0.5) * M_TAU;
float cos_phi = cos(phi);
float sin_phi = sqrt(1.0 - sqr(cos_phi)) * sign(phi);
float sin_phi = sqrt(1.0 - square(cos_phi)) * sign(phi);
return vec2(cos_phi, sin_phi);
}
@ -149,7 +149,7 @@ vec3 sample_sphere(vec2 rand)
vec3 sample_hemisphere(vec2 rand)
{
float cos_theta = rand.x;
float sin_theta = safe_sqrt(1.0 - sqr(cos_theta));
float sin_theta = safe_sqrt(1.0 - square(cos_theta));
return vec3(sin_theta * sample_circle(rand.y), cos_theta);
}

View File

@ -7,8 +7,8 @@
* See eShadowDebug for more information.
*/
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_debug_gradients_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_light_iter_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_light_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_shadow_lib.glsl)
@ -173,7 +173,7 @@ void main()
out_color_mul = vec4(1.0);
float depth = texelFetch(hiz_tx, ivec2(gl_FragCoord.xy), 0).r;
vec3 P = get_world_space_from_depth(uvcoordsvar.xy, depth);
vec3 P = drw_point_screen_to_world(vec3(uvcoordsvar.xy, depth));
/* Make it pass the depth test. */
gl_FragDepth = depth - 1e-6;

View File

@ -2,6 +2,8 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_matrix_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl)
#define EEVEE_SHADOW_LIB
@ -32,12 +34,6 @@ float shadow_read_depth_at_tilemap_uv(usampler2DArray atlas_tx,
return uintBitsToFloat(texelFetch(atlas_tx, texel, 0).r);
}
/* TODO(fclem): Use utildef version. Only here to avoid include order hell with common_math_lib. */
float shadow_orderedIntBitsToFloat(int int_value)
{
return intBitsToFloat((int_value < 0) ? (int_value ^ 0x7FFFFFFF) : int_value);
}
struct ShadowEvalResult {
/* Visibility of the light. */
float light_visibilty;
@ -80,8 +76,8 @@ float shadow_linear_occluder_distance(LightData light,
vec3 lP,
float occluder)
{
float near = shadow_orderedIntBitsToFloat(light.clip_near);
float far = shadow_orderedIntBitsToFloat(light.clip_far);
float near = orderedIntBitsToFloat(light.clip_near);
float far = orderedIntBitsToFloat(light.clip_far);
float occluder_z = (is_directional) ? (occluder * (far - near) + near) :
((near * far) / (occluder * (near - far) + far));
@ -128,8 +124,8 @@ ShadowEvalResult shadow_directional_sample_get(usampler2DArray atlas_tx,
vec3 lP = P * mat3(light.object_mat);
ShadowCoordinates coord = shadow_directional_coordinates(light, lP);
float clip_near = shadow_orderedIntBitsToFloat(light.clip_near);
float clip_far = shadow_orderedIntBitsToFloat(light.clip_far);
float clip_near = orderedIntBitsToFloat(light.clip_near);
float clip_far = orderedIntBitsToFloat(light.clip_far);
/* Assumed to be non-null. */
float z_range = clip_far - clip_near;
float dist_to_near_plane = -lP.z - clip_near;

View File

@ -35,6 +35,7 @@
* belong to shadow pages not being updated in this pass are discarded.
**/
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl)
#if defined(PASS_CLEAR)

View File

@ -11,8 +11,9 @@
* tag the appropriate tiles.
*/
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_intersect_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_aabb_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl)

View File

@ -27,8 +27,8 @@ void main()
}
vec2 uv = (vec2(texel) + 0.5) / vec2(tex_size);
vec3 vP = get_view_space_from_depth(uv, depth);
vec3 P = transform_point(ViewMatrixInverse, vP);
vec3 vP = drw_point_screen_to_view(vec3(uv, depth));
vec3 P = drw_point_view_to_world(vP);
vec2 pixel = vec2(gl_GlobalInvocationID.xy);
shadow_tag_usage(vP, P, pixel);

View File

@ -10,8 +10,8 @@
* tiles.
*/
#pragma BLENDER_REQUIRE(draw_model_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_shadow_tag_usage_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
float ray_aabb(vec3 ray_origin, vec3 ray_direction, vec3 aabb_min, vec3 aabb_max)
{
@ -19,8 +19,8 @@ float ray_aabb(vec3 ray_origin, vec3 ray_direction, vec3 aabb_min, vec3 aabb_max
vec3 t_mins = (aabb_min - ray_origin) / ray_direction;
vec3 t_maxs = (aabb_max - ray_origin) / ray_direction;
float t_min = max_v3(min(t_mins, t_maxs));
float t_max = min_v3(max(t_mins, t_maxs));
float t_min = reduce_max(min(t_mins, t_maxs));
float t_max = reduce_min(max(t_mins, t_maxs));
/* AABB is in the opposite direction. */
if (t_max < 0.0) {
@ -68,14 +68,14 @@ void step_bounding_sphere(vec3 vs_near_plane,
for (int x = -1; x <= 1; x += 2) {
for (int y = -1; y <= 1; y += 2) {
vec3 near_corner = near_center + (near_pixel_size * 0.5 * vec3(x, y, 0));
sphere_radius = max(sphere_radius, len_squared(near_corner - sphere_center));
sphere_radius = max(sphere_radius, length_squared(near_corner - sphere_center));
vec3 far_corner = far_center + (far_pixel_size * 0.5 * vec3(x, y, 0));
sphere_radius = max(sphere_radius, len_squared(far_corner - sphere_center));
sphere_radius = max(sphere_radius, length_squared(far_corner - sphere_center));
}
}
sphere_center = point_view_to_world(sphere_center);
sphere_center = drw_point_view_to_world(sphere_center);
sphere_radius = sqrt(sphere_radius);
}
@ -84,14 +84,14 @@ void main()
vec2 screen_uv = gl_FragCoord.xy / vec2(fb_resolution);
float opaque_depth = texelFetch(hiz_tx, ivec2(gl_FragCoord.xy), fb_lod).r;
vec3 ws_opaque = get_world_space_from_depth(screen_uv, opaque_depth);
vec3 ws_opaque = drw_point_screen_to_world(vec3(screen_uv, opaque_depth));
vec3 ws_near_plane = get_world_space_from_depth(screen_uv, 0);
vec3 ws_near_plane = drw_point_screen_to_world(vec3(screen_uv, 0.0));
vec3 ws_view_direction = normalize(interp.P - ws_near_plane);
vec3 vs_near_plane = get_view_space_from_depth(screen_uv, 0);
vec3 vs_near_plane = drw_point_screen_to_view(vec3(screen_uv, 0.0));
vec3 vs_view_direction = normalize(interp.vP - vs_near_plane);
vec3 ls_near_plane = point_world_to_object(ws_near_plane);
vec3 ls_view_direction = normalize(point_world_to_object(interp.P) - ls_near_plane);
vec3 ls_near_plane = drw_point_world_to_object(ws_near_plane);
vec3 ls_view_direction = normalize(drw_point_world_to_object(interp.P) - ls_near_plane);
/* TODO (Miguel Pozo): We could try to ray-cast against the non-inflated bounds first,
* and fallback to the inflated ones if there is no hit.
@ -99,7 +99,7 @@ void main()
float ls_near_box_t = ray_aabb(
ls_near_plane, ls_view_direction, interp_flat.ls_aabb_min, interp_flat.ls_aabb_max);
vec3 ls_near_box = ls_near_plane + ls_view_direction * ls_near_box_t;
vec3 ws_near_box = point_object_to_world(ls_near_box);
vec3 ws_near_box = drw_point_object_to_world(ls_near_box);
float near_box_t = distance(ws_near_plane, ws_near_box);
float far_box_t = distance(ws_near_plane, interp.P);
@ -116,7 +116,7 @@ void main()
vec3 P = ws_near_plane + (ws_view_direction * t);
float step_radius;
step_bounding_sphere(vs_near_plane, vs_view_direction, t, t + step_size, P, step_radius);
vec3 vP = point_world_to_view(P);
vec3 vP = drw_point_world_to_view(P);
shadow_tag_usage(
vP, P, ws_view_direction, step_radius, t, gl_FragCoord.xy * exp2(float(fb_lod)), 0);

View File

@ -9,9 +9,8 @@
* This contains the common logic used for tagging shadows for opaque and transparent receivers.
*/
#pragma BLENDER_REQUIRE(common_intersect_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
#pragma BLENDER_REQUIRE(draw_intersect_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_light_iter_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_light_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_shadow_lib.glsl)

View File

@ -9,39 +9,40 @@
* This renders the bounding boxes for transparent objects in order to tag the correct shadows.
*/
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_vector_lib.glsl)
#pragma BLENDER_REQUIRE(draw_model_lib.glsl)
#pragma BLENDER_REQUIRE(common_shape_lib.glsl)
/* Inflate bounds by half a pixel as a conservative rasterization alternative,
* to ensure the tiles needed by all LOD0 pixels get tagged */
void inflate_bounds(vec3 ls_center, inout vec3 P, inout vec3 lP)
{
vec3 vP = point_world_to_view(P);
vec3 vP = drw_point_world_to_view(P);
float inflate_scale = pixel_world_radius * exp2(float(fb_lod));
bool is_persp = (ProjectionMatrix[3][3] == 0.0);
if (is_persp) {
if (drw_view_is_perspective()) {
inflate_scale *= -vP.z;
}
/* Half-pixel. */
inflate_scale *= 0.5;
vec3 vs_inflate_vector = normal_object_to_view(sign(lP - ls_center));
vec3 vs_inflate_vector = drw_normal_object_to_view(sign(lP - ls_center));
vs_inflate_vector.z = 0;
/* Scale the vector so the largest axis length is 1 */
vs_inflate_vector /= max_v2(abs(vs_inflate_vector.xy));
vs_inflate_vector /= reduce_max(abs(vs_inflate_vector.xy));
vs_inflate_vector *= inflate_scale;
vP += vs_inflate_vector;
P = point_view_to_world(vP);
lP = point_world_to_object(P);
P = drw_point_view_to_world(vP);
lP = drw_point_world_to_object(P);
}
void main()
{
PASS_RESOURCE_ID
DRW_RESOURCE_ID_VARYING_SET
const ObjectBounds bounds = bounds_buf[resource_id];
ObjectBounds bounds = bounds_buf[resource_id];
Box box = shape_box(bounds.bounding_corners[0].xyz,
bounds.bounding_corners[0].xyz + bounds.bounding_corners[1].xyz,
@ -52,14 +53,14 @@ void main()
vec3 ws_aabb_max = bounds.bounding_corners[0].xyz + bounds.bounding_corners[1].xyz +
bounds.bounding_corners[2].xyz + bounds.bounding_corners[3].xyz;
vec3 ls_center = point_world_to_object((ws_aabb_min + ws_aabb_max) / 2.0);
vec3 ls_center = drw_point_world_to_object(midpoint(ws_aabb_min, ws_aabb_max));
vec3 ls_conservative_min = vec3(FLT_MAX);
vec3 ls_conservative_max = vec3(-FLT_MAX);
for (int i = 0; i < 8; i++) {
vec3 P = box.corners[i];
vec3 lP = point_world_to_object(P);
vec3 lP = drw_point_world_to_object(P);
inflate_bounds(ls_center, P, lP);
ls_conservative_min = min(ls_conservative_min, lP);
@ -71,10 +72,10 @@ void main()
vec3 lP = mix(ls_conservative_min, ls_conservative_max, max(vec3(0), pos));
interp.P = point_object_to_world(lP);
interp.vP = point_world_to_view(interp.P);
interp.P = drw_point_object_to_world(lP);
interp.vP = drw_point_world_to_view(interp.P);
gl_Position = point_world_to_ndc(interp.P);
gl_Position = drw_point_world_to_homogenous(interp.P);
#if 0
if (gl_VertexID == 0) {
@ -84,7 +85,7 @@ void main()
ls_conservative_min + (ls_conservative_max - ls_conservative_min) * vec3(0, 1, 0),
ls_conservative_min + (ls_conservative_max - ls_conservative_min) * vec3(0, 0, 1));
for (int i = 0; i < 8; i++) {
debug_box.corners[i] = point_object_to_world(debug_box.corners[i]);
debug_box.corners[i] = drw_point_object_to_world(debug_box.corners[i]);
}
drw_debug(debug_box);
}

View File

@ -29,9 +29,9 @@ void main()
}
vec3 jitter = sampling_rng_3D_get(SAMPLING_VOLUME_U);
vec3 volume_ndc = volume_to_ndc((vec3(froxel) + jitter) * uniform_buf.volumes.inv_tex_size);
vec3 vP = get_view_space_from_depth(volume_ndc.xy, volume_ndc.z);
vec3 P = point_view_to_world(vP);
vec3 volume_ndc = volume_to_screen((vec3(froxel) + jitter) * uniform_buf.volumes.inv_tex_size);
vec3 vP = drw_point_screen_to_view(vec3(volume_ndc.xy, volume_ndc.z));
vec3 P = drw_point_view_to_world(vP);
float depth = texelFetch(hiz_tx, froxel.xy, uniform_buf.volumes.tile_size_lod).r;
if (depth < volume_ndc.z) {
@ -42,5 +42,5 @@ void main()
uniform_buf.volumes.viewport_size_inv;
int bias = uniform_buf.volumes.tile_size_lod;
shadow_tag_usage(vP, P, cameraVec(P), 0.01, length(vP), pixel, bias);
shadow_tag_usage(vP, P, drw_world_incident_vector(P), 0.01, length(vP), pixel, bias);
}

View File

@ -11,7 +11,6 @@
*/
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_intersect_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_light_iter_lib.glsl)

Some files were not shown because too many files have changed in this diff Show More