commit x64 compilation from lulu cause the other branch dont seems to compile properly at home
This commit is contained in:
181
include/modules/raytracer/raytracer_material.cpp
Normal file
181
include/modules/raytracer/raytracer_material.cpp
Normal file
@ -0,0 +1,181 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include "raytracer/raytracer_core.h"
|
||||
#include "core/camera.h"
|
||||
#include "core/geometry.h"
|
||||
#include "core/shader_block.h"
|
||||
#include "scene3d/scene.h"
|
||||
|
||||
using namespace GS::Core;
|
||||
using namespace GS::Raytrace;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
GS::Vector4 Raytracer::SampleMaterialSink(const Trace &trace, ShaderTree::ShaderSinkType sink)
|
||||
{
|
||||
if (trace.st)
|
||||
{
|
||||
// Evaluate sink.
|
||||
if (ShaderBlock *block = trace.st->sink[sink])
|
||||
{
|
||||
ShaderBlockValue block_out;
|
||||
if (EvaluateShaderBlock(trace, block, block_out))
|
||||
return block_out.v;
|
||||
}
|
||||
|
||||
// Default values.
|
||||
switch (sink)
|
||||
{
|
||||
case ShaderTree::SinkNormal: return Vector4(0, 0, 1);
|
||||
case ShaderTree::SinkDiffuse: return trace.m->diffuse;
|
||||
case ShaderTree::SinkModulate: return Vector4(1, 1, 1);
|
||||
case ShaderTree::SinkSpecular: return trace.m->specular;
|
||||
case ShaderTree::SinkGlossiness: return Vector4(trace.m->glossiness, 0, 0);
|
||||
case ShaderTree::SinkConstant: return Vector4(0, 0, 0);
|
||||
case ShaderTree::SinkOpacity: return Vector4(1, 0, 0);
|
||||
case ShaderTree::SinkReflection: return Vector4(trace.m->reflection, 0, 0);
|
||||
}
|
||||
}
|
||||
return Vector4(1, 0, 0, 1);
|
||||
}
|
||||
GS::Vector4 Raytracer::SampleMaterialAttribute(const Trace &trace, MaterialChannel channel)
|
||||
{
|
||||
Color sample(1, 1, 1);
|
||||
if (!trace.m)
|
||||
return sample;
|
||||
|
||||
Material::TextureStage *stage = trace.m->GetChannelStage(channel);
|
||||
|
||||
/*
|
||||
Texture sampling.
|
||||
@TODO This is insanely slow.
|
||||
*/
|
||||
if (stage && trace.g)
|
||||
{
|
||||
float sample_uv_u = 0, sample_uv_v = 0;
|
||||
|
||||
switch (stage->uv_mode)
|
||||
{
|
||||
case Material::UV_SphericalEnvironment:
|
||||
{
|
||||
Vector4 w;
|
||||
scene->current_camera->GetInverseMatrix().ApplyRotation(&w, &trace.n);
|
||||
|
||||
// Find the Euler vector from the reflection normal.
|
||||
Vector4 euler_vec = trace.d - (w * 2.0f * fabs((w*-1.0f).Dot(trace.d)));
|
||||
euler_vec.Normalize();
|
||||
|
||||
// Euler to UV coordinate.
|
||||
// float Y = (1.0f - euler_vec.y) * 0.5f;
|
||||
|
||||
Vector4 XZ(euler_vec.x, euler_vec.z, 0.0);
|
||||
XZ.Normalize();
|
||||
float DotX = /*nVector(1.0f, 0.0f, 0.0f).Dot(XZ)*/XZ.x;
|
||||
|
||||
// Set from -1;1 to 0;1.
|
||||
DotX = (1.0f - DotX) * 0.5f;
|
||||
|
||||
float DotY = /*nVector(0.0f, 1.0f, 0.0f).Dot(XZ)*/XZ.y;
|
||||
// Set -1 or 1.
|
||||
DotY = (DotY >= 0 ? 1.0f :-1.0f);
|
||||
|
||||
float value_angle = DotX * DotY;
|
||||
// Set from -1;1 to 0;1.
|
||||
value_angle = (1.0f - value_angle) * 0.5f;
|
||||
|
||||
sample_uv_u = DotX;
|
||||
sample_uv_v = value_angle;
|
||||
}
|
||||
break;
|
||||
|
||||
case Material::UV_LSN:
|
||||
{
|
||||
// Derive UV coordinates from intersection normal.
|
||||
Vector4 w;
|
||||
scene->current_camera->GetInverseMatrix().ApplyRotation(&w, &trace.n);
|
||||
|
||||
sample_uv_u = w.x * 0.5f + 0.5f;
|
||||
sample_uv_v = w.y * 0.5f + 0.5f;
|
||||
}
|
||||
break;
|
||||
|
||||
case Material::UV_FrontMap:
|
||||
{
|
||||
// Derive UV coordinated from view item projection matrix.
|
||||
Vector4 s;
|
||||
scene->current_camera->WorldToScreen(fRect(0, 0, viewport.x, viewport.y), trace.pi, s, false);
|
||||
|
||||
float k_ar = viewport.y / viewport.x;
|
||||
sample_uv_u = (s.x - 0.5f) * k_ar + 0.5f;
|
||||
sample_uv_v = s.y;
|
||||
}
|
||||
break;
|
||||
|
||||
case Material::UV_UV:
|
||||
// Compute UV from geometry topology.
|
||||
if (Vector2 *uv = (stage->uv_index < __UV_PER_GEOMETRY__) ? &trace.g->uv[stage->uv_index][0] : NULL)
|
||||
{
|
||||
Vector2 &uv0 = uv[trace.bi], &uv1 = uv[trace.bi + trace.it + 1], &uv2 = uv[trace.bi + trace.it + 2];
|
||||
sample_uv_u = trace.w * uv0.x + trace.u * uv1.x + trace.v * uv2.x,
|
||||
sample_uv_v = trace.w * uv0.y + trace.u * uv1.y + trace.v * uv2.y;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// UV matrix.
|
||||
Vector4 sample_uv = Vector4(sample_uv_u, sample_uv_v, 0.0) * stage->uv_matrix;
|
||||
|
||||
// Handle wrapping.
|
||||
/*
|
||||
if (stage->wrap_u)
|
||||
{
|
||||
if (sample_uv.x < 0)
|
||||
sample_uv.x = sample_uv.x - (int)sample_uv.x + 1;
|
||||
else sample_uv.x = sample_uv.x - (int)sample_uv.x;
|
||||
}
|
||||
if (stage->wrap_v)
|
||||
{
|
||||
if (sample_uv.y < 0)
|
||||
sample_uv.y = sample_uv.y - (int)sample_uv.y + 1;
|
||||
else sample_uv.y = sample_uv.y - (int)sample_uv.y;
|
||||
}
|
||||
*/
|
||||
// FIXME performance bottleneck!
|
||||
if (Picture *p = gf->LoadPicture(stage->t))
|
||||
p->SampleRGBA(sample_uv.x, sample_uv.y, sample);
|
||||
}
|
||||
else
|
||||
switch (channel)
|
||||
{
|
||||
case Channel_Diffuse:
|
||||
sample *= trace.m->diffuse;
|
||||
break;
|
||||
case Channel_Specular:
|
||||
sample *= trace.m->specular;
|
||||
break;
|
||||
case Channel_SelfIllum:
|
||||
sample *= trace.m->self;
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
return sample;
|
||||
}
|
||||
float Raytracer::SampleMaterialOpacity(const Trace &trace)
|
||||
{
|
||||
float opacity = 1.f;
|
||||
|
||||
if (trace.m->GetChannelStage(Channel_Opacity))
|
||||
{
|
||||
Vector4 sample = SampleMaterialAttribute(trace, Channel_Opacity);
|
||||
opacity = sample.w;
|
||||
}
|
||||
return opacity * trace.m->opacity;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user