私はディファード シェーディング プログラムに取り組んでおり、シーンに 50 の異なるライトを設定する必要があります。そのために、次のコードを使用して属性 (位置、拡散色、反射色) をランダムに生成しています。
void FBORender::BuildLights()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dis(0.0, 0.1);
for (int i = 0; i < NUM_LIGHTS; i++)
{
float dc_r = (float) dis(gen);
float dc_g = (float) dis(gen);
float dc_b = (float) dis(gen);
printf("%f\n", dc_r);
float lp_x = (float)(rand() % 40 - 20);
float lp_y = (float)(rand() % 100 + 10);
float lp_z = (float)(rand() % 40 - 20);
DC[i * NUM_LIGHTS] = dc_r;
DC[i * NUM_LIGHTS + 1] = dc_g;
DC[i * NUM_LIGHTS + 2] = dc_b;
LP[i * NUM_LIGHTS] = lp_x;
LP[i * NUM_LIGHTS + 1] = lp_y;
LP[i * NUM_LIGHTS + 2] = lp_z;
}
}
ただし、複数のライトでライティングを実行する方法がよくわかりません。アンビエント ライトはディフューズ ライトと等しくなければならず、スペキュラー ライトは白であるべきだと言われました。
Phong Ilumination を実行するために必要だったシェーダーを適応させると、次のようになります。
#version 410 core
#define numLights 5
uniform sampler2D tDiffuse;
uniform sampler2D tPosition;
uniform sampler2D tNormals;
uniform vec4 specularColor;
uniform vec3 diffuseColor[numLights];
uniform vec3 vLightPosition[numLights];
in vec2 texCoord;
out vec4 fragColor;
void main( void )
{
vec3 tex = texture( tDiffuse, texCoord.st ).xyz;
vec3 vPosition = texture( tPosition, texCoord.st ).xyz;
vec3 vNormal = normalize( texture( tNormals, texCoord.st ).xyz * 2 - 1 );
vec3 vVaryingNormal = vNormal;
for (int i = 0; i < numLights; i++)
{
vec3 vVaryingLightDir = normalize( vLightPosition[i] - vPosition );
float diff = max( 0.0, dot( normalize( vVaryingNormal ), normalize( vVaryingLightDir ) ) );
vec4 partialColor = diff * vec4(diffuseColor[i], 1.0);
partialColor = vec4( mix( partialColor.rgb, tex, 0.5 ), partialColor.a );
partialColor += vec4( diffuseColor[i], 1.0 );
vec3 vReflection = normalize( reflect( -normalize( vVaryingLightDir ), normalize( vVaryingNormal )));
float spec = max( 0.0, dot( normalize( vVaryingNormal ), vReflection ));
if( diff != 0 )
{
float fSpec = pow( spec, 128.0 );
partialColor.rgb += vec3( fSpec, fSpec, fSpec );
}
fragColor += partialColor;
}
}
ただし、次の図に示すように、(間違っていない場合でも) 醜い結果が得られます。
この結果は 2 つのライトのみを使用しています。50を使わないといけないので、真っ白な画面ばかりだと思いますが…