GLSL Shader on 3D Ring not working

I’m try to map GLSL texture shader to 3D ring, I’ve got little working, but I think i’m miss some translation to 3D (i think), as it’s mapping it to 2D. I try use fragment from processing site. Where am I going wrong?

sketch.pde

PShape mRing;
float angle;
int time;

PShader mShader;

void setup() 
{
  time = 0;
  size(800, 600, P3D);
  
  mRing = loadRing(160,80,24,24);
  mShader = loadShader("fragment.glsl");
}



void draw() 
{
  background(128);
  translate(width/2, height/2);
  rotateY(angle);
  
  mShader.set("u_resolution", float(width), float(height));
  mShader.set("u_time", time);
  shader(mShader);
  shape(mRing);
  
  angle += 0.01;
  time+= 0.5;
}

PShape loadRing(float outerRad, float innerRad, int numc, int numt) 
{
  textureMode(NORMAL);
  PShape shape = createShape();

  shape.beginShape(TRIANGLE_STRIP);
  shape.noStroke();

  float x, y, z, s, t, u, v;
  float nx, ny, nz;
  float p1, p2;
  for (int a = 0; a < numc; a++) 
  {
    for (int b = 0; b <= numt; b++) 
    {
      for (int c = 1; c >= 0; c--) 
      {
         s = (a + c) % numc + 0.5;
         t = b % numt;
         u = s / numc;
         v = t / numt;
         p1 = s * TWO_PI / numc;
         p2 = t * TWO_PI / numt;
 
         x = (outerRad + innerRad * cos(p1)) * cos(p2);
         y = (outerRad + innerRad * cos(p1)) * sin(p2);
         z = innerRad * sin(p1);
 
         nx = cos(p1) * cos(p2); 
         ny = cos(p1) * sin(p2);
         nz = sin(p1);
         shape.normal(nx, ny, nz);
         shape.vertex(x, y, z);
      }
    }
  }
  shape.endShape(); 
  return shape;
}

fragment.glsl


#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform float u_time;

#define PI 3.14159265358979323846

vec2 rotate2D(vec2 _st, float _angle){
    _st -= 0.5;
    _st =  mat2(cos(_angle),-sin(_angle),
                sin(_angle),cos(_angle)) * _st;
    _st += 0.5;
    return _st;
}

vec2 tile(vec2 _st, float _zoom){
    _st *= _zoom;
    return fract(_st);
}

float box(vec2 _st, vec2 _size, float _smoothEdges){
    _size = vec2(0.5)-_size*0.5;
    vec2 aa = vec2(_smoothEdges*0.5);
    vec2 uv = smoothstep(_size,_size+aa,_st);
    uv *= smoothstep(_size,_size+aa,vec2(1.0)-_st);
    return uv.x*uv.y;
}

void main(void){
    vec2 st = gl_FragCoord.xy/u_resolution.xy;
    vec3 color = vec3(0.0);

    st = tile(st,4.);

    st = rotate2D(st,PI*0.25);

    color = vec3(box(st,vec2(0.7),0.01));
    gl_FragColor = vec4(color,1.0);
}
1 Like

This is what happens when I run your program.

What exactly are you trying to accomplish here?

You mentioned texture mapping but shaders aren’t used to map textures, they’re used to control the flow of data going through the gpu. You can handle texture mapping with UVs when you’re defining your shape.

You’re currently defining no UVs in your loadRing() function.

I try to make a tile pattern on 3d ring. Not texture, I follow tutorial online, but it not working with ring. Now it look like it mask to ring, not apply pattern to ring surface.I think calculation not for 3D? How do i make tile pattern stick to ring.

You need to tell us what you’re trying to accomplish. As far as what you’re saying is concerned, you’re asking

and as far as your description is concerned, you have a tile pattern on a 3d ring right there.

We’re gonna need a better description of what exactly you want. You can either post the tutorial you’re following or describe what you want more precisely. In your first post you said you wanted “to map GLSL texture shader to 3D ring”, and now you’re saying “Not texture”, so what you’re asking for isn’t very clear at all.

Keep in mind as well that although Processing can handle and run GLSL shader code it’s not very well supported in its documentation. This forum is also for the Processing language and not GLSL. Considering that, along with how Processing is a beginner friendly language, it’s not very likely you will find support for GLSL here. I recommend you find resources elsewhere regarding GLSL help. I left some resources for GLSL and writing shaders in another forum post elsewhere.

Thank you for your answer.

I have 3D Ring, and I want to use GLSL to draw tile pattern on the ring. Same as below, but different pattern.


I want to use my own pattern. I think i did wrong, because I copy code for square? I am still new, and try to understand, but difficult.

I started looking through your shader code and there’s nothing accessing the location of any vertices (uv coordinates) and no fragment is asking for the location of where it is relative to the shape.

As I’m looking through it I’m seeing copy-pasted code from here and not much else. In the end, the code is simply mapping screen space to values, and wherever a fragment is being drawn it is drawing that color.

Once again, your question isn’t a coding question regarding processing and it’s a question regarding GLSL and implementation of graphics language concepts.

Once again I suggest you read my response to another user’s question about GLSL code. It contains several resources to help you learn GLSL as well as writing shaders along with access to communities that can help you learn. There’s not much this forum can do for you otherwise.

1 Like

ok, thank you for your help.

Hi! I think there are two ways to have a texture in a torus. One is to use an image mapped to it. For that you would pass the texture uv coordinates for each single vertex in the torus. The other option is to create generative patterns, which I think is what you are trying to do.

I think the easiest way to figure it out is to use http://shdr.bkcore.com/ On the top right you can choose the torus shape. You can edit both vertex and fragment shaders on that page. The fragment shader is already receiving the positions and normals, and that should be enough to create a generative pattern.

The reason I suggest using that page is that you can do live coding and forget about the issues that might be introduced by Processing. You get faster feedback so you know if you are getting closer or not. Once you figure it out, if you have trouble porting the code to Processing you can share your working code from shdr.bkcore.com (click the share button, post here the URL) and then try figuring out why it doesn’t work in Processing.

1 Like

Thankyou, that site is very good. It show me I have shader and vertex almost correct.

But when I try to use standard torus, and I copy to processing

(http://shdr.bkcore.com/#1/dZHLTsMwEEV/ZeRViqLw6qoVKyR2IFZsCEImcdKpHE9kO6UP9d+ZvNoQJSvLc+Z67lyfREpJVSjjnVh9itKqBB2SgQ3mmxIyTdKvY1MZzMgW7R08FmpQ3KnkAaxypCvPUiY7aQ9o8po8QvZODifBG6ul5jIDwhQKiSZYxOYUG4Bcf79YmT+TJgtPtWIZdIoQ7qO7BevOIpy1LL23+FN51Q4rryZGxPQu+n0K6fvqq+TW/X+2hIJSpT9Q/U7j0tJWJfWwC5/ZezanqUA6GWfResOjCoYu4aYDdTLQBFZvzf0jv9zYpNlHcokTrh5YxTjaH47r7jOGZLQgP8jNzX98haKZJlbt6W492cpFWyfOfw==)

It show black screen only. Even I make very simple.

void draw() 
{
  background(0);
  translate(width/2, height/2);
  shader.set("resolution", float(width), float(height));
  shader.set("time", millis() / 1000.0);
  
  shader(shader);
  shape(ring);

}

Hi! Could you share your full Processing program to test (including shaders)?

For some reason the shdr link you shared shows the default shader for me (mapping normals to colors). Maybe you can verify if your link is correct?

Cheers!

https://goo.gl/PRmxPB
my pattern i try.

My Sketch:

PShape ring;
PShader shader;

void setup() 
{
  size(800, 600, P3D);
  
  ring = loadRing(160,80,24,24);
  shader = loadShader("fragment.glsl","vertex.glsl");
}


void draw() 
{
  background(0);
  
  translate(width/2, height/2);
  
  shader(shader);
  shape(ring);
}



I get black screen, but on site it shows pattern.

Did you update the shaders to work with Processing? The uniform names are different in every platform (like ShaderToy, shdr, Procesing, openFrameworks, etc). So you can’t unfortunately copy paste the shaders from shdr to Processing.

Here are the default Processing shaders so you can look up the attributes and uniforms.

If you want the texture to be attached to the object, you should pass the position to the fragment shader without multiplying it by any matrix, so it uses the objects coordinates. Like here.

2 Likes