Skip to content

Commit d360191

Browse files
ports cosmicrender from avaritia to gtnhlib (#205)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent fa9cd78 commit d360191

File tree

25 files changed

+719
-0
lines changed

25 files changed

+719
-0
lines changed
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
package com.gtnewhorizon.gtnhlib.client.renderer.shader;
2+
3+
import java.nio.FloatBuffer;
4+
5+
import net.minecraft.client.Minecraft;
6+
import net.minecraft.util.IIcon;
7+
import net.minecraft.world.World;
8+
import net.minecraftforge.client.event.GuiScreenEvent;
9+
import net.minecraftforge.client.event.TextureStitchEvent;
10+
11+
import org.lwjgl.BufferUtils;
12+
import org.lwjgl.opengl.GL20;
13+
14+
import com.gtnewhorizon.gtnhlib.GTNHLib;
15+
import com.gtnewhorizon.gtnhlib.eventbus.EventBusSubscriber;
16+
import com.gtnewhorizon.gtnhlib.mixins.early.EntityRendererAccessor;
17+
18+
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
19+
import cpw.mods.fml.common.gameevent.TickEvent.Phase;
20+
import cpw.mods.fml.common.gameevent.TickEvent.RenderTickEvent;
21+
22+
/// This was largely copied from avaritia
23+
@EventBusSubscriber
24+
public class UniverseShader extends ShaderProgram {
25+
26+
public static final UniverseShader INSTANCE = new UniverseShader();
27+
28+
private UniverseShader() {
29+
super(GTNHLib.MODID, "shaders/universe/universe.vert", "shaders/universe/universe.frag");
30+
}
31+
32+
private static final int COSMIC_COUNT = 10;
33+
public static final String[] COSMIC_TEXTURES = new String[COSMIC_COUNT];
34+
35+
static {
36+
for (int i = 0; i < COSMIC_COUNT; i++) {
37+
COSMIC_TEXTURES[i] = GTNHLib.MODID + ":universe/cosmic" + i;
38+
}
39+
}
40+
41+
public static final FloatBuffer COSMIC_UVS = BufferUtils.createFloatBuffer(4 * COSMIC_TEXTURES.length);
42+
public static final IIcon[] COSMIC_ICONS = new IIcon[COSMIC_TEXTURES.length];
43+
44+
public static final float[] LIGHT_LEVEL = new float[3];
45+
46+
@SubscribeEvent
47+
public static void letsMakeAQuilt(TextureStitchEvent.Pre event) {
48+
if (event.map.getTextureType() != 0) {
49+
return;
50+
}
51+
52+
for (int i = 0; i < COSMIC_TEXTURES.length; i++) {
53+
IIcon icon = event.map.registerIcon(COSMIC_TEXTURES[i]);
54+
COSMIC_ICONS[i] = icon;
55+
}
56+
}
57+
58+
@SubscribeEvent
59+
public static void pushTheCosmicFancinessToTheLimit(RenderTickEvent event) {
60+
if (event.phase == Phase.START) {
61+
for (IIcon icon : COSMIC_ICONS) {
62+
COSMIC_UVS.put(icon.getMinU());
63+
COSMIC_UVS.put(icon.getMinV());
64+
COSMIC_UVS.put(icon.getMaxU());
65+
COSMIC_UVS.put(icon.getMaxV());
66+
}
67+
68+
COSMIC_UVS.flip();
69+
}
70+
}
71+
72+
private static boolean inventoryRender = false;
73+
74+
@SubscribeEvent
75+
public static void makeCosmicStuffLessDumbInGUIs(GuiScreenEvent.DrawScreenEvent.Pre event) {
76+
inventoryRender = true;
77+
}
78+
79+
@SubscribeEvent
80+
public static void finishMakingCosmicStuffLessDumbInGUIs(GuiScreenEvent.DrawScreenEvent.Post event) {
81+
inventoryRender = false;
82+
}
83+
84+
@Override
85+
public void use() {
86+
super.use();
87+
88+
Minecraft mc = Minecraft.getMinecraft();
89+
90+
float yaw = 0;
91+
float pitch = 0;
92+
float scale = 1.0f;
93+
94+
if (!inventoryRender) {
95+
yaw = (float) ((mc.thePlayer.rotationYaw * 2 * Math.PI) / 360.0);
96+
pitch = -(float) ((mc.thePlayer.rotationPitch * 2 * Math.PI) / 360.0);
97+
} else {
98+
scale = 25.0f;
99+
}
100+
101+
int time2 = INSTANCE.getUniformLocation("time2");
102+
GL20.glUniform1f(time2, mc.thePlayer.ticksExisted);
103+
104+
int x = INSTANCE.getUniformLocation("yaw");
105+
GL20.glUniform1f(x, yaw);
106+
107+
int z = INSTANCE.getUniformLocation("pitch");
108+
GL20.glUniform1f(z, pitch);
109+
110+
int l = INSTANCE.getUniformLocation("lightlevel");
111+
GL20.glUniform3f(l, LIGHT_LEVEL[0], LIGHT_LEVEL[1], LIGHT_LEVEL[2]);
112+
113+
int lightmix = INSTANCE.getUniformLocation("lightmix");
114+
GL20.glUniform1f(lightmix, 0.2f);
115+
116+
int uvs = INSTANCE.getUniformLocation("cosmicuvs");
117+
GL20.glUniformMatrix2(uvs, false, COSMIC_UVS);
118+
119+
int s = INSTANCE.getUniformLocation("externalScale");
120+
GL20.glUniform1f(s, scale);
121+
122+
int o = INSTANCE.getUniformLocation("opacity");
123+
GL20.glUniform1f(o, 1f);
124+
}
125+
126+
public static void setLightFromLocation(World world, int x, int y, int z) {
127+
if (world == null) {
128+
setLightLevel(1.0f);
129+
return;
130+
}
131+
132+
int coord = world.getLightBrightnessForSkyBlocks(x, y, z, 0);
133+
134+
int[] map = ((EntityRendererAccessor) Minecraft.getMinecraft().entityRenderer).getLightmapColors();
135+
136+
if (map == null) {
137+
setLightLevel(1.0f);
138+
return;
139+
}
140+
141+
int mx = (coord % 65536) / 16;
142+
int my = (coord / 65536) / 16;
143+
144+
int lightColour = map[Math.max(0, Math.min(map.length - 1, my * 16 + mx))];
145+
146+
setLightLevel(
147+
((lightColour >> 16) & 0xFF) / 256.0f,
148+
((lightColour >> 8) & 0xFF) / 256.0f,
149+
((lightColour) & 0xFF) / 256.0f);
150+
}
151+
152+
public static void setLightLevel(float level) {
153+
setLightLevel(level, level, level);
154+
}
155+
156+
public static void setLightLevel(float r, float g, float b) {
157+
LIGHT_LEVEL[0] = Math.max(0.0f, Math.min(1.0f, r));
158+
LIGHT_LEVEL[1] = Math.max(0.0f, Math.min(1.0f, g));
159+
LIGHT_LEVEL[2] = Math.max(0.0f, Math.min(1.0f, b));
160+
}
161+
}

src/main/java/com/gtnewhorizon/gtnhlib/mixins/Mixins.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public enum Mixins implements IMixins {
3838
"block_sounds.MixinPlayerControllerMP")
3939
.addClientMixins("block_sounds.MixinRenderGlobal").setPhase(Phase.EARLY)
4040
.setApplyIf(() -> GTNHLibConfig.blockSoundMixins)),
41+
ENTITY_RENDERER_ACCESSOR(new MixinBuilder("Accesses the lightmap property of EntityRenderer").setPhase(Phase.EARLY)
42+
.addCommonMixins("EntityRendererAccessor")),
4143
//
4244
;
4345

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.gtnewhorizon.gtnhlib.mixins.early;
2+
3+
import net.minecraft.client.renderer.EntityRenderer;
4+
5+
import org.spongepowered.asm.mixin.Mixin;
6+
import org.spongepowered.asm.mixin.gen.Accessor;
7+
8+
@Mixin(EntityRenderer.class)
9+
public interface EntityRendererAccessor {
10+
11+
@Accessor("lightmapColors")
12+
int[] getLightmapColors();
13+
}
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
#version 120
2+
3+
#define M_PI 3.1415926535897932384626433832795
4+
5+
const int cosmiccount = 10;
6+
const int cosmicoutof = 101;
7+
8+
uniform sampler2D texture0;
9+
uniform vec3 lightlevel;
10+
11+
uniform float time2;
12+
13+
uniform float yaw;
14+
uniform float pitch;
15+
uniform float externalScale;
16+
17+
uniform float lightmix;
18+
uniform float opacity;
19+
20+
uniform mat2 cosmicuvs[cosmiccount];
21+
22+
varying vec3 position;
23+
24+
float rand2d(vec2 x) {
25+
return fract(sin(mod(dot(x, vec2(12.9898, 78.233)), 3.14)) * 43758.5453);
26+
}
27+
28+
mat4 rotationMatrix(vec3 axis, float angle) {
29+
axis = normalize(axis);
30+
float s = sin(angle);
31+
float c = cos(angle);
32+
float oc = 1.0 - c;
33+
34+
return mat4(
35+
oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0,
36+
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0,
37+
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0,
38+
0.0, 0.0, 0.0, 1.0);
39+
}
40+
41+
void main (void) {
42+
vec4 light = gl_Color;
43+
vec4 mask = texture2D(texture0, gl_TexCoord[0].xy);
44+
light.rgb *= lightlevel;
45+
float correctTime = mod(time2,12000);
46+
47+
float oneOverExternalScale = 1.0/externalScale;
48+
49+
int uvtiles = 16;
50+
51+
// background colour
52+
vec4 col = vec4(0.1,0.0,0.0,1.0);
53+
54+
float pulse = mod(correctTime,400)/400.0;
55+
56+
col.g = sin(pulse*M_PI*2) * 0.075 + 0.225;
57+
col.b = cos(pulse*M_PI*2) * 0.05 + 0.3;
58+
59+
// get ray from camera to fragment
60+
vec4 dir = normalize(vec4( -position, 0));
61+
62+
// rotate the ray to show the right bit of the sphere for the angle
63+
float sb = sin(pitch);
64+
float cb = cos(pitch);
65+
dir = normalize(vec4(dir.x, dir.y * cb - dir.z * sb, dir.y * sb + dir.z * cb, 0));
66+
67+
float sa = sin(-yaw);
68+
float ca = cos(-yaw);
69+
dir = normalize(vec4(dir.z * sa + dir.x * ca, dir.y, dir.z * ca - dir.x * sa, 0));
70+
71+
vec4 ray;
72+
73+
// draw the layers
74+
for (int i=0; i<16; i++) {
75+
int mult = 16-i;
76+
77+
// get semi-random stuff
78+
int j = i + 7;
79+
float rand1 = (j * j * 4321 + j * 8) * 2.0;
80+
int k = j + 1;
81+
float rand2 = (k * k * k * 239 + k * 37) * 3.6;
82+
float rand3 = rand1 * 347.4 + rand2 * 63.4;
83+
84+
// random rotation matrix by random rotation around random axis
85+
vec3 axis = normalize(vec3(sin(rand1), sin(rand2) , cos(rand3)));
86+
87+
// apply
88+
ray = dir * rotationMatrix(axis, mod(rand3, 2*M_PI));
89+
90+
// calcuate the UVs from the final ray
91+
float rawu = 0.5 + (atan(ray.z,ray.x)/(2*M_PI));
92+
float rawv = 0.5 + (asin(ray.y)/M_PI);
93+
94+
// get UV scaled for layers and offset by time;
95+
float scale = mult*0.5 + 2.75;
96+
float u = rawu * scale * externalScale;
97+
//float v = (rawv + time * 0.00006) * scale * 0.6;
98+
float v = (rawv + correctTime * 0.0002 * oneOverExternalScale) * scale * 0.6 * externalScale;
99+
100+
vec2 tex = vec2( u, v );
101+
102+
// tile position of the current uv
103+
int tu = int(mod(floor(u*uvtiles),uvtiles));
104+
int tv = int(mod(floor(v*uvtiles),uvtiles));
105+
106+
// get pseudorandom variants
107+
int symbol = int(rand2d(vec2(tu, tv + i * 10.0)) * cosmicoutof);
108+
int rotation = int(mod(pow(tu,float(tv)) + tu + 3 + tv*i, 8));
109+
bool flip = false;
110+
if (rotation >= 4) {
111+
rotation -= 4;
112+
flip = true;
113+
}
114+
115+
// if it's an icon, then add the colour!
116+
if (symbol >= 0 && symbol < cosmiccount) {
117+
118+
vec2 cosmictex = vec2(1.0,1.0);
119+
vec4 tcol = vec4(1.0,0.0,0.0,1.0);
120+
121+
// get uv within the tile
122+
float ru = clamp(mod(u,1.0)*uvtiles - tu, 0.0, 1.0);
123+
float rv = clamp(mod(v,1.0)*uvtiles - tv, 0.0, 1.0);
124+
125+
if (flip) {
126+
ru = 1.0 - ru;
127+
}
128+
129+
float oru = ru;
130+
float orv = rv;
131+
132+
// rotate uvs if necessary
133+
if (rotation == 1) {
134+
oru = 1.0-rv;
135+
orv = ru;
136+
} else if (rotation == 2) {
137+
oru = 1.0-ru;
138+
orv = 1.0-rv;
139+
} else if (rotation == 3) {
140+
oru = rv;
141+
orv = 1.0-ru;
142+
}
143+
144+
// get the iicon uvs for the tile
145+
float umin = cosmicuvs[symbol][0][0];
146+
float umax = cosmicuvs[symbol][1][0];
147+
float vmin = cosmicuvs[symbol][0][1];
148+
float vmax = cosmicuvs[symbol][1][1];
149+
150+
// interpolate based on tile uvs
151+
cosmictex.x = umin * (1.0-oru) + umax * oru;
152+
cosmictex.y = vmin * (1.0-orv) + vmax * orv;
153+
154+
tcol = texture2D(texture0, cosmictex);
155+
156+
// set the alpha, blending out at the bunched ends
157+
float a = tcol.r * (0.5 + (1.0/mult) * 1.0) * (1.0-smoothstep(0.15, 0.48, abs(rawv-0.5)));
158+
159+
// get fancy colours
160+
float r = (mod(rand1, 29.0)/29.0) * 0.3 + 0.4;
161+
float g = (mod(rand2, 35.0)/35.0) * 0.4 + 0.6;
162+
float b = (mod(rand1, 17.0)/17.0) * 0.3 + 0.7;
163+
164+
// mix the colours
165+
//col = col*(1-a) + vec4(r,g,b,1)*a;
166+
col = col + vec4(r,g,b,1)*a;
167+
}
168+
}
169+
170+
// apply lighting
171+
vec3 shade = light.rgb * (lightmix) + vec3(1.0-lightmix,1.0-lightmix,1.0-lightmix);
172+
col.rgb *= shade;
173+
174+
// apply mask
175+
col.a *= mask.a * opacity;
176+
177+
col = clamp(col,0.0,1.0);
178+
179+
gl_FragColor = col;
180+
}

0 commit comments

Comments
 (0)