Exemplo n.º 1
0
int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
  EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
  EEVEE_FramebufferList *fbl = vedata->fbl;
  EEVEE_StorageList *stl = vedata->stl;
  EEVEE_EffectsInfo *effects = stl->effects;

  const DRWContextState *draw_ctx = DRW_context_state_get();
  const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);

  if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) {
    const float *viewport_size = DRW_viewport_size_get();
    const int fs_size[2] = {(int)viewport_size[0], (int)viewport_size[1]};

    /* Shaders */
    if (!e_data.gtao_sh) {
      eevee_create_shader_occlusion();
    }

    common_data->ao_dist = scene_eval->eevee.gtao_distance;
    common_data->ao_factor = scene_eval->eevee.gtao_factor;
    common_data->ao_quality = 1.0f - scene_eval->eevee.gtao_quality;

    common_data->ao_settings = 1.0f; /* USE_AO */
    if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_BENT_NORMALS) {
      common_data->ao_settings += 2.0f; /* USE_BENT_NORMAL */
    }
    if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_BOUNCE) {
      common_data->ao_settings += 4.0f; /* USE_DENOISE */
    }

    common_data->ao_bounce_fac = (scene_eval->eevee.flag & SCE_EEVEE_GTAO_BOUNCE) ? 1.0f : 0.0f;

    effects->gtao_horizons = DRW_texture_pool_query_2d(
        fs_size[0], fs_size[1], GPU_RGBA8, &draw_engine_eevee_type);
    GPU_framebuffer_ensure_config(
        &fbl->gtao_fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->gtao_horizons)});

    if (G.debug_value == 6) {
      effects->gtao_horizons_debug = DRW_texture_pool_query_2d(
          fs_size[0], fs_size[1], GPU_RGBA8, &draw_engine_eevee_type);
      GPU_framebuffer_ensure_config(
          &fbl->gtao_debug_fb,
          {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->gtao_horizons_debug)});
    }
    else {
      effects->gtao_horizons_debug = NULL;
    }

    return EFFECT_GTAO | EFFECT_NORMAL_BUFFER;
  }

  /* Cleanup */
  effects->gtao_horizons = NULL;
  GPU_FRAMEBUFFER_FREE_SAFE(fbl->gtao_fb);
  common_data->ao_settings = 0.0f;

  return 0;
}
Exemplo n.º 2
0
static void deformVerts(ModifierData *UNUSED(md),
                        const ModifierEvalContext *ctx,
                        Mesh *UNUSED(derivedData),
                        float (*vertexCos)[3],
                        int numVerts)
{
  Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
  sbObjectStep(
      ctx->depsgraph, scene, ctx->object, DEG_get_ctime(ctx->depsgraph), vertexCos, numVerts);
}
Exemplo n.º 3
0
static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
  DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;

  /* dont apply dynamic paint on orco mesh stack */
  if (!(ctx->flag & MOD_APPLY_ORCO)) {
    Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
    return dynamicPaint_Modifier_do(pmd, ctx->depsgraph, scene, ctx->object, mesh);
  }
  return mesh;
}
Exemplo n.º 4
0
static void multires_reshape_propagate_prepare_from_mmd(MultiresPropagateData *data,
                                                        struct Depsgraph *depsgraph,
                                                        Object *object,
                                                        const MultiresModifierData *mmd,
                                                        const int top_level,
                                                        const bool use_render_params)
{
  /* TODO(sergey): Find mode reliable way of getting current level. */
  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
  Mesh *mesh = object->data;
  const int level = multires_get_level(scene_eval, object, mmd, use_render_params, true);
  multires_reshape_propagate_prepare(data, mesh, level, top_level);
}
Exemplo n.º 5
0
static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
{
  Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
  SceneEEVEE *eevee = &scene_eval->eevee;

  lbake->bounce_len = eevee->gi_diffuse_bounces;
  lbake->vis_res = eevee->gi_visibility_resolution;
  lbake->rt_res = eevee->gi_cubemap_resolution;

  irradiance_pool_size_get(lbake->vis_res, lbake->total_irr_samples, lbake->irr_size);

  lbake->ref_cube_res = OCTAHEDRAL_SIZE_FROM_CUBESIZE(lbake->rt_res);

  lbake->cube_prb = MEM_callocN(sizeof(LightProbe *) * lbake->cube_len, "EEVEE Cube visgroup ptr");
  lbake->grid_prb = MEM_callocN(sizeof(LightProbe *) * lbake->grid_len, "EEVEE Grid visgroup ptr");

  lbake->grid_prev = DRW_texture_create_2d_array(lbake->irr_size[0],
                                                 lbake->irr_size[1],
                                                 lbake->irr_size[2],
                                                 IRRADIANCE_FORMAT,
                                                 DRW_TEX_FILTER,
                                                 NULL);

  /* Ensure Light Cache is ready to accept new data. If not recreate one.
   * WARNING: All the following must be threadsafe. It's currently protected
   * by the DRW mutex. */
  lbake->lcache = eevee->light_cache;

  /* TODO validate irradiance and reflection cache independently... */
  if (!EEVEE_lightcache_validate(
          lbake->lcache, lbake->cube_len, lbake->ref_cube_res, lbake->grid_len, lbake->irr_size)) {
    eevee->light_cache = lbake->lcache = NULL;
  }

  if (lbake->lcache == NULL) {
    lbake->lcache = EEVEE_lightcache_create(
        lbake->grid_len, lbake->cube_len, lbake->ref_cube_res, lbake->vis_res, lbake->irr_size);
    lbake->lcache->flag = LIGHTCACHE_UPDATE_WORLD | LIGHTCACHE_UPDATE_CUBE |
                          LIGHTCACHE_UPDATE_GRID;
    lbake->lcache->vis_res = lbake->vis_res;
    lbake->own_light_cache = true;

    eevee->light_cache = lbake->lcache;
  }

  EEVEE_lightcache_load(eevee->light_cache);

  lbake->lcache->flag |= LIGHTCACHE_BAKING;
  lbake->lcache->cube_len = 1;
}
Exemplo n.º 6
0
static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
  ExplodeModifierData *emd = (ExplodeModifierData *)md;
  ParticleSystemModifierData *psmd = findPrecedingParticlesystem(ctx->object, md);

  if (psmd) {
    ParticleSystem *psys = psmd->psys;

    if (psys == NULL || psys->totpart == 0) {
      return mesh;
    }
    if (psys->part == NULL || psys->particles == NULL) {
      return mesh;
    }
    if (psmd->mesh_final == NULL) {
      return mesh;
    }

    BKE_mesh_tessface_ensure(mesh); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */

    /* 1. find faces to be exploded if needed */
    if (emd->facepa == NULL || psmd->flag & eParticleSystemFlag_Pars ||
        emd->flag & eExplodeFlag_CalcFaces ||
        MEM_allocN_len(emd->facepa) / sizeof(int) != mesh->totface) {
      if (psmd->flag & eParticleSystemFlag_Pars) {
        psmd->flag &= ~eParticleSystemFlag_Pars;
      }
      if (emd->flag & eExplodeFlag_CalcFaces) {
        emd->flag &= ~eExplodeFlag_CalcFaces;
      }
      createFacepa(emd, psmd, mesh);
    }
    /* 2. create new mesh */
    Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
    if (emd->flag & eExplodeFlag_EdgeCut) {
      int *facepa = emd->facepa;
      Mesh *split_m = cutEdges(emd, mesh);
      Mesh *explode = explodeMesh(emd, psmd, ctx, scene, split_m);

      MEM_freeN(emd->facepa);
      emd->facepa = facepa;
      BKE_id_free(NULL, split_m);
      return explode;
    }
    else {
      return explodeMesh(emd, psmd, ctx, scene, mesh);
    }
  }
  return mesh;
}
Exemplo n.º 7
0
static void vpaint_proj_dm_map_cosnos_init(struct Depsgraph *depsgraph,
                                           Scene *UNUSED(scene),
                                           Object *ob,
                                           struct VertProjHandle *vp_handle)
{
  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
  Mesh *me = ob->data;

  CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH_ORIGINDEX;
  Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks);

  memset(vp_handle->vcosnos, 0, sizeof(*vp_handle->vcosnos) * me->totvert);
  BKE_mesh_foreach_mapped_vert(
      me_eval, vpaint_proj_dm_map_cosnos_init__map_cb, vp_handle, MESH_FOREACH_USE_NORMAL);
}
Exemplo n.º 8
0
static Subdiv *multires_create_subdiv_for_reshape(struct Depsgraph *depsgraph,
                                                  /*const*/ Object *object,
                                                  const MultiresModifierData *mmd)
{
  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
  Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
  Mesh *deformed_mesh = mesh_get_eval_deform(
      depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH);
  SubdivSettings subdiv_settings;
  BKE_multires_subdiv_settings_init(&subdiv_settings, mmd);
  Subdiv *subdiv = BKE_subdiv_new_from_mesh(&subdiv_settings, deformed_mesh);
  if (!BKE_subdiv_eval_update_from_mesh(subdiv, deformed_mesh)) {
    BKE_subdiv_free(subdiv);
    return NULL;
  }
  return subdiv;
}
Exemplo n.º 9
0
void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
  EEVEE_FramebufferList *fbl = vedata->fbl;
  EEVEE_TextureList *txl = vedata->txl;
  EEVEE_StorageList *stl = vedata->stl;
  EEVEE_PassList *psl = vedata->psl;
  EEVEE_EffectsInfo *effects = stl->effects;

  const DRWContextState *draw_ctx = DRW_context_state_get();
  const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);

  if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) {
    DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
    float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};

    DRW_texture_ensure_fullscreen_2d(
        &txl->ao_accum, GPU_R32F, 0); /* Should be enough precision for many samples. */

    GPU_framebuffer_ensure_config(&fbl->ao_accum_fb,
                                  {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->ao_accum)});

    /* Clear texture. */
    GPU_framebuffer_bind(fbl->ao_accum_fb);
    GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear);

    /* Accumulation pass */
    DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE;
    psl->ao_accum_ps = DRW_pass_create("AO Accum", state);
    DRWShadingGroup *grp = DRW_shgroup_create(e_data.gtao_debug_sh, psl->ao_accum_ps);
    DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
    DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
    DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
    DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
    DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons);
    DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
    DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
  }
  else {
    /* Cleanup to release memory */
    DRW_TEXTURE_FREE_SAFE(txl->ao_accum);
    GPU_FRAMEBUFFER_FREE_SAFE(fbl->ao_accum_fb);
  }
}
Exemplo n.º 10
0
/* FIXME: Ideally we be doing this on a copy of the main depsgraph
 * (i.e. one where we don't have to worry about restoring state)
 */
static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob)
{
  LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md;
  Scene *scene = DEG_get_evaluated_scene(depsgraph);
  struct LatticeDeformData *ldata = NULL;
  bGPdata *gpd = ob->data;
  int oldframe = (int)DEG_get_ctime(depsgraph);

  if (mmd->object == NULL) {
    return;
  }

  for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
    for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
      /* apply lattice effects on this frame
       * NOTE: this assumes that we don't want lattice animation on non-keyframed frames
       */
      CFRA = gpf->framenum;
      BKE_scene_graph_update_for_newframe(depsgraph, bmain);

      /* recalculate lattice data */
      BKE_gpencil_lattice_init(ob);

      /* compute lattice effects on this frame */
      for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
        deformStroke(md, depsgraph, ob, gpl, gps);
      }
    }
  }

  /* free lingering data */
  ldata = (struct LatticeDeformData *)mmd->cache_data;
  if (ldata) {
    end_latt_deform(ldata);
    mmd->cache_data = NULL;
  }

  /* return frame state and DB to original state */
  CFRA = oldframe;
  BKE_scene_graph_update_for_newframe(depsgraph, bmain);
}
Exemplo n.º 11
0
static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob)
{
  Scene *scene = DEG_get_evaluated_scene(depsgraph);
  bGPdata *gpd = ob->data;
  int oldframe = (int)DEG_get_ctime(depsgraph);

  for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
    for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
      /* apply mirror effects on this frame */
      CFRA = gpf->framenum;
      BKE_scene_graph_update_for_newframe(depsgraph, bmain);

      /* compute mirror effects on this frame */
      generateStrokes(md, depsgraph, ob, gpl, gpf);
    }
  }

  /* return frame state and DB to original state */
  CFRA = oldframe;
  BKE_scene_graph_update_for_newframe(depsgraph, bmain);
}
Exemplo n.º 12
0
static bool multires_reshape_from_vertcos(struct Depsgraph *depsgraph,
                                          Object *object,
                                          const MultiresModifierData *mmd,
                                          const float (*deformed_verts)[3],
                                          const int num_deformed_verts,
                                          const bool use_render_params)
{
  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
  Mesh *coarse_mesh = object->data;
  MDisps *mdisps = CustomData_get_layer(&coarse_mesh->ldata, CD_MDISPS);
  /* Pick maximum between multires level and dispalcement level.
   * This is because mesh can be used by objects with multires at different
   * levels.
   *
   * TODO(sergey): At this point it should be possible to always use
   * mdisps->level. */
  const int top_level = max_ii(mmd->totlvl, mdisps->level);
  /* Make sure displacement grids are ready. */
  multires_reshape_ensure_grids(coarse_mesh, top_level);
  /* Initialize subdivision surface. */
  Subdiv *subdiv = multires_create_subdiv_for_reshape(depsgraph, object, mmd);
  if (subdiv == NULL) {
    return false;
  }
  /* Construct context. */
  MultiresReshapeFromDeformedVertsContext reshape_deformed_verts_ctx = {
      .reshape_ctx =
          {
              .subdiv = subdiv,
              .coarse_mesh = coarse_mesh,
              .mdisps = mdisps,
              .grid_paint_mask = NULL,
              .top_grid_size = BKE_subdiv_grid_size_from_level(top_level),
              .top_level = top_level,
              .face_ptex_offset = BKE_subdiv_face_ptex_offset_get(subdiv),
          },
      .deformed_verts = deformed_verts,
      .num_deformed_verts = num_deformed_verts,
  };
Exemplo n.º 13
0
static void vpaint_proj_dm_map_cosnos_update(struct Depsgraph *depsgraph,
                                             struct VertProjHandle *vp_handle,
                                             ARegion *ar,
                                             const float mval_fl[2])
{
  struct VertProjUpdate vp_update = {vp_handle, ar, mval_fl};

  Object *ob = vp_handle->ob;
  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
  Mesh *me = ob->data;

  CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH_ORIGINDEX;
  Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks);

  /* quick sanity check - we shouldn't have to run this if there are no modifiers */
  BLI_assert(BLI_listbase_is_empty(&ob->modifiers) == false);

  copy_vn_fl(vp_handle->dists_sq, me->totvert, FLT_MAX);
  BKE_mesh_foreach_mapped_vert(
      me_eval, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update, MESH_FOREACH_USE_NORMAL);
}
Exemplo n.º 14
0
static void eevee_lightbake_render_world_sample(void *ved, void *user_data)
{
  EEVEE_Data *vedata = (EEVEE_Data *)ved;
  EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
  EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
  Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
  LightCache *lcache = scene_eval->eevee.light_cache;
  float clamp = scene_eval->eevee.gi_glossy_clamp;
  float filter_quality = scene_eval->eevee.gi_filter_quality;

  /* TODO do this once for the whole bake when we have independent DRWManagers. */
  eevee_lightbake_cache_create(vedata, lbake);

  sldata->common_data.ray_type = EEVEE_RAY_GLOSSY;
  sldata->common_data.ray_depth = 1;
  DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
  EEVEE_lightbake_render_world(sldata, vedata, lbake->rt_fb);
  EEVEE_lightbake_filter_glossy(sldata,
                                vedata,
                                lbake->rt_color,
                                lbake->store_fb,
                                0,
                                1.0f,
                                lcache->mips_len,
                                filter_quality,
                                clamp);

  sldata->common_data.ray_type = EEVEE_RAY_DIFFUSE;
  sldata->common_data.ray_depth = 1;
  DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
  EEVEE_lightbake_render_world(sldata, vedata, lbake->rt_fb);
  EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake->rt_color, lbake->store_fb, 0, 1.0f);

  /* Clear the cache to avoid white values in the grid. */
  GPU_framebuffer_texture_attach(lbake->store_fb, lbake->grid_prev, 0, 0);
  GPU_framebuffer_bind(lbake->store_fb);
  /* Clear to 1.0f for visibility. */
  GPU_framebuffer_clear_color(lbake->store_fb, ((float[4]){1.0f, 1.0f, 1.0f, 1.0f}));
Exemplo n.º 15
0
void BKE_mesh_to_curve(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob)
{
  /* make new mesh data from the original copy */
  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
  Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_MESH);
  ListBase nurblist = {NULL, NULL};

  BKE_mesh_to_curve_nurblist(me_eval, &nurblist, 0);
  BKE_mesh_to_curve_nurblist(me_eval, &nurblist, 1);

  if (nurblist.first) {
    Curve *cu = BKE_curve_add(bmain, ob->id.name + 2, OB_CURVE);
    cu->flag |= CU_3D;

    cu->nurb = nurblist;

    id_us_min(&((Mesh *)ob->data)->id);
    ob->data = cu;
    ob->type = OB_CURVE;

    BKE_object_free_derived_caches(ob);
  }
}
Exemplo n.º 16
0
static void warpModifier_do(WarpModifierData *wmd,
                            const ModifierEvalContext *ctx,
                            Mesh *mesh,
                            float (*vertexCos)[3],
                            int numVerts)
{
  Object *ob = ctx->object;
  float obinv[4][4];
  float mat_from[4][4];
  float mat_from_inv[4][4];
  float mat_to[4][4];
  float mat_unit[4][4];
  float mat_final[4][4];

  float tmat[4][4];

  const float falloff_radius_sq = SQUARE(wmd->falloff_radius);
  float strength = wmd->strength;
  float fac = 1.0f, weight;
  int i;
  int defgrp_index;
  MDeformVert *dvert, *dv = NULL;

  float(*tex_co)[3] = NULL;

  if (!(wmd->object_from && wmd->object_to)) {
    return;
  }

  MOD_get_vgroup(ob, mesh, wmd->defgrp_name, &dvert, &defgrp_index);
  if (dvert == NULL) {
    defgrp_index = -1;
  }

  if (wmd->curfalloff == NULL) { /* should never happen, but bad lib linking could cause it */
    wmd->curfalloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
  }

  if (wmd->curfalloff) {
    curvemapping_initialize(wmd->curfalloff);
  }

  invert_m4_m4(obinv, ob->obmat);

  mul_m4_m4m4(mat_from, obinv, wmd->object_from->obmat);
  mul_m4_m4m4(mat_to, obinv, wmd->object_to->obmat);

  invert_m4_m4(tmat, mat_from);  // swap?
  mul_m4_m4m4(mat_final, tmat, mat_to);

  invert_m4_m4(mat_from_inv, mat_from);

  unit_m4(mat_unit);

  if (strength < 0.0f) {
    float loc[3];
    strength = -strength;

    /* inverted location is not useful, just use the negative */
    copy_v3_v3(loc, mat_final[3]);
    invert_m4(mat_final);
    negate_v3_v3(mat_final[3], loc);
  }
  weight = strength;

  Tex *tex_target = wmd->texture;
  if (mesh != NULL && tex_target != NULL) {
    tex_co = MEM_malloc_arrayN(numVerts, sizeof(*tex_co), "warpModifier_do tex_co");
    MOD_get_texture_coords((MappingInfoModifierData *)wmd, ctx, ob, mesh, vertexCos, tex_co);

    MOD_init_texture((MappingInfoModifierData *)wmd, ctx);
  }

  for (i = 0; i < numVerts; i++) {
    float *co = vertexCos[i];

    if (wmd->falloff_type == eWarp_Falloff_None ||
        ((fac = len_squared_v3v3(co, mat_from[3])) < falloff_radius_sq &&
         (fac = (wmd->falloff_radius - sqrtf(fac)) / wmd->falloff_radius))) {
      /* skip if no vert group found */
      if (defgrp_index != -1) {
        dv = &dvert[i];
        weight = defvert_find_weight(dv, defgrp_index) * strength;
        if (weight <= 0.0f) {
          continue;
        }
      }

      /* closely match PROP_SMOOTH and similar */
      switch (wmd->falloff_type) {
        case eWarp_Falloff_None:
          fac = 1.0f;
          break;
        case eWarp_Falloff_Curve:
          fac = curvemapping_evaluateF(wmd->curfalloff, 0, fac);
          break;
        case eWarp_Falloff_Sharp:
          fac = fac * fac;
          break;
        case eWarp_Falloff_Smooth:
          fac = 3.0f * fac * fac - 2.0f * fac * fac * fac;
          break;
        case eWarp_Falloff_Root:
          fac = sqrtf(fac);
          break;
        case eWarp_Falloff_Linear:
          /* pass */
          break;
        case eWarp_Falloff_Const:
          fac = 1.0f;
          break;
        case eWarp_Falloff_Sphere:
          fac = sqrtf(2 * fac - fac * fac);
          break;
        case eWarp_Falloff_InvSquare:
          fac = fac * (2.0f - fac);
          break;
      }

      fac *= weight;

      if (tex_co) {
        struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
        TexResult texres;
        texres.nor = NULL;
        BKE_texture_get_value(scene, tex_target, tex_co[i], &texres, false);
        fac *= texres.tin;
      }

      if (fac != 0.0f) {
        /* into the 'from' objects space */
        mul_m4_v3(mat_from_inv, co);

        if (fac == 1.0f) {
          mul_m4_v3(mat_final, co);
        }
        else {
          if (wmd->flag & MOD_WARP_VOLUME_PRESERVE) {
            /* interpolate the matrix for nicer locations */
            blend_m4_m4m4(tmat, mat_unit, mat_final, fac);
            mul_m4_v3(tmat, co);
          }
          else {
            float tvec[3];
            mul_v3_m4v3(tvec, mat_final, co);
            interp_v3_v3v3(co, co, tvec, fac);
          }
        }

        /* out of the 'from' objects space */
        mul_m4_v3(mat_from, co);
      }
    }
  }

  if (tex_co) {
    MEM_freeN(tex_co);
  }
}
Exemplo n.º 17
0
static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
  BLI_assert(mesh != NULL);

  WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;

  MDeformVert *dvert = NULL;
  MDeformWeight **dw1, **tdw1, **dw2, **tdw2;
  float *org_w;
  float *new_w;
  int *tidx, *indices = NULL;
  int numIdx = 0;
  int i;
  /* Flags. */
#if 0
  const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0;
#endif

  /* Get number of verts. */
  const int numVerts = mesh->totvert;

  /* Check if we can just return the original mesh.
   * Must have verts and therefore verts assigned to vgroups to do anything useful!
   */
  if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) {
    return mesh;
  }

  /* Get vgroup idx from its name. */
  const int defgrp_index = defgroup_name_index(ctx->object, wmd->defgrp_name_a);
  if (defgrp_index == -1) {
    return mesh;
  }
  /* Get second vgroup idx from its name, if given. */
  int defgrp_index_other = -1;
  if (wmd->defgrp_name_b[0] != '\0') {
    defgrp_index_other = defgroup_name_index(ctx->object, wmd->defgrp_name_b);
    if (defgrp_index_other == -1) {
      return mesh;
    }
  }

  const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT);
  /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
  if (!has_mdef) {
    /* If not affecting all vertices, just return. */
    if (wmd->mix_set != MOD_WVG_SET_ALL) {
      return mesh;
    }
  }

  if (has_mdef) {
    dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts);
  }
  else {
    /* Add a valid data layer! */
    dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts);
  }
  /* Ultimate security check. */
  if (!dvert) {
    return mesh;
  }
  mesh->dvert = dvert;

  /* Find out which vertices to work on. */
  tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGMix Modifier, tidx");
  tdw1 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw1");
  tdw2 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw2");
  switch (wmd->mix_set) {
    case MOD_WVG_SET_A:
      /* All vertices in first vgroup. */
      for (i = 0; i < numVerts; i++) {
        MDeformWeight *dw = defvert_find_index(&dvert[i], defgrp_index);
        if (dw) {
          tdw1[numIdx] = dw;
          tdw2[numIdx] = (defgrp_index_other >= 0) ?
                             defvert_find_index(&dvert[i], defgrp_index_other) :
                             NULL;
          tidx[numIdx++] = i;
        }
      }
      break;
    case MOD_WVG_SET_B:
      /* All vertices in second vgroup. */
      for (i = 0; i < numVerts; i++) {
        MDeformWeight *dw = (defgrp_index_other >= 0) ?
                                defvert_find_index(&dvert[i], defgrp_index_other) :
                                NULL;
        if (dw) {
          tdw1[numIdx] = defvert_find_index(&dvert[i], defgrp_index);
          tdw2[numIdx] = dw;
          tidx[numIdx++] = i;
        }
      }
      break;
    case MOD_WVG_SET_OR:
      /* All vertices in one vgroup or the other. */
      for (i = 0; i < numVerts; i++) {
        MDeformWeight *adw = defvert_find_index(&dvert[i], defgrp_index);
        MDeformWeight *bdw = (defgrp_index_other >= 0) ?
                                 defvert_find_index(&dvert[i], defgrp_index_other) :
                                 NULL;
        if (adw || bdw) {
          tdw1[numIdx] = adw;
          tdw2[numIdx] = bdw;
          tidx[numIdx++] = i;
        }
      }
      break;
    case MOD_WVG_SET_AND:
      /* All vertices in both vgroups. */
      for (i = 0; i < numVerts; i++) {
        MDeformWeight *adw = defvert_find_index(&dvert[i], defgrp_index);
        MDeformWeight *bdw = (defgrp_index_other >= 0) ?
                                 defvert_find_index(&dvert[i], defgrp_index_other) :
                                 NULL;
        if (adw && bdw) {
          tdw1[numIdx] = adw;
          tdw2[numIdx] = bdw;
          tidx[numIdx++] = i;
        }
      }
      break;
    case MOD_WVG_SET_ALL:
    default:
      /* Use all vertices. */
      for (i = 0; i < numVerts; i++) {
        tdw1[i] = defvert_find_index(&dvert[i], defgrp_index);
        tdw2[i] = (defgrp_index_other >= 0) ? defvert_find_index(&dvert[i], defgrp_index_other) :
                                              NULL;
      }
      numIdx = -1;
      break;
  }
  if (numIdx == 0) {
    /* Use no vertices! Hence, return org data. */
    MEM_freeN(tdw1);
    MEM_freeN(tdw2);
    MEM_freeN(tidx);
    return mesh;
  }
  if (numIdx != -1) {
    indices = MEM_malloc_arrayN(numIdx, sizeof(int), "WeightVGMix Modifier, indices");
    memcpy(indices, tidx, sizeof(int) * numIdx);
    dw1 = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw1");
    memcpy(dw1, tdw1, sizeof(MDeformWeight *) * numIdx);
    MEM_freeN(tdw1);
    dw2 = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw2");
    memcpy(dw2, tdw2, sizeof(MDeformWeight *) * numIdx);
    MEM_freeN(tdw2);
  }
  else {
    /* Use all vertices. */
    numIdx = numVerts;
    /* Just copy MDeformWeight pointers arrays, they will be freed at the end. */
    dw1 = tdw1;
    dw2 = tdw2;
  }
  MEM_freeN(tidx);

  org_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGMix Modifier, org_w");
  new_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGMix Modifier, new_w");

  /* Mix weights. */
  for (i = 0; i < numIdx; i++) {
    float weight2;
    org_w[i] = dw1[i] ? dw1[i]->weight : wmd->default_weight_a;
    weight2 = dw2[i] ? dw2[i]->weight : wmd->default_weight_b;

    new_w[i] = mix_weight(org_w[i], weight2, wmd->mix_mode);
  }

  /* Do masking. */
  struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
  weightvg_do_mask(ctx,
                   numIdx,
                   indices,
                   org_w,
                   new_w,
                   ctx->object,
                   mesh,
                   wmd->mask_constant,
                   wmd->mask_defgrp_name,
                   scene,
                   wmd->mask_texture,
                   wmd->mask_tex_use_channel,
                   wmd->mask_tex_mapping,
                   wmd->mask_tex_map_obj,
                   wmd->mask_tex_uvlayer_name);

  /* Update (add to) vgroup.
   * XXX Depending on the MOD_WVG_SET_xxx option chosen, we might have to add vertices to vgroup.
   */
  weightvg_update_vg(
      dvert, defgrp_index, dw1, numIdx, indices, org_w, true, -FLT_MAX, false, 0.0f);

  /* If weight preview enabled... */
#if 0 /* XXX Currently done in mod stack :/ */
  if (do_prev)
    DM_update_weight_mcol(ob, dm, 0, org_w, numIdx, indices);
#endif

  /* Freeing stuff. */
  MEM_freeN(org_w);
  MEM_freeN(new_w);
  MEM_freeN(dw1);
  MEM_freeN(dw2);
  MEM_SAFE_FREE(indices);

  /* Return the vgroup-modified mesh. */
  return mesh;
}
Exemplo n.º 18
0
/* Cache as in draw cache not light cache. */
static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lbake)
{
  EEVEE_TextureList *txl = vedata->txl;
  EEVEE_StorageList *stl = vedata->stl;
  EEVEE_FramebufferList *fbl = vedata->fbl;
  EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
  Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
  lbake->sldata = sldata;

  /* Disable all effects BUT high bitdepth shadows. */
  scene_eval->eevee.flag &= SCE_EEVEE_SHADOW_HIGH_BITDEPTH;
  scene_eval->eevee.taa_samples = 1;
  scene_eval->eevee.gi_irradiance_smoothing = 0.0f;

  stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
  stl->g_data->background_alpha = 1.0f;

  /* XXX TODO remove this. This is in order to make the init functions work. */
  DRWMatrixState dummy_mats = {{{{{0}}}}};
  DRW_viewport_matrix_override_set_all(&dummy_mats);

  if (sldata->common_ubo == NULL) {
    sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data),
                                                  &sldata->common_data);
  }
  if (sldata->clip_ubo == NULL) {
    sldata->clip_ubo = DRW_uniformbuffer_create(sizeof(sldata->clip_data), &sldata->clip_data);
  }

  /* HACK: set txl->color but unset it before Draw Manager frees it. */
  txl->color = lbake->rt_color;
  int viewport_size[2] = {
      GPU_texture_width(txl->color),
      GPU_texture_height(txl->color),
  };
  DRW_render_viewport_size_set(viewport_size);

  EEVEE_effects_init(sldata, vedata, NULL, true);
  EEVEE_materials_init(sldata, stl, fbl);
  EEVEE_lights_init(sldata);
  EEVEE_lightprobes_init(sldata, vedata);

  EEVEE_effects_cache_init(sldata, vedata);
  EEVEE_materials_cache_init(sldata, vedata);
  EEVEE_lights_cache_init(sldata, vedata);
  EEVEE_lightprobes_cache_init(sldata, vedata);

  EEVEE_lightbake_cache_init(sldata, vedata, lbake->rt_color, lbake->rt_depth);

  if (lbake->probe) {
    EEVEE_LightProbesInfo *pinfo = sldata->probes;
    LightProbe *prb = *lbake->probe;
    pinfo->vis_data.collection = prb->visibility_grp;
    pinfo->vis_data.invert = prb->flag & LIGHTPROBE_FLAG_INVERT_GROUP;
    pinfo->vis_data.cached = false;
  }
  DRW_render_object_iter(vedata, NULL, lbake->depsgraph, EEVEE_render_cache);

  EEVEE_materials_cache_finish(vedata);
  EEVEE_lights_cache_finish(sldata, vedata);
  EEVEE_lightprobes_cache_finish(sldata, vedata);

  txl->color = NULL;

  DRW_render_instance_buffer_finish();
  DRW_hair_update();
}
Exemplo n.º 19
0
int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
  EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
  EEVEE_StorageList *stl = vedata->stl;
  EEVEE_FramebufferList *fbl = vedata->fbl;
  EEVEE_TextureList *txl = vedata->txl;
  EEVEE_EffectsInfo *effects = stl->effects;
  const float *viewport_size = DRW_viewport_size_get();

  const DRWContextState *draw_ctx = DRW_context_state_get();
  const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);

  /* Compute pixel size, (shared with contact shadows) */
  copy_v2_v2(common_data->ssr_pixelsize, viewport_size);
  invert_v2(common_data->ssr_pixelsize);

  if (scene_eval->eevee.flag & SCE_EEVEE_SSR_ENABLED) {
    const bool use_refraction = (scene_eval->eevee.flag & SCE_EEVEE_SSR_REFRACTION) != 0;

    if (use_refraction) {
      /* TODO: Opti: Could be shared. */
      DRW_texture_ensure_fullscreen_2d(
          &txl->refract_color, GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP);

      GPU_framebuffer_ensure_config(
          &fbl->refract_fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->refract_color)});
    }

    const bool is_persp = DRW_view_is_persp_get(NULL);
    if (effects->ssr_was_persp != is_persp) {
      effects->ssr_was_persp = is_persp;
      DRW_viewport_request_redraw();
      EEVEE_temporal_sampling_reset(vedata);
      stl->g_data->valid_double_buffer = false;
    }

    effects->reflection_trace_full = (scene_eval->eevee.flag & SCE_EEVEE_SSR_HALF_RESOLUTION) == 0;
    common_data->ssr_thickness = scene_eval->eevee.ssr_thickness;
    common_data->ssr_border_fac = scene_eval->eevee.ssr_border_fade;
    common_data->ssr_firefly_fac = scene_eval->eevee.ssr_firefly_fac;
    common_data->ssr_max_roughness = scene_eval->eevee.ssr_max_roughness;
    common_data->ssr_quality = 1.0f - 0.95f * scene_eval->eevee.ssr_quality;
    common_data->ssr_brdf_bias = 0.1f + common_data->ssr_quality * 0.6f; /* Range [0.1, 0.7]. */

    if (common_data->ssr_firefly_fac < 1e-8f) {
      common_data->ssr_firefly_fac = FLT_MAX;
    }

    const int divisor = (effects->reflection_trace_full) ? 1 : 2;
    int tracing_res[2] = {(int)viewport_size[0] / divisor, (int)viewport_size[1] / divisor};
    int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]};
    const bool high_qual_input = true; /* TODO dither low quality input */
    const eGPUTextureFormat format = (high_qual_input) ? GPU_RGBA16F : GPU_RGBA8;

    /* MRT for the shading pass in order to output needed data for the SSR pass. */
    effects->ssr_specrough_input = DRW_texture_pool_query_2d(
        size_fs[0], size_fs[1], format, &draw_engine_eevee_type);

    GPU_framebuffer_texture_attach(fbl->main_fb, effects->ssr_specrough_input, 2, 0);

    /* Raytracing output */
    effects->ssr_hit_output = DRW_texture_pool_query_2d(
        tracing_res[0], tracing_res[1], GPU_RG16I, &draw_engine_eevee_type);
    effects->ssr_pdf_output = DRW_texture_pool_query_2d(
        tracing_res[0], tracing_res[1], GPU_R16F, &draw_engine_eevee_type);

    GPU_framebuffer_ensure_config(&fbl->screen_tracing_fb,
                                  {GPU_ATTACHMENT_NONE,
                                   GPU_ATTACHMENT_TEXTURE(effects->ssr_hit_output),
                                   GPU_ATTACHMENT_TEXTURE(effects->ssr_pdf_output)});

    /* Enable double buffering to be able to read previous frame color */
    return EFFECT_SSR | EFFECT_NORMAL_BUFFER | EFFECT_DOUBLE_BUFFER |
           ((use_refraction) ? EFFECT_REFRACT : 0);
  }

  /* Cleanup to release memory */
  GPU_FRAMEBUFFER_FREE_SAFE(fbl->screen_tracing_fb);
  effects->ssr_specrough_input = NULL;
  effects->ssr_hit_output = NULL;
  effects->ssr_pdf_output = NULL;

  return 0;
}