bump mapping 2d softwarowy

bump mapping 2d softwarowy
wilkwielki
  • Rejestracja:ponad rok
  • Ostatnio:około 16 godzin
  • Postów:430
0

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:

Kopiuj
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

Kopiuj
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:

Kopiuj
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?

edytowany 8x, ostatnio: wilkwielki
AN
  • Rejestracja:około 19 lat
  • Ostatnio:około 5 godzin
0

EDIT: ten algorytm jest z chatgp i jest wadliwy , wie ktoś i czy zna jakiś algorytm do policzenia bump mappingu 2D?

To napisz na chatgpt, co jest nie tak i powinien wydać poprawioną wersję. Czasami to dopiero za dziesiątym razem wytworzony kod działa poprawnie i odpowiada potrzebom.

wilkwielki
  • Rejestracja:ponad rok
  • Ostatnio:około 16 godzin
  • Postów:430
0

juz mam napisałem ręcznie tylko coś jest jeszcze źle, nie iwiem czemu:

Kopiuj
void RendererLightBM(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;

				unsigned char leftred,leftgreen,leftblue;
				unsigned char rightred,rightgreen,rightblue;
				unsigned char upred,upgreen,upblue;
				unsigned char downred,downgreen,downblue;
				float left,right,up,down;
				float poziom,pion;
				GetPixel(px-1,py,leftred,leftgreen,leftblue);
				GetPixel(px+1,py,rightred,rightgreen,rightblue);
				GetPixel(px,py-1,upred,upgreen,upblue);
				GetPixel(px,py+1,downred,downgreen,downblue);
				left=float(leftred/255+leftgreen/255+leftblue/255)/3;
				right=float(rightred/255+rightgreen/255+rightblue/255)/3;
				up=float(upred/255+upgreen/255+upblue/255)/3;
				down=float(downred/255+downgreen/255+downblue/255)/3;
				poziom=(left+right)/2;
				pion=(up+down)/2;
				float lenght=sqrt(poziom*poziom+pion*pion);
				poziom=poziom/lenght;
				pion=pion/lenght;
				float lightDirX,lightDirY;
				lightDirX=x+r;
				lightDirY=y+r;
				lightDirX=lightDirX-px;
				lightDirY=lightDirY-py;
				lenght=sqrt(lightDirX*lightDirX+lightDirY*lightDirY);
				lightDirX=lightDirX/lenght;
				lightDirY=lightDirY/lenght;
				float S=lightDirX*poziom+lightDirY*pion;
				if(S<0)
					S=0;
				if(S>1)
					S=1;
				GetPixel(px,py,red,green,blue);
				float r1,g1,b1;

				r1=float(red)/255;
				g1=float(green)/255;
				b1=float(blue)/255;
		
				
				r1+=r2*a*r1*S;
				g1+=r2*a*g1*S;
				b1+=r2*a*b1*S;
				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);

			}
		}
	}

jesli ktos wie w którym miejscu jest błąd to proszę o poprawke

wilkwielki
  • Rejestracja:ponad rok
  • Ostatnio:około 16 godzin
  • Postów:430
0

dodałem poprawke i idzała tylko tekstury nie są filtrowane to tak nie widac tak za bardzo tego bump mappingu ale na podglądzie wiidać , o to wersja działająca

Kopiuj
void RendererLightBM(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;

				unsigned char leftred,leftgreen,leftblue;
				unsigned char rightred,rightgreen,rightblue;
				unsigned char upred,upgreen,upblue;
				unsigned char downred,downgreen,downblue;
				float left,right,up,down;
				float poziom,pion;
				GetPixel(px-1,py,leftred,leftgreen,leftblue);
				GetPixel(px+1,py,rightred,rightgreen,rightblue);
				GetPixel(px,py-1,upred,upgreen,upblue);
				GetPixel(px,py+1,downred,downgreen,downblue);

				left=float(float(leftred)/255+float(leftgreen)/255+float(leftblue)/255)/3;
				right=float(float(rightred)/255+float(rightgreen)/255+float(rightblue)/255)/3;
				up=float(float(upred)/255+float(upgreen)/255+float(upblue)/255)/3;
				down=float(float(downred)/255+float(downgreen)/255+float(downblue)/255)/3;

				poziom=(left+right)/2;
				pion=(up+down)/2;
				float lenght=sqrt(poziom*poziom+pion*pion);
				poziom=poziom/lenght;
				pion=pion/lenght;
				float lightDirX,lightDirY;
				lightDirX=x+r;
				lightDirY=y+r;
				lightDirX=lightDirX-px;
				lightDirY=lightDirY-py;
				lenght=sqrt(lightDirX*lightDirX+lightDirY*lightDirY);
				lightDirX=lightDirX/lenght;
				lightDirY=lightDirY/lenght;
				float S=lightDirX*poziom+lightDirY*pion;
				if(S<0)
					S=0;
				if(S>1)
					S=1;
				GetPixel(px,py,red,green,blue);
				float r1,g1,b1;

				r1=float(red)/255;
				g1=float(green)/255;
				b1=float(blue)/255;
		
				
				//r1+=r2*a*r1+(S);
				//g1+=r2*a*g1+(S);
				//b1+=r2*a*b1+(S);
				r1+=S*r2*r1*a;
				g1+=S*r2*g1*a;
				b1+=S*r2*b1*a;

				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);

			}
		}
	}

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.