Bonjour, j'essaie en ce moment de générer des ombres en utilisant le lancer de rayons.

J'ai donc un plan, et une sphère.
Le plan remplit toute la fenêtre et l'affectation d'une couleur à un pixel de la fenêtre se fait en déterminant si le pixel est à une certaine distance du centre de la sphère.

Puis dans un deuxième temps, j'ai essayé de déterminer pour chaque pixel de la fenêtre s'il montre une partie de la sphère ou une partie du plan. S'il montre une partie du plan, un rayon sera lancé à partir du plan vers une source lumineuse placée au dessus de la sphère. Si le rayon intersecte la sphère, le pixel sera noir, sinon il sera de la couleur du plan.

Le problème, c'est que je n'arrive pas à avoir des pixels noirs.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <GLUT/glut.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
 
// Sphere
#define X0 200
#define Y0 240
#define Z0 120
#define RAYON 100
 
// Source
#define XSOURCE 100
#define YSOURCE 240
#define ZSOURCE 420
 
struct vecteur{
  int xi;
  int xf;
  int yi;
  int yf;
  int zi;
  int zf;
};
 
// gcc -framework OpenGL -framework GLUT -framework Cocoa dures.c -o dures
 
void Display();
void Reshape(int h, int w);
int intersects(int xpix, int ypix, int zpix, int xsource, int ysource, int zsource);
 
 
int main(int argc, char **argv){
  // Initialisation de OpenGL
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
 
  // Creation de la fenetre
  glutInitWindowPosition(0, 0);
  glutInitWindowSize(640, 480);
  glutCreateWindow("Ombres dures");
 
  // Fonctions de base
  glutReshapeFunc(Reshape);
  glutDisplayFunc(Display);
 
  // Boucle principale
  glutMainLoop();
 
  return EXIT_SUCCESS;
}
 
 
void Reshape(int h, int w){
  // Zone d'affichage
  glViewport(0, 0, h, w);
 
  // Initialisation
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
 
  gluOrtho2D(0, 640, 0, 480);
  glMatrixMode(GL_MODELVIEW);
}
 
 
void Display(){
  int i, j;
  glMatrixMode(GL_MODELVIEW);
  glClearColor(0, 0, 0, 1);
  glClear(GL_COLOR_BUFFER_BIT);
  glLoadIdentity();
 
  // Simulation de construction des objets de la scene
  for(i=0 ; i<640 ; i++){
    for(j=0 ; j<480 ; j++){
      if(sqrt((X0-i)*(X0-i)+(Y0-j)*(Y0-j))<RAYON){
	// Le pixel montre une partie de la sphere
	glBegin(GL_POINTS);
	glColor3f(1, 1, 0);
	glVertex2i(i, j);
	glEnd();
      }
      else{
	// Le pixel montre une partie du plan
	if(intersects(i, j, 0, XSOURCE, YSOURCE, ZSOURCE) == 1){
	  // Le rayon lance du pixel vers la source intersecte la sphere
	  glBegin(GL_POINTS);
	  glColor3f(0, 0, 0);
	  glVertex2i(i, j);
	  glEnd();
	}
	else{
	  // Le rayon lance du pixel vers la source n'intersecte pas la sphere
	  glBegin(GL_POINTS);
	  glColor3f(1, 0, 1);
	  glVertex2i(i, j);
	  glEnd();
	}
      }
    }
  }
  glFlush();
  glutSwapBuffers();
}
 
 
int intersects(int xpix, int ypix, int zpix, int xsource, int ysource, int zsource){
  float xpc, ypc, zpc;
  float norm;
  float distance;
  // Vecteur rayon du pixel vers la source
  struct vecteur rayon;
  rayon.xi = xpix;
  rayon.xf = xsource;
  rayon.yi = ypix;
  rayon.yf = ysource;
  rayon.zi = zpix;
  rayon.zf = zsource;
 
  // Norme du vecteur rayon
  norm = sqrt((rayon.xf-rayon.xi)*(rayon.xf-rayon.xi)+(rayon.yf-rayon.yi)*(rayon.yf-rayon.yi)+(rayon.zf-rayon.zi)*(rayon.zf-rayon.zi));
 
  // Vecteur du pixel vers le centre de la sphere
  struct vecteur vpc;
  vpc.xi = xpix;
  vpc.xf = X0;
  vpc.yi = ypix;
  vpc.yf = X0;
  vpc.zi = zpix;
  vpc.zf = Z0;
 
  // Projection du centre de la sphere sur le rayon
  xpc = (vpc.xf-vpc.xi)*(rayon.xf-rayon.xi) / norm;
  ypc = (vpc.yf-vpc.yi)*(rayon.yf-rayon.yi) / norm;
  zpc = (vpc.zf-vpc.zi)*(rayon.zf-rayon.zi) / norm;
 
  // Distance du centre de la sphere au rayon
  distance = sqrt((X0-xpc)*(X0-xpc)+(Y0-ypc)*(Y0-ypc)+(Z0-zpc)*(Z0-zpc));
  if (distance>RAYON)
    // Il n'y a pas d'intersection
    return 0;
  else
    // Il y a une ou deux intersections
    return 1;
}
J'ai fait une double boucle sur les pixels, puis selon les cas, je leur ai affecté une couleur particulière.

Pour déterminer si un rayon intersecte la sphère, j'ai projeté le centre C de la sphère sur le rayon (le projeté noté PC) et si la distance entre C et PC était inférieure au rayon R de la sphère, il y a intersection. Sinon, il n'y en a pas.

Merci