jzy3d-api icon indicating copy to clipboard operation
jzy3d-api copied to clipboard

Volume Rendering : can not mix shader based volume with legacy opengl polygons

Open jzy3d opened this issue 3 years ago • 2 comments

One can't mix colored polygons with volume properly

  • Polygon render black
  • Polygon are not visible behind the translucent parts of the volume

macOS 10.12

Capture d’écran 2021-12-13 à 16 05 58

Ubuntu 20.04 and macOS 11.4 on Silicon

Capture d’écran du 2021-12-13 17-03-32

Whereas the polygon have the following colors

Capture d’écran 2021-12-13 à 16 07 13

Can be reproduced with 2.0.1-SNAPSHOT and the following program

import java.nio.ByteBuffer;
import org.jzy3d.analysis.AWTAbstractAnalysis;
import org.jzy3d.analysis.AnalysisLauncher;
import org.jzy3d.chart.factories.AWTChartFactory;
import org.jzy3d.chart.factories.AWTPainterFactory;
import org.jzy3d.chart.factories.ChartFactory;
import org.jzy3d.chart.factories.IPainterFactory;
import org.jzy3d.colors.Color;
import org.jzy3d.colors.ColorMapper;
import org.jzy3d.colors.colormaps.ColorMapRainbow;
import org.jzy3d.maths.BoundingBox3d;
import org.jzy3d.plot3d.primitives.Polygon;
import org.jzy3d.plot3d.primitives.RandomGeom;
import org.jzy3d.plot3d.primitives.volume.Texture3D;
import org.jzy3d.plot3d.rendering.canvas.Quality;
import com.jogamp.opengl.util.GLBuffers;

public class VolumeDemo_Shaders extends AWTAbstractAnalysis {
  public static void main(String[] args) throws Exception {
    AnalysisLauncher.open(new VolumeDemo_Shaders());
  }

  @Override
  public void init() {

    ColorMapper colorMapper = new ColorMapper(new ColorMapRainbow(), 0, 1, new Color(1, 1, 1, 1.5f));

    ByteBuffer buffer = GLBuffers.newDirectByteBuffer(10 * 10 * 10 * 4);
    // make some kind of volume
    for (float x = 0; x < 2; x += 0.2) {
      for (float y = 0; y < 2; y += 0.2) {
        for (float z = 0; z < 2; z += 0.2) {
          buffer.putFloat((float) Math.sin(x * y * z));
        }
      }
    }

    Texture3D volume = new Texture3D(buffer, new int[] {10, 10, 10}, (float) 0, (float) 1,
        colorMapper, new BoundingBox3d(1, 10, 1, 10, 1, 10));
    
    RandomGeom rg= new RandomGeom();
    Polygon p1 = rg.poly(0, 0, 2, 10, 10, true, Color.RED);
    Polygon p2 = rg.poly(0, 0, 4, 10, 10, true, Color.GREEN);
    Polygon p3 = rg.poly(0, 0, 6, 10, 10, true, Color.BLUE);

    // Create a chart
    IPainterFactory p = new AWTPainterFactory();
    //p.setDebugGL(true);
    ChartFactory f = new AWTChartFactory(p);
    chart = f.newChart(Quality.Intermediate());
    chart.add(volume);
    chart.add(p1);
    chart.add(p2);
    chart.add(p3);
  }
}

jzy3d avatar Dec 13 '21 15:12 jzy3d

"Polygon are not visible behind the translucent parts of the volume" : this can be fixed by rendering the polygon first AND then the volume, which can be done by adding the volume last in the scene graph :

chart.add(p1);
chart.add(p2);
chart.add(p3);
chart.add(volume);
Capture d’écran 2021-12-13 à 18 28 49

This raises the need for an order independent transparency renderer. This is currently in progress (in module jzy3d-depthpeeling, on this branch). Trying to apply it to this scene involving Texture3D

DepthPeelingPainterFactory p = new DepthPeelingPainterFactory();
p.setPeelingMethod(PeelingMethod.WEIGHTED_AVERAGE_MODE);
ChartFactory f = new AWTChartFactory(p);

lead to better rendering of the R,G,B planes but a volume coloring mess

Capture d’écran 2021-12-13 à 18 23 19

Which renders quite the same when planes are removed

Capture d’écran 2021-12-13 à 18 31 47

The depth peeling implementation used in this example is here :

@jacobfilik

jzy3d avatar Dec 13 '21 17:12 jzy3d

See here an example of mixing volume and legacy polygons

https://forum.jogamp.org/TextRender-only-work-after-reshape-with-GL-TEXTURE2-binding-td4041609.html#a4041621

jzy3d avatar Feb 05 '22 11:02 jzy3d