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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/draw/intern/draw_manager_data.c4
-rw-r--r--source/blender/gpu/GPU_material.h3
-rw-r--r--source/blender/gpu/GPU_texture.h2
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c23
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h1
-rw-r--r--source/blender/gpu/intern/gpu_material.c61
-rw-r--r--source/blender/gpu/intern/gpu_texture.c7
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl48
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_blackbody.c7
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_curves.c12
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_valToRgb.c5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_volume_principled.c14
12 files changed, 130 insertions, 57 deletions
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 6b15803723b..b97101c0e6d 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -776,7 +776,9 @@ static DRWShadingGroup *drw_shgroup_material_inputs(DRWShadingGroup *grp, struct
}
/* Color Ramps */
else if (input->tex) {
- DRW_shgroup_uniform_texture(grp, input->shadername, input->tex);
+ /* HACK : input->tex is a (GPUTexture **) in this case. */
+ GPUTexture *tex = *((GPUTexture **)input->tex);
+ DRW_shgroup_uniform_texture(grp, input->shadername, tex);
}
/* Floats */
else {
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 9dcf308a414..6b0296361ec 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -80,6 +80,7 @@ typedef enum GPUType {
GPU_MAT4 = 16,
/* Values not in GPU_DATATYPE_STR */
+ GPU_TEX1D_ARRAY = 1001,
GPU_TEX2D = 1002,
GPU_TEX3D = 1003,
GPU_SHADOW2D = 1004,
@@ -229,7 +230,7 @@ GPUNodeLink *GPU_uniform_buffer(float *num, GPUType gputype);
GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser, bool is_data);
GPUNodeLink *GPU_cube_map(struct Image *ima, struct ImageUser *iuser, bool is_data);
GPUNodeLink *GPU_image_preview(struct PreviewImage *prv);
-GPUNodeLink *GPU_texture(int size, float *pixels);
+GPUNodeLink *GPU_texture_ramp(GPUMaterial *mat, int size, float *pixels, float *layer);
GPUNodeLink *GPU_dynamic_texture(struct GPUTexture *tex, GPUDynamicType dynamictype, void *data);
GPUNodeLink *GPU_builtin(GPUBuiltin builtin);
GPUNodeLink *GPU_opengl_builtin(GPUOpenGLBuiltin builtin);
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 1ddf801e166..23b88645e33 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -163,6 +163,8 @@ GPUTexture *GPU_texture_create_nD(
GPUTexture *GPU_texture_create_1D(
int w, GPUTextureFormat data_type, const float *pixels, char err_out[256]);
+GPUTexture *GPU_texture_create_1D_array(
+ int w, int h, GPUTextureFormat data_type, const float *pixels, char err_out[256]);
GPUTexture *GPU_texture_create_2D(
int w, int h, GPUTextureFormat data_type, const float *pixels, char err_out[256]);
GPUTexture *GPU_texture_create_2D_multisample(
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index cc4b7cc8ebc..289befe674e 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -257,6 +257,9 @@ static void gpu_parse_functions_string(GHash *hash, char *code)
if (!type && gpu_str_prefix(code, "sampler2DShadow")) {
type = GPU_SHADOW2D;
}
+ if (!type && gpu_str_prefix(code, "sampler1DArray")) {
+ type = GPU_TEX1D_ARRAY;
+ }
if (!type && gpu_str_prefix(code, "sampler2D")) {
type = GPU_TEX2D;
}
@@ -617,6 +620,7 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds,
if (codegen_input_has_texture(input) && input->bindtex) {
BLI_dynstr_appendf(
ds, "uniform %s samp%d;\n",
+ (input->textype == GPU_TEX1D_ARRAY) ? "sampler1DArray" :
(input->textype == GPU_TEX2D) ? "sampler2D" :
(input->textype == GPU_TEXCUBE) ? "samplerCube" : "sampler2DShadow",
input->texid);
@@ -1330,15 +1334,9 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const GPUType
/* small texture created on the fly, like for colorbands */
input->type = GPU_VEC4;
input->source = GPU_SOURCE_TEX;
- input->textype = type;
-
-#if 0
- input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2, NULL);
-#endif
- input->tex = GPU_texture_create_2D(link->texturesize, 1, GPU_RGBA8, link->ptr1, NULL);
- input->textarget = GL_TEXTURE_2D;
-
- MEM_freeN(link->ptr1);
+ input->textype = GPU_TEX1D_ARRAY;
+ input->tex = link->ptr1; /* HACK ptr1 is actually a (GPUTexture **). */
+ input->textarget = GL_TEXTURE_1D_ARRAY;
MEM_freeN(link);
}
else if (link->image) {
@@ -1687,13 +1685,14 @@ GPUNodeLink *GPU_image_preview(PreviewImage *prv)
}
-GPUNodeLink *GPU_texture(int size, float *pixels)
+GPUNodeLink *GPU_texture_ramp(GPUMaterial *mat, int size, float *pixels, float *row)
{
GPUNodeLink *link = GPU_node_link_create();
link->texture = true;
- link->texturesize = size;
- link->ptr1 = pixels;
+ link->ptr1 = gpu_material_ramp_texture_row_set(mat, size, pixels, row);
+
+ MEM_freeN(pixels);
return link;
}
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index 4af87c6a226..77e6e5cf4ef 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -197,6 +197,7 @@ void gpu_codegen_exit(void);
const char *GPU_builtin_name(GPUBuiltin builtin);
void gpu_material_add_node(struct GPUMaterial *material, struct GPUNode *node);
+struct GPUTexture **gpu_material_ramp_texture_row_set(GPUMaterial *mat, int size, float *pixels, float *row);
int GPU_link_changed(struct GPUNodeLink *link);
#endif
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 69c3a3a73ba..b03df2c643c 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -63,6 +63,12 @@
#endif
/* Structs */
+#define MAX_COLOR_BAND 128
+
+typedef struct GPUColorBandBuilder {
+ float pixels[MAX_COLOR_BAND][CM_TABLE + 1][4];
+ int current_layer;
+} GPUColorBandBuilder;
struct GPUMaterial {
Scene *scene; /* DEPRECATED was only usefull for lamps */
@@ -125,6 +131,9 @@ struct GPUMaterial {
float sss_sharpness;
bool sss_dirty;
+ GPUTexture *coba_tex; /* 1D Texture array containing all color bands. */
+ GPUColorBandBuilder *coba_builder;
+
#ifndef NDEBUG
char name[64];
#endif
@@ -138,6 +147,47 @@ enum {
/* Functions */
+/* Returns the adress of the future pointer to coba_tex */
+GPUTexture **gpu_material_ramp_texture_row_set(GPUMaterial *mat, int size, float *pixels, float *row)
+{
+ /* In order to put all the colorbands into one 1D array texture,
+ * we need them to be the same size. */
+ BLI_assert(size == CM_TABLE + 1);
+
+ if (mat->coba_builder == NULL) {
+ mat->coba_builder = MEM_mallocN(sizeof(GPUColorBandBuilder), "GPUColorBandBuilder");
+ mat->coba_builder->current_layer = 0;
+ }
+
+ int layer = mat->coba_builder->current_layer;
+ *row = (float)layer;
+
+ if (*row == MAX_COLOR_BAND) {
+ printf("Too many color band in shader! Remove some Curve, Black Body or Color Ramp Node.\n");
+ }
+ else {
+ float *dst = (float *)mat->coba_builder->pixels[layer];
+ memcpy(dst, pixels, sizeof(float) * (CM_TABLE + 1) * 4);
+ mat->coba_builder->current_layer += 1;
+ }
+
+ return &mat->coba_tex;
+}
+
+static void gpu_material_ramp_texture_build(GPUMaterial *mat)
+{
+ if (mat->coba_builder == NULL)
+ return;
+
+ GPUColorBandBuilder *builder = mat->coba_builder;
+
+ mat->coba_tex = GPU_texture_create_1D_array(CM_TABLE + 1, builder->current_layer, GPU_RGBA16F,
+ (float *)builder->pixels, NULL);
+
+ MEM_freeN(builder);
+ mat->coba_builder = NULL;
+}
+
static void gpu_material_free_single(GPUMaterial *material)
{
/* Cancel / wait any pending lazy compilation. */
@@ -146,20 +196,21 @@ static void gpu_material_free_single(GPUMaterial *material)
GPU_pass_free_nodes(&material->nodes);
GPU_inputs_free(&material->inputs);
- if (material->pass)
+ if (material->pass != NULL) {
GPU_pass_release(material->pass);
-
+ }
if (material->ubo != NULL) {
GPU_uniformbuffer_free(material->ubo);
}
-
if (material->sss_tex_profile != NULL) {
GPU_texture_free(material->sss_tex_profile);
}
-
if (material->sss_profile != NULL) {
GPU_uniformbuffer_free(material->sss_profile);
}
+ if (material->coba_tex != NULL) {
+ GPU_texture_free(material->coba_tex);
+ }
}
void GPU_material_free(ListBase *gpumaterial)
@@ -622,6 +673,8 @@ GPUMaterial *GPU_material_from_nodetree(
bNodeTree *localtree = ntreeLocalize(ntree);
ntreeGPUMaterialNodes(localtree, mat, &has_surface_output, &has_volume_output);
+ gpu_material_ramp_texture_build(mat);
+
if (has_surface_output) {
mat->domain |= GPU_DOMAIN_SURFACE;
}
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index a5dfb6a6b73..2ccc9f10269 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -871,6 +871,13 @@ GPUTexture *GPU_texture_create_1D(
return GPU_texture_create_nD(w, 0, 0, 1, pixels, tex_format, data_format, 0, false, err_out);
}
+GPUTexture *GPU_texture_create_1D_array(
+ int w, int h, GPUTextureFormat tex_format, const float *pixels, char err_out[256])
+{
+ GPUDataFormat data_format = gpu_get_data_format_from_tex_format(tex_format);
+ return GPU_texture_create_nD(w, h, 0, 1, pixels, tex_format, data_format, 0, false, err_out);
+}
+
GPUTexture *GPU_texture_create_2D(
int w, int h, GPUTextureFormat tex_format, const float *pixels, char err_out[256])
{
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 56fa6291c65..91104fe51bd 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -480,27 +480,26 @@ void normal_new_shading(vec3 dir, vec3 nor, out vec3 outnor, out float outdot)
outdot = dot(normalize(dir), nor);
}
-void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec)
+void curves_vec(float fac, vec3 vec, sampler1DArray curvemap, float layer, out vec3 outvec)
{
- outvec.x = texture(curvemap, vec2((vec.x + 1.0) * 0.5, 0.0)).x;
- outvec.y = texture(curvemap, vec2((vec.y + 1.0) * 0.5, 0.0)).y;
- outvec.z = texture(curvemap, vec2((vec.z + 1.0) * 0.5, 0.0)).z;
-
- if (fac != 1.0)
- outvec = (outvec * fac) + (vec * (1.0 - fac));
-
+ vec4 co = vec4(vec * 0.5 + 0.5, layer);
+ outvec.x = texture(curvemap, co.xw).x;
+ outvec.y = texture(curvemap, co.yw).y;
+ outvec.z = texture(curvemap, co.zw).z;
+ outvec = mix(vec, outvec, fac);
}
-void curves_rgb(float fac, vec4 col, sampler2D curvemap, out vec4 outcol)
+void curves_rgb(float fac, vec4 col, sampler1DArray curvemap, float layer, out vec4 outcol)
{
- outcol.r = texture(curvemap, vec2(texture(curvemap, vec2(col.r, 0.0)).a, 0.0)).r;
- outcol.g = texture(curvemap, vec2(texture(curvemap, vec2(col.g, 0.0)).a, 0.0)).g;
- outcol.b = texture(curvemap, vec2(texture(curvemap, vec2(col.b, 0.0)).a, 0.0)).b;
-
- if (fac != 1.0)
- outcol = (outcol * fac) + (col * (1.0 - fac));
-
+ vec4 co = vec4(col.rgb, layer);
+ co.x = texture(curvemap, co.xw).a;
+ co.y = texture(curvemap, co.yw).a;
+ co.z = texture(curvemap, co.zw).a;
+ outcol.r = texture(curvemap, co.xw).r;
+ outcol.g = texture(curvemap, co.yw).g;
+ outcol.b = texture(curvemap, co.zw).b;
outcol.a = col.a;
+ outcol = mix(col, outcol, fac);
}
void set_value(float val, out float outval)
@@ -813,9 +812,9 @@ void mix_linear(float fac, vec4 col1, vec4 col2, out vec4 outcol)
outcol = col1 + fac * (2.0 * (col2 - vec4(0.5)));
}
-void valtorgb(float fac, sampler2D colormap, out vec4 outcol, out float outalpha)
+void valtorgb(float fac, sampler1DArray colormap, float layer, out vec4 outcol, out float outalpha)
{
- outcol = texture(colormap, vec2(fac, 0.0));
+ outcol = texture(colormap, vec2(fac, layer));
outalpha = outcol.a;
}
@@ -1464,17 +1463,17 @@ void node_volume_absorption(vec4 color, float density, out Closure result)
#endif
}
-void node_blackbody(float temperature, sampler2D spectrummap, out vec4 color)
+void node_blackbody(float temperature, sampler1DArray spectrummap, float layer, out vec4 color)
{
- if(temperature >= 12000.0) {
+ if (temperature >= 12000.0) {
color = vec4(0.826270103, 0.994478524, 1.56626022, 1.0);
}
- else if(temperature < 965.0) {
+ else if (temperature < 965.0) {
color = vec4(4.70366907, 0.0, 0.0, 1.0);
}
else {
float t = (temperature - 965.0) / (12000.0 - 965.0);
- color = vec4(texture(spectrummap, vec2(t, 0.0)).rgb, 1.0);
+ color = vec4(texture(spectrummap, vec2(t, layer)).rgb, 1.0);
}
}
@@ -1491,7 +1490,8 @@ void node_volume_principled(
float density_attribute,
vec4 color_attribute,
float temperature_attribute,
- sampler2D spectrummap,
+ sampler1DArray spectrummap,
+ float layer,
out Closure result)
{
#ifdef VOLUMETRICS
@@ -1533,7 +1533,7 @@ void node_volume_principled(
if(intensity > 1e-5) {
vec4 bb;
- node_blackbody(T, spectrummap, bb);
+ node_blackbody(T, spectrummap, layer, bb);
emission_coeff += bb.rgb * blackbody_tint.rgb * intensity;
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_blackbody.c b/source/blender/nodes/shader/nodes/node_shader_blackbody.c
index 76291df41bc..e57f5e0d6cf 100644
--- a/source/blender/nodes/shader/nodes/node_shader_blackbody.c
+++ b/source/blender/nodes/shader/nodes/node_shader_blackbody.c
@@ -40,12 +40,15 @@ static bNodeSocketTemplate sh_node_blackbody_out[] = {
static int node_shader_gpu_blackbody(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- const int size = 256;
+ const int size = CM_TABLE + 1;
float *data = MEM_mallocN(sizeof(float) * size * 4, "blackbody texture");
blackbody_temperature_to_rgb_table(data, size, 965.0f, 12000.0f);
- return GPU_stack_link(mat, node, "node_blackbody", in, out, GPU_texture(size, data));
+ float layer;
+ GPUNodeLink *ramp_texture = GPU_texture_ramp(mat, size, data, &layer);
+
+ return GPU_stack_link(mat, node, "node_blackbody", in, out, ramp_texture, GPU_uniform(&layer));
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c
index d5932ff233a..21bdc3cd0d8 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.c
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.c
@@ -62,11 +62,13 @@ static void node_shader_init_curve_vec(bNodeTree *UNUSED(ntree), bNode *node)
static int gpu_shader_curve_vec(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- float *array;
+ float *array, layer;
int size;
curvemapping_table_RGBA(node->storage, &array, &size);
- return GPU_stack_link(mat, node, "curves_vec", in, out, GPU_texture(size, array));
+ GPUNodeLink *tex = GPU_texture_ramp(mat, size, array, &layer);
+
+ return GPU_stack_link(mat, node, "curves_vec", in, out, tex, GPU_uniform(&layer));
}
void register_node_type_sh_curve_vec(void)
@@ -119,12 +121,14 @@ static void node_shader_init_curve_rgb(bNodeTree *UNUSED(ntree), bNode *node)
static int gpu_shader_curve_rgb(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- float *array;
+ float *array, layer;
int size;
curvemapping_initialize(node->storage);
curvemapping_table_RGBA(node->storage, &array, &size);
- return GPU_stack_link(mat, node, "curves_rgb", in, out, GPU_texture(size, array));
+ GPUNodeLink *tex = GPU_texture_ramp(mat, size, array, &layer);
+
+ return GPU_stack_link(mat, node, "curves_rgb", in, out, tex, GPU_uniform(&layer));
}
void register_node_type_sh_curve_rgb(void)
diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
index b6581cb18cb..00940b5acaf 100644
--- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
+++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
@@ -65,11 +65,12 @@ static void node_shader_init_valtorgb(bNodeTree *UNUSED(ntree), bNode *node)
static int gpu_shader_valtorgb(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- float *array;
+ float *array, layer;
int size;
BKE_colorband_evaluate_table_rgba(node->storage, &array, &size);
- return GPU_stack_link(mat, node, "valtorgb", in, out, GPU_texture(size, array));
+ GPUNodeLink *tex = GPU_texture_ramp(mat, size, array, &layer);
+ return GPU_stack_link(mat, node, "valtorgb", in, out, tex, GPU_uniform(&layer));
}
void register_node_type_sh_valtorgb(void)
diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_principled.c b/source/blender/nodes/shader/nodes/node_shader_volume_principled.c
index a88a7ebb21a..c946c42f9af 100644
--- a/source/blender/nodes/shader/nodes/node_shader_volume_principled.c
+++ b/source/blender/nodes/shader/nodes/node_shader_volume_principled.c
@@ -132,19 +132,19 @@ static int node_shader_gpu_volume_principled(GPUMaterial *mat, bNode *node, bNod
}
/* Create blackbody spectrum. */
- GPUNodeLink *spectrummap;
+ const int size = CM_TABLE + 1;
+ float *data, layer;
if (use_blackbody) {
- const int size = 256;
- float *data = MEM_mallocN(sizeof(float) * size * 4, "blackbody texture");
+ data = MEM_mallocN(sizeof(float) * size * 4, "blackbody texture");
blackbody_temperature_to_rgb_table(data, size, 965.0f, 12000.0f);
- spectrummap = GPU_texture(size, data);
}
else {
- float *data = MEM_callocN(sizeof(float) * 4, "blackbody black");
- spectrummap = GPU_texture(1, data);
+ data = MEM_callocN(sizeof(float) * size * 4, "blackbody black");
}
+ GPUNodeLink *spectrummap = GPU_texture_ramp(mat, size, data, &layer);
- return GPU_stack_link(mat, node, "node_volume_principled", in, out, density, color, temperature, spectrummap);
+ return GPU_stack_link(mat, node, "node_volume_principled", in, out, density, color, temperature, spectrummap,
+ GPU_uniform(&layer));
}
/* node type definition */