mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-16 07:23:42 +01:00
Fog modes for new rendering.
- For each fog mode, compile a different version of each shader. - Could maybe do some fancier preprocessing to make writing shaders easier?
This commit is contained in:
parent
b511a20814
commit
25fdf08e11
19 changed files with 306 additions and 49 deletions
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.render;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.gl.shader.ProgramFogMode;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
|
||||
|
@ -15,8 +16,8 @@ public class ContraptionProgram extends BasicProgram {
|
|||
|
||||
protected int uLightVolume;
|
||||
|
||||
public ContraptionProgram(ResourceLocation name, int handle) {
|
||||
super(name, handle);
|
||||
public ContraptionProgram(ResourceLocation name, int handle, ProgramFogMode.Factory fogFactory) {
|
||||
super(name, handle, fogFactory);
|
||||
uLightBoxSize = getUniformLocation("uLightBoxSize");
|
||||
uLightBoxMin = getUniformLocation("uLightBoxMin");
|
||||
uModel = getUniformLocation("uModel");
|
||||
|
|
|
@ -26,6 +26,7 @@ import net.minecraft.util.Direction;
|
|||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Direction.AxisDirection;
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
import net.minecraft.util.Rotation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
|
@ -211,6 +212,14 @@ public class BeltTunnelBlock extends Block implements ITE<BeltTunnelTileEntity>,
|
|||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState rotate(BlockState state, Rotation rotation) {
|
||||
Direction fromAxis = Direction.getFacingFromAxis(AxisDirection.POSITIVE, state.get(HORIZONTAL_AXIS));
|
||||
Direction rotated = rotation.rotate(fromAxis);
|
||||
|
||||
return state.with(HORIZONTAL_AXIS, rotated.getAxis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
||||
boolean isMoving) {
|
||||
|
|
|
@ -4,10 +4,14 @@ import java.io.BufferedInputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.gl.GlFog;
|
||||
import com.simibubi.create.foundation.render.backend.gl.GlFogMode;
|
||||
import com.simibubi.create.foundation.render.backend.gl.shader.*;
|
||||
import com.simibubi.create.foundation.render.backend.gl.versioned.GlFeatureCompat;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
@ -16,10 +20,6 @@ import org.lwjgl.opengl.GLCapabilities;
|
|||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.render.backend.gl.shader.GlProgram;
|
||||
import com.simibubi.create.foundation.render.backend.gl.shader.GlShader;
|
||||
import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec;
|
||||
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderType;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.TextureUtil;
|
||||
|
@ -31,11 +31,13 @@ import net.minecraftforge.resource.ISelectiveResourceReloadListener;
|
|||
import net.minecraftforge.resource.VanillaResourceType;
|
||||
|
||||
public class Backend {
|
||||
public static final Boolean SHADER_DEBUG_OUTPUT = false;
|
||||
|
||||
public static final Logger log = LogManager.getLogger(Backend.class);
|
||||
public static final FloatBuffer MATRIX_BUFFER = MemoryUtil.memAllocFloat(16);
|
||||
|
||||
private static final Map<ResourceLocation, ProgramSpec<?>> registry = new HashMap<>();
|
||||
private static final Map<ProgramSpec<?>, GlProgram> programs = new HashMap<>();
|
||||
private static final Map<ProgramSpec<?>, ProgramGroup<?>> programs = new HashMap<>();
|
||||
|
||||
private static boolean enabled;
|
||||
|
||||
|
@ -60,7 +62,7 @@ public class Backend {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <P extends GlProgram, S extends ProgramSpec<P>> P getProgram(S spec) {
|
||||
return (P) programs.get(spec);
|
||||
return (P) programs.get(spec).get(GlFog.getFogMode());
|
||||
}
|
||||
|
||||
public static boolean available() {
|
||||
|
@ -109,7 +111,7 @@ public class Backend {
|
|||
|
||||
if (gl20()) {
|
||||
|
||||
programs.values().forEach(GlProgram::delete);
|
||||
programs.values().forEach(ProgramGroup::delete);
|
||||
programs.clear();
|
||||
for (ProgramSpec<?> shader : registry.values()) {
|
||||
loadProgram(manager, shader);
|
||||
|
@ -123,23 +125,39 @@ public class Backend {
|
|||
}
|
||||
|
||||
private static <P extends GlProgram, S extends ProgramSpec<P>> void loadProgram(IResourceManager manager, S programSpec) {
|
||||
GlShader vert = null;
|
||||
GlShader frag = null;
|
||||
try {
|
||||
vert = loadShader(manager, programSpec.getVert(), ShaderType.VERTEX, programSpec.defines);
|
||||
frag = loadShader(manager, programSpec.getFrag(), ShaderType.FRAGMENT, programSpec.defines);
|
||||
Map<GlFogMode, P> programGroup = new EnumMap<>(GlFogMode.class);
|
||||
|
||||
GlProgram.Builder builder = GlProgram.builder(programSpec.name).attachShader(vert).attachShader(frag);
|
||||
for (GlFogMode fogMode : GlFogMode.values()) {
|
||||
programGroup.put(fogMode, loadProgram(manager, programSpec, fogMode));
|
||||
}
|
||||
|
||||
programSpec.attributes.forEach(builder::addAttribute);
|
||||
|
||||
P program = builder.build(programSpec.factory);
|
||||
|
||||
programs.put(programSpec, program);
|
||||
programs.put(programSpec, new ProgramGroup<>(programGroup));
|
||||
|
||||
log.info("Loaded program {}", programSpec.name);
|
||||
} catch (IOException ex) {
|
||||
log.error("Failed to load program {}", programSpec.name, ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private static <P extends GlProgram, S extends ProgramSpec<P>> P loadProgram(IResourceManager manager, S programSpec, GlFogMode fogMode) throws IOException {
|
||||
GlShader vert = null;
|
||||
GlShader frag = null;
|
||||
try {
|
||||
ShaderConstants defines = new ShaderConstants(programSpec.defines);
|
||||
|
||||
defines.defineAll(fogMode.getDefines());
|
||||
|
||||
vert = loadShader(manager, programSpec.getVert(), ShaderType.VERTEX, defines);
|
||||
frag = loadShader(manager, programSpec.getFrag(), ShaderType.FRAGMENT, defines);
|
||||
|
||||
GlProgram.Builder builder = GlProgram.builder(programSpec.name, fogMode).attachShader(vert).attachShader(frag);
|
||||
|
||||
programSpec.attributes.forEach(builder::addAttribute);
|
||||
|
||||
return builder.build(programSpec.factory);
|
||||
|
||||
} finally {
|
||||
if (vert != null) vert.delete();
|
||||
if (frag != null) frag.delete();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.foundation.render.backend.gl;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.gl.shader.ProgramFogMode;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.Backend;
|
||||
|
@ -14,20 +15,20 @@ public class BasicProgram extends GlProgram {
|
|||
protected final int uViewProjection;
|
||||
protected final int uDebug;
|
||||
protected final int uCameraPos;
|
||||
protected final int uFogRange;
|
||||
protected final int uFogColor;
|
||||
|
||||
protected final ProgramFogMode fogMode;
|
||||
|
||||
protected int uBlockAtlas;
|
||||
protected int uLightMap;
|
||||
|
||||
public BasicProgram(ResourceLocation name, int handle) {
|
||||
public BasicProgram(ResourceLocation name, int handle, ProgramFogMode.Factory fogFactory) {
|
||||
super(name, handle);
|
||||
uTime = getUniformLocation("uTime");
|
||||
uViewProjection = getUniformLocation("uViewProjection");
|
||||
uDebug = getUniformLocation("uDebug");
|
||||
uCameraPos = getUniformLocation("uCameraPos");
|
||||
uFogRange = getUniformLocation("uFogRange");
|
||||
uFogColor = getUniformLocation("uFogColor");
|
||||
|
||||
fogMode = fogFactory.create(this);
|
||||
|
||||
bind();
|
||||
registerSamplers();
|
||||
|
@ -48,8 +49,7 @@ public class BasicProgram extends GlProgram {
|
|||
uploadMatrixUniform(uViewProjection, viewProjection);
|
||||
GL20.glUniform3f(uCameraPos, (float) camX, (float) camY, (float) camZ);
|
||||
|
||||
GL20.glUniform2f(uFogRange, GlFog.getFogStart(), GlFog.getFogEnd());
|
||||
GL20.glUniform4fv(uFogColor, GlFog.FOG_COLOR);
|
||||
fogMode.bind();
|
||||
}
|
||||
|
||||
protected static void uploadMatrixUniform(int uniform, Matrix4f mat) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.foundation.render.backend.gl;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class GlFog {
|
||||
public static float[] FOG_COLOR = new float[] {0, 0, 0, 0};
|
||||
|
@ -9,7 +10,7 @@ public class GlFog {
|
|||
return GlStateManager.FOG.field_179049_a.field_179201_b;
|
||||
}
|
||||
|
||||
public static int getFogMode() {
|
||||
public static int getFogModeGlEnum() {
|
||||
return GlStateManager.FOG.field_179047_b;
|
||||
}
|
||||
|
||||
|
@ -24,4 +25,22 @@ public class GlFog {
|
|||
public static float getFogStart() {
|
||||
return GlStateManager.FOG.field_179045_d;
|
||||
}
|
||||
|
||||
public static GlFogMode getFogMode() {
|
||||
if (!fogEnabled()) {
|
||||
return GlFogMode.NONE;
|
||||
}
|
||||
|
||||
int mode = getFogModeGlEnum();
|
||||
|
||||
switch (mode) {
|
||||
case GL11.GL_EXP2:
|
||||
case GL11.GL_EXP:
|
||||
return GlFogMode.EXP2;
|
||||
case GL11.GL_LINEAR:
|
||||
return GlFogMode.LINEAR;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unknown fog mode: " + mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package com.simibubi.create.foundation.render.backend.gl;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.simibubi.create.foundation.render.backend.gl.shader.GlShader;
|
||||
import com.simibubi.create.foundation.render.backend.gl.shader.ProgramFogMode;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public enum GlFogMode {
|
||||
NONE(ProgramFogMode.None::new),
|
||||
LINEAR(ProgramFogMode.Linear::new, "USE_FOG_LINEAR"),
|
||||
EXP2(ProgramFogMode.Exp2::new, "USE_FOG_EXP2"),
|
||||
;
|
||||
|
||||
public static final String USE_FOG = "USE_FOG";
|
||||
|
||||
private final ProgramFogMode.Factory fogFactory;
|
||||
private final List<String> defines;
|
||||
|
||||
GlFogMode(ProgramFogMode.Factory fogFactory) {
|
||||
this.fogFactory = fogFactory;
|
||||
this.defines = Collections.emptyList();
|
||||
}
|
||||
|
||||
GlFogMode(ProgramFogMode.Factory fogFactory, String name) {
|
||||
this.fogFactory = fogFactory;
|
||||
this.defines = Lists.newArrayList(USE_FOG, name);
|
||||
}
|
||||
|
||||
public List<String> getDefines() {
|
||||
return defines;
|
||||
}
|
||||
|
||||
public ProgramFogMode.Factory getFogFactory() {
|
||||
return fogFactory;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.foundation.render.backend.gl.shader;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.gl.GlFogMode;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.Backend;
|
||||
|
@ -17,8 +18,8 @@ public abstract class GlProgram extends GlObject {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
public static Builder builder(ResourceLocation name) {
|
||||
return new Builder(name);
|
||||
public static Builder builder(ResourceLocation name, GlFogMode fogMode) {
|
||||
return new Builder(name, fogMode);
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
|
@ -37,7 +38,7 @@ public abstract class GlProgram extends GlObject {
|
|||
public int getUniformLocation(String uniform) {
|
||||
int index = GL20.glGetUniformLocation(this.handle(), uniform);
|
||||
|
||||
if (index < 0) {
|
||||
if (index < 0 && Backend.SHADER_DEBUG_OUTPUT) {
|
||||
Backend.log.warn("No active uniform '{}' exists in program '{}'. Could be unused.", uniform, this.name);
|
||||
}
|
||||
|
||||
|
@ -69,12 +70,14 @@ public abstract class GlProgram extends GlObject {
|
|||
public static class Builder {
|
||||
private final ResourceLocation name;
|
||||
private final int program;
|
||||
private final GlFogMode fogMode;
|
||||
|
||||
private int attributeIndex;
|
||||
|
||||
public Builder(ResourceLocation name) {
|
||||
public Builder(ResourceLocation name, GlFogMode fogMode) {
|
||||
this.name = name;
|
||||
this.program = GL20.glCreateProgram();
|
||||
this.fogMode = fogMode;
|
||||
}
|
||||
|
||||
public Builder attachShader(GlShader shader) {
|
||||
|
@ -113,12 +116,12 @@ public abstract class GlProgram extends GlObject {
|
|||
throw new RuntimeException("Shader program linking failed, see log for details");
|
||||
}
|
||||
|
||||
return factory.create(this.name, this.program);
|
||||
return factory.create(this.name, this.program, this.fogMode.getFogFactory());
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ProgramFactory<P extends GlProgram> {
|
||||
P create(ResourceLocation name, int handle);
|
||||
P create(ResourceLocation name, int handle, ProgramFogMode.Factory fogFactory);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,9 @@ public class GlShader extends GlObject {
|
|||
|
||||
if (preProcessor != null) {
|
||||
source = preProcessor.process(source);
|
||||
Backend.log.info("Preprocessor run on " + name);// + ":\n" + source);
|
||||
|
||||
if (Backend.SHADER_DEBUG_OUTPUT)
|
||||
Backend.log.info("Preprocessor run on " + name);// + ":\n" + source);
|
||||
}
|
||||
|
||||
GL20.glShaderSource(handle, source);
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package com.simibubi.create.foundation.render.backend.gl.shader;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.gl.GlFog;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
|
||||
public abstract class ProgramFogMode {
|
||||
|
||||
public abstract void bind();
|
||||
|
||||
public static class None extends ProgramFogMode {
|
||||
|
||||
public None(GlProgram program) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static class Linear extends ProgramFogMode {
|
||||
private final int uFogColor;
|
||||
private final int uFogRange;
|
||||
|
||||
public Linear(GlProgram program) {
|
||||
this.uFogColor = program.getUniformLocation("uFogColor");
|
||||
this.uFogRange = program.getUniformLocation("uFogRange");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind() {
|
||||
GL20.glUniform2f(uFogRange, GlFog.getFogStart(), GlFog.getFogEnd());
|
||||
GL20.glUniform4fv(uFogColor, GlFog.FOG_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Exp2 extends ProgramFogMode {
|
||||
private final int uFogColor;
|
||||
private final int uFogDensity;
|
||||
|
||||
public Exp2(GlProgram program) {
|
||||
this.uFogColor = program.getUniformLocation("uFogColor");
|
||||
this.uFogDensity = program.getUniformLocation("uFogDensity");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind() {
|
||||
GL20.glUniform1f(uFogDensity, GlFog.getFogDensity());
|
||||
GL20.glUniform4fv(uFogColor, GlFog.FOG_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
public interface Factory {
|
||||
ProgramFogMode create(GlProgram program);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.simibubi.create.foundation.render.backend.gl.shader;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.gl.GlFogMode;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ProgramGroup<P extends GlProgram> {
|
||||
|
||||
private final Map<GlFogMode, P> programs;
|
||||
|
||||
public ProgramGroup(Map<GlFogMode, P> programs) {
|
||||
this.programs = programs;
|
||||
}
|
||||
|
||||
public P get(GlFogMode fogMode) {
|
||||
return programs.get(fogMode);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
programs.values().forEach(GlProgram::delete);
|
||||
}
|
||||
}
|
|
@ -50,7 +50,7 @@ public class ProgramSpec<P extends GlProgram> {
|
|||
public static class Builder<P extends GlProgram> {
|
||||
private ResourceLocation vert;
|
||||
private ResourceLocation frag;
|
||||
private ShaderConstants defines = null;
|
||||
private ShaderConstants defines = ShaderConstants.EMPTY;
|
||||
|
||||
private final ResourceLocation name;
|
||||
private final GlProgram.ProgramFactory<P> factory;
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
package com.simibubi.create.foundation.render.backend.gl.shader;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ShaderConstants implements GlShader.PreProcessor {
|
||||
public static final ShaderConstants EMPTY = new ShaderConstants();
|
||||
|
||||
private final ArrayList<String> defines;
|
||||
|
||||
|
@ -14,6 +18,10 @@ public class ShaderConstants implements GlShader.PreProcessor {
|
|||
defines = new ArrayList<>();
|
||||
}
|
||||
|
||||
public ShaderConstants(ShaderConstants other) {
|
||||
this.defines = Lists.newArrayList(other.defines);
|
||||
}
|
||||
|
||||
public static ShaderConstants define(String def) {
|
||||
return new ShaderConstants().def(def);
|
||||
}
|
||||
|
@ -23,6 +31,11 @@ public class ShaderConstants implements GlShader.PreProcessor {
|
|||
return this;
|
||||
}
|
||||
|
||||
public ShaderConstants defineAll(Collection<String> defines) {
|
||||
this.defines.addAll(defines);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArrayList<String> getDefines() {
|
||||
return defines;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,10 @@ uniform mat4 uViewProjection;
|
|||
uniform int uDebug;
|
||||
|
||||
uniform vec3 uCameraPos;
|
||||
|
||||
#if defined(USE_FOG)
|
||||
varying float FragDistance;
|
||||
#endif
|
||||
|
||||
mat4 rotate(vec3 axis, float angle) {
|
||||
float s = sin(angle);
|
||||
|
@ -71,12 +74,16 @@ void main() {
|
|||
mat4 normalMat = uModel * localRotation;
|
||||
|
||||
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
|
||||
#if defined(USE_FOG)
|
||||
FragDistance = length(worldPos.xyz);
|
||||
#endif
|
||||
#else
|
||||
mat4 normalMat = localRotation;
|
||||
|
||||
#if defined(USE_FOG)
|
||||
FragDistance = length(worldPos.xyz - uCameraPos);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
vec3 norm = normalize(normalMat * vec4(aNormal, 0.)).xyz;
|
||||
|
||||
|
|
|
@ -4,17 +4,35 @@ varying vec2 TexCoords;
|
|||
varying vec4 Color;
|
||||
varying float Diffuse;
|
||||
varying vec2 Light;
|
||||
varying float FragDistance;
|
||||
|
||||
varying vec3 BoxCoord;
|
||||
|
||||
uniform vec2 uFogRange;
|
||||
uniform vec4 uFogColor;
|
||||
|
||||
uniform sampler2D uBlockAtlas;
|
||||
uniform sampler2D uLightMap;
|
||||
uniform sampler3D uLightVolume;
|
||||
|
||||
#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
|
||||
|
||||
vec4 light() {
|
||||
vec2 lm = texture3D(uLightVolume, BoxCoord).rg * 0.9375 + 0.03125;
|
||||
return texture2D(uLightMap, max(lm, Light));
|
||||
|
@ -25,9 +43,12 @@ void main() {
|
|||
|
||||
vec4 color = vec4(tex.rgb * light().rgb * Diffuse * Color.rgb, tex.a);
|
||||
|
||||
float fog = (uFogRange.y - FragDistance) / (uFogRange.y - uFogRange.x);
|
||||
fog = clamp(fog, 0., 1.);
|
||||
#if defined(USE_FOG)
|
||||
float fog = clamp(fogFactor(), 0., 1.);
|
||||
|
||||
gl_FragColor = mix(uFogColor, color, fog);
|
||||
gl_FragColor.a = color.a;
|
||||
#else
|
||||
gl_FragColor = color;
|
||||
#endif
|
||||
}
|
|
@ -29,7 +29,10 @@ uniform mat4 uViewProjection;
|
|||
uniform int uDebug;
|
||||
|
||||
uniform vec3 uCameraPos;
|
||||
|
||||
#if defined(USE_FOG)
|
||||
varying float FragDistance;
|
||||
#endif
|
||||
|
||||
mat4 rotate(vec3 axis, float angle) {
|
||||
float s = sin(angle);
|
||||
|
@ -77,9 +80,12 @@ void main() {
|
|||
Diffuse = diffuse(norm);
|
||||
TexCoords = aTexCoords;
|
||||
Light = aModelLight;
|
||||
FragDistance = length(worldPos.xyz);
|
||||
gl_Position = uViewProjection * worldPos;
|
||||
|
||||
#if defined(USE_FOG)
|
||||
FragDistance = length(worldPos.xyz);
|
||||
#endif
|
||||
|
||||
if (uDebug == 2) {
|
||||
Color = vec4(norm, 1.);
|
||||
} else {
|
||||
|
|
|
@ -22,7 +22,10 @@ uniform mat4 uViewProjection;
|
|||
uniform int uDebug;
|
||||
|
||||
uniform vec3 uCameraPos;
|
||||
|
||||
#if defined(USE_FOG)
|
||||
varying float FragDistance;
|
||||
#endif
|
||||
|
||||
mat4 rotate(vec3 axis, float angle) {
|
||||
float s = sin(angle);
|
||||
|
@ -52,8 +55,10 @@ void main() {
|
|||
Color = aColor / diffuse(aNormal);
|
||||
TexCoords = aTexCoords;
|
||||
Light = aModelLight;
|
||||
FragDistance = length(viewPos.xyz);
|
||||
gl_Position = uViewProjection * viewPos;
|
||||
#if defined(USE_FOG)
|
||||
FragDistance = length(viewPos.xyz);
|
||||
#endif
|
||||
|
||||
if (uDebug == 2) {
|
||||
Color = vec4(norm, 1.);
|
||||
|
|
|
@ -35,7 +35,10 @@ uniform mat4 uViewProjection;
|
|||
uniform int uDebug;
|
||||
|
||||
uniform vec3 uCameraPos;
|
||||
|
||||
#if defined(USE_FOG)
|
||||
varying float FragDistance;
|
||||
#endif
|
||||
|
||||
float diffuse(vec3 normal) {
|
||||
float x = normal.x;
|
||||
|
@ -86,12 +89,16 @@ void main() {
|
|||
mat4 normalMat = uModel * orientation * flapRotation;
|
||||
|
||||
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
|
||||
#if defined(USE_FOG)
|
||||
FragDistance = length(worldPos.xyz);
|
||||
#endif
|
||||
#else
|
||||
mat4 normalMat = orientation * flapRotation;
|
||||
|
||||
#if defined(USE_FOG)
|
||||
FragDistance = length(worldPos.xyz - uCameraPos);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
vec3 norm = normalize(normalMat * vec4(aNormal, 0.)).xyz;
|
||||
|
||||
|
|
|
@ -4,14 +4,32 @@ varying vec2 TexCoords;
|
|||
varying vec2 Light;
|
||||
varying float Diffuse;
|
||||
varying vec4 Color;
|
||||
varying float FragDistance;
|
||||
|
||||
uniform vec2 uFogRange;
|
||||
uniform vec4 uFogColor;
|
||||
|
||||
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
|
||||
|
||||
vec4 light() {
|
||||
vec2 lm = Light * 0.9375 + 0.03125;
|
||||
return texture2D(uLightMap, lm);
|
||||
|
@ -22,9 +40,12 @@ void main() {
|
|||
|
||||
vec4 color = vec4(tex.rgb * light().rgb * Diffuse, tex.a) * Color;
|
||||
|
||||
float fog = (uFogRange.y - FragDistance) / (uFogRange.y - uFogRange.x);
|
||||
fog = clamp(fog, 0., 1.);
|
||||
#if defined(USE_FOG)
|
||||
float fog = clamp(fogFactor(), 0., 1.);
|
||||
|
||||
gl_FragColor = mix(uFogColor, color, fog);
|
||||
gl_FragColor.a = color.a;
|
||||
#else
|
||||
gl_FragColor = color;
|
||||
#endif
|
||||
}
|
|
@ -29,7 +29,10 @@ uniform mat4 uViewProjection;
|
|||
uniform int uDebug;
|
||||
|
||||
uniform vec3 uCameraPos;
|
||||
|
||||
#if defined(USE_FOG)
|
||||
varying float FragDistance;
|
||||
#endif
|
||||
|
||||
mat4 rotate(vec3 axis, float angle) {
|
||||
float s = sin(angle);
|
||||
|
@ -69,12 +72,16 @@ void main() {
|
|||
mat4 normalMat = uModel * kineticRotation;
|
||||
|
||||
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
|
||||
#if defined(USE_FOG)
|
||||
FragDistance = length(worldPos.xyz);
|
||||
#endif
|
||||
#else
|
||||
mat4 normalMat = kineticRotation;
|
||||
|
||||
#if defined(USE_FOG)
|
||||
FragDistance = length(worldPos.xyz - uCameraPos);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
vec3 norm = normalize(normalMat * vec4(aNormal, 0.)).xyz;
|
||||
|
||||
|
|
Loading…
Reference in a new issue