124 lines
5.5 KiB
Plaintext
Executable File
124 lines
5.5 KiB
Plaintext
Executable File
// ======================================================================== //
|
|
// Copyright 2009-2013 Intel Corporation //
|
|
// //
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); //
|
|
// you may not use this file except in compliance with the License. //
|
|
// You may obtain a copy of the License at //
|
|
// //
|
|
// http://www.apache.org/licenses/LICENSE-2.0 //
|
|
// //
|
|
// Unless required by applicable law or agreed to in writing, software //
|
|
// distributed under the License is distributed on an "AS IS" BASIS, //
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
|
|
// See the License for the specific language governing permissions and //
|
|
// limitations under the License. //
|
|
// ======================================================================== //
|
|
|
|
#pragma once
|
|
|
|
/*! \file shapesampler.isph Implements sampling functions for different
|
|
* geometric shapes. */
|
|
|
|
//inline float cos2sin(const float f) { return sqrt(max(0.f,1.f-f*f)); }
|
|
//inline float sin2cos(const float f) { return sqrt(max(0.f,1.f-f*f)); }
|
|
|
|
/*! Cosine weighted hemisphere sampling. Up direction is the z direction. */
|
|
inline Sample3f cosineSampleHemisphere(const float u, const float v) {
|
|
const float phi = 2.0f * (M_PI) * u;
|
|
const float cosTheta = sqrt(v);
|
|
const float sinTheta = sqrt(1.0f - v);
|
|
return make_Sample3f(make_Vec3f(cos(phi) * sinTheta,
|
|
sin(phi) * sinTheta,
|
|
cosTheta),
|
|
cosTheta*(1.f/(M_PI)));
|
|
}
|
|
|
|
/*! Cosine weighted hemisphere sampling. Up direction is provided as argument. */
|
|
inline Sample3f cosineSampleHemisphere(const float u, const float v, const Vec3f& N)
|
|
{
|
|
Sample3f s = cosineSampleHemisphere(u,v);
|
|
return make_Sample3f(frame(N)*s.v,s.pdf);
|
|
}
|
|
|
|
/*! Samples hemisphere with power cosine distribution. Up direction
|
|
* is the z direction. */
|
|
inline Sample3f powerCosineSampleHemisphere(const float u, const float v, const float _exp)
|
|
{
|
|
const float phi = 2.0f * (M_PI) * u;
|
|
const float cosTheta = pow(v,1.0f/(_exp+1.0f));
|
|
const float sinTheta = cos2sin(cosTheta);
|
|
return make_Sample3f(make_Vec3f(cos(phi) * sinTheta,
|
|
sin(phi) * sinTheta,
|
|
cosTheta),
|
|
(_exp+1.0f)*pow(cosTheta,_exp)*0.5f/(M_PI));
|
|
}
|
|
|
|
/*! Computes the probability density for the power cosine sampling of the hemisphere. */
|
|
inline float powerCosineSampleHemispherePDF(const Vec3f& s, const float _exp) {
|
|
if (s.z < 0.f) return 0.f;
|
|
return (_exp+1.0f)*pow(s.z,_exp)*0.5f/M_PI;
|
|
}
|
|
|
|
/*! Samples hemisphere with power cosine distribution. Up direction
|
|
* is provided as argument. */
|
|
inline Sample3f powerCosineSampleHemisphere(const float u, const float v, const Vec3f& N, const float _exp) {
|
|
Sample3f s = powerCosineSampleHemisphere(u,v,_exp);
|
|
return make_Sample3f(frame(N)*s.v,s.pdf);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// Sampling of Spherical Cone
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/*! Uniform sampling of spherical cone. Cone direction is the z
|
|
* direction. */
|
|
inline Sample3f UniformSampleCone(const float u, const float v, const float angle) {
|
|
const float phi = (float)(2.0f * M_PI) * u;
|
|
const float cosTheta = 1.0f - v*(1.0f - cos(angle));
|
|
const float sinTheta = cos2sin(cosTheta);
|
|
return make_Sample3f(make_Vec3f(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta), 1.0f/((float)(4.0f*M_PI)*sqr(sin(0.5f*angle))));
|
|
}
|
|
|
|
/*! Computes the probability density of uniform spherical cone sampling. */
|
|
inline float UniformSampleConePDF(const Vec3f &s, const float angle) {
|
|
return select(s.z < cos(angle), 0.0f, 1.0f/((float)(4.0f*M_PI)*sqr(sin(0.5f*angle))));
|
|
}
|
|
|
|
/*! Uniform sampling of spherical cone. Cone direction is provided as argument. */
|
|
inline Sample3f UniformSampleCone(const float u, const float v, const float angle, const Vec3f& N) {
|
|
Sample3f s = UniformSampleCone(u,v,angle);
|
|
return make_Sample3f(frame(N)*s.v,s.pdf);
|
|
}
|
|
|
|
/*! Computes the probability density of uniform spherical cone sampling. */
|
|
inline float UniformSampleConePDF(const Vec3f &s, const float angle, const Vec3f &N) {
|
|
// return make_select(dot(s,N) < cos(angle), 0.0f, 1.0f/((float)(4.0f*M_PI)*sqr(sin(0.5f*angle))));
|
|
if (dot(s,N) < cos(angle))
|
|
return 0.f;
|
|
else
|
|
return 1.0f/((float)(4.0f*M_PI)*sqr(sin(0.5f*angle)));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// Sampling of Triangle
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/*! Uniform sampling of triangle. */
|
|
inline Vec3f UniformSampleTriangle(const float u, const float v, const Vec3f& A, const Vec3f& B, const Vec3f& C) {
|
|
const float su = sqrt(u);
|
|
return C + (1.0f-su)*(A-C) + (v*su)*(B-C);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// Sampling of Disk
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/*! Uniform sampling of disk. */
|
|
inline Vec2f UniformSampleDisk(const Vec2f &sample, const float radius)
|
|
{
|
|
const float r = sqrt(sample.x);
|
|
const float theta = (2.f*M_PI) * sample.y;
|
|
return make_Vec2f(radius*r*cos(theta), radius*r*sin(theta));
|
|
}
|