szukam algorytmu do bump mappingu w wersji 2D , tzn tak mam teksture 2d i światło 2d liczone na tą teksture , wszędzie są wzory i szkolenia na google w wersji 3D a to utrudnia sprawe, o to kod do renderingu światła:
void RendererLight(int x,int y,int r,float a)
{
for(int py=y-r;py<y+r;py+=1)
{
for(int px=x-r;px<x+r;px+=1)
{
float r2=1-sqrt( (px-x)*(px-x)+(py-y)*(py-y))/float(r);
if(r2<0)
r2=0;
if(r2>1)
r2=1;
unsigned char red;
unsigned char green;
unsigned char blue;
GetPixel(px,py,red,green,blue);
float r1,g1,b1;
r1=float(red)/255;
g1=float(green)/255;
b1=float(blue)/255;
float t=(r1+g1+b1)*r1*g1*b1;
t=t*a*r2;
r1+=r2*a*r1+t;
g1+=r2*a*g1+t;
b1+=r2*a*b1+t;
if(r1>1)
r1=1;
if(g1>1)
g1=1;
if(b1>1)
b1=1;
unsigned char rW=r1*255;
unsigned char gW=g1*255;
unsigned char bW=b1*255;
Color3iT(rW,gW,bW);
PutPixelT(px,py);
}
}
}
x,y - pozycja środek , r - promień czyli zasięg , a - natężenie światła domyślnie na wartość 1
i jak tutaj dopisać liczenie wybojów tzn bump mapy przy czym chciałbym aby normal map była liczona na bieżąco a nie wczytywana z tekstury ponieważ światło jest nakładane na teksture a nie wyświetlana tekstura tzn rendering w połączeniu z światłem.
EDIT: znalazłem algorytm do liczenia normalnej
std::vector<std::vector<float>> heightMap = {
{0.1f, 0.2f, 0.1f},
{0.3f, 0.4f, 0.3f},
{0.2f, 0.1f, 0.2f}
};
float calculateNormal(int x, int y) {
// Basic finite difference approximation for normal calculation
float dx = (heightMap[x + 1][y] - heightMap[x - 1][y]) / 2.0f;
float dy = (heightMap[x][y + 1] - heightMap[x][y - 1]) / 2.0f;
return std::sqrt(dx * dx + dy * dy);
}
EDIT: tutaj znalazłem technologie ale jak to rozpisać na łatwiejszą wersje:
cv::Mat applyBumpMapping(const cv::Mat& image, const cv::Mat& bumpMap, const cv::Point3f& lightPosition) {
cv::Mat resultImage = image.clone();
int width = image.cols;
int height = image.rows;
// Iterate over each pixel in the image
for (int y = 1; y < height - 1; ++y) {
for (int x = 1; x < width - 1; ++x) {
// Get the bump map height value for this pixel
float heightValue = bumpMap.at<float>(y, x);
// Calculate the normal perturbation using the surrounding pixels
float dx = bumpMap.at<float>(y, x + 1) - bumpMap.at<float>(y, x - 1);
float dy = bumpMap.at<float>(y + 1, x) - bumpMap.at<float>(y - 1, x);
// Simulate a basic normal perturbation (just using the gradient)
cv::Point3f normal(dx, dy, 1.0f); // Assume the normal is affected by the bump map
// Normalize the normal
float length = std::sqrt(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z);
normal /= length;
// Calculate the light direction (lightPosition is a 3D vector)
cv::Point3f lightDir = lightPosition - cv::Point3f(x, y, 0);
length = std::sqrt(lightDir.x * lightDir.x + lightDir.y * lightDir.y + lightDir.z * lightDir.z);
lightDir /= length;
// Calculate the dot product between normal and light direction
float intensity = std::max(0.0f, normal.dot(lightDir));
// Get the original pixel color
cv::Vec3b pixelColor = image.at<cv::Vec3b>(y, x);
// Modify the pixel color based on the intensity
pixelColor[0] = std::min(255, (int)(pixelColor[0] * intensity));
pixelColor[1] = std::min(255, (int)(pixelColor[1] * intensity));
pixelColor[2] = std::min(255, (int)(pixelColor[2] * intensity));
resultImage.at<cv::Vec3b>(y, x) = pixelColor;
}
}
jeszcze brakuje algorytmu do liczenia bump mapy dla pojedynczego pixela w locie zamiast zapodanej całej tablicy
EDIT: ten algorytm jest z chatgp i jest wadliwy , wie ktoś i czy zna jakiś algorytm do policzenia bump mappingu 2D?