I am trying to implement a simple shader. A round ball object is rendered with uniform albedo and I noticed some strange white spots on the outputs.
I perform importance sampling with 512 light directions on the cosine-weighted hemisphere to render the scene. For debugging purposes, I dropped the specular component from the visualization and only show the
The spots roughly align with the position of the sun in the env map. From what I have understood the issue is that some values in the hdr are very high (up to
~8384, 12% of the environment map pixels have a value over
1). So if one of the very high values is sampled, then the resulting average light intensity will be very high. However, I don't see why the resulting diffuse color is sparse like this.
From this render, I expect to see a uniform color with a bright side on the left of the sphere. Could this issue be fixed with a more advanced sampling method based on the env map intensity, or am I missing something with the current approach?
For additional reference, I use the following python code to query the env map:
def get_light(self, incident_dir, envir_map): """ envir_map: shape (1, 3, H, W) incident_dir: (3, point_num*samples_num) """ # convert from cartesian to spherical x,y,z = incident_dir phi = torch.arccos(z).flatten() - 1e-6 theta = torch.atan2(y, x).flatten() # normalize to [-1, 1] query_y = (phi / np.pi) * 2 - 1 query_x = - theta / np.pi # sampling grid is shaped (1, 1, pn*sn, 2) grid = torch.stack((query_x, query_y)).permute(1, 0).unsqueeze(0).unsqueeze(0) # interpolate to query env map, sampled = F.grid_sample(envir_map, grid, align_corners=True) # [1, 3, 1, pn*sn] light_rgbs = sampled.squeeze().permute(1, 0).reshape(pn, -1, 3) # [pn, sn, 3] return light_rgbs
The environment map looks like so: