mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-28 07:48:37 -04:00
shader: Get all aggregate shader inputs (eg. lights) in one go
This means that p3d_LightSource[n] will be fetched once off the LightAttrib, written to the matrix cache, and then indexed into by the various ShaderMatSpec. This should be significantly more efficient, but the main aim is to prepare for a new binding system in the new shader pipeline User structs are still an exception as of now
This commit is contained in:
parent
99225dfaef
commit
cd68287b6a
@ -1156,32 +1156,23 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
|
||||
_target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
|
||||
// Material matrix contains AMBIENT, DIFFUSE, EMISSION, SPECULAR+SHININESS
|
||||
if (target_material->is_off()) {
|
||||
into[0].set(1, 1, 1, 1);
|
||||
into[1].set(1, 1, 1, 1);
|
||||
into[2].set(0, 0, 0, 0);
|
||||
into[3].set(0, 0, 0, 0);
|
||||
into[Shader::MA_ambient].set(1, 1, 1, 1);
|
||||
into[Shader::MA_diffuse].set(1, 1, 1, 1);
|
||||
into[Shader::MA_emission].set(0, 0, 0, 0);
|
||||
into[Shader::MA_specular].set(0, 0, 0, 0);
|
||||
into[Shader::MA_base_color].set(0, 0, 0, 0);
|
||||
into[Shader::MA_metallic_ior_roughness].set(0, 0, 0, 1);
|
||||
return;
|
||||
}
|
||||
Material *m = target_material->get_material();
|
||||
LVecBase4 spc = m->get_specular();
|
||||
spc[3] = m->get_shininess();
|
||||
into[0] = LCAST(float, m->get_ambient());
|
||||
into[1] = LCAST(float, m->get_diffuse());
|
||||
into[2] = LCAST(float, m->get_emission());
|
||||
into[3] = LCAST(float, spc);
|
||||
return;
|
||||
}
|
||||
case Shader::SMO_attr_material2: {
|
||||
const MaterialAttrib *target_material = (const MaterialAttrib *)
|
||||
_target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
|
||||
if (target_material->is_off()) {
|
||||
into[0].set(0, 0, 0, 0);
|
||||
into[1].set(0, 0, 0, 1);
|
||||
return;
|
||||
}
|
||||
Material *m = target_material->get_material();
|
||||
into[0] = LCAST(float, m->get_base_color());
|
||||
into[1].set(m->get_metallic(), m->get_refractive_index(), 0, m->get_roughness());
|
||||
into[Shader::MA_ambient] = LCAST(float, m->get_ambient());
|
||||
into[Shader::MA_diffuse] = LCAST(float, m->get_diffuse());
|
||||
into[Shader::MA_emission] = LCAST(float, m->get_emission());
|
||||
into[Shader::MA_specular] = LCAST(float, spc);
|
||||
into[Shader::MA_base_color] = LCAST(float, m->get_base_color());
|
||||
into[Shader::MA_metallic_ior_roughness].set(m->get_metallic(), m->get_refractive_index(), 0, m->get_roughness());
|
||||
return;
|
||||
}
|
||||
case Shader::SMO_attr_color: {
|
||||
@ -1210,22 +1201,13 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
|
||||
Fog *fog = target_fog->get_fog();
|
||||
if (fog == nullptr) {
|
||||
into[0].set(0, 1, 1, 1);
|
||||
into[1].set(1, 1, 1, 1);
|
||||
return;
|
||||
}
|
||||
PN_stdfloat start, end;
|
||||
fog->get_linear_range(start, end);
|
||||
into[0].set(fog->get_exp_density(), start, end, 1.0f / (end - start));
|
||||
return;
|
||||
}
|
||||
case Shader::SMO_attr_fogcolor: {
|
||||
const FogAttrib *target_fog = (const FogAttrib *)
|
||||
_target_rs->get_attrib_def(FogAttrib::get_class_slot());
|
||||
Fog *fog = target_fog->get_fog();
|
||||
if (fog == nullptr) {
|
||||
into[0].set(1, 1, 1, 1);
|
||||
return;
|
||||
}
|
||||
into[0] = LCAST(float, fog->get_color());
|
||||
into[1] = LCAST(float, fog->get_color());
|
||||
return;
|
||||
}
|
||||
case Shader::SMO_alight_x: {
|
||||
@ -1706,7 +1688,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
|
||||
fetch_specified_member(np, name->get_basename(), into[0]);
|
||||
return;
|
||||
}
|
||||
case Shader::SMO_light_source_i_vec_attrib: {
|
||||
case Shader::SMO_light_source_i: {
|
||||
const LightAttrib *target_light;
|
||||
_target_rs->get_attrib_def(target_light);
|
||||
|
||||
@ -1718,17 +1700,17 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
|
||||
for (i = 0; i < num_lights; ++i) {
|
||||
NodePath light = target_light->get_on_light(i);
|
||||
nassertv(!light.is_empty());
|
||||
fetch_specified_member(light, name, into[i]);
|
||||
fetch_specified_light(light, into);
|
||||
into += Shader::LA_COUNT;
|
||||
}
|
||||
// Apply the default OpenGL lights otherwise.
|
||||
// Special exception for light 0, which defaults to white.
|
||||
if (i == 0) {
|
||||
//FIXME: only the color attribute
|
||||
into[0].set(1, 1, 1, 1);
|
||||
++i;
|
||||
}
|
||||
for (; i < (size_t)count; ++i) {
|
||||
fetch_specified_member(NodePath(), name, into[i]);
|
||||
fetch_specified_light(NodePath(), into);
|
||||
if (i == 0) {
|
||||
into[Shader::LA_color].set(1, 1, 1, 1);
|
||||
}
|
||||
into += Shader::LA_COUNT;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1767,7 +1749,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
|
||||
return;
|
||||
}
|
||||
case Shader::SMO_light_source_i_packed: {
|
||||
// The light matrix contains COLOR, ATTENUATION, POSITION, VIEWVECTOR
|
||||
// The light matrix contains COLOR, ATTENUATION, VIEWVECTOR, POSITION
|
||||
const LightAttrib *target_light;
|
||||
_target_rs->get_attrib_def(target_light);
|
||||
|
||||
@ -2126,6 +2108,111 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LVecBase4f &
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a NodePath passed into a shader input that is a structure, fetches
|
||||
* the value for the given member.
|
||||
*/
|
||||
void GraphicsStateGuardian::
|
||||
fetch_specified_light(const NodePath &np, LVecBase4f *into) {
|
||||
PandaNode *node = nullptr;
|
||||
if (!np.is_empty()) {
|
||||
node = np.node();
|
||||
}
|
||||
|
||||
if (node == nullptr) {
|
||||
into[Shader::LA_color].set(0, 0, 0, 1);
|
||||
into[Shader::LA_specular].set(0, 0, 0, 1);
|
||||
into[Shader::LA_ambient].set(0, 0, 0, 1);
|
||||
into[Shader::LA_diffuse].set(0, 0, 0, 1);
|
||||
into[Shader::LA_position].set(0, 0, 1, 0);
|
||||
into[Shader::LA_half_vector].set(0, 0, 1, 0);
|
||||
into[Shader::LA_spot_direction].set(0, 0, -1, 0);
|
||||
into[Shader::LA_spot_params].set(-1, 180, 0, 0);
|
||||
into[Shader::LA_attenuation].set(1, 0, 0, 0);
|
||||
*(LMatrix4f *)&into[Shader::LA_shadow_view_matrix] = LCAST(float, shadow_bias_mat);
|
||||
} else {
|
||||
Light *light = node->as_light();
|
||||
nassertv(light != nullptr);
|
||||
|
||||
LVecBase4f color = LCAST(float, light->get_color());
|
||||
into[Shader::LA_color] = color;
|
||||
into[Shader::LA_specular] = LCAST(float, light->get_specular_color());
|
||||
|
||||
if (node->is_ambient_light()) {
|
||||
into[Shader::LA_ambient] = color;
|
||||
into[Shader::LA_diffuse].set(0, 0, 0, 1);
|
||||
into[Shader::LA_position].set(0, 0, 0, 0);
|
||||
into[Shader::LA_half_vector].set(0, 0, 0, 0);
|
||||
into[Shader::LA_spot_direction].set(0, 0, 0, 0);
|
||||
into[Shader::LA_spot_params].set(-1, 180, 0, 0);
|
||||
} else {
|
||||
into[Shader::LA_ambient].set(0, 0, 0, 1);
|
||||
into[Shader::LA_diffuse] = color;
|
||||
|
||||
CPT(TransformState) net_transform =
|
||||
np.get_transform(_scene_setup->get_scene_root().get_parent());
|
||||
CPT(TransformState) transform =
|
||||
_scene_setup->get_cs_world_transform()->compose(net_transform);
|
||||
const LMatrix4 &light_mat = transform->get_mat();
|
||||
|
||||
LightLensNode *light;
|
||||
DCAST_INTO_V(light, node);
|
||||
Lens *lens = light->get_lens();
|
||||
nassertv(lens != nullptr);
|
||||
|
||||
if (node->is_of_type(DirectionalLight::get_class_type())) {
|
||||
DirectionalLight *light;
|
||||
DCAST_INTO_V(light, node);
|
||||
|
||||
LVector3 dir = -(light->get_direction() * light_mat);
|
||||
into[Shader::LA_position].set(dir[0], dir[1], dir[2], 0);
|
||||
|
||||
dir.normalize();
|
||||
dir += LVector3(0, 0, 1);
|
||||
dir.normalize();
|
||||
into[Shader::LA_half_vector].set(dir[0], dir[1], dir[2], 1);
|
||||
}
|
||||
else {
|
||||
LPoint3 pos = lens->get_nodal_point() * light_mat;
|
||||
into[Shader::LA_position].set(pos[0], pos[1], pos[2], 1);
|
||||
|
||||
pos.normalize();
|
||||
pos += LVector3(0, 0, 1);
|
||||
pos.normalize();
|
||||
into[Shader::LA_half_vector].set(pos[0], pos[1], pos[2], 1);
|
||||
}
|
||||
|
||||
if (node->is_of_type(Spotlight::get_class_type())) {
|
||||
float cutoff = lens->get_hfov() * 0.5f;
|
||||
into[Shader::LA_spot_params].set(ccos(deg_2_rad(cutoff)), cutoff, light->get_exponent(), 0);
|
||||
} else {
|
||||
// spotCosCutoff, spotCutoff, spotExponent
|
||||
into[Shader::LA_spot_params].set(-1, 180, light->get_exponent(), 0);
|
||||
}
|
||||
|
||||
LVector3 dir = lens->get_view_vector() * light_mat;
|
||||
into[Shader::LA_spot_direction].set(dir[0], dir[1], dir[2], 0);
|
||||
|
||||
LMatrix4 t = _inv_cs_transform->get_mat() *
|
||||
_scene_setup->get_camera_transform()->get_mat() *
|
||||
net_transform->get_inverse()->get_mat() *
|
||||
LMatrix4::convert_mat(_coordinate_system, lens->get_coordinate_system());
|
||||
|
||||
if (!node->is_of_type(PointLight::get_class_type())) {
|
||||
t *= lens->get_projection_mat() * shadow_bias_mat;
|
||||
}
|
||||
*(LMatrix4f *)&into[Shader::LA_shadow_view_matrix] = t;
|
||||
}
|
||||
|
||||
LVecBase3 atten = light->get_attenuation();
|
||||
PN_stdfloat radius = 0;
|
||||
if (node->is_of_type(SphereLight::get_class_type())) {
|
||||
radius = ((const SphereLight *)node)->get_radius();
|
||||
}
|
||||
into[Shader::LA_attenuation].set(atten[0], atten[1], atten[2], radius);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Like fetch_specified_value, but for texture inputs.
|
||||
*/
|
||||
|
@ -343,6 +343,7 @@ public:
|
||||
LVecBase4f *into, int count = 1);
|
||||
void fetch_specified_member(const NodePath &np, CPT_InternalName member,
|
||||
LVecBase4f &v);
|
||||
void fetch_specified_light(const NodePath &np, LVecBase4f *into);
|
||||
PT(Texture) fetch_specified_texture(Shader::ShaderTexSpec &spec,
|
||||
SamplerState &sampler, int &view);
|
||||
const Shader::ShaderPtrData *fetch_ptr_parameter(const Shader::ShaderPtrSpec& spec);
|
||||
|
@ -960,10 +960,11 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
}
|
||||
|
||||
bind._func = Shader::SMF_first;
|
||||
bind._part[0] = Shader::SMO_apiview_to_apiclip_light_source_i;
|
||||
bind._part[0] = Shader::SMO_light_source_i;
|
||||
bind._arg[0] = nullptr;
|
||||
bind._part[1] = Shader::SMO_identity;
|
||||
bind._arg[1] = nullptr;
|
||||
bind._offset = 4 * Shader::LA_shadow_view_matrix;
|
||||
|
||||
} else if (strncmp(name_buffer, "shadowMatrix", 127) == 0) {
|
||||
// Only supported for backward compatibility: includes the model
|
||||
@ -1074,90 +1075,88 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
GLCAT.error()
|
||||
<< "p3d_Material.baseColor should be vec4\n";
|
||||
}
|
||||
bind._part[0] = Shader::SMO_attr_material2;
|
||||
bind._offset = 4 * Shader::MA_base_color;
|
||||
bind._piece = Shader::SMP_vec4;
|
||||
_shader->cp_add_mat_spec(bind);
|
||||
return;
|
||||
|
||||
} else if (noprefix == "Material.ambient") {
|
||||
}
|
||||
else if (noprefix == "Material.ambient") {
|
||||
if (param_type != GL_FLOAT_VEC4) {
|
||||
GLCAT.error()
|
||||
<< "p3d_Material.ambient should be vec4\n";
|
||||
}
|
||||
bind._offset = 4 * Shader::MA_ambient;
|
||||
bind._piece = Shader::SMP_vec4;
|
||||
_shader->cp_add_mat_spec(bind);
|
||||
return;
|
||||
|
||||
} else if (noprefix == "Material.diffuse") {
|
||||
}
|
||||
else if (noprefix == "Material.diffuse") {
|
||||
if (param_type != GL_FLOAT_VEC4) {
|
||||
GLCAT.error()
|
||||
<< "p3d_Material.diffuse should be vec4\n";
|
||||
}
|
||||
bind._offset = 4 * Shader::MA_diffuse;
|
||||
bind._piece = Shader::SMP_vec4;
|
||||
bind._offset = 4;
|
||||
_shader->cp_add_mat_spec(bind);
|
||||
return;
|
||||
|
||||
} else if (noprefix == "Material.emission") {
|
||||
}
|
||||
else if (noprefix == "Material.emission") {
|
||||
if (param_type != GL_FLOAT_VEC4) {
|
||||
GLCAT.error()
|
||||
<< "p3d_Material.emission should be vec4\n";
|
||||
}
|
||||
bind._offset = 4 * Shader::MA_emission;
|
||||
bind._piece = Shader::SMP_vec4;
|
||||
bind._offset = 8;
|
||||
_shader->cp_add_mat_spec(bind);
|
||||
return;
|
||||
|
||||
} else if (noprefix == "Material.specular") {
|
||||
}
|
||||
else if (noprefix == "Material.specular") {
|
||||
if (param_type != GL_FLOAT_VEC3) {
|
||||
GLCAT.error()
|
||||
<< "p3d_Material.specular should be vec3\n";
|
||||
}
|
||||
bind._offset = 4 * Shader::MA_specular;
|
||||
bind._piece = Shader::SMP_vec3;
|
||||
bind._offset = 12;
|
||||
_shader->cp_add_mat_spec(bind);
|
||||
return;
|
||||
|
||||
} else if (noprefix == "Material.shininess") {
|
||||
}
|
||||
else if (noprefix == "Material.shininess") {
|
||||
if (param_type != GL_FLOAT) {
|
||||
GLCAT.error()
|
||||
<< "p3d_Material.shininess should be float\n";
|
||||
}
|
||||
bind._offset = 4 * Shader::MA_specular + 3;
|
||||
bind._piece = Shader::SMP_scalar;
|
||||
bind._offset = 15;
|
||||
_shader->cp_add_mat_spec(bind);
|
||||
return;
|
||||
|
||||
} else if (noprefix == "Material.roughness") {
|
||||
}
|
||||
else if (noprefix == "Material.roughness") {
|
||||
if (param_type != GL_FLOAT) {
|
||||
GLCAT.error()
|
||||
<< "p3d_Material.roughness should be float\n";
|
||||
}
|
||||
bind._part[0] = Shader::SMO_attr_material2;
|
||||
bind._offset = 4 * Shader::MA_metallic_ior_roughness + 3;
|
||||
bind._piece = Shader::SMP_scalar;
|
||||
bind._offset = 7;
|
||||
_shader->cp_add_mat_spec(bind);
|
||||
return;
|
||||
|
||||
} else if (noprefix == "Material.metallic") {
|
||||
}
|
||||
else if (noprefix == "Material.metallic") {
|
||||
if (param_type != GL_FLOAT && param_type != GL_BOOL) {
|
||||
GLCAT.error()
|
||||
<< "p3d_Material.metallic should be bool or float\n";
|
||||
}
|
||||
bind._part[0] = Shader::SMO_attr_material2;
|
||||
bind._offset = 4 * Shader::MA_metallic_ior_roughness;
|
||||
bind._piece = Shader::SMP_scalar;
|
||||
bind._offset = 4;
|
||||
_shader->cp_add_mat_spec(bind);
|
||||
return;
|
||||
|
||||
} else if (noprefix == "Material.refractiveIndex") {
|
||||
}
|
||||
else if (noprefix == "Material.refractiveIndex") {
|
||||
if (param_type != GL_FLOAT) {
|
||||
GLCAT.error()
|
||||
<< "p3d_Material.refractiveIndex should be float\n";
|
||||
}
|
||||
bind._part[0] = Shader::SMO_attr_material2;
|
||||
bind._offset = 4 * Shader::MA_metallic_ior_roughness + 1;
|
||||
bind._piece = Shader::SMP_scalar;
|
||||
bind._offset = 5;
|
||||
_shader->cp_add_mat_spec(bind);
|
||||
return;
|
||||
}
|
||||
@ -1231,7 +1230,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
bind._arg[1] = nullptr;
|
||||
|
||||
if (noprefix == "Fog.color") {
|
||||
bind._part[0] = Shader::SMO_attr_fogcolor;
|
||||
bind._part[0] = Shader::SMO_attr_fog;
|
||||
bind._offset = 4 * Shader::FA_color;
|
||||
|
||||
if (param_type == GL_FLOAT_VEC3) {
|
||||
bind._piece = Shader::SMP_vec3;
|
||||
@ -1245,6 +1245,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
|
||||
} else if (noprefix == "Fog.density") {
|
||||
bind._part[0] = Shader::SMO_attr_fog;
|
||||
bind._offset = 4 * Shader::FA_params;
|
||||
|
||||
if (param_type == GL_FLOAT) {
|
||||
bind._piece = Shader::SMP_scalar;
|
||||
@ -1256,10 +1257,10 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
|
||||
} else if (noprefix == "Fog.start") {
|
||||
bind._part[0] = Shader::SMO_attr_fog;
|
||||
bind._offset = 4 * Shader::FA_params + 1;
|
||||
|
||||
if (param_type == GL_FLOAT) {
|
||||
bind._piece = Shader::SMP_scalar;
|
||||
bind._offset = 1;
|
||||
} else {
|
||||
GLCAT.error()
|
||||
<< "p3d_Fog.start should be float\n";
|
||||
@ -1268,10 +1269,10 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
|
||||
} else if (noprefix == "Fog.end") {
|
||||
bind._part[0] = Shader::SMO_attr_fog;
|
||||
bind._offset = 4 * Shader::FA_params + 2;
|
||||
|
||||
if (param_type == GL_FLOAT) {
|
||||
bind._piece = Shader::SMP_scalar;
|
||||
bind._offset = 2;
|
||||
} else {
|
||||
GLCAT.error()
|
||||
<< "p3d_Fog.end should be float\n";
|
||||
@ -1280,10 +1281,10 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
|
||||
} else if (noprefix == "Fog.scale") {
|
||||
bind._part[0] = Shader::SMO_attr_fog;
|
||||
bind._offset = 4 * Shader::FA_params + 3;
|
||||
|
||||
if (param_type == GL_FLOAT) {
|
||||
bind._piece = Shader::SMP_scalar;
|
||||
bind._offset = 3;
|
||||
} else {
|
||||
GLCAT.error()
|
||||
<< "p3d_Fog.scale should be float\n";
|
||||
@ -1350,11 +1351,78 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
bind._id = arg_id;
|
||||
bind._func = Shader::SMF_first;
|
||||
bind._index = index;
|
||||
bind._part[0] = Shader::SMO_light_source_i_vec_attrib;
|
||||
bind._arg[0] = InternalName::make(member_name);
|
||||
bind._part[0] = Shader::SMO_light_source_i;
|
||||
bind._arg[0] = nullptr;
|
||||
bind._part[1] = Shader::SMO_identity;
|
||||
bind._arg[1] = nullptr;
|
||||
|
||||
GLenum expected = GL_FLOAT_VEC4;
|
||||
if (member_name == "color") {
|
||||
bind._offset = 4 * Shader::LA_color;
|
||||
}
|
||||
else if (member_name == "specular") {
|
||||
bind._offset = 4 * Shader::LA_specular;
|
||||
}
|
||||
else if (member_name == "ambient") {
|
||||
bind._offset = 4 * Shader::LA_ambient;
|
||||
}
|
||||
else if (member_name == "diffuse") {
|
||||
bind._offset = 4 * Shader::LA_diffuse;
|
||||
}
|
||||
else if (member_name == "position") {
|
||||
bind._offset = 4 * Shader::LA_position;
|
||||
}
|
||||
else if (member_name == "halfVector") {
|
||||
bind._offset = 4 * Shader::LA_half_vector;
|
||||
}
|
||||
else if (member_name == "spotDirection") {
|
||||
bind._offset = 4 * Shader::LA_spot_direction;
|
||||
}
|
||||
else if (member_name == "spotCosCutoff") {
|
||||
bind._offset = 4 * Shader::LA_spot_params;
|
||||
expected = GL_FLOAT;
|
||||
}
|
||||
else if (member_name == "spotCutoff") {
|
||||
bind._offset = 4 * Shader::LA_spot_params + 1;
|
||||
expected = GL_FLOAT;
|
||||
}
|
||||
else if (member_name == "spotExponent") {
|
||||
bind._offset = 4 * Shader::LA_spot_params + 2;
|
||||
expected = GL_FLOAT;
|
||||
}
|
||||
else if (member_name == "attenuation") {
|
||||
bind._offset = 4 * Shader::LA_attenuation;
|
||||
expected = GL_FLOAT_VEC3;
|
||||
}
|
||||
else if (member_name == "constantAttenuation") {
|
||||
bind._offset = 4 * Shader::LA_attenuation;
|
||||
expected = GL_FLOAT;
|
||||
}
|
||||
else if (member_name == "linearAttenuation") {
|
||||
bind._offset = 4 * Shader::LA_attenuation + 1;
|
||||
expected = GL_FLOAT;
|
||||
}
|
||||
else if (member_name == "quadraticAttenuation") {
|
||||
bind._offset = 4 * Shader::LA_attenuation + 2;
|
||||
expected = GL_FLOAT;
|
||||
}
|
||||
else if (member_name == "radius") {
|
||||
bind._offset = 4 * Shader::LA_attenuation + 3;
|
||||
expected = GL_FLOAT;
|
||||
}
|
||||
else {
|
||||
GLCAT.error()
|
||||
<< "Invalid light struct member " << member_name << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// It's okay to declare as vec3 if we allow vec4.
|
||||
if (param_type != expected && (expected != GL_FLOAT_VEC4 || param_type != GL_FLOAT_VEC3)) {
|
||||
GLCAT.error()
|
||||
<< "p3d_LightSource[]." << member_name << " has unexpected type\n";
|
||||
return;
|
||||
}
|
||||
|
||||
switch (param_type) {
|
||||
case GL_FLOAT:
|
||||
bind._piece = Shader::SMP_scalar;
|
||||
@ -1373,8 +1441,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
break;
|
||||
|
||||
default:
|
||||
GLCAT.error()
|
||||
<< "p3d_LightSource[]." << member_name << " should be float or vec\n";
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
_shader->cp_add_mat_spec(bind);
|
||||
|
@ -381,16 +381,16 @@ cp_dependency(ShaderMatInput inp) {
|
||||
if (inp == SMO_INVALID) {
|
||||
return SSD_NONE;
|
||||
}
|
||||
if (inp == SMO_attr_material || inp == SMO_attr_material2) {
|
||||
if (inp == SMO_attr_material) {
|
||||
dep |= SSD_material | SSD_frame;
|
||||
}
|
||||
if (inp == SMO_attr_color || inp == SMO_attr_material2) {
|
||||
if (inp == SMO_attr_color) {
|
||||
dep |= SSD_color;
|
||||
}
|
||||
if (inp == SMO_attr_colorscale) {
|
||||
dep |= SSD_colorscale;
|
||||
}
|
||||
if (inp == SMO_attr_fog || inp == SMO_attr_fogcolor) {
|
||||
if (inp == SMO_attr_fog) {
|
||||
dep |= SSD_fog | SSD_frame;
|
||||
}
|
||||
if ((inp == SMO_model_to_view) ||
|
||||
@ -459,12 +459,12 @@ cp_dependency(ShaderMatInput inp) {
|
||||
}
|
||||
}
|
||||
if ((inp == SMO_light_ambient) ||
|
||||
(inp == SMO_light_source_i_vec_attrib) ||
|
||||
(inp == SMO_light_source_i) ||
|
||||
(inp == SMO_apiview_to_apiclip_light_source_i) ||
|
||||
(inp == SMO_light_source_i_packed)) {
|
||||
dep |= SSD_light | SSD_frame;
|
||||
}
|
||||
if (inp == SMO_light_source_i_vec_attrib ||
|
||||
if (inp == SMO_light_source_i ||
|
||||
inp == SMO_apiview_to_apiclip_light_source_i ||
|
||||
inp == SMO_light_source_i_packed ||
|
||||
inp == SMO_mat_constant_x_attrib ||
|
||||
@ -512,6 +512,90 @@ cp_dependency(ShaderMatInput inp) {
|
||||
return dep;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given ShaderMatInput, returns the size in the cache that this part requires.
|
||||
*/
|
||||
int Shader::
|
||||
cp_size(ShaderMatInput inp) {
|
||||
switch (inp) {
|
||||
case SMO_INVALID:
|
||||
return 0;
|
||||
|
||||
case SMO_window_size:
|
||||
case SMO_pixel_size:
|
||||
case SMO_texpad_x:
|
||||
case SMO_texpix_x:
|
||||
case SMO_attr_color:
|
||||
case SMO_attr_colorscale:
|
||||
case SMO_satten_x:
|
||||
case SMO_plane_x:
|
||||
case SMO_clipplane_x:
|
||||
case SMO_vec_constant_x:
|
||||
case SMO_frame_number:
|
||||
case SMO_frame_time:
|
||||
case SMO_frame_delta:
|
||||
case SMO_vec_constant_x_attrib:
|
||||
case SMO_light_ambient:
|
||||
case SMO_light_product_i_ambient:
|
||||
case SMO_light_product_i_diffuse:
|
||||
case SMO_light_product_i_specular:
|
||||
case SMO_apiview_clipplane_i:
|
||||
case SMO_tex_is_alpha_i:
|
||||
case SMO_texscale_i:
|
||||
case SMO_texcolor_i:
|
||||
case SMO_texconst_i:
|
||||
case SMO_attr_pointparams:
|
||||
return 1;
|
||||
|
||||
case SMO_identity:
|
||||
case SMO_alight_x:
|
||||
case SMO_dlight_x:
|
||||
case SMO_plight_x:
|
||||
case SMO_slight_x:
|
||||
case SMO_texmat_i:
|
||||
case SMO_mat_constant_x:
|
||||
case SMO_world_to_view:
|
||||
case SMO_view_to_world:
|
||||
case SMO_model_to_view:
|
||||
case SMO_view_to_model:
|
||||
case SMO_apiview_to_view:
|
||||
case SMO_view_to_apiview:
|
||||
case SMO_clip_to_view:
|
||||
case SMO_view_to_clip:
|
||||
case SMO_apiclip_to_view:
|
||||
case SMO_view_to_apiclip:
|
||||
case SMO_view_x_to_view:
|
||||
case SMO_view_to_view_x:
|
||||
case SMO_apiview_x_to_view:
|
||||
case SMO_view_to_apiview_x:
|
||||
case SMO_clip_x_to_view:
|
||||
case SMO_view_to_clip_x:
|
||||
case SMO_apiclip_x_to_view:
|
||||
case SMO_view_to_apiclip_x:
|
||||
case SMO_mat_constant_x_attrib:
|
||||
case SMO_apiview_to_apiclip_light_source_i:
|
||||
case SMO_model_to_apiview:
|
||||
case SMO_apiview_to_model:
|
||||
case SMO_apiview_to_apiclip:
|
||||
case SMO_apiclip_to_apiview:
|
||||
case SMO_inv_texmat_i:
|
||||
case SMO_light_source_i_packed:
|
||||
return 4;
|
||||
|
||||
case SMO_attr_material:
|
||||
return MA_COUNT;
|
||||
|
||||
case SMO_light_source_i:
|
||||
return LA_COUNT;
|
||||
|
||||
case SMO_attr_fog:
|
||||
return FA_COUNT;
|
||||
}
|
||||
|
||||
nassertr(false, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given ShaderMatSpec to the shader's mat spec table.
|
||||
*/
|
||||
@ -581,7 +665,7 @@ cp_add_mat_spec(ShaderMatSpec &spec) {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (spec._part[i] == SMO_texmat_i ||
|
||||
spec._part[i] == SMO_inv_texmat_i ||
|
||||
spec._part[i] == SMO_light_source_i_vec_attrib ||
|
||||
spec._part[i] == SMO_light_source_i ||
|
||||
spec._part[i] == SMO_apiview_to_apiclip_light_source_i ||
|
||||
spec._part[i] == SMO_light_product_i_ambient ||
|
||||
spec._part[i] == SMO_light_product_i_diffuse ||
|
||||
@ -638,6 +722,7 @@ cp_add_mat_spec(ShaderMatSpec &spec) {
|
||||
}
|
||||
offset += part._count * part._size;
|
||||
}
|
||||
int size = cp_size(spec._part[p]);
|
||||
if (i == _mat_parts.size()) {
|
||||
// Didn't find this part yet, create a new one.
|
||||
ShaderMatPart part;
|
||||
@ -645,83 +730,7 @@ cp_add_mat_spec(ShaderMatSpec &spec) {
|
||||
part._count = end[p];
|
||||
part._arg = spec._arg[p];
|
||||
part._dep = dep;
|
||||
|
||||
switch (part._part) {
|
||||
case SMO_INVALID:
|
||||
part._size = 0;
|
||||
break;
|
||||
|
||||
case SMO_window_size:
|
||||
case SMO_pixel_size:
|
||||
case SMO_texpad_x:
|
||||
case SMO_texpix_x:
|
||||
case SMO_attr_color:
|
||||
case SMO_attr_colorscale:
|
||||
case SMO_satten_x:
|
||||
case SMO_plane_x:
|
||||
case SMO_clipplane_x:
|
||||
case SMO_vec_constant_x:
|
||||
case SMO_attr_fog:
|
||||
case SMO_attr_fogcolor:
|
||||
case SMO_frame_number:
|
||||
case SMO_frame_time:
|
||||
case SMO_frame_delta:
|
||||
case SMO_vec_constant_x_attrib:
|
||||
case SMO_light_ambient:
|
||||
case SMO_light_source_i_vec_attrib:
|
||||
case SMO_light_product_i_ambient:
|
||||
case SMO_light_product_i_diffuse:
|
||||
case SMO_light_product_i_specular:
|
||||
case SMO_apiview_clipplane_i:
|
||||
case SMO_tex_is_alpha_i:
|
||||
case SMO_texscale_i:
|
||||
case SMO_texcolor_i:
|
||||
case SMO_texconst_i:
|
||||
case SMO_attr_pointparams:
|
||||
part._size = 1;
|
||||
break;
|
||||
|
||||
case SMO_attr_material2:
|
||||
part._size = 2;
|
||||
break;
|
||||
|
||||
case SMO_identity:
|
||||
case SMO_attr_material:
|
||||
case SMO_alight_x:
|
||||
case SMO_dlight_x:
|
||||
case SMO_plight_x:
|
||||
case SMO_slight_x:
|
||||
case SMO_texmat_i:
|
||||
case SMO_mat_constant_x:
|
||||
case SMO_world_to_view:
|
||||
case SMO_view_to_world:
|
||||
case SMO_model_to_view:
|
||||
case SMO_view_to_model:
|
||||
case SMO_apiview_to_view:
|
||||
case SMO_view_to_apiview:
|
||||
case SMO_clip_to_view:
|
||||
case SMO_view_to_clip:
|
||||
case SMO_apiclip_to_view:
|
||||
case SMO_view_to_apiclip:
|
||||
case SMO_view_x_to_view:
|
||||
case SMO_view_to_view_x:
|
||||
case SMO_apiview_x_to_view:
|
||||
case SMO_view_to_apiview_x:
|
||||
case SMO_clip_x_to_view:
|
||||
case SMO_view_to_clip_x:
|
||||
case SMO_apiclip_x_to_view:
|
||||
case SMO_view_to_apiclip_x:
|
||||
case SMO_mat_constant_x_attrib:
|
||||
case SMO_apiview_to_apiclip_light_source_i:
|
||||
case SMO_model_to_apiview:
|
||||
case SMO_apiview_to_model:
|
||||
case SMO_apiview_to_apiclip:
|
||||
case SMO_apiclip_to_apiview:
|
||||
case SMO_inv_texmat_i:
|
||||
case SMO_light_source_i_packed:
|
||||
part._size = 4;
|
||||
break;
|
||||
}
|
||||
part._size = size;
|
||||
|
||||
if (spec._func != SMF_first) {
|
||||
assert(part._size == 4);
|
||||
@ -730,7 +739,7 @@ cp_add_mat_spec(ShaderMatSpec &spec) {
|
||||
_mat_cache_deps |= part._dep;
|
||||
_mat_parts.push_back(std::move(part));
|
||||
}
|
||||
spec._cache_offset[p] = offset + begin[p];
|
||||
spec._cache_offset[p] = offset + begin[p] * size;
|
||||
}
|
||||
if (spec._func == SMF_shader_input_ptr) {
|
||||
_mat_scratch_size = std::max(_mat_scratch_size, spec._array_count);
|
||||
@ -1188,6 +1197,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
||||
bind._arg[0] = nullptr;
|
||||
bind._part[1] = SMO_identity;
|
||||
bind._arg[1] = nullptr;
|
||||
bind._offset = FA_params;
|
||||
} else if (pieces[1] == "fogcolor") {
|
||||
if (!cp_errchk_parameter_float(p,3,4)) {
|
||||
return false;
|
||||
@ -1195,10 +1205,11 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
||||
bind._id = p._id;
|
||||
bind._piece = SMP_vec4;
|
||||
bind._func = SMF_first;
|
||||
bind._part[0] = SMO_attr_fogcolor;
|
||||
bind._part[0] = SMO_attr_fog;
|
||||
bind._arg[0] = nullptr;
|
||||
bind._part[1] = SMO_identity;
|
||||
bind._arg[1] = nullptr;
|
||||
bind._offset = FA_color;
|
||||
} else if (pieces[1] == "ambient") {
|
||||
if (!cp_errchk_parameter_float(p,3,4)) {
|
||||
return false;
|
||||
@ -1229,11 +1240,12 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
||||
bind._id = p._id;
|
||||
bind._piece = SMP_vec4;
|
||||
bind._func = SMF_first;
|
||||
bind._part[0] = SMO_light_source_i_vec_attrib;
|
||||
bind._arg[0] = InternalName::make("specular");
|
||||
bind._part[0] = SMO_light_source_i;
|
||||
bind._arg[0] = nullptr;
|
||||
bind._part[1] = SMO_identity;
|
||||
bind._arg[1] = nullptr;
|
||||
bind._index = atoi(pieces[1].c_str() + 5);
|
||||
bind._offset = LA_specular;
|
||||
} else if (pieces[1] == "pointparams") {
|
||||
if (!cp_errchk_parameter_float(p,3,4)) {
|
||||
return false;
|
||||
|
@ -173,7 +173,6 @@ public:
|
||||
SMO_view_to_apiclip_x,
|
||||
|
||||
SMO_attr_fog,
|
||||
SMO_attr_fogcolor,
|
||||
|
||||
SMO_frame_number,
|
||||
SMO_frame_time,
|
||||
@ -183,7 +182,8 @@ public:
|
||||
SMO_vec_constant_x_attrib,
|
||||
|
||||
SMO_light_ambient,
|
||||
SMO_light_source_i_vec_attrib,
|
||||
SMO_light_source_i,
|
||||
SMO_light_source_i_packed,
|
||||
SMO_apiview_to_apiclip_light_source_i,
|
||||
|
||||
SMO_light_product_i_ambient,
|
||||
@ -200,14 +200,9 @@ public:
|
||||
|
||||
SMO_inv_texmat_i,
|
||||
|
||||
// Additional properties for PBR materials
|
||||
SMO_attr_material2,
|
||||
|
||||
// Hack for text rendering. Don't use in user shaders.
|
||||
SMO_tex_is_alpha_i,
|
||||
|
||||
SMO_light_source_i_packed,
|
||||
|
||||
// Texture scale component of texture matrix.
|
||||
SMO_texscale_i,
|
||||
|
||||
@ -358,6 +353,39 @@ public:
|
||||
SPT_unknown
|
||||
};
|
||||
|
||||
// Attributes (vec4) of the material structure.
|
||||
enum MaterialAttribute {
|
||||
MA_ambient,
|
||||
MA_diffuse,
|
||||
MA_emission,
|
||||
MA_specular, // shininess in w
|
||||
MA_base_color,
|
||||
MA_metallic_ior_roughness,
|
||||
MA_COUNT,
|
||||
};
|
||||
|
||||
// Attributes (vec4) of the light structure.
|
||||
enum LightAttribute {
|
||||
LA_color,
|
||||
LA_specular,
|
||||
LA_ambient,
|
||||
LA_diffuse,
|
||||
LA_position,
|
||||
LA_half_vector,
|
||||
LA_spot_direction,
|
||||
LA_spot_params, // spotCosCutoff, spotCutoff, spotExponent
|
||||
LA_attenuation, // and radius
|
||||
LA_shadow_view_matrix, // mat4
|
||||
LA_COUNT = LA_shadow_view_matrix + 4,
|
||||
};
|
||||
|
||||
// Attributes (vec4) of the fog structure.
|
||||
enum FogAttribute {
|
||||
FA_params, // exp density, start, end, scale
|
||||
FA_color,
|
||||
FA_COUNT,
|
||||
};
|
||||
|
||||
struct ShaderArgInfo {
|
||||
ShaderArgId _id;
|
||||
ShaderArgClass _class;
|
||||
@ -550,6 +578,7 @@ public:
|
||||
vector_string &pieces, int &next,
|
||||
ShaderMatSpec &spec, bool fromflag);
|
||||
int cp_dependency(ShaderMatInput inp);
|
||||
int cp_size(ShaderMatInput inp);
|
||||
void cp_add_mat_spec(ShaderMatSpec &spec);
|
||||
size_t cp_get_mat_cache_size() const;
|
||||
size_t cp_get_mat_scratch_size() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user