Первый скрин нового рей трейсера,с использованием более брутального шейдера
.
Код шейдера:
class ReflectionShader : public Shader
{
public:
ReflectionShader(){
}
float3 shader_main( const Ray& ray , const RayHit& hit , void* data )
{
int bounces = 2;
if(data){
bounces = *static_cast<int*>(data);
}
float3 base = hit.material->getColor();
float3 accum = float3(0,0,0);
for(int i=0;i<getRenderer()->getNumLights();i++)
{
ObjectLight* light = getRenderer()->getLight(i);
float3 l = light->getPosition() - hit.point;
float dist = length(l);
l = normalize( l );
Ray shadowRay;
shadowRay.o = hit.point + ( hit.normal * 1.01f );
shadowRay.d = l;
RayHit hit2;
hit2.empty();
float shade = 1.0f;
if(light->getCastShadows()){
if(light->getShadowSamples() <= 0){
if(rayCast(shadowRay,hit2,dist))
shade = 0.0f;
}else{
for(int i=0;i<light->getShadowSamples();i++){
shadowRay.d = shadowRay.d + normalize(float3(randf(),randf(),randf()));
if(rayCast(shadowRay,hit2,dist))
shade -= 0.1f;
}
if(shade < 0.0f)
shade = 0.0f;
}
}
float d = dot(hit.normal,l);
if(d > 0.0f){
float attenuation = 1 - sqrt(dist) / sqrt(light->getRadius());
accum += light->getColor() * d * attenuation * shade;
}
if(hit.material->getSpecularPower() > 0.0f){
float3 v = ray.d;
float3 r = l - 2.0f * dot( l, hit.normal ) * hit.normal;
float d = dot( v, r );
if(d > 0.0f){
float spec = powf( d , 2 ) * hit.material->getSpecularPower() * shade;
accum += float3(spec) * light->getColor();
}
}
}
base *= accum;
if(bounces > 0 && hit.material->getReflective() > 0.0f ){
bounces--;
Ray r;
r.o = hit.point + ( hit.normal * 1.01f );
r.d = ray.d.reflect(hit.normal);
RayHit hit2;
hit2.empty();
if(rayCast(r,hit2,10000.0f)){
base = base * ( 1.0f - hit.material->getReflective() ) + hit2.material->getShader()->shader_main(r,hit2,&bounces) * hit.material->getReflective();
}
}
return base;
}
};