summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/asymptote/shaders
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2022-02-27 23:41:11 +0000
committerKarl Berry <karl@freefriends.org>2022-02-27 23:41:11 +0000
commit8027f287eb46d487a0e379911bdbc4d6c2bf44e4 (patch)
treeb6e3aeebab3f5c2560ae1ab892b76cca269eb05e /Master/texmf-dist/asymptote/shaders
parenta4855ce49e2101557c17547c2d22594e1b2a215c (diff)
asymptote 2.78 support files
git-svn-id: svn://tug.org/texlive/trunk@62265 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/asymptote/shaders')
-rwxr-xr-xMaster/texmf-dist/asymptote/shaders/blend.glsl131
-rwxr-xr-xMaster/texmf-dist/asymptote/shaders/count.glsl11
-rwxr-xr-xMaster/texmf-dist/asymptote/shaders/count0.glsl11
-rwxr-xr-xMaster/texmf-dist/asymptote/shaders/fragment.glsl209
-rwxr-xr-xMaster/texmf-dist/asymptote/shaders/offset.glsl11
-rwxr-xr-xMaster/texmf-dist/asymptote/shaders/partialsum.glsl37
-rwxr-xr-xMaster/texmf-dist/asymptote/shaders/presum.glsl37
-rwxr-xr-xMaster/texmf-dist/asymptote/shaders/screen.glsl5
-rwxr-xr-xMaster/texmf-dist/asymptote/shaders/vertex.glsl15
9 files changed, 388 insertions, 79 deletions
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
}