PShader Texture Sphere / Processing 2b8
in
Programming Questions
•
5 months ago
Hello,
I want apply texture on Sphere in PShader mode, that's ok for the mapping but I lost the possibility to move, rotation... the sphere.
If any have an idea, I'll very happy.
Thx
Stan
I want apply texture on Sphere in PShader mode, that's ok for the mapping but I lost the possibility to move, rotation... the sphere.
If any have an idea, I'll very happy.
Thx
Stan
- PShader theShader;
PGraphics offscreen;
PImage img;
int sDetail = 35; // Sphere detail setting
float rotationX = 0;
float rotationY = 50;
float velocityX = 0;
float velocityY = 0;
float globeRadius = 150;
float pushBack = 0;
float[] cx, cz, sphereX, sphereY, sphereZ;
float sinLUT[];
float cosLUT[];
float SINCOS_PRECISION = 0.5;
int SINCOS_LENGTH = int(360.0 / SINCOS_PRECISION);
void setup()
{
size(800, 600, P3D);
img = loadImage("BancPublic.jpg");
//sphere
initializeSphere(sDetail);
//offscreen
offscreen = createGraphics(width,height,P3D);
//shader
theShader = loadShader("dither_frag.glsl");
theShader.set("scale", 10.5);
}
void draw()
{
renderGlobeOffscreen();
}
void renderGlobeOffscreen() {
offscreen.beginDraw();
background(0) ;
pushMatrix();
translate(width * 0.33, height * 0.5, pushBack);
pushMatrix();
offscreen.noFill();
offscreen.stroke(255,200);
offscreen.strokeWeight(2);
offscreen.smooth();
popMatrix();
offscreen.lights();
pushMatrix();
offscreen.rotateX( radians(-rotationX) );
offscreen.rotateY( radians(270 - rotationY) );
offscreen.fill(200);
offscreen.noStroke();
offscreen.textureMode(IMAGE);
texturedSphere(globeRadius, img);
popMatrix();
popMatrix();
rotationX += velocityX;
rotationY += velocityY;
velocityX *= 0.95;
velocityY *= 0.95;
println(rotationX + " / " + radians(-rotationX) ) ;
offscreen.endDraw();
shader(theShader);
image(offscreen,0,0);
// Implements mouse control (interaction will be inverse when sphere is upside down)
if(mousePressed){
velocityX += (mouseY-pmouseY) * 0.01;
velocityY -= (mouseX-pmouseX) * 0.01;
}
}
Sphere
- void initializeSphere(int res)
{
sinLUT = new float[SINCOS_LENGTH];
cosLUT = new float[SINCOS_LENGTH];
for (int i = 0; i < SINCOS_LENGTH; i++) {
sinLUT[i] = (float) Math.sin(i * DEG_TO_RAD * SINCOS_PRECISION);
cosLUT[i] = (float) Math.cos(i * DEG_TO_RAD * SINCOS_PRECISION);
}
float delta = (float)SINCOS_LENGTH/res;
float[] cx = new float[res];
float[] cz = new float[res];
// Calc unit circle in XZ plane
for (int i = 0; i < res; i++) {
cx[i] = -cosLUT[(int) (i*delta) % SINCOS_LENGTH];
cz[i] = sinLUT[(int) (i*delta) % SINCOS_LENGTH];
}
// Computing vertexlist vertexlist starts at south pole
int vertCount = res * (res-1) + 2;
int currVert = 0;
// Re-init arrays to store vertices
sphereX = new float[vertCount];
sphereY = new float[vertCount];
sphereZ = new float[vertCount];
float angle_step = (SINCOS_LENGTH*0.5f)/res;
float angle = angle_step;
// Step along Y axis
for (int i = 1; i < res; i++) {
float curradius = sinLUT[(int) angle % SINCOS_LENGTH];
float currY = -cosLUT[(int) angle % SINCOS_LENGTH];
for (int j = 0; j < res; j++) {
sphereX[currVert] = cx[j] * curradius;
sphereY[currVert] = currY;
sphereZ[currVert++] = cz[j] * curradius;
}
angle += angle_step;
}
sDetail = res;
}
// Generic routine to draw textured sphere
void texturedSphere(float r, PImage t) {
int v1,v11,v2;
r = (r + 240 ) * 0.33;
beginShape(TRIANGLE_STRIP);
texture(t);
float iu=(float)(t.width-1)/(sDetail);
float iv=(float)(t.height-1)/(sDetail);
float u=0,v=iv;
for (int i = 0; i < sDetail; i++) {
vertex(0, -r, 0,u,0);
vertex(sphereX[i]*r, sphereY[i]*r, sphereZ[i]*r, u, v);
u+=iu;
}
vertex(0, -r, 0,u,0);
vertex(sphereX[0]*r, sphereY[0]*r, sphereZ[0]*r, u, v);
endShape();
// Middle rings
int voff = 0;
for(int i = 2; i < sDetail; i++) {
v1=v11=voff;
voff += sDetail;
v2=voff;
u=0;
beginShape(TRIANGLE_STRIP);
texture(t);
for (int j = 0; j < sDetail; j++) {
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1++]*r, u, v);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2++]*r, u, v+iv);
u+=iu;
}
// Close each ring
v1=v11;
v2=voff;
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1]*r, u, v);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v+iv);
endShape();
v+=iv;
}
u=0;
// Add the northern cap
beginShape(TRIANGLE_STRIP);
texture(t);
for (int i = 0; i < sDetail; i++) {
v2 = voff + i;
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v);
vertex(0, r, 0,u,v+iv);
u+=iu;
}
vertex(sphereX[voff]*r, sphereY[voff]*r, sphereZ[voff]*r, u, v);
endShape();
}
GLSL
- #define PROCESSING_TEXTURE_SHADER
uniform sampler2D texture;
uniform float scale;
varying vec4 vertTexCoord;
float find_closest(int x, int y, float c0)
{
mat4 dither = mat4(
1.0, 33.0, 9.0, 41.0,
49.0, 17.0, 57.0, 25.0,
13.0, 45.0, 5.0, 37.0,
61.0, 29.0, 53.0, 21.0 );
float limit = 0.0;
if(x < 4) {
if(y >= 4) {
limit = (dither[x][y-4]+3.0)/65.0;
} else {
limit = (dither[x][y])/65.0;
}
}
if(x >= 4) {
if(y >= 4)
limit = (dither[x-4][y-4]+1.0)/65.0;
else
limit = (dither[x-4][y]+2.0)/65.0;
}
if(c0 < limit)
return 0.0;
return 1.0;
}
void main(void)
{
float grayscale = dot( texture2D(texture, vertTexCoord.xy), vec4(0.299, 0.587, 0.114, 0));
vec2 xy = gl_FragCoord.xy * scale;
//int x = int(mod(gl_FragCoord.x, 8));
int x = int(mod(xy.x, 8.0));
int y = int(mod(xy.y, 8.0));
float final = find_closest(x, y, grayscale);
// gl_FragColor = texture2D(texture, vertTexCoord.xy);//vec4(final, final, final, 1.0);
gl_FragColor = vec4(final, final, final, 1.0);
}
1