static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(quad), int x, int y, float UNUSED(u), float UNUSED(v), float *tvn, float *ttang) { BakeShade *bs = handle; ShadeSample *ssamp = &bs->ssamp; ShadeResult shr; VlakRen *vlr = shi->vlr; shade_input_init_material(shi); if (bs->type == RE_BAKE_AO) { ambient_occlusion(shi); if (R.r.bake_flag & R_BAKE_NORMALIZE) { copy_v3_v3(shr.combined, shi->ao); } else { zero_v3(shr.combined); environment_lighting_apply(shi, &shr); } } else { if (bs->type == RE_BAKE_SHADOW) /* Why do shadows set the color anyhow?, ignore material color for baking */ shi->r = shi->g = shi->b = 1.0f; shade_input_set_shade_texco(shi); /* only do AO for a full bake (and obviously AO bakes) * AO for light bakes is a leftover and might not be needed */ if (ELEM3(bs->type, RE_BAKE_ALL, RE_BAKE_AO, RE_BAKE_LIGHT)) shade_samples_do_AO(ssamp); if (shi->mat->nodetree && shi->mat->use_nodes) { ntreeShaderExecTree(shi->mat->nodetree, shi, &shr); shi->mat = vlr->mat; /* shi->mat is being set in nodetree */ } else shade_material_loop(shi, &shr); if (bs->type == RE_BAKE_NORMALS) { float nor[3]; copy_v3_v3(nor, shi->vn); if (R.r.bake_normal_space == R_BAKE_SPACE_CAMERA) { /* pass */ } else if (R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) { float mat[3][3], imat[3][3]; /* bitangent */ if (tvn && ttang) { copy_v3_v3(mat[0], ttang); cross_v3_v3v3(mat[1], tvn, ttang); mul_v3_fl(mat[1], ttang[3]); copy_v3_v3(mat[2], tvn); } else { copy_v3_v3(mat[0], shi->nmaptang); cross_v3_v3v3(mat[1], shi->nmapnorm, shi->nmaptang); mul_v3_fl(mat[1], shi->nmaptang[3]); copy_v3_v3(mat[2], shi->nmapnorm); } invert_m3_m3(imat, mat); mul_m3_v3(imat, nor); } else if (R.r.bake_normal_space == R_BAKE_SPACE_OBJECT) mul_mat3_m4_v3(ob->imat_ren, nor); /* ob->imat_ren includes viewinv! */ else if (R.r.bake_normal_space == R_BAKE_SPACE_WORLD) mul_mat3_m4_v3(R.viewinv, nor); normalize_v3(nor); /* in case object has scaling */ /* The invert of the red channel is to make * the normal map compliant with the outside world. * It needs to be done because in Blender * the normal used in the renderer points inward. It is generated * this way in calc_vertexnormals(). Should this ever change * this negate must be removed. */ shr.combined[0] = (-nor[0]) / 2.0f + 0.5f; shr.combined[1] = nor[1] / 2.0f + 0.5f; shr.combined[2] = nor[2] / 2.0f + 0.5f; } else if (bs->type == RE_BAKE_TEXTURE) { copy_v3_v3(shr.combined, &shi->r); shr.alpha = shi->alpha; } else if (bs->type == RE_BAKE_SHADOW) { copy_v3_v3(shr.combined, shr.shad); shr.alpha = shi->alpha; } else if (bs->type == RE_BAKE_SPEC_COLOR) { copy_v3_v3(shr.combined, &shi->specr); shr.alpha = 1.0f; } else if (bs->type == RE_BAKE_SPEC_INTENSITY) { copy_v3_fl(shr.combined, shi->spec); shr.alpha = 1.0f; } else if (bs->type == RE_BAKE_MIRROR_COLOR) { copy_v3_v3(shr.combined, &shi->mirr); shr.alpha = 1.0f; } else if (bs->type == RE_BAKE_MIRROR_INTENSITY) { copy_v3_fl(shr.combined, shi->ray_mirror); shr.alpha = 1.0f; } else if (bs->type == RE_BAKE_ALPHA) { copy_v3_fl(shr.combined, shi->alpha); shr.alpha = 1.0f; } else if (bs->type == RE_BAKE_EMIT) { copy_v3_fl(shr.combined, shi->emit); shr.alpha = 1.0f; } else if (bs->type == RE_BAKE_VERTEX_COLORS) { copy_v3_v3(shr.combined, shi->vcol); shr.alpha = shi->vcol[3]; } } if (bs->rect_float && !bs->vcol) { float *col = bs->rect_float + 4 * (bs->rectx * y + x); copy_v3_v3(col, shr.combined); if (bs->type == RE_BAKE_ALL || bs->type == RE_BAKE_TEXTURE || bs->type == RE_BAKE_VERTEX_COLORS) { col[3] = shr.alpha; } else { col[3] = 1.0; } } else { /* Target is char (LDR). */ unsigned char col[4]; if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) { float rgb[3]; copy_v3_v3(rgb, shr.combined); if (R.scene_color_manage) { /* Vertex colors have no way to specify color space, so they * default to sRGB. */ if (!bs->vcol) IMB_colormanagement_scene_linear_to_colorspace_v3(rgb, bs->rect_colorspace); else linearrgb_to_srgb_v3_v3(rgb, rgb); } rgb_float_to_uchar(col, rgb); } else { rgb_float_to_uchar(col, shr.combined); } if (ELEM3(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE, RE_BAKE_VERTEX_COLORS)) { col[3] = FTOCHAR(shr.alpha); } else { col[3] = 255; } if (bs->vcol) { /* Vertex color baking. Vcol has no useful alpha channel (it exists * but is used only for vertex painting). */ bs->vcol->r = col[0]; bs->vcol->g = col[1]; bs->vcol->b = col[2]; } else { unsigned char *imcol = (unsigned char *)(bs->rect + bs->rectx * y + x); copy_v4_v4_char((char *)imcol, (char *)col); } } if (bs->rect_mask) { bs->rect_mask[bs->rectx * y + x] = FILTER_MASK_USED; } if (bs->do_update) { *bs->do_update = true; } }
static void occ_shade(ShadeSample *ssamp, ObjectInstanceRen *obi, VlakRen *vlr, float *rad) { ShadeInput *shi = ssamp->shi; ShadeResult *shr = ssamp->shr; float l, u, v, *v1, *v2, *v3; /* init */ if (vlr->v4) { shi->u = u = 0.5f; shi->v = v = 0.5f; } else { shi->u = u = 1.0f / 3.0f; shi->v = v = 1.0f / 3.0f; } /* setup render coordinates */ v1 = vlr->v1->co; v2 = vlr->v2->co; v3 = vlr->v3->co; /* renderco */ l = 1.0f - u - v; shi->co[0] = l * v3[0] + u * v1[0] + v * v2[0]; shi->co[1] = l * v3[1] + u * v1[1] + v * v2[1]; shi->co[2] = l * v3[2] + u * v1[2] + v * v2[2]; shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2); /* set up view vector */ copy_v3_v3(shi->view, shi->co); normalize_v3(shi->view); /* cache for shadow */ shi->samplenr++; shi->xs = 0; /* TODO */ shi->ys = 0; shade_input_set_normals(shi); /* no normal flip */ if (shi->flippednor) shade_input_flip_normals(shi); madd_v3_v3fl(shi->co, shi->facenor, -0.0001f); /* ugly.. */ /* not a pretty solution, but fixes common cases */ if (shi->obr->ob && shi->obr->ob->transflag & OB_NEG_SCALE) { negate_v3(shi->vn); negate_v3(shi->vno); negate_v3(shi->nmapnorm); } /* init material vars */ shade_input_init_material(shi); /* render */ shade_input_set_shade_texco(shi); if (shi->mat->nodetree && shi->mat->use_nodes) { ntreeShaderExecTree(shi->mat->nodetree, shi, shr); shi->mat = vlr->mat; /* shi->mat is being set in nodetree */ } else { shade_material_loop(shi, shr); } copy_v3_v3(rad, shr->combined); }