42 TFUNC_FLAME_SPECTRUM = 0,
46# define TFUNC_WIDTH 256
48static void create_flame_spectrum_texture(
float *
data)
51# define MAX_FIRE_ALPHA 0.06f
52# define FULL_ON_FIRE 100
58 for (
int i = 0;
i < 16;
i++) {
59 for (
int j = 0; j < 16; j++) {
60 for (
int k = 0; k < TFUNC_WIDTH; k++) {
61 int index = (j * TFUNC_WIDTH * 16 +
i * TFUNC_WIDTH + k) * 4;
62 if (k >= FIRE_THRESH) {
63 spec_pixels[index] = (
data[k * 4]);
64 spec_pixels[index + 1] = (
data[k * 4 + 1]);
65 spec_pixels[index + 2] = (
data[k * 4 + 2]);
66 spec_pixels[index + 3] = MAX_FIRE_ALPHA *
69 (k - FIRE_THRESH) / (float(FULL_ON_FIRE) - FIRE_THRESH));
78 memcpy(
data, spec_pixels,
sizeof(
float) * 4 * TFUNC_WIDTH);
87static void create_color_ramp(
const ColorBand *coba,
float *
data)
89 for (
int i = 0;
i < TFUNC_WIDTH;
i++) {
95static GPUTexture *create_transfer_function(
int type,
const ColorBand *coba)
97 float *
data = (
float *)
MEM_mallocN(
sizeof(
float[4]) * TFUNC_WIDTH, __func__);
100 case TFUNC_FLAME_SPECTRUM:
101 create_flame_spectrum_texture(
data);
103 case TFUNC_COLOR_RAMP:
104 create_color_ramp(coba,
data);
116static void swizzle_texture_channel_single(GPUTexture *tex)
123static float *rescale_3d(
const int dim[3],
124 const int final_dim[3],
126 const float *fpixels)
128 const uint w = dim[0], h = dim[1], d = dim[2];
129 const uint fw = final_dim[0], fh = final_dim[1], fd = final_dim[2];
130 const uint xf =
w / fw, yf = h / fh, zf = d / fd;
131 const uint pixel_count = fw * fh * fd;
132 float *nfpixels = (
float *)
MEM_mallocN(channels *
sizeof(
float) * pixel_count, __func__);
135 printf(
"Performance: You need to scale a 3D texture, feel the pain!\n");
137 for (
uint k = 0; k < fd; k++) {
138 for (
uint j = 0; j < fh; j++) {
139 for (
uint i = 0;
i < fw;
i++) {
145 uint offset = k * (fw * fh) +
i * fh + j;
146 uint offset_orig = (zb) * (
w * h) + (xb)*h + (yb);
149 nfpixels[offset * 4] = fpixels[offset_orig * 4];
150 nfpixels[offset * 4 + 1] = fpixels[offset_orig * 4 + 1];
151 nfpixels[offset * 4 + 2] = fpixels[offset_orig * 4 + 2];
152 nfpixels[offset * 4 + 3] = fpixels[offset_orig * 4 + 3];
154 else if (channels == 1) {
155 nfpixels[offset] = fpixels[offset_orig];
168static GPUTexture *create_volume_texture(
const int dim[3],
173 GPUTexture *tex =
nullptr;
176 if (
data ==
nullptr) {
184 if (tex !=
nullptr) {
188 if (final_dim[0] == 1 && final_dim[1] == 1 && final_dim[2] == 1) {
192 for (
int i = 0;
i < 3;
i++) {
193 final_dim[
i] =
max_ii(1, final_dim[
i] / 2);
197 if (tex ==
nullptr) {
198 printf(
"Error: Could not create 3D texture.\n");
206 printf(
"Error: Could not allocate 3D texture and not attempting to rescale non-float data.\n");
212 float *rescaled_data = rescale_3d(dim, final_dim, channels,
static_cast<const float *
>(
data));
218 printf(
"Error: Could not allocate rescaled 3d texture!\n");
228 void *field =
nullptr;
232 if (single_precision) {
308 if (field ==
nullptr) {
312 GPUTexture *tex = create_volume_texture(fds->
res, texture_format, data_format, field);
313 swizzle_texture_channel_single(tex);
319 int *dim = (highres) ? fds->
res_noise : fds->res;
329 if (
data ==
nullptr) {
334 swizzle_texture_channel_single(tex);
348 int *dim = (highres) ? fds->
res_noise : fds->res;
351 if (
data ==
nullptr) {
371 float *source =
nullptr;
374 int *dim = (highres) ? fds->
res_noise : fds->res;
388 swizzle_texture_channel_single(tex);
393 float **r_velocity_x,
394 float **r_velocity_y,
395 float **r_velocity_z)
416 return *r_velocity_x && *r_velocity_y && *r_velocity_z;
436 fds->
tex_field = create_field_texture(fds,
false);
447 fds->
tex_coba = create_transfer_function(TFUNC_COLOR_RAMP, fds->
coba);
463 fds->
tex_density = create_density_texture(fds, highres);
467 fds->
tex_color = create_color_texture(fds, highres);
471 fds->
tex_flame = create_flame_texture(fds, highres);
475 fds->
tex_flame_coba = create_transfer_function(TFUNC_FLAME_SPECTRUM,
nullptr);
494 float *vel_x =
nullptr, *vel_y =
nullptr, *vel_z =
nullptr;
496 if (!get_smoke_velocity_field(fds, &vel_x, &vel_y, &vel_z)) {
498 get_smoke_velocity_field(fds, &vel_x, &vel_y, &vel_z);
501 if (
ELEM(
nullptr, vel_x, vel_y, vel_z)) {
532 swizzle_texture_channel_single(fds->
tex_flags);
bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
LinkData * BLI_genericNodeN(void *data)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
MINLINE int max_ii(int a, int b)
MINLINE void straight_to_premul_v4(float color[4])
MINLINE void zero_v4(float r[4])
@ FLUID_DOMAIN_FIELD_COLOR_B
@ FLUID_DOMAIN_FIELD_FLAME
@ FLUID_DOMAIN_FIELD_REACT
@ FLUID_DOMAIN_FIELD_PHI_OUT
@ FLUID_DOMAIN_FIELD_FORCE_Z
@ FLUID_DOMAIN_FIELD_PHI_OBSTACLE
@ FLUID_DOMAIN_FIELD_FLAGS
@ FLUID_DOMAIN_FIELD_VELOCITY_Z
@ FLUID_DOMAIN_FIELD_FORCE_Y
@ FLUID_DOMAIN_FIELD_PRESSURE
@ FLUID_DOMAIN_FIELD_VELOCITY_X
@ FLUID_DOMAIN_FIELD_DENSITY
@ FLUID_DOMAIN_FIELD_VELOCITY_Y
@ FLUID_DOMAIN_FIELD_PHI_IN
@ FLUID_DOMAIN_FIELD_HEAT
@ FLUID_DOMAIN_FIELD_COLOR_G
@ FLUID_DOMAIN_FIELD_FORCE_X
@ FLUID_DOMAIN_FIELD_FUEL
@ FLUID_DOMAIN_FIELD_COLOR_R
@ FLUID_DOMAIN_VECTOR_FIELD_FORCE
@ FLUID_DOMAIN_VECTOR_FIELD_VELOCITY
@ FLUID_DOMAIN_VECTOR_FIELD_GUIDE_VELOCITY
GPUTexture * GPU_texture_create_1d(const char *name, int width, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_free(GPUTexture *texture)
GPUTexture * GPU_texture_create_error(int dimension, bool array)
@ GPU_TEXTURE_USAGE_SHADER_READ
void GPU_texture_update_sub(GPUTexture *texture, eGPUDataFormat data_format, const void *pixels, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
GPUTexture * GPU_texture_create_3d(const char *name, int width, int height, int depth, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const void *data)
#define GPU_TEXTURE_FREE_SAFE(texture)
void GPU_texture_swizzle_set(GPUTexture *texture, const char swizzle[4])
void IMB_colormanagement_blackbody_temperature_to_rgb_table(float *r_table, int width, float min, float max)
Read Guarded memory(de)allocation.
BMesh const char void * data
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
void DRW_fluid_ensure_flags(FluidModifierData *fmd)
void DRW_smoke_begin_sync(DRWData *drw_data)
void DRW_smoke_ensure_coba_field(FluidModifierData *fmd)
void DRW_fluid_ensure_range_field(FluidModifierData *fmd)
void DRW_smoke_ensure(FluidModifierData *fmd, int highres)
void DRW_smoke_ensure_velocity(FluidModifierData *fmd)
void DRW_smoke_exit(DRWData *drw_data)
void * MEM_mallocN(size_t len, const char *str)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
float * manta_noise_get_density(struct MANTA *smoke)
float * manta_smoke_get_color_r(struct MANTA *smoke)
float * manta_smoke_get_shadow(struct MANTA *smoke)
float * manta_get_force_z(struct MANTA *fluid)
bool manta_noise_has_colors(struct MANTA *smoke)
float * manta_get_force_y(struct MANTA *fluid)
float * manta_get_guide_velocity_y(struct MANTA *fluid)
float * manta_smoke_get_react(struct MANTA *smoke)
float * manta_get_guide_velocity_z(struct MANTA *fluid)
float * manta_get_guide_velocity_x(struct MANTA *fluid)
void manta_noise_get_rgba(struct MANTA *smoke, float *data, int sequential)
float * manta_get_velocity_y(struct MANTA *fluid)
bool manta_noise_has_fuel(struct MANTA *smoke)
float * manta_get_force_x(struct MANTA *fluid)
float * manta_smoke_get_density(struct MANTA *smoke)
float * manta_get_phi(struct MANTA *fluid)
float * manta_get_phi_in(struct MANTA *fluid)
float * manta_get_velocity_z(struct MANTA *fluid)
bool manta_smoke_has_colors(struct MANTA *smoke)
float * manta_get_phiout_in(struct MANTA *fluid)
float * manta_get_phiobs_in(struct MANTA *fluid)
int * manta_smoke_get_flags(struct MANTA *smoke)
float * manta_get_velocity_x(struct MANTA *fluid)
bool manta_smoke_has_fuel(struct MANTA *smoke)
float * manta_get_pressure(struct MANTA *fluid)
float * manta_smoke_get_color_g(struct MANTA *smoke)
int manta_noise_get_cells(struct MANTA *smoke)
float * manta_smoke_get_heat(struct MANTA *smoke)
float * manta_smoke_get_color_b(struct MANTA *smoke)
void manta_smoke_get_rgba(struct MANTA *smoke, float *data, int sequential)
float * manta_smoke_get_fuel(struct MANTA *smoke)
float * manta_smoke_get_flame(struct MANTA *smoke)
float * manta_noise_get_flame(struct MANTA *smoke)
VecBase< int32_t, 3 > int3
struct GPUTexture * tex_density
struct GPUTexture * tex_range_field
struct GPUTexture * tex_velocity_x
struct GPUTexture * tex_color
struct GPUTexture * tex_velocity_y
struct GPUTexture * tex_field
struct GPUTexture * tex_velocity_z
struct GPUTexture * tex_shadow
struct GPUTexture * tex_flags
struct GPUTexture * tex_coba
struct GPUTexture * tex_flame
struct GPUTexture * tex_flame_coba
struct FluidDomainSettings * domain