mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -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() {
|
make() {
|
||||||
PolylightEffect *effect = new PolylightEffect;
|
PolylightEffect *effect = new PolylightEffect;
|
||||||
effect->_contribution_type = CT_proximal;
|
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);
|
effect->_effect_center = LPoint3f(0.0,0.0,0.0);
|
||||||
return return_new(effect);
|
return return_new(effect);
|
||||||
}
|
}
|
||||||
@ -116,90 +116,113 @@ cull_callback(CullTraverser *, CullTraverserData &data,
|
|||||||
// Function: PolylightEffect::do_poly_light
|
// Function: PolylightEffect::do_poly_light
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: Gets the node's position and based on distance from
|
// 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::
|
CPT(RenderAttrib) PolylightEffect::
|
||||||
do_poly_light(const CullTraverserData *data, const TransformState *node_transform) const {
|
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 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
|
int num_lights = 0; // Keep track of number of lights for division
|
||||||
r = 1.0;
|
float light_scale; // Variable to calculate attenuation
|
||||||
g = 1.0;
|
float weight_scale; // Variable to compensate snap of color when you walk inside the light volume
|
||||||
b = 1.0;
|
float Rcollect, Gcollect, Bcollect;
|
||||||
LightGroup::const_iterator light_iter;
|
|
||||||
|
// Initialize Color variables
|
||||||
|
r = g = b = 1.0;
|
||||||
|
Rcollect = Gcollect = Bcollect = 0.0;
|
||||||
|
|
||||||
// Cycle through all the lights in this effect's lightgroup
|
// 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++){
|
for (light_iter = _lightgroup.begin(); light_iter != _lightgroup.end(); light_iter++){
|
||||||
const PolylightNode *light = DCAST(PolylightNode, (*light_iter).node());
|
const PolylightNode *light = DCAST(PolylightNode, (*light_iter).node());
|
||||||
|
|
||||||
// light holds the current PolylightNode
|
// light holds the current PolylightNode
|
||||||
if (light->is_enabled()) { // if enabled get all the properties
|
if (light->is_enabled()) { // if enabled get all the properties
|
||||||
float light_radius = light->get_radius();
|
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
|
// Calculate the distance of the node from the light
|
||||||
//dist = light_iter->second->get_distance(data->_node_path.get_node_path());
|
//dist = light_iter->second->get_distance(data->_node_path.get_node_path());
|
||||||
const NodePath lightnp = *light_iter;
|
const NodePath lightnp = *light_iter;
|
||||||
LPoint3f point = data->_node_path.get_node_path().get_relative_point(lightnp,
|
LPoint3f point = data->_node_path.get_node_path().get_relative_point(lightnp,
|
||||||
light->get_pos());
|
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) {
|
if (light_attenuation == PolylightNode::ALINEAR) {
|
||||||
light_scale = (light_radius - dist)/light_radius;
|
light_scale = (light_radius - dist)/light_radius;
|
||||||
} else if (light_attenuation == PolylightNode::AQUADRATIC) {
|
} 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);
|
fd = 1.0 / (light_a0 + light_a1 * dist + light_a2 * dist * dist);
|
||||||
if (fd < 1.0) {
|
if (fd < 1.0) {
|
||||||
light_scale = fd;
|
light_scale = fd;
|
||||||
} else {
|
} else {
|
||||||
light_scale = 1.0;
|
light_scale = 1.0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
light_scale = 1.0;
|
light_scale = 1.0;
|
||||||
}
|
}
|
||||||
// Keep accumulating each lights contribution... we divide by
|
|
||||||
// number of lights later.
|
pgraph_cat.debug() << "dist = " << dist << ";radius = " << light_radius << endl;
|
||||||
Rcollect += light_color[0] * light_scale;
|
|
||||||
Gcollect += light_color[1] * light_scale;
|
// Keep accumulating each lights contribution...
|
||||||
Bcollect += light_color[2] * light_scale;
|
// we have to prevent color snap, so factor in the weight.
|
||||||
num_lights++;
|
// 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 dist< radius
|
||||||
} // if light is enabled
|
} // if light is enabled
|
||||||
} // for all lights
|
} // for all lights
|
||||||
|
|
||||||
|
|
||||||
if ( _contribution_type == CT_all) {
|
if ( _contribution_type == CT_all) {
|
||||||
// Sometimes to prevent snapping of color at light volume boundaries
|
// Sometimes to prevent snapping of color at light volume boundaries
|
||||||
// just divide total contribution by all the lights in the effect
|
// just divide total contribution by all the lights in the effect
|
||||||
// whether or not they contribute color
|
// whether or not they contribute color
|
||||||
num_lights = _lightgroup.size();
|
num_lights = _lightgroup.size();
|
||||||
}
|
}
|
||||||
if (num_lights == 0) {
|
|
||||||
no_lights_closeby = true;
|
if (num_lights) {
|
||||||
num_lights = 1;
|
pgraph_cat.debug() << "num lights = " << num_lights << endl;
|
||||||
}
|
// divide by number of lights to get average.
|
||||||
Rcollect /= num_lights;
|
r = Rcollect / num_lights;
|
||||||
Gcollect /= num_lights;
|
g = Gcollect / num_lights;
|
||||||
Bcollect /= num_lights;
|
b = Bcollect / num_lights;
|
||||||
if (!no_lights_closeby) {
|
pgraph_cat.debug() << "r = " << r << ";g = " << g << ";b = " << b << endl;
|
||||||
//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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ColorScaleAttrib::make(LVecBase4f(r, g, b, 1.0));
|
return ColorScaleAttrib::make(LVecBase4f(r, g, b, 1.0));
|
||||||
|
@ -70,7 +70,8 @@ Colorf PolylightNode::flicker() const {
|
|||||||
float r,g,b;
|
float r,g,b;
|
||||||
|
|
||||||
Colorf color;
|
Colorf color;
|
||||||
color = get_color_scenegraph();
|
color = get_color();
|
||||||
|
//color = get_color_scenegraph();
|
||||||
r = color[0];
|
r = color[0];
|
||||||
g = color[1];
|
g = color[1];
|
||||||
b = color[2];
|
b = color[2];
|
||||||
@ -81,13 +82,13 @@ Colorf PolylightNode::flicker() const {
|
|||||||
variation = (rand()%100);// * ClockObject::get_global_clock()->get_dt();
|
variation = (rand()%100);// * ClockObject::get_global_clock()->get_dt();
|
||||||
variation /= 100.0;
|
variation /= 100.0;
|
||||||
//printf("Random Variation: %f\n",variation);
|
//printf("Random Variation: %f\n",variation);
|
||||||
variation += _offset;
|
//variation += _offset;
|
||||||
variation *= _scale;
|
variation *= _scale;
|
||||||
} else if (_flicker_type == FSIN) {
|
} else if (_flicker_type == FSIN) {
|
||||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||||
variation = sinf(now*_sin_freq);// * ClockObject::get_global_clock()->get_dt();
|
variation = sinf(now*_sin_freq);// * ClockObject::get_global_clock()->get_dt();
|
||||||
//printf("Variation: %f\n",variation);
|
//printf("Variation: %f\n",variation);
|
||||||
variation += _offset;
|
//variation += _offset;
|
||||||
variation *= _scale;
|
variation *= _scale;
|
||||||
} else if (_flicker_type == FCUSTOM) {
|
} else if (_flicker_type == FCUSTOM) {
|
||||||
// fixed point list of variation values coming soon...
|
// fixed point list of variation values coming soon...
|
||||||
|
Loading…
x
Reference in New Issue
Block a user