diff --git a/zenovis/xinxinoptix/DeflMatShader.cu b/zenovis/xinxinoptix/DeflMatShader.cu index ab3c171cb9..ea7d1f7fcc 100644 --- a/zenovis/xinxinoptix/DeflMatShader.cu +++ b/zenovis/xinxinoptix/DeflMatShader.cu @@ -79,20 +79,20 @@ MatInput const &attrs) { MatOutput mats; /* MODME */ mats.basecolor = mat_basecolor; - mats.metallic = mat_metallic; - mats.roughness = mat_roughness; + mats.metallic = clamp(mat_metallic,0.0f,1.0f); + mats.roughness = clamp(mat_roughness,0.01,0.99); mats.subsurface = mat_subsurface; mats.specular = mat_specular; mats.specularTint = mat_specularTint; - mats.anisotropic = mat_anisotropic; + mats.anisotropic = clamp(mat_anisotropic,0.0f,1.0f); mats.sheen = mat_sheen; mats.sheenTint = mat_sheenTint; - mats.clearcoat = mat_clearcoat; + mats.clearcoat = clamp(mat_clearcoat,0.0f,1.0f); mats.clearcoatGloss = mat_clearcoatGloss; mats.opacity = mat_opacity; mats.nrm = mat_normal; mats.emission = mat_emission; - mats.specTrans = mat_specTrans; + mats.specTrans = clamp(mat_specTrans,0.0f,1.0f); mats.ior = mat_ior; mats.scatterDistance = mat_scatterDistance; mats.flatness = mat_flatness; @@ -228,7 +228,7 @@ extern "C" __global__ void __anyhit__shadow_cutout() N = mats.nrm.x * attrs.tang + mats.nrm.y * b + mats.nrm.z * attrs.nrm; } //end of material computation - mats.metallic = clamp(mats.metallic,0.01, 0.99); + //mats.metallic = clamp(mats.metallic,0.01, 0.99); mats.roughness = clamp(mats.roughness, 0.01,0.99); /* MODME */ @@ -390,7 +390,7 @@ extern "C" __global__ void __closesthit__radiance() zenotex30, zenotex31,attrs); //end of material computation - mats.metallic = clamp(mats.metallic,0.01, 0.99); + //mats.metallic = clamp(mats.metallic,0.01, 0.99); mats.roughness = clamp(mats.roughness, 0.01,0.99); if(length(attrs.tang)>0) { @@ -528,7 +528,7 @@ extern "C" __global__ void __closesthit__radiance() } - //prd->passed = (flag == DisneyBSDF::transmissionEvent) ; + prd->passed = (flag == DisneyBSDF::transmissionEvent) ; prd->prob *= 1.0f; prd->origin = P; diff --git a/zenovis/xinxinoptix/DisneyBRDF.h b/zenovis/xinxinoptix/DisneyBRDF.h index 0a74641e27..4a1b982860 100644 --- a/zenovis/xinxinoptix/DisneyBRDF.h +++ b/zenovis/xinxinoptix/DisneyBRDF.h @@ -26,7 +26,7 @@ static __inline__ __device__ float SchlickWeight(float u) } static __inline__ __device__ float fresnelSchlickR0(float eta) { - return pow(eta - 1.0f, 2.0f) / (pow(eta + 1.0f, 2.0f) + 1e-6); + return pow(eta - 1.0f, 2.0f) / (pow(eta + 1.0f, 2.0f) ); } static __inline__ __device__ float SchlickDielectic(float cosThetaI, float relativeIor) { @@ -46,7 +46,7 @@ static __inline__ __device__ float fresnelDielectric(float cosThetaI, float ni, } float sinThetaI = sqrtf(max(0.0f, 1.0f - cosThetaI * cosThetaI)); - float sinThetaT = ni / (nt + 1e-6) * sinThetaI; + float sinThetaT = ni / (nt + 1e-5) * sinThetaI; if(sinThetaT >= 1) { @@ -55,23 +55,23 @@ static __inline__ __device__ float fresnelDielectric(float cosThetaI, float ni, float cosThetaT = sqrtf(max(0.0f, 1.0f - sinThetaT * sinThetaT)); - float rParallel = ((nt * cosThetaI) - (ni * cosThetaT)) / ((nt * cosThetaI) + (ni * cosThetaT) + 1e-6); - float rPerpendicuar = ((ni * cosThetaI) - (nt * cosThetaT)) / ((ni * cosThetaI) + (nt * cosThetaT) + 1e-6); + float rParallel = ((nt * cosThetaI) - (ni * cosThetaT)) / ((nt * cosThetaI) + (ni * cosThetaT) + 1e-5); + float rPerpendicuar = ((ni * cosThetaI) - (nt * cosThetaT)) / ((ni * cosThetaI) + (nt * cosThetaT) + 1e-5); return (rParallel * rParallel + rPerpendicuar * rPerpendicuar) / 2; } static __inline__ __device__ float GTR1(float cosT,float a){ if(a >= 1.0f) return 1/M_PIf; float t = (1+(a*a-1)*cosT*cosT); - return (a*a-1.0f) / (M_PIf*logf(a*a)*t); + return (a*a-1.0f) / (M_PIf*logf(a*a)*t + 1e-5); } static __inline__ __device__ float GTR2(float cosT,float a){ float t = (1+(a*a-1)*cosT*cosT); - return (a*a) / (M_PIf*t*t); + return (a*a) / (M_PIf*t*t + 1e-5); } static __inline__ __device__ float GGX(float cosT, float a){ float a2 = a*a; float b = cosT*cosT; - return 2.0f/ (1.0f + sqrtf(a2 + b - a2*b)); + return 2.0f/ (1.0f + sqrtf(a2 + b - a2*b)); } static __inline__ __device__ vec3 sampleOnHemisphere(unsigned int &seed, float roughness) { @@ -115,7 +115,7 @@ static __inline__ __device__ void CalculateAnisotropicParams(float roughness, float anisotropic, float &ax, float &ay) { float aspect = sqrtf(1.0f - 0.9f * anisotropic); - ax = max(0.001f, roughness*roughness / (aspect + 1e-6)); + ax = max(0.001f, roughness*roughness / (aspect)); ay = max(0.001f, roughness*roughness * aspect); } static __inline__ __device__ @@ -127,14 +127,14 @@ vec3 CalculateTint(vec3 baseColor) static __inline__ __device__ float SeparableSmithGGXG1(vec3 w, vec3 wm, float ax, float ay) { - if(abs(w.z)<1e-7) { + if(abs(w.z)<1e-5) { return 0.0f; } float sinTheta = sqrtf(1.0f - w.z * w.z); float absTanTheta = abs( sinTheta / w.z); - float Cos2Phi = (sinTheta == 0.0f)? 1.0f:clamp(w.x / (sinTheta + 1e-6), -1.0f, 1.0f); + float Cos2Phi = (sinTheta == 0.0f)? 1.0f:clamp(w.x / (sinTheta + 1e-5), -1.0f, 1.0f); Cos2Phi *= Cos2Phi; - float Sin2Phi = (sinTheta == 0.0f)? 1.0f:clamp(w.y / (sinTheta + 1e-6), -1.0f, 1.0f); + float Sin2Phi = (sinTheta == 0.0f)? 1.0f:clamp(w.y / (sinTheta + 1e-5), -1.0f, 1.0f); Sin2Phi *= Sin2Phi; float a = sqrtf(Cos2Phi * ax * ax + Sin2Phi * ay * ay); float a2Tan2Theta = pow(a * absTanTheta, 2.0f); @@ -150,7 +150,7 @@ static __inline__ __device__ float GgxAnisotropicD(vec3 wm, float ax, float ay) float ax2 = ax * ax; float ay2 = ay * ay; - return 1.0f / (M_PIf * ax * ay * powf(dotHX2 / ax2 + dotHY2 / ay2 + cos2Theta, 2.0f) + 1e-6); + return 1.0f / (M_PIf * ax * ay * powf(dotHX2 / ax2 + dotHY2 / ay2 + cos2Theta, 2.0f) + 1e-5); } static __inline__ __device__ void GgxVndfAnisotropicPdf(vec3 wi, vec3 wm, vec3 wo, float ax, float ay, @@ -161,35 +161,37 @@ static __inline__ __device__ void GgxVndfAnisotropicPdf(vec3 wi, vec3 wm, vec3 w float absDotNL = abs(wi.z); float absDotHL = abs(dot(wm, wi)); float G1v = SeparableSmithGGXG1(wo, wm, ax, ay); - forwardPdfW = G1v * absDotHL * D / (absDotNL + 1e-6); + forwardPdfW = G1v * absDotHL * D / (absDotNL); float absDotNV = abs(wo.z); float absDotHV = abs(dot(wm, wo)); float G1l = SeparableSmithGGXG1(wi, wm, ax, ay); - reversePdfW = G1l * absDotHV * D / (absDotNV + 1e-6); + reversePdfW = G1l * absDotHV * D / (absDotNV); } static __inline__ __device__ vec3 SampleGgxVndfAnisotropic(vec3 wo, float ax, float ay, float u1, float u2) { // -- Stretch the view vector so we are sampling as though roughness==1 - vec3 v = normalize(vec3(wo.x * ax, wo.y * ay, wo.z)); - - // -- Build an orthonormal basis with v, t1, and t2 - vec3 t1 = (v.z < 0.9999f) ? normalize(cross(v, vec3(0,0,1))) : vec3(1,0,0); - vec3 t2 = cross(t1, v); - - // -- Choose a point on a disk with each half of the disk weighted proportionally to its projection onto direction v - float a = 1.0f / (1.0f + v.z); - float r = sqrtf(u1); - float phi = (u2 < a) ? (u2 / a) * M_PIf : M_PIf + (u2 - a) / (1.0f - a) * M_PIf; - float p1 = r * cos(phi); - float p2 = r * sin(phi) * ((u2 < a) ? 1.0f : v.z); - - // -- Calculate the normal in this stretched tangent space - vec3 n = p1 * t1 + p2 * t2 + sqrtf(max(0.0f, 1.0f - p1 * p1 - p2 * p2)) * v; - - // -- unstretch and normalize the normal - return normalize(vec3(ax * n.x, ay * n.y, n.z)); + vec3 Vh = normalize(vec3(ax * wo.x, ay * wo.y, wo.z)); + + // Section 4.1: orthonormal basis (with special case if cross product is zero) + float lensq = Vh.x * Vh.x + Vh.y * Vh.y; + vec3 T1 = lensq > 0.0f ? vec3(-Vh.y, Vh.x, 0.0f) / sqrt(lensq) : vec3(1.0f, 0.0f, 0.0f); + vec3 T2 = cross(Vh, T1); + + // Section 4.2: parameterization of the projected area + float r = sqrt(u1); + float phi = M_PIf * 2.0 * u2; + float t1 = r * cos(phi); + float t2 = r * sin(phi); + float s = 0.5f * (1.0f + Vh.z); + t2 = mix(sqrt(1.0f - t1 * t1), t2, s); + + // Section 4.3: reprojection onto hemisphere + vec3 Nh = t1 * T1 + t2 * T2 + sqrt(max(0.0f, 1.0f - t1 * t1 - t2 * t2)) * Vh; + + // Section 3.4: transforming the normal back to the ellipsoid configuration + return normalize(vec3(ax * Nh.x, ay * Nh.y, max(0.0f, Nh.z))); } } namespace DisneyBRDF diff --git a/zenovis/xinxinoptix/DisneyBSDF.h b/zenovis/xinxinoptix/DisneyBSDF.h index 60ef82b681..50d1e22afb 100644 --- a/zenovis/xinxinoptix/DisneyBSDF.h +++ b/zenovis/xinxinoptix/DisneyBSDF.h @@ -58,7 +58,7 @@ namespace DisneyBSDF{ vec3 alpha = vec3(1.0f) - exp(-5.09406f * a + 2.61188f * a2 - 4.31805f * a3); vec3 s = vec3(1.9f) - a + 3.5f * (a - vec3(0.8f)) * (a - vec3(0.8f)); - return 1.0f / dot(s , scatterDistance); + return vec3(1.0f / dot(s, vec3(scatterDistance))); } static __inline__ __device__ @@ -85,7 +85,7 @@ namespace DisneyBSDF{ float diffuseW = dielectricBRDF; float clearcoatW = 1.0f * clamp(clearCoat, 0.0f, 1.0f); - float norm = 1.0f/(specularW + transmissionW + diffuseW + clearcoatW + 1e-6); + float norm = 1.0f/(specularW + transmissionW + diffuseW + clearcoatW); pSpecular = specularW * norm; pSpecTrans = transmissionW * norm; @@ -511,7 +511,7 @@ namespace DisneyBSDF{ fPdf = d / (4.0f * dot(wo,wm)); rPdf = d /(4.0f * LoH); - reflectance = vec3(0.25f * clearCoat * g * f *d ) / rPdf; + reflectance = vec3(0.25f * clearCoat * g * f *d ) / rPdf; Onb tbn = Onb(N); tbn.inverse_transform(wi); @@ -596,7 +596,7 @@ namespace DisneyBSDF{ reflectance = G1v * baseColor; //fPdf *= (1.0f / (4 * abs(dot(wo, wm)))); - float jacobian = 4 * abs(VoH); + float jacobian = 4 * abs(VoH) + 1e-5; pdf = F / jacobian; }else{ @@ -618,7 +618,7 @@ namespace DisneyBSDF{ reflectance = G1v * baseColor; } float LoH = abs(dot(wi,wm)); - float jacobian = LoH / (pow(LoH + relativeIOR * VoH, 2.0f)); + float jacobian = LoH / (pow(LoH + relativeIOR * VoH, 2.0f) + 1e-5) + 1e-5; pdf = (1.0f - F) / jacobian; } @@ -681,19 +681,13 @@ namespace DisneyBSDF{ ) { - float si; - if(wo.z != 0.0f){ - si = wo.z > 0.0f ? 1.0f : -1.0f; - }else{ - si = 0.0f; - } float r0 = rnd(seed); float r1 = rnd(seed); - wi = normalize(si * BRDFBasics::sampleOnHemisphere(seed, 1.0f)); + wi = normalize(BRDFBasics::sampleOnHemisphere(seed, 1.0f)); vec3 wm = normalize(wi+wo); float NoL = wi.z; - if(NoL == 0.0f){ + if(abs(NoL)<1e-6 ){ fPdf = 0.0f; rPdf = 0.0f; reflectance = vec3(0.0f); @@ -701,7 +695,7 @@ namespace DisneyBSDF{ return false; } - float NoV = NoL; + float NoV = wo.z; vec3 color = baseColor; float pdf; @@ -728,7 +722,7 @@ namespace DisneyBSDF{ vec3 sheenTerm = EvaluateSheen(baseColor, sheen, sheenTint, HoL); float diff = EvaluateDisneyDiffuse(roughness, flatness, wi, wo, wm, thin); - reflectance = sheen + color * (diff / pdf); + reflectance = sheen + color * (diff / (pdf)); fPdf = abs(NoL) * pdf; rPdf = abs(NoL) * pdf; Onb tbn = Onb(N); @@ -816,7 +810,9 @@ namespace DisneyBSDF{ fPdf = 0.000000001f; rPdf = 0.000000001f; } + reflectance = clamp(reflectance, vec3(0,0,0), vec3(1,1,1)); if(pLobe > 0.0f){ + pLobe = clamp(pLobe, 0.001f, 0.999f); reflectance = reflectance * (1.0f/pLobe); rPdf *= pLobe; fPdf *= pLobe; diff --git a/zenovis/xinxinoptix/PTKernel.cu b/zenovis/xinxinoptix/PTKernel.cu index 4ed7663b14..8dc105d829 100644 --- a/zenovis/xinxinoptix/PTKernel.cu +++ b/zenovis/xinxinoptix/PTKernel.cu @@ -65,7 +65,7 @@ extern "C" __global__ void __raygen__rg() //result += prd.emitted; if(prd.countEmitted==false || depth>0) - result += prd.radiance * prd.attenuation2/(prd.prob2+1e-6); + result += prd.radiance * prd.attenuation2/(prd.prob2+1e-5); if(prd.countEmitted==true && depth>0) prd.done = true; if( prd.done || depth >= 5 ) // TODO RR, variable for depth