diff --git a/Skeleton.cpp b/Skeleton.cpp index 16b7627cd67b86f6e10009c344e01d600774d4a2..dd0e3a598165f6361e31589339262f6031e716f8 100644 --- a/Skeleton.cpp +++ b/Skeleton.cpp @@ -48,15 +48,14 @@ struct Light; class Scene; struct Material { - vec3 ka, kd, ks; - float shininess; - vec3 F0; Material() {} virtual void trace(const Scene& scene, const Hit& hit, const Ray& ray, const std::vector<Light*>& lights, int depth, vec3& outRadiance) = 0; }; struct RoughMaterial: Material { + vec3 ka, kd, ks; + float shininess; RoughMaterial(vec3 _kd, vec3 _ks, float _shininess) { ka = _kd * M_PI; kd = _kd; @@ -72,6 +71,7 @@ vec3 operator/(const vec3& num, const vec3& denom) { } struct ReflectiveMaterial: Material { + vec3 F0; ReflectiveMaterial(vec3 n, vec3 kappa) { vec3 one(1, 1, 1); F0 = ((n - one)*(n - one) + kappa*kappa) / ((n + one)*(n + one) + kappa*kappa); @@ -80,13 +80,10 @@ struct ReflectiveMaterial: Material { void trace(const Scene& scene, const Hit& hit, const Ray& ray, const std::vector<Light*>& lights, int depth, vec3& outRadiance) override; }; -struct PortalMaterial: ReflectiveMaterial { - PortalMaterial(): ReflectiveMaterial(0, 0){ - F0 = 1; - } - void trace(const Scene& scene, const Hit& hit, const Ray& ray, const std::vector<Light*>& lights, int depth, vec3& outRadiance) override { - ReflectiveMaterial::trace(scene, hit, ray, lights, depth, outRadiance); +struct PortalMaterial: Material { + PortalMaterial() { } + void trace(const Scene& scene, const Hit& hit, const Ray& ray, const std::vector<Light*>& lights, int depth, vec3& outRadiance) override; }; struct Hit { @@ -329,17 +326,17 @@ public: }; void RoughMaterial::trace(const Scene& scene, const Hit& hit, const Ray& ray, const std::vector<Light*>& lights, int depth, vec3& outRadiance) { - outRadiance = hit.material->ka * scene.getLa(); + outRadiance = ka * scene.getLa(); for (Light *light : lights) { auto cosTheta = dot(hit.normal, light->getDirection(hit.position)); Ray shadowRay(hit.position + hit.normal * epsilon, light->getDirection(hit.position)); if (cosTheta > 0 && !scene.shadowIntersect(shadowRay, light)) { // shadow computation vec3 le = light->Le / powf(light->getDistance(hit.position), 2); - outRadiance = outRadiance + le * hit.material->kd * cosTheta; + outRadiance = outRadiance + le * kd * cosTheta; vec3 halfway = normalize(-ray.dir + light->getDirection(hit.position)); float cosDelta = dot(hit.normal, halfway); if (cosDelta > 0) - outRadiance = outRadiance + le * hit.material->ks * powf(cosDelta, hit.material->shininess); + outRadiance = outRadiance + le * ks * powf(cosDelta, shininess); } } } @@ -349,11 +346,16 @@ void ReflectiveMaterial::trace(const Scene& scene, const Hit& hit, const Ray& ra float cosa = -dot(ray.dir, hit.normal); vec3 one(1, 1, 1); - vec3 F = hit.material->F0 + (one - hit.material->F0) * pow(1 - cosa, 5); + vec3 F = F0 + (one - F0) * pow(1 - cosa, 5); outRadiance = outRadiance + scene.trace(Ray(hit.position + hit.normal * epsilon, reflectedDir), depth + 1) * F; } +void PortalMaterial::trace(const Scene& scene, const Hit& hit, const Ray& ray, const std::vector<Light*>& lights, int depth, vec3& outRadiance) { + vec3 reflectedDir = ray.dir - hit.normal * dot(hit.normal, ray.dir) * 2.0f; + outRadiance = outRadiance + scene.trace(Ray(hit.position + hit.normal * epsilon, reflectedDir), depth + 1); +} + GPUProgram gpuProgram; // vertex and fragment shaders Scene scene;