Files
test2/intern/cycles/subd/dice.h
Brecht Van Lommel 59b4842117 Cycles: Adaptive subdivision triangular patches
There is a corner case where one side of a quad needs splitting and the other
side has only one segment. Previously this would produce either gaps or after
recent changes to stitch together geometry, uninitialized memory.

Now solve this by splitting into triangular patches, as suggested in the
DiagSplit paper. These triangular patches can be further subdivided themselves.
Dicing has special cases for 1 or 2 segments on edges. For more segments it
works the same as: quad dicing: A regular inner triangle grid stitched to the
outer edges.

Fix #136973: Inconsistent results with adaptive subdivision

Pull Request: https://projects.blender.org/blender/blender/pulls/139062
2025-05-19 12:04:11 +02:00

85 lines
2.4 KiB
C++

/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: Apache-2.0 */
#pragma once
/* DX11 like EdgeDice implementation, with different tessellation factors for
* each edge for watertight tessellation, with subpatch remapping to work with
* DiagSplit. For more algorithm details, see the DiagSplit paper or the
* ARB_tessellation_shader OpenGL extension, Section 2.X.2. */
#include "util/transform.h"
#include "util/types.h"
#include "subd/subpatch.h"
CCL_NAMESPACE_BEGIN
class Camera;
class Mesh;
class Patch;
class SubdAttributeInterpolation;
class DiagSplit;
struct SubdParams {
Mesh *mesh = nullptr;
bool ptex = false;
int test_steps = 3;
int split_threshold = 1;
float dicing_rate = 1.0f;
int max_level = 12;
Camera *camera = nullptr;
Transform objecttoworld = transform_identity();
SubdParams(Mesh *mesh_, bool ptex_ = false) : mesh(mesh_), ptex(ptex_) {}
};
class EdgeDice {
public:
SubdParams params;
SubdAttributeInterpolation &interpolation;
int *mesh_triangles = nullptr;
int *mesh_shader = nullptr;
bool *mesh_smooth = nullptr;
float3 *mesh_P = nullptr;
float3 *mesh_N = nullptr;
float *mesh_ptex_face_id = nullptr;
float2 *mesh_ptex_uv = nullptr;
explicit EdgeDice(const SubdParams &params,
const int num_verts,
const int num_triangles,
SubdAttributeInterpolation &interpolation);
void dice(const DiagSplit &split);
protected:
void tri_dice(const SubPatch &sub);
void quad_dice(const SubPatch &sub);
void set_vertex(const SubPatch &sub, const int index, const float2 uv);
void set_triangle(const SubPatch &sub,
const int triangle_index,
const int v0,
const int v1,
const int v2,
const float2 uv0,
const float2 uv1,
const float2 uv2);
void add_grid_triangles_and_stitch(const SubPatch &sub, const int Mu, const int Mv);
void add_triangle_strip(const SubPatch &sub, const int left_edge, const int right_edge);
float3 eval_projected(const SubPatch &sub, const float2 uv);
void tri_set_sides(const SubPatch &sub);
void quad_set_sides(const SubPatch &sub);
float quad_area(const float3 &a, const float3 &b, const float3 &c, const float3 &d);
float scale_factor(const SubPatch &sub, const int Mu, const int Mv);
};
CCL_NAMESPACE_END