Показать сообщение отдельно
Старый 23.10.2009, 01:49   #23
Igor'
ПроЭктировщик
 
Аватар для Igor'
 
Регистрация: 15.10.2009
Сообщений: 190
Написано 47 полезных сообщений
(для 142 пользователей)
Ответ: BurnFX RayTracer - W.I.P

Первый скрин нового рей трейсера,с использованием более брутального шейдера .



Код шейдера:
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;
	}
};
(Offline)
 
Ответить с цитированием