sp614x / optifine

1.81k stars 416 forks source link

[Request] Adding geometry shaders #1355

Closed sonicether closed 6 years ago

sonicether commented 6 years ago

I'm not sure if this is practical or not, but I'd like to be able to have the option of having a duplicate copy of all geometry provided to a program, with an attribute to identify the original vs the duplicate geometry.

This could be useful for a few applications. We could do our own stereoscopic 3D rendering (analyph, for example), or use this feature to render "multiple shadow maps" (which would also allow me to render the sunlight shadow map as well as "voxelize" the world with my technique) by applying different transformations to each "copy" of the geometry. Another idea is rendering a traditional planar reflection for water at sea level.

If we could use geometry shaders, we could of course do this ourselves, but alas, we don't. I know almost nothing about Vertex Buffer Objects and don't know how heavy this would be to do on the CPU side.

sp614x commented 6 years ago

Geometry shaders could be added if needed. This should be easier and faster than duplicating all the geometry and adding a flag attribute.

sonicether commented 6 years ago

If geometry shaders could be added, that would be awesome!

sp614x commented 6 years ago

Testing geometry shaders

image

#version 150

layout(triangles) in;
layout(triangle_strip, max_vertices = 6) out;

in vec2 gtexcoord[];
in vec2 glmcoord[];
in vec4 gcolor[];

out vec2 texcoord;
out vec2 lmcoord;
out vec4 color;

void main()
{   
  // Original geometry
  for(int i = 0; i < 3; i++)
  {
    gl_Position = gl_in[i].gl_Position;
    //
    texcoord = gtexcoord[i];
    lmcoord = glmcoord[i];
    color = gcolor[i];
    //
    EmitVertex();
  }
  EndPrimitive();

  // New geometry
  for(int i = 0; i < 3; i++)
  {
    vec4 pos = gl_in[i].gl_Position;
    pos.xy += 0.5;
    gl_Position = pos;
    //
    texcoord = gtexcoord[i];
    lmcoord = glmcoord[i];
    color = gcolor[i];
    //
    EmitVertex();
  }
  EndPrimitive();
}
sonicether commented 6 years ago

Fantastic!!

sp614x commented 6 years ago

Updated preview D2 for 1.12.2

https://github.com/sp614x/optifine/blob/master/OptiFineDoc/doc/shaders.txt#L17

sp614x commented 6 years ago

Currently the geometry shaders need OpenGL 3.2 (core). Support for the older ARB_geometry_shader4 can also be added if needed. It works a bit differently, but only requires OpenGL 2.0. This may be useful for Macs which in Minecraft are limited to OpenGL 2.1. The main difference is that the input/output types have to be specified via gl_ProgramParameteriARB() in the Java code instead of GLSL layout qualifiers.

sp614x commented 6 years ago

Looks like it may work for Macs: https://stackoverflow.com/questions/4179828/opengl-geometry-shader-mac-os-x?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

Most of the MC geometry is defined as triangles (quads) so the input/output type may be fixed to TRIANGLES. Only the max out vertices are to be configurable.

sp614x commented 6 years ago

Using GL_ARB_geometry_shader4 with OpenGL 2.1 (Mac compatible):

#version 120
#extension GL_ARB_geometry_shader4 : enable

// GEOMETRY_VERTICES_OUT_ARB
const int maxVerticesOut = 6;

varying in vec2 gtexcoord[];
varying in vec2 glmcoord[];
varying in vec4 gcolor[];

varying out vec2 texcoord;
varying out vec2 lmcoord;
varying out vec4 color;

void main()
{
  for(int i = 0; i < gl_VerticesIn; i++)
  {
    gl_Position = gl_PositionIn[i];
    //
    texcoord = gtexcoord[i];
    lmcoord = glmcoord[i];
    color = gcolor[i];
    //
    EmitVertex();
  }
  EndPrimitive();

  // New piece of geometry!
  for(int i = 0; i < gl_VerticesIn; i++)
  {
    vec4 vertex = gl_PositionIn[i];
    vertex.xy += 0.5;
    gl_Position = vertex;
    //
    texcoord = gtexcoord[i];
    lmcoord = glmcoord[i];
    color = gcolor[i];
    //
    EmitVertex();
  }
  EndPrimitive();
}
sp614x commented 6 years ago

Updated preview D2 for 1.12.2

https://github.com/sp614x/optifine/blob/master/OptiFineDoc/doc/shaders.txt#L20 https://github.com/sp614x/optifine/blob/master/OptiFineDoc/doc/shaders.txt#L349