#flwbuiltins and oh so much less overhead

- Put a lot of the reusable code in a sort of standard library
 - Need to evaluate just how much should be lumped in there
 - Still need to allow for users to create alternate contexts for the builtins
 - Normal world and contraptions are still hardcoded contexts
This commit is contained in:
JozsefA 2021-05-03 13:42:23 -07:00
parent 35768b5ade
commit fcbab5b820
15 changed files with 144 additions and 139 deletions

View file

@ -46,7 +46,8 @@ public class ShaderLoader {
// #flwinclude <"valid_namespace:valid/path_to_file.glsl">
private static final Pattern includePattern = Pattern.compile("#flwinclude <\"([\\w\\d_]+:[\\w\\d_./]+)\">");
private static boolean debugDumpFile = false;
private static final Pattern builtinPattern = Pattern.compile("#flwbuiltins");
private static boolean debugDumpFile = true;
final Map<ResourceLocation, String> shaderSource = new HashMap<>();
@ -64,6 +65,9 @@ public class ShaderLoader {
Backend.registry.values().forEach(this::loadProgramFromSpec);
Backend.log.info("Loaded all shader programs.");
// no need to hog all that memory
shaderSource.clear();
}
}
}
@ -125,7 +129,54 @@ public class ShaderLoader {
}
}
private String processIncludes(ResourceLocation baseName, String source) {
public GlShader loadShader(ResourceLocation name, ShaderType type, ShaderConstants defines) {
String source = shaderSource.get(name);
source = expandBuiltins(source, type);
source = processIncludes(source, name);
if (defines != null)
source = defines.process(source);
if (debugDumpFile) {
Backend.log.debug("Finished processing '" + name + "':");
int i = 1;
for (String s : source.split("\n")) {
Backend.log.debug(String.format("%1$4s: ", i++) + s);
}
}
return new GlShader(type, name, source);
}
private String expandBuiltins(String source, ShaderType type) {
return lines(source).flatMap(line -> {
Matcher matcher = builtinPattern.matcher(line);
if (matcher.find()) {
ResourceLocation builtins;
switch (type) {
case FRAGMENT:
builtins = new ResourceLocation("create", "std/builtin.frag");
break;
case VERTEX:
builtins = new ResourceLocation("create", "std/builtin.vert");
break;
default:
builtins = null;
}
String includeSource = shaderSource.get(builtins);
return lines(includeSource);
}
return Stream.of(line);
}).collect(Collectors.joining("\n"));
}
private String processIncludes(String source, ResourceLocation baseName) {
HashSet<ResourceLocation> seen = new HashSet<>();
seen.add(baseName);
@ -133,7 +184,7 @@ public class ShaderLoader {
}
private Stream<String> includeRecursive(String source, Set<ResourceLocation> seen) {
return new BufferedReader(new StringReader(source)).lines().flatMap(line -> {
return lines(source).flatMap(line -> {
Matcher matcher = includePattern.matcher(line);
@ -155,23 +206,8 @@ public class ShaderLoader {
});
}
public GlShader loadShader(ResourceLocation name, ShaderType type, ShaderConstants defines) {
String source = shaderSource.get(name);
source = processIncludes(name, source);
if (defines != null)
source = defines.process(source);
if (debugDumpFile) {
Backend.log.debug("Finished processing '" + name + "':");
int i = 1;
for (String s : source.split("\n")) {
Backend.log.debug(String.format("%1$4s: ", i++) + s);
}
}
return new GlShader(type, name, source);
public static Stream<String> lines(String s) {
return new BufferedReader(new StringReader(s)).lines();
}
public String readToString(InputStream is) {

View file

@ -105,13 +105,7 @@ public abstract class GlProgram extends GlObject {
}
/**
* Links the attached shaders to this program and returns a user-defined container which wraps the shader
* program. This container can, for example, provide methods for updating the specific uniforms of that shader
* set.
*
* @param factory The factory which will create the shader program's container
* @param <P> The type which should be instantiated with the new program's handle
* @return An instantiated shader container as provided by the factory
* Links the attached shaders to this program.
*/
public Builder link() {
GL20.glLinkProgram(this.program);

View file

@ -1,6 +1,7 @@
#version 110
#define PI 3.1415926538
#flwbuiltins
#flwinclude <"create:core/quaternion.glsl">
#flwinclude <"create:core/matutils.glsl">
#flwinclude <"create:core/diffuse.glsl">
@ -30,16 +31,6 @@ uniform int uDebug;
uniform vec3 uCameraPos;
#if defined(USE_FOG)
varying float FragDistance;
#endif
#ifdef CONTRAPTION
#flwinclude <"create:contraption/builtin.vert">
#else
#flwinclude <"create:std/builtin.vert">
#endif
void main() {
vec3 rotated = rotateVertexByQuat(aPos - .5, aInstanceRot) + aInstancePos + .5;
@ -47,7 +38,7 @@ void main() {
vec3 norm = rotateVertexByQuat(aNormal, aInstanceRot);
FLWFinalizeWorldPos(worldPos);
FLWFinalizeWorldPos(worldPos, uCameraPos);
FLWFinalizeNormal(norm);
float scrollSize = aScrollTexture.w - aScrollTexture.y;

View file

@ -1,5 +1,7 @@
#version 110
#flwbuiltins
varying vec2 TexCoords;
varying vec2 Light;
varying float Diffuse;
@ -8,45 +10,12 @@ varying vec4 Color;
uniform sampler2D uBlockAtlas;
uniform sampler2D uLightMap;
#if defined(USE_FOG)
varying float FragDistance;
uniform vec4 uFogColor;
#endif
#if defined(USE_FOG_LINEAR)
uniform vec2 uFogRange;
float fogFactor() {
return (uFogRange.y - FragDistance) / (uFogRange.y - uFogRange.x);
}
#endif
#ifdef USE_FOG_EXP2
uniform float uFogDensity;
float fogFactor() {
float dist = FragDistance * uFogDensity;
return 1. / exp2(dist * dist);
}
#endif
#ifdef CONTRAPTION
#flwinclude <"create:contraption/builtin.frag">
#else
#flwinclude <"create:std/builtin.frag">
#endif
void main() {
vec4 tex = texture2D(uBlockAtlas, TexCoords);
vec4 color = vec4(tex.rgb * FLWLight(Light, uLightMap).rgb * Diffuse, tex.a) * Color;
#if defined(USE_FOG)
float fog = clamp(fogFactor(), 0., 1.);
FLWFinalizeColor(color);
gl_FragColor = mix(uFogColor, color, fog);
gl_FragColor.a = color.a;
#else
gl_FragColor = color;
#endif
}

View file

@ -1,6 +1,16 @@
varying vec3 BoxCoord;
uniform sampler3D uLightVolume;
void FLWFinalizeColor(vec4 color) {
#if defined(USE_FOG)
float a = color.a;
float fog = clamp(FLWFogFactor(), 0., 1.);
color = mix(uFogColor, color, fog);
color.a = a;
#endif
}
vec4 FLWLight(vec2 lightCoords, sampler2D lightMap) {
vec2 lm = max(lightCoords, texture3D(uLightVolume, BoxCoord).rg);
return texture2D(lightMap, lm * 0.9375 + 0.03125);

View file

@ -1,20 +1,28 @@
#if defined(USE_FOG)
varying float FragDistance;
#endif
varying vec3 BoxCoord;
uniform vec3 uLightBoxSize;
uniform vec3 uLightBoxMin;
uniform mat4 uModel;
void FLWFinalizeWorldPos(inout vec4 worldPos) {
void FLWFinalizeWorldPos(inout vec4 worldPos, vec3 cameraPos) {
worldPos = uModel * worldPos;
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
#if defined(USE_FOG)
#if defined(USE_FOG)
FragDistance = length(worldPos.xyz);
#endif
}
void FLWFinalizeNormal(inout vec3 normal) {
normal = modelToNormal(uModel) * normal;
mat3 m;
m[0] = uModel[0].xyz;
m[1] = uModel[1].xyz;
m[2] = uModel[2].xyz;
normal = m * normal;
}

View file

@ -19,7 +19,6 @@ attribute vec4 aInstanceRot;
attribute vec3 aRotationCenter;
attribute float aSpeed;
varying float Diffuse;
varying vec2 TexCoords;
varying vec4 Color;

View file

@ -1,17 +1,4 @@
//mat4 rotate(vec3 axis, float angle) {
// float s = sin(angle);
// float c = cos(angle);
// float oc = 1. - c;
//
// return mat4(
// oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.,
// oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.,
// oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.,
// 0., 0., 0., 1.
// );
//}
mat4 rotate(vec3 axis, float angle) {
float s = sin(angle);
float c = cos(angle);

View file

@ -1,6 +1,7 @@
#version 110
#define PI 3.1415926538
#flwbuiltins
#flwinclude <"create:core/matutils.glsl">
#flwinclude <"create:core/quaternion.glsl">
#flwinclude <"create:core/diffuse.glsl">
@ -32,16 +33,6 @@ uniform int uDebug;
uniform vec3 uCameraPos;
#if defined(USE_FOG)
varying float FragDistance;
#endif
#ifdef CONTRAPTION
#flwinclude <"create:contraption/builtin.vert">
#else
#flwinclude <"create:std/builtin.vert">
#endif
float toRad(float degrees) {
return fract(degrees / 360.) * PI * 2.;
}
@ -71,7 +62,7 @@ void main() {
vec4 worldPos = vec4(rotated, 1.);
vec3 norm = rotateVertexByQuat(rotateVertexByQuat(aNormal, flapRotation), orientation);
FLWFinalizeWorldPos(worldPos);
FLWFinalizeWorldPos(worldPos, uCameraPos);
FLWFinalizeNormal(norm);
Diffuse = diffuse(norm);

View file

@ -1,5 +1,6 @@
#version 110
#flwbuiltins
#flwinclude <"create:core/matutils.glsl">
#flwinclude <"create:core/diffuse.glsl">
@ -23,24 +24,13 @@ uniform int uDebug;
uniform vec3 uCameraPos;
#if defined(USE_FOG)
varying float FragDistance;
#endif
#ifdef CONTRAPTION
#flwinclude <"create:contraption/builtin.vert">
#else
#flwinclude <"create:std/builtin.vert">
#endif
void main() {
vec4 worldPos = aTransform * vec4(aPos, 1.);
vec3 norm = aNormalMat * aNormal;
FLWFinalizeWorldPos(worldPos, uCameraPos);
FLWFinalizeNormal(norm);
FLWFinalizeWorldPos(worldPos);
norm = normalize(norm);

View file

@ -1,5 +1,6 @@
#version 110
#flwbuiltins
#flwinclude <"create:core/matutils.glsl">
#flwinclude <"create:core/quaternion.glsl">
#flwinclude <"create:core/diffuse.glsl">
@ -25,22 +26,12 @@ uniform int uDebug;
uniform vec3 uCameraPos;
#if defined(USE_FOG)
varying float FragDistance;
#endif
#ifdef CONTRAPTION
#flwinclude <"create:contraption/builtin.vert">
#else
#flwinclude <"create:std/builtin.vert">
#endif
void main() {
vec4 worldPos = vec4(rotateVertexByQuat(aPos - aPivot, aRotation) + aPivot + aInstancePos, 1.);
vec3 norm = rotateVertexByQuat(aNormal, aRotation);
FLWFinalizeWorldPos(worldPos);
FLWFinalizeWorldPos(worldPos, uCameraPos);
FLWFinalizeNormal(norm);
Diffuse = diffuse(norm);

View file

@ -1,6 +1,7 @@
#version 110
#define PI 3.1415926538
#flwbuiltins
#flwinclude <"create:core/quaternion.glsl">
#flwinclude <"create:core/matutils.glsl">
#flwinclude <"create:core/diffuse.glsl">
@ -27,16 +28,6 @@ uniform int uDebug;
uniform vec3 uCameraPos;
#if defined(USE_FOG)
varying float FragDistance;
#endif
#ifdef CONTRAPTION
#flwinclude <"create:contraption/builtin.vert">
#else
#flwinclude <"create:std/builtin.vert">
#endif
mat4 kineticRotation() {
float degrees = aOffset + uTime * aSpeed * 3./10.;
float angle = fract(degrees / 360.) * PI * 2.;
@ -50,7 +41,7 @@ void main() {
vec3 norm = modelToNormal(kineticRotation) * aNormal;
FLWFinalizeWorldPos(worldPos);
FLWFinalizeWorldPos(worldPos, uCameraPos);
FLWFinalizeNormal(norm);
Diffuse = diffuse(norm);

View file

@ -1,4 +1,21 @@
#flwinclude <"create:std/fog.glsl">
#if defined(CONTRAPTION)
#flwinclude <"create:contraption/builtin.frag">
#else
void FLWFinalizeColor(vec4 color) {
#if defined(USE_FOG)
float a = color.a;
float fog = clamp(FLWFogFactor(), 0., 1.);
color = mix(uFogColor, color, fog);
color.a = a;
#endif
}
vec4 FLWLight(vec2 lightCoords, sampler2D lightMap) {
vec2 lm = lightCoords * 0.9375 + 0.03125;
return texture2D(lightMap, lm);
}
#endif

View file

@ -1,10 +1,18 @@
void FLWFinalizeWorldPos(inout vec4 worldPos) {
#if defined(USE_FOG)
#if defined(CONTRAPTION)
#flwinclude <"create:contraption/builtin.vert">
#else
FragDistance = length(worldPos.xyz - uCameraPos);
#if defined(USE_FOG)
varying float FragDistance;
#endif
void FLWFinalizeWorldPos(inout vec4 worldPos, vec3 cameraPos) {
#if defined(USE_FOG)
FragDistance = length(worldPos.xyz - cameraPos);
#endif
}
void FLWFinalizeNormal(inout vec3 normal) {
// noop
}
#endif

View file

@ -0,0 +1,23 @@
#if defined(USE_FOG)
varying float FragDistance;
uniform vec4 uFogColor;
#endif
#if defined(USE_FOG_LINEAR)
uniform vec2 uFogRange;
float FLWFogFactor() {
return (uFogRange.y - FragDistance) / (uFogRange.y - uFogRange.x);
}
#elif defined(USE_FOG_EXP2)
uniform float uFogDensity;
float FLWFogFactor() {
float dist = FragDistance * uFogDensity;
return 1. / exp2(dist * dist);
}
#else
float FLWFogFactor() {
return 0.;
}
#endif