Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/intern/gpu_material.c
| Context not available. | |||||
| float horicol[3]; | float horicol[3]; | ||||
| float ambcol[4]; | float ambcol[4]; | ||||
| float zencol[3]; | float zencol[3]; | ||||
| float logfac; | |||||
| float linfac; | |||||
| } GPUWorld; | } GPUWorld; | ||||
| struct GPUMaterial { | struct GPUMaterial { | ||||
| Context not available. | |||||
| int partvel; | int partvel; | ||||
| int partangvel; | int partangvel; | ||||
| int ininstposloc; | |||||
| int ininstmatloc; | |||||
| int ininstcolloc; | |||||
| bool use_instancing; | |||||
| ListBase lamps; | ListBase lamps; | ||||
| bool bound; | bool bound; | ||||
| bool is_opensubdiv; | bool is_opensubdiv; | ||||
| float har; | |||||
| }; | }; | ||||
| struct GPULamp { | struct GPULamp { | ||||
| Context not available. | |||||
| &material->attribs, &material->builtins, material->type, | &material->attribs, &material->builtins, material->type, | ||||
| passname, | passname, | ||||
| material->is_opensubdiv, | material->is_opensubdiv, | ||||
| material->use_instancing, | |||||
| GPU_material_use_new_shading_nodes(material)); | GPU_material_use_new_shading_nodes(material)); | ||||
| if (!material->pass) | if (!material->pass) | ||||
| Context not available. | |||||
| material->partvel = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_VELOCITY)); | material->partvel = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_VELOCITY)); | ||||
| if (material->builtins & GPU_PARTICLE_ANG_VELOCITY) | if (material->builtins & GPU_PARTICLE_ANG_VELOCITY) | ||||
| material->partangvel = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_ANG_VELOCITY)); | material->partangvel = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_ANG_VELOCITY)); | ||||
| if (material->use_instancing) { | |||||
| material->ininstposloc = GPU_shader_get_attribute(shader, GPU_builtin_name(GPU_INSTANCING_POSITION_ATTRIB)); | |||||
| material->ininstmatloc = GPU_shader_get_attribute(shader, GPU_builtin_name(GPU_INSTANCING_MATRIX_ATTRIB)); | |||||
| material->ininstcolloc = GPU_shader_get_attribute(shader, GPU_builtin_name(GPU_INSTANCING_COLOR_ATTRIB)); | |||||
| } | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| else { | else { | ||||
| Context not available. | |||||
| return true; | return true; | ||||
| } | } | ||||
| void GPU_material_bind_instancing_attrib(GPUMaterial *material, void *matrixoffset, void *positionoffset, void *coloroffset, unsigned int stride) | |||||
| { | |||||
| // Matrix | |||||
| if (material->ininstmatloc != -1) { | |||||
| glEnableVertexAttribArrayARB(material->ininstmatloc); | |||||
| glEnableVertexAttribArrayARB(material->ininstmatloc + 1); | |||||
| glEnableVertexAttribArrayARB(material->ininstmatloc + 2); | |||||
| glVertexAttribPointerARB(material->ininstmatloc, 3, GL_FLOAT, GL_FALSE, stride, matrixoffset); | |||||
| glVertexAttribPointerARB(material->ininstmatloc + 1, 3, GL_FLOAT, GL_FALSE, stride, ((char *)matrixoffset) + 3 * sizeof(float)); | |||||
| glVertexAttribPointerARB(material->ininstmatloc + 2, 3, GL_FLOAT, GL_FALSE, stride, ((char *)matrixoffset) + 6 * sizeof(float)); | |||||
| glVertexAttribDivisorARB(material->ininstmatloc, 1); | |||||
| glVertexAttribDivisorARB(material->ininstmatloc + 1, 1); | |||||
| glVertexAttribDivisorARB(material->ininstmatloc + 2, 1); | |||||
| } | |||||
| // Position | |||||
| if (material->ininstposloc != -1) { | |||||
| glEnableVertexAttribArrayARB(material->ininstposloc); | |||||
| glVertexAttribPointerARB(material->ininstposloc, 3, GL_FLOAT, GL_FALSE, stride, positionoffset); | |||||
| glVertexAttribDivisorARB(material->ininstposloc, 1); | |||||
| } | |||||
| // Color | |||||
| if (material->ininstcolloc != -1) { | |||||
| glEnableVertexAttribArrayARB(material->ininstcolloc); | |||||
| glVertexAttribPointerARB(material->ininstcolloc, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, coloroffset); | |||||
| glVertexAttribDivisorARB(material->ininstcolloc, 1); | |||||
| } | |||||
| } | |||||
| void GPU_material_unbind_instancing_attrib(GPUMaterial *material) | |||||
| { | |||||
| // Matrix | |||||
| if (material->ininstmatloc != -1) { | |||||
| glDisableVertexAttribArrayARB(material->ininstmatloc); | |||||
| glDisableVertexAttribArrayARB(material->ininstmatloc + 1); | |||||
| glDisableVertexAttribArrayARB(material->ininstmatloc + 2); | |||||
| glVertexAttribDivisorARB(material->ininstmatloc, 0); | |||||
| glVertexAttribDivisorARB(material->ininstmatloc + 1, 0); | |||||
| glVertexAttribDivisorARB(material->ininstmatloc + 2, 0); | |||||
| } | |||||
| // Position | |||||
| if (material->ininstposloc != -1) { | |||||
| glDisableVertexAttribArrayARB(material->ininstposloc); | |||||
| glVertexAttribDivisorARB(material->ininstposloc, 0); | |||||
| } | |||||
| // Color | |||||
| if (material->ininstcolloc != -1) { | |||||
| glDisableVertexAttribArrayARB(material->ininstcolloc); | |||||
| glVertexAttribDivisorARB(material->ininstcolloc, 0); | |||||
| } | |||||
| } | |||||
| void GPU_material_bind( | void GPU_material_bind( | ||||
| GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, | GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, | ||||
| float viewmat[4][4], float viewinv[4][4], float camerafactors[4], bool scenelock) | float viewmat[4][4], float viewinv[4][4], float camerafactors[4], bool scenelock) | ||||
| Context not available. | |||||
| GPUShader *shader = GPU_pass_shader(material->pass); | GPUShader *shader = GPU_pass_shader(material->pass); | ||||
| SceneRenderLayer *srl = scenelock ? BLI_findlink(&material->scene->r.layers, material->scene->r.actlay) : NULL; | SceneRenderLayer *srl = scenelock ? BLI_findlink(&material->scene->r.layers, material->scene->r.actlay) : NULL; | ||||
| if (material->ma) { | |||||
| material->har = material->ma->har; | |||||
| } | |||||
| if (srl) | if (srl) | ||||
| viewlay &= srl->lay; | viewlay &= srl->lay; | ||||
| /* handle layer lamps */ | /* handle layer lamps */ | ||||
| if (material->type == GPU_MATERIAL_TYPE_MESH) { | if (material->type == GPU_MATERIAL_TYPE_MESH || material->use_instancing) { | ||||
| for (LinkData *nlink = material->lamps.first; nlink; nlink = nlink->next) { | for (LinkData *nlink = material->lamps.first; nlink; nlink = nlink->next) { | ||||
| GPULamp *lamp = nlink->data; | GPULamp *lamp = nlink->data; | ||||
| if (!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay)) && | if (!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay)) && | ||||
| GPU_lamp_override_visible(lamp, srl, material->ma)) | GPU_lamp_override_visible(lamp, srl, material->ma)) | ||||
| { | { | ||||
| Context not available. | |||||
| return material->type; | return material->type; | ||||
| } | } | ||||
| void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs) | void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs) | ||||
| { | { | ||||
| *attribs = material->attribs; | *attribs = material->attribs; | ||||
| Context not available. | |||||
| static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **lv, GPUNodeLink **dist) | static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **lv, GPUNodeLink **dist) | ||||
| { | { | ||||
| Material *ma = mat->ma; | |||||
| GPUNodeLink *visifac; | GPUNodeLink *visifac; | ||||
| /* from get_lamp_visibility */ | /* from get_lamp_visibility */ | ||||
| Context not available. | |||||
| break; | break; | ||||
| case LA_FALLOFF_INVLINEAR: | case LA_FALLOFF_INVLINEAR: | ||||
| GPU_link(mat, "lamp_falloff_invlinear", | GPU_link(mat, "lamp_falloff_invlinear", | ||||
| GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac); | GPU_select_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob, ma), *dist, &visifac); | ||||
| break; | break; | ||||
| case LA_FALLOFF_INVSQUARE: | case LA_FALLOFF_INVSQUARE: | ||||
| GPU_link(mat, "lamp_falloff_invsquare", | GPU_link(mat, "lamp_falloff_invsquare", | ||||
| GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac); | GPU_select_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob, ma), *dist, &visifac); | ||||
| break; | break; | ||||
| case LA_FALLOFF_SLIDERS: | case LA_FALLOFF_SLIDERS: | ||||
| GPU_link(mat, "lamp_falloff_sliders", | GPU_link(mat, "lamp_falloff_sliders", | ||||
| GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), | GPU_select_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob, ma), | ||||
| GPU_dynamic_uniform(&lamp->att1, GPU_DYNAMIC_LAMP_ATT1, lamp->ob), | GPU_select_uniform(&lamp->att1, GPU_DYNAMIC_LAMP_ATT1, lamp->ob, ma), | ||||
| GPU_dynamic_uniform(&lamp->att2, GPU_DYNAMIC_LAMP_ATT2, lamp->ob), *dist, &visifac); | GPU_select_uniform(&lamp->att2, GPU_DYNAMIC_LAMP_ATT2, lamp->ob, ma), *dist, &visifac); | ||||
| break; | break; | ||||
| case LA_FALLOFF_INVCOEFFICIENTS: | case LA_FALLOFF_INVCOEFFICIENTS: | ||||
| GPU_link(mat, "lamp_falloff_invcoefficients", | GPU_link(mat, "lamp_falloff_invcoefficients", | ||||
| GPU_dynamic_uniform(&lamp->coeff_const, GPU_DYNAMIC_LAMP_COEFFCONST, lamp->ob), | GPU_select_uniform(&lamp->coeff_const, GPU_DYNAMIC_LAMP_COEFFCONST, lamp->ob, ma), | ||||
| GPU_dynamic_uniform(&lamp->coeff_lin, GPU_DYNAMIC_LAMP_COEFFLIN, lamp->ob), | GPU_select_uniform(&lamp->coeff_lin, GPU_DYNAMIC_LAMP_COEFFLIN, lamp->ob, ma), | ||||
| GPU_dynamic_uniform(&lamp->coeff_quad, GPU_DYNAMIC_LAMP_COEFFQUAD, lamp->ob), *dist, &visifac); | GPU_select_uniform(&lamp->coeff_quad, GPU_DYNAMIC_LAMP_COEFFQUAD, lamp->ob, ma), *dist, &visifac); | ||||
| break; | break; | ||||
| case LA_FALLOFF_CURVE: | case LA_FALLOFF_CURVE: | ||||
| { | { | ||||
| Context not available. | |||||
| curvemapping_initialize(lamp->curfalloff); | curvemapping_initialize(lamp->curfalloff); | ||||
| curvemapping_table_RGBA(lamp->curfalloff, &array, &size); | curvemapping_table_RGBA(lamp->curfalloff, &array, &size); | ||||
| GPU_link(mat, "lamp_falloff_curve", | GPU_link(mat, "lamp_falloff_curve", | ||||
| GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), | GPU_select_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob, ma), | ||||
| GPU_texture(size, array), *dist, &visifac); | GPU_texture(size, array), *dist, &visifac); | ||||
| break; | break; | ||||
| Context not available. | |||||
| if (lamp->mode & LA_SPHERE) | if (lamp->mode & LA_SPHERE) | ||||
| GPU_link(mat, "lamp_visibility_sphere", | GPU_link(mat, "lamp_visibility_sphere", | ||||
| GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), | GPU_select_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob, ma), | ||||
| *dist, visifac, &visifac); | *dist, visifac, &visifac); | ||||
| if (lamp->type == LA_SPOT) { | if (lamp->type == LA_SPOT) { | ||||
| Context not available. | |||||
| GPU_link(mat, "lamp_visibility_spot_square", | GPU_link(mat, "lamp_visibility_spot_square", | ||||
| GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), | GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), | ||||
| GPU_dynamic_uniform((float *)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob), | GPU_dynamic_uniform((float *)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob), | ||||
| GPU_dynamic_uniform((float *)lamp->spotvec, GPU_DYNAMIC_LAMP_SPOTSCALE, lamp->ob), *lv, &inpr); | GPU_dynamic_uniform((float *)lamp->spotvec, GPU_DYNAMIC_LAMP_DYNSPOTSCALE, lamp->ob), *lv, &inpr); | ||||
| } | } | ||||
| else { | else { | ||||
| mat->dynproperty |= DYN_LAMP_VEC | DYN_LAMP_IMAT; | mat->dynproperty |= DYN_LAMP_VEC | DYN_LAMP_IMAT; | ||||
| GPU_link(mat, "lamp_visibility_spot_circle", | GPU_link(mat, "lamp_visibility_spot_circle", | ||||
| GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), | GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), | ||||
| GPU_dynamic_uniform((float *)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob), | GPU_dynamic_uniform((float *)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob), | ||||
| GPU_dynamic_uniform((float *)lamp->spotvec, GPU_DYNAMIC_LAMP_SPOTSCALE, lamp->ob), *lv, &inpr); | GPU_dynamic_uniform((float *)lamp->spotvec, GPU_DYNAMIC_LAMP_DYNSPOTSCALE, lamp->ob), *lv, &inpr); | ||||
| } | } | ||||
| GPU_link(mat, "lamp_visibility_spot", | GPU_link(mat, "lamp_visibility_spot", | ||||
| GPU_dynamic_uniform(&lamp->spotsi, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob), | GPU_select_uniform(&lamp->spotsi, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob, ma), | ||||
| GPU_dynamic_uniform(&lamp->spotbl, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob), | GPU_select_uniform(&lamp->spotbl, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob, ma), | ||||
| inpr, visifac, &visifac); | inpr, visifac, &visifac); | ||||
| } | } | ||||
| Context not available. | |||||
| GPU_link(mat, "shade_light_texture", | GPU_link(mat, "shade_light_texture", | ||||
| GPU_builtin(GPU_VIEW_POSITION), | GPU_builtin(GPU_VIEW_POSITION), | ||||
| GPU_image(mtex->tex->ima, &mtex->tex->iuser, false), | GPU_image(mtex->tex->ima, &mtex->tex->iuser, false), GPU_uniform(mtex->size), | ||||
| GPU_select_uniform(&mtex->lodbias, GPU_DYNAMIC_TEX_LODBIAS, NULL, mat->ma), | |||||
| GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), | GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), | ||||
| &tex_rgb); | &tex_rgb); | ||||
| texture_rgb_blend(mat, tex_rgb, *rgb, GPU_uniform(&one), GPU_uniform(&mtex->colfac), mtex->blendtype, rgb); | texture_rgb_blend(mat, tex_rgb, *rgb, GPU_uniform(&one), GPU_uniform(&mtex->colfac), mtex->blendtype, rgb); | ||||
| Context not available. | |||||
| GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias), inp, &shadfac); | GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias), inp, &shadfac); | ||||
| } | } | ||||
| else { | else { | ||||
| GPU_link(mat, "test_shadowbuf", | if (lamp->la->samp > 1 && lamp->la->soft >= 0.01f && lamp->la->shadow_filter != LA_SHADOW_FILTER_NONE) { | ||||
| GPU_builtin(GPU_VIEW_POSITION), | float samp = lamp->la->samp; | ||||
| GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), | float samplesize = lamp->la->soft / lamp->la->shadow_frustum_size; | ||||
| GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), | if (lamp->la->shadow_filter == LA_SHADOW_FILTER_PCF) { | ||||
| GPU_uniform(&lamp->bias), inp, &shadfac); | GPU_link(mat, "test_shadowbuf_pcf", | ||||
| GPU_builtin(GPU_VIEW_POSITION), | |||||
| GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), | |||||
| GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), | |||||
| GPU_uniform(&samp), GPU_uniform(&samplesize), GPU_uniform(&lamp->bias), inp, &shadfac); | |||||
| } | |||||
| else if (lamp->la->shadow_filter == LA_SHADOW_FILTER_PCF_BAIL) { | |||||
| GPU_link(mat, "test_shadowbuf_pcf_early_bail", | |||||
| GPU_builtin(GPU_VIEW_POSITION), | |||||
| GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), | |||||
| GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), | |||||
| GPU_uniform(&samp), GPU_uniform(&samplesize), GPU_uniform(&lamp->bias), inp, &shadfac); | |||||
| } | |||||
| } | |||||
| else { | |||||
| GPU_link(mat, "test_shadowbuf", | |||||
| GPU_builtin(GPU_VIEW_POSITION), | |||||
| GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), | |||||
| GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), | |||||
| GPU_uniform(&lamp->bias), inp, &shadfac); | |||||
| } | |||||
| } | } | ||||
| if (lamp->mode & LA_ONLYSHADOW) { | if (lamp->mode & LA_ONLYSHADOW) { | ||||
| Context not available. | |||||
| else | else | ||||
| GPU_link(mat, "set_value", GPU_uniform(&one), &shadfac); | GPU_link(mat, "set_value", GPU_uniform(&one), &shadfac); | ||||
| if (GPU_link_changed(shi->refl) || ma->ref != 0.0f) { | if (ma->sss_flag && lamp->type != LA_SPOT) { | ||||
| GPU_link(mat, "set_sss", GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob), visifac, | |||||
| GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), | |||||
| GPU_uniform(&ma->sss_scale), GPU_uniform((float *)&ma->sss_radius), | |||||
| shi->rgb, i, view, lv, vn, &shr->combined); | |||||
| GPU_link(mat, "shade_add", shr->combined, shr->diff, &shr->diff); | |||||
| } | |||||
| if (GPU_link_changed(shi->refl) || ma->ref != 0.0f || !(ma->constflag & MA_CONSTANT_MATERIAL)) { | |||||
| if (!(lamp->mode & LA_NO_DIFF)) { | if (!(lamp->mode & LA_NO_DIFF)) { | ||||
| GPUNodeLink *rgb; | GPUNodeLink *rgb; | ||||
| GPU_link(mat, "shade_mul_value", i, lcol, &rgb); | GPU_link(mat, "shade_mul_value", i, lcol, &rgb); | ||||
| Context not available. | |||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| else if (!(lamp->mode & LA_NO_SPEC) && !(lamp->mode & LA_ONLYSHADOW) && | else if (!(lamp->mode & LA_NO_SPEC) && !(lamp->mode & LA_ONLYSHADOW) && | ||||
| (GPU_link_changed(shi->spec) || ma->spec != 0.0f)) | (GPU_link_changed(shi->spec) || ma->spec != 0.0f || !(ma->constflag & MA_CONSTANT_MATERIAL))) | ||||
| { | { | ||||
| if (lamp->type == LA_HEMI) { | if (lamp->type == LA_HEMI) { | ||||
| GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_uniform(&ma->spec), shi->har, visifac, &t); | GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_uniform(&ma->spec), shi->har, visifac, &t); | ||||
| Context not available. | |||||
| GPUMaterial *mat = shi->gpumat; | GPUMaterial *mat = shi->gpumat; | ||||
| MTex *mtex; | MTex *mtex; | ||||
| Tex *tex; | Tex *tex; | ||||
| GPUNodeLink *texco, *tin, *trgb, *tnor, *tcol, *stencil, *tnorfac; | GPUNodeLink *texco, *tin, *trgb, *tnor, *tcol, *stencil, *tnorfac, *rotmat; | ||||
| GPUNodeLink *texco_norm, *texco_orco, *texco_object; | GPUNodeLink *texco_norm, *texco_orco, *texco_object; | ||||
| GPUNodeLink *texco_global, *texco_uv = NULL; | GPUNodeLink *texco_global, *texco_uv = NULL; | ||||
| GPUNodeLink *newnor, *orn; | GPUNodeLink *newnor, *orn; | ||||
| float one = 1.0f; | float one = 1.0f; | ||||
| GPUNodeLink *parco = NULL; | |||||
| int rgbnor, talpha; | int rgbnor, talpha; | ||||
| bool init_done = false; | bool init_done = false; | ||||
| float discard; | |||||
| int tex_nr; | |||||
| int iBumpSpacePrev = 0; /* Not necessary, quieting gcc warning. */ | int iBumpSpacePrev = 0; /* Not necessary, quieting gcc warning. */ | ||||
| GPUNodeLink *vNorg, *vNacc, *fPrevMagnitude; | GPUNodeLink *vNorg, *vNacc, *fPrevMagnitude; | ||||
| int iFirstTimeNMap = 1; | int iFirstTimeNMap = 1; | ||||
| Context not available. | |||||
| GPU_link(mat, "texco_norm", GPU_builtin(GPU_VIEW_NORMAL), &texco_norm); | GPU_link(mat, "texco_norm", GPU_builtin(GPU_VIEW_NORMAL), &texco_norm); | ||||
| GPU_link(mat, "texco_orco", GPU_attribute(CD_ORCO, ""), &texco_orco); | GPU_link(mat, "texco_orco", GPU_attribute(CD_ORCO, ""), &texco_orco); | ||||
| GPU_link(mat, "texco_object", GPU_builtin(GPU_INVERSE_VIEW_MATRIX), | GPU_link(mat, "texco_object", GPU_builtin(GPU_INVERSE_VIEW_MATRIX), | ||||
| GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), | GPU_builtin((mat->use_instancing) ? GPU_INSTANCING_INVERSE_MATRIX : GPU_INVERSE_OBJECT_MATRIX), | ||||
| GPU_builtin(GPU_VIEW_POSITION), &texco_object); | GPU_builtin(GPU_VIEW_POSITION), &texco_object); | ||||
| #if 0 | #if 0 | ||||
| GPU_link(mat, "texco_tangent", GPU_attribute(CD_TANGENT, ""), &texco_tangent); | GPU_link(mat, "texco_tangent", GPU_attribute(CD_TANGENT, ""), &texco_tangent); | ||||
| Context not available. | |||||
| GPU_builtin(GPU_VIEW_POSITION), &texco_global); | GPU_builtin(GPU_VIEW_POSITION), &texco_global); | ||||
| orn = texco_norm; | orn = texco_norm; | ||||
| /* find parallax texco (parco) */ | |||||
| for (tex_nr = 0; tex_nr < MAX_MTEX; tex_nr++) { | |||||
| /* separate tex switching */ | |||||
| if (ma->septex & (1 << tex_nr)) continue; | |||||
| if (ma->mtex[tex_nr]) { | |||||
| mtex = ma->mtex[tex_nr]; | |||||
| tex = mtex->tex; | |||||
| if (tex == NULL || !((mtex->texflag & MTEX_PARALLAX_UV) || (mtex->mapto & MAP_PARALLAX)) || mtex->texco != TEXCO_UV) { | |||||
| continue; | |||||
| } | |||||
| GPU_link(mat, "texco_uv", GPU_attribute(CD_MTFACE, mtex->uvname), &texco_uv); | |||||
| texco = texco_uv; | |||||
| if (mtex->mapto & MAP_PARALLAX) { | |||||
| GPU_link(mat, "mat_math_rot", GPU_select_uniform(&mtex->rot, GPU_DYNAMIC_TEX_UVROTATION, NULL, ma), &rotmat); | |||||
| GPU_link(mat, "mtex_mapping_transform", texco, rotmat, | |||||
| GPU_select_uniform(mtex->ofs, GPU_DYNAMIC_TEX_UVOFFSET, NULL, ma), | |||||
| GPU_select_uniform(mtex->size, GPU_DYNAMIC_TEX_UVSIZE, NULL, ma), | |||||
| &texco); | |||||
| discard = (mtex->parflag & MTEX_DISCARD_AT_EDGES) != 0 ? 1.0f : 0.0f; | |||||
| GPU_link(mat, "parallax_out", texco, | |||||
| GPU_builtin(GPU_VIEW_POSITION), GPU_attribute(CD_TANGENT, ""), | |||||
| GPU_builtin(GPU_VIEW_NORMAL), | |||||
| GPU_select_uniform(mtex->size, GPU_DYNAMIC_TEX_UVSIZE, NULL, ma), rotmat, | |||||
| GPU_image(tex->ima, &tex->iuser, false), | |||||
| GPU_uniform(&mtex->parallaxuv), | |||||
| GPU_select_uniform(&mtex->parallaxsteps, GPU_DYNAMIC_TEX_PARALLAXSTEP, NULL, ma), | |||||
| GPU_select_uniform(&mtex->parallaxbumpsc, GPU_DYNAMIC_TEX_PARALLAXBUMP, NULL, ma), | |||||
| GPU_uniform(&discard), | |||||
| &parco); | |||||
| } | |||||
| } | |||||
| } | |||||
| /* go over texture slots */ | /* go over texture slots */ | ||||
| for (int tex_nr = 0; tex_nr < MAX_MTEX; tex_nr++) { | for (tex_nr = 0; tex_nr < MAX_MTEX; tex_nr++) { | ||||
| /* separate tex switching */ | /* separate tex switching */ | ||||
| if (ma->septex & (1 << tex_nr)) continue; | if (ma->septex & (1 << tex_nr)) continue; | ||||
| if (ma->mtex[tex_nr]) { | if (ma->mtex[tex_nr]) { | ||||
| mtex = ma->mtex[tex_nr]; | mtex = ma->mtex[tex_nr]; | ||||
| bool use_parallax = (mtex->texflag & MTEX_PARALLAX_UV) || (mtex->mapto & MAP_PARALLAX); | |||||
| tex = mtex->tex; | tex = mtex->tex; | ||||
| if (tex == NULL) continue; | if (tex == NULL) continue; | ||||
| Context not available. | |||||
| } | } | ||||
| else | else | ||||
| continue; | continue; | ||||
| /*if parallax has modified uv*/ | |||||
| if (use_parallax && parco) { | |||||
| texco = parco; | |||||
| } | |||||
| /* in case of uv, this would just undo a multiplication in texco_uv */ | /* in case of uv, this would just undo a multiplication in texco_uv */ | ||||
| if (mtex->texco != TEXCO_UV) | if (mtex->texco != TEXCO_UV) | ||||
| GPU_link(mat, "mtex_2d_mapping", texco, &texco); | GPU_link(mat, "mtex_2d_mapping", texco, &texco); | ||||
| if (mtex->size[0] != 1.0f || mtex->size[1] != 1.0f || mtex->size[2] != 1.0f) | if (!use_parallax && (!(ma->constflag & MA_CONSTANT_TEXTURE_UV) || | ||||
| GPU_link(mat, "mtex_mapping_size", texco, GPU_uniform(mtex->size), &texco); | (mtex->size[0] != 1.0f || mtex->size[1] != 1.0f || mtex->size[2] != 1.0f) || | ||||
| (mtex->ofs[0] == 0.0f || mtex->ofs[1] == 0.0f) || | |||||
| float ofs[3] = { | (mtex->rot != 0.0f))) | ||||
| mtex->ofs[0] + 0.5f - 0.5f * mtex->size[0], | { | ||||
| mtex->ofs[1] + 0.5f - 0.5f * mtex->size[1], | GPU_link(mat, "mat_math_rot", GPU_select_uniform(&mtex->rot, GPU_DYNAMIC_TEX_UVROTATION, NULL, ma), &rotmat); | ||||
| 0.0f | GPU_link(mat, "mtex_mapping_transform", texco, rotmat, | ||||
| }; | GPU_select_uniform(mtex->ofs, GPU_DYNAMIC_TEX_UVOFFSET, NULL, ma), | ||||
| GPU_select_uniform(mtex->size, GPU_DYNAMIC_TEX_UVSIZE, NULL, ma), | |||||
| if (ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f) | &texco); | ||||
| GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco); | } | ||||
| talpha = 0; | talpha = 0; | ||||
| Context not available. | |||||
| ((tex->type == TEX_ENVMAP) && (mtex->texco == TEXCO_REFL)))) | ((tex->type == TEX_ENVMAP) && (mtex->texco == TEXCO_REFL)))) | ||||
| { | { | ||||
| if (tex->type == TEX_IMAGE) { | if (tex->type == TEX_IMAGE) { | ||||
| GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false), &tin, &trgb); | GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false), | ||||
| GPU_select_uniform(&mtex->lodbias, GPU_DYNAMIC_TEX_LODBIAS, NULL, ma), &tin, &trgb); | |||||
| } | } | ||||
| else { | else { | ||||
| GPU_link(mat, "mtex_cube_map_refl", | GPU_link(mat, "mtex_cube_map_refl_refr", | ||||
| GPU_cube_map(tex->ima, &tex->iuser, false), shi->view, shi->vn, | GPU_cube_map(tex->ima, &tex->iuser, false), shi->view, shi->vn, | ||||
| GPU_builtin(GPU_INVERSE_VIEW_MATRIX), | GPU_select_uniform(&mtex->lodbias, GPU_DYNAMIC_TEX_LODBIAS, NULL, ma), | ||||
| GPU_builtin(GPU_VIEW_MATRIX), &tin, &trgb); | GPU_builtin(GPU_INVERSE_VIEW_MATRIX), | ||||
| GPU_select_uniform(&mtex->ior, GPU_DYNAMIC_TEX_IOR, NULL, ma), | |||||
| GPU_select_uniform(&mtex->refrratio, GPU_DYNAMIC_TEX_REFRRATIO, NULL, ma), | |||||
| &tin, &trgb); | |||||
| } | } | ||||
| rgbnor = TEX_RGB; | rgbnor = TEX_RGB; | ||||
| Context not available. | |||||
| if ((tex->type == TEX_IMAGE) || | if ((tex->type == TEX_IMAGE) || | ||||
| ((tex->type == TEX_ENVMAP) && (mtex->texco == TEXCO_REFL))) | ((tex->type == TEX_ENVMAP) && (mtex->texco == TEXCO_REFL))) | ||||
| { | { | ||||
| if (GPU_material_do_color_management(mat)) { | if (GPU_material_do_color_management(mat) && !(ma->sss_flag)) { | ||||
| GPU_link(mat, "srgb_to_linearrgb", tcol, &tcol); | GPU_link(mat, "srgb_to_linearrgb", tcol, &tcol); | ||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||
| if (mtex->mapto & MAP_COL) { | if (mtex->mapto & MAP_COL) { | ||||
| GPUNodeLink *colfac; | GPUNodeLink *colfac; | ||||
| if (mtex->colfac == 1.0f) colfac = stencil; | if (mtex->colfac == 1.0f && (ma->constflag & MA_CONSTANT_TEXTURE)) colfac = stencil; | ||||
| else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colfac), stencil, &colfac); | else GPU_link(mat, "math_multiply", GPU_select_uniform(&mtex->colfac, GPU_DYNAMIC_TEX_COLFAC, NULL, ma), stencil, &colfac); | ||||
| texture_rgb_blend(mat, tcol, shi->rgb, tin, colfac, mtex->blendtype, &shi->rgb); | texture_rgb_blend(mat, tcol, shi->rgb, tin, colfac, mtex->blendtype, &shi->rgb); | ||||
| } | } | ||||
| Context not available. | |||||
| if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_COLSPEC)) { | if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_COLSPEC)) { | ||||
| GPUNodeLink *colspecfac; | GPUNodeLink *colspecfac; | ||||
| if (mtex->colspecfac == 1.0f) colspecfac = stencil; | if (mtex->colspecfac == 1.0f && (ma->constflag & MA_CONSTANT_TEXTURE)) colspecfac = stencil; | ||||
| else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colspecfac), stencil, &colspecfac); | else GPU_link(mat, "math_multiply", GPU_select_uniform(&mtex->colspecfac, GPU_DYNAMIC_TEX_SPECFAC, NULL, ma), stencil, &colspecfac); | ||||
| texture_rgb_blend(mat, tcol, shi->specrgb, tin, colspecfac, mtex->blendtype, &shi->specrgb); | texture_rgb_blend(mat, tcol, shi->specrgb, tin, colspecfac, mtex->blendtype, &shi->specrgb); | ||||
| } | } | ||||
| Context not available. | |||||
| if (mtex->mapto & MAP_COLMIR) { | if (mtex->mapto & MAP_COLMIR) { | ||||
| GPUNodeLink *colmirfac; | GPUNodeLink *colmirfac; | ||||
| if (mtex->mirrfac == 1.0f) colmirfac = stencil; | if (mtex->mirrfac == 1.0f && (ma->constflag & MA_CONSTANT_TEXTURE)) colmirfac = stencil; | ||||
| else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->mirrfac), stencil, &colmirfac); | else GPU_link(mat, "math_multiply", GPU_select_uniform(&mtex->mirrfac, GPU_DYNAMIC_TEX_MIRROR, NULL, ma), stencil, &colmirfac); | ||||
| /* exception for envmap only */ | /* exception for envmap only */ | ||||
| if (tex->type == TEX_ENVMAP && mtex->blendtype == MTEX_BLEND) { | if (tex->type == TEX_ENVMAP && mtex->blendtype == MTEX_BLEND) { | ||||
| Context not available. | |||||
| if (tex->imaflag & TEX_NORMALMAP) { | if (tex->imaflag & TEX_NORMALMAP) { | ||||
| /* normalmap image */ | /* normalmap image */ | ||||
| GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser, true), &tnor); | GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser, true), | ||||
| GPU_select_uniform(&mtex->lodbias, GPU_DYNAMIC_TEX_LODBIAS, NULL, ma), &tnor); | |||||
| if (mtex->norfac < 0.0f) | if (mtex->norfac < 0.0f) | ||||
| GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor); | GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor); | ||||
| Context not available. | |||||
| float norfac = min_ff(fabsf(mtex->norfac), 1.0f); | float norfac = min_ff(fabsf(mtex->norfac), 1.0f); | ||||
| if (norfac == 1.0f && !GPU_link_changed(stencil)) { | if (norfac == 1.0f && !GPU_link_changed(stencil) && (ma->constflag & MA_CONSTANT_TEXTURE)) { | ||||
| shi->vn = newnor; | shi->vn = newnor; | ||||
| } | } | ||||
| else { | else { | ||||
| tnorfac = GPU_uniform(&norfac); | tnorfac = GPU_select_uniform(&mtex->norfac, GPU_DYNAMIC_TEX_NORMAL, NULL, ma); | ||||
| if (GPU_link_changed(stencil)) | if (GPU_link_changed(stencil)) | ||||
| GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac); | GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac); | ||||
| Context not available. | |||||
| surf_pos, vNorg, | surf_pos, vNorg, | ||||
| GPU_builtin(GPU_VIEW_MATRIX), | GPU_builtin(GPU_VIEW_MATRIX), | ||||
| GPU_builtin(GPU_INVERSE_VIEW_MATRIX), | GPU_builtin(GPU_INVERSE_VIEW_MATRIX), | ||||
| GPU_builtin(GPU_OBJECT_MATRIX), | GPU_builtin((mat->use_instancing) ? GPU_INSTANCING_MATRIX : GPU_OBJECT_MATRIX), | ||||
| GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), | GPU_builtin((mat->use_instancing) ? GPU_INSTANCING_INVERSE_MATRIX : GPU_INVERSE_OBJECT_MATRIX), | ||||
| fPrevMagnitude, vNacc, | fPrevMagnitude, vNacc, | ||||
| &fPrevMagnitude, &vNacc, | &fPrevMagnitude, &vNacc, | ||||
| &vR1, &vR2, &fDet); | &vR1, &vR2, &fDet); | ||||
| Context not available. | |||||
| GPU_link(mat, "mtex_bump_deriv", | GPU_link(mat, "mtex_bump_deriv", | ||||
| texco, GPU_image(tex->ima, &tex->iuser, true), | texco, GPU_image(tex->ima, &tex->iuser, true), | ||||
| GPU_uniform(&ima_x), GPU_uniform(&ima_y), tnorfac, | GPU_uniform(&ima_x), GPU_uniform(&ima_y), tnorfac, | ||||
| GPU_select_uniform(&mtex->lodbias, GPU_DYNAMIC_TEX_LODBIAS, NULL, ma), | |||||
| &dBs, &dBt); | &dBs, &dBt); | ||||
| } | } | ||||
| else if (mtex->texflag & MTEX_3TAP_BUMP) | else if (mtex->texflag & MTEX_3TAP_BUMP) | ||||
| GPU_link(mat, "mtex_bump_tap3", | GPU_link(mat, "mtex_bump_tap3", | ||||
| texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac, | texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac, | ||||
| GPU_select_uniform(&mtex->lodbias, GPU_DYNAMIC_TEX_LODBIAS, NULL, ma), | |||||
| &dBs, &dBt); | &dBs, &dBt); | ||||
| else if (mtex->texflag & MTEX_5TAP_BUMP) | else if (mtex->texflag & MTEX_5TAP_BUMP) | ||||
| GPU_link(mat, "mtex_bump_tap5", | GPU_link(mat, "mtex_bump_tap5", | ||||
| texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac, | texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac, | ||||
| GPU_select_uniform(&mtex->lodbias, GPU_DYNAMIC_TEX_LODBIAS, NULL, ma), | |||||
| &dBs, &dBt); | &dBs, &dBt); | ||||
| else if (mtex->texflag & MTEX_BICUBIC_BUMP) { | else if (mtex->texflag & MTEX_BICUBIC_BUMP) { | ||||
| if (GPU_bicubic_bump_support()) { | if (GPU_bicubic_bump_support()) { | ||||
| GPU_link(mat, "mtex_bump_bicubic", | GPU_link(mat, "mtex_bump_bicubic", | ||||
| texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac, | texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac, | ||||
| GPU_select_uniform(&mtex->lodbias, GPU_DYNAMIC_TEX_LODBIAS, NULL, ma), | |||||
| &dBs, &dBt); | &dBs, &dBt); | ||||
| } | } | ||||
| else { | else { | ||||
| GPU_link(mat, "mtex_bump_tap5", | GPU_link(mat, "mtex_bump_tap5", | ||||
| texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac, | texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac, | ||||
| GPU_select_uniform(&mtex->lodbias, GPU_DYNAMIC_TEX_LODBIAS, NULL, ma), | |||||
| &dBs, &dBt); | &dBs, &dBt); | ||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||
| if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_REF) { | if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_REF) { | ||||
| GPUNodeLink *difffac; | GPUNodeLink *difffac; | ||||
| if (mtex->difffac == 1.0f) difffac = stencil; | if (mtex->difffac == 1.0f && (ma->constflag & MA_CONSTANT_TEXTURE)) difffac = stencil; | ||||
| else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->difffac), stencil, &difffac); | else GPU_link(mat, "math_multiply", GPU_select_uniform(&mtex->difffac, GPU_DYNAMIC_TEX_COLINTENS, NULL, ma), stencil, &difffac); | ||||
| texture_value_blend( | texture_value_blend( | ||||
| mat, GPU_uniform(&mtex->def_var), shi->refl, tin, difffac, | mat, GPU_uniform(&mtex->def_var), shi->refl, tin, difffac, | ||||
| Context not available. | |||||
| if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_SPEC) { | if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_SPEC) { | ||||
| GPUNodeLink *specfac; | GPUNodeLink *specfac; | ||||
| if (mtex->specfac == 1.0f) specfac = stencil; | if (mtex->specfac == 1.0f && (ma->constflag & MA_CONSTANT_TEXTURE)) specfac = stencil; | ||||
| else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->specfac), stencil, &specfac); | else GPU_link(mat, "math_multiply", GPU_select_uniform(&mtex->specfac, GPU_DYNAMIC_TEX_SPECINTENS, NULL, ma), stencil, &specfac); | ||||
| texture_value_blend( | texture_value_blend( | ||||
| mat, GPU_uniform(&mtex->def_var), shi->spec, tin, specfac, | mat, GPU_uniform(&mtex->def_var), shi->spec, tin, specfac, | ||||
| Context not available. | |||||
| if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_EMIT) { | if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_EMIT) { | ||||
| GPUNodeLink *emitfac; | GPUNodeLink *emitfac; | ||||
| if (mtex->emitfac == 1.0f) emitfac = stencil; | if (mtex->emitfac == 1.0f && (ma->constflag & MA_CONSTANT_TEXTURE)) emitfac = stencil; | ||||
| else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->emitfac), stencil, &emitfac); | else GPU_link(mat, "math_multiply", GPU_select_uniform(&mtex->emitfac, GPU_DYNAMIC_TEX_EMIT, NULL, ma), stencil, &emitfac); | ||||
| texture_value_blend( | texture_value_blend( | ||||
| mat, GPU_uniform(&mtex->def_var), shi->emit, tin, emitfac, | mat, GPU_uniform(&mtex->def_var), shi->emit, tin, emitfac, | ||||
| Context not available. | |||||
| if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_HAR) { | if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_HAR) { | ||||
| GPUNodeLink *hardfac; | GPUNodeLink *hardfac; | ||||
| if (mtex->hardfac == 1.0f) hardfac = stencil; | if (mtex->hardfac == 1.0f && (ma->constflag & MA_CONSTANT_TEXTURE)) hardfac = stencil; | ||||
| else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->hardfac), stencil, &hardfac); | else GPU_link(mat, "math_multiply", GPU_select_uniform(&mtex->hardfac, GPU_DYNAMIC_TEX_HARDNESS, NULL, ma), stencil, &hardfac); | ||||
| GPU_link(mat, "mtex_har_divide", shi->har, &shi->har); | GPU_link(mat, "mtex_har_divide", shi->har, &shi->har); | ||||
| texture_value_blend( | texture_value_blend( | ||||
| Context not available. | |||||
| if (mtex->mapto & MAP_ALPHA) { | if (mtex->mapto & MAP_ALPHA) { | ||||
| GPUNodeLink *alphafac; | GPUNodeLink *alphafac; | ||||
| if (mtex->alphafac == 1.0f) alphafac = stencil; | if (mtex->alphafac == 1.0f && (ma->constflag & MA_CONSTANT_TEXTURE)) alphafac = stencil; | ||||
| else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->alphafac), stencil, &alphafac); | else GPU_link(mat, "math_multiply", GPU_select_uniform(&mtex->alphafac, GPU_DYNAMIC_TEX_ALPHA, NULL, ma), stencil, &alphafac); | ||||
| texture_value_blend( | texture_value_blend( | ||||
| mat, GPU_uniform(&mtex->def_var), shi->alpha, tin, alphafac, | mat, GPU_uniform(&mtex->def_var), shi->alpha, tin, alphafac, | ||||
| Context not available. | |||||
| shi->gpumat = mat; | shi->gpumat = mat; | ||||
| shi->mat = ma; | shi->mat = ma; | ||||
| GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->r, GPU_DYNAMIC_MAT_DIFFRGB, ma), &shi->rgb); | GPU_link(mat, "set_rgb", GPU_select_uniform(&ma->r, GPU_DYNAMIC_MAT_DIFFRGB, ma, ma), &shi->rgb); | ||||
| GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->specr, GPU_DYNAMIC_MAT_SPECRGB, ma), &shi->specrgb); | GPU_link(mat, "set_rgb", GPU_select_uniform(&ma->specr, GPU_DYNAMIC_MAT_SPECRGB, ma, ma), &shi->specrgb); | ||||
| GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->mirr, GPU_DYNAMIC_MAT_MIR, ma), &shi->mir); | GPU_link(mat, "set_rgb", GPU_select_uniform(&ma->mirr, GPU_DYNAMIC_MAT_MIR, ma, ma), &shi->mir); | ||||
| GPU_link(mat, "set_rgba_zero", &shi->refcol); | GPU_link(mat, "set_rgba_zero", &shi->refcol); | ||||
| GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &shi->vn); | GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &shi->vn); | ||||
| if (mat->alpha) | if (mat->alpha) | ||||
| GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->alpha, GPU_DYNAMIC_MAT_ALPHA, ma), &shi->alpha); | GPU_link(mat, "set_value", GPU_select_uniform(&ma->alpha, GPU_DYNAMIC_MAT_ALPHA, ma, ma), &shi->alpha); | ||||
| else | else | ||||
| GPU_link(mat, "set_value", GPU_uniform(&one), &shi->alpha); | GPU_link(mat, "set_value", GPU_uniform(&one), &shi->alpha); | ||||
| GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->ref, GPU_DYNAMIC_MAT_REF, ma), &shi->refl); | GPU_link(mat, "set_value", GPU_select_uniform(&ma->ref, GPU_DYNAMIC_MAT_REF, ma, ma), &shi->refl); | ||||
| GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->spec, GPU_DYNAMIC_MAT_SPEC, ma), &shi->spec); | GPU_link(mat, "set_value", GPU_select_uniform(&ma->spec, GPU_DYNAMIC_MAT_SPEC, ma, ma), &shi->spec); | ||||
| GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->emit, GPU_DYNAMIC_MAT_EMIT, ma), &shi->emit); | GPU_link(mat, "set_value", GPU_select_uniform(&ma->emit, GPU_DYNAMIC_MAT_EMIT, ma, ma), &shi->emit); | ||||
| GPU_link(mat, "set_value", GPU_dynamic_uniform((float *)&ma->har, GPU_DYNAMIC_MAT_HARD, ma), &shi->har); | GPU_link(mat, "set_value", GPU_select_uniform(&mat->har, GPU_DYNAMIC_MAT_HARD, ma, ma), &shi->har); | ||||
| GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->amb, GPU_DYNAMIC_MAT_AMB, ma), &shi->amb); | GPU_link(mat, "set_value", GPU_select_uniform(&ma->amb, GPU_DYNAMIC_MAT_AMB, ma, ma), &shi->amb); | ||||
| GPU_link(mat, "set_value", GPU_uniform(&ma->spectra), &shi->spectra); | GPU_link(mat, "set_value", GPU_select_uniform(&ma->spectra, GPU_DYNAMIC_MAT_SPECTRA, ma, ma), &shi->spectra); | ||||
| GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &shi->view); | GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &shi->view); | ||||
| GPU_link(mat, "vcol_attribute", GPU_attribute(CD_MCOL, ""), &shi->vcol); | GPU_link(mat, "vcol_attribute", GPU_attribute(CD_MCOL, ""), &shi->vcol); | ||||
| if (GPU_material_do_color_management(mat)) | if (GPU_material_do_color_management(mat) && !(ma->sss_flag)) | ||||
| GPU_link(mat, "srgb_to_linearrgb", shi->vcol, &shi->vcol); | GPU_link(mat, "srgb_to_linearrgb", shi->vcol, &shi->vcol); | ||||
| GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref); | GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref); | ||||
| } | } | ||||
| Context not available. | |||||
| copy_v3_v3(GPUWorld.zencol, color); | copy_v3_v3(GPUWorld.zencol, color); | ||||
| } | } | ||||
| void GPU_update_exposure_range(float exp, float range) | |||||
| { | |||||
| GPUWorld.linfac = 1.0f + powf((2.0f * exp + 0.5f), -10.0f); | |||||
| GPUWorld.logfac = log((GPUWorld.linfac - 1.0f) / GPUWorld.linfac) / range; | |||||
| } | |||||
| void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr) | void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr) | ||||
| { | { | ||||
| GPUMaterial *mat = shi->gpumat; | GPUMaterial *mat = shi->gpumat; | ||||
| GPUNodeLink *emit, *ulinfac, *ulogfac, *mistfac; | GPUNodeLink *emit, *mistfac; | ||||
| Material *ma = shi->mat; | Material *ma = shi->mat; | ||||
| World *world = mat->scene->world; | World *world = mat->scene->world; | ||||
| float linfac, logfac; | |||||
| mat->dynproperty |= DYN_LAMP_CO; | |||||
| memset(shr, 0, sizeof(*shr)); | memset(shr, 0, sizeof(*shr)); | ||||
| if (ma->mode & MA_VERTEXCOLP) | if (ma->mode & MA_VERTEXCOLP) | ||||
| Context not available. | |||||
| shr->combined = shr->diff; | shr->combined = shr->diff; | ||||
| } | } | ||||
| else { | else { | ||||
| if (GPU_link_changed(shi->emit) || ma->emit != 0.0f) { | if (GPU_link_changed(shi->emit) || ma->emit != 0.0f || !(ma->constflag & MA_CONSTANT_MATERIAL)) { | ||||
| if ((ma->mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) == MA_VERTEXCOL) { | if ((ma->mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) == MA_VERTEXCOL) { | ||||
| GPU_link(mat, "shade_add", shi->emit, shi->vcol, &emit); | GPU_link(mat, "shade_add", shi->emit, shi->vcol, &emit); | ||||
| GPU_link(mat, "shade_mul", emit, shi->rgb, &shr->diff); | GPU_link(mat, "shade_mul", emit, shi->rgb, &shr->diff); | ||||
| Context not available. | |||||
| if (world) { | if (world) { | ||||
| /* exposure correction */ | /* exposure correction */ | ||||
| if (world->exp != 0.0f || world->range != 1.0f) { | GPU_link(mat, "shade_exposure_correct", shr->combined, | ||||
| linfac = 1.0f + powf((2.0f * world->exp + 0.5f), -10); | GPU_select_uniform(&GPUWorld.linfac, GPU_DYNAMIC_WORLD_LINFAC, NULL, ma), | ||||
| logfac = logf((linfac - 1.0f) / linfac) / world->range; | GPU_select_uniform(&GPUWorld.logfac, GPU_DYNAMIC_WORLD_LOGFAC, NULL, ma), | ||||
| &shr->combined); | |||||
| GPU_link(mat, "set_value", GPU_uniform(&linfac), &ulinfac); | GPU_link(mat, "shade_exposure_correct", shr->spec, | ||||
| GPU_link(mat, "set_value", GPU_uniform(&logfac), &ulogfac); | GPU_select_uniform(&GPUWorld.linfac, GPU_DYNAMIC_WORLD_LINFAC, NULL, ma), | ||||
| GPU_select_uniform(&GPUWorld.logfac, GPU_DYNAMIC_WORLD_LOGFAC, NULL, ma), | |||||
| GPU_link(mat, "shade_exposure_correct", shr->combined, | &shr->spec); | ||||
| ulinfac, ulogfac, &shr->combined); | |||||
| GPU_link(mat, "shade_exposure_correct", shr->spec, | |||||
| ulinfac, ulogfac, &shr->spec); | |||||
| } | |||||
| /* environment lighting */ | /* environment lighting */ | ||||
| if (!(mat->scene->gm.flag & GAME_GLSL_NO_ENV_LIGHTING) && | if (!(mat->scene->gm.flag & GAME_GLSL_NO_ENV_LIGHTING) && | ||||
| Context not available. | |||||
| GPU_link(mat, "math_multiply", f, GPU_uniform(&world->ao_env_energy), &f); | GPU_link(mat, "math_multiply", f, GPU_uniform(&world->ao_env_energy), &f); | ||||
| GPU_link(mat, "shade_mul_value", f, shi->rgb, &fcol); | GPU_link(mat, "shade_mul_value", f, shi->rgb, &fcol); | ||||
| GPU_link(mat, "env_apply", shr->combined, | GPU_link(mat, "env_apply", shr->combined, | ||||
| GPU_dynamic_uniform(GPUWorld.horicol, GPU_DYNAMIC_HORIZON_COLOR, NULL), | GPU_select_uniform(GPUWorld.horicol, GPU_DYNAMIC_HORIZON_COLOR, NULL, ma), | ||||
| GPU_dynamic_uniform(GPUWorld.zencol, GPU_DYNAMIC_ZENITH_COLOR, NULL), fcol, | GPU_select_uniform(GPUWorld.zencol, GPU_DYNAMIC_ZENITH_COLOR, NULL, ma), fcol, | ||||
| GPU_builtin(GPU_VIEW_MATRIX), shi->vn, &shr->combined); | GPU_builtin(GPU_VIEW_MATRIX), shi->vn, &shr->combined); | ||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||
| } | } | ||||
| /* ambient color */ | /* ambient color */ | ||||
| if (GPU_link_changed(shi->amb) || ma->amb != 0.0f) { | if (GPU_link_changed(shi->amb) || ma->amb != 0.0f || !(ma->constflag & MA_CONSTANT_MATERIAL)) { | ||||
| GPU_link(mat, "shade_maddf", shr->combined, GPU_uniform(&ma->amb), | GPU_link(mat, "shade_maddf", shr->combined, GPU_select_uniform(&ma->amb, GPU_DYNAMIC_MAT_AMB, NULL, ma), | ||||
| GPU_dynamic_uniform(GPUWorld.ambcol, GPU_DYNAMIC_AMBIENT_COLOR, NULL), | GPU_select_uniform(GPUWorld.ambcol, GPU_DYNAMIC_AMBIENT_COLOR, NULL, ma), | ||||
| &shr->combined); | &shr->combined); | ||||
| } | } | ||||
| } | } | ||||
| if (ma->mode & MA_TRANSP && (ma->mode & (MA_ZTRANSP | MA_RAYTRANSP))) { | if (ma->mode & MA_TRANSP && (ma->mode & (MA_ZTRANSP | MA_RAYTRANSP))) { | ||||
| if (GPU_link_changed(shi->spectra) || ma->spectra != 0.0f) { | if (GPU_link_changed(shi->spectra) || ma->spectra != 0.0f || !(ma->constflag & MA_CONSTANT_MATERIAL)) { | ||||
| GPU_link(mat, "alpha_spec_correction", shr->spec, shi->spectra, | GPU_link(mat, "alpha_spec_correction", shr->spec, shi->spectra, | ||||
| shi->alpha, &shr->alpha); | shi->alpha, &shr->alpha); | ||||
| } | } | ||||
| Context not available. | |||||
| if (GPU_link_changed(shi->refcol)) | if (GPU_link_changed(shi->refcol)) | ||||
| GPU_link(mat, "shade_add_mirror", shi->mir, shi->refcol, shr->combined, &shr->combined); | GPU_link(mat, "shade_add_mirror", shi->mir, shi->refcol, shr->combined, &shr->combined); | ||||
| if (GPU_link_changed(shi->spec) || ma->spec != 0.0f) | if (GPU_link_changed(shi->spec) || ma->spec != 0.0f || !(ma->constflag & MA_CONSTANT_MATERIAL)) | ||||
| GPU_link(mat, "shade_add", shr->combined, shr->spec, &shr->combined); | GPU_link(mat, "shade_add", shr->combined, shr->spec, &shr->combined); | ||||
| } | } | ||||
| if (ma->mode & MA_TRANSP && ma->mode2 & MA_DEPTH_TRANSP) { | |||||
| GPU_link(mat, "shade_alpha_depth", | |||||
| GPU_builtin(GPU_VIEW_POSITION), | |||||
| GPU_dynamic_texture_ptr(GPU_texture_global_depth_ptr(), GPU_DYNAMIC_SAMPLER_2DBUFFER, ma), | |||||
| shi->alpha, GPU_uniform(&ma->depthtranspfactor), &shr->alpha); | |||||
| } | |||||
| GPU_link(mat, "mtex_alpha_to_col", shr->combined, shr->alpha, &shr->combined); | GPU_link(mat, "mtex_alpha_to_col", shr->combined, shr->alpha, &shr->combined); | ||||
| if (ma->shade_flag & MA_OBCOLOR) | if (ma->shade_flag & MA_OBCOLOR) { | ||||
| GPU_link(mat, "shade_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined); | GPU_link(mat, "shade_obcolor", shr->combined, | ||||
| GPU_builtin((mat->use_instancing) ? GPU_INSTANCING_COLOR : GPU_OBCOLOR), &shr->combined); | |||||
| } | |||||
| if (!(ma->mode & MA_NOMIST)) { | if (!(ma->mode & MA_NOMIST)) { | ||||
| GPU_link(mat, "shade_mist_factor", GPU_builtin(GPU_VIEW_POSITION), | GPU_link(mat, "shade_mist_factor", GPU_builtin(GPU_VIEW_POSITION), | ||||
| GPU_dynamic_uniform(&GPUWorld.mistenabled, GPU_DYNAMIC_MIST_ENABLE, NULL), | GPU_select_uniform(&GPUWorld.mistenabled, GPU_DYNAMIC_MIST_ENABLE, NULL, ma), | ||||
| GPU_dynamic_uniform(&GPUWorld.miststart, GPU_DYNAMIC_MIST_START, NULL), | GPU_select_uniform(&GPUWorld.miststart, GPU_DYNAMIC_MIST_START, NULL, ma), | ||||
| GPU_dynamic_uniform(&GPUWorld.mistdistance, GPU_DYNAMIC_MIST_DISTANCE, NULL), | GPU_select_uniform(&GPUWorld.mistdistance, GPU_DYNAMIC_MIST_DISTANCE, NULL, ma), | ||||
| GPU_dynamic_uniform(&GPUWorld.mistype, GPU_DYNAMIC_MIST_TYPE, NULL), | GPU_select_uniform(&GPUWorld.mistype, GPU_DYNAMIC_MIST_TYPE, NULL, ma), | ||||
| GPU_dynamic_uniform(&GPUWorld.mistintensity, GPU_DYNAMIC_MIST_INTENSITY, NULL), &mistfac); | GPU_select_uniform(&GPUWorld.mistintensity, GPU_DYNAMIC_MIST_INTENSITY, NULL, ma), &mistfac); | ||||
| GPU_link(mat, "mix_blend", mistfac, shr->combined, | GPU_link(mat, "mix_blend", mistfac, shr->combined, | ||||
| GPU_dynamic_uniform(GPUWorld.mistcol, GPU_DYNAMIC_MIST_COLOR, NULL), &shr->combined); | GPU_select_uniform(GPUWorld.mistcol, GPU_DYNAMIC_MIST_COLOR, NULL, ma), &shr->combined); | ||||
| } | } | ||||
| if (!mat->alpha) { | if (!mat->alpha) { | ||||
| if (world && (GPU_link_changed(shr->alpha) || ma->alpha != 1.0f)) | if (world && (GPU_link_changed(shr->alpha) || ma->alpha != 1.0f)) | ||||
| GPU_link(mat, "shade_world_mix", GPU_dynamic_uniform(GPUWorld.horicol, GPU_DYNAMIC_HORIZON_COLOR, NULL), | GPU_link(mat, "shade_world_mix", GPU_select_uniform(GPUWorld.horicol, GPU_DYNAMIC_HORIZON_COLOR, NULL, ma), | ||||
| shr->combined, &shr->combined); | shr->combined, &shr->combined); | ||||
| GPU_link(mat, "shade_alpha_opaque", shr->combined, &shr->combined); | GPU_link(mat, "shade_alpha_opaque", shr->combined, &shr->combined); | ||||
| Context not available. | |||||
| if (ma->shade_flag & MA_OBCOLOR) { | if (ma->shade_flag & MA_OBCOLOR) { | ||||
| mat->obcolalpha = 1; | mat->obcolalpha = 1; | ||||
| GPU_link(mat, "shade_alpha_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined); | GPU_link(mat, "shade_alpha_obcolor", shr->combined, | ||||
| GPU_builtin((mat->use_instancing) ? GPU_INSTANCING_COLOR : GPU_OBCOLOR), &shr->combined); | |||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||
| if (ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f) | if (ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f) | ||||
| GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco); | GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco); | ||||
| if (mtex->texco == TEXCO_EQUIRECTMAP) { | if (mtex->texco == TEXCO_EQUIRECTMAP) { | ||||
| GPU_link(mat, "node_tex_environment_equirectangular", texco, GPU_image(tex->ima, &tex->iuser, false), &trgb); | GPU_link(mat, "node_tex_environment_equirectangular", texco, GPU_image(tex->ima, &tex->iuser, false), GPU_uniform(&mtex->lodbias), &trgb); | ||||
| } | } | ||||
| else if (mtex->texco == TEXCO_ANGMAP) { | else if (mtex->texco == TEXCO_ANGMAP) { | ||||
| GPU_link(mat, "node_tex_environment_mirror_ball", texco, GPU_image(tex->ima, &tex->iuser, false), &trgb); | GPU_link(mat, "node_tex_environment_mirror_ball", texco, GPU_image(tex->ima, &tex->iuser, false), GPU_uniform(&mtex->lodbias), &trgb); | ||||
| } | } | ||||
| else { | else { | ||||
| if (tex->type == TEX_ENVMAP) | if (tex->type == TEX_ENVMAP) | ||||
| GPU_link(mat, "mtex_cube_map", texco, GPU_cube_map(tex->ima, &tex->iuser, false), &tin, &trgb); | GPU_link(mat, "mtex_cube_map", texco, GPU_cube_map(tex->ima, &tex->iuser, false), GPU_uniform(&mtex->lodbias), &tin, &trgb); | ||||
| else if (tex->type == TEX_IMAGE) | else if (tex->type == TEX_IMAGE) | ||||
| GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false), &tin, &trgb); | GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false), GPU_uniform(&mtex->lodbias), &tin, &trgb); | ||||
| } | } | ||||
| rgbnor = TEX_RGB; | rgbnor = TEX_RGB; | ||||
| if (tex->type == TEX_IMAGE || tex->type == TEX_ENVMAP) | if (tex->type == TEX_IMAGE || tex->type == TEX_ENVMAP) | ||||
| Context not available. | |||||
| } | } | ||||
| GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma, bool use_opensubdiv) | GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma, bool use_opensubdiv, bool is_instancing) | ||||
| { | { | ||||
| GPUMaterial *mat; | GPUMaterial *mat; | ||||
| GPUNodeLink *outlink; | GPUNodeLink *outlink; | ||||
| LinkData *link; | LinkData *link; | ||||
| ListBase *gpumaterials; | |||||
| for (link = ma->gpumaterial.first; link; link = link->next) { | if (is_instancing) { | ||||
| gpumaterials = &ma->gpumaterialinstancing; | |||||
| } | |||||
| else { | |||||
| gpumaterials = &ma->gpumaterial; | |||||
| } | |||||
| for (link = gpumaterials->first; link; link = link->next) { | |||||
| GPUMaterial *current_material = (GPUMaterial *)link->data; | GPUMaterial *current_material = (GPUMaterial *)link->data; | ||||
| if (current_material->scene == scene && | if (current_material->scene == scene && | ||||
| current_material->is_opensubdiv == use_opensubdiv) | current_material->is_opensubdiv == use_opensubdiv) | ||||
| Context not available. | |||||
| mat = GPU_material_construct_begin(ma); | mat = GPU_material_construct_begin(ma); | ||||
| mat->scene = scene; | mat->scene = scene; | ||||
| mat->type = GPU_MATERIAL_TYPE_MESH; | mat->type = GPU_MATERIAL_TYPE_MESH; | ||||
| mat->use_instancing = is_instancing; | |||||
| mat->is_opensubdiv = use_opensubdiv; | mat->is_opensubdiv = use_opensubdiv; | ||||
| mat->har = ma->har; | |||||
| /* render pipeline option */ | /* render pipeline option */ | ||||
| bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); | bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); | ||||
| Context not available. | |||||
| GPU_material_output_link(mat, outlink); | GPU_material_output_link(mat, outlink); | ||||
| } | } | ||||
| if (GPU_material_do_color_management(mat)) | if (GPU_material_do_color_management(mat) && !(ma->sss_flag)) | ||||
| if (mat->outlink) | if (mat->outlink) | ||||
| GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink); | GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink); | ||||
| Context not available. | |||||
| link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink"); | link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink"); | ||||
| link->data = mat; | link->data = mat; | ||||
| BLI_addtail(&ma->gpumaterial, link); | BLI_addtail(gpumaterials, link); | ||||
| return mat; | return mat; | ||||
| } | } | ||||
| Context not available. | |||||
| World *wo; | World *wo; | ||||
| extern Material defmaterial; | extern Material defmaterial; | ||||
| for (ma = G.main->mat.first; ma; ma = ma->id.next) | for (ma = G.main->mat.first; ma; ma = ma->id.next) { | ||||
| GPU_material_free(&ma->gpumaterial); | GPU_material_free(&ma->gpumaterial); | ||||
| GPU_material_free(&ma->gpumaterialinstancing); | |||||
| } | |||||
| for (wo = G.main->world.first; wo; wo = wo->id.next) | for (wo = G.main->world.first; wo; wo = wo->id.next) | ||||
| GPU_material_free(&wo->gpumaterial); | GPU_material_free(&wo->gpumaterial); | ||||
| GPU_material_free(&defmaterial.gpumaterial); | GPU_material_free(&defmaterial.gpumaterial); | ||||
| GPU_material_free(&defmaterial.gpumaterialinstancing); | |||||
| for (ob = G.main->object.first; ob; ob = ob->id.next) | for (ob = G.main->object.first; ob; ob = ob->id.next) | ||||
| GPU_lamp_free(ob); | GPU_lamp_free(ob); | ||||
| Context not available. | |||||
| if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) { | if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) { | ||||
| /* Shadow depth map */ | /* Shadow depth map */ | ||||
| lamp->depthtex = GPU_texture_create_depth(lamp->size, lamp->size, NULL); | lamp->depthtex = GPU_texture_create_depth(lamp->size, lamp->size, true, NULL); | ||||
| if (!lamp->depthtex) { | if (!lamp->depthtex) { | ||||
| gpu_lamp_shadow_free(lamp); | gpu_lamp_shadow_free(lamp); | ||||
| return lamp; | return lamp; | ||||
| Context not available. | |||||
| GPU_framebuffer_texture_unbind(lamp->blurfb, lamp->blurtex); | GPU_framebuffer_texture_unbind(lamp->blurfb, lamp->blurtex); | ||||
| } | } | ||||
| else { | else { | ||||
| lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL); | lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, true, NULL); | ||||
| if (!lamp->tex) { | if (!lamp->tex) { | ||||
| gpu_lamp_shadow_free(lamp); | gpu_lamp_shadow_free(lamp); | ||||
| return lamp; | return lamp; | ||||
| Context not available. | |||||
| if (ma->gpumaterial.first) | if (ma->gpumaterial.first) | ||||
| GPU_material_free(&ma->gpumaterial); | GPU_material_free(&ma->gpumaterial); | ||||
| if (ma->gpumaterialinstancing.first) | |||||
| GPU_material_free(&ma->gpumaterialinstancing); | |||||
| } | } | ||||
| gpu_lamp_shadow_free(lamp); | gpu_lamp_shadow_free(lamp); | ||||
| Context not available. | |||||
| /* opengl */ | /* opengl */ | ||||
| glDisable(GL_SCISSOR_TEST); | glDisable(GL_SCISSOR_TEST); | ||||
| GPU_texture_bind_as_framebuffer(lamp->tex); | GPU_texture_bind_as_framebuffer(lamp->tex); | ||||
| if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) | |||||
| GPU_shader_bind(GPU_shader_get_builtin_shader(GPU_SHADER_VSM_STORE)); | |||||
| /* set matrices */ | /* set matrices */ | ||||
| copy_m4_m4(viewmat, lamp->viewmat); | copy_m4_m4(viewmat, lamp->viewmat); | ||||
| Context not available. | |||||
| { | { | ||||
| if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) { | if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) { | ||||
| GPU_shader_unbind(); | GPU_shader_unbind(); | ||||
| GPU_framebuffer_blur(lamp->fb, lamp->tex, lamp->blurfb, lamp->blurtex); | GPU_framebuffer_blur(lamp->fb, lamp->tex, lamp->blurfb, lamp->blurtex, lamp->la->bufsharp); | ||||
| } | } | ||||
| GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex); | GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex); | ||||
| Context not available. | |||||
| GPUNodeLink **r_col, GPUNodeLink **r_lv, GPUNodeLink **r_dist, GPUNodeLink **r_shadow, GPUNodeLink **r_energy) | GPUNodeLink **r_col, GPUNodeLink **r_lv, GPUNodeLink **r_dist, GPUNodeLink **r_shadow, GPUNodeLink **r_energy) | ||||
| { | { | ||||
| GPUNodeLink *visifac; | GPUNodeLink *visifac; | ||||
| GPUNodeLink *shadowfac; | |||||
| *r_col = GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob); | *r_col = GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob); | ||||
| *r_energy = GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob); | *r_energy = GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob); | ||||
| Context not available. | |||||
| mat->dynproperty |= DYN_LAMP_PERSMAT; | mat->dynproperty |= DYN_LAMP_PERSMAT; | ||||
| if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) { | if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) { | ||||
| GPU_link(mat, "shadows_only_vsm", | GPU_link(mat, "test_shadowbuf_vsm", | ||||
| GPU_builtin(GPU_VIEW_POSITION), | GPU_builtin(GPU_VIEW_POSITION), | ||||
| GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), | GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), | ||||
| GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), | GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), | ||||
| GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias), | GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias), inp, &shadowfac); | ||||
| GPU_uniform(lamp->shadow_color), inp, r_shadow); | |||||
| } | } | ||||
| else { | else { | ||||
| GPU_link(mat, "shadows_only", | if (lamp->la->samp > 1 && lamp->la->soft >= 0.01f && lamp->la->shadow_filter != LA_SHADOW_FILTER_NONE) { | ||||
| GPU_builtin(GPU_VIEW_POSITION), | float samp = lamp->la->samp; | ||||
| GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), | float samplesize = lamp->la->soft / lamp->la->shadow_frustum_size; | ||||
| GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), | if (lamp->la->shadow_filter == LA_SHADOW_FILTER_PCF) { | ||||
| GPU_uniform(&lamp->bias), GPU_uniform(lamp->shadow_color), inp, r_shadow); | GPU_link(mat, "test_shadowbuf_pcf", | ||||
| GPU_builtin(GPU_VIEW_POSITION), | |||||
| GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), | |||||
| GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), | |||||
| GPU_uniform(&samp), GPU_uniform(&samplesize), GPU_uniform(&lamp->bias), inp, &shadowfac); | |||||
| } | |||||
| else if (lamp->la->shadow_filter == LA_SHADOW_FILTER_PCF_BAIL) { | |||||
| GPU_link(mat, "test_shadowbuf_pcf_early_bail", | |||||
| GPU_builtin(GPU_VIEW_POSITION), | |||||
| GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), | |||||
| GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), | |||||
| GPU_uniform(&samp), GPU_uniform(&samplesize), GPU_uniform(&lamp->bias), inp, &shadowfac); | |||||
| } | |||||
| } | |||||
| else { | |||||
| GPU_link(mat, "test_shadowbuf", | |||||
| GPU_builtin(GPU_VIEW_POSITION), | |||||
| GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), | |||||
| GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), | |||||
| GPU_uniform(&lamp->bias), inp, &shadowfac); | |||||
| } | |||||
| } | } | ||||
| GPU_link(mat, "shadows_only", inp, shadowfac, GPU_uniform(lamp->shadow_color), r_shadow); | |||||
| } | } | ||||
| else { | else { | ||||
| GPU_link(mat, "set_rgb_one", r_shadow); | GPU_link(mat, "set_rgb_one", r_shadow); | ||||
| Context not available. | |||||
| int liblen, fraglen; | int liblen, fraglen; | ||||
| /* TODO(sergey): How to determine whether we need OSD or not here? */ | /* TODO(sergey): How to determine whether we need OSD or not here? */ | ||||
| GPUMaterial *mat = GPU_material_from_blender(scene, ma, false); | GPUMaterial *mat = GPU_material_from_blender(scene, ma, false, false); | ||||
| GPUPass *pass = (mat) ? mat->pass : NULL; | GPUPass *pass = (mat) ? mat->pass : NULL; | ||||
| if (pass && pass->fragmentcode && pass->vertexcode) { | if (pass && pass->fragmentcode && pass->vertexcode) { | ||||
| Context not available. | |||||