/// <summary> /// 根据焦距和透镜半径计算光线 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="sampler"></param> /// <returns></returns> private Ray GetThinLensRayFromPixel(int x, int y, SamplerBase sampler) { if (renderTarget == null) { throw new System.NullReferenceException(); } var sample = sampler.SampleUnitSquare(); double px = (renderTarget.width - 1 - (sample.x + x)) / renderTarget.width * 2 - 1; double py = (sample.y + y) / renderTarget.height * 2 - 1; px *= m_Width; py *= m_Height; double per = focal / near; px = px * per; py = py * per; Vector3 p = position + right * px + up * py + forward * focal; Vector2 disk = sampler.SampleUnitDisk(); Vector3 ori = position + right * disk.x * radius + up * disk.y * radius; Vector3 dir = (p - ori).normalized; return(new Ray(ori, dir)); }
private Vector3 SampleLocalPosition(SamplerBase sampler) { double rand = sampler.GetRandom(); double areaRand = rand * (m_Area0 * 2.0 + m_Area1 * 2.0 + m_Area2 * 2.0); Vector2 sample = sampler.SampleUnitSquare(); if (areaRand < m_Area0) { return(new Vector3(-scale.x * 0.5 + scale.x * sample.x, -scale.y * 0.5 + scale.y * sample.y, -scale.z * 0.5)); } else if (areaRand >= m_Area0 && areaRand < m_Area0 * 2.0) { return(new Vector3(-scale.x * 0.5 + scale.x * sample.x, -scale.y * 0.5 + scale.y * sample.y, scale.z * 0.5)); } else if (areaRand >= m_Area0 * 2.0 && areaRand < m_Area0 * 2.0 + m_Area1) { return(new Vector3(-scale.x * 0.5, -scale.y * 0.5 + scale.y * sample.x, -scale.z * 0.5 + scale.z * sample.y)); } else if (areaRand >= m_Area0 * 2.0 + m_Area1 && areaRand < m_Area0 * 2.0 + m_Area1 * 2.0) { return(new Vector3(scale.x * 0.5, -scale.y * 0.5 + scale.y * sample.x, -scale.z * 0.5 + scale.z * sample.y)); } else if (areaRand >= m_Area0 * 2.0 + m_Area1 * 2.0 && areaRand < m_Area0 * 2.0 + m_Area1 * 2.0 + m_Area2) { return(new Vector3(-scale.x * 0.5 + scale.x * sample.x, -scale.y * 0.5, -scale.z * 0.5 + scale.z * sample.y)); } else { return(new Vector3(-scale.x * 0.5 + scale.x * sample.x, scale.y * 0.5, -scale.z * 0.5 + scale.z * sample.y)); } }
public override Ray GetRay(int x, int y, SamplerBase sampler) { if (useThinLens) { return(GetThinLensRayFromPixel(x, y, sampler)); } var sample = sampler.SampleUnitSquare(); return(GetRayFromPixel(sample.x + x, sample.y + y)); }