90 lines
2.7 KiB
C++
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;
|
|
}
|
|
//------------------------------------------------------------------------------
|