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;
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();
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) {
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()) ||
562 light_np.node()->is_of_type(Spotlight::get_class_type()), NULL);
564 if (light == NULL || !light->_shadow_caster) {
570 if (light->_sbuffers.count(_gsg) == 0) {
572 tex = _gsg->make_shadow_buffer(light_np, _host);
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";
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) {
887 if (_material->get_local()) {
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";
1059 if (_material->has_specular()) {
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) {
1093 if (_material->get_local()) {
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) {
1117 if (_material->get_local()) {
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) {
1156 if (_material->get_local()) {
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)) {
1212 if (_material->has_ambient()) {
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) {
1223 if (_material->has_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) {
1403 if (_material->has_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();
1467 return DCAST(ShaderAttrib, shattr);
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";
A light shining from infinitely far away in a particular direction, like sunlight.
Mode get_mode() const
Returns the colorBlend mode.
const RenderAttrib * get_attrib_def(int slot) const
Returns the RenderAttrib with the indicated slot index, or the default attrib for that slot if there ...
A basic node of the scene graph or data graph.
int get_rgb_scale() const
See set_rgb_scale().
Mode get_mode() const
Return the mode of this stage.
int get_alpha_scale() const
See set_alpha_scale().
This is our own Panda specialization on the default STL map.
const LColor & get_ambient() const
Returns the ambient color setting, if it has been set.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
bool has_ambient() const
Returns true if the ambient color has been explicitly set for this material, false otherwise...
bool is_off() const
Returns true if the MaterialAttrib is an 'off' MaterialAttrib, indicating that it should disable the ...
bool has_specular() const
Returns true if the specular color has been explicitly set for this material, false otherwise...
Indicates which, if any, material should be applied to geometry.
CombineSource get_combine_alpha_source0() const
Get source0 of combine_alpha_mode.
virtual ~ShaderGenerator()
Destroy a ShaderGenerator.
This controls the enabling of transparency.
CombineMode get_combine_alpha_mode() const
Get combine_alpha_mode.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
int get_num_on_stages() const
Returns the number of stages that are turned on by the attribute.
Material * get_material() const
If the MaterialAttrib is not an 'off' MaterialAttrib, returns the material that is associated...
PandaNode * node() const
Returns the referenced node of the path.
Texture * get_texture() const
Returns the base-level texture that has been set on this particular node, or NULL if no texture has b...
A light source that seems to illuminate all points in space at once.
This functions similarly to a LightAttrib.
CombineOperand get_combine_alpha_operand2() const
Get operand2 of combine_alpha_mode.
A Light Ramp is any unary operator that takes a rendered pixel as input, and adjusts the brightness o...
Type get_color_type() const
Returns the type of color specified by this ColorAttrib.
Mode get_mode(TextureStage *stage) const
Returns the generation mode associated with the named texture stage, or M_off if nothing is associate...
static Material * get_default()
Returns the default material.
TextureStage * get_on_stage(int n) const
Returns the nth stage turned on by the attribute, sorted in render order.
bool has_emission() const
Returns true if the emission color has been explicitly set for this material, false otherwise...
const LColor & get_emission() const
Returns the emission color setting, if it has been set.
bool auto_shader() const
If true, then this ShaderAttrib does not contain an explicit shader - instead, it requests the automa...
LColor get_color() const
return the color for this stage
PN_stdfloat get_level(int n) const
Returns the nth lighting level.
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.
CombineMode get_combine_rgb_mode() const
Get the combine_rgb_mode.
Applies a Fog to the geometry at and below this node.
int get_outputs() const
Returns the AuxBitplaneAttrib output bits.
Modern frame buffers can have 'aux' bitplanes, which are additional bitplanes above and beyond the st...
InternalName * get_texcoord_name() const
See set_texcoord_name.
bool is_off() const
Returns true if the FogAttrib is an 'off' FogAttrib, indicating that it should disable fog...
PandaCompareFunc get_mode() const
Returns the alpha write mode.
ShaderGenerator(GraphicsStateGuardianBase *gsg, GraphicsOutputBase *host)
Create a ShaderGenerator.
PN_stdfloat get_reference_alpha() const
Returns the alpha reference value.
Specifies how atmospheric fog effects are applied to geometry.
CombineOperand get_combine_rgb_operand2() const
Get operand2 of combine_rgb_mode.
CombineSource get_combine_rgb_source0() const
Get source0 of combine_rgb_mode.
CombineOperand get_combine_alpha_operand1() const
Get operand1 of combine_alpha_mode.
The ShaderGenerator is a device that effectively replaces the classic fixed function pipeline with a ...
CombineSource get_combine_alpha_source2() const
Get source2 of combine_alpha_mode.
A light originating from a single point in space, and shining in a particular direction, with a cone-shaped falloff.
const LColor & get_specular() const
Returns the specular 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...
CombineOperand get_combine_alpha_operand0() const
Get operand0 of combine_alpha_mode.
int get_num_on_planes() const
Returns the number of planes that are enabled by the attribute.
Enables or disables writing of pixel to framebuffer based on its alpha value relative to a reference ...
TextureType get_texture_type() const
Returns the overall interpretation of the texture.
int get_num_on_lights() const
Returns the number of lights that are turned on by the attribute.
Defines the way an object appears in the presence of lighting.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
PN_stdfloat get_threshold(int n) const
Returns the nth threshold level.
bool has_stage(TextureStage *stage) const
Returns true if there is a transform associated with the indicated stage, or false otherwise (in whic...
This is the base class for all three-component vectors and points.
Applies a transform matrix to UV's before they are rendered.
bool has_diffuse() const
Returns true if the diffuse color has been explicitly set for this material, false otherwise...
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
Mode get_mode() const
Returns the transparency mode.
LightRampMode get_mode() const
Returns the LightRampAttrib mode.
This specifies how colors are blended into the frame buffer, for special effects. ...
CombineOperand get_combine_rgb_operand1() const
Get operand1 of combine_rgb_mode.
bool has_stage(TextureStage *stage) const
Returns true if there is a mode associated with the indicated stage, or false otherwise (in which cas...
A derivative of Light and of Camera.
bool get_saved_result() const
Returns the current setting of the saved_result flag.
bool is_empty() const
Returns true if the NodePath contains no nodes.
Indicates what color should be applied to renderable geometry.
An abstract base class for GraphicsOutput, for all the usual reasons.
CombineOperand get_combine_rgb_operand0() const
Get operand0 of combine_rgb_mode.
bool get_local() const
Returns the local viewer flag.
TypeHandle is the identifier used to differentiate C++ class types.
NodePath get_on_light(int n) const
Returns the nth light turned on by the attribute, sorted in render order.
Fog * get_fog() const
If the FogAttrib is not an 'off' FogAttrib, returns the fog that is associated.
Defines the properties of a named stage of the multitexture pipeline.
Computes texture coordinates for geometry automatically based on vertex position and/or normal...
const LColor & get_diffuse() const
Returns the diffuse color setting, if it has been set.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
A light originating from a single point in space, and shining in all directions.
bool uses_primary_color() const
Returns true if the TextureStage makes use of the CS_primary_color combine source.
CombineSource get_combine_rgb_source2() const
Get source2 of combine_rgb_mode.
CombineSource get_combine_rgb_source1() const
Get source1 of combine_rgb_mode.
Indicates which set of lights should be considered "on" to illuminate geometry at this level and belo...
bool uses_last_saved_result() const
Returns true if the TextureStage makes use of the CS_primary_color combine source.
CombineSource get_combine_alpha_source1() const
Get source1 of combine_alpha_mode.