diff --git a/projects/voxelization/resources/shaders/shader.frag b/projects/voxelization/resources/shaders/shader.frag
index aba54a23963c02ef8ae08a7409e0ff83318f2039..39af585b03036e9f7a4b8977bcea90fbac9587d4 100644
--- a/projects/voxelization/resources/shaders/shader.frag
+++ b/projects/voxelization/resources/shaders/shader.frag
@@ -39,13 +39,13 @@ vec3 voxelConeTrace(texture3D voxelTexture, sampler voxelSampler, vec3 direction
     float maxMip        = float(log2(voxelResolution));
     float maxStableMip  = 4;    // must be the same as in Voxelization::voxelizeMeshes
     maxMip              = min(maxMip, maxStableMip);
-    float d             = sqrt(3 * pow(voxelSize, 2));
+    float d             = 2 * sqrt(3 * pow(voxelSize, 2));
     vec3 color          = vec3(0);
     float a             = 0;
     
     float coneAngleHalf = coneAngleRadian * 0.5f;
     
-    int maxSamples = 16;
+    int maxSamples = 128;
     for(int i = 0; i < maxSamples; i++){
         
         vec3 samplePos      = startPosition + d * direction;
@@ -65,13 +65,36 @@ vec3 voxelConeTrace(texture3D voxelTexture, sampler voxelSampler, vec3 direction
         voxelSample.a       = pow(voxelSample.a, 0.6);
         a                   += (1 - a) * voxelSample.a;
         
-        d                   += coneDiameter;
+        float minStepSize   = 0.15;
+        d                   += max(coneDiameter, minStepSize);
         samplePos           = startPosition + d * direction;
         sampleUV            = worldToVoxelCoordinates(samplePos, voxelInfo);
     }
     return color;
 }
 
+float degreeToRadian(float d){
+    return d / 180.f * pi;
+}
+
+vec3 cookTorrance(vec3 f0, float r, vec3 N, vec3 V, vec3 L){
+    
+    vec3 H  = normalize(L + V);
+    
+    float NoH = clamp(dot(N, H), 0, 1);
+    float NoL = clamp(dot(N, L), 0, 1);
+    float NoV = clamp(dot(N, V), 0, 1);
+    
+    vec3    F           = fresnelSchlick(NoH, f0);
+    float   D           = GGXDistribution(r, NoH);
+    float   G           = GGXSmithShadowing(r, NoV, NoL);
+    return (F * D * G) / max(4 * NoV * NoL, 0.000001);
+}
+
+float roughnessToConeAngle(float r){
+    return mix(degreeToRadian(10), degreeToRadian(90), r);
+}
+
 void main()	{
 
     vec3 albedoTexel    = texture(sampler2D(albedoTexture, textureSampler), passUV).rgb;
@@ -79,12 +102,11 @@ void main()	{
     vec3 specularTexel  = texture(sampler2D(specularTexture, textureSampler), passUV).rgb;
     
     float r             = specularTexel.g;
-    r                   *= r;   // remapping roughness for perceptual linearity
     
     float metal         = specularTexel.b;
     vec3 albedo         = mix(albedoTexel, vec3(0), metal);
     vec3 f0_dielectric  = vec3(0.04f);
-    vec3 f0             = mix(f0_dielectric, albedo, metal);
+    vec3 f0             = mix(f0_dielectric, albedoTexel, metal);
     
     vec3 T      = normalize(passTangent.xyz);
     vec3 N_geo  = normalize(passNormal);
@@ -95,16 +117,11 @@ void main()	{
     vec3 N  = TBN * normalTexel;
     vec3 L  = lightInfo.L;
     vec3 V  = normalize(cameraPos - passPos);
-    vec3 H  = normalize(L + V);
     
-    float NoH = clamp(dot(N, H), 0, 1);
-    float NoL = clamp(dot(N, L), 0, 1);
+    float NoL = clamp(dot(N, L), 0, 1);    
     float NoV = clamp(dot(N, V), 0, 1);
     
-    vec3 F          = fresnelSchlick(NoH, f0);
-    float D         = GGXDistribution(r, NoH);
-    float G         = GGXSmithShadowing(r, NoV, NoL);
-    vec3 specular   = (F * D * G) / max(4 * NoV * NoL, 0.000001);
+    vec3 sunSpecular = cookTorrance(f0, r, N, V, L);
     
     vec3 sun        = lightInfo.sunStrength * lightInfo.sunColor * NoL;
     sun             *= shadowTest(passPos, lightInfo, shadowMap, shadowMapSampler);
@@ -118,7 +135,7 @@ void main()	{
     up              = cross(N, right); 
     mat3 toSurface  = mat3(right, up, N);
     
-    float coneAngle = 60.f / 180.f * pi;
+    float coneAngle = degreeToRadian(60.f);
     vec3 diffuseTrace = vec3(0);
     {
         vec3 sampleDirection    = toSurface * vec3(0, 0, 1);
@@ -130,9 +147,18 @@ void main()	{
         float phi               = pi / 3;   // 60 degrees
         vec3 sampleDirection    = toSurface * vec3(cos(theta) * sin(phi), sin(theta) * sin(phi), cos(phi));
         float weight            = pi * (3.f / 4.f) / i;
-        diffuseTrace            += voxelConeTrace(voxelTexture, voxelSampler, sampleDirection, passPos, coneAngle);
+        vec3 trace              = voxelConeTrace(voxelTexture, voxelSampler, sampleDirection, passPos, coneAngle);
+        diffuseTrace            += trace * (1 - fresnelSchlick(NoV, f0)) * (1 - fresnelSchlick(cos(phi), f0));
     }
     
-	outColor = (diffuse + specular) * sun + diffuse * diffuseTrace;
-    //outColor = diffuseTrace;
+    vec3 R                      = reflect(-V, N);
+    float reflectionConeAngle   = degreeToRadian(roughnessToConeAngle(r));
+    vec3 offsetTraceStart       = passPos + N_geo * 0.1f;
+    vec3 specularTrace          = voxelConeTrace(voxelTexture, voxelSampler, R, offsetTraceStart, reflectionConeAngle);
+    vec3 reflectionBRDF         = cookTorrance(f0, r, N, V, R);
+    
+	outColor = 
+        (diffuse + sunSpecular) * sun + 
+        lambertBRDF(albedo) * diffuseTrace + 
+        reflectionBRDF * specularTrace;
 }
\ No newline at end of file
diff --git a/projects/voxelization/src/Voxelization.cpp b/projects/voxelization/src/Voxelization.cpp
index 15a6a8f5e3dfd4c0b78594cb8cf7f37c05ff1119..824c3856a2edb7b12635cbfddd780cbd2594f330 100644
--- a/projects/voxelization/src/Voxelization.cpp
+++ b/projects/voxelization/src/Voxelization.cpp
@@ -197,8 +197,9 @@ void Voxelization::voxelizeMeshes(
 	const int   maxStableMip    = 4;	// must be the same as in voxelConeTrace shader function
 	const float snapSize        = voxelSize * exp2(maxStableMip);
 
-	const glm::vec3 voxelVolumeCenter   = cameraPosition + (1.f / 3.f) * m_voxelExtent * cameraLookDirection;
-	voxelizationInfo.offset             = glm::floor(voxelVolumeCenter / snapSize) * snapSize;
+	glm::vec3 voxelVolumeCenter = cameraPosition + (1.f / 3.f) * m_voxelExtent * cameraLookDirection;
+	voxelVolumeCenter.y         = cameraPosition.y;
+	voxelizationInfo.offset     = glm::floor(voxelVolumeCenter / snapSize) * snapSize;
 
 	m_voxelInfoBuffer.fill({ voxelizationInfo });