This includes much improved GPU rendering performance, viewport interactivity, new shadow catcher, revamped sampling settings, subsurface scattering anisotropy, new GPU volume sampling, improved PMJ sampling pattern, and more. Some features have also been removed or changed, breaking backwards compatibility. Including the removal of the OpenCL backend, for which alternatives are under development. Release notes and code docs: https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles https://wiki.blender.org/wiki/Source/Render/Cycles Credits: * Sergey Sharybin * Brecht Van Lommel * Patrick Mours (OptiX backend) * Christophe Hery (subsurface scattering anisotropy) * William Leeson (PMJ sampling pattern) * Alaska (various fixes and tweaks) * Thomas Dinges (various fixes) For the full commit history, see the cycles-x branch. This squashes together all the changes since intermediate changes would often fail building or tests. Ref T87839, T87837, T87836 Fixes T90734, T89353, T80267, T80267, T77185, T69800
244 lines
5.9 KiB
C
244 lines
5.9 KiB
C
/*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
/** \file
|
|
* \ingroup render
|
|
*/
|
|
|
|
/* Global includes */
|
|
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "BLI_blenlib.h"
|
|
#include "BLI_ghash.h"
|
|
#include "BLI_math.h"
|
|
#include "BLI_utildefines.h"
|
|
|
|
#include "DNA_camera_types.h"
|
|
|
|
#include "BKE_camera.h"
|
|
|
|
/* this module */
|
|
#include "pipeline.h"
|
|
#include "render_types.h"
|
|
|
|
/* ****************** MASKS and LUTS **************** */
|
|
|
|
static float filt_quadratic(float x)
|
|
{
|
|
if (x < 0.0f) {
|
|
x = -x;
|
|
}
|
|
if (x < 0.5f) {
|
|
return 0.75f - (x * x);
|
|
}
|
|
if (x < 1.5f) {
|
|
return 0.50f * (x - 1.5f) * (x - 1.5f);
|
|
}
|
|
return 0.0f;
|
|
}
|
|
|
|
static float filt_cubic(float x)
|
|
{
|
|
float x2 = x * x;
|
|
|
|
if (x < 0.0f) {
|
|
x = -x;
|
|
}
|
|
|
|
if (x < 1.0f) {
|
|
return 0.5f * x * x2 - x2 + 2.0f / 3.0f;
|
|
}
|
|
if (x < 2.0f) {
|
|
return (2.0f - x) * (2.0f - x) * (2.0f - x) / 6.0f;
|
|
}
|
|
return 0.0f;
|
|
}
|
|
|
|
static float filt_catrom(float x)
|
|
{
|
|
float x2 = x * x;
|
|
|
|
if (x < 0.0f) {
|
|
x = -x;
|
|
}
|
|
if (x < 1.0f) {
|
|
return 1.5f * x2 * x - 2.5f * x2 + 1.0f;
|
|
}
|
|
if (x < 2.0f) {
|
|
return -0.5f * x2 * x + 2.5f * x2 - 4.0f * x + 2.0f;
|
|
}
|
|
return 0.0f;
|
|
}
|
|
|
|
static float filt_mitchell(float x) /* Mitchell & Netravali's two-param cubic */
|
|
{
|
|
float b = 1.0f / 3.0f, c = 1.0f / 3.0f;
|
|
float p0 = (6.0f - 2.0f * b) / 6.0f;
|
|
float p2 = (-18.0f + 12.0f * b + 6.0f * c) / 6.0f;
|
|
float p3 = (12.0f - 9.0f * b - 6.0f * c) / 6.0f;
|
|
float q0 = (8.0f * b + 24.0f * c) / 6.0f;
|
|
float q1 = (-12.0f * b - 48.0f * c) / 6.0f;
|
|
float q2 = (6.0f * b + 30.0f * c) / 6.0f;
|
|
float q3 = (-b - 6.0f * c) / 6.0f;
|
|
|
|
if (x < -2.0f) {
|
|
return 0.0f;
|
|
}
|
|
if (x < -1.0f) {
|
|
return (q0 - x * (q1 - x * (q2 - x * q3)));
|
|
}
|
|
if (x < 0.0f) {
|
|
return (p0 + x * x * (p2 - x * p3));
|
|
}
|
|
if (x < 1.0f) {
|
|
return (p0 + x * x * (p2 + x * p3));
|
|
}
|
|
if (x < 2.0f) {
|
|
return (q0 + x * (q1 + x * (q2 + x * q3)));
|
|
}
|
|
return 0.0f;
|
|
}
|
|
|
|
/* x ranges from -1 to 1 */
|
|
float RE_filter_value(int type, float x)
|
|
{
|
|
float gaussfac = 1.6f;
|
|
|
|
x = fabsf(x);
|
|
|
|
switch (type) {
|
|
case R_FILTER_BOX:
|
|
if (x > 1.0f) {
|
|
return 0.0f;
|
|
}
|
|
return 1.0f;
|
|
|
|
case R_FILTER_TENT:
|
|
if (x > 1.0f) {
|
|
return 0.0f;
|
|
}
|
|
return 1.0f - x;
|
|
|
|
case R_FILTER_GAUSS: {
|
|
const float two_gaussfac2 = 2.0f * gaussfac * gaussfac;
|
|
x *= 3.0f * gaussfac;
|
|
return 1.0f / sqrtf((float)M_PI * two_gaussfac2) * expf(-x * x / two_gaussfac2);
|
|
}
|
|
|
|
case R_FILTER_MITCH:
|
|
return filt_mitchell(x * gaussfac);
|
|
|
|
case R_FILTER_QUAD:
|
|
return filt_quadratic(x * gaussfac);
|
|
|
|
case R_FILTER_CUBIC:
|
|
return filt_cubic(x * gaussfac);
|
|
|
|
case R_FILTER_CATROM:
|
|
return filt_catrom(x * gaussfac);
|
|
}
|
|
return 0.0f;
|
|
}
|
|
|
|
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
|
struct Object *RE_GetCamera(Render *re)
|
|
{
|
|
Object *camera = re->camera_override ? re->camera_override : re->scene->camera;
|
|
return BKE_camera_multiview_render(re->scene, camera, re->viewname);
|
|
}
|
|
|
|
void RE_SetOverrideCamera(Render *re, Object *cam_ob)
|
|
{
|
|
re->camera_override = cam_ob;
|
|
}
|
|
|
|
/**
|
|
* Per render, there's one persistent view-plane. Parts will set their own view-planes.
|
|
*
|
|
* \note call this after #RE_InitState().
|
|
*/
|
|
void RE_SetCamera(Render *re, Object *cam_ob)
|
|
{
|
|
CameraParams params;
|
|
|
|
/* setup parameters */
|
|
BKE_camera_params_init(¶ms);
|
|
BKE_camera_params_from_object(¶ms, cam_ob);
|
|
BKE_camera_multiview_params(&re->r, ¶ms, cam_ob, re->viewname);
|
|
|
|
/* Compute matrix, view-plane, etc. */
|
|
BKE_camera_params_compute_viewplane(¶ms, re->winx, re->winy, re->r.xasp, re->r.yasp);
|
|
BKE_camera_params_compute_matrix(¶ms);
|
|
|
|
/* extract results */
|
|
copy_m4_m4(re->winmat, params.winmat);
|
|
re->clip_start = params.clip_start;
|
|
re->clip_end = params.clip_end;
|
|
re->viewplane = params.viewplane;
|
|
}
|
|
|
|
void RE_GetCameraWindow(struct Render *re, struct Object *camera, float r_winmat[4][4])
|
|
{
|
|
RE_SetCamera(re, camera);
|
|
copy_m4_m4(r_winmat, re->winmat);
|
|
}
|
|
|
|
/* Must be called after RE_GetCameraWindow(), does not change re->winmat. */
|
|
void RE_GetCameraWindowWithOverscan(struct Render *re, float overscan, float r_winmat[4][4])
|
|
{
|
|
CameraParams params;
|
|
params.is_ortho = re->winmat[3][3] != 0.0f;
|
|
params.clip_start = re->clip_start;
|
|
params.clip_end = re->clip_end;
|
|
params.viewplane = re->viewplane;
|
|
|
|
overscan *= max_ff(BLI_rctf_size_x(¶ms.viewplane), BLI_rctf_size_y(¶ms.viewplane));
|
|
|
|
params.viewplane.xmin -= overscan;
|
|
params.viewplane.xmax += overscan;
|
|
params.viewplane.ymin -= overscan;
|
|
params.viewplane.ymax += overscan;
|
|
BKE_camera_params_compute_matrix(¶ms);
|
|
copy_m4_m4(r_winmat, params.winmat);
|
|
}
|
|
|
|
void RE_GetCameraModelMatrix(Render *re, struct Object *camera, float r_modelmat[4][4])
|
|
{
|
|
BKE_camera_multiview_model_matrix(&re->r, camera, re->viewname, r_modelmat);
|
|
}
|
|
|
|
void RE_GetViewPlane(Render *re, rctf *r_viewplane, rcti *r_disprect)
|
|
{
|
|
*r_viewplane = re->viewplane;
|
|
|
|
/* make disprect zero when no border render, is needed to detect changes in 3d view render */
|
|
if (re->r.mode & R_BORDER) {
|
|
*r_disprect = re->disprect;
|
|
}
|
|
else {
|
|
BLI_rcti_init(r_disprect, 0, 0, 0, 0);
|
|
}
|
|
}
|