Improvements to Shader Generator

This commit is contained in:
Josh Yelon 2008-01-28 17:28:09 +00:00
parent f56960674e
commit 1d954d5104
25 changed files with 438 additions and 251 deletions

View File

@ -815,79 +815,59 @@ clear(DrawableRegion *clearable) {
// shoehorning them into a matrix. In this way, we avoid // shoehorning them into a matrix. In this way, we avoid
// the need for a separate routine to fetch these values. // the need for a separate routine to fetch these values.
// //
// If "altered" is false, that means you promise that // The "altered" bits indicate what parts of the
// this ShaderMatSpec has been evaluated before, and that // state_and_transform have changed since the last
// since the last time this ShaderMatSpec was evaluated, // time this particular ShaderMatSpec was evaluated.
// that no part of the render state has changed except // This may allow data to be cached and not reevaluated.
// the external and internal transforms.
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
const LMatrix4f *GraphicsStateGuardian:: const LMatrix4f *GraphicsStateGuardian::
fetch_specified_value(Shader::ShaderMatSpec &spec, bool altered) { fetch_specified_value(Shader::ShaderMatSpec &spec, int altered) {
static LMatrix4f acc;
const LMatrix4f *val1;
const LMatrix4f *val2;
static LMatrix4f t1;
static LMatrix4f t2;
LVecBase3f v; LVecBase3f v;
if (altered & spec._dep[0]) {
const LMatrix4f *t = fetch_specified_part(spec._part[0], spec._arg[0], spec._cache[0]);
if (t != &spec._cache[0]) {
spec._cache[0] = *t;
}
}
if (altered & spec._dep[1]) {
const LMatrix4f *t = fetch_specified_part(spec._part[1], spec._arg[1], spec._cache[1]);
if (t != &spec._cache[1]) {
spec._cache[1] = *t;
}
}
switch(spec._func) { switch(spec._func) {
case Shader::SMF_compose: case Shader::SMF_compose:
val1 = fetch_specified_part(spec._part[0], spec._arg[0], t1); spec._value.multiply(spec._cache[0], spec._cache[1]);
val2 = fetch_specified_part(spec._part[1], spec._arg[1], t2); return &spec._value;
acc.multiply(*val1, *val2);
return &acc;
case Shader::SMF_compose_cache_first:
if (altered) {
spec._cache = *fetch_specified_part(spec._part[0], spec._arg[0], t1);
}
val2 = fetch_specified_part(spec._part[1], spec._arg[1], t2);
acc.multiply(spec._cache, *val2);
return &acc;
case Shader::SMF_compose_cache_second:
if (altered) {
spec._cache = *fetch_specified_part(spec._part[1], spec._arg[1], t2);
}
val1 = fetch_specified_part(spec._part[0], spec._arg[0], t1);
acc.multiply(*val1, spec._cache);
return &acc;
case Shader::SMF_transform_dlight: case Shader::SMF_transform_dlight:
if (altered) { spec._value = spec._cache[0];
spec._cache = *fetch_specified_part(spec._part[0], spec._arg[0], t1); v = spec._cache[1].xform_vec(spec._cache[0].get_row3(2));
}
val2 = fetch_specified_part(spec._part[1], spec._arg[1], t2);
acc = spec._cache;
v = val2->xform_vec(spec._cache.get_row3(2));
v.normalize(); v.normalize();
acc.set_row(2, v); spec._value.set_row(2, v);
v = val2->xform_vec(spec._cache.get_row3(3)); v = spec._cache[1].xform_vec(spec._cache[0].get_row3(3));
v.normalize(); v.normalize();
acc.set_row(3, v); spec._value.set_row(3, v);
return &acc; return &spec._value;
case Shader::SMF_transform_plight: case Shader::SMF_transform_plight:
if (altered) { spec._value = spec._cache[0];
spec._cache = *fetch_specified_part(spec._part[0], spec._arg[0], t1); spec._value.set_row(2, spec._cache[1].xform_point(spec._cache[0].get_row3(2)));
} return &spec._value;
val2 = fetch_specified_part(spec._part[1], spec._arg[1], t2);
acc = spec._cache;
acc.set_row(2, val2->xform_point(spec._cache.get_row3(2)));
return &acc;
case Shader::SMF_transform_slight: case Shader::SMF_transform_slight:
if (altered) { spec._value = spec._cache[0];
spec._cache = *fetch_specified_part(spec._part[0], spec._arg[0], t1); spec._value.set_row(2, spec._cache[1].xform_point(spec._cache[0].get_row3(2)));
} v = spec._cache[1].xform_vec(spec._cache[0].get_row3(3));
val2 = fetch_specified_part(spec._part[1], spec._arg[1], t2);
acc = spec._cache;
acc.set_row(2, val2->xform_point(spec._cache.get_row3(2)));
v = val2->xform_vec(spec._cache.get_row3(3));
v.normalize(); v.normalize();
acc.set_row(3, v); spec._value.set_row(3, v);
return &acc; return &spec._value;
case Shader::SMF_first: case Shader::SMF_first:
return fetch_specified_part(spec._part[0], spec._arg[0], t1); return &spec._cache[0];
default: default:
// should never get here // should never get here
return &LMatrix4f::ident_mat(); spec._value = LMatrix4f::ident_mat();
return &spec._value;
} }
} }

View File

@ -195,7 +195,7 @@ public:
void clear(DrawableRegion *clearable); void clear(DrawableRegion *clearable);
const LMatrix4f *fetch_specified_value(Shader::ShaderMatSpec &spec, bool altered); const LMatrix4f *fetch_specified_value(Shader::ShaderMatSpec &spec, int altered);
const LMatrix4f *fetch_specified_part(Shader::ShaderMatInput input, InternalName *name, LMatrix4f &t); const LMatrix4f *fetch_specified_part(Shader::ShaderMatInput input, InternalName *name, LMatrix4f &t);
virtual void prepare_display_region(DisplayRegionPipelineReader *dr, virtual void prepare_display_region(DisplayRegionPipelineReader *dr,

View File

@ -3335,7 +3335,8 @@ void DXGraphicsStateGuardian8::
set_texture_blend_mode(int i, const TextureStage *stage) { set_texture_blend_mode(int i, const TextureStage *stage) {
switch (stage->get_mode()) { switch (stage->get_mode()) {
case TextureStage::M_modulate: case TextureStage::M_modulate:
case TextureStage::M_modulate_glow_map: case TextureStage::M_modulate_glow:
case TextureStage::M_modulate_gloss:
// emulates GL_MODULATE glTexEnv mode // emulates GL_MODULATE glTexEnv mode
_d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_MODULATE); _d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_MODULATE);
_d3d_device->SetTextureStageState(i, D3DTSS_COLORARG1, D3DTA_TEXTURE); _d3d_device->SetTextureStageState(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);

View File

@ -3095,7 +3095,7 @@ do_issue_transform() {
if (_current_shader_context) { if (_current_shader_context) {
// _current_shader_context->issue_transform(this); // _current_shader_context->issue_transform(this);
_current_shader_context->issue_parameters(this, false); _current_shader_context->issue_parameters(this, Shader::SSD_transform);
// ??? NO NEED TO SET THE D3D TRANSFORM VIA SetTransform SINCE THE TRANSFORM IS ONLY USED IN THE SHADER // ??? NO NEED TO SET THE D3D TRANSFORM VIA SetTransform SINCE THE TRANSFORM IS ONLY USED IN THE SHADER
const D3DMATRIX *d3d_mat = (const D3DMATRIX *)transform->get_mat().get_data(); const D3DMATRIX *d3d_mat = (const D3DMATRIX *)transform->get_mat().get_data();
@ -3191,7 +3191,7 @@ do_issue_shader() {
} }
} else { } else {
// Use the same shader as before, but with new input arguments. // Use the same shader as before, but with new input arguments.
context->issue_parameters(this, true); context->issue_parameters(this, Shader::SSD_shaderinputs);
} }
} }
@ -3469,6 +3469,9 @@ set_state_and_transform(const RenderState *target,
do_issue_color_scale(); do_issue_color_scale();
_state._color = _target._color; _state._color = _target._color;
_state._color_scale = _target._color_scale; _state._color_scale = _target._color_scale;
if (_current_shader_context) {
_current_shader_context->issue_parameters(this, Shader::SSD_color);
}
} }
if (_target._cull_face != _state._cull_face) { if (_target._cull_face != _state._cull_face) {
@ -3542,6 +3545,9 @@ set_state_and_transform(const RenderState *target,
if (_target._material != _state._material) { if (_target._material != _state._material) {
do_issue_material(); do_issue_material();
_state._material = _target._material; _state._material = _target._material;
if (_current_shader_context) {
_current_shader_context->issue_parameters(this, Shader::SSD_material);
}
} }
if (_target._light != _state._light) { if (_target._light != _state._light) {
@ -4614,7 +4620,8 @@ void DXGraphicsStateGuardian9::
set_texture_blend_mode(int i, const TextureStage *stage) { set_texture_blend_mode(int i, const TextureStage *stage) {
switch (stage->get_mode()) { switch (stage->get_mode()) {
case TextureStage::M_modulate: case TextureStage::M_modulate:
case TextureStage::M_modulate_glow_map: case TextureStage::M_modulate_glow:
case TextureStage::M_modulate_gloss:
// emulates GL_MODULATE glTexEnv mode // emulates GL_MODULATE glTexEnv mode
set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_MODULATE); set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_MODULATE);
set_texture_stage_state(i, D3DTSS_COLORARG1, D3DTA_TEXTURE); set_texture_stage_state(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);

View File

@ -210,7 +210,7 @@ bind(GSG *gsg) {
gsg -> _last_fvf = 0; gsg -> _last_fvf = 0;
// Pass in k-parameters and transform-parameters // Pass in k-parameters and transform-parameters
issue_parameters(gsg, true); issue_parameters(gsg, Shader::SSD_general);
HRESULT hr; HRESULT hr;
@ -297,12 +297,12 @@ InternalName *global_internal_name_1 = 0;
#endif #endif
void CLP(ShaderContext):: void CLP(ShaderContext)::
issue_parameters(GSG *gsg, bool altered) issue_parameters(GSG *gsg, int altered)
{ {
#ifdef HAVE_CG #ifdef HAVE_CG
if (_cg_context) { if (_cg_context) {
for (int i=0; i<(int)_shader->_mat_spec.size(); i++) { for (int i=0; i<(int)_shader->_mat_spec.size(); i++) {
if (altered || _shader->_mat_spec[i]._trans_dependent) { if (altered & (_shader->_mat_spec[i]._dep[0] | _shader->_mat_spec[i]._dep[1])) {
CGparameter p = _cg_parameter_map[_shader->_mat_spec[i]._id._seqno]; CGparameter p = _cg_parameter_map[_shader->_mat_spec[i]._id._seqno];
if (p == NULL) { if (p == NULL) {
continue; continue;

View File

@ -77,7 +77,7 @@ public:
INLINE bool valid(GSG *gsg); INLINE bool valid(GSG *gsg);
bool bind(GSG *gsg); bool bind(GSG *gsg);
void unbind(GSG *gsg); void unbind(GSG *gsg);
void issue_parameters(GSG *gsg, bool altered); void issue_parameters(GSG *gsg, int altered);
void issue_transform(GSG *gsg); void issue_transform(GSG *gsg);
void disable_shader_vertex_arrays(GSG *gsg); void disable_shader_vertex_arrays(GSG *gsg);
void update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg); void update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg);

View File

@ -562,14 +562,15 @@ affects_polygon_alpha() const {
case ET_add: case ET_add:
case ET_blend_color_scale: case ET_blend_color_scale:
return false; return false;
case ET_modulate_glow_map: case ET_modulate_glow:
case ET_normal_map: case ET_modulate_gloss:
case ET_gloss_map: case ET_normal:
case ET_glow_map: case ET_normal_height:
case ET_normal_gloss_map: case ET_glow:
case ET_gloss:
return false; return false;
case ET_selector_map: case ET_selector:
return true; return true;
case ET_unspecified: case ET_unspecified:
@ -881,23 +882,29 @@ string_env_type(const string &string) {
} else if (cmp_nocase_uh(string, "blend_color_scale") == 0) { } else if (cmp_nocase_uh(string, "blend_color_scale") == 0) {
return ET_blend_color_scale; return ET_blend_color_scale;
} else if (cmp_nocase_uh(string, "modulate_glow_map") == 0) { } else if (cmp_nocase_uh(string, "modulate_glow") == 0) {
return ET_modulate_glow_map; return ET_modulate_glow;
} else if (cmp_nocase_uh(string, "normal_map") == 0) { } else if (cmp_nocase_uh(string, "modulate_gloss") == 0) {
return ET_normal_map; return ET_modulate_gloss;
} else if (cmp_nocase_uh(string, "gloss_map") == 0) { } else if (cmp_nocase_uh(string, "normal") == 0) {
return ET_gloss_map; return ET_normal;
} else if (cmp_nocase_uh(string, "glow_map") == 0) { } else if (cmp_nocase_uh(string, "normal_height") == 0) {
return ET_glow_map; return ET_normal_height;
} else if (cmp_nocase_uh(string, "normal_gloss_map") == 0) { } else if (cmp_nocase_uh(string, "glow") == 0) {
return ET_normal_gloss_map; return ET_glow;
} else if (cmp_nocase_uh(string, "selector_map") == 0) { } else if (cmp_nocase_uh(string, "gloss") == 0) {
return ET_selector_map; return ET_gloss;
} else if (cmp_nocase_uh(string, "height") == 0) {
return ET_height;
} else if (cmp_nocase_uh(string, "selector") == 0) {
return ET_selector;
} else { } else {
return ET_unspecified; return ET_unspecified;
@ -1298,23 +1305,29 @@ ostream &operator << (ostream &out, EggTexture::EnvType type) {
case EggTexture::ET_blend_color_scale: case EggTexture::ET_blend_color_scale:
return out << "blend_color_scale"; return out << "blend_color_scale";
case EggTexture::ET_modulate_glow_map: case EggTexture::ET_modulate_glow:
return out << "modulate_glow_map"; return out << "modulate_glow";
case EggTexture::ET_normal_map: case EggTexture::ET_modulate_gloss:
return out << "normal_map"; return out << "modulate_gloss";
case EggTexture::ET_gloss_map: case EggTexture::ET_normal:
return out << "gloss_map"; return out << "normal";
case EggTexture::ET_glow_map: case EggTexture::ET_normal_height:
return out << "glow_map"; return out << "normal_height";
case EggTexture::ET_normal_gloss_map: case EggTexture::ET_glow:
return out << "normal_gloss_map"; return out << "glow";
case EggTexture::ET_selector_map: case EggTexture::ET_gloss:
return out << "selector_map"; return out << "gloss";
case EggTexture::ET_height:
return out << "height";
case EggTexture::ET_selector:
return out << "selector";
} }
nassertr(false, out); nassertr(false, out);

View File

@ -102,12 +102,14 @@ PUBLISHED:
ET_replace, ET_replace,
ET_add, ET_add,
ET_blend_color_scale, ET_blend_color_scale,
ET_modulate_glow_map, ET_modulate_glow,
ET_normal_map, ET_modulate_gloss,
ET_gloss_map, ET_normal,
ET_glow_map, ET_normal_height,
ET_normal_gloss_map, ET_glow,
ET_selector_map, ET_gloss,
ET_height,
ET_selector,
}; };
enum CombineMode { enum CombineMode {
CM_unspecified, CM_unspecified,

View File

@ -1393,28 +1393,36 @@ make_texture_stage(const EggTexture *egg_tex) {
stage->set_mode(TextureStage::M_blend_color_scale); stage->set_mode(TextureStage::M_blend_color_scale);
break; break;
case EggTexture::ET_modulate_glow_map: case EggTexture::ET_modulate_glow:
stage->set_mode(TextureStage::M_modulate_glow_map); stage->set_mode(TextureStage::M_modulate_glow);
break; break;
case EggTexture::ET_normal_map: case EggTexture::ET_modulate_gloss:
stage->set_mode(TextureStage::M_normal_map); stage->set_mode(TextureStage::M_modulate_gloss);
break; break;
case EggTexture::ET_gloss_map: case EggTexture::ET_normal:
stage->set_mode(TextureStage::M_gloss_map); stage->set_mode(TextureStage::M_normal);
break; break;
case EggTexture::ET_glow_map: case EggTexture::ET_normal_height:
stage->set_mode(TextureStage::M_glow_map); stage->set_mode(TextureStage::M_normal_height);
break; break;
case EggTexture::ET_normal_gloss_map: case EggTexture::ET_glow:
stage->set_mode(TextureStage::M_normal_gloss_map); stage->set_mode(TextureStage::M_glow);
break; break;
case EggTexture::ET_selector_map: case EggTexture::ET_gloss:
stage->set_mode(TextureStage::M_selector_map); stage->set_mode(TextureStage::M_gloss);
break;
case EggTexture::ET_height:
stage->set_mode(TextureStage::M_height);
break;
case EggTexture::ET_selector:
stage->set_mode(TextureStage::M_selector);
break; break;
case EggTexture::ET_unspecified: case EggTexture::ET_unspecified:

View File

@ -3494,7 +3494,7 @@ do_issue_transform() {
} }
if (_current_shader_context) { if (_current_shader_context) {
_current_shader_context->issue_parameters(this, false); _current_shader_context->issue_parameters(this, Shader::SSD_transform);
} }
report_my_gl_errors(); report_my_gl_errors();
@ -3555,7 +3555,7 @@ do_issue_shader() {
_current_shader_context = context; _current_shader_context = context;
} else { } else {
// Use the same shader as before, but with new input arguments. // Use the same shader as before, but with new input arguments.
context->issue_parameters(this, true); context->issue_parameters(this, Shader::SSD_shaderinputs);
} }
} }
@ -5284,7 +5284,8 @@ get_texture_apply_mode_type(TextureStage::Mode am) {
case TextureStage::M_add: return GL_ADD; case TextureStage::M_add: return GL_ADD;
case TextureStage::M_combine: return GL_COMBINE; case TextureStage::M_combine: return GL_COMBINE;
case TextureStage::M_blend_color_scale: return GL_BLEND; case TextureStage::M_blend_color_scale: return GL_BLEND;
case TextureStage::M_modulate_glow_map: return GL_MODULATE; case TextureStage::M_modulate_glow: return GL_MODULATE;
case TextureStage::M_modulate_gloss: return GL_MODULATE;
} }
GLCAT.error() GLCAT.error()
@ -5867,6 +5868,9 @@ set_state_and_transform(const RenderState *target,
do_issue_color_scale(); do_issue_color_scale();
_state._color = _target._color; _state._color = _target._color;
_state._color_scale = _target._color_scale; _state._color_scale = _target._color_scale;
if (_current_shader_context) {
_current_shader_context->issue_parameters(this, Shader::SSD_color);
}
} }
if (_target._cull_face != _state._cull_face) { if (_target._cull_face != _state._cull_face) {
@ -5970,6 +5974,9 @@ set_state_and_transform(const RenderState *target,
PStatTimer timer(_draw_set_state_material_pcollector); PStatTimer timer(_draw_set_state_material_pcollector);
do_issue_material(); do_issue_material();
_state._material = _target._material; _state._material = _target._material;
if (_current_shader_context) {
_current_shader_context->issue_parameters(this, Shader::SSD_material);
}
} }
if (_target._light != _state._light) { if (_target._light != _state._light) {

View File

@ -110,7 +110,7 @@ bind(GSG *gsg) {
if (_cg_context != 0) { if (_cg_context != 0) {
// Pass in k-parameters and transform-parameters // Pass in k-parameters and transform-parameters
issue_parameters(gsg, true); issue_parameters(gsg, Shader::SSD_general);
// Bind the shaders. // Bind the shaders.
cgGLEnableProfile(cgGetProgramProfile(_cg_vprogram)); cgGLEnableProfile(cgGetProgramProfile(_cg_vprogram));
@ -154,14 +154,14 @@ unbind() {
// transforms. // transforms.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CLP(ShaderContext):: void CLP(ShaderContext)::
issue_parameters(GSG *gsg, bool altered) { issue_parameters(GSG *gsg, int altered) {
#ifdef HAVE_CG #ifdef HAVE_CG
if (_cg_context == 0) { if (_cg_context == 0) {
return; return;
} }
for (int i=0; i<(int)_shader->_mat_spec.size(); i++) { for (int i=0; i<(int)_shader->_mat_spec.size(); i++) {
if (altered || _shader->_mat_spec[i]._trans_dependent) { if (altered & (_shader->_mat_spec[i]._dep[0] | _shader->_mat_spec[i]._dep[1])) {
CGparameter p = _cg_parameter_map[_shader->_mat_spec[i]._id._seqno]; CGparameter p = _cg_parameter_map[_shader->_mat_spec[i]._id._seqno];
const LMatrix4f *val = gsg->fetch_specified_value(_shader->_mat_spec[i], altered); const LMatrix4f *val = gsg->fetch_specified_value(_shader->_mat_spec[i], altered);
if (val) { if (val) {

View File

@ -41,7 +41,7 @@ public:
INLINE bool valid(void); INLINE bool valid(void);
void bind(GSG *gsg); void bind(GSG *gsg);
void unbind(); void unbind();
void issue_parameters(GSG *gsg, bool all); void issue_parameters(GSG *gsg, int altered);
void disable_shader_vertex_arrays(GSG *gsg); void disable_shader_vertex_arrays(GSG *gsg);
bool update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, bool update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg,
bool force); bool force);

View File

@ -323,6 +323,52 @@ cp_parse_coord_sys(ShaderArgInfo &p,
return true; return true;
} }
////////////////////////////////////////////////////////////////////
// Function: Shader::cp_dependency
// Access: Public
// Description: Given ShaderMatInput, returns an indication of what
// part or parts of the state_and_transform the
// ShaderMatInput depends upon.
////////////////////////////////////////////////////////////////////
int Shader::
cp_dependency(ShaderMatInput inp) {
int dep = SSD_general;
if (inp == SMO_INVALID) {
return SSD_NONE;
}
if (inp == SMO_attr_material) {
dep |= SSD_material;
}
if (inp == SMO_attr_color) {
dep |= SSD_color;
}
if ((inp == SMO_model_to_view)||
(inp == SMO_view_to_model)) {
dep |= SSD_transform;
}
if ((inp == SMO_alight_x)||
(inp == SMO_dlight_x)||
(inp == SMO_plight_x)||
(inp == SMO_slight_x)||
(inp == SMO_satten_x)||
(inp == SMO_mat_constant_x)||
(inp == SMO_vec_constant_x)||
(inp == SMO_view_x_to_view)||
(inp == SMO_view_to_view_x)||
(inp == SMO_apiview_x_to_view)||
(inp == SMO_view_to_apiview_x)||
(inp == SMO_clip_x_to_view)||
(inp == SMO_view_to_clip_x)||
(inp == SMO_apiclip_x_to_view)||
(inp == SMO_view_to_apiclip_x)) {
dep |= SSD_shaderinputs;
}
return dep;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Shader::cp_optimize_mat_spec // Function: Shader::cp_optimize_mat_spec
// Access: Public // Access: Public
@ -336,6 +382,11 @@ void Shader::
cp_optimize_mat_spec(ShaderMatSpec &spec) { cp_optimize_mat_spec(ShaderMatSpec &spec) {
// If we're composing with identity, simplify. // If we're composing with identity, simplify.
if (spec._func == SMF_first) {
spec._part[1] = SMO_INVALID;
spec._arg[1] = 0;
}
if (spec._func == SMF_compose) { if (spec._func == SMF_compose) {
if (spec._part[1] == SMO_identity) { if (spec._part[1] == SMO_identity) {
spec._func = SMF_first; spec._func = SMF_first;
@ -349,33 +400,10 @@ cp_optimize_mat_spec(ShaderMatSpec &spec) {
} }
} }
// See if either half can be cached. // Calculate state and transform dependencies.
bool can_cache_part0 = true;
bool can_cache_part1 = true;
if ((spec._part[0] == SMO_model_to_view)||
(spec._part[0] == SMO_view_to_model)) {
can_cache_part0 = false;
}
if ((spec._part[1] == SMO_model_to_view)||
(spec._part[1] == SMO_view_to_model)) {
can_cache_part1 = false;
}
// See if we can use a compose-with-cache variant. spec._dep[0] = cp_dependency(spec._part[0]);
if (spec._func == SMF_compose) { spec._dep[1] = cp_dependency(spec._part[1]);
if (can_cache_part0) {
spec._func = SMF_compose_cache_first;
} else if (can_cache_part1) {
spec._func = SMF_compose_cache_second;
}
}
// Determine transform-dependence.
if (can_cache_part0 && can_cache_part1) {
spec._trans_dependent = false;
} else {
spec._trans_dependent = true;
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -111,10 +111,6 @@ public:
SMO_apiclip_x_to_view, SMO_apiclip_x_to_view,
SMO_view_to_apiclip_x, SMO_view_to_apiclip_x,
SMO_light_vector,
SMO_light_color,
SMO_light_spec,
SMO_INVALID SMO_INVALID
}; };
@ -151,14 +147,21 @@ public:
SMP_col3, SMP_col3,
}; };
enum ShaderStateDep {
SSD_NONE = 0,
SSD_general = 1,
SSD_transform = 2,
SSD_color = 4,
SSD_material = 8,
SSD_shaderinputs = 16,
};
enum ShaderBug { enum ShaderBug {
SBUG_ati_draw_buffers, SBUG_ati_draw_buffers,
}; };
enum ShaderMatFunc { enum ShaderMatFunc {
SMF_compose, SMF_compose,
SMF_compose_cache_first,
SMF_compose_cache_second,
SMF_transform_dlight, SMF_transform_dlight,
SMF_transform_plight, SMF_transform_plight,
SMF_transform_slight, SMF_transform_slight,
@ -176,9 +179,10 @@ public:
ShaderMatFunc _func; ShaderMatFunc _func;
ShaderMatInput _part[2]; ShaderMatInput _part[2];
PT(InternalName) _arg[2]; PT(InternalName) _arg[2];
LMatrix4f _cache; int _dep[2];
LMatrix4f _cache[2];
LMatrix4f _value;
ShaderMatPiece _piece; ShaderMatPiece _piece;
bool _trans_dependent;
}; };
struct ShaderTexSpec { struct ShaderTexSpec {
@ -241,6 +245,7 @@ public:
bool cp_parse_coord_sys(ShaderArgInfo &arg, bool cp_parse_coord_sys(ShaderArgInfo &arg,
vector_string &pieces, int &next, vector_string &pieces, int &next,
ShaderMatSpec &spec, bool fromflag); ShaderMatSpec &spec, bool fromflag);
int cp_dependency(ShaderMatInput inp);
void cp_optimize_mat_spec(ShaderMatSpec &spec); void cp_optimize_mat_spec(ShaderMatSpec &spec);
bool compile_parameter(const ShaderArgId &arg_id, bool compile_parameter(const ShaderArgId &arg_id,

View File

@ -197,7 +197,7 @@ get_mode() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE bool TextureStage:: INLINE bool TextureStage::
is_fixed_function() const { is_fixed_function() const {
return (_mode < M_normal_map); return (_mode < M_normal);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -397,23 +397,29 @@ operator << (ostream &out, TextureStage::Mode mode) {
case TextureStage::M_blend_color_scale: case TextureStage::M_blend_color_scale:
return out << "blend_color_scale"; return out << "blend_color_scale";
case TextureStage::M_modulate_glow_map: case TextureStage::M_modulate_glow:
return out << "modulate_glow_map"; return out << "modulate_glow";
case TextureStage::M_normal_map: case TextureStage::M_modulate_gloss:
return out << "normal_map"; return out << "modulate_gloss";
case TextureStage::M_gloss_map: case TextureStage::M_normal:
return out << "gloss_map"; return out << "normal";
case TextureStage::M_glow_map: case TextureStage::M_normal_height:
return out << "glow_map"; return out << "normal_height";
case TextureStage::M_normal_gloss_map: case TextureStage::M_glow:
return out << "normal_gloss_map"; return out << "glow";
case TextureStage::M_selector_map: case TextureStage::M_gloss:
return out << "selector_map"; return out << "gloss";
case TextureStage::M_height:
return out << "height";
case TextureStage::M_selector:
return out << "selector";
} }
return out << "**invalid Mode(" << (int)mode << ")**"; return out << "**invalid Mode(" << (int)mode << ")**";

View File

@ -57,15 +57,18 @@ PUBLISHED:
M_add, M_add,
M_combine, M_combine,
M_blend_color_scale, M_blend_color_scale,
M_modulate_glow_map, // When fixed-function, equivalent to modulate.
M_modulate_glow, // When fixed-function, equivalent to modulate.
M_modulate_gloss, // When fixed-function, equivalent to modulate.
// Modes that are only relevant to shader-based rendering. // Modes that are only relevant to shader-based rendering.
M_normal_map, M_normal,
M_gloss_map, M_normal_height,
M_glow_map, M_glow, // Rarely used: modulate_glow is more efficient.
M_normal_gloss_map, M_gloss, // Rarely used: modulate_gloss is more efficient.
M_selector_map, M_height, // Rarely used: normal_height is more efficient.
M_selector,
}; };
enum CombineMode { enum CombineMode {

View File

@ -742,14 +742,18 @@ make_texture_layer(const NodePath &render,
CPT(RenderAttrib) cba; CPT(RenderAttrib) cba;
switch (stage_info._stage->get_mode()) { switch (stage_info._stage->get_mode()) {
case TextureStage::M_normal_map: case TextureStage::M_normal:
case TextureStage::M_gloss_map: case TextureStage::M_normal_height:
case TextureStage::M_normal_gloss_map: case TextureStage::M_glow:
case TextureStage::M_selector_map: case TextureStage::M_gloss:
case TextureStage::M_height:
case TextureStage::M_selector:
// Don't know what to do with these funny modes. We should // Don't know what to do with these funny modes. We should
// probably raise an exception or something. Fall through for // probably raise an exception or something. Fall through for
// now. // now.
case TextureStage::M_modulate_glow:
case TextureStage::M_modulate_gloss:
case TextureStage::M_modulate: case TextureStage::M_modulate:
cba = ColorBlendAttrib::make cba = ColorBlendAttrib::make
(ColorBlendAttrib::M_add, ColorBlendAttrib::O_fbuffer_color, (ColorBlendAttrib::M_add, ColorBlendAttrib::O_fbuffer_color,

View File

@ -223,10 +223,29 @@ analyze_renderstate(const RenderState *rs) {
} }
} }
// See if there is a normal map, height map, gloss map, or glow map.
for (int i=0; i<_num_textures; i++) {
TextureStage *stage = _attribs._texture->get_on_stage(i);
TextureStage::Mode mode = stage->get_mode();
if ((mode == TextureStage::M_normal)||(mode == TextureStage::M_normal_height)) {
_map_index_normal = i;
}
if ((mode == TextureStage::M_height)||(mode == TextureStage::M_normal_height)) {
_map_index_height = i;
}
if ((mode == TextureStage::M_glow)||(mode == TextureStage::M_modulate_glow)) {
_map_index_glow = i;
}
if ((mode == TextureStage::M_gloss)||(mode == TextureStage::M_modulate_gloss)) {
_map_index_gloss = i;
}
}
// Determine whether model-space or tangent-space lighting is recommended. // Determine whether model-space or tangent-space lighting is recommended.
if (_attribs._light->get_num_on_lights() > 0) { if (_attribs._light->get_num_on_lights() > 0) {
_ms_lighting = true; _lighting = true;
} }
// Find the material. // Find the material.
@ -299,12 +318,15 @@ void ShaderGenerator::
clear_analysis() { clear_analysis() {
_vertex_colors = false; _vertex_colors = false;
_flat_colors = false; _flat_colors = false;
_ms_lighting = false; _lighting = false;
_ts_lighting = false;
_have_ambient = false; _have_ambient = false;
_have_diffuse = false; _have_diffuse = false;
_have_emission = false; _have_emission = false;
_have_specular = false; _have_specular = false;
_map_index_normal = -1;
_map_index_height = -1;
_map_index_glow = -1;
_map_index_gloss = -1;
_attribs.clear_to_defaults(); _attribs.clear_to_defaults();
_material = (Material*)NULL; _material = (Material*)NULL;
_alights.clear(); _alights.clear();
@ -329,7 +351,7 @@ create_shader_attrib(const string &txt) {
PT(Shader) shader = Shader::make(txt); PT(Shader) shader = Shader::make(txt);
CPT(RenderAttrib) shattr = ShaderAttrib::make(); CPT(RenderAttrib) shattr = ShaderAttrib::make();
shattr=DCAST(ShaderAttrib, shattr)->set_shader(shader); shattr=DCAST(ShaderAttrib, shattr)->set_shader(shader);
if (_ms_lighting) { if (_lighting) {
for (int i=0; i<(int)_alights.size(); i++) { for (int i=0; i<(int)_alights.size(); i++) {
shattr=DCAST(ShaderAttrib, shattr)->set_shader_input(InternalName::make("alight", i), _alights_np[i]); shattr=DCAST(ShaderAttrib, shattr)->set_shader_input(InternalName::make("alight", i), _alights_np[i]);
} }
@ -377,10 +399,11 @@ synthesize_shader(const RenderState *rs) {
char *pos_freg = 0; char *pos_freg = 0;
char *normal_vreg = 0; char *normal_vreg = 0;
// char *tangent_vreg = 0;
// char *binormal_vreg = 0;
char *normal_freg = 0; char *normal_freg = 0;
// char *eyevec_freg = 0; char *tangent_vreg = 0;
char *tangent_freg = 0;
char *binormal_vreg = 0;
char *binormal_freg = 0;
pvector<char *> texcoord_vreg; pvector<char *> texcoord_vreg;
pvector<char *> texcoord_freg; pvector<char *> texcoord_freg;
pvector<char *> tslightvec_freg; pvector<char *> tslightvec_freg;
@ -407,13 +430,23 @@ synthesize_shader(const RenderState *rs) {
text << "\t in float4 vtx_color : COLOR,\n"; text << "\t in float4 vtx_color : COLOR,\n";
text << "\t out float4 l_color : COLOR,\n"; text << "\t out float4 l_color : COLOR,\n";
} }
if (_ms_lighting) { if (_lighting) {
pos_freg = alloc_freg(); pos_freg = alloc_freg();
normal_vreg = alloc_vreg(); normal_vreg = alloc_vreg();
normal_freg = alloc_freg(); normal_freg = alloc_freg();
text << "\t in float4 vtx_normal : " << normal_vreg << ",\n"; text << "\t in float4 vtx_normal : " << normal_vreg << ",\n";
text << "\t out float4 l_normal : " << normal_freg << ",\n"; text << "\t out float4 l_normal : " << normal_freg << ",\n";
text << "\t out float4 l_pos : " << pos_freg << ",\n"; text << "\t out float4 l_pos : " << pos_freg << ",\n";
if (_map_index_normal >= 0) {
tangent_vreg = alloc_vreg();
tangent_freg = alloc_freg();
binormal_vreg = alloc_vreg();
binormal_freg = alloc_freg();
text << "\t in float4 vtx_tangent" << _map_index_normal << " : " << tangent_vreg << ",\n";
text << "\t in float4 vtx_binormal" << _map_index_normal << " : " << binormal_vreg << ",\n";
text << "\t out float4 l_tangent : " << tangent_freg << ",\n";
text << "\t out float4 l_binormal : " << binormal_freg << ",\n";
}
} }
text << "\t float4 vtx_position : POSITION,\n"; text << "\t float4 vtx_position : POSITION,\n";
@ -429,9 +462,13 @@ synthesize_shader(const RenderState *rs) {
if (_vertex_colors) { if (_vertex_colors) {
text << "\t l_color = vtx_color;\n"; text << "\t l_color = vtx_color;\n";
} }
if (_ms_lighting) { if (_lighting) {
text << "\t l_normal = vtx_normal;\n";
text << "\t l_pos = vtx_position;\n"; text << "\t l_pos = vtx_position;\n";
text << "\t l_normal = vtx_normal;\n";
if (_map_index_normal) {
text << "\t l_tangent = vtx_tangent" << _map_index_normal << ";\n";
text << "\t l_binormal = vtx_binormal" << _map_index_normal << ";\n";
}
} }
text << "}\n\n"; text << "}\n\n";
@ -446,8 +483,12 @@ synthesize_shader(const RenderState *rs) {
} else { } else {
text << "\t uniform float4 attr_color,\n"; text << "\t uniform float4 attr_color,\n";
} }
if (_ms_lighting) { if (_lighting) {
text << "\t in float3 l_normal : " << normal_freg << ",\n"; text << "\t in float3 l_normal : " << normal_freg << ",\n";
if (_map_index_normal) {
text << "\t in float3 l_tangent : " << tangent_freg << ",\n";
text << "\t in float3 l_binormal : " << binormal_freg << ",\n";
}
text << "\t in float4 l_pos : " << pos_freg << ",\n"; text << "\t in float4 l_pos : " << pos_freg << ",\n";
for (int i=0; i<(int)_alights.size(); i++) { for (int i=0; i<(int)_alights.size(); i++) {
text << "\t uniform float4 alight_alight" << i << ",\n"; text << "\t uniform float4 alight_alight" << i << ",\n";
@ -475,8 +516,13 @@ synthesize_shader(const RenderState *rs) {
} }
text << "\t out float4 o_color : COLOR\n"; text << "\t out float4 o_color : COLOR\n";
text << ") {\n"; text << ") {\n";
text << "\t // Fetch all textures.\n";
for (int i=0; i<_num_textures; i++) {
text << "\t float4 tex" << i << " = tex2D(tex_" << i << ", float2(l_texcoord" << i << "));\n";
}
if (_ms_lighting) { if (_lighting) {
text << "\t // Begin model-space light calculations\n";
if (_have_ambient) { if (_have_ambient) {
text << "\t float4 tot_ambient = float4(0,0,0,0);\n"; text << "\t float4 tot_ambient = float4(0,0,0,0);\n";
} }
@ -486,7 +532,16 @@ synthesize_shader(const RenderState *rs) {
if (_have_specular) { if (_have_specular) {
text << "\t float4 tot_specular = float4(0,0,0,0);\n"; text << "\t float4 tot_specular = float4(0,0,0,0);\n";
} }
text << "\t l_normal = normalize(l_normal);\n"; if (_map_index_normal) {
text << "\t // Translate tangent-space normal in map to model-space.\n";
text << "\t float3 tsnormal = ((float3)tex" << _map_index_normal << " * 2) - 1;\n";
text << "\t l_normal = l_normal * tsnormal.z;\n";
text << "\t l_normal+= l_tangent * tsnormal.x;\n";
text << "\t l_normal+= l_binormal * tsnormal.y;\n";
text << "\t l_normal = normalize(l_normal);\n";
} else {
text << "\t l_normal = normalize(l_normal);\n";
}
text << "\t float ldist,lattenv,langle;\n"; text << "\t float ldist,lattenv,langle;\n";
text << "\t float4 lcolor,lspec,lvec,lpoint,latten,ldir,leye,lhalf;\n"; text << "\t float4 lcolor,lspec,lvec,lpoint,latten,ldir,leye,lhalf;\n";
for (int i=0; i<(int)_alights.size(); i++) { for (int i=0; i<(int)_alights.size(); i++) {
@ -561,11 +616,12 @@ synthesize_shader(const RenderState *rs) {
text << "\t tot_specular += lspec;\n"; text << "\t tot_specular += lspec;\n";
} }
} }
text << "\t // Begin model-space light summation\n";
if (_have_emission) { if (_have_emission) {
text << "\t o_color = attr_material[2];\n"; text << "\t o_color = attr_material[2];\n";
} else { } else {
text << "\t o_color = float4(0,0,0,1);\n"; text << "\t o_color = float4(0,0,0,0);\n";
} }
if (_have_ambient) { if (_have_ambient) {
if (_material->has_ambient()) { if (_material->has_ambient()) {
@ -589,6 +645,14 @@ synthesize_shader(const RenderState *rs) {
text << "\t o_color += tot_diffuse;\n"; text << "\t o_color += tot_diffuse;\n";
} }
} }
if (_vertex_colors) {
text << "\t o_color.a = l_color.a;\n";
} else if (_flat_colors) {
text << "\t o_color.a = attr_color.a;\n";
} else {
text << "\t o_color.a = 1;\n";
}
text << "\t // End model-space light calculations\n";
} else { } else {
if (_vertex_colors) { if (_vertex_colors) {
text << "\t o_color = l_color;\n"; text << "\t o_color = l_color;\n";
@ -599,9 +663,12 @@ synthesize_shader(const RenderState *rs) {
} }
} }
for (int i=0; i<_num_textures; i++) { for (int i=0; i<_num_textures; i++) {
text << "\t o_color *= tex2D(tex_" << i << ", float2(l_texcoord" << i << "));\n"; TextureStage *stage = _attribs._texture->get_on_stage(i);
if (stage->get_mode() != TextureStage::M_normal) {
text << "\t o_color *= tex" << i << ";\n";
}
} }
if (_ms_lighting) { if (_lighting) {
if (_have_specular) { if (_have_specular) {
text << "\t o_color += tot_specular;\n"; text << "\t o_color += tot_specular;\n";
} }

View File

@ -104,14 +104,18 @@ protected:
bool _vertex_colors; bool _vertex_colors;
bool _flat_colors; bool _flat_colors;
bool _ms_lighting; bool _lighting;
bool _ts_lighting;
bool _have_ambient; bool _have_ambient;
bool _have_diffuse; bool _have_diffuse;
bool _have_emission; bool _have_emission;
bool _have_specular; bool _have_specular;
int _map_index_normal;
int _map_index_height;
int _map_index_glow;
int _map_index_gloss;
bool _need_material_props; bool _need_material_props;
void analyze_renderstate(const RenderState *rs); void analyze_renderstate(const RenderState *rs);

View File

@ -175,11 +175,14 @@ collect_maps() {
for (size_t i=0; i<_normal_maps.size(); i++) { for (size_t i=0; i<_normal_maps.size(); i++) {
_all_maps.push_back(_normal_maps[i]); _all_maps.push_back(_normal_maps[i]);
} }
for (size_t i=0; i<_glow_maps.size(); i++) {
_all_maps.push_back(_glow_maps[i]);
}
for (size_t i=0; i<_gloss_maps.size(); i++) { for (size_t i=0; i<_gloss_maps.size(); i++) {
_all_maps.push_back(_gloss_maps[i]); _all_maps.push_back(_gloss_maps[i]);
} }
for (size_t i=0; i<_glow_maps.size(); i++) { for (size_t i=0; i<_height_maps.size(); i++) {
_all_maps.push_back(_glow_maps[i]); _all_maps.push_back(_height_maps[i]);
} }
for (size_t i=0; i<_color.size(); i++) { for (size_t i=0; i<_color.size(); i++) {
@ -236,6 +239,10 @@ find_textures_modern(MObject shader) {
if (_glow_maps.size() == 0) { if (_glow_maps.size() == 0) {
MayaShaderColorDef::find_textures_modern(n, _glow_maps, shader_fn.findPlug("incandescenceR"), true); MayaShaderColorDef::find_textures_modern(n, _glow_maps, shader_fn.findPlug("incandescenceR"), true);
} }
MayaShaderColorDef::find_textures_modern(n, _height_maps, shader_fn.findPlug("surfaceThickness"), true);
if (_height_maps.size() == 0) {
MayaShaderColorDef::find_textures_modern(n, _height_maps, shader_fn.findPlug("surfaceThicknessR"), true);
}
collect_maps(); collect_maps();
@ -292,47 +299,82 @@ calculate_pairings() {
_all_maps[i]->_opposite = 0; _all_maps[i]->_opposite = 0;
} }
bool using_color_alpha = (_trans_maps.size() > 0);
for (size_t i=0; i<_color_maps.size(); i++) {
if ((_color_maps[i]->_blend_type != MayaShaderColorDef::BT_modulate)&&
(_color_maps[i]->_blend_type != MayaShaderColorDef::BT_unspecified)) {
using_color_alpha = true;
}
}
for (int retry=0; retry<2; retry++) { for (int retry=0; retry<2; retry++) {
bool perfect=(retry==0); bool perfect=(retry==0);
for (size_t i=0; i<_color_maps.size(); i++) { for (size_t i=0; i<_color_maps.size(); i++) {
if ((_color_maps[i]->_blend_type == MayaShaderColorDef::BT_modulate)|| if ((_color_maps[i]->_blend_type != MayaShaderColorDef::BT_modulate)&&
(_color_maps[i]->_blend_type == MayaShaderColorDef::BT_unspecified)) { (_color_maps[i]->_blend_type != MayaShaderColorDef::BT_unspecified)) {
for (size_t j=0; j<_trans_maps.size(); j++) { for (size_t j=0; j<_trans_maps.size(); j++) {
try_pair(_color_maps[i], _trans_maps[j], perfect); try_pair(_color_maps[i], _trans_maps[j], perfect);
} }
} }
} }
for (size_t i=0; i<_normal_maps.size(); i++) { }
for (size_t j=0; j<_gloss_maps.size(); j++) {
try_pair(_normal_maps[i], _gloss_maps[j], perfect); if (!using_color_alpha) {
} for (int retry=0; retry<2; retry++) {
} bool perfect=(retry==0);
if (_trans_maps.size() == 0) {
for (size_t i=0; i<_color_maps.size(); i++) { for (size_t i=0; i<_color_maps.size(); i++) {
for (size_t j=0; j<_glow_maps.size(); j++) { for (size_t j=0; j<_glow_maps.size(); j++) {
try_pair(_color_maps[i], _glow_maps[j], perfect); try_pair(_color_maps[i], _glow_maps[j], perfect);
} }
for (size_t j=0; j<_gloss_maps.size(); j++) {
try_pair(_color_maps[i], _gloss_maps[j], perfect);
}
} }
} }
} }
for (size_t i=0; i<_normal_maps.size(); i++) { for (int retry=0; retry<2; retry++) {
_normal_maps[i]->_blend_type = MayaShaderColorDef::BT_normal_map; bool perfect=(retry==0);
} for (size_t i=0; i<_normal_maps.size(); i++) {
for (size_t i=0; i<_gloss_maps.size(); i++) { for (size_t j=0; j<_height_maps.size(); j++) {
if (_gloss_maps[i]->_opposite) { try_pair(_normal_maps[i], _height_maps[j], perfect);
_gloss_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified; }
_gloss_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_normal_gloss_map;
} else {
_gloss_maps[i]->_blend_type = MayaShaderColorDef::BT_gloss_map;
} }
} }
for (size_t i=0; i<_normal_maps.size(); i++) {
_normal_maps[i]->_blend_type = MayaShaderColorDef::BT_normal;
}
for (size_t i=0; i<_glow_maps.size(); i++) { for (size_t i=0; i<_glow_maps.size(); i++) {
if (_glow_maps[i]->_opposite) { if (_glow_maps[i]->_opposite) {
_glow_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified; _glow_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
_glow_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate_glow_map; _glow_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate_glow;
} else { } else {
_glow_maps[i]->_blend_type = MayaShaderColorDef::BT_glow_map; _glow_maps[i]->_blend_type = MayaShaderColorDef::BT_glow;
}
}
for (size_t i=0; i<_gloss_maps.size(); i++) {
if (_gloss_maps[i]->_opposite) {
_gloss_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
_gloss_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate_gloss;
} else {
_gloss_maps[i]->_blend_type = MayaShaderColorDef::BT_gloss;
}
}
for (size_t i=0; i<_height_maps.size(); i++) {
if (_height_maps[i]->_opposite) {
_height_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
_height_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_normal_height;
} else {
_height_maps[i]->_blend_type = MayaShaderColorDef::BT_height;
}
}
for (size_t i=0; i<_trans_maps.size(); i++) {
if (_trans_maps[i]->_opposite) {
_trans_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
_trans_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate;
} else {
_trans_maps[i]->_blend_type = MayaShaderColorDef::BT_modulate;
} }
} }
} }
@ -342,24 +384,24 @@ calculate_pairings() {
// Access: Private // Access: Private
// Description: Try to associate an RGB tex with an Alpha tex. // Description: Try to associate an RGB tex with an Alpha tex.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void MayaShader::try_pair(MayaShaderColorDef *map1, bool MayaShader::try_pair(MayaShaderColorDef *map1,
MayaShaderColorDef *map2, MayaShaderColorDef *map2,
bool perfect) { bool perfect) {
if ((map1->_opposite)||(map2->_opposite)) { if ((map1->_opposite)||(map2->_opposite)) {
// one of the maps is already paired // one of the maps is already paired
return; return false;
} }
if (perfect) { if (perfect) {
if (map1->_texture_filename != map2->_texture_filename) { if (map1->_texture_filename != map2->_texture_filename) {
// perfect mode requires a filename match. // perfect mode requires a filename match.
return; return false;
} }
} else { } else {
string pre1 = get_file_prefix(map1->_texture_filename); string pre1 = get_file_prefix(map1->_texture_filename);
string pre2 = get_file_prefix(map2->_texture_filename); string pre2 = get_file_prefix(map2->_texture_filename);
if (pre1 != pre2) { if (pre1 != pre2) {
// imperfect mode requires a filename prefix match. // imperfect mode requires a filename prefix match.
return; return false;
} }
} }
@ -375,11 +417,12 @@ void MayaShader::try_pair(MayaShaderColorDef *map1,
(map1->_repeat_uv != map2->_repeat_uv) || (map1->_repeat_uv != map2->_repeat_uv) ||
(map1->_offset != map2->_offset) || (map1->_offset != map2->_offset) ||
(map1->_rotate_uv != map2->_rotate_uv)) { (map1->_rotate_uv != map2->_rotate_uv)) {
return; return false;
} }
// Pairing successful. // Pairing successful.
map1->_opposite = map2; map1->_opposite = map2;
map2->_opposite = map1; map2->_opposite = map1;
return true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -61,14 +61,15 @@ public: // relevant only to modern mode.
MayaShaderColorList _color_maps; MayaShaderColorList _color_maps;
MayaShaderColorList _trans_maps; MayaShaderColorList _trans_maps;
MayaShaderColorList _normal_maps; MayaShaderColorList _normal_maps;
MayaShaderColorList _gloss_maps;
MayaShaderColorList _glow_maps; MayaShaderColorList _glow_maps;
MayaShaderColorList _gloss_maps;
MayaShaderColorList _height_maps;
void bind_uvsets(MayaFileToUVSetMap &map); void bind_uvsets(MayaFileToUVSetMap &map);
private: private:
void calculate_pairings(); void calculate_pairings();
void try_pair(MayaShaderColorDef *map1, bool try_pair(MayaShaderColorDef *map1,
MayaShaderColorDef *map2, MayaShaderColorDef *map2,
bool perfect); bool perfect);
string get_file_prefix(const string &fn); string get_file_prefix(const string &fn);

View File

@ -624,7 +624,7 @@ find_textures_modern(const string &shadername, MayaShaderColorList &list, MPlug
MPlug inputsPlug = sourceFn.findPlug("inputs"); MPlug inputsPlug = sourceFn.findPlug("inputs");
size_t nlayers = inputsPlug.numElements(); size_t nlayers = inputsPlug.numElements();
for (int layer=0; layer<nlayers; layer++) { for (size_t layer=0; layer<nlayers; layer++) {
MPlug elt = inputsPlug.elementByPhysicalIndex(layer); MPlug elt = inputsPlug.elementByPhysicalIndex(layer);
MPlug color; MPlug color;
MPlug blend; MPlug blend;

View File

@ -60,12 +60,14 @@ public:
BT_replace, BT_replace,
BT_add, BT_add,
BT_blend_color_scale, BT_blend_color_scale,
BT_modulate_glow_map, BT_modulate_glow,
BT_normal_map, BT_modulate_gloss,
BT_gloss_map, BT_normal,
BT_glow_map, BT_normal_height,
BT_normal_gloss_map, BT_gloss,
BT_selector_map, BT_glow,
BT_height,
BT_selector,
}; };
enum ProjectionType { enum ProjectionType {

View File

@ -2805,23 +2805,29 @@ apply_texture_blendtype(EggTexture &tex, const MayaShaderColorDef &color_def) {
case MayaShaderColorDef::BT_blend_color_scale: case MayaShaderColorDef::BT_blend_color_scale:
tex.set_env_type(EggTexture::ET_blend_color_scale); tex.set_env_type(EggTexture::ET_blend_color_scale);
return; return;
case MayaShaderColorDef::BT_modulate_glow_map: case MayaShaderColorDef::BT_modulate_glow:
tex.set_env_type(EggTexture::ET_modulate_glow_map); tex.set_env_type(EggTexture::ET_modulate_glow);
return; return;
case MayaShaderColorDef::BT_normal_map: case MayaShaderColorDef::BT_modulate_gloss:
tex.set_env_type(EggTexture::ET_normal_map); tex.set_env_type(EggTexture::ET_modulate_gloss);
return; return;
case MayaShaderColorDef::BT_gloss_map: case MayaShaderColorDef::BT_normal:
tex.set_env_type(EggTexture::ET_gloss_map); tex.set_env_type(EggTexture::ET_normal);
return; return;
case MayaShaderColorDef::BT_glow_map: case MayaShaderColorDef::BT_normal_height:
tex.set_env_type(EggTexture::ET_glow_map); tex.set_env_type(EggTexture::ET_normal_height);
return; return;
case MayaShaderColorDef::BT_normal_gloss_map: case MayaShaderColorDef::BT_glow:
tex.set_env_type(EggTexture::ET_normal_gloss_map); tex.set_env_type(EggTexture::ET_glow);
return; return;
case MayaShaderColorDef::BT_selector_map: case MayaShaderColorDef::BT_gloss:
tex.set_env_type(EggTexture::ET_selector_map); tex.set_env_type(EggTexture::ET_gloss);
return;
case MayaShaderColorDef::BT_height:
tex.set_env_type(EggTexture::ET_height);
return;
case MayaShaderColorDef::BT_selector:
tex.set_env_type(EggTexture::ET_selector);
return; return;
} }
} }