diff --git a/src/main/java/li/cil/oc2/client/renderer/ModShaders.java b/src/main/java/li/cil/oc2/client/renderer/ModShaders.java index ceb449d4..2960cbd8 100644 --- a/src/main/java/li/cil/oc2/client/renderer/ModShaders.java +++ b/src/main/java/li/cil/oc2/client/renderer/ModShaders.java @@ -3,7 +3,6 @@ package li.cil.oc2.client.renderer; import com.mojang.blaze3d.pipeline.RenderTarget; -import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.math.Matrix4f; import li.cil.oc2.api.API; @@ -23,6 +22,8 @@ public final class ModShaders { public static final int MAX_PROJECTORS = 3; private static final ResourceLocation PROJECTORS_SHADER_LOCATION = new ResourceLocation(API.MOD_ID, "projectors"); + private static final String[] PROJECTOR_COLOR_NAMES = {"ProjectorColor0", "ProjectorColor1", "ProjectorColor2"}; + private static final String[] PROJECTOR_DEPTH_NAMES = {"ProjectorDepth0", "ProjectorDepth1", "ProjectorDepth2"}; private static final String[] PROJECTOR_CAMERA_NAMES = {"ProjectorCamera0", "ProjectorCamera1", "ProjectorCamera2"}; /////////////////////////////////////////////////////////////////// @@ -47,12 +48,12 @@ public final class ModShaders { final int projectorCount = Math.min(count, MAX_PROJECTORS); projectorsShader.safeGetUniform("Count").set(projectorCount); - RenderSystem.setShaderTexture(0, target.getDepthTextureId()); + projectorsShader.setSampler("MainCameraDepth", target.getDepthTextureId()); projectorsShader.safeGetUniform("InverseMainCamera").set(inverseCameraMatrix); for (int i = 0; i < projectorCount; i++) { - RenderSystem.setShaderTexture(1 + i * 2, colors[i].getId()); - RenderSystem.setShaderTexture(1 + i * 2 + 1, depths[i].getDepthTextureId()); + projectorsShader.setSampler(PROJECTOR_COLOR_NAMES[i], colors[i].getId()); + projectorsShader.setSampler(PROJECTOR_DEPTH_NAMES[i], depths[i].getDepthTextureId()); projectorsShader.safeGetUniform(PROJECTOR_CAMERA_NAMES[i]).set(projectorCameraMatrices[i]); } } diff --git a/src/main/resources/assets/oc2/shaders/core/projectors.fsh b/src/main/resources/assets/oc2/shaders/core/projectors.fsh index 8c50fb7a..ec605bbc 100644 --- a/src/main/resources/assets/oc2/shaders/core/projectors.fsh +++ b/src/main/resources/assets/oc2/shaders/core/projectors.fsh @@ -4,23 +4,26 @@ uniform int Count; -// Projector 1 -uniform sampler2D Sampler0; // Main Depth -uniform mat4 InverseMainCamera; // Inverse Main View Projection Matrix +// Main camera depth buffer. +uniform sampler2D MainCameraDepth; +// Inverse matrix of main camera view rotation and projection. Not that this +// explicitly does *not* include the camera's actual position. All projector +// matrices are computed relative to the main camera position, for precision. +uniform mat4 InverseMainCamera; -// Projector 2 -uniform sampler2D Sampler1; // Color -uniform sampler2D Sampler2; // Depth +// Projector 1 +uniform sampler2D ProjectorColor0; +uniform sampler2D ProjectorDepth0; uniform mat4 ProjectorCamera0; -// Projector 3 -uniform sampler2D Sampler3; // Color -uniform sampler2D Sampler4; // Depth +// Projector 2 +uniform sampler2D ProjectorColor1; +uniform sampler2D ProjectorDepth1; uniform mat4 ProjectorCamera1; -// Projector 4 -uniform sampler2D Sampler5; // Color -uniform sampler2D Sampler6; // Depth +// Projector 3 +uniform sampler2D ProjectorColor2; +uniform sampler2D ProjectorDepth2; uniform mat4 ProjectorCamera2; const float PROJECTOR_NEAR = 1.0/16.0; @@ -57,9 +60,11 @@ bool isInClipBounds(vec3 v) { v.z >= -1 && v.z <= 1; } -bool getProjectorColor(vec3 worldPos, vec3 worldNormal, mat4 projectorCamera, - sampler2D projectorColorSampler, sampler2D projectorDepthSampler, - out vec4 result) { +bool getProjectorColor(vec3 worldPos, vec3 worldNormal, + mat4 projectorCamera, + sampler2D projectorColorSampler, + sampler2D projectorDepthSampler, + out vec3 result) { // Project world normal into projector clip space. vec3 projectorClipNormal = (projectorCamera * vec4(worldNormal, 0)).xyz; @@ -83,7 +88,7 @@ bool getProjectorColor(vec3 worldPos, vec3 worldNormal, mat4 projectorCamera, float projectorClipDepth = projectorDepth * 2 - 1; if (projectorClipPos.z <= projectorClipDepth + DEPTH_BIAS) { - vec4 projectorColor = texture2D(projectorColorSampler, vec2(projectorUv.s, 1 - projectorUv.t)); + vec3 projectorColor = texture2D(projectorColorSampler, vec2(projectorUv.s, 1 - projectorUv.t)).rgb; float dotAttenuation = clamp((d - DOT_EPSILON) / (1 - DOT_EPSILON), 0, 1); float distanceAttenuation = clamp(1 - (linearDepth - START_FADE_DISTANCE) / (MAX_DISTANCE - START_FADE_DISTANCE), 0, 1); result = projectorColor * dotAttenuation * distanceAttenuation; @@ -93,7 +98,7 @@ bool getProjectorColor(vec3 worldPos, vec3 worldNormal, mat4 projectorCamera, } void main() { - float depth = texture2D(Sampler0, texCoord).r; + float depth = texture2D(MainCameraDepth, texCoord).r; // Check for no hit, for early exit. if (depth >= 1) { @@ -104,18 +109,18 @@ void main() { vec3 worldPos = getWorldPos(texCoord, clipDepth); vec3 worldNormal = getNormal(worldPos); - vec4 colorAcc = vec4(0, 0, 0, 0); - vec4 color; + vec3 colorAcc = vec3(0); + vec3 color; int accCount = 0; - if (Count > 0 && getProjectorColor(worldPos, worldNormal, ProjectorCamera0, Sampler1, Sampler2, color)) { + if (Count > 0 && getProjectorColor(worldPos, worldNormal, ProjectorCamera0, ProjectorColor0, ProjectorDepth0, color)) { colorAcc += color; accCount += 1; } - if (Count > 1 && getProjectorColor(worldPos, worldNormal, ProjectorCamera1, Sampler3, Sampler4, color)) { + if (Count > 1 && getProjectorColor(worldPos, worldNormal, ProjectorCamera1, ProjectorColor1, ProjectorDepth1, color)) { colorAcc += color; accCount += 1; } - if (Count > 2 && getProjectorColor(worldPos, worldNormal, ProjectorCamera2, Sampler5, Sampler6, color)) { + if (Count > 2 && getProjectorColor(worldPos, worldNormal, ProjectorCamera2, ProjectorColor2, ProjectorDepth2, color)) { colorAcc += color; accCount += 1; } @@ -125,5 +130,5 @@ void main() { discard; } - fragColor = colorAcc / accCount; + fragColor = vec4(colorAcc, 1) / accCount; } diff --git a/src/main/resources/assets/oc2/shaders/core/projectors.json b/src/main/resources/assets/oc2/shaders/core/projectors.json index e2138806..b26f9a94 100644 --- a/src/main/resources/assets/oc2/shaders/core/projectors.json +++ b/src/main/resources/assets/oc2/shaders/core/projectors.json @@ -8,13 +8,13 @@ "fragment": "oc2:projectors", "attributes": ["Position", "UV0"], "samplers": [ - {"name": "Sampler0"}, - {"name": "Sampler1"}, - {"name": "Sampler2"}, - {"name": "Sampler3"}, - {"name": "Sampler4"}, - {"name": "Sampler5"}, - {"name": "Sampler6"} + {"name": "MainCameraDepth"}, + {"name": "ProjectorColor0"}, + {"name": "ProjectorDepth0"}, + {"name": "ProjectorColor1"}, + {"name": "ProjectorDepth1"}, + {"name": "ProjectorColor2"}, + {"name": "ProjectorDepth2"} ], "uniforms": [ {"name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]},