From 8027f287eb46d487a0e379911bdbc4d6c2bf44e4 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 27 Feb 2022 23:41:11 +0000 Subject: asymptote 2.78 support files git-svn-id: svn://tug.org/texlive/trunk@62265 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/asymptote/shaders/blend.glsl | 131 +++++++++++++ Master/texmf-dist/asymptote/shaders/count.glsl | 11 ++ Master/texmf-dist/asymptote/shaders/count0.glsl | 11 ++ Master/texmf-dist/asymptote/shaders/fragment.glsl | 209 +++++++++++++-------- Master/texmf-dist/asymptote/shaders/offset.glsl | 11 ++ .../texmf-dist/asymptote/shaders/partialsum.glsl | 37 ++++ Master/texmf-dist/asymptote/shaders/presum.glsl | 37 ++++ Master/texmf-dist/asymptote/shaders/screen.glsl | 5 + Master/texmf-dist/asymptote/shaders/vertex.glsl | 15 +- 9 files changed, 388 insertions(+), 79 deletions(-) create mode 100755 Master/texmf-dist/asymptote/shaders/blend.glsl create mode 100755 Master/texmf-dist/asymptote/shaders/count.glsl create mode 100755 Master/texmf-dist/asymptote/shaders/count0.glsl create mode 100755 Master/texmf-dist/asymptote/shaders/offset.glsl create mode 100755 Master/texmf-dist/asymptote/shaders/partialsum.glsl create mode 100755 Master/texmf-dist/asymptote/shaders/presum.glsl create mode 100755 Master/texmf-dist/asymptote/shaders/screen.glsl (limited to 'Master/texmf-dist/asymptote/shaders') diff --git a/Master/texmf-dist/asymptote/shaders/blend.glsl b/Master/texmf-dist/asymptote/shaders/blend.glsl new file mode 100755 index 00000000000..629cc2dda5e --- /dev/null +++ b/Master/texmf-dist/asymptote/shaders/blend.glsl @@ -0,0 +1,131 @@ +layout(binding=0, std430) buffer sumBuffer { + uint sum[]; +}; + +layout(binding=1, std430) buffer offsetBuffer { + uint offset[]; +}; + +layout(binding=2, std430) buffer countBuffer { + uint count[]; +}; + +layout(binding=3, std430) buffer fragmentBuffer { + vec4 fragment[]; +}; + +layout(binding=4, std430) buffer depthBuffer { + float depth[]; +}; + +layout(binding=5, std430) buffer opaqueBuffer { + vec4 opaqueColor[]; +}; + +layout(binding=6, std430) buffer opaqueDepthBuffer { + float opaqueDepth[]; +}; + +out vec4 outColor; + +uniform uint width; +uniform uint M; +uniform uint r; +uniform vec4 background; + +vec4 blend(vec4 outColor, vec4 color) +{ + return mix(outColor,color,color.a); +} + +void main() +{ + uint headIndex=uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x); + uint size=count[headIndex]; + float OpaqueDepth=opaqueDepth[headIndex]; + if(size == 0u) { +#ifdef GPUINDEXING + offset[headIndex]=0u; +#endif + opaqueDepth[headIndex]=0.0; + discard; + } + + uint listIndex= +#ifdef GPUINDEXING + sum[headIndex < r*(M+1u) ? headIndex/(M+1u) : (headIndex-r)/M]+ +#endif + offset[headIndex]; + const uint maxSize=16u; + + // Sort the fragments with respect to descending depth + if(size < maxSize) { + vec4 sortedColor[maxSize]; + float sortedDepth[maxSize]; + + uint k=0u; + + if(OpaqueDepth != 0.0) + while(k < size && depth[listIndex+k] >= OpaqueDepth) + ++k; + + uint i=0u; + if(k < size) { + sortedColor[0]=fragment[listIndex+k]; + sortedDepth[0]=depth[listIndex+k]; + ++k; + i=1u; + while(true) { + if(OpaqueDepth != 0.0) + while(k < size && depth[listIndex+k] >= OpaqueDepth) + ++k; + if(k == size) break; + float D=depth[listIndex+k]; + uint j=i; + float d; + while(j > 0u && D > sortedDepth[j-1u]) { + sortedColor[j]=sortedColor[j-1u]; + sortedDepth[j]=sortedDepth[j-1u]; + --j; + } + sortedColor[j]=fragment[listIndex+k]; + sortedDepth[j]=D; + ++i; + ++k; + } + } + outColor=OpaqueDepth != 0.0 ? opaqueColor[headIndex] : background; + for(uint j=0u; j < i; ++j) + outColor=blend(outColor,sortedColor[j]); + } else { + uint k=0u; + if(OpaqueDepth != 0.0) + while(k < size && depth[listIndex+k] >= OpaqueDepth) + ++k; + for(uint i=k+1u; i < size; i++) { + vec4 temp=fragment[listIndex+i]; + float D=depth[listIndex+i]; + uint j=i; + while(j > 0u && D > depth[listIndex+j-1u]) { + fragment[listIndex+j]=fragment[listIndex+j-1u]; + depth[listIndex+j]=depth[listIndex+j-1u]; + --j; + } + fragment[listIndex+j]=temp; + depth[listIndex+j]=D; + } + + outColor=OpaqueDepth != 0.0 ? opaqueColor[headIndex] : background; + uint stop=listIndex+size; + for(uint i=listIndex+k; i < stop; i++) { + if(OpaqueDepth == 0.0 || depth[i] < OpaqueDepth) + outColor=blend(outColor,fragment[i]); + } + } + + count[headIndex]=0u; + opaqueDepth[headIndex]=0.0; +#ifdef GPUINDEXING + offset[headIndex]=0u; +#endif +} diff --git a/Master/texmf-dist/asymptote/shaders/count.glsl b/Master/texmf-dist/asymptote/shaders/count.glsl new file mode 100755 index 00000000000..dae4e51f1b7 --- /dev/null +++ b/Master/texmf-dist/asymptote/shaders/count.glsl @@ -0,0 +1,11 @@ +layout(binding=2, std430) buffer countBuffer { + uint count[]; +}; + +uniform uint width; + +void main() +{ + atomicAdd(count[uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x)],1u); + discard; +} diff --git a/Master/texmf-dist/asymptote/shaders/count0.glsl b/Master/texmf-dist/asymptote/shaders/count0.glsl new file mode 100755 index 00000000000..9bcb6d222e5 --- /dev/null +++ b/Master/texmf-dist/asymptote/shaders/count0.glsl @@ -0,0 +1,11 @@ +layout(binding=2, std430) buffer countBuffer { + uint count[]; +}; + +uniform uint width; + +void main() +{ + count[uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x)]=0u; + discard; +} diff --git a/Master/texmf-dist/asymptote/shaders/fragment.glsl b/Master/texmf-dist/asymptote/shaders/fragment.glsl index 057acbc744f..5f60a56efd3 100755 --- a/Master/texmf-dist/asymptote/shaders/fragment.glsl +++ b/Master/texmf-dist/asymptote/shaders/fragment.glsl @@ -10,25 +10,13 @@ struct Light vec3 color; }; -uniform int nlights; +uniform uint nlights; uniform Light lights[max(Nlights,1)]; uniform MaterialBuffer { Material Materials[Nmaterials]; }; -#ifdef NORMAL -#ifndef ORTHOGRAPHIC -in vec3 ViewPosition; -#endif -in vec3 Normal; -vec3 normal; -#endif - -#ifdef COLOR -in vec4 Color; -#endif - flat in int materialIndex; out vec4 outColor; @@ -38,41 +26,107 @@ vec3 Specular; // Specular tint for nonmetals float Metallic; // Metallic/Nonmetals parameter float Fresnel0; // Fresnel at zero for nonmetals float Roughness2; // roughness squared, for smoothing +float Roughness; + +#ifdef HAVE_SSBO + +layout(binding=0, std430) buffer sumBuffer { + uint sum[]; +}; + +layout(binding=1, std430) buffer offsetBuffer { + uint offset[]; +}; + +layout(binding=2, std430) buffer countBuffer { + uint count[]; +}; -#ifdef ENABLE_TEXTURE -uniform sampler2D environmentMap; -const float PI=acos(-1.0); -const float twopi=2*PI; -const float halfpi=PI/2; +layout(binding=3, std430) buffer fragmentBuffer { + vec4 fragment[]; +}; -const int numSamples=7; +layout(binding=4, std430) buffer depthBuffer { + float depth[]; +}; + +layout(binding=5, std430) buffer opaqueBuffer { + vec4 opaqueColor[]; +}; + +layout(binding=6, std430) buffer opaqueDepthBuffer { + float opaqueDepth[]; +}; + +uniform uint width; +uniform uint M; +uniform uint r; +#endif + +#ifdef NORMAL + +#ifndef ORTHOGRAPHIC +in vec3 ViewPosition; +#endif +in vec3 Normal; +vec3 normal; + +#ifdef USE_IBL +uniform sampler2D reflBRDFSampler; +uniform sampler2D diffuseSampler; +uniform sampler3D reflImgSampler; + +const float pi=acos(-1.0); +const float piInv=1.0/pi; +const float twopi=2.0*pi; +const float twopiInv=1.0/twopi; // (x,y,z) -> (r,theta,phi); -// theta -> [0,\pi]: colatitude -// phi -> [0, 2\pi]: longitude +// theta -> [0,pi]: colatitude +// phi -> [-pi,pi]: longitude vec3 cart2sphere(vec3 cart) { - float x=cart.z; - float y=cart.x; + float x=cart.x; + float y=cart.z; float z=cart.y; float r=length(cart); + float theta=r > 0.0 ? acos(z/r) : 0.0; float phi=atan(y,x); - float theta=acos(z/r); - return vec3(r,phi,theta); + return vec3(r,theta,phi); } vec2 normalizedAngle(vec3 cartVec) { vec3 sphericalVec=cart2sphere(cartVec); - sphericalVec.y=sphericalVec.y/(2*PI)-0.25; - sphericalVec.z=sphericalVec.z/PI; - return sphericalVec.yz; + sphericalVec.y=sphericalVec.y*piInv; + sphericalVec.z=0.75-sphericalVec.z*twopiInv; + + return sphericalVec.zy; } -#endif -#ifdef NORMAL +vec3 IBLColor(vec3 viewDir) +{ + // + // based on the split sum formula approximation + // L(v)=\int_\Omega L(l)f(l,v) \cos \theta_l + // which, by the split sum approiximation (assuming independence+GGX distrubition), + // roughly equals (within a margin of error) + // [\int_\Omega L(l)] * [\int_\Omega f(l,v) \cos \theta_l]. + // the first term is the reflectance irradiance integral + + vec3 IBLDiffuse=Diffuse*texture(diffuseSampler,normalizedAngle(normal)).rgb; + vec3 reflectVec=normalize(reflect(-viewDir,normal)); + vec2 reflCoord=normalizedAngle(reflectVec); + vec3 IBLRefl=texture(reflImgSampler,vec3(reflCoord,Roughness)).rgb; + vec2 IBLbrdf=texture(reflBRDFSampler,vec2(dot(normal,viewDir),Roughness)).rg; + float specularMultiplier=Fresnel0*IBLbrdf.x+IBLbrdf.y; + vec3 dielectric=IBLDiffuse+specularMultiplier*IBLRefl; + vec3 metal=Diffuse*IBLRefl; + return mix(dielectric,metal,Metallic); +} +#else // h is the halfway vector between normal and light direction // GGX Trowbridge-Reitz Approximation float NDF_TRG(vec3 h) @@ -122,18 +176,24 @@ vec3 BRDF(vec3 viewDirection, vec3 lightDirection) vec3 dielectric=mix(lambertian,rawReflectance*Specular,F); vec3 metal=rawReflectance*Diffuse; - + return mix(dielectric,metal,Metallic); } #endif +#endif + +#ifdef COLOR +in vec4 Color; +#endif + void main() { vec4 diffuse; vec4 emissive; Material m; -#ifdef TRANSPARENT +#ifdef GENERAL m=Materials[abs(materialIndex)-1]; emissive=m.emissive; if(materialIndex >= 0) @@ -150,18 +210,18 @@ void main() #ifdef COLOR diffuse=Color; #if Nlights == 0 - emissive += Color; + emissive += Color; #endif -#else - diffuse=m.diffuse; +#else + diffuse=m.diffuse; #endif #endif - + #if defined(NORMAL) && Nlights > 0 Specular=m.specular.rgb; vec4 parameters=m.parameters; - Roughness2=1.0-parameters[0]; - Roughness2=Roughness2*Roughness2; + Roughness=1.0-parameters[0]; + Roughness2=Roughness*Roughness; Metallic=parameters[1]; Fresnel0=parameters[2]; Diffuse=diffuse.rgb; @@ -178,50 +238,51 @@ void main() #else vec3 viewDir=-normalize(ViewPosition); #endif + vec3 color; +#ifdef USE_IBL + color=IBLColor(viewDir); +#else // For a finite point light, the rendering equation simplifies. - vec3 color=emissive.rgb; - for(int i=0; i < nlights; ++i) { + color=emissive.rgb; + for(uint i=0u; i < nlights; ++i) { Light Li=lights[i]; vec3 L=Li.direction; float cosTheta=max(dot(normal,L),0.0); // $\omega_i \cdot n$ term vec3 radiance=cosTheta*Li.color; color += BRDF(viewDir,L)*radiance; } - -#if defined(ENABLE_TEXTURE) && !defined(COLOR) - // Experimental environment radiance using Riemann sums; - // can also do importance sampling. - vec3 envRadiance=vec3(0.0,0.0,0.0); - - vec3 normalPerp=vec3(-normal.y,normal.x,0.0); - if(length(normalPerp) == 0.0) - normalPerp=vec3(1.0,0.0,0.0); - - // we now have a normal basis; - normalPerp=normalize(normalPerp); - vec3 normalPerp2=normalize(cross(normal,normalPerp)); - - const float step=1.0/numSamples; - const float phistep=twopi*step; - const float thetastep=halfpi*step; - for (int iphi=0; iphi < numSamples; ++iphi) { - float phi=iphi*phistep; - for (int itheta=0; itheta < numSamples; ++itheta) { - float theta=itheta*thetastep; - - vec3 azimuth=cos(phi)*normalPerp+sin(phi)*normalPerp2; - vec3 L=sin(theta)*azimuth+cos(theta)*normal; - - vec3 rawRadiance=texture(environmentMap,normalizedAngle(L)).rgb; - vec3 surfRefl=BRDF(Z,L); - envRadiance += surfRefl*rawRadiance*sin(2.0*theta); - } - } - envRadiance *= halfpi*step*step; - color += envRadiance.rgb; #endif outColor=vec4(color,diffuse.a); -#else +#else outColor=emissive; -#endif +#endif + +#ifndef WIDTH +#ifdef HAVE_SSBO + uint headIndex=uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x); +#if defined(TRANSPARENT) || (!defined(HAVE_INTERLOCK) && !defined(OPAQUE)) + uint listIndex= +#ifdef GPUINDEXING + sum[headIndex < r*(M+1u) ? headIndex/(M+1u) : (headIndex-r)/M]+ +#endif + offset[headIndex]+atomicAdd(count[headIndex],1u); + fragment[listIndex]=outColor; + depth[listIndex]=gl_FragCoord.z; +#ifndef WIREFRAME + discard; +#endif +#else +#ifndef OPAQUE +#ifdef HAVE_INTERLOCK +beginInvocationInterlockARB(); +if(opaqueDepth[headIndex] == 0.0 || gl_FragCoord.z < opaqueDepth[headIndex]) { + opaqueDepth[headIndex]=gl_FragCoord.z; + opaqueColor[headIndex]=outColor; +} +endInvocationInterlockARB(); +#endif +#endif +#endif +#endif +#endif } diff --git a/Master/texmf-dist/asymptote/shaders/offset.glsl b/Master/texmf-dist/asymptote/shaders/offset.glsl new file mode 100755 index 00000000000..5fe24e75587 --- /dev/null +++ b/Master/texmf-dist/asymptote/shaders/offset.glsl @@ -0,0 +1,11 @@ +layout(binding=1, std430) buffer offsetBuffer { + uint offset[]; +}; + +uniform uint width; + +void main() +{ + atomicAdd(offset[uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x)+1u],1u); + discard; +} diff --git a/Master/texmf-dist/asymptote/shaders/partialsum.glsl b/Master/texmf-dist/asymptote/shaders/partialsum.glsl new file mode 100755 index 00000000000..d00195bb3ae --- /dev/null +++ b/Master/texmf-dist/asymptote/shaders/partialsum.glsl @@ -0,0 +1,37 @@ +layout(local_size_x=PROCESSORS) in; + +uniform uint elements; + +layout(binding=0, std430) buffer sumBuffer +{ + uint sum[]; +}; + +shared uint sharedData[PROCESSORS]; + +void main(void) +{ + uint id=gl_LocalInvocationID.x; + sharedData[id]=sum[id+1u]; + + barrier(); + + uint index=id << 1u; + sharedData[index+1u] += sharedData[index]; + barrier(); + for(uint step=1u; step < STEPSM1; step++) { + uint mask=(1u << step)-1u; + uint index=((id >> step) << (step+1u))+mask; + uint windex=index+(id&mask)+1u; + sharedData[windex] += sharedData[index]; + barrier(); + } + uint mask=(1u << STEPSM1)-1u; + index=((id >> STEPSM1) << (STEPSM1+1u))+mask; + uint windex=index+(id&mask)+1u; + if(windex < PROCESSORS) + sharedData[windex] += sharedData[index]; + barrier(); + + sum[id+1u]=sharedData[id]; +} diff --git a/Master/texmf-dist/asymptote/shaders/presum.glsl b/Master/texmf-dist/asymptote/shaders/presum.glsl new file mode 100755 index 00000000000..5b0a8df89e0 --- /dev/null +++ b/Master/texmf-dist/asymptote/shaders/presum.glsl @@ -0,0 +1,37 @@ +layout(local_size_x=1) in; + +uniform uint elements; + +layout(binding=0, std430) buffer sumBuffer +{ + uint sum[]; +}; + +layout(binding=1, std430) buffer offsetBuffer +{ + uint offset[]; +}; + +void main(void) +{ + uint id=gl_GlobalInvocationID.x; + + uint m=elements/gl_NumWorkGroups.x; + uint r=elements-m*gl_NumWorkGroups.x; + uint row,stop; + if(id < r) { + row=m*id+id; + stop=row+m+1u; + } else { + row=m*id+r; + stop=row+m; + } + + uint Sum=offset[row]; + for(uint i=row+1u; i < stop; ++i) { + Sum += offset[i]; + offset[i]=Sum; + } + + sum[id+1u]=Sum; +} diff --git a/Master/texmf-dist/asymptote/shaders/screen.glsl b/Master/texmf-dist/asymptote/shaders/screen.glsl new file mode 100755 index 00000000000..9e8611a7270 --- /dev/null +++ b/Master/texmf-dist/asymptote/shaders/screen.glsl @@ -0,0 +1,5 @@ +void main() +{ + vec2 vertices[3]=vec2[3](vec2(-1,-1),vec2(3,-1),vec2(-1, 3)); + gl_Position = vec4(vertices[gl_VertexID],0,1); +} diff --git a/Master/texmf-dist/asymptote/shaders/vertex.glsl b/Master/texmf-dist/asymptote/shaders/vertex.glsl index 4b2a54b9897..42623ccef6e 100755 --- a/Master/texmf-dist/asymptote/shaders/vertex.glsl +++ b/Master/texmf-dist/asymptote/shaders/vertex.glsl @@ -1,16 +1,22 @@ in vec3 position; -uniform mat3 normMat; - #ifdef NORMAL + #ifndef ORTHOGRAPHIC +uniform mat4 viewMat; out vec3 ViewPosition; #endif + +uniform mat3 normMat; in vec3 normal; out vec3 Normal; + #endif +#ifdef MATERIAL in int material; +flat out int materialIndex; +#endif #ifdef COLOR in vec4 color; @@ -22,9 +28,6 @@ in float width; #endif uniform mat4 projViewMat; -uniform mat4 viewMat; - -flat out int materialIndex; void main() { @@ -45,5 +48,7 @@ void main() gl_PointSize=width; #endif +#ifdef MATERIAL materialIndex=material; +#endif } -- cgit v1.2.3