728x90
반응형
https://tithingbygame.tistory.com/138
[실습저장소] Multi Light + Fog Effect
tithingbygame.tistory.com
1. Multi Light
Multi Light는 생각보다 간단합니다.
그냥 데이터를 2개 보내주고, Shader에서 for문으로 2번 그려주면 됩니다.
데이터 보내는 코드
// 첫 번째 조명 정보 설정
lights[0].lightPos = lightPosition;
lights[0].padding = 0.0f; // 패딩은 사용하지 않지만 정렬을 위해 필요
lights[0].lightColor = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f); // 빨간 조명
// 두 번째 조명 정보 설정
lights[1].lightPos = lightPosition + vec3(-1.0f, 0.0f, -1.0f);
lights[1].padding = 0.0f; // 패딩은 사용하지 않지만 정렬을 위해 필요
lights[1].lightColor = glm::vec4(0.0f, 0.0f, 1.0f, 1.0f); // 파란 조명
GLint lightPosLoc = glGetUniformLocation(shaderProgram.ID, "lights[0].lightPos");
GLint lightColorLoc = glGetUniformLocation(shaderProgram.ID, "lights[0].lightColor");
// 첫 번째 조명 데이터
glUniform3fv(lightPosLoc, 1, glm::value_ptr(lights[0].lightPos));
glUniform4fv(lightColorLoc, 1, glm::value_ptr(lights[0].lightColor));
// 두 번째 조명 데이터
lightPosLoc = glGetUniformLocation(shaderProgram.ID, "lights[1].lightPos");
lightColorLoc = glGetUniformLocation(shaderProgram.ID, "lights[1].lightColor");
glUniform3fv(lightPosLoc, 1, glm::value_ptr(lights[1].lightPos));
glUniform4fv(lightColorLoc, 1, glm::value_ptr(lights[1].lightColor));
FogInfo fogInfo;
fogInfo.maxDist = 3.0f;
fogInfo.minDist = 1.0f;
fogInfo.color = vec3(1,1,1);
fogInfo.padding = vec3(0, 0, 0);
GLuint fogMaxDist = glGetUniformLocation(shaderProgram.ID,"Fog.maxDist");
GLuint fogMinDist = glGetUniformLocation(shaderProgram.ID,"Fog.minDist");
GLuint fogPaddingDist = glGetUniformLocation(shaderProgram.ID,"Fog.padding");
GLuint fogColorDist = glGetUniformLocation(shaderProgram.ID,"Fog.color");
glUniform1f(fogMaxDist, fogInfo.maxDist);
glUniform1f(fogMinDist, fogInfo.minDist);
glUniform3fv(fogPaddingDist, 1, glm::value_ptr(fogInfo.padding));
glUniform3fv(fogColorDist, 1, glm::value_ptr(fogInfo.color));
그리는 코드
fragment Shader
vec4 spotLight()
{
vec4 Color = vec4(0.0f, 0.0f, 0.0f, 0.0f);
for(int i = 0; i < 2; i++)
{
//ambient
float ambient = 0.2f;
//diffuse
float outerCone = 0.90f;
float innerCone = 0.95f;
vec3 n_normal = normalize(normal);
vec3 lightDir = normalize(lights[i].lightPos - curPos);
float diffuse = max( dot( lightDir, n_normal) , 0.0f);
//specular
float specularLight = 0.5f;
vec3 viewDir = normalize(camPos - curPos);
vec3 reflectDir = reflect(-lightDir, n_normal);
float specularPow = pow(max(dot(viewDir, reflectDir), 0.0f), 16);
float specular = specularLight * specularPow;
float angle = dot(vec3(0.0f, -1.0f, 0.0f), -lightDir);
float inten = clamp((angle - outerCone) / (innerCone - outerCone), 0.0f, 1.0f);
//return texture(tex0, texCord) * lights[i].lightColor * (diffuse + ambient + specular);
//return texture(tex0, texCord) * ( ambient + diffuse *inten + specular * inten) * lights[i].lightColor;
Color += (ambient + diffuse *inten + specular * inten) * lights[i].lightColor;
}
return Color;
}
2. Fog Effect
기본적인 Fog 효과는 아래의 공식을 사용하면 됩니다.
dmax는 안개효과의 최대치가 적용되는 (물체가 안보이는) 거리,
dmin은 안개효과가 적용되지 않는(물체가 온전히 보이는) 거리,
z는 물체와 카메라의 거리입니다.
float dist = length(camPos - curPos);
float fogFactor = (Fog.maxDist - dist) / (Fog.maxDist - Fog.minDist);
fogFactor = clamp(fogFactor, 0.0f, 1.0f);
vec4 shadeColor = spotLight();
vec3 color = mix( Fog.color, shadeColor.xyz, fogFactor );
FragColor = vec4(color, fogFactor);
지수함수를 사용하면 더 사실적으로 나타낼 수 있다고 합니다. 거의 차이는 없지만 밀도가 느껴지기는 합니다.
float density = 0.5f;
float dist = length(camPos - curPos);
float fogFactor = exp(-pow(density * dist,2));
vec4 shadeColor = spotLight();
vec3 finalColor = mix(Fog.color, shadeColor.xyz, fogFactor);
FragColor = vec4(finalColor, 1.0f);
728x90
반응형
'ComputerGraphics' 카테고리의 다른 글
[CG] Ray Tracing (Ray Tracing in One Weekend) (0) | 2025.01.17 |
---|---|
[CG] FrameBuffer 사용해서 postProcessing(후처리) (0) | 2025.01.15 |
[CG] Shadow Map using Depth Map (0) | 2024.12.08 |
[CG] Depth Map(fog를 곁들인..) (0) | 2024.12.07 |
[CG] Texturing (0) | 2024.12.04 |