19 #include "shaderGenerator.h" 20 #include "renderState.h" 21 #include "shaderAttrib.h" 22 #include "auxBitplaneAttrib.h" 23 #include "alphaTestAttrib.h" 24 #include "colorBlendAttrib.h" 25 #include "transparencyAttrib.h" 26 #include "textureAttrib.h" 27 #include "colorAttrib.h" 28 #include "lightAttrib.h" 29 #include "materialAttrib.h" 30 #include "lightRampAttrib.h" 31 #include "texMatrixAttrib.h" 32 #include "texGenAttrib.h" 33 #include "colorScaleAttrib.h" 34 #include "clipPlaneAttrib.h" 35 #include "fogAttrib.h" 37 #include "ambientLight.h" 38 #include "directionalLight.h" 39 #include "pointLight.h" 40 #include "spotlight.h" 41 #include "lightLensNode.h" 43 #include "config_pgraphnodes.h" 57 _gsg(gsg), _host(host) {
76 void ShaderGenerator::
77 reset_register_allocator() {
89 const char *ShaderGenerator::
91 switch (_vtregs_used) {
92 case 0: _vtregs_used += 1;
return "TEXCOORD0";
93 case 1: _vtregs_used += 1;
return "TEXCOORD1";
94 case 2: _vtregs_used += 1;
return "TEXCOORD2";
95 case 3: _vtregs_used += 1;
return "TEXCOORD3";
96 case 4: _vtregs_used += 1;
return "TEXCOORD4";
97 case 5: _vtregs_used += 1;
return "TEXCOORD5";
98 case 6: _vtregs_used += 1;
return "TEXCOORD6";
99 case 7: _vtregs_used += 1;
return "TEXCOORD7";
101 switch (_vcregs_used) {
102 case 0: _vcregs_used += 1;
return "COLOR0";
103 case 1: _vcregs_used += 1;
return "COLOR1";
107 switch (_vtregs_used) {
108 case 8: _vtregs_used += 1;
return "TEXCOORD8";
109 case 9: _vtregs_used += 1;
return "TEXCOORD9";
110 case 10: _vtregs_used += 1;
return "TEXCOORD10";
111 case 11: _vtregs_used += 1;
return "TEXCOORD11";
112 case 12: _vtregs_used += 1;
return "TEXCOORD12";
113 case 13: _vtregs_used += 1;
return "TEXCOORD13";
114 case 14: _vtregs_used += 1;
return "TEXCOORD14";
115 case 15: _vtregs_used += 1;
return "TEXCOORD15";
125 const char *ShaderGenerator::
127 switch (_ftregs_used) {
128 case 0: _ftregs_used += 1;
return "TEXCOORD0";
129 case 1: _ftregs_used += 1;
return "TEXCOORD1";
130 case 2: _ftregs_used += 1;
return "TEXCOORD2";
131 case 3: _ftregs_used += 1;
return "TEXCOORD3";
132 case 4: _ftregs_used += 1;
return "TEXCOORD4";
133 case 5: _ftregs_used += 1;
return "TEXCOORD5";
134 case 6: _ftregs_used += 1;
return "TEXCOORD6";
135 case 7: _ftregs_used += 1;
return "TEXCOORD7";
145 switch (_ftregs_used) {
146 case 8: _ftregs_used += 1;
return "TEXCOORD8";
147 case 9: _ftregs_used += 1;
return "TEXCOORD9";
148 case 10: _ftregs_used += 1;
return "TEXCOORD10";
149 case 11: _ftregs_used += 1;
return "TEXCOORD11";
150 case 12: _ftregs_used += 1;
return "TEXCOORD12";
151 case 13: _ftregs_used += 1;
return "TEXCOORD13";
152 case 14: _ftregs_used += 1;
return "TEXCOORD14";
153 case 15: _ftregs_used += 1;
return "TEXCOORD15";
165 void ShaderGenerator::
177 if ((alpha_test->
get_mode() != RenderAttrib::M_none)&&
178 (alpha_test->
get_mode() != RenderAttrib::M_always)) {
179 _have_alpha_test =
true;
182 if (color_blend->
get_mode() != ColorBlendAttrib::M_none) {
183 _have_alpha_blend =
true;
186 if ((transparency->
get_mode() == TransparencyAttrib::M_alpha)||
187 (transparency->
get_mode() == TransparencyAttrib::M_dual)) {
188 _have_alpha_blend =
true;
193 if (outputs & AuxBitplaneAttrib::ABO_glow) {
194 if (_have_alpha_blend) {
195 _calc_primary_alpha =
true;
196 _out_primary_glow =
false;
197 _disable_alpha_write =
true;
198 }
else if (_have_alpha_test) {
199 _calc_primary_alpha =
true;
200 _out_primary_glow =
true;
201 _subsume_alpha_test =
true;
203 _calc_primary_alpha =
false;
204 _out_primary_glow =
true;
207 if (_have_alpha_blend || _have_alpha_test) {
208 _calc_primary_alpha =
true;
214 _out_aux_normal = (outputs & AuxBitplaneAttrib::ABO_aux_normal) ?
true:
false;
215 _out_aux_glow = (outputs & AuxBitplaneAttrib::ABO_aux_glow) ?
true:
false;
216 _out_aux_any = (_out_aux_normal || _out_aux_glow);
218 if (_out_aux_normal) {
219 _need_eye_normal =
true;
231 _vertex_colors =
true;
244 nassertv(light_obj != (
PandaNode *)NULL);
246 if (light_obj->get_type() == AmbientLight::get_class_type()) {
247 _alights_np.push_back(light);
250 else if (light_obj->get_type() == DirectionalLight::get_class_type()) {
251 _dlights_np.push_back(light);
257 else if (light_obj->get_type() == PointLight::get_class_type()) {
258 _plights_np.push_back(light);
261 else if (light_obj->get_type() == Spotlight::get_class_type()) {
262 _slights_np.push_back(light);
263 _slights.push_back((
Spotlight*)light_obj);
274 for (
int i=0; i<_num_textures; i++) {
276 TextureStage::Mode mode = stage->
get_mode();
277 if ((mode == TextureStage::M_normal)||
278 (mode == TextureStage::M_normal_height)||
279 (mode == TextureStage::M_normal_gloss)) {
280 _map_index_normal = i;
282 if ((mode == TextureStage::M_height)||(mode == TextureStage::M_normal_height)) {
283 _map_index_height = i;
285 if ((mode == TextureStage::M_glow)||(mode == TextureStage::M_modulate_glow)) {
288 if ((mode == TextureStage::M_gloss)||
289 (mode == TextureStage::M_modulate_gloss)||
290 (mode == TextureStage::M_normal_gloss)) {
291 _map_index_gloss = i;
293 if (mode == TextureStage::M_height) {
294 _map_height_in_alpha =
false;
296 if (mode == TextureStage::M_normal_height) {
297 _map_height_in_alpha =
true;
299 if (tex_gen->has_stage(stage)) {
300 switch (tex_gen->get_mode(stage)) {
301 case TexGenAttrib::M_world_position:
302 _need_world_position =
true;
304 case TexGenAttrib::M_world_normal:
305 _need_world_normal =
true;
307 case TexGenAttrib::M_eye_position:
308 _need_eye_position =
true;
310 case TexGenAttrib::M_eye_normal:
311 _need_eye_normal =
true;
323 _need_eye_normal =
true;
330 if (!material->
is_off()) {
338 if (_lighting && (_alights.size() > 0)) {
341 if ((a[0]!=0.0)||(a[1]!=0.0)||(a[2]!=0.0)) {
342 _have_ambient =
true;
345 _have_ambient =
true;
349 if (_lighting && (_dlights.size() + _plights.size() + _slights.size())) {
352 if ((d[0]!=0.0)||(d[1]!=0.0)||(d[2]!=0.0)) {
353 _have_diffuse =
true;
356 _have_diffuse =
true;
362 if ((e[0]!=0.0)||(e[1]!=0.0)||(e[2]!=0.0)) {
363 _have_emission =
true;
367 if (_lighting && (_dlights.size() + _plights.size() + _slights.size())) {
370 if ((s[0]!=0.0)||(s[1]!=0.0)||(s[2]!=0.0)) {
371 _have_specular =
true;
373 }
else if (_map_index_gloss >= 0) {
374 _have_specular =
true;
377 if (_plights.size() + _slights.size() > 0) {
378 _need_eye_position =
true;
380 }
else if (_have_specular && _material->
get_local()) {
381 _need_eye_position =
true;
387 if (_have_ambient && _have_diffuse) {
392 _separate_ambient_diffuse =
true;
396 _separate_ambient_diffuse =
true;
398 _separate_ambient_diffuse =
false;
405 (light_ramp->
get_mode() != LightRampAttrib::LRT_identity)) {
406 _separate_ambient_diffuse =
true;
412 _use_shadow_filter = _gsg->get_supports_shadow_filter();
416 _need_material_props =
426 if (_num_clip_planes > 0) {
427 _need_world_position =
true;
432 _auto_normal_on = shader_attrib->auto_normal_on();
433 _auto_glow_on = shader_attrib->auto_glow_on();
434 _auto_gloss_on = shader_attrib->auto_gloss_on();
435 _auto_ramp_on = shader_attrib->auto_ramp_on();
436 _auto_shadow_on = shader_attrib->auto_shadow_on();
440 const FogAttrib *fog = DCAST(
FogAttrib, rs->get_attrib_def(FogAttrib::get_class_slot()));
453 void ShaderGenerator::
455 _vertex_colors =
false;
456 _flat_colors =
false;
460 _have_ambient =
false;
461 _have_diffuse =
false;
462 _have_emission =
false;
463 _have_specular =
false;
464 _separate_ambient_diffuse =
false;
465 _map_index_normal = -1;
466 _map_index_glow = -1;
467 _map_index_gloss = -1;
468 _map_index_height = -1;
469 _map_height_in_alpha =
false;
470 _calc_primary_alpha =
false;
471 _have_alpha_test =
false;
472 _have_alpha_blend =
false;
473 _subsume_alpha_test =
false;
474 _disable_alpha_write =
false;
475 _num_clip_planes = 0;
476 _use_shadow_filter =
false;
477 _out_primary_glow =
false;
478 _out_aux_normal =
false;
479 _out_aux_glow =
false;
480 _out_aux_any =
false;
482 _need_material_props =
false;
483 _need_world_position =
false;
484 _need_world_normal =
false;
485 _need_eye_position =
false;
486 _need_eye_normal =
false;
487 _auto_normal_on =
false;
488 _auto_glow_on =
false;
489 _auto_gloss_on =
false;
490 _auto_ramp_on =
false;
491 _auto_shadow_on =
false;
511 create_shader_attrib(
const string &txt) {
512 PT(
Shader) shader = Shader::make(txt, Shader::SL_Cg);
514 shattr = DCAST(
ShaderAttrib, shattr)->set_shader(shader);
516 for (
int i=0; i < (int)_alights.size(); i++) {
517 shattr = DCAST(
ShaderAttrib, shattr)->set_shader_input(InternalName::make(
"alight", i), _alights_np[i]);
519 for (
int i=0; i < (int)_dlights.size(); i++) {
520 shattr = DCAST(
ShaderAttrib, shattr)->set_shader_input(InternalName::make(
"dlight", i), _dlights_np[i]);
521 if (_shadows && _dlights[i]->_shadow_caster) {
522 PT(
Texture) tex = update_shadow_buffer(_dlights_np[i]);
524 pgraph_cat.error() <<
"Failed to create shadow buffer for DirectionalLight '" << _dlights[i]->get_name() <<
"'!\n";
526 shattr = DCAST(
ShaderAttrib, shattr)->set_shader_input(InternalName::make(
"dlighttex", i), tex);
528 _dlights[i]->clear_shadow_buffers();
531 for (
int i=0; i < (int)_plights.size(); i++) {
532 shattr = DCAST(
ShaderAttrib, shattr)->set_shader_input(InternalName::make(
"plight", i), _plights_np[i]);
534 for (
int i=0; i < (int)_slights.size(); i++) {
535 shattr = DCAST(
ShaderAttrib, shattr)->set_shader_input(InternalName::make(
"slight", i), _slights_np[i]);
536 if (_shadows && _slights[i]->_shadow_caster) {
537 PT(
Texture) tex = update_shadow_buffer(_slights_np[i]);
539 pgraph_cat.error() <<
"Failed to create shadow buffer for Spotlight '" << _slights[i]->get_name() <<
"'!\n";
541 shattr = DCAST(
ShaderAttrib, shattr)->set_shader_input(InternalName::make(
"slighttex", i), tex);
543 _slights[i]->clear_shadow_buffers();
559 update_shadow_buffer(
NodePath light_np) {
561 nassertr(light_np.
node()->
is_of_type(DirectionalLight::get_class_type()) ||
564 if (light == NULL || !light->_shadow_caster) {
570 if (light->_sbuffers.count(_gsg) == 0) {
572 tex = _gsg->make_shadow_buffer(light_np, _host);
575 tex = light->_sbuffers[_gsg]->get_texture();
577 nassertr(tex != NULL, NULL);
617 analyze_renderstate(rs);
618 reset_register_allocator();
620 if (pgraph_cat.is_debug()) {
622 <<
"Generating shader for render state " << *rs <<
"\n";
627 const char *tangent_freg = 0;
628 const char *binormal_freg = 0;
629 string tangent_input;
630 string binormal_input;
634 const char *world_position_freg = 0;
635 const char *world_normal_freg = 0;
636 const char *eye_position_freg = 0;
637 const char *eye_normal_freg = 0;
638 const char *hpos_freg = 0;
640 if (_vertex_colors) {
652 text <<
"/* Generated shader for render state:\n";
656 text <<
"void vshader(\n";
659 for (
int i = 0; i < _num_textures; ++i) {
661 if (!tex_gen->has_stage(stage)) {
664 if (texcoord_fregs.count(texcoord_name) == 0) {
665 const char *freg = alloc_freg();
666 string tcname = texcoord_name->join(
"_");
667 texcoord_fregs[texcoord_name] = freg;
669 text <<
"\t in float4 vtx_" << tcname <<
" : " << alloc_vreg() <<
",\n";
670 text <<
"\t out float4 l_" << tcname <<
" : " << freg <<
",\n";
674 if ((_map_index_normal == i && (_lighting || _out_aux_normal) && _auto_normal_on) || _map_index_height == i) {
676 PT(InternalName) tangent_name = InternalName::get_tangent();
677 PT(InternalName) binormal_name = InternalName::get_binormal();
679 if (texcoord_name != InternalName::get_texcoord()) {
680 tangent_name = tangent_name->append(texcoord_name->get_basename());
681 binormal_name = binormal_name->append(texcoord_name->get_basename());
683 tangent_input = tangent_name->join(
"_");
684 binormal_input = binormal_name->join(
"_");
686 text <<
"\t in float4 vtx_" << tangent_input <<
" : " << alloc_vreg() <<
",\n";
687 text <<
"\t in float4 vtx_" << binormal_input <<
" : " << alloc_vreg() <<
",\n";
689 if (_map_index_normal == i && (_lighting || _out_aux_normal) && _auto_normal_on) {
690 tangent_freg = alloc_freg();
691 binormal_freg = alloc_freg();
692 text <<
"\t out float4 l_tangent : " << tangent_freg <<
",\n";
693 text <<
"\t out float4 l_binormal : " << binormal_freg <<
",\n";
697 if (_vertex_colors) {
698 text <<
"\t in float4 vtx_color : COLOR0,\n";
699 text <<
"\t out float4 l_color : COLOR0,\n";
701 if (_need_world_position || _need_world_normal) {
702 text <<
"\t uniform float4x4 trans_model_to_world,\n";
704 if (_need_world_position) {
705 world_position_freg = alloc_freg();
706 text <<
"\t out float4 l_world_position : " << world_position_freg <<
",\n";
708 if (_need_world_normal) {
709 world_normal_freg = alloc_freg();
710 text <<
"\t out float4 l_world_normal : " << world_normal_freg <<
",\n";
712 if (_need_eye_position) {
713 text <<
"\t uniform float4x4 trans_model_to_view,\n";
714 eye_position_freg = alloc_freg();
715 text <<
"\t out float4 l_eye_position : " << eye_position_freg <<
",\n";
716 }
else if ((_lighting || _out_aux_normal) && (_map_index_normal >= 0 && _auto_normal_on)) {
717 text <<
"\t uniform float4x4 trans_model_to_view,\n";
719 if (_need_eye_normal) {
720 eye_normal_freg = alloc_freg();
721 text <<
"\t uniform float4x4 tpose_view_to_model,\n";
722 text <<
"\t out float4 l_eye_normal : " << eye_normal_freg <<
",\n";
724 if (_map_index_height >= 0 || _need_world_normal || _need_eye_normal) {
725 text <<
"\t in float3 vtx_normal : NORMAL,\n";
727 if (_map_index_height >= 0) {
728 text <<
"\t uniform float4 mspos_view,\n";
729 text <<
"\t out float3 l_eyevec,\n";
732 if (_shadows && _auto_shadow_on) {
733 for (
int i=0; i < (int)_dlights.size(); i++) {
734 if (_dlights[i]->_shadow_caster) {
735 dlightcoord_fregs.push_back(alloc_freg());
736 text <<
"\t uniform float4x4 trans_model_to_clip_of_dlight" << i <<
",\n";
737 text <<
"\t out float4 l_dlightcoord" << i <<
" : " << dlightcoord_fregs[i] <<
",\n";
739 dlightcoord_fregs.push_back(NULL);
742 for (
int i=0; i < (int)_slights.size(); i++) {
743 if (_slights[i]->_shadow_caster) {
744 slightcoord_fregs.push_back(alloc_freg());
745 text <<
"\t uniform float4x4 trans_model_to_clip_of_slight" << i <<
",\n";
746 text <<
"\t out float4 l_slightcoord" << i <<
" : " << slightcoord_fregs[i] <<
",\n";
748 slightcoord_fregs.push_back(NULL);
754 hpos_freg = alloc_freg();
755 text <<
"\t out float4 l_hpos : " << hpos_freg <<
",\n";
757 text <<
"\t float4 vtx_position : POSITION,\n";
758 text <<
"\t out float4 l_position : POSITION,\n";
759 text <<
"\t uniform float4x4 mat_modelproj\n";
762 text <<
"\t l_position = mul(mat_modelproj, vtx_position);\n";
764 text <<
"\t l_hpos = l_position;\n";
766 if (_need_world_position) {
767 text <<
"\t l_world_position = mul(trans_model_to_world, vtx_position);\n";
769 if (_need_world_normal) {
770 text <<
"\t l_world_normal = mul(trans_model_to_world, float4(vtx_normal, 0));\n";
772 if (_need_eye_position) {
773 text <<
"\t l_eye_position = mul(trans_model_to_view, vtx_position);\n";
775 if (_need_eye_normal) {
776 text <<
"\t l_eye_normal.xyz = mul((float3x3)tpose_view_to_model, vtx_normal);\n";
777 text <<
"\t l_eye_normal.w = 0;\n";
780 for (it = texcoord_fregs.begin(); it != texcoord_fregs.end(); ++it) {
782 string tcname = it->first->join(
"_");
783 text <<
"\t l_" << tcname <<
" = vtx_" << tcname <<
";\n";
785 if (_vertex_colors) {
786 text <<
"\t l_color = vtx_color;\n";
788 if ((_lighting || _out_aux_normal) && (_map_index_normal >= 0 && _auto_normal_on)) {
789 text <<
"\t l_tangent.xyz = normalize(mul((float3x3)trans_model_to_view, vtx_" << tangent_input <<
".xyz));\n";
790 text <<
"\t l_tangent.w = 0;\n";
791 text <<
"\t l_binormal.xyz = normalize(mul((float3x3)trans_model_to_view, -vtx_" << binormal_input <<
".xyz));\n";
792 text <<
"\t l_binormal.w = 0;\n";
794 if (_shadows && _auto_shadow_on) {
795 text <<
"\t float4x4 biasmat = {0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.0f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f};\n";
796 for (
int i=0; i < (int)_dlights.size(); i++) {
797 if (_dlights[i]->_shadow_caster) {
798 text <<
"\t l_dlightcoord" << i <<
" = mul(biasmat, mul(trans_model_to_clip_of_dlight" << i <<
", vtx_position));\n";
801 for (
int i=0; i < (int)_slights.size(); i++) {
802 if (_slights[i]->_shadow_caster) {
803 text <<
"\t l_slightcoord" << i <<
" = mul(biasmat, mul(trans_model_to_clip_of_slight" << i <<
", vtx_position));\n";
807 if (_map_index_height >= 0) {
808 text <<
"\t float3 eyedir = mspos_view.xyz - vtx_position.xyz;\n";
809 text <<
"\t l_eyevec.x = dot(vtx_" << tangent_input <<
".xyz, eyedir);\n";
810 text <<
"\t l_eyevec.y = dot(vtx_" << binormal_input <<
".xyz, eyedir);\n";
811 text <<
"\t l_eyevec.z = dot(vtx_normal, eyedir);\n";
812 text <<
"\t l_eyevec = normalize(l_eyevec);\n";
818 text <<
"void fshader(\n";
820 text <<
"\t in float4 l_hpos : " << hpos_freg <<
",\n";
821 text <<
"\t in uniform float4 attr_fog,\n";
822 text <<
"\t in uniform float4 attr_fogcolor,\n";
824 if (_need_world_position) {
825 text <<
"\t in float4 l_world_position : " << world_position_freg <<
",\n";
827 if (_need_world_normal) {
828 text <<
"\t in float4 l_world_normal : " << world_normal_freg <<
",\n";
830 if (_need_eye_position) {
831 text <<
"\t in float4 l_eye_position : " << eye_position_freg <<
",\n";
833 if (_need_eye_normal) {
834 text <<
"\t in float4 l_eye_normal : " << eye_normal_freg <<
",\n";
836 for (it = texcoord_fregs.begin(); it != texcoord_fregs.end(); ++it) {
837 text <<
"\t in float4 l_" << it->first->join(
"_") <<
" : " << it->second <<
",\n";
840 for (
int i=0; i<_num_textures; i++) {
843 nassertr(tex != NULL, NULL);
844 text <<
"\t uniform sampler" << texture_type_as_string(tex->
get_texture_type()) <<
" tex_" << i <<
",\n";
845 if (tex_matrix->has_stage(stage)) {
846 text <<
"\t uniform float4x4 texmat_" << i <<
",\n";
849 if ((_lighting || _out_aux_normal) && (_map_index_normal >= 0 && _auto_normal_on)) {
850 text <<
"\t in float3 l_tangent : " << tangent_freg <<
",\n";
851 text <<
"\t in float3 l_binormal : " << binormal_freg <<
",\n";
854 for (
int i=0; i < (int)_alights.size(); i++) {
855 text <<
"\t uniform float4 alight_alight" << i <<
",\n";
857 for (
int i=0; i < (int)_dlights.size(); i++) {
858 text <<
"\t uniform float4x4 dlight_dlight" << i <<
"_rel_view,\n";
859 if (_shadows && _dlights[i]->_shadow_caster && _auto_shadow_on) {
860 if (_use_shadow_filter) {
861 text <<
"\t uniform sampler2DShadow k_dlighttex" << i <<
",\n";
863 text <<
"\t uniform sampler2D k_dlighttex" << i <<
",\n";
865 text <<
"\t in float4 l_dlightcoord" << i <<
" : " << dlightcoord_fregs[i] <<
",\n";
868 for (
int i=0; i < (int)_plights.size(); i++) {
869 text <<
"\t uniform float4x4 plight_plight" << i <<
"_rel_view,\n";
871 for (
int i=0; i < (int)_slights.size(); i++) {
872 text <<
"\t uniform float4x4 slight_slight" << i <<
"_rel_view,\n";
873 text <<
"\t uniform float4 satten_slight" << i <<
",\n";
874 if (_shadows && _slights[i]->_shadow_caster && _auto_shadow_on) {
875 if (_use_shadow_filter) {
876 text <<
"\t uniform sampler2DShadow k_slighttex" << i <<
",\n";
878 text <<
"\t uniform sampler2D k_slighttex" << i <<
",\n";
880 text <<
"\t in float4 l_slightcoord" << i <<
" : " << slightcoord_fregs[i] <<
",\n";
883 if (_need_material_props) {
884 text <<
"\t uniform float4x4 attr_material,\n";
886 if (_have_specular) {
888 text <<
"\t uniform float4 mspos_view,\n";
890 text <<
"\t uniform float4 row1_view_to_model,\n";
894 if (_map_index_height >= 0) {
895 text <<
"\t float3 l_eyevec,\n";
898 text <<
"\t out float4 o_aux : COLOR1,\n";
900 text <<
"\t out float4 o_color : COLOR0,\n";
901 if (_vertex_colors) {
902 text <<
"\t in float4 l_color : COLOR0,\n";
904 text <<
"\t uniform float4 attr_color,\n";
906 for (
int i=0; i<_num_clip_planes; ++i) {
907 text <<
"\t uniform float4 clipplane_" << i <<
",\n";
909 text <<
"\t uniform float4 attr_colorscale\n";
912 for (
int i=0; i<_num_clip_planes; ++i) {
913 text <<
"\t if (l_world_position.x * clipplane_" << i <<
".x + l_world_position.y ";
914 text <<
"* clipplane_" << i <<
".y + l_world_position.z * clipplane_" << i <<
".z + clipplane_" << i <<
".w <= 0) {\n";
915 text <<
"\t discard;\n";
918 text <<
"\t float4 result;\n";
920 text <<
"\t o_aux = float4(0, 0, 0, 0);\n";
923 for (
int i=0; i<_num_textures; i++) {
925 if (tex_gen != NULL && tex_gen->has_stage(stage)) {
926 switch (tex_gen->get_mode(stage)) {
927 case TexGenAttrib::M_world_position:
928 text <<
"\t float4 texcoord" << i <<
" = l_world_position;\n";
930 case TexGenAttrib::M_world_normal:
931 text <<
"\t float4 texcoord" << i <<
" = l_world_normal;\n";
933 case TexGenAttrib::M_eye_position:
934 text <<
"\t float4 texcoord" << i <<
" = l_eye_position;\n";
936 case TexGenAttrib::M_eye_normal:
937 text <<
"\t float4 texcoord" << i <<
" = l_eye_normal;\n";
938 text <<
"\t texcoord" << i <<
".w = 1.0f;\n";
941 pgraph_cat.error() <<
"Unsupported TexGenAttrib mode\n";
942 text <<
"\t float4 texcoord" << i <<
" = float4(0, 0, 0, 0);\n";
947 text <<
"\t float4 texcoord" << i <<
" = l_" << texcoord_name->join(
"_") <<
";\n";
949 if (tex_matrix != NULL && tex_matrix->has_stage(stage)) {
950 text <<
"\t texcoord" << i <<
" = mul(texmat_" << i <<
", texcoord" << i <<
");\n";
951 text <<
"\t texcoord" << i <<
".xyz /= texcoord" << i <<
".w;\n";
954 text <<
"\t // Fetch all textures.\n";
955 if (_map_index_height >= 0 && parallax_mapping_samples > 0) {
957 nassertr(tex != NULL, NULL);
958 text <<
"\t float4 tex" << _map_index_height <<
" = tex" << texture_type_as_string(tex->
get_texture_type());
959 text <<
"(tex_" << _map_index_height <<
", texcoord" << _map_index_height <<
".";
961 case Texture::TT_cube_map:
962 case Texture::TT_3d_texture:
963 case Texture::TT_2d_texture_array:
966 case Texture::TT_2d_texture:
969 case Texture::TT_1d_texture:
975 text <<
");\n\t float3 parallax_offset = l_eyevec.xyz * (tex" << _map_index_height;
976 if (_map_height_in_alpha) {
981 text <<
" * 2.0 - 1.0) * " << parallax_mapping_scale <<
";\n";
983 for (
int i=0; i<parallax_mapping_samples-1; i++) {
984 text <<
"\t parallax_offset = l_eyevec.xyz * (parallax_offset + (tex" << _map_index_height;
985 if (_map_height_in_alpha) {
990 text <<
" * 2.0 - 1.0)) * " << 0.5 * parallax_mapping_scale <<
";\n";
993 for (
int i=0; i<_num_textures; i++) {
994 if (i != _map_index_height) {
996 nassertr(tex != NULL, NULL);
998 if (_map_index_height >= 0 && parallax_mapping_samples > 0) {
999 text <<
"\t texcoord" << i <<
".xyz -= parallax_offset;\n";
1001 text <<
"\t float4 tex" << i <<
" = tex" << texture_type_as_string(tex->
get_texture_type());
1002 text <<
"(tex_" << i <<
", texcoord" << i <<
".";
1004 case Texture::TT_cube_map:
1005 case Texture::TT_3d_texture:
1006 case Texture::TT_2d_texture_array:
1009 case Texture::TT_2d_texture:
1012 case Texture::TT_1d_texture:
1021 if (_lighting || _out_aux_normal) {
1022 if (_map_index_normal >= 0 && _auto_normal_on) {
1023 text <<
"\t // Translate tangent-space normal in map to view-space.\n";
1024 text <<
"\t float3 tsnormal = ((float3)tex" << _map_index_normal <<
" * 2) - 1;\n";
1025 text <<
"\t l_eye_normal.xyz *= tsnormal.z;\n";
1026 text <<
"\t l_eye_normal.xyz += l_tangent * tsnormal.x;\n";
1027 text <<
"\t l_eye_normal.xyz += l_binormal * tsnormal.y;\n";
1030 if (_need_eye_normal) {
1031 text <<
"\t // Correct the surface normal for interpolation effects\n";
1032 text <<
"\t l_eye_normal.xyz = normalize(l_eye_normal.xyz);\n";
1034 if (_out_aux_normal) {
1035 text <<
"\t // Output the camera-space surface normal\n";
1036 text <<
"\t o_aux.rgb = (l_eye_normal.xyz*0.5) + float3(0.5,0.5,0.5);\n";
1039 text <<
"\t // Begin view-space light calculations\n";
1040 text <<
"\t float ldist,lattenv,langle;\n";
1041 text <<
"\t float4 lcolor,lspec,lvec,lpoint,latten,ldir,leye,lhalf;\n";
1042 if (_shadows && _auto_shadow_on) {
1043 text <<
"\t float lshad;\n";
1045 if (_separate_ambient_diffuse) {
1046 if (_have_ambient) {
1047 text <<
"\t float4 tot_ambient = float4(0,0,0,0);\n";
1049 if (_have_diffuse) {
1050 text <<
"\t float4 tot_diffuse = float4(0,0,0,0);\n";
1053 if (_have_ambient || _have_diffuse) {
1054 text <<
"\t float4 tot_diffuse = float4(0,0,0,0);\n";
1057 if (_have_specular) {
1058 text <<
"\t float4 tot_specular = float4(0,0,0,0);\n";
1060 text <<
"\t float shininess = attr_material[3].w;\n";
1062 text <<
"\t float shininess = 50; // no shininess specified, using default\n";
1065 for (
int i=0; i < (int)_alights.size(); i++) {
1066 text <<
"\t // Ambient Light " << i <<
"\n";
1067 text <<
"\t lcolor = alight_alight" << i <<
";\n";
1068 if (_separate_ambient_diffuse && _have_ambient) {
1069 text <<
"\t tot_ambient += lcolor;\n";
1070 }
else if(_have_diffuse) {
1071 text <<
"\t tot_diffuse += lcolor;\n";
1074 for (
int i=0; i < (int)_dlights.size(); i++) {
1075 text <<
"\t // Directional Light " << i <<
"\n";
1076 text <<
"\t lcolor = dlight_dlight" << i <<
"_rel_view[0];\n";
1077 text <<
"\t lspec = dlight_dlight" << i <<
"_rel_view[1];\n";
1078 text <<
"\t lvec = dlight_dlight" << i <<
"_rel_view[2];\n";
1079 text <<
"\t lcolor *= saturate(dot(l_eye_normal.xyz, lvec.xyz));\n";
1080 if (_shadows && _dlights[i]->_shadow_caster && _auto_shadow_on) {
1081 if (_use_shadow_filter) {
1082 text <<
"\t lshad = shadow2DProj(k_dlighttex" << i <<
", l_dlightcoord" << i <<
").r;\n";
1084 text <<
"\t lshad = tex2Dproj(k_dlighttex" << i <<
", l_dlightcoord" << i <<
").r > l_dlightcoord" << i <<
".z / l_dlightcoord" << i <<
".w;\n";
1086 text <<
"\t lcolor *= lshad;\n";
1087 text <<
"\t lspec *= lshad;\n";
1089 if (_have_diffuse) {
1090 text <<
"\t tot_diffuse += lcolor;\n";
1092 if (_have_specular) {
1094 text <<
"\t lhalf = normalize(lvec - normalize(l_eye_position));\n";
1096 text <<
"\t lhalf = dlight_dlight" << i <<
"_rel_view[3];\n";
1098 text <<
"\t lspec *= pow(saturate(dot(l_eye_normal.xyz, lhalf.xyz)), shininess);\n";
1099 text <<
"\t tot_specular += lspec;\n";
1102 for (
int i=0; i < (int)_plights.size(); i++) {
1103 text <<
"\t // Point Light " << i <<
"\n";
1104 text <<
"\t lcolor = plight_plight" << i <<
"_rel_view[0];\n";
1105 text <<
"\t lspec = plight_plight" << i <<
"_rel_view[1];\n";
1106 text <<
"\t lpoint = plight_plight" << i <<
"_rel_view[2];\n";
1107 text <<
"\t latten = plight_plight" << i <<
"_rel_view[3];\n";
1108 text <<
"\t lvec = lpoint - l_eye_position;\n";
1109 text <<
"\t ldist = length(float3(lvec));\n";
1110 text <<
"\t lvec /= ldist;\n";
1111 text <<
"\t lattenv = 1/(latten.x + latten.y*ldist + latten.z*ldist*ldist);\n";
1112 text <<
"\t lcolor *= lattenv * saturate(dot(l_eye_normal.xyz, lvec.xyz));\n";
1113 if (_have_diffuse) {
1114 text <<
"\t tot_diffuse += lcolor;\n";
1116 if (_have_specular) {
1118 text <<
"\t lhalf = normalize(lvec - normalize(l_eye_position));\n";
1120 text <<
"\t lhalf = normalize(lvec - float4(0, 1, 0, 0));\n";
1122 text <<
"\t lspec *= lattenv;\n";
1123 text <<
"\t lspec *= pow(saturate(dot(l_eye_normal.xyz, lhalf.xyz)), shininess);\n";
1124 text <<
"\t tot_specular += lspec;\n";
1127 for (
int i=0; i < (int)_slights.size(); i++) {
1128 text <<
"\t // Spot Light " << i <<
"\n";
1129 text <<
"\t lcolor = slight_slight" << i <<
"_rel_view[0];\n";
1130 text <<
"\t lspec = slight_slight" << i <<
"_rel_view[1];\n";
1131 text <<
"\t lpoint = slight_slight" << i <<
"_rel_view[2];\n";
1132 text <<
"\t ldir = slight_slight" << i <<
"_rel_view[3];\n";
1133 text <<
"\t latten = satten_slight" << i <<
";\n";
1134 text <<
"\t lvec = lpoint - l_eye_position;\n";
1135 text <<
"\t ldist = length(float3(lvec));\n";
1136 text <<
"\t lvec /= ldist;\n";
1137 text <<
"\t langle = saturate(dot(ldir.xyz, lvec.xyz));\n";
1138 text <<
"\t lattenv = 1/(latten.x + latten.y*ldist + latten.z*ldist*ldist);\n";
1139 text <<
"\t lattenv *= pow(langle, latten.w);\n";
1140 text <<
"\t if (langle < ldir.w) lattenv = 0;\n";
1141 text <<
"\t lcolor *= lattenv * saturate(dot(l_eye_normal.xyz, lvec.xyz));\n";
1142 if (_shadows && _slights[i]->_shadow_caster && _auto_shadow_on) {
1143 if (_use_shadow_filter) {
1144 text <<
"\t lshad = shadow2DProj(k_slighttex" << i <<
", l_slightcoord" << i <<
").r;\n";
1146 text <<
"\t lshad = tex2Dproj(k_slighttex" << i <<
", l_slightcoord" << i <<
").r > l_slightcoord" << i <<
".z / l_slightcoord" << i <<
".w;\n";
1148 text <<
"\t lcolor *= lshad;\n";
1149 text <<
"\t lspec *= lshad;\n";
1152 if (_have_diffuse) {
1153 text <<
"\t tot_diffuse += lcolor;\n";
1155 if (_have_specular) {
1157 text <<
"\t lhalf = normalize(lvec - normalize(l_eye_position));\n";
1159 text <<
"\t lhalf = normalize(lvec - float4(0,1,0,0));\n";
1161 text <<
"\t lspec *= lattenv;\n";
1162 text <<
"\t lspec *= pow(saturate(dot(l_eye_normal.xyz, lhalf.xyz)), shininess);\n";
1163 text <<
"\t tot_specular += lspec;\n";
1167 if (_auto_ramp_on && _have_diffuse) {
1169 case LightRampAttrib::LRT_single_threshold:
1172 PN_stdfloat l0 = light_ramp->
get_level(0);
1173 text <<
"\t // Single-threshold light ramp\n";
1174 text <<
"\t float lr_in = dot(tot_diffuse.rgb, float3(0.33,0.34,0.33));\n";
1175 text <<
"\t float lr_scale = (lr_in < " << t <<
") ? 0.0 : (" << l0 <<
"/lr_in);\n";
1176 text <<
"\t tot_diffuse = tot_diffuse * lr_scale;\n";
1179 case LightRampAttrib::LRT_double_threshold:
1183 PN_stdfloat l0 = light_ramp->
get_level(0);
1184 PN_stdfloat l1 = light_ramp->
get_level(1);
1185 text <<
"\t // Double-threshold light ramp\n";
1186 text <<
"\t float lr_in = dot(tot_diffuse.rgb, float3(0.33,0.34,0.33));\n";
1187 text <<
"\t float lr_out = 0.0;\n";
1188 text <<
"\t if (lr_in > " << t0 <<
") lr_out=" << l0 <<
";\n";
1189 text <<
"\t if (lr_in > " << t1 <<
") lr_out=" << l1 <<
";\n";
1190 text <<
"\t tot_diffuse = tot_diffuse * (lr_out / lr_in);\n";
1197 text <<
"\t // Begin view-space light summation\n";
1198 if (_have_emission) {
1199 if (_map_index_glow >= 0 && _auto_glow_on) {
1200 text <<
"\t result = attr_material[2] * saturate(2 * (tex" << _map_index_glow <<
".a - 0.5));\n";
1202 text <<
"\t result = attr_material[2];\n";
1205 if (_map_index_glow >= 0 && _auto_glow_on) {
1206 text <<
"\t result = saturate(2 * (tex" << _map_index_glow <<
".a - 0.5));\n";
1208 text <<
"\t result = float4(0,0,0,0);\n";
1211 if ((_have_ambient)&&(_separate_ambient_diffuse)) {
1213 text <<
"\t result += tot_ambient * attr_material[0];\n";
1214 }
else if (_vertex_colors) {
1215 text <<
"\t result += tot_ambient * l_color;\n";
1216 }
else if (_flat_colors) {
1217 text <<
"\t result += tot_ambient * attr_color;\n";
1219 text <<
"\t result += tot_ambient;\n";
1222 if (_have_diffuse) {
1224 text <<
"\t result += tot_diffuse * attr_material[1];\n";
1225 }
else if (_vertex_colors) {
1226 text <<
"\t result += tot_diffuse * l_color;\n";
1227 }
else if (_flat_colors) {
1228 text <<
"\t result += tot_diffuse * attr_color;\n";
1230 text <<
"\t result += tot_diffuse;\n";
1233 if (light_ramp->
get_mode() == LightRampAttrib::LRT_default) {
1234 text <<
"\t result = saturate(result);\n";
1236 text <<
"\t // End view-space light calculations\n";
1240 if (_calc_primary_alpha) {
1241 if (_vertex_colors) {
1242 text <<
"\t result.a = l_color.a;\n";
1243 }
else if (_flat_colors) {
1244 text <<
"\t result.a = attr_color.a;\n";
1246 text <<
"\t result.a = 1;\n";
1250 if (_vertex_colors) {
1251 text <<
"\t result = l_color;\n";
1252 }
else if (_flat_colors) {
1253 text <<
"\t result = attr_color;\n";
1255 text <<
"\t result = float4(1, 1, 1, 1);\n";
1260 bool have_saved_result =
false;
1261 bool have_primary_color =
false;
1262 for (
int i=0; i<_num_textures; i++) {
1264 if (stage->
get_mode() != TextureStage::M_combine)
continue;
1266 text <<
"\t float4 primary_color = result;\n";
1267 have_primary_color =
true;
1270 text <<
"\t float4 last_saved_result = result;\n";
1271 have_saved_result =
true;
1276 for (
int i=0; i<_num_textures; i++) {
1279 case TextureStage::M_modulate: {
1282 if (num_components == 1) {
1283 text <<
"\t result.a *= tex" << i <<
".a;\n";
1284 }
else if (num_components == 3) {
1285 text <<
"\t result.rgb *= tex" << i <<
".rgb;\n";
1287 text <<
"\t result.rgba *= tex" << i <<
".rgba;\n";
1291 case TextureStage::M_modulate_glow:
1292 case TextureStage::M_modulate_gloss:
1300 text <<
"\t result.rgb *= tex" << i <<
";\n";
1302 case TextureStage::M_decal:
1303 text <<
"\t result.rgb = lerp(result, tex" << i <<
", tex" << i <<
".a).rgb;\n";
1305 case TextureStage::M_blend: {
1307 text <<
"\t result.rgb = lerp(result, tex" << i <<
" * float4(" 1308 << c[0] <<
", " << c[1] <<
", " << c[2] <<
", " << c[3] <<
"), tex" << i <<
".r).rgb;\n";
1310 case TextureStage::M_replace:
1311 text <<
"\t result = tex" << i <<
";\n";
1313 case TextureStage::M_add:
1314 text <<
"\t result.rgb += tex" << i <<
".rgb;\n";
1315 if (_calc_primary_alpha) {
1316 text <<
"\t result.a *= tex" << i <<
".a;\n";
1319 case TextureStage::M_combine:
1320 text <<
"\t result.rgb = ";
1324 text <<
"tex" << i <<
".rgb";
1329 text <<
";\n\t result.a = ";
1333 text <<
"tex" << i <<
".a";
1340 case TextureStage::M_blend_color_scale:
1341 text <<
"\t result.rgb = lerp(result, tex" << i <<
" * attr_colorscale, tex" << i <<
".r).rgb;\n";
1347 text <<
"\t last_saved_result = result;\n";
1351 text <<
"\t result *= attr_colorscale;\n";
1353 if (_subsume_alpha_test) {
1355 text <<
"\t // Shader includes alpha test:\n";
1358 case RenderAttrib::M_never:
1359 text <<
"\t discard;\n";
1361 case RenderAttrib::M_less:
1362 text <<
"\t if (result.a >= " << ref <<
") discard;\n";
1364 case RenderAttrib::M_equal:
1365 text <<
"\t if (result.a != " << ref <<
") discard;\n";
1367 case RenderAttrib::M_less_equal:
1368 text <<
"\t if (result.a > " << ref <<
") discard;\n";
1370 case RenderAttrib::M_greater:
1371 text <<
"\t if (result.a <= " << ref <<
") discard;\n";
1373 case RenderAttrib::M_not_equal:
1374 text <<
"\t if (result.a == " << ref <<
") discard;\n";
1376 case RenderAttrib::M_greater_equal:
1377 text <<
"\t if (result.a < " << ref <<
") discard;\n";
1379 case RenderAttrib::M_none:
1380 case RenderAttrib::M_always:
1386 if (_out_primary_glow) {
1387 if (_map_index_glow >= 0 && _auto_glow_on) {
1388 text <<
"\t result.a = tex" << _map_index_glow <<
".a;\n";
1390 text <<
"\t result.a = 0.5;\n";
1393 if (_out_aux_glow) {
1394 if (_map_index_glow >= 0 && _auto_glow_on) {
1395 text <<
"\t o_aux.a = tex" << _map_index_glow <<
".a;\n";
1397 text <<
"\t o_aux.a = 0.5;\n";
1402 if (_have_specular) {
1404 text <<
"\t tot_specular *= attr_material[3];\n";
1406 if (_map_index_gloss >= 0 && _auto_gloss_on) {
1407 text <<
"\t tot_specular *= tex" << _map_index_gloss <<
".a;\n";
1409 text <<
"\t result.rgb = result.rgb + tot_specular.rgb;\n";
1412 if (_auto_ramp_on) {
1415 case LightRampAttrib::LRT_hdr0:
1416 text <<
"\t result.rgb = (result*result*result + result*result + result) / (result*result*result + result*result + result + 1);\n";
1418 case LightRampAttrib::LRT_hdr1:
1419 text <<
"\t result.rgb = (result*result + result) / (result*result + result + 1);\n";
1421 case LightRampAttrib::LRT_hdr2:
1422 text <<
"\t result.rgb = result / (result + 1);\n";
1430 const FogAttrib *fog_attr = DCAST(
FogAttrib, rs->get_attrib_def(FogAttrib::get_class_slot()));
1433 switch (fog->get_mode()) {
1435 text <<
"\t result.rgb = lerp(attr_fogcolor.rgb, result.rgb, saturate((attr_fog.z - l_hpos.z) * attr_fog.w));\n";
1437 case Fog::M_exponential:
1438 text <<
"\t result.rgb = lerp(attr_fogcolor.rgb, result.rgb, saturate(exp2(attr_fog.x * l_hpos.z * -1.442695f)));\n";
1440 case Fog::M_exponential_squared:
1441 text <<
"\t result.rgb = lerp(attr_fogcolor.rgb, result.rgb, saturate(exp2(attr_fog.x * attr_fog.x * l_hpos.z * l_hpos.z * -1.442695f)));\n";
1448 text <<
"\t o_color = result * 1.000001;\n";
1449 if (_subsume_alpha_test) {
1450 text <<
"\t // Shader subsumes normal alpha test.\n";
1452 if (_disable_alpha_write) {
1453 text <<
"\t // Shader disables alpha write.\n";
1458 CPT(
RenderAttrib) shattr = create_shader_attrib(text.str());
1459 if (_subsume_alpha_test) {
1460 shattr = DCAST(
ShaderAttrib, shattr)->set_flag(ShaderAttrib::F_subsume_alpha_test,
true);
1462 if (_disable_alpha_write) {
1463 shattr = DCAST(
ShaderAttrib, shattr)->set_flag(ShaderAttrib::F_disable_alpha_write,
true);
1466 reset_register_allocator();
1475 const string ShaderGenerator::
1476 combine_mode_as_string(CPT(
TextureStage) stage, TextureStage::CombineMode c_mode,
bool alpha,
short texindex) {
1479 case TextureStage::CM_modulate:
1480 text << combine_source_as_string(stage, 0, alpha, alpha, texindex);
1482 text << combine_source_as_string(stage, 1, alpha, alpha, texindex);
1484 case TextureStage::CM_add:
1485 text << combine_source_as_string(stage, 0, alpha, alpha, texindex);
1487 text << combine_source_as_string(stage, 1, alpha, alpha, texindex);
1489 case TextureStage::CM_add_signed:
1490 text << combine_source_as_string(stage, 0, alpha, alpha, texindex);
1492 text << combine_source_as_string(stage, 1, alpha, alpha, texindex);
1496 text <<
" - float3(0.5, 0.5, 0.5)";
1499 case TextureStage::CM_interpolate:
1501 text << combine_source_as_string(stage, 1, alpha, alpha, texindex);
1503 text << combine_source_as_string(stage, 0, alpha, alpha, texindex);
1505 text << combine_source_as_string(stage, 2, alpha,
true, texindex);
1508 case TextureStage::CM_subtract:
1509 text << combine_source_as_string(stage, 0, alpha, alpha, texindex);
1511 text << combine_source_as_string(stage, 1, alpha, alpha, texindex);
1513 case TextureStage::CM_dot3_rgb:
1514 pgraph_cat.error() <<
"TextureStage::CombineMode DOT3_RGB not yet supported in per-pixel mode.\n";
1516 case TextureStage::CM_dot3_rgba:
1517 pgraph_cat.error() <<
"TextureStage::CombineMode DOT3_RGBA not yet supported in per-pixel mode.\n";
1519 case TextureStage::CM_replace:
1521 text << combine_source_as_string(stage, 0, alpha, alpha, texindex);
1532 const string ShaderGenerator::
1533 combine_source_as_string(CPT(
TextureStage) stage,
short num,
bool alpha,
bool single_value,
short texindex) {
1534 TextureStage::CombineSource c_src = TextureStage::CS_undefined;
1535 TextureStage::CombineOperand c_op = TextureStage::CO_undefined;
1568 if (c_op == TextureStage::CO_one_minus_src_color ||
1569 c_op == TextureStage::CO_one_minus_src_alpha) {
1570 csource <<
"1.0f - ";
1573 case TextureStage::CS_texture:
1574 csource <<
"tex" << texindex;
1576 case TextureStage::CS_constant: {
1578 csource <<
"float4(" << c[0] <<
", " << c[1] <<
", " << c[2] <<
", " << c[3] <<
")";
1580 case TextureStage::CS_primary_color:
1581 csource <<
"primary_color";
1583 case TextureStage::CS_previous:
1584 csource <<
"result";
1586 case TextureStage::CS_constant_color_scale:
1587 csource <<
"attr_colorscale";
1589 case TextureStage::CS_last_saved_result:
1590 csource <<
"last_saved_result";
1592 case TextureStage::CS_undefined:
1595 if (c_op == TextureStage::CO_src_color || c_op == TextureStage::CO_one_minus_src_color) {
1604 if (!single_value) {
1606 return "float3(" + csource.str() +
")";
1609 return csource.str();
1618 const string ShaderGenerator::
1619 texture_type_as_string(Texture::TextureType ttype) {
1621 case Texture::TT_1d_texture:
1624 case Texture::TT_2d_texture:
1627 case Texture::TT_3d_texture:
1630 case Texture::TT_cube_map:
1633 case Texture::TT_2d_texture_array:
1637 pgraph_cat.error() <<
"Unsupported texture type!\n";
CombineSource get_combine_alpha_source2() const
Get source2 of combine_alpha_mode.
A light shining from infinitely far away in a particular direction, like sunlight.
Fog * get_fog() const
If the FogAttrib is not an 'off' FogAttrib, returns the fog that is associated.
A basic node of the scene graph or data graph.
Mode get_mode() const
Returns the colorBlend mode.
This is our own Panda specialization on the default STL map.
bool auto_shader() const
If true, then this ShaderAttrib does not contain an explicit shader - instead, it requests the automa...
LightRampMode get_mode() const
Returns the LightRampAttrib mode.
bool get_local() const
Returns the local viewer flag.
Material * get_material() const
If the MaterialAttrib is not an 'off' MaterialAttrib, returns the material that is associated...
This is the base class for a number of render attributes (other than transform) that may be set on sc...
LColor get_color() const
return the color for this stage
CombineOperand get_combine_alpha_operand0() const
Get operand0 of combine_alpha_mode.
int get_rgb_scale() const
See set_rgb_scale().
TextureType get_texture_type() const
Returns the overall interpretation of the texture.
bool is_empty() const
Returns true if the NodePath contains no nodes.
Indicates which, if any, material should be applied to geometry.
bool has_ambient() const
Returns true if the ambient color has been explicitly set for this material, false otherwise...
virtual ~ShaderGenerator()
Destroy a ShaderGenerator.
This controls the enabling of transparency.
PN_stdfloat get_threshold(int n) const
Returns the nth threshold level.
Mode get_mode() const
Returns the transparency mode.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
PandaCompareFunc get_mode() const
Returns the alpha write mode.
int get_outputs() const
Returns the AuxBitplaneAttrib output bits.
A light source that seems to illuminate all points in space at once.
This functions similarly to a LightAttrib.
int get_alpha_scale() const
See set_alpha_scale().
A Light Ramp is any unary operator that takes a rendered pixel as input, and adjusts the brightness o...
Mode get_mode() const
Return the mode of this stage.
CombineOperand get_combine_rgb_operand1() const
Get operand1 of combine_rgb_mode.
static Material * get_default()
Returns the default material.
Type get_color_type() const
Returns the type of color specified by this ColorAttrib.
CombineSource get_combine_rgb_source1() const
Get source1 of combine_rgb_mode.
Indicates the set of TextureStages and their associated Textures that should be applied to (or remove...
This is our own Panda specialization on the default STL vector.
const LColor & get_diffuse() const
Returns the diffuse color setting, if it has been set.
Applies a Fog to the geometry at and below this node.
Modern frame buffers can have 'aux' bitplanes, which are additional bitplanes above and beyond the st...
const LColor & get_ambient() const
Returns the ambient color setting, if it has been set.
Texture * get_on_texture(TextureStage *stage) const
Returns the texture associated with the indicated stage, or NULL if no texture is associated...
bool uses_last_saved_result() const
Returns true if the TextureStage makes use of the CS_primary_color combine source.
int get_num_on_planes() const
Returns the number of planes that are enabled by the attribute.
CombineSource get_combine_alpha_source0() const
Get source0 of combine_alpha_mode.
bool uses_primary_color() const
Returns true if the TextureStage makes use of the CS_primary_color combine source.
ShaderGenerator(GraphicsStateGuardianBase *gsg, GraphicsOutputBase *host)
Create a ShaderGenerator.
CombineSource get_combine_rgb_source2() const
Get source2 of combine_rgb_mode.
Specifies how atmospheric fog effects are applied to geometry.
CombineOperand get_combine_rgb_operand0() const
Get operand0 of combine_rgb_mode.
A light originating from a single point in space, and shining in a particular direction, with a cone-shaped falloff.
bool has_specular() const
Returns true if the specular color has been explicitly set for this material, false otherwise...
TextureStage * get_on_stage(int n) const
Returns the nth stage turned on by the attribute, sorted in render order.
InternalName * get_texcoord_name() const
See set_texcoord_name.
CombineMode get_combine_alpha_mode() const
Get combine_alpha_mode.
Enables or disables writing of pixel to framebuffer based on its alpha value relative to a reference ...
CombineOperand get_combine_alpha_operand1() const
Get operand1 of combine_alpha_mode.
Defines the way an object appears in the presence of lighting.
void ref() const
Explicitly increments the reference count.
PN_stdfloat get_level(int n) const
Returns the nth lighting level.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
int get_num_on_lights() const
Returns the number of lights that are turned on by the attribute.
PN_stdfloat get_reference_alpha() const
Returns the alpha reference value.
This is the base class for all three-component vectors and points.
Applies a transform matrix to UV's before they are rendered.
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
This specifies how colors are blended into the frame buffer, for special effects. ...
CombineMode get_combine_rgb_mode() const
Get the combine_rgb_mode.
PandaNode * node() const
Returns the referenced node of the path.
CombineSource get_combine_rgb_source0() const
Get source0 of combine_rgb_mode.
A derivative of Light and of Camera.
bool is_off() const
Returns true if the MaterialAttrib is an 'off' MaterialAttrib, indicating that it should disable the ...
int get_num_on_stages() const
Returns the number of stages that are turned on by the attribute.
Indicates what color should be applied to renderable geometry.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
CombineOperand get_combine_rgb_operand2() const
Get operand2 of combine_rgb_mode.
CombineSource get_combine_alpha_source1() const
Get source1 of combine_alpha_mode.
CombineOperand get_combine_alpha_operand2() const
Get operand2 of combine_alpha_mode.
An abstract base class for GraphicsOutput, for all the usual reasons.
const LColor & get_emission() const
Returns the emission color setting, if it has been set.
TypeHandle is the identifier used to differentiate C++ class types.
bool has_diffuse() const
Returns true if the diffuse color has been explicitly set for this material, false otherwise...
bool is_off() const
Returns true if the FogAttrib is an 'off' FogAttrib, indicating that it should disable fog...
bool has_emission() const
Returns true if the emission color has been explicitly set for this material, false otherwise...
Defines the properties of a named stage of the multitexture pipeline.
Computes texture coordinates for geometry automatically based on vertex position and/or normal...
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
const LColor & get_specular() const
Returns the specular color setting, if it has been set.
A light originating from a single point in space, and shining in all directions.
Indicates which set of lights should be considered "on" to illuminate geometry at this level and belo...
NodePath get_on_light(int n) const
Returns the nth light turned on by the attribute, sorted in render order.
bool get_saved_result() const
Returns the current setting of the saved_result flag.