Files
Webcam/include/modules/raytracer/raytracer_geometry.cpp

90 lines
2.7 KiB
C++

/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "raytracer/raytracer_core.h"
#include "core/geometry.h"
using namespace GS;
using namespace GS::Core;
using namespace GS::Raytrace;
//------------------------------------------------------------------------------
Vector4 Raytracer::SampleGeometryAttribute(const Trace &trace, GeometryAttribute attr)
{
Vector4 sample;
switch (attr)
{
case GeometryVertexColor:
if (trace.g->rgb)
sample = ( trace.g->rgb[trace.bi + 0] * trace.w +
trace.g->rgb[trace.bi + trace.it + 1] * trace.u +
trace.g->rgb[trace.bi + trace.it + 2] * trace.v );
else
sample.Set(0.25f, 0.f, 0.f);
break;
case GeometryNormal:
{
if (
(trace.m->renderword & Material::Render_Smooth) ||
(trace.m->renderword & Material::Render_NormalTangent)
)
{
// Interpolated vertex normal.
sample = ( trace.g->vtx_normal[trace.bi + 0] * trace.w +
trace.g->vtx_normal[trace.bi + trace.it + 1] * trace.u +
trace.g->vtx_normal[trace.bi + trace.it + 2] * trace.v ).Normalized();
// Normal map support.
if (trace.m->GetChannelStage(Channel_Normal))
{
if (trace.m->renderword & Material::Render_NormalTangent)
{
Vector4 T, B;
if (trace.g->vtx_tangent)
{
// Interpolated tangent basis.
T = ( trace.g->vtx_tangent[trace.bi + 0].T * trace.w +
trace.g->vtx_tangent[trace.bi + trace.it + 1].T * trace.u +
trace.g->vtx_tangent[trace.bi + trace.it + 2].T * trace.v ).Normalized();
B = ( trace.g->vtx_tangent[trace.bi + 0].B * trace.w +
trace.g->vtx_tangent[trace.bi + trace.it + 1].B * trace.u +
trace.g->vtx_tangent[trace.bi + trace.it + 2].B * trace.v ).Normalized();
}
else
{
T.Set(1, 0, 0);
B.Set(0, 1, 0);
}
// Build tangent frame.
Matrix3 tangent_matrix(T, B, sample);
Vector4 normal_sample(SampleMaterialAttribute(trace, Channel_Normal)),
tangent_normal(normal_sample.x * 2 - 1, normal_sample.y * 2 - 1, normal_sample.z * 2 - 1);
sample = tangent_normal * tangent_matrix;
}
else
{
// World space.
Vector4 normal_sample(SampleMaterialAttribute(trace, Channel_Normal)),
tangent_normal(normal_sample.x * 2 - 1, normal_sample.z * 2 - 1, normal_sample.y * 2 - 1);
sample = tangent_normal;
}
}
}
else
sample = trace.g->pol_normal[trace.ip];
}
break;
}
return sample;
}
//------------------------------------------------------------------------------