mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 17:35:34 -04:00
cleaned up Shalin's polylight code. Still need to work on the flicker code, will do it tomorrow
This commit is contained in:
parent
3cf0b32484
commit
7ff0b84f6a
@ -37,7 +37,7 @@ CPT(RenderEffect) PolylightEffect::
|
||||
make() {
|
||||
PolylightEffect *effect = new PolylightEffect;
|
||||
effect->_contribution_type = CT_proximal;
|
||||
effect->_weight = 0.9;
|
||||
effect->_weight = 1.0; // 0.9; // Asad: I don't think we should monkey with the weight.
|
||||
effect->_effect_center = LPoint3f(0.0,0.0,0.0);
|
||||
return return_new(effect);
|
||||
}
|
||||
@ -116,90 +116,113 @@ cull_callback(CullTraverser *, CullTraverserData &data,
|
||||
// Function: PolylightEffect::do_poly_light
|
||||
// Access: Public
|
||||
// Description: Gets the node's position and based on distance from
|
||||
// lights in the lightgroup calculates the color to be modulated in
|
||||
// lights in the lightgroup calculates the color to be
|
||||
// modulated in
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) PolylightEffect::
|
||||
do_poly_light(const CullTraverserData *data, const TransformState *node_transform) const {
|
||||
bool no_lights_closeby = false;
|
||||
float r,g,b; // To hold the color calculation
|
||||
float dist; // To calculate the distance of each light from the node
|
||||
float light_scale = 1.0; // Variable to calculate attenuation
|
||||
float fd; // Variable for quadratic attenuation
|
||||
float Rcollect = 0.0,Gcollect = 0.0,Bcollect = 0.0; // Color variables
|
||||
float dist; // To calculate the distance of each light from the node
|
||||
float r,g,b; // To hold the color calculation
|
||||
int num_lights = 0; // Keep track of number of lights for division
|
||||
r = 1.0;
|
||||
g = 1.0;
|
||||
b = 1.0;
|
||||
LightGroup::const_iterator light_iter;
|
||||
float light_scale; // Variable to calculate attenuation
|
||||
float weight_scale; // Variable to compensate snap of color when you walk inside the light volume
|
||||
float Rcollect, Gcollect, Bcollect;
|
||||
|
||||
// Initialize Color variables
|
||||
r = g = b = 1.0;
|
||||
Rcollect = Gcollect = Bcollect = 0.0;
|
||||
|
||||
// Cycle through all the lights in this effect's lightgroup
|
||||
LightGroup::const_iterator light_iter;
|
||||
for (light_iter = _lightgroup.begin(); light_iter != _lightgroup.end(); light_iter++){
|
||||
const PolylightNode *light = DCAST(PolylightNode, (*light_iter).node());
|
||||
|
||||
// light holds the current PolylightNode
|
||||
if (light->is_enabled()) { // if enabled get all the properties
|
||||
float light_radius = light->get_radius();
|
||||
PolylightNode::Attenuation_Type light_attenuation = light->get_attenuation();
|
||||
float light_a0 = light->get_a0();
|
||||
float light_a1 = light->get_a1();
|
||||
float light_a2 = light->get_a2();
|
||||
if (light_a0 == 0 && light_a1 == 0 && light_a2 == 0) { // To prevent division by zero
|
||||
light_a0 = 1.0;
|
||||
}
|
||||
Colorf light_color;
|
||||
if (light->is_flickering()) { // If flickering, modify color
|
||||
light_color = light->flicker();
|
||||
} else {
|
||||
light_color = light->get_color_scenegraph();
|
||||
}
|
||||
// Calculate the distance of the node from the light
|
||||
//dist = light_iter->second->get_distance(data->_node_path.get_node_path());
|
||||
const NodePath lightnp = *light_iter;
|
||||
LPoint3f point = data->_node_path.get_node_path().get_relative_point(lightnp,
|
||||
light->get_pos());
|
||||
dist = (point - _effect_center).length();
|
||||
if (dist < light_radius) { // If node is in range of this light
|
||||
|
||||
if (_effect_center[2]) {
|
||||
dist = (point - _effect_center).length(); // this counts height difference
|
||||
} else {
|
||||
// get distance as if the light is at the same height of player
|
||||
LVector2f xz(point[0], point[1]);
|
||||
dist = xz.length(); // this does not count height difference
|
||||
}
|
||||
|
||||
if (dist < light_radius) { // If node is in range of this light
|
||||
pgraph_cat.debug() << "light's position = " << light->get_pos() << endl;
|
||||
pgraph_cat.debug() << "relative position = " << point << endl;
|
||||
pgraph_cat.debug() << "effect center = " << _effect_center << endl;
|
||||
pgraph_cat.debug() << "close to this light = " << light->get_name() << endl;
|
||||
|
||||
PolylightNode::Attenuation_Type light_attenuation = light->get_attenuation();
|
||||
Colorf light_color;
|
||||
if (light->is_flickering()) { // If flickering, modify color
|
||||
light_color = light->flicker();
|
||||
} else {
|
||||
light_color = light->get_color();
|
||||
//light_color = light->get_color_scenegraph();
|
||||
}
|
||||
|
||||
if (light_attenuation == PolylightNode::ALINEAR) {
|
||||
light_scale = (light_radius - dist)/light_radius;
|
||||
} else if (light_attenuation == PolylightNode::AQUADRATIC) {
|
||||
float light_a0 = light->get_a0();
|
||||
float light_a1 = light->get_a1();
|
||||
float light_a2 = light->get_a2();
|
||||
if (light_a0 == 0 && light_a1 == 0 && light_a2 == 0) { // To prevent division by zero
|
||||
light_a0 = 1.0;
|
||||
}
|
||||
fd = 1.0 / (light_a0 + light_a1 * dist + light_a2 * dist * dist);
|
||||
if (fd < 1.0) {
|
||||
light_scale = fd;
|
||||
} else {
|
||||
light_scale = 1.0;
|
||||
}
|
||||
} else {
|
||||
light_scale = 1.0;
|
||||
}
|
||||
// Keep accumulating each lights contribution... we divide by
|
||||
// number of lights later.
|
||||
Rcollect += light_color[0] * light_scale;
|
||||
Gcollect += light_color[1] * light_scale;
|
||||
Bcollect += light_color[2] * light_scale;
|
||||
num_lights++;
|
||||
} else {
|
||||
light_scale = 1.0;
|
||||
}
|
||||
|
||||
pgraph_cat.debug() << "dist = " << dist << ";radius = " << light_radius << endl;
|
||||
|
||||
// Keep accumulating each lights contribution...
|
||||
// we have to prevent color snap, so factor in the weight.
|
||||
// weight becomes negligent as you are closer to the light
|
||||
// and opposite otherwise
|
||||
weight_scale = _weight * (1.0 - light_scale);
|
||||
|
||||
pgraph_cat.debug() << "weight_scale = " << weight_scale
|
||||
<< "; light_scale " << light_scale << endl;
|
||||
|
||||
Rcollect += light_color[0] * light_scale + weight_scale;
|
||||
Gcollect += light_color[1] * light_scale + weight_scale;
|
||||
Bcollect += light_color[2] * light_scale + weight_scale;
|
||||
|
||||
num_lights++;
|
||||
} // if dist< radius
|
||||
} // if light is enabled
|
||||
} // for all lights
|
||||
|
||||
|
||||
if ( _contribution_type == CT_all) {
|
||||
// Sometimes to prevent snapping of color at light volume boundaries
|
||||
// just divide total contribution by all the lights in the effect
|
||||
// whether or not they contribute color
|
||||
num_lights = _lightgroup.size();
|
||||
}
|
||||
if (num_lights == 0) {
|
||||
no_lights_closeby = true;
|
||||
num_lights = 1;
|
||||
}
|
||||
Rcollect /= num_lights;
|
||||
Gcollect /= num_lights;
|
||||
Bcollect /= num_lights;
|
||||
if (!no_lights_closeby) {
|
||||
//r = 1.0 + ((1.0 - _weight) + Rcollect * _weight);
|
||||
//g = 1.0 + ((1.0 - _weight) + Gcollect * _weight);
|
||||
//b = 1.0 + ((1.0 - _weight) + Bcollect * _weight);
|
||||
r = _weight + Rcollect;
|
||||
g = _weight + Gcollect;
|
||||
b = _weight + Bcollect;
|
||||
|
||||
if (num_lights) {
|
||||
pgraph_cat.debug() << "num lights = " << num_lights << endl;
|
||||
// divide by number of lights to get average.
|
||||
r = Rcollect / num_lights;
|
||||
g = Gcollect / num_lights;
|
||||
b = Bcollect / num_lights;
|
||||
pgraph_cat.debug() << "r = " << r << ";g = " << g << ";b = " << b << endl;
|
||||
}
|
||||
|
||||
return ColorScaleAttrib::make(LVecBase4f(r, g, b, 1.0));
|
||||
|
@ -70,7 +70,8 @@ Colorf PolylightNode::flicker() const {
|
||||
float r,g,b;
|
||||
|
||||
Colorf color;
|
||||
color = get_color_scenegraph();
|
||||
color = get_color();
|
||||
//color = get_color_scenegraph();
|
||||
r = color[0];
|
||||
g = color[1];
|
||||
b = color[2];
|
||||
@ -81,13 +82,13 @@ Colorf PolylightNode::flicker() const {
|
||||
variation = (rand()%100);// * ClockObject::get_global_clock()->get_dt();
|
||||
variation /= 100.0;
|
||||
//printf("Random Variation: %f\n",variation);
|
||||
variation += _offset;
|
||||
//variation += _offset;
|
||||
variation *= _scale;
|
||||
} else if (_flicker_type == FSIN) {
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
variation = sinf(now*_sin_freq);// * ClockObject::get_global_clock()->get_dt();
|
||||
//printf("Variation: %f\n",variation);
|
||||
variation += _offset;
|
||||
//variation += _offset;
|
||||
variation *= _scale;
|
||||
} else if (_flicker_type == FCUSTOM) {
|
||||
// fixed point list of variation values coming soon...
|
||||
|
Loading…
x
Reference in New Issue
Block a user