Skip to content

Commit f79fbf2

Browse files
committed
ShaderGenerator: big overhaul, don't generate more shaders than needed
1 parent 1b690e5 commit f79fbf2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1104
-1202
lines changed

panda/src/display/graphicsStateGuardian.cxx

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "ambientLight.h"
4545
#include "directionalLight.h"
4646
#include "pointLight.h"
47+
#include "sphereLight.h"
4748
#include "spotlight.h"
4849
#include "textureReloadRequest.h"
4950
#include "shaderAttrib.h"
@@ -1122,6 +1123,28 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
11221123
return &LMatrix4::ident_mat();
11231124
}
11241125
}
1126+
case Shader::SMO_texscale_i: {
1127+
const TexMatrixAttrib *tma;
1128+
const TextureAttrib *ta;
1129+
if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
1130+
index < ta->get_num_on_stages()) {
1131+
LVecBase3 scale = tma->get_transform(ta->get_on_stage(index))->get_scale();
1132+
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,scale[0],scale[1],scale[2],0);
1133+
return &t;
1134+
} else {
1135+
return &LMatrix4::ident_mat();
1136+
}
1137+
}
1138+
case Shader::SMO_texcolor_i: {
1139+
const TextureAttrib *ta;
1140+
if (_target_rs->get_attrib(ta) && index < ta->get_num_on_stages()) {
1141+
TextureStage *ts = ta->get_on_stage(index);
1142+
t.set_row(3, ts->get_color());
1143+
return &t;
1144+
} else {
1145+
return &LMatrix4::zeros_mat();
1146+
}
1147+
}
11251148
case Shader::SMO_tex_is_alpha_i: {
11261149
// This is a hack so we can support both F_alpha and other formats in the
11271150
// default shader, to fix font rendering in GLES2
@@ -1156,9 +1179,14 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
11561179
nassertr(!np.is_empty(), &LMatrix4::zeros_mat());
11571180
const PlaneNode *plane_node;
11581181
DCAST_INTO_R(plane_node, np.node(), &LMatrix4::zeros_mat());
1159-
LPlane p (plane_node->get_plane());
1160-
p.xform(np.get_net_transform()->get_mat()); // World-space
1161-
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,p[0],p[1],p[2],p[3]);
1182+
1183+
// Transform plane to world space
1184+
CPT(TransformState) transform = np.get_net_transform();
1185+
LPlane plane = plane_node->get_plane();
1186+
if (!transform->is_identity()) {
1187+
plane.xform(transform->get_mat());
1188+
}
1189+
t.set_row(3, plane);
11621190
return &t;
11631191
}
11641192
case Shader::SMO_apiview_clipplane_i: {
@@ -1195,7 +1223,6 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
11951223
}
11961224
case Shader::SMO_world_to_view: {
11971225
return &(_scene_setup->get_world_transform()->get_mat());
1198-
break;
11991226
}
12001227
case Shader::SMO_view_to_world: {
12011228
return &(_scene_setup->get_camera_transform()->get_mat());
@@ -1387,6 +1414,62 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
13871414
}
13881415
return fetch_specified_member(NodePath(), name, t);
13891416
}
1417+
case Shader::SMO_light_source_i_packed: {
1418+
// The light matrix contains COLOR, ATTENUATION, POSITION, VIEWVECTOR
1419+
const LightAttrib *target_light;
1420+
_target_rs->get_attrib_def(target_light);
1421+
1422+
// We don't count ambient lights, which would be pretty silly to handle
1423+
// via this mechanism.
1424+
size_t num_lights = target_light->get_num_non_ambient_lights();
1425+
if (index >= 0 && (size_t)index < num_lights) {
1426+
NodePath np = target_light->get_on_light((size_t)index);
1427+
nassertr(!np.is_empty(), &LMatrix4::ident_mat());
1428+
PandaNode *node = np.node();
1429+
Light *light = node->as_light();
1430+
nassertr(light != nullptr, &LMatrix4::zeros_mat());
1431+
t.set_row(0, light->get_color());
1432+
t.set_row(1, light->get_attenuation());
1433+
1434+
LMatrix4 mat = np.get_net_transform()->get_mat() *
1435+
_scene_setup->get_world_transform()->get_mat();
1436+
1437+
if (node->is_of_type(DirectionalLight::get_class_type())) {
1438+
LVecBase3 d = mat.xform_vec(((const DirectionalLight *)node)->get_direction());
1439+
d.normalize();
1440+
t.set_row(2, LVecBase4(d, 0));
1441+
t.set_row(3, LVecBase4(-d, 0));
1442+
1443+
} else if (node->is_of_type(LightLensNode::get_class_type())) {
1444+
const Lens *lens = ((const LightLensNode *)node)->get_lens();
1445+
1446+
LPoint3 p = mat.xform_point(lens->get_nodal_point());
1447+
t.set_row(3, LVecBase4(p));
1448+
1449+
// For shadowed point light we need to store near/far.
1450+
// For spotlight we need to store cutoff angle.
1451+
if (node->is_of_type(Spotlight::get_class_type())) {
1452+
PN_stdfloat cutoff = ccos(deg_2_rad(lens->get_hfov() * 0.5f));
1453+
LVecBase3 d = -(mat.xform_vec(lens->get_view_vector()));
1454+
t.set_cell(1, 3, ((const Spotlight *)node)->get_exponent());
1455+
t.set_row(2, LVecBase4(d, cutoff));
1456+
1457+
} else if (node->is_of_type(PointLight::get_class_type())) {
1458+
t.set_cell(1, 3, lens->get_near());
1459+
t.set_cell(3, 3, lens->get_far());
1460+
1461+
if (node->is_of_type(SphereLight::get_class_type())) {
1462+
t.set_cell(2, 3, ((const SphereLight *)node)->get_radius());
1463+
}
1464+
}
1465+
}
1466+
} else if (index == 0) {
1467+
// Apply the default OpenGL lights otherwise.
1468+
// Special exception for light 0, which defaults to white.
1469+
t.set_row(0, _light_color_scale);
1470+
}
1471+
return &t;
1472+
}
13901473
default:
13911474
nassertr(false /*should never get here*/, &LMatrix4::ident_mat());
13921475
return &LMatrix4::ident_mat();

panda/src/display/standardMunger.cxx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -343,28 +343,29 @@ munge_state_impl(const RenderState *state) {
343343

344344
#ifdef HAVE_CG
345345
if (_auto_shader) {
346-
CPT(RenderState) shader_state = munged_state->get_auto_shader_state();
347346
GraphicsStateGuardian *gsg = get_gsg();
348347
ShaderGenerator *shader_generator = gsg->get_shader_generator();
349348
if (shader_generator == nullptr) {
350349
shader_generator = new ShaderGenerator(gsg);
351350
gsg->set_shader_generator(shader_generator);
352351
}
353-
if (shader_state->_generated_shader == NULL) {
352+
if (munged_state->_generated_shader == nullptr) {
354353
// Cache the generated ShaderAttrib on the shader state.
355354
GeomVertexAnimationSpec spec;
356355

357356
// Currently we overload this flag to request vertex animation for the
358357
// shader generator.
359358
const ShaderAttrib *sattr;
360-
shader_state->get_attrib_def(sattr);
359+
munged_state->get_attrib_def(sattr);
361360
if (sattr->get_flag(ShaderAttrib::F_hardware_skinning)) {
362361
spec.set_hardware(4, true);
363362
}
364363

365-
shader_state->_generated_shader = shader_generator->synthesize_shader(shader_state, spec);
364+
munged_state->_generated_shader = shader_generator->synthesize_shader(munged_state, spec);
365+
}
366+
if (munged_state->_generated_shader != nullptr) {
367+
munged_state = munged_state->set_attrib(munged_state->_generated_shader);
366368
}
367-
munged_state = munged_state->set_attrib(shader_state->_generated_shader);
368369
}
369370
#endif
370371

panda/src/gobj/material.I

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,3 +327,11 @@ INLINE void Material::
327327
set_attrib_lock() {
328328
_flags |= F_attrib_lock;
329329
}
330+
331+
/**
332+
*
333+
*/
334+
INLINE int Material::
335+
get_flags() const {
336+
return _flags;
337+
}

panda/src/gobj/material.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ class EXPCL_PANDA_GOBJ Material : public TypedWritableReferenceCount, public Nam
128128
MAKE_PROPERTY(twoside, get_twoside, set_twoside);
129129

130130
public:
131+
INLINE int get_flags() const;
132+
131133
enum Flags {
132134
F_ambient = 0x001,
133135
F_diffuse = 0x002,
@@ -157,8 +159,6 @@ class EXPCL_PANDA_GOBJ Material : public TypedWritableReferenceCount, public Nam
157159

158160
int _flags;
159161

160-
friend class MaterialAttrib;
161-
162162
public:
163163
static void register_with_read_factory();
164164
virtual void write_datagram(BamWriter *manager, Datagram &me);

panda/src/gobj/shader.cxx

Lines changed: 109 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -450,9 +450,11 @@ cp_dependency(ShaderMatInput inp) {
450450
}
451451
}
452452
if ((inp == SMO_light_ambient) ||
453-
(inp == SMO_light_source_i_attrib)) {
454-
dep |= SSD_light;
455-
if (inp == SMO_light_source_i_attrib) {
453+
(inp == SMO_light_source_i_attrib) ||
454+
(inp == SMO_light_source_i_packed)) {
455+
dep |= SSD_light | SSD_frame;
456+
if (inp == SMO_light_source_i_attrib ||
457+
inp == SMO_light_source_i_packed) {
456458
dep |= SSD_view_transform;
457459
}
458460
}
@@ -465,7 +467,7 @@ cp_dependency(ShaderMatInput inp) {
465467
(inp == SMO_apiview_clipplane_i)) {
466468
dep |= SSD_clip_planes;
467469
}
468-
if (inp == SMO_texmat_i || inp == SMO_inv_texmat_i) {
470+
if (inp == SMO_texmat_i || inp == SMO_inv_texmat_i || inp == SMO_texscale_i) {
469471
dep |= SSD_tex_matrix;
470472
}
471473
if ((inp == SMO_window_size) ||
@@ -483,7 +485,7 @@ cp_dependency(ShaderMatInput inp) {
483485
(inp == SMO_apiclip_to_apiview)) {
484486
dep |= SSD_projection;
485487
}
486-
if (inp == SMO_tex_is_alpha_i) {
488+
if (inp == SMO_tex_is_alpha_i || inp == SMO_texcolor_i) {
487489
dep |= SSD_texture | SSD_frame;
488490
}
489491

@@ -734,6 +736,29 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
734736
return true;
735737
}
736738

739+
if (pieces[0] == "mat" && pieces[1] == "shadow") {
740+
if ((!cp_errchk_parameter_words(p,3))||
741+
(!cp_errchk_parameter_in(p)) ||
742+
(!cp_errchk_parameter_uniform(p))||
743+
(!cp_errchk_parameter_float(p,16,16))) {
744+
return false;
745+
}
746+
ShaderMatSpec bind;
747+
bind._id = p._id;
748+
bind._piece = SMP_whole;
749+
bind._func = SMF_compose;
750+
bind._part[1] = SMO_light_source_i_attrib;
751+
bind._arg[1] = InternalName::make("shadowViewMatrix");
752+
bind._part[0] = SMO_view_to_apiview;
753+
bind._arg[0] = NULL;
754+
bind._index = atoi(pieces[2].c_str());
755+
756+
cp_optimize_mat_spec(bind);
757+
_mat_spec.push_back(bind);
758+
_mat_deps |= bind._dep[0] | bind._dep[1];
759+
return true;
760+
}
761+
737762
// Implement some macros. Macros work by altering the contents of the
738763
// 'pieces' array, and then falling through.
739764

@@ -833,7 +858,13 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
833858

834859
ShaderMatSpec bind;
835860
bind._id = p._id;
861+
bind._piece = SMP_whole;
836862
bind._func = SMF_compose;
863+
bind._part[1] = SMO_light_source_i_attrib;
864+
bind._arg[1] = InternalName::make("shadowViewMatrix");
865+
bind._part[0] = SMO_view_to_apiview;
866+
bind._arg[0] = NULL;
867+
bind._index = atoi(pieces[2].c_str());
837868

838869
int next = 1;
839870
pieces.push_back("");
@@ -958,6 +989,30 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
958989
bind._arg[0] = NULL;
959990
bind._part[1] = SMO_identity;
960991
bind._arg[1] = NULL;
992+
} else if (pieces[1].compare(0, 5, "light") == 0) {
993+
if (!cp_errchk_parameter_float(p,16,16)) {
994+
return false;
995+
}
996+
bind._id = p._id;
997+
bind._piece = SMP_transpose;
998+
bind._func = SMF_first;
999+
bind._part[0] = SMO_light_source_i_packed;
1000+
bind._arg[0] = NULL;
1001+
bind._part[1] = SMO_identity;
1002+
bind._arg[1] = NULL;
1003+
bind._index = atoi(pieces[1].c_str() + 5);
1004+
} else if (pieces[1].compare(0, 5, "lspec") == 0) {
1005+
if (!cp_errchk_parameter_float(p,3,4)) {
1006+
return false;
1007+
}
1008+
bind._id = p._id;
1009+
bind._piece = SMP_row3;
1010+
bind._func = SMF_first;
1011+
bind._part[0] = SMO_light_source_i_attrib;
1012+
bind._arg[0] = InternalName::make("specular");
1013+
bind._part[1] = SMO_identity;
1014+
bind._arg[1] = NULL;
1015+
bind._index = atoi(pieces[1].c_str() + 5);
9611016
} else {
9621017
cp_report_error(p,"Unknown attr parameter.");
9631018
return false;
@@ -1094,6 +1149,52 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
10941149
return true;
10951150
}
10961151

1152+
if (pieces[0] == "texscale") {
1153+
if ((!cp_errchk_parameter_words(p,2))||
1154+
(!cp_errchk_parameter_in(p)) ||
1155+
(!cp_errchk_parameter_uniform(p))||
1156+
(!cp_errchk_parameter_float(p,3,4))) {
1157+
return false;
1158+
}
1159+
ShaderMatSpec bind;
1160+
bind._id = p._id;
1161+
bind._piece = SMP_row3;
1162+
bind._func = SMF_first;
1163+
bind._part[0] = SMO_texscale_i;
1164+
bind._arg[0] = NULL;
1165+
bind._part[1] = SMO_identity;
1166+
bind._arg[1] = NULL;
1167+
bind._index = atoi(pieces[1].c_str());
1168+
1169+
cp_optimize_mat_spec(bind);
1170+
_mat_spec.push_back(bind);
1171+
_mat_deps |= bind._dep[0] | bind._dep[1];
1172+
return true;
1173+
}
1174+
1175+
if (pieces[0] == "texcolor") {
1176+
if ((!cp_errchk_parameter_words(p,2))||
1177+
(!cp_errchk_parameter_in(p)) ||
1178+
(!cp_errchk_parameter_uniform(p))||
1179+
(!cp_errchk_parameter_float(p,3,4))) {
1180+
return false;
1181+
}
1182+
ShaderMatSpec bind;
1183+
bind._id = p._id;
1184+
bind._piece = SMP_row3;
1185+
bind._func = SMF_first;
1186+
bind._part[0] = SMO_texcolor_i;
1187+
bind._arg[0] = NULL;
1188+
bind._part[1] = SMO_identity;
1189+
bind._arg[1] = NULL;
1190+
bind._index = atoi(pieces[1].c_str());
1191+
1192+
cp_optimize_mat_spec(bind);
1193+
_mat_spec.push_back(bind);
1194+
_mat_deps |= bind._dep[0] | bind._dep[1];
1195+
return true;
1196+
}
1197+
10971198
if (pieces[0] == "plane") {
10981199
if ((!cp_errchk_parameter_words(p,2))||
10991200
(!cp_errchk_parameter_in(p)) ||
@@ -1233,9 +1334,9 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
12331334
}
12341335
ShaderTexSpec bind;
12351336
bind._id = p._id;
1236-
bind._name = InternalName::make(pieces[1])->append("shadowMap");
1237-
bind._stage = -1;
1238-
bind._part = STO_named_input;
1337+
bind._name = nullptr;
1338+
bind._stage = atoi(pieces[1].c_str());
1339+
bind._part = STO_light_i_shadow_map;
12391340
switch (p._type) {
12401341
case SAT_sampler2d: bind._desired_type = Texture::TT_2d_texture; break;
12411342
case SAT_sampler_cube: bind._desired_type = Texture::TT_cube_map; break;

panda/src/gobj/shader.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,17 @@ class EXPCL_PANDA_GOBJ Shader : public TypedWritableReferenceCount {
202202
// Hack for text rendering. Don't use in user shaders.
203203
SMO_tex_is_alpha_i,
204204

205+
SMO_transform_i,
206+
SMO_slider_i,
207+
208+
SMO_light_source_i_packed,
209+
210+
// Texture scale component of texture matrix.
211+
SMO_texscale_i,
212+
213+
// Color of an M_blend texture stage.
214+
SMO_texcolor_i,
215+
205216
SMO_INVALID
206217
};
207218

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy