Results 1 to 6 of 6

Thread: iter->sample() more or less samples

  1. #1
    Join Date
    Dec 2004
    Location
    Moscow, Russia
    Posts
    682

    Default iter->sample() more or less samples

    I have a few questions about light sampling in material shader;

    1. Why actual number of samples (manual counter inside iter->sample() loop) is less than iter->get_number_of_samples() return in some cases? Or the lose samples are when the light shader return miFALSE?
    2. How can I break light sampling? Looks like iter->get_number_of_samples() return incorrect value in this case.
    3. How can I sample more samples from light than light really have.

    For example, I take some measurement of uniformity of samples and I decide to sample farther or not.
    Pavel Ledin

  2. #2
    Join Date
    Dec 2004
    Location
    Marina Del Rey, California
    Posts
    4,143

    Default

    Last question first. It sounds like you want to do the importance part of the light sampling yourself. Light Importance Sampling (LIS) measures importance and redistributes the number of samples per light. It splits up the samples for you. For example, if there ar 4 samples per light for 3 area lights, then 12 samples will be redistributed to each light based on importance. It might end up 2, 4, and 6 for example.

    Now the samples per light (in advnaced) is a nominal value that is scaled by the Light Quality setting.
    Barton Gawboy

  3. #3
    Join Date
    Dec 2004
    Location
    Marina Del Rey, California
    Posts
    4,143

    Default

    Let me explain about how we use the light sample count for mila. The short answer is that the number of samples should be used for weighting. Divide by that number if summing the light samples contribution. We don't quite do that for mila.

    We keep track of valid samples in the lter loop for each light

    Code:
    for (mi::shader::LightIterator iter(state, state->normal, (both_sides) ? -1.0f : 0.0f);
         !iter.at_end(); ++iter)
    { ...
        while (iter->sample())
        {
        ... in mila, we store light samples for re-use ...
        ... counting the number of valid samples in this while loop
        }
        ... now we use the total number of light samples for area light sample weighting ...
        ... assuming we have valid samples and a count greater than one.
        num_samples = iter->get_number_of_samples();
        weight = 1.0f / num_samples;
            ... then we use the weight to multiply by each of the stored light samples.
            ... which ends up being the equivalent of summing the light and dividing by num_samples
    }
    The difference between valid and number of samples is a non-contribution of light. So yes, this would include miFALSE returned for example when caused by an occluding object. If 80% of the area light is occluded, chances are only 20% of the light samples are valid.
    Last edited by bart; May 4th, 2016 at 23:01.
    Barton Gawboy

  4. #4
    Join Date
    Dec 2004
    Location
    Moscow, Russia
    Posts
    682

    Default

    Thank you for reply.
    Yes, it's my LIS alternative realization, because we have 2 issues with mr LIS, that I'm talking in beta section.
    Sorry, but in your code you are using get_number_of_samples like any standard shaders or doc example. "sample*=weight" it's same that "sum/=samples". So I can't see any difference. What you are doing with valid samples and valid samples count? Can you explain?
    Looks like get_number_of_samples always return same value, no matter interrupted or full loop of samples. So it's no correct way to stop sampling.
    Last edited by Puppet; May 11th, 2016 at 22:00.
    Pavel Ledin

  5. #5
    Join Date
    Dec 2004
    Location
    Marina Del Rey, California
    Posts
    4,143

    Default

    valid samples counted in the while (iter->sample()) loop could be a smaller number than samples as returned by get_number_of_samples.

    Think of the difference in number between valid and total number, as being black/non-light samples being returned. For example, if total number is 10, but only 8 returned as valid, then 20% are black naturally, because the weighting was 0.1 on 8 samples.
    Barton Gawboy

  6. #6
    Join Date
    Dec 2004
    Location
    Moscow, Russia
    Posts
    682

    Default

    Is it correct way to change number of light samples by editing state->importance for every light before sample?
    It works, but sometimes I have strange artifacts in area where importance was increased or decreased from nominal value.
    Looks like it because of first light iterator cache some data.
    Code:
    //first light loop for measure light intensity and samples spread
    //disable shadow and save all samples without shadow
    for (mi::shader::LightIterator iterM(state, state->normal, spread_cos, light, n_light); !iterM.at_end(); ++iterM) 
    {
    	...
    	lightTable.add_light(cur_light);  //add light to table
    	while (iterM->sample()) 
    	{
    		iterM->get_contribution(&l_color);		
    		lightTable.add_sample(cur_light, &l_color);  //save sample color
    	}
    	lightTable.set_samples(cur_light, iterM->get_number_of_samples());
    }
    //restore shadow
    
    //regular light loop, that use measured data from first light loop
    for (mi::shader::LightIterator iter(state, state->normal, spread_cos, light, n_light); !iter.at_end(); ++iter) 
    {
    	...
    	light_importance = lightTable.get(cur_light);
    	if(light_importance <= 0.f)	continue;	//skip black light
    	
    	//multiply importance to measured light_intensity * samples_spread
    	state->importance *= light_importance;	
    
    	while (iter->sample()) 
    	{				
    		//regular sampling
    		...
    	}	
    	samples = iter->get_number_of_samples();
    	...
    }
    Pavel Ledin

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •