DRW: Use USHORT for vertex color and upload them in linear color to the GPU
This way we remove the need for the srgb boolean uniform and a lot of code complexity. However, mesh update is going to be a bit slower. I did not benchmark the performance impact. This also fix a typo in draw_cache_impl_particles.c and fix hair not using vertex color in workbench. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D6610
This commit is contained in:
parent
9410e5dc97
commit
6eaf51ef3e
Notes:
blender-bot
2023-02-14 05:51:15 +01:00
Referenced by issue #75263, Vertex Colors and Hair Particles crashes Blender Referenced by issue #67226, Eevee: Vertex Color Groups with the same name but used in different materials produce inconsistent results
|
@ -1529,18 +1529,10 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
|
|||
|
||||
if ((ob->dt >= OB_SOLID) || DRW_state_is_image_render()) {
|
||||
/* Get per-material split surface */
|
||||
char *auto_layer_names;
|
||||
int *auto_layer_is_srgb;
|
||||
int auto_layer_count;
|
||||
struct GPUBatch **mat_geom = NULL;
|
||||
|
||||
if (!use_sculpt_pbvh) {
|
||||
mat_geom = DRW_cache_object_surface_material_get(ob,
|
||||
gpumat_array,
|
||||
materials_len,
|
||||
&auto_layer_names,
|
||||
&auto_layer_is_srgb,
|
||||
&auto_layer_count);
|
||||
mat_geom = DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len);
|
||||
}
|
||||
|
||||
if (use_sculpt_pbvh) {
|
||||
|
@ -1577,28 +1569,6 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
|
|||
ADD_SHGROUP_CALL_SAFE(shgrp_depth_array[i], ob, mat_geom[i], oedata);
|
||||
ADD_SHGROUP_CALL_SAFE(shgrp_depth_clip_array[i], ob, mat_geom[i], oedata);
|
||||
|
||||
char *name = auto_layer_names;
|
||||
for (int j = 0; j < auto_layer_count; j++) {
|
||||
/* TODO don't add these uniform when not needed (default pass shaders). */
|
||||
/* FIXME: This is broken, as it overrides any autolayers srgb bool of the previous mesh
|
||||
* that shares the same material. */
|
||||
if (shgrp_array[i]) {
|
||||
DRW_shgroup_uniform_bool_copy(shgrp_array[i], name, auto_layer_is_srgb[j]);
|
||||
}
|
||||
if (shgrp_depth_array[i]) {
|
||||
DRW_shgroup_uniform_bool_copy(shgrp_depth_array[i], name, auto_layer_is_srgb[j]);
|
||||
}
|
||||
if (shgrp_depth_clip_array[i]) {
|
||||
DRW_shgroup_uniform_bool_copy(
|
||||
shgrp_depth_clip_array[i], name, auto_layer_is_srgb[j]);
|
||||
}
|
||||
/* Go to next layer name. */
|
||||
while (*name != '\0') {
|
||||
name++;
|
||||
}
|
||||
name += 1;
|
||||
}
|
||||
|
||||
/* Shadow Pass */
|
||||
struct GPUMaterial *gpumat;
|
||||
const bool use_gpumat = (ma_array[i]->use_nodes && ma_array[i]->nodetree);
|
||||
|
|
|
@ -4,13 +4,18 @@ in vec3 pos;
|
|||
in vec3 nor;
|
||||
in vec2 au; /* active texture layer */
|
||||
# ifdef V3D_SHADING_VERTEX_COLOR
|
||||
in vec3 ac; /* active color */
|
||||
in vec4 ac; /* active color */
|
||||
# endif
|
||||
# define uv au
|
||||
#else /* HAIR_SHADER */
|
||||
|
||||
# ifdef V3D_SHADING_TEXTURE_COLOR
|
||||
uniform samplerBuffer au; /* active texture layer */
|
||||
# endif
|
||||
# ifdef V3D_SHADING_VERTEX_COLOR
|
||||
uniform samplerBuffer ac; /* active color layer */
|
||||
# endif
|
||||
|
||||
flat out float hair_rand;
|
||||
#endif /* HAIR_SHADER */
|
||||
|
||||
|
@ -37,16 +42,6 @@ float integer_noise(int n)
|
|||
return (float(nn) / 1073741824.0);
|
||||
}
|
||||
|
||||
#ifdef V3D_SHADING_VERTEX_COLOR
|
||||
vec3 srgb_to_linear_attr(vec3 c)
|
||||
{
|
||||
c = max(c, vec3(0.0));
|
||||
vec3 c1 = c * (1.0 / 12.92);
|
||||
vec3 c2 = pow((c + 0.055) * (1.0 / 1.055), vec3(2.4));
|
||||
return mix(c1, c2, step(vec3(0.04045), c));
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 workbench_hair_hair_normal(vec3 tan, vec3 binor, float rand)
|
||||
{
|
||||
/* To "simulate" anisotropic shading, randomize hair normal per strand. */
|
||||
|
@ -90,7 +85,9 @@ void main()
|
|||
|
||||
#ifdef V3D_SHADING_VERTEX_COLOR
|
||||
# ifndef HAIR_SHADER
|
||||
vertexColor = srgb_to_linear_attr(ac);
|
||||
vertexColor = ac.rgb;
|
||||
# else
|
||||
vertexColor = hair_get_customdata_vec4(ac).rgb;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1138,8 +1138,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||
struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
|
||||
memset(gpumat_array, 0, sizeof(*gpumat_array) * materials_len);
|
||||
|
||||
geoms = DRW_cache_object_surface_material_get(
|
||||
ob, gpumat_array, materials_len, NULL, NULL, NULL);
|
||||
geoms = DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len);
|
||||
for (int i = 0; i < materials_len; i++) {
|
||||
if (geoms != NULL && geoms[i] != NULL) {
|
||||
Material *mat = give_current_material(ob, i + 1);
|
||||
|
|
|
@ -756,7 +756,7 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||
memset(gpumat_array, 0, sizeof(*gpumat_array) * materials_len);
|
||||
|
||||
struct GPUBatch **mat_geom = DRW_cache_object_surface_material_get(
|
||||
ob, gpumat_array, materials_len, NULL, NULL, NULL);
|
||||
ob, gpumat_array, materials_len);
|
||||
if (mat_geom) {
|
||||
for (int i = 0; i < materials_len; i++) {
|
||||
if (mat_geom[i] == NULL) {
|
||||
|
|
|
@ -826,25 +826,11 @@ GPUBatch *DRW_cache_object_surface_get(Object *ob)
|
|||
|
||||
GPUBatch **DRW_cache_object_surface_material_get(struct Object *ob,
|
||||
struct GPUMaterial **gpumat_array,
|
||||
uint gpumat_array_len,
|
||||
char **auto_layer_names,
|
||||
int **auto_layer_is_srgb,
|
||||
int *auto_layer_count)
|
||||
uint gpumat_array_len)
|
||||
{
|
||||
if (auto_layer_names != NULL) {
|
||||
*auto_layer_names = NULL;
|
||||
*auto_layer_is_srgb = NULL;
|
||||
*auto_layer_count = 0;
|
||||
}
|
||||
|
||||
switch (ob->type) {
|
||||
case OB_MESH:
|
||||
return DRW_cache_mesh_surface_shaded_get(ob,
|
||||
gpumat_array,
|
||||
gpumat_array_len,
|
||||
auto_layer_names,
|
||||
auto_layer_is_srgb,
|
||||
auto_layer_count);
|
||||
return DRW_cache_mesh_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
|
||||
case OB_CURVE:
|
||||
return DRW_cache_curve_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
|
||||
case OB_SURF:
|
||||
|
@ -2733,18 +2719,10 @@ GPUBatch *DRW_cache_mesh_surface_edges_get(Object *ob)
|
|||
/* Return list of batches with length equal to max(1, totcol). */
|
||||
GPUBatch **DRW_cache_mesh_surface_shaded_get(Object *ob,
|
||||
struct GPUMaterial **gpumat_array,
|
||||
uint gpumat_array_len,
|
||||
char **auto_layer_names,
|
||||
int **auto_layer_is_srgb,
|
||||
int *auto_layer_count)
|
||||
uint gpumat_array_len)
|
||||
{
|
||||
BLI_assert(ob->type == OB_MESH);
|
||||
return DRW_mesh_batch_cache_get_surface_shaded(ob->data,
|
||||
gpumat_array,
|
||||
gpumat_array_len,
|
||||
auto_layer_names,
|
||||
auto_layer_is_srgb,
|
||||
auto_layer_count);
|
||||
return DRW_mesh_batch_cache_get_surface_shaded(ob->data, gpumat_array, gpumat_array_len);
|
||||
}
|
||||
|
||||
/* Return list of batches with length equal to max(1, totcol). */
|
||||
|
@ -2895,8 +2873,7 @@ GPUBatch **DRW_cache_curve_surface_shaded_get(Object *ob,
|
|||
struct Curve *cu = ob->data;
|
||||
struct Mesh *mesh_eval = ob->runtime.mesh_eval;
|
||||
if (mesh_eval != NULL) {
|
||||
return DRW_mesh_batch_cache_get_surface_shaded(
|
||||
mesh_eval, gpumat_array, gpumat_array_len, NULL, NULL, NULL);
|
||||
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len);
|
||||
}
|
||||
else {
|
||||
return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
|
||||
|
@ -3036,8 +3013,7 @@ GPUBatch **DRW_cache_text_surface_shaded_get(Object *ob,
|
|||
return NULL;
|
||||
}
|
||||
if (mesh_eval != NULL) {
|
||||
return DRW_mesh_batch_cache_get_surface_shaded(
|
||||
mesh_eval, gpumat_array, gpumat_array_len, NULL, NULL, NULL);
|
||||
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len);
|
||||
}
|
||||
else {
|
||||
return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
|
||||
|
@ -3131,8 +3107,7 @@ GPUBatch **DRW_cache_surf_surface_shaded_get(Object *ob,
|
|||
struct Curve *cu = ob->data;
|
||||
struct Mesh *mesh_eval = ob->runtime.mesh_eval;
|
||||
if (mesh_eval != NULL) {
|
||||
return DRW_mesh_batch_cache_get_surface_shaded(
|
||||
mesh_eval, gpumat_array, gpumat_array_len, NULL, NULL, NULL);
|
||||
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len);
|
||||
}
|
||||
else {
|
||||
return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
|
||||
|
|
|
@ -54,10 +54,7 @@ struct GPUBatch *DRW_cache_object_surface_get(struct Object *ob);
|
|||
struct GPUBatch *DRW_cache_object_loose_edges_get(struct Object *ob);
|
||||
struct GPUBatch **DRW_cache_object_surface_material_get(struct Object *ob,
|
||||
struct GPUMaterial **gpumat_array,
|
||||
uint gpumat_array_len,
|
||||
char **auto_layer_names,
|
||||
int **auto_layer_is_srgb,
|
||||
int *auto_layer_count);
|
||||
uint gpumat_array_len);
|
||||
struct GPUBatch *DRW_cache_object_face_wireframe_get(struct Object *ob);
|
||||
|
||||
/* Empties */
|
||||
|
@ -127,10 +124,7 @@ struct GPUBatch *DRW_cache_mesh_surface_get(struct Object *ob);
|
|||
struct GPUBatch *DRW_cache_mesh_surface_edges_get(struct Object *ob);
|
||||
struct GPUBatch **DRW_cache_mesh_surface_shaded_get(struct Object *ob,
|
||||
struct GPUMaterial **gpumat_array,
|
||||
uint gpumat_array_len,
|
||||
char **auto_layer_names,
|
||||
int **auto_layer_is_srgb,
|
||||
int *auto_layer_count);
|
||||
uint gpumat_array_len);
|
||||
struct GPUBatch **DRW_cache_mesh_surface_texpaint_get(struct Object *ob);
|
||||
struct GPUBatch *DRW_cache_mesh_surface_texpaint_single_get(struct Object *ob);
|
||||
struct GPUBatch *DRW_cache_mesh_surface_vertpaint_get(struct Object *ob);
|
||||
|
|
|
@ -213,12 +213,6 @@ typedef struct MeshBatchCache {
|
|||
|
||||
GPUBatch **surface_per_mat;
|
||||
|
||||
/* arrays of bool uniform names (and value) that will be use to
|
||||
* set srgb conversion for auto attributes.*/
|
||||
char *auto_layer_names;
|
||||
int *auto_layer_is_srgb;
|
||||
int auto_layer_len;
|
||||
|
||||
DRWBatchFlag batch_requested;
|
||||
DRWBatchFlag batch_ready;
|
||||
|
||||
|
|
|
@ -1928,7 +1928,7 @@ static void *extract_vcol_init(const MeshRenderData *mr, void *buf)
|
|||
GPU_vertformat_safe_attrib_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTRIB_NAME);
|
||||
|
||||
BLI_snprintf(attr_name, sizeof(attr_name), "c%s", attr_safe_name);
|
||||
GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||
GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||
|
||||
if (i == CustomData_get_render_layer(cd_ldata, CD_MLOOPCOL)) {
|
||||
GPU_vertformat_alias_add(&format, "c");
|
||||
|
@ -1948,12 +1948,20 @@ static void *extract_vcol_init(const MeshRenderData *mr, void *buf)
|
|||
GPU_vertbuf_init_with_format(vbo, &format);
|
||||
GPU_vertbuf_data_alloc(vbo, mr->loop_len);
|
||||
|
||||
MLoopCol *vcol_data = (MLoopCol *)vbo->data;
|
||||
typedef struct gpuMeshVcol {
|
||||
ushort r, g, b, a;
|
||||
} gpuMeshVcol;
|
||||
|
||||
gpuMeshVcol *vcol_data = (gpuMeshVcol *)vbo->data;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (vcol_layers & (1 << i)) {
|
||||
void *layer_data = CustomData_get_layer_n(cd_ldata, CD_MLOOPCOL, i);
|
||||
memcpy(vcol_data, layer_data, sizeof(*vcol_data) * mr->loop_len);
|
||||
vcol_data += mr->loop_len;
|
||||
MLoopCol *mcol = (MLoopCol *)CustomData_get_layer_n(cd_ldata, CD_MLOOPCOL, i);
|
||||
for (int l = 0; l < mr->loop_len; l++, mcol++, vcol_data++) {
|
||||
vcol_data->r = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->r]);
|
||||
vcol_data->g = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->g]);
|
||||
vcol_data->b = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->b]);
|
||||
vcol_data->a = unit_float_to_ushort_clamp(mcol->a * (1.0f / 255.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
@ -127,10 +127,7 @@ struct GPUBatch *DRW_mesh_batch_cache_get_surface(struct Mesh *me);
|
|||
struct GPUBatch *DRW_mesh_batch_cache_get_surface_edges(struct Mesh *me);
|
||||
struct GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(struct Mesh *me,
|
||||
struct GPUMaterial **gpumat_array,
|
||||
uint gpumat_array_len,
|
||||
char **auto_layer_names,
|
||||
int **auto_layer_is_srgb,
|
||||
int *auto_layer_count);
|
||||
uint gpumat_array_len);
|
||||
struct GPUBatch **DRW_mesh_batch_cache_get_surface_texpaint(struct Mesh *me);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_surface_texpaint_single(struct Mesh *me);
|
||||
struct GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(struct Mesh *me);
|
||||
|
|
|
@ -230,68 +230,6 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Mesh *me,
|
|||
return cd_used;
|
||||
}
|
||||
|
||||
static void mesh_cd_extract_auto_layers_names_and_srgb(Mesh *me,
|
||||
DRW_MeshCDMask cd_used,
|
||||
char **r_auto_layers_names,
|
||||
int **r_auto_layers_srgb,
|
||||
int *r_auto_layers_len)
|
||||
{
|
||||
const Mesh *me_final = (me->edit_mesh) ? me->edit_mesh->mesh_eval_final : me;
|
||||
const CustomData *cd_ldata = &me_final->ldata;
|
||||
|
||||
int uv_len_used = count_bits_i(cd_used.uv);
|
||||
int vcol_len_used = count_bits_i(cd_used.vcol);
|
||||
int uv_len = CustomData_number_of_layers(cd_ldata, CD_MLOOPUV);
|
||||
int vcol_len = CustomData_number_of_layers(cd_ldata, CD_MLOOPCOL);
|
||||
|
||||
uint auto_names_len = 32 * (uv_len_used + vcol_len_used);
|
||||
uint auto_ofs = 0;
|
||||
/* Allocate max, resize later. */
|
||||
char *auto_names = MEM_callocN(sizeof(char) * auto_names_len, __func__);
|
||||
int *auto_is_srgb = MEM_callocN(sizeof(int) * (uv_len_used + vcol_len_used), __func__);
|
||||
|
||||
for (int i = 0; i < uv_len; i++) {
|
||||
if ((cd_used.uv & (1 << i)) != 0) {
|
||||
const char *name = CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i);
|
||||
char safe_name[GPU_MAX_SAFE_ATTRIB_NAME];
|
||||
GPU_vertformat_safe_attrib_name(name, safe_name, GPU_MAX_SAFE_ATTRIB_NAME);
|
||||
auto_ofs += BLI_snprintf_rlen(
|
||||
auto_names + auto_ofs, auto_names_len - auto_ofs, "ba%s", safe_name);
|
||||
/* +1 to include '\0' terminator. */
|
||||
auto_ofs += 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint auto_is_srgb_ofs = uv_len_used;
|
||||
for (int i = 0; i < vcol_len; i++) {
|
||||
if ((cd_used.vcol & (1 << i)) != 0) {
|
||||
const char *name = CustomData_get_layer_name(cd_ldata, CD_MLOOPCOL, i);
|
||||
/* We only do vcols that are not overridden by a uv layer with same name. */
|
||||
if (CustomData_get_named_layer_index(cd_ldata, CD_MLOOPUV, name) == -1) {
|
||||
char safe_name[GPU_MAX_SAFE_ATTRIB_NAME];
|
||||
GPU_vertformat_safe_attrib_name(name, safe_name, GPU_MAX_SAFE_ATTRIB_NAME);
|
||||
auto_ofs += BLI_snprintf_rlen(
|
||||
auto_names + auto_ofs, auto_names_len - auto_ofs, "ba%s", safe_name);
|
||||
/* +1 to include '\0' terminator. */
|
||||
auto_ofs += 1;
|
||||
auto_is_srgb[auto_is_srgb_ofs] = true;
|
||||
auto_is_srgb_ofs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto_names = MEM_reallocN(auto_names, sizeof(char) * auto_ofs);
|
||||
auto_is_srgb = MEM_reallocN(auto_is_srgb, sizeof(int) * auto_is_srgb_ofs);
|
||||
|
||||
/* WATCH: May have been referenced somewhere before freeing. */
|
||||
MEM_SAFE_FREE(*r_auto_layers_names);
|
||||
MEM_SAFE_FREE(*r_auto_layers_srgb);
|
||||
|
||||
*r_auto_layers_names = auto_names;
|
||||
*r_auto_layers_srgb = auto_is_srgb;
|
||||
*r_auto_layers_len = auto_is_srgb_ofs;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
@ -492,8 +430,6 @@ static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache)
|
|||
mesh_cd_layers_type_clear(&cache->cd_used);
|
||||
|
||||
MEM_SAFE_FREE(cache->surface_per_mat);
|
||||
MEM_SAFE_FREE(cache->auto_layer_names);
|
||||
MEM_SAFE_FREE(cache->auto_layer_is_srgb);
|
||||
|
||||
cache->mat_len = 0;
|
||||
}
|
||||
|
@ -771,10 +707,7 @@ GPUBatch *DRW_mesh_batch_cache_get_edit_mesh_analysis(Mesh *me)
|
|||
|
||||
GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(Mesh *me,
|
||||
struct GPUMaterial **gpumat_array,
|
||||
uint gpumat_array_len,
|
||||
char **auto_layer_names,
|
||||
int **auto_layer_is_srgb,
|
||||
int *auto_layer_count)
|
||||
uint gpumat_array_len)
|
||||
{
|
||||
MeshBatchCache *cache = mesh_batch_cache_get(me);
|
||||
DRW_MeshCDMask cd_needed = mesh_cd_calc_used_gpu_layers(me, gpumat_array, gpumat_array_len);
|
||||
|
@ -783,21 +716,8 @@ GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(Mesh *me,
|
|||
|
||||
mesh_cd_layers_type_merge(&cache->cd_needed, cd_needed);
|
||||
|
||||
if (!mesh_cd_layers_type_overlap(cache->cd_used, cd_needed)) {
|
||||
mesh_cd_extract_auto_layers_names_and_srgb(me,
|
||||
cache->cd_needed,
|
||||
&cache->auto_layer_names,
|
||||
&cache->auto_layer_is_srgb,
|
||||
&cache->auto_layer_len);
|
||||
}
|
||||
|
||||
mesh_batch_cache_add_request(cache, MBC_SURF_PER_MAT);
|
||||
|
||||
if (auto_layer_names) {
|
||||
*auto_layer_names = cache->auto_layer_names;
|
||||
*auto_layer_is_srgb = cache->auto_layer_is_srgb;
|
||||
*auto_layer_count = cache->auto_layer_len;
|
||||
}
|
||||
for (int i = 0; i < cache->mat_len; i++) {
|
||||
DRW_batch_request(&cache->surface_per_mat[i]);
|
||||
}
|
||||
|
|
|
@ -1199,7 +1199,7 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit,
|
|||
GPU_vertformat_safe_attrib_name(name, attr_safe_name, GPU_MAX_SAFE_ATTRIB_NAME);
|
||||
|
||||
BLI_snprintf(uuid, sizeof(uuid), "c%s", attr_safe_name);
|
||||
col_id[i] = GPU_vertformat_attr_add(&format, uuid, GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
col_id[i] = GPU_vertformat_attr_add(&format, uuid, GPU_COMP_U16, 4, GPU_FETCH_FLOAT);
|
||||
|
||||
if (i == active_col) {
|
||||
GPU_vertformat_alias_add(&format, "c");
|
||||
|
|
|
@ -116,7 +116,7 @@ void gpu_pbvh_init()
|
|||
g_vbo_id.msk = GPU_vertformat_attr_add(
|
||||
&g_vbo_id.format, "msk", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
g_vbo_id.col = GPU_vertformat_attr_add(
|
||||
&g_vbo_id.format, "ac", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||
&g_vbo_id.format, "ac", GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,8 +240,13 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
|
|||
for (int j = 0; j < 3; j++) {
|
||||
const int loop_index = lt->tri[j];
|
||||
const int vidx = face_vert_indices[i][j];
|
||||
const uchar *elem = &vcol[loop_index].r;
|
||||
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vidx, elem);
|
||||
const MLoopCol *mcol = &vcol[loop_index];
|
||||
ushort scol[4];
|
||||
scol[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->r]);
|
||||
scol[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->g]);
|
||||
scol[2] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->b]);
|
||||
scol[3] = unit_float_to_ushort_clamp(mcol->a * (1.0f / 255.0f));
|
||||
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vidx, scol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -289,8 +294,13 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
|
|||
|
||||
if (show_vcol) {
|
||||
const uint loop_index = lt->tri[j];
|
||||
const uchar *elem = &vcol[loop_index].r;
|
||||
memcpy(GPU_vertbuf_raw_step(&col_step), elem, sizeof(uchar) * 4);
|
||||
const MLoopCol *mcol = &vcol[loop_index];
|
||||
ushort scol[4];
|
||||
scol[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->r]);
|
||||
scol[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->g]);
|
||||
scol[2] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->b]);
|
||||
scol[3] = unit_float_to_ushort_clamp(mcol->a * (1.0f / 255.0f));
|
||||
memcpy(GPU_vertbuf_raw_step(&col_step), scol, sizeof(scol));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -654,7 +664,7 @@ void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers,
|
|||
}
|
||||
|
||||
if (show_vcol) {
|
||||
char vcol[4] = {255, 255, 255, 255};
|
||||
ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
|
||||
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index, &vcol);
|
||||
}
|
||||
|
||||
|
@ -705,7 +715,7 @@ void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers,
|
|||
empty_mask = empty_mask && (fmask == 0.0f);
|
||||
}
|
||||
|
||||
char vcol[4] = {255, 255, 255, 255};
|
||||
ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
|
||||
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 0, &vcol);
|
||||
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 1, &vcol);
|
||||
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 2, &vcol);
|
||||
|
@ -781,7 +791,7 @@ static void gpu_bmesh_vert_to_buffer_copy(BMVert *v,
|
|||
}
|
||||
|
||||
if (show_vcol) {
|
||||
static char vcol[4] = {255, 255, 255, 255};
|
||||
ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
|
||||
GPU_vertbuf_attr_set(vert_buf, g_vbo_id.col, v_index, &vcol);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1042,12 +1042,6 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
|
|||
input->attr_id,
|
||||
attr_prefix_get(input->attr_type),
|
||||
attr_safe_name);
|
||||
/* Auto attribute can be vertex color byte buffer.
|
||||
* We need to know and convert them to linear space in VS. */
|
||||
if (input->attr_type == CD_AUTO_FROM_NAME) {
|
||||
BLI_dynstr_appendf(ds, "uniform bool ba%s;\n", attr_safe_name);
|
||||
BLI_dynstr_appendf(ds, "#define att%d_is_srgb ba%s\n", input->attr_id, attr_safe_name);
|
||||
}
|
||||
}
|
||||
BLI_dynstr_appendf(ds,
|
||||
"out %s var%d%s;\n",
|
||||
|
@ -1101,24 +1095,6 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
|
|||
|
||||
BLI_dynstr_append(ds, use_geom ? "RESOURCE_ID_VARYING_GEOM\n" : "RESOURCE_ID_VARYING\n");
|
||||
|
||||
BLI_dynstr_append(ds,
|
||||
"#define USE_ATTR\n"
|
||||
"vec3 srgb_to_linear_attr(vec3 c) {\n"
|
||||
"\tc = max(c, vec3(0.0));\n"
|
||||
"\tvec3 c1 = c * (1.0 / 12.92);\n"
|
||||
"\tvec3 c2 = pow((c + 0.055) * (1.0 / 1.055), vec3(2.4));\n"
|
||||
"\treturn mix(c1, c2, step(vec3(0.04045), c));\n"
|
||||
"}\n\n");
|
||||
|
||||
BLI_dynstr_append(ds,
|
||||
"vec4 srgba_to_linear_attr(vec4 c) {\n"
|
||||
"\tc = max(c, vec4(0.0));\n"
|
||||
"\tvec4 c1 = c * (1.0 / 12.92);\n"
|
||||
"\tvec4 c2 = pow((c + 0.055) * (1.0 / 1.055), vec4(2.4));\n"
|
||||
"\tvec4 final = mix(c1, c2, step(vec4(0.04045), c));"
|
||||
"\treturn vec4(final.xyz, c.a);\n"
|
||||
"}\n\n");
|
||||
|
||||
/* Prototype because defined later. */
|
||||
BLI_dynstr_append(ds,
|
||||
"vec2 hair_get_customdata_vec2(const samplerBuffer);\n"
|
||||
|
@ -1224,22 +1200,6 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
|
|||
input->attr_id,
|
||||
use_geom ? "g" : "");
|
||||
}
|
||||
else if (input->attr_type == CD_MCOL) {
|
||||
BLI_dynstr_appendf(ds,
|
||||
"\tvar%d%s = srgba_to_linear_attr(att%d);\n",
|
||||
input->attr_id,
|
||||
use_geom ? "g" : "",
|
||||
input->attr_id);
|
||||
}
|
||||
else if (input->attr_type == CD_AUTO_FROM_NAME) {
|
||||
BLI_dynstr_appendf(ds,
|
||||
"\tvar%d%s = (att%d_is_srgb) ? srgb_to_linear_attr(att%d) : att%d;\n",
|
||||
input->attr_id,
|
||||
use_geom ? "g" : "",
|
||||
input->attr_id,
|
||||
input->attr_id,
|
||||
input->attr_id);
|
||||
}
|
||||
else {
|
||||
BLI_dynstr_appendf(
|
||||
ds, "\tvar%d%s = att%d;\n", input->attr_id, use_geom ? "g" : "", input->attr_id);
|
||||
|
|
Loading…
Reference in New Issue