UNPKG

@babylonjs/core

Version:

Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.

68 lines 6.24 kB
// Do not edit. import { ShaderStore } from "../../Engines/shaderStore.js"; const name = "openpbrVolumeFunctions"; const shader = `struct OpenPBRHomogeneousVolume {extinction_coeff: vec3f, ss_albedo: vec3f, multi_scatter_color: vec3f, absorption_coeff: vec3f, scatter_coeff: vec3f, anisotropy: f32, };fn computeOpenPBRTransmissionVolume( transmission_color: vec3f, transmission_depth: f32, transmission_scatter: vec3f, anisotropy: f32 )->OpenPBRHomogeneousVolume {var volumeParams: OpenPBRHomogeneousVolume;volumeParams.absorption_coeff=vec3f(0.0f);volumeParams.scatter_coeff=vec3f(0.0f);volumeParams.anisotropy=anisotropy; #ifdef GEOMETRY_THIN_WALLED volumeParams.scatter_coeff=vec3f(1.0f);volumeParams.anisotropy=1.0f; volumeParams.extinction_coeff=volumeParams.absorption_coeff+volumeParams.scatter_coeff;volumeParams.ss_albedo=vec3f(1.0f); #else if (transmission_depth>0.0f) {let invDepth: vec3f=vec3f(1.f/maxEps(transmission_depth));volumeParams.extinction_coeff=-log(maxEpsVec3(transmission_color.rgb))*invDepth;volumeParams.scatter_coeff=transmission_scatter.rgb*invDepth;volumeParams.absorption_coeff=volumeParams.extinction_coeff-volumeParams.scatter_coeff.rgb;let minCoeff: f32=min3(volumeParams.absorption_coeff);if (minCoeff<0.0f) {volumeParams.absorption_coeff-=vec3f(minCoeff);} volumeParams.extinction_coeff=volumeParams.absorption_coeff+volumeParams.scatter_coeff;volumeParams.ss_albedo=volumeParams.scatter_coeff/(volumeParams.extinction_coeff);} else {volumeParams.extinction_coeff=volumeParams.absorption_coeff+volumeParams.scatter_coeff;volumeParams.ss_albedo=vec3f(0.0f);} #endif return volumeParams;} fn computeOpenPBRSubsurfaceVolume( subsurface_color: vec3f, subsurface_radius: f32, subsurface_radius_scale: vec3f, anisotropy: f32 )->OpenPBRHomogeneousVolume {var volumeParams: OpenPBRHomogeneousVolume;volumeParams.absorption_coeff=vec3f(0.0f);volumeParams.scatter_coeff=vec3f(0.0f);volumeParams.anisotropy=anisotropy;volumeParams.multi_scatter_color=subsurface_color;let mfp: vec3f=subsurface_radius_scale*vec3f(subsurface_radius);volumeParams.extinction_coeff=vec3f(1.0f)/maxEpsVec3(mfp);volumeParams.ss_albedo=multiScatterToSingleScatterAlbedoWithAniso(subsurface_color,anisotropy);volumeParams.scatter_coeff=volumeParams.ss_albedo*volumeParams.extinction_coeff;volumeParams.absorption_coeff=volumeParams.extinction_coeff-volumeParams.scatter_coeff.rgb;let minCoeff: f32=min3(volumeParams.absorption_coeff);if (minCoeff<0.0f) {volumeParams.absorption_coeff-=vec3f(minCoeff);} volumeParams.extinction_coeff=volumeParams.absorption_coeff+volumeParams.scatter_coeff;return volumeParams;} fn sss_pdf(r: f32,d: vec3f)->vec3f {let d_clamped=max(vec3f(1e-4f),d);return (exp(-r/d_clamped)+exp(-r/(3.0f*d_clamped)))/max(vec3f(1e-5f),8.0f*PI*d_clamped*r);} fn sss_samples_pdf(r: f32,d: f32)->f32 {let d_clamped=max(1e-4f,d);return exp(-r/(3.0f*d_clamped))/(6.0f*PI*d_clamped*r);} fn sss_samples_icdf(x: f32,d: f32)->f32 {let d_clamped=max(1e-4f,d);let x_clamped=max(1e-4f,x);return -3.0f*log(x_clamped)*d_clamped;} fn samples_scale(x: f32,d: f32)->f32 {return 1.0f-exp(-x/(3.0f*d));} fn sss_get_position(depth_texture: texture_2d<f32>,tex_coord: vec2f,render_resolution: vec2f,inv_proj: mat4x4f)->vec3f {var P: vec4f=vec4f(tex_coord,textureLoad(depth_texture,vec2i(tex_coord*render_resolution),0).x,1.0f);P.x=2.0f*P.x-1.0f;P.y=2.0f*P.y-1.0f;P=inv_proj*P;return P.xyz/P.w;} fn sss_filter_scale(currZ: f32,proj: mat4x4f)->f32 {return 1.0f/dot(vec2f(proj[2].w,proj[3].w),vec2f(currZ,1.0f));} fn projective_to_pixels(proj_dist: f32,proj: mat4x4f,resolution: vec2f)->f32 {return proj_dist*proj[1][1]*resolution.y;} fn pixels_to_projective(pixel_dist: f32,proj: mat4x4f,resolution: vec2f)->f32 {return pixel_dist/(proj[1][1]*resolution.y);} fn sss_convolve(sss_irradiance_texture: texture_2d<f32>,depth_texture: texture_2d<f32>,render_resolution: vec2f,d: vec3f,proj: mat4x4f,inv_proj: mat4x4f,sample_count: i32,noise: vec2f)->vec3f {let tex_coord: vec2f=fragmentInputs.position.xy/render_resolution;let unconvolved_irradiance: vec3f=textureLoad(sss_irradiance_texture,vec2i(fragmentInputs.position.xy),0).rgb;let curr_pos: vec3f=sss_get_position(depth_texture,tex_coord,render_resolution,inv_proj);var dmax: f32=max3(d);let max_dmax: f32=0.1*f32(sample_count);var d_adjusted=d;if (dmax>max_dmax) {d_adjusted*=max_dmax/dmax;dmax=max_dmax;} var dz: f32=dmax*sss_filter_scale(curr_pos.z,proj);let projMat2d: mat2x2f=mat2x2f(proj[0].xy,proj[1].xy);if (determinant(projMat2d)*dz<1e-4f) {return unconvolved_irradiance;} let overscan_size_in_pixels: f32=max(render_resolution.x,render_resolution.y)*0.1;let filter_crop_ratio: f32=0.8f; let crop_radius: f32=projective_to_pixels(sss_samples_icdf(1.0f-filter_crop_ratio,dz),proj,render_resolution);if (crop_radius>overscan_size_in_pixels) {d_adjusted*=overscan_size_in_pixels/crop_radius;dz*=overscan_size_in_pixels/crop_radius;} let filter_samples_scale: f32=samples_scale(pixels_to_projective(overscan_size_in_pixels,proj,render_resolution),dz);var irradiance_sum: vec3f=vec3f(0.0f);var weight_sum: vec3f=vec3f(0.0f);for (var i: i32=0; i<sample_count; i++) {var r: vec2f=fract(plasticSequence(u32(i+sample_count))+noise*vec2(0.2));r.x*=TWO_PI;r.y*=filter_samples_scale;let icdf: f32=sss_samples_icdf(1.0-r.y,dz);let sample_uv: vec2f=tex_coord+icdf*projMat2d*vec2f(cos(r.x),sin(r.x));let sss_irradiance: vec4f=textureLoad(sss_irradiance_texture,vec2i(sample_uv*render_resolution),0);let dist: f32=distance(curr_pos,sss_get_position(depth_texture,sample_uv,render_resolution,inv_proj));if (dist>0.0f) {let weights: vec3f=sss_irradiance.a/sss_samples_pdf(icdf,dz)*sss_pdf(dist,d_adjusted);irradiance_sum+=weights*sss_irradiance.rgb;weight_sum+=weights;}} return vec3f(select(unconvolved_irradiance.r,irradiance_sum.r/weight_sum.r,weight_sum.r>=1e-5f), select(unconvolved_irradiance.g,irradiance_sum.g/weight_sum.g,weight_sum.g>=1e-5f), select(unconvolved_irradiance.b,irradiance_sum.b/weight_sum.b,weight_sum.b>=1e-5f));} `; // Sideeffect if (!ShaderStore.IncludesShadersStoreWGSL[name]) { ShaderStore.IncludesShadersStoreWGSL[name] = shader; } /** @internal */ export const openpbrVolumeFunctionsWGSL = { name, shader }; //# sourceMappingURL=openpbrVolumeFunctions.js.map