Commit b2823a95 authored by unknown's avatar unknown
Browse files

Cook-Torrance finally kinda working well

parent 1ae903ea
<linespace version="1.0">
<item name="subdivisions" value="10"/>
<item name="subdivisions" value="30"/>
<item name="radial-subdivision" value="50"/>
<item name="generator" value="gpu"/>
</linespace>
......@@ -109,19 +109,9 @@ bool shade(int id, inout vec3 radiance, uint bounce, out uint bsdf_id)
//That means the random sample will always have a value between (0,0) and (1,1).
vec2 random_sample = vec2(ray.px, ray.py) - ivec2(ray.px, ray.py);
//Sample BSDF
//float pdf;
//vec3 light_influence;
//Ray out_ray;
//vec3 reflectance =
// BSDFResult bsdf_result;
//bsdf_result.radiance = material.sampleBSDF(random_sample, vertex, ray, bsdf_result.generated_ray, bsdf_result.irradiance, bsdf_result.distribution, bsdf_result.bsdf_id);
// reflectance = radiance; light_influence = irradiance; pdf = distribution; out_ray = generated_ray
BSDFResult bsdf_result = material.computeBSDF(random_sample, vertex, ray);
b_traces[id].addBounceAmount(bsdf_result.bsdf_id, 1);
if(b_traces[id].getBounceAmount(bsdf_result.bsdf_id) > getBounceThreshold(bsdf_result.bsdf_id))
{
b_traces[id].hit.invalidate();
......@@ -132,8 +122,8 @@ bool shade(int id, inout vec3 radiance, uint bounce, out uint bsdf_id)
{
// Treat as emissive material.
//writeColorStore(ray, radiance * bsdf_result.irradiance, clamp_color_max);
//if(length(bsdf_result.generated_ray.direction) > 0)
writeColorStore(ray, normalize(bsdf_result.radiance), clamp_color_max);
//if(!isnan(normali))
writeColorStore(ray, bsdf_result.radiance, clamp_color_max);
b_traces[id].hit.invalidate();
return false;
}
......@@ -142,13 +132,7 @@ bool shade(int id, inout vec3 radiance, uint bounce, out uint bsdf_id)
&& (b_traces[id].getBounceAmount(bsdf_result.bsdf_id) < getLSBounceThreshold(bsdf_result.bsdf_id))
&& b_traces[id].properties.travelled_distance < u_linespace_properties.distance_threshold;
// Environment shading for the diffuse part
// if(length(bsdf_result.irradiance) > 0.01f && !bsdf_result.diffuse_ray.intersectsAny(FLT_MAX, use_bvh)){
// writeColorStore(ray, u_environment.sampleColor(bsdf_result.diffuse_ray.direction.xyz).rgb * bsdf_result.irradiance * radiance, clamp_color_max);
// }
if (false && b_lights.length() > 0) {
if (b_lights.length() > 0) {
//Select random light... well... at least if there are any.
BufferLight light = b_lights[int(floor(random_sample.x * b_lights.length()))];
......@@ -175,7 +159,7 @@ bool shade(int id, inout vec3 radiance, uint bounce, out uint bsdf_id)
b_traces[id].properties.accuracy_importance *= bsdf_result.probability_density;
b_traces[id].properties.shadow_importance *= bsdf_result.probability_density;
b_traces[id].ray = bsdf_result.generated_ray;
radiance *= bsdf_result.radiance * angle(bsdf_result.generated_ray, vertex) / bsdf_result.probability_density;//
radiance *= clamp(bsdf_result.radiance * angle(bsdf_result.generated_ray, vertex) / bsdf_result.probability_density, 0, 1);//
return true;
}
......
......@@ -64,56 +64,50 @@ SampledMaterial getMaterialParameters(const in Material material, const in Verte
BSDFResult computeBSDF(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in)
{
const SampledMaterial sampled_material = material.getMaterialParameters(vertex);
const vec3 hemisphere = ggxImportantHemisphereSample(random, sampled_material.roughness);
HemisphereSample hemisphere_sample = ggxSample(random, sampled_material.roughness);
vec3 incoming = normalize(-ray_in.direction);
bool entering = dot(incoming, vertex.normal.xyz) > 0.f;
vec3 micro_normal = normalize(toWorld(hemisphere, vertex.normal.xyz));
vec3 micro_normal = normalize(toWorld(hemisphere_sample.micro_normal, vertex.normal.xyz));
vec3 outgoing = normalize(2 * clamp(dot(incoming, micro_normal), 0, 1) * micro_normal - incoming);
vec3 half_vector = normalize(sign(dot(incoming, vertex.normal.xyz)) * (incoming + outgoing));
float jacobian = 1 / (4 * clamp(dot(outgoing, half_vector), 0, 1));
float dist_m = ggxDist(vertex.normal.xyz, micro_normal, sampled_material.roughness);
float geometry = ggxGeometry(incoming, outgoing, vertex.normal.xyz, micro_normal, sampled_material.roughness);
float geom_in = ggxGeom(vertex.normal.xyz, incoming, micro_normal, sampled_material.roughness);
float geom_out = ggxGeom(vertex.normal.xyz, outgoing, micro_normal, sampled_material.roughness);
//Approx. by Smith
float geometry = clamp(geom_in * geom_out, 0, 1);
vec3 normal_response = normalResponse(sampled_material.diffuse.rgb, sampled_material.ior, sampled_material.metallic);
vec3 fresnel = fresnelSchlick(clamp(dot(incoming, micro_normal), 0, 1), normal_response);
float normal_response = normalResponse(sampled_material.ior, sampled_material.metallic);
float fresnel = fresnelSchlick(clamp(dot(incoming, micro_normal), 0, 1), normal_response);
vec3 fresnel_tint = fresnelTint(fresnel, sampled_material.metallic, sampled_material.diffuse.rgb);
float n_dot_in = clamp(dot(vertex.normal.xyz, incoming), 0, 1);
float n_dot_out = clamp(dot(vertex.normal.xyz, outgoing), 0, 1);
float m_dot_out = clamp(dot(micro_normal, outgoing), 0, 1);
float cos_theta = clamp(dot(vertex.normal.xyz, micro_normal), 0, 1);// * dist_m
float cos_theta = hemisphere_sample.importance.y;
float sin_theta = sqrt(1-(cos_theta*cos_theta));
float sin_aa = sqrt(1-(m_dot_out*m_dot_out));
float prop_m = dist_m * m_dot_out;
float prop_o = m_dot_out;//prop_m * jacobian;
float jacobian = 1 / (4 * clamp(dot(outgoing, micro_normal), 0, 1));
float prop_m = hemisphere_sample.distribution * cos_theta;
float prop_o = prop_m * jacobian;
vec3 brdf = clamp(fresnel * geometry / clamp((4 * n_dot_in * n_dot_out), 0.05f, 1.f), 0, 1);
vec3 brdf = clamp(fresnel_tint * geometry * hemisphere_sample.distribution / clamp((4 * n_dot_in * n_dot_out), 0.1f, 1.f), 0, 1);
BSDFResult result;
result.generated_ray = ray_in;
result.evaluation = (1-fresnel)*(1-sampled_material.metallic)*sampled_material.diffuse.rgb * ONE_OVER_PI;
result.evaluation = (1-sampled_material.metallic)*sampled_material.diffuse.rgb * ONE_OVER_PI;
if(sampled_material.metallic == 1 || (fresnel.x + fresnel.y + fresnel.z)/3 > random.x*random.y)
if(sampled_material.metallic == 1 || fresnel*PI > random.x)
{
result.generated_ray.direction = outgoing;
result.radiance = brdf;
result.probability_density = prop_o;
result.probability_density = hemisphere_sample.distribution * jacobian * PI/2;
}
else
{
result.generated_ray.direction = normalize(toWorld(randCosineHemisphere(random.x, random.y), vertex.normal.xyz));
result.probability_density = abs(dot(vec4(result.generated_ray.direction, 0), vertex.normal)) * ONE_OVER_PI;
result.radiance = result.evaluation;
result.radiance = (1-sampled_material.metallic)*sampled_material.diffuse.rgb * ONE_OVER_PI;
}
result.generated_ray.origin = vertex.position.xyz + 1e-5f * result.generated_ray.direction;
......@@ -125,135 +119,6 @@ BSDFResult computeBSDF(const in Material material, const in vec2 random, const i
//
//
//
//
// BSDFResult computeBSDFaaaaa(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in)
// {
// const SampledMaterial sampled_material = getMaterialParameters(material, vertex);
// //const vec2 importance_sample = ggxImportanceSample(random);
//
// vec3 backwards_direction = normalize(-ray_in.direction);
//
// bool entering = dot(backwards_direction, vertex.normal.xyz) > 0.f;
// vec3 hemi = randCosineHemisphere(random.x, random.y) * (entering ? 1 : -1);
// vec3 reflected = reflect(-backwards_direction, faceforward(vertex.normal.xyz, -backwards_direction, vertex.normal.xyz));
//
// BSDFResult result;
// result.generated_ray = ray_in;
// result.generated_ray.direction = reflectedDirection(hemi, vertex.normal.xyz, reflected, sampled_material.roughness);
// result.generated_ray.origin = vertex.position.xyz + 1e-5f * result.generated_ray.direction;
//
// result.diffuse_ray.direction = localToWorldNormal(hemi, vertex.normal.xyz).xyz;
// result.diffuse_ray.origin = vertex.position.xyz + 1e-5f*result.diffuse_ray.direction;
//
// vec3 normal_response = normalResponse(sampled_material.diffuse.rgb, sampled_material.ior, sampled_material.metallic);
// vec3 half_vector = normalize(result.generated_ray.direction.xyz + backwards_direction);
//
// float cosT = clamp(dot(result.generated_ray.direction.xyz, vertex.normal.xyz), 0, 1);
// float sinT = sqrt(1 - cosT * cosT);
// vec3 fresnel = fresnelSchlick(clamp(dot(backwards_direction, half_vector), 0, 1), normal_response);
// float geometry = ggxPartialGeometry(backwards_direction, vertex.normal.xyz, half_vector, sampled_material.roughness)
// * ggxPartialGeometry(result.generated_ray.direction, vertex.normal.xyz, half_vector, sampled_material.roughness);
// float denominator = clamp(4 * (clamp(dot(vertex.normal.xyz, backwards_direction), 0, 1) * clamp(dot(half_vector, vertex.normal.xyz), 0, 1)) + 0.05f, 0, 1);
// float distribution = ggxDistribution(vertex.normal.xyz, half_vector, sampled_material.roughness);
//
// vec3 k_specular = fresnel;
// vec3 one_minus_kspec = (1-k_specular);
//
// result.radiance = fresnel * geometry;
// result.distribution = denominator;//cosT * geometry * sinT / denominator;
// result.irradiance = (1-k_specular)*(1-sampled_material.metallic)*sampled_material.diffuse.rgb * ONE_OVER_PI;
// result.bsdf_id = 0;
//
// return result;
// }
//
//
//
//
// BSDFResult computeBSDFabcdefg(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in)
// {
// SampledMaterial sampled_material;
// sampled_material.diffuse = material.getDiffuse(vertex.texcoord);
// sampled_material.specular = material.getSpecular(vertex.texcoord);
// sampled_material.transparent = material.getTransparent(vertex.texcoord);
// sampled_material.emissive = material.getEmissive(vertex.texcoord);
// sampled_material.ambient = material.getAmbient(vertex.texcoord);
//
// sampled_material.roughness = material.getRoughness();
// sampled_material.metallic = clamp((sampled_material.specular.r + sampled_material.specular.g + sampled_material.specular.b )/3, 0, 1);
// sampled_material.ior = 1.56f;//material.ior;
//
// vec3 incoming = normalize(-ray_in.direction);
//
// vec3 normal_response = normalResponse(sampled_material.diffuse.rgb, sampled_material.ior, sampled_material.metallic);
// bool entering = dot(incoming, vertex.normal.xyz) > 0.f;
// vec3 hemi = randUniformSphere(random.x, random.y);
// hemi.z = abs(hemi.z);
// hemi *= (entering ? 1 : -1);
// float distribution = ggxDistribution(vec3(0,0,1), hemi, sampled_material.roughness);
// hemi.xy *= distribution;
// vec3 microsurface_normal = reflectedDirection(hemi, incoming, vertex.normal.xyz, 1);
// vec3 outgoing = reflect(-incoming, microsurface_normal);
// vec3 fresnel = fresnelSchlick(clamp(dot(incoming, microsurface_normal), 0, 1), normal_response);
//
// // m is h
// float n_dot_m = clamp(dot(vertex.normal.xyz, microsurface_normal), 0, 1);
// float n_dot_i = clamp(dot(vertex.normal.xyz, incoming), 0, 1);
// float n_dot_o = clamp(dot(vertex.normal.xyz, outgoing), 0, 1);
// float i_dot_m = clamp(dot(incoming, microsurface_normal), 0, 1);
// float o_dot_m = clamp(dot(outgoing, microsurface_normal), 0, 1);
// float roughness2 = sampled_material.roughness * sampled_material.roughness;
// float sin_theta = sqrt(1 - n_dot_o*n_dot_o);
// float sin_theta_in = sqrt(1 - n_dot_i*n_dot_i);
//
// float geometric_in = ggxPartialGeometry(incoming, vertex.normal.xyz, microsurface_normal, sampled_material.roughness);
// float geometric_out = ggxPartialGeometry(incoming, vertex.normal.xyz, microsurface_normal, sampled_material.roughness);
// float geometric = clamp(min(geometric_in, geometric_out), 0, 1);
// // float n_dot_m2 = 2.0f * n_dot_m;
// // float geom1 = (n_dot_m2 * n_dot_i) / o_dot_m;
// // float geom2 = (n_dot_m2 * n_dot_o) / o_dot_m;
// // float geometric = min(1.0f, min(geom1, geom2));
//
// float denom_part = (roughness2 - 1) * (n_dot_m*n_dot_m) + 1;
// float distribution_part = roughness2 / (denom_part * denom_part);
// //float distribution = distribution_part * ONE_OVER_PI;
// float probability_half_theta = distribution * 2 * n_dot_m;
// // float distribution = ggxDistribution(vertex.normal.xyz, microsurface_normal, sampled_material.roughness);
// float denominator = clamp(4 * (n_dot_i * n_dot_o), 0.05f, 1);
// vec3 specular = (fresnel * geometric * distribution) / denominator;
//
//
// BSDFResult result;
// result.generated_ray = ray_in;
// result.generated_ray.direction = outgoing;
// result.generated_ray.origin = vertex.position.xyz + 1e-5 * outgoing;
// // result.diffuse_ray.direction = localToWorldNormal(hemi, vertex.normal.xyz).xyz;
// //result.diffuse_ray.origin = vertex.position.xyz + 1e-5f*result.diffuse_ray.direction;
// result.radiance = specular;// * distribution;
// result.distribution = probability_half_theta / denominator;// * mix(1, 0.5f, sampled_material.roughness);//sin_theta * ONE_OVER_PI * n_dot_o;
// result.irradiance = vec3(0);//(1-fresnel)*(1-sampled_material.metallic)*sampled_material.diffuse.rgb;
// result.bsdf_id = 0;
// return result;
// }
//
//
//
//
//
//
//
//
......@@ -475,44 +340,44 @@ vec3 sampleEmissive(const in Material material, const in vec2 random, const in V
return vec3(0);
}
subroutine(bsdfSampler)
vec3 sampleGGX(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
{
float roughness = 1-(material.specular_exponent / 100.f);
bool entering = dot(-ray_in.direction.xyz, vertex.normal.xyz) > 0.f;
vec3 hemi = randCosineHemisphere(random.x, random.y);
hemi.xy *= roughness;
vec3 reflected = normalize(reflect(ray_in.direction, faceforward(vertex.normal.xyz, ray_in.direction, vertex.normal.xyz)).xyz);
ray_out.origin = vertex.position.xyz + 1e-5 * -ray_in.direction;
ray_out.direction.xyz = normalize(localToWorldNormal(entering ? hemi : -hemi, reflected.xyz));
vec3 half_view = ggxHalfView(ray_out.direction.xyz, -ray_in.direction.xyz);
vec3 diffuse_color = material.getDiffuse(vertex.texcoord).xyz;
vec3 specular_color = material.getDiffuse(vertex.texcoord).xyz;
bsdf_id = 0;
float metallic = 0.f;
float cosT = clamp(dot(ray_out.direction.xyz, vertex.normal.xyz), 0, 1);
float sinT = sqrt(1 - cosT * cosT);
vec3 fresnel = fresnelSchlick(dot(-ray_in.direction.xyz, half_view), normalResponse(diffuse_color, material.ior, metallic));
float normal_dot_view = dot(vertex.normal.xyz, ray_in.direction.xyz);
float geometry = ggxPartialGeometry(-ray_in.direction.xyz, vertex.normal.xyz, half_view, roughness)
* ggxPartialGeometry(ray_out.direction.xyz, vertex.normal.xyz, half_view, roughness);
float denominator = clamp(4 * (normal_dot_view * dot(half_view, vertex.normal.xyz)) + 0.05f, 0, 1);
pdf = ggxDistribution(vertex.normal.xyz, half_view, roughness);
vec3 specular_factor = fresnel;
vec3 diffuse_factor = (1-specular_factor)*(1-metallic);
light_influence = diffuse_factor * diffuse_color * ONE_OVER_PI;
return diffuse_factor * diffuse_color * ONE_OVER_PI + geometry * fresnel * sinT / denominator;
}
// subroutine(bsdfSampler)
// vec3 sampleGGX(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
// {
// float roughness = 1-(material.specular_exponent / 100.f);
// bool entering = dot(-ray_in.direction.xyz, vertex.normal.xyz) > 0.f;
// vec3 hemi = randCosineHemisphere(random.x, random.y);
// hemi.xy *= roughness;
// vec3 reflected = normalize(reflect(ray_in.direction, faceforward(vertex.normal.xyz, ray_in.direction, vertex.normal.xyz)).xyz);
//
// ray_out.origin = vertex.position.xyz + 1e-5 * -ray_in.direction;
// ray_out.direction.xyz = normalize(localToWorldNormal(entering ? hemi : -hemi, reflected.xyz));
//
// vec3 half_view = ggxHalfView(ray_out.direction.xyz, -ray_in.direction.xyz);
//
// vec3 diffuse_color = material.getDiffuse(vertex.texcoord).xyz;
// vec3 specular_color = material.getDiffuse(vertex.texcoord).xyz;
//
// bsdf_id = 0;
// float metallic = 0.f;
//
// float cosT = clamp(dot(ray_out.direction.xyz, vertex.normal.xyz), 0, 1);
// float sinT = sqrt(1 - cosT * cosT);
//
// vec3 fresnel = fresnelSchlick(dot(-ray_in.direction.xyz, half_view), normalResponse(diffuse_color, material.ior, metallic));
// float normal_dot_view = dot(vertex.normal.xyz, ray_in.direction.xyz);
// float geometry = ggxPartialGeometry(-ray_in.direction.xyz, vertex.normal.xyz, half_view, roughness)
// * ggxPartialGeometry(ray_out.direction.xyz, vertex.normal.xyz, half_view, roughness);
//
// float denominator = clamp(4 * (normal_dot_view * dot(half_view, vertex.normal.xyz)) + 0.05f, 0, 1);
// pdf = ggxDistribution(vertex.normal.xyz, half_view, roughness);
//
// vec3 specular_factor = fresnel;
// vec3 diffuse_factor = (1-specular_factor)*(1-metallic);
//
// light_influence = diffuse_factor * diffuse_color * ONE_OVER_PI;
//
// return diffuse_factor * diffuse_color * ONE_OVER_PI + geometry * fresnel * sinT / denominator;
// }
subroutine uniform bsdfSampler u_bsdf_sample[8];
......
......@@ -5,36 +5,87 @@
#define GGX_PI 3.14159265359f
struct HemisphereSample
{
vec3 micro_normal;
vec2 importance;
float distribution;
};
float normalResponse(float ior, float metallic)
{
float response = abs((1-ior) / (1+ior));
response = response * response;
return mix(response, 1.f, metallic);
}
float fresnelSchlick(float view_dot_half, const in float normal_response)
{
return normal_response + (1-normal_response) * pow(1 - view_dot_half, 5);
}
vec3 fresnelTint(float fresnel, float metallic, const in vec3 material_color)
{
return mix(vec3(1), material_color, metallic) * fresnel;
}
vec2 ggxImportanceSample(const in vec2 random_sample, const in float roughness)
{
// float phi = 2.f * GGX_PI * random_sample.x;
// float theta = acos(sqrt((1.f - random_sample.y) / ((roughness * roughness - 1.f) * random_sample.y + 1.f)));
// return vec2(phi, theta);
float phi = random_sample.y;
// float theta = acos(sqrt((1.f - random_sample.y) / ((roughness * roughness - 1.f) * random_sample.y + 1.f)));
float rough2 = roughness*roughness;
float theta = sqrt(rough2 * random_sample.x / (1 - random_sample.x));
return vec2(phi, theta);
}
vec3 ggxImportantHemisphereSample(const in vec2 random_sample, const in float roughness)
vec3 ggxImportantHemisphereSample(const in vec2 random_sample, const in float roughness, out vec2 importance)
{
vec2 important = ggxImportanceSample(random_sample, roughness);
float phi = important.x * 2.f * PI;
float cosTheta = cos(important.y);
importance = ggxImportanceSample(random_sample, roughness);
float phi = importance.x * 2.f * PI;
float cosTheta = cos(importance.y);
float sinTheta = sqrt(max(0, 1 - cosTheta * cosTheta));
return vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
}
float ggxDist(const in vec3 normal, const in vec3 vector, float roughness)
float ggxPartialGeometry(const in vec3 vector, const in vec3 normal, const in vec3 half_view, float roughness)
{
float normal_dot_half = dot(normal, vector);
float roughness2 = roughness * roughness;
float eye_dot_half2 = clamp(dot(vector, half_view), 0, 1);
float chi = ggxChi(eye_dot_half2 / clamp(dot(vector, normal), 0, 1));
eye_dot_half2 = eye_dot_half2 * eye_dot_half2;
float tan2 = (1 - eye_dot_half2) / eye_dot_half2;
return (chi*2) / (1 + sqrt(1 + roughness * roughness * tan2));
}
float ggxGeometry(const in vec3 vector_in, const in vec3 vector_out, const in vec3 normal, const in vec3 half_view, float roughness)
{
float geom_in = ggxPartialGeometry(vector_in, normal, half_view, roughness);
float geom_out = ggxPartialGeometry(vector_out, normal, half_view, roughness);
return clamp(geom_in * geom_out, 0, 1);
}
HemisphereSample ggxSample(const in vec2 random, const in float roughness)
{
HemisphereSample hemisphere_sample;
hemisphere_sample.micro_normal = ggxImportantHemisphereSample(random, roughness, hemisphere_sample.importance);
hemisphere_sample.distribution = ggxDistribution(hemisphere_sample.importance.y, roughness);
return hemisphere_sample;
}
float ggxDist(const in vec3 normal, const in vec3 vector, float roughness, float cosT)
{
roughness = clamp(roughness, 1e-5f, 1.f);
float normal_dot_half = cosT;
float roughness2 = roughness * roughness;
float normal_dot_half2 = normal_dot_half * normal_dot_half;
float denominator = normal_dot_half2 * roughness2 + (1-normal_dot_half2);
float tan2 = (1-normal_dot_half2) / normal_dot_half2;
float mult = roughness2 + tan2;
mult *= mult;
float denominator = GGX_PI * normal_dot_half2 * normal_dot_half2 * mult;
float d = (ggxChi(dot(normal, vector)) * roughness2) / denominator;
return (ggxChi(normal_dot_half) * roughness2) / (GGX_PI * denominator * denominator);
if(isinf(d)) return 1;//cosT == 0 ? 1 : 0;
return d;
}
float ggxGeom(const in vec3 normal, const in vec3 vector, const in vec3 micro_normal, float roughness)
......
......@@ -15,9 +15,9 @@ float ggxChi(float v)
return v > 0 ? 1 : 0;
}
float ggxDistribution(const in vec3 normal, const in vec3 half_view, float roughness)
float ggxDistribution(float cosT, float roughness)
{
float normal_dot_half = dot(normal, half_view);
float normal_dot_half = cosT;
float roughness2 = roughness * roughness;
float normal_dot_half2 = normal_dot_half * normal_dot_half;
......@@ -26,7 +26,7 @@ float ggxDistribution(const in vec3 normal, const in vec3 half_view, float rough
return (ggxChi(normal_dot_half) * roughness2) / (GGX_PI * denominator * denominator);
}
float ggxPartialGeometry(const in vec3 to_eye, const in vec3 normal, const in vec3 half_view, float roughness)
float ggxPartialGeometrys(const in vec3 to_eye, const in vec3 normal, const in vec3 half_view, float roughness)
{
float eye_dot_half2 = clamp(dot(to_eye, half_view), 0, 1);
float chi = ggxChi(eye_dot_half2 / clamp(dot(to_eye, normal), 0, 1));
......@@ -36,14 +36,14 @@ float ggxPartialGeometry(const in vec3 to_eye, const in vec3 normal, const in ve
return (chi*2) / (1 + sqrt(1 + roughness * roughness * tan2));
}
vec3 normalResponse(const in vec3 material_color, float ior, float metallic)
vec3 normalResponses(const in vec3 material_color, float ior, float metallic)
{
vec3 response = vec3(abs((1-ior) / (1+ior)));
response = response * response;
return mix(response, material_color, metallic);
}
vec3 fresnelSchlick(float view_dot_half, const in vec3 normal_response)
vec3 fresnelSchlicks(float view_dot_half, const in vec3 normal_response)
{
return normal_response + (1-normal_response) * pow(1 - view_dot_half, 5);
}
......@@ -68,9 +68,9 @@ vec3 ggxSpecular(samplerCube environment, const in vec3 normal, const in vec3 to
float cosT = clamp(dot(random_direction, normal), 0, 1);
float sinT = sqrt(1 - cosT * cosT);
vec3 fresnel = fresnelSchlick(dot(to_eye, half_vector), normal_response);
vec3 fresnel = fresnelSchlicks(dot(to_eye, half_vector), normal_response);
float geometry = ggxPartialGeometry(to_eye, normal, half_vector, roughness) * ggxPartialGeometry(random_direction, normal, half_vector, roughness);
float geometry = ggxPartialGeometrys(to_eye, normal, half_vector, roughness) * ggxPartialGeometrys(random_direction, normal, half_vector, roughness);
float denominator = clamp(4 * (normal_dot_view * dot(half_vector, normal)) + 0.05f, 0, 1);
k_specular += fresnel;
......
......@@ -180,7 +180,7 @@ vec4 phong(const in LightWithShadowmap light_and_map, samplerCube environment, c
// float cos_phi_n = GGX_Distribution(normal, half_vector, 1-shininess);
float f_metallic = metallic ? 1 :0;
float roughness = 1-shininess;
vec3 fresnel = fresnelSchlick(dot(eye, half_vector), normalResponse(diffuse.xyz, 1.56, f_metallic));
vec3 fresnel = fresnelSchlicks(dot(eye, half_vector), normalResponses(diffuse.xyz, 1.56, f_metallic));
vec3 reflection = textureLod(environment, reflection_vec, roughness * 8).rgb;
vec4 phong_diffuse = (diffuse * cos_phi * color);
......
#include <cinttypes>
#include <util/log.h>
#include <core/time.h>
#include <glm/glm.hpp>
int main(int argc, char* argv[])
{
using uint = unsigned;
for (uint h = 0; h < 200; ++h)
{
int k = rand()%1902;
Log_Info << "----------------------------------------------";
std::vector<int> t1(1000000);
glare::core::ClockNS clock;
#define in
#define ggxChi(a) (a > 0 ? 1 : 0)
using namespace glm;
for (uint i = 0; i < 1000000; ++i)
{
if (i % k == 0)
{
t1[i] = i;
}
else
{
t1[i] = -i;
}
}
float ggxDist(float roughness, float cosT)
{
//roughness += 1e-5f;
//float normal_dot_half = cosT;
//float roughness2 = roughness * roughness;
//float normal_dot_half2 = normal_dot_half * normal_dot_half;
//float tan2 = (1 - normal_dot_half2) / normal_dot_half2;
//float mult = roughness2 + tan2;
//mult *= mult;
//float denominator = 3.141592f * normal_dot_half2 * normal_dot_half2 * mult;
Log_Info << "Took " << clock.restart() << "ns";
std::vector<int> t2(1000000);
clock.restart();
//return (ggxChi(cosT) * roughness2) / denominator;
float alphaSqr = max(roughness * roughness, 0.005f);
float denom = cosT * cosT * (alphaSqr - 1.0) + 1.0;
return alphaSqr / (denom * denom);
}
for (uint i = 0; i < 1000000; ++i)
{
switch (i % k == 0)
{
case true:
{ t2[i] = i; } break;
case false:
{ t2[i] = -i; } break;
}
}
int main(int argc, char* argv[])
{
auto i = ggxDist(0, 1);
auto a = ggxDist(0, 0.5f);
auto r = ggxDist(0.5f, 1);
auto z = ggxDist(0.5f, 0.5f);
auto t = ggxDist(1, 1);
auto h = ggxDist(1, 0.5f);
Log_Info << "Took " << clock.time() << "ns";
}
system("pause");
}
\ No newline at end of file
Markdown is supported
0% or .