示例#1
0
static int node_shader_gpu_blackbody(GPUMaterial *mat,
                                     bNode *node,
                                     bNodeExecData *UNUSED(execdata),
                                     GPUNodeStack *in,
                                     GPUNodeStack *out)
{
  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);

  float layer;
  GPUNodeLink *ramp_texture = GPU_color_band(mat, size, data, &layer);

  return GPU_stack_link(mat, node, "node_blackbody", in, out, ramp_texture, GPU_constant(&layer));
}
示例#2
0
static GPUTexture *create_flame_spectrum_texture(void)
{
#define SPEC_WIDTH 256
#define FIRE_THRESH 7
#define MAX_FIRE_ALPHA 0.06f
#define FULL_ON_FIRE 100

	GPUTexture *tex;
	int i, j, k;
	float *spec_data = MEM_mallocN(SPEC_WIDTH * 4 * sizeof(float), "spec_data");
	float *spec_pixels = MEM_mallocN(SPEC_WIDTH * 4 * 16 * 16 * sizeof(float), "spec_pixels");

	blackbody_temperature_to_rgb_table(spec_data, SPEC_WIDTH, 1500, 3000);

	for (i = 0; i < 16; i++) {
		for (j = 0; j < 16; j++) {
			for (k = 0; k < SPEC_WIDTH; k++) {
				int index = (j * SPEC_WIDTH * 16 + i * SPEC_WIDTH + k) * 4;
				if (k >= FIRE_THRESH) {
					spec_pixels[index] = (spec_data[k * 4]);
					spec_pixels[index + 1] = (spec_data[k * 4 + 1]);
					spec_pixels[index + 2] = (spec_data[k * 4 + 2]);
					spec_pixels[index + 3] = MAX_FIRE_ALPHA * (
					        (k > FULL_ON_FIRE) ? 1.0f : (k - FIRE_THRESH) / ((float)FULL_ON_FIRE - FIRE_THRESH));
				}
				else {
					zero_v4(&spec_pixels[index]);
				}
			}
		}
	}

	tex = GPU_texture_create_1D(SPEC_WIDTH, spec_pixels, NULL);

	MEM_freeN(spec_data);
	MEM_freeN(spec_pixels);

#undef SPEC_WIDTH
#undef FIRE_THRESH
#undef MAX_FIRE_ALPHA
#undef FULL_ON_FIRE

	return tex;
}
static int node_shader_gpu_volume_principled(GPUMaterial *mat,
                                             bNode *node,
                                             bNodeExecData *UNUSED(execdata),
                                             GPUNodeStack *in,
                                             GPUNodeStack *out)
{
  /* Test if blackbody intensity is enabled. */
  bool use_blackbody = (in[8].link || in[8].vec[0] != 0.0f);

  /* Get volume attributes. */
  GPUNodeLink *density = NULL, *color = NULL, *temperature = NULL;

  for (bNodeSocket *sock = node->inputs.first; sock; sock = sock->next) {
    if (sock->typeinfo->type != SOCK_STRING) {
      continue;
    }

    bNodeSocketValueString *value = sock->default_value;
    GPUNodeLink *outcol, *outvec, *outf;

    if (STREQ(sock->name, "Density Attribute")) {
      node_shader_gpu_volume_attribute(mat, value->value, &outcol, &outvec, &density);
    }
    else if (STREQ(sock->name, "Color Attribute")) {
      node_shader_gpu_volume_attribute(mat, value->value, &color, &outvec, &outf);
    }
    else if (use_blackbody && STREQ(sock->name, "Temperature Attribute")) {
      node_shader_gpu_volume_attribute(mat, value->value, &outcol, &outvec, &temperature);
    }
  }

  /* Default values if attributes not found. */
  if (!density) {
    static float one = 1.0f;
    density = GPU_constant(&one);
  }
  if (!color) {
    static float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
    color = GPU_constant(white);
  }
  if (!temperature) {
    static float one = 1.0f;
    temperature = GPU_constant(&one);
  }

  /* Create blackbody spectrum. */
  const int size = CM_TABLE + 1;
  float *data, layer;
  if (use_blackbody) {
    data = MEM_mallocN(sizeof(float) * size * 4, "blackbody texture");
    blackbody_temperature_to_rgb_table(data, size, 965.0f, 12000.0f);
  }
  else {
    data = MEM_callocN(sizeof(float) * size * 4, "blackbody black");
  }
  GPUNodeLink *spectrummap = GPU_color_band(mat, size, data, &layer);

  return GPU_stack_link(mat,
                        node,
                        "node_volume_principled",
                        in,
                        out,
                        density,
                        color,
                        temperature,
                        spectrummap,
                        GPU_constant(&layer));
}