Beispiel #1
0
void SpotLight::rectangleAlignedAt( float z,
                                   Vector3f* bottomLeft, Vector3f* bottomRight,
                                   Vector3f* topRight, Vector3f* topLeft ) const
{
    float top = z * tanf( 0.5f * m_fovYRadians );
    float bottom = -top;
    float right = m_aspect * top;
    float left = -right;

    Vector3f worldRight = this->right();

    *topLeft = m_position + top * m_up + left * worldRight + z * lightDirection();
    *bottomLeft = m_position + bottom * m_up + left * worldRight + z * lightDirection();
    *bottomRight = m_position + bottom * m_up + right * worldRight + z * lightDirection();
    *topRight = m_position + top * m_up + right * worldRight + z * lightDirection();
}
Beispiel #2
0
	void iSkySimulation::update()
	{
		iaMatrixf rotate;
		iaVector3f lightDirection(0, 1, 0);

		rotate.rotate(latitude / 90.0f * 0.5f * M_PI, iaAxis::X);
		rotate.rotate((time / 24.0f - 0.5f) * 2.0f * M_PI, iaAxis::Z);
		lightDirection = rotate * lightDirection;

		skyLightNode->setLightDirection(lightDirection);

		iaVector3f up(0,1,0);
		float32 elevation = up * lightDirection;

		iaColor3f color;
		color.lerp(iaColor3f(1,1,1), iaColor3f(0.95,0.5,0), elevation);
		directionalLightNode->setColor(color);
		directionalLightNode->setDirection(lightDirection);
	
		float32 alpha = -elevation + 0.1f * 0.2f; //! \todo
		if(alpha < 0.0f) alpha = 0.0f;
		if(alpha > 1.0f) alpha = 1.0f;
		skyBoxNode->setAlpha(alpha);

		skyBoxNode->setMatrix(rotate);
	}
//聚光灯(边缘软化)
void LightCasterStudy::render()
{
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	double currentTime = glfwGetTime();

	spotLightShader->UseProgram();

	vec3 lightPos(3.0f, 0.0f, 0.0f);
	vec3 viewPosition(0.0f, 0.0f, 5.0f);
	vec3 lightDirection(0.0f, 0.0f, -1.0f);
	auto tempValue = dot(normalize(viewPosition - vec3(1.0f, 0.0f, 0.0f)), normalize(-lightDirection));
	//glm::cos 中的参数为弧度,非角度(有点坑),需要用radians进行角度转换。
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, this->cubeDiffuseTexture);
	glUniform1i(glGetUniformLocation(spotLightShader->getProgram(), "material.diffuse"), 0);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, this->cubeSpecularTexture);
	glUniform1i(glGetUniformLocation(spotLightShader->getProgram(), "material.specular"), 1);
	glUniform1f(glGetUniformLocation(spotLightShader->getProgram(), "material.shininess"), 0.6f * 128.0f);
	glUniform3fv(glGetUniformLocation(spotLightShader->getProgram(), "light.direction"), 1, value_ptr(lightDirection));
	glUniform1f(glGetUniformLocation(spotLightShader->getProgram(), "light.cutOff"), glm::cos(glm::radians(12.5f)));
	glUniform3f(glGetUniformLocation(spotLightShader->getProgram(), "light.ambient"), 0.1f, 0.1f, 0.1f);
	glUniform3f(glGetUniformLocation(spotLightShader->getProgram(), "light.specular"), 1.0f, 1.0f, 1.0f);
	glUniform3f(glGetUniformLocation(spotLightShader->getProgram(), "light.diffuse"), 1.0f, 1.0f, 1.0f);
	glUniform3fv(glGetUniformLocation(spotLightShader->getProgram(), "light.position"), 1, value_ptr(viewPosition));
	glUniform1f(glGetUniformLocation(spotLightShader->getProgram(), "light.outerCutOff"), glm::cos(glm::radians(17.0f)));
	glUniform1f(glGetUniformLocation(spotLightShader->getProgram(), "light.constant"), 1.0f);
	glUniform1f(glGetUniformLocation(spotLightShader->getProgram(), "light.linear"), 0.09f);
	glUniform1f(glGetUniformLocation(spotLightShader->getProgram(), "light.quadratic"), 0.032f);
	glUniform3f(glGetUniformLocation(spotLightShader->getProgram(), "lightcolor"), 1.0f, 1.0f, 1.0f);
	glUniform3fv(glGetUniformLocation(spotLightShader->getProgram(), "viewPos"), 1, value_ptr(viewPosition));

	mat4 model(1.0);
	mat4 view(1.0);
	mat4 projection(1.0);
	RenderDelegate::getInstance()->printProgramInfoLog(spotLightShader->getProgram());
	view = lookAt(viewPosition, vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f));
	projection = perspective(radians(45.0f), 800.0f / 600.0f, 0.1f, 1000.0f);

	glUniformMatrix4fv(glGetUniformLocation(cubeShader->getProgram(), "view"), 1, GL_FALSE, value_ptr(view));
	glUniformMatrix4fv(glGetUniformLocation(cubeShader->getProgram(), "projection"), 1, GL_FALSE, value_ptr(projection));

	glBindVertexArray(this->cubeVAO);

	for(GLuint i = 0; i < 10; i++)
	{
		model = glm::translate(mat4(1.0f), cubePositions[i]);
		GLfloat angle = (i + 1) * currentTime * 5.0f;
		model = glm::rotate(model, radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
		glUniformMatrix4fv(glGetUniformLocation(cubeShader->getProgram(), "model"), 1, GL_FALSE, glm::value_ptr(model));
		glDrawArrays(GL_TRIANGLES, 0, 36);
	}
	glBindVertexArray(0);
	
}
Beispiel #4
0
void RenderShadow()
{
    Device->SetRenderState(D3DRS_STENCILENABLE,    true);
    Device->SetRenderState(D3DRS_STENCILFUNC,      D3DCMP_EQUAL);
    Device->SetRenderState(D3DRS_STENCILREF,       0x0);
    Device->SetRenderState(D3DRS_STENCILMASK,      0xffffffff);
    Device->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff);
    Device->SetRenderState(D3DRS_STENCILZFAIL,     D3DSTENCILOP_KEEP);
    Device->SetRenderState(D3DRS_STENCILFAIL,      D3DSTENCILOP_KEEP);
    Device->SetRenderState(D3DRS_STENCILPASS,      D3DSTENCILOP_INCR); // increment to 1

    // position shadow
    D3DXVECTOR4 lightDirection(0.707f, -0.707f, 0.707f, 0.0f);
    D3DXPLANE groundPlane(0.0f, -1.0f, 0.0f, 0.0f);

    D3DXMATRIX S;
    D3DXMatrixShadow(
        &S,
        &lightDirection,
        &groundPlane);

    D3DXMATRIX T;
    D3DXMatrixTranslation(
        &T,
        TeapotPosition.x,
        TeapotPosition.y,
        TeapotPosition.z);

    D3DXMATRIX W = T * S;
    Device->SetTransform(D3DTS_WORLD, &W);

    // alpha blend the shadow
    Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
    Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

    D3DMATERIAL9 mtrl = d3d::InitMtrl(d3d::BLACK, d3d::BLACK, d3d::BLACK, d3d::BLACK, 0.0f);
    mtrl.Diffuse.a = 0.5f; // 50% transparency.

    // Disable depth buffer so that z-fighting doesn't occur when we
    // render the shadow on top of the floor.
    Device->SetRenderState(D3DRS_ZENABLE, false);

    Device->SetMaterial(&mtrl);
    Device->SetTexture(0, 0);
    Teapot->DrawSubset(0);

    Device->SetRenderState(D3DRS_ZENABLE, true);
    Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
    Device->SetRenderState(D3DRS_STENCILENABLE,    false);
}
Beispiel #5
0
void DirectionalLight::apply( glm::mat4 view )
{
	DirectionalLightParam lightParam;
	
	glm::vec3 lightDirection( -1.0f, -1.0f, -1.0f );
	lightDirection = glm::normalize( lightDirection );
	lightParam.Direction.vec = glm::mat3( view ) * lightDirection;
	lightParam.LightIntensity.vec = glm::vec3( 0.2f, 0.2f, 0.2f );

	mUniformBlock_DirectionalLight.writeData( &lightParam );
	mUniformBlock_DirectionalLight.updateBuffer();

	mUniformBlock_DirectionalLight.bindToBufferTarget( ShaderEffectStandard::UB_BIND_DIRECTIONAL_LIGHT );
}
    void displayOcean() {

        oceanTexture->bind(0);
        shaderProgram->bind();

        math::matrix3x1<float> size(10.0f, 1.0, 10.0f);

        math::matrix4x1<float> materialAmbient(0.1f, 0.1f, 0.1f, 1.0f);
        math::matrix4x1<float> materialDiffuse(1.0f, 1.0f, 1.0f, 1.0f);
        math::matrix3x1<float> lightDirection(0, 1.0f, 0.0f);

        shaderProgram->setUniform(shaderProgram->getUniformLocation("Size"), size);

        math::TransformStack<float> transformWorld;

        size = math::matrix3x1<float>(10.0f, 1.0, 10.0f);

        const int N = 8;

        transformWorld.translate(-size.x * N * 0.5f, -0.5f, -size.z * N * 0.5f);

        for (int row = 0; row < N; row++) {
            for (int col = 0; col < N; col++) {
                transformWorld.push();
                transformWorld.translate(col * size.x, 0, row * size.z);

                math::matrix4x4<float> world = transformWorld.get();
                math::matrix3x3<float> normal = world.slice3x3(0, 0);
                math::matrix4x4<float> modelViewProj =  camera.transform() * world;
                math::matrix4x4<float> modelView = camera.view() * world;

                shaderProgram->setUniform(shaderProgram->getUniformLocation("T_ModelViewProj"), modelViewProj.transpose());
                shaderProgram->setUniform(shaderProgram->getUniformLocation("T_Normal"), normal.transpose());
                shaderProgram->setUniform(shaderProgram->getUniformLocation("T_ModelView"), modelView.transpose());

                heightMapTile->render();

                transformWorld.pop();
            }
        }
    }
//
// Framework Functions
//
bool Setup()
{
    //
    // Create the terrain.
    //

    D3DXVECTOR3 lightDirection(0.0f, 1.0f, 0.0f);
    TheTerrain = new Terrain(Device, "castlehm257.raw", 257, 257, 1, 0.2f);
    TheTerrain->genTexture(&lightDirection);

    //
    // Create the font.
    //

    FPS = new FPSCounter(Device);

    //
    // Set texture filters.
    //

    Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

    //
    // Set projection matrix.
    //

    D3DXMATRIX proj;
    D3DXMatrixPerspectiveFovLH(
        &proj,
        D3DX_PI * 0.25f, // 45 - degree
        (float)Width / (float)Height,
        1.0f,
        1000.0f);
    Device->SetTransform(D3DTS_PROJECTION, &proj);

    return true;
}
	void DeferredDirectionalLighting::bind(const DirectionalLight& light, const Matrix4f& modelView)
	{
		_program.bind();
		
		//tell the shader about uniforms
		GLint program = _program.getProgram();


		Vector3f lightDir = light.getDirection();

		//light in view space
		Vector4f lightDirection(lightDir.x(),
								lightDir.y(),
								lightDir.z(),
								0);
		Vector4f lightDirectionView = (modelView) * lightDirection;
		lightDirectionView.normalize();
		glUniform3f(glGetUniformLocation(program, "lightdir"),
					lightDirectionView.x(),
					lightDirectionView.y(),
					lightDirectionView.z());
	}
Beispiel #9
0
//
// Framework functions
//
bool Setup()
{
	HRESULT hr = 0;

	//
	// Init Scene. 
	//

	D3DXVECTOR3 lightDirection(0.0f, 1.0f, 0.0f);
	TheTerrain = new Terrain(Device, "coastMountain64.raw", 64, 64, 6, 0.5f);
	TheTerrain->genTexture(&lightDirection);

	//
	// Set texture filters.
	//

	Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
	Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
	Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

	//
	// Set Camera Position.
	//

	D3DXVECTOR3 pos(100.0f, 100.0f, -250.0f);
	TheCamera.setPosition(&pos);

	//
	// Create effect.
	//

	ID3DXBuffer* errorBuffer = 0;
	hr = D3DXCreateEffectFromFile(
		Device,
		"fog.txt",
		0,                // no preprocessor definitions
		0,                // no ID3DXInclude interface
		D3DXSHADER_DEBUG, // compile flags
		0,                // don't share parameters
		&FogEffect,
		&errorBuffer);

	// output any error messages
	if( errorBuffer )
	{
		::MessageBox(0, (char*)errorBuffer->GetBufferPointer(), 0, 0);
		d3d::Release<ID3DXBuffer*>(errorBuffer);
	}

	if(FAILED(hr))
	{
		::MessageBox(0, "D3DXCreateEffectFromFile() - FAILED", 0, 0);
		return false;
	}

	// 
	// Save Frequently Accessed Parameter Handles
	//

	FogTechHandle = FogEffect->GetTechniqueByName("Fog");
	
	//
	// Set Projection.
	//
	D3DXMATRIX P;

	D3DXMatrixPerspectiveFovLH(
		&P,	D3DX_PI * 0.25f, // 45 - degree
		(float)Width / (float)Height,
		1.0f, 1000.0f);

	Device->SetTransform(D3DTS_PROJECTION, &P);

	return true;
}
Beispiel #10
0
Vector3f SpotLight::right() const
{
    return Vector3f::cross( lightDirection(), m_up );
}
Beispiel #11
0
void SpotLight::setUpWithRight( const Vector3f& right )
{
    m_up = Vector3f::cross( right, lightDirection() );
}
Beispiel #12
0
bool Setup()
{
		D3DXVECTOR3 lightDirection(0.0f, 1.0f, 0.0f);

	TheTerrain = new Terrain(Device, "Faces.raw", 734,1024,20,1.0f);
	TheTerrain->genTexture(&lightDirection);
	TheTerrain->loadTexture("Faces.jpg");

	
		D3DXCreateFont(Device, 20, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), &m_font );
	//
	// Lights.
	//
	Barrels.init(Device, "barells/barrels.x");
	Dalek.init(Device, "dalek/dalek.x");
	tank.init(Device, "Oiltank/tank.x");
	Table.init(Device, "table/table.x");
	Ton.init(Device, "ton/ton3.x");
	Tree.init(Device, "trees/palm_tree_3.x");

	numbertrees = rand() % 100 - 1;

	for(int i = 0;  i < 10; i++)
		BoolTrash[i] = true;

	D3DXCreateSprite(Device, &spriteMap);
	D3DXCreateSprite(Device, &spritePlayer);
	for(int i = 0; i < 10; i++)
	{
		D3DXCreateSprite(Device, &spriteTrash[i]);
	}
	
	D3DXCreateTextureFromFile(Device, "Map.png", &texMap);
	srand(GetTickCount());

	TrashPositions[0].x = rand() % 360 - 180;
	TrashPositions[0].z = rand() % 360 - 180;
	float height = TheTerrain->getHeight(TrashPositions[0].x, TrashPositions[0].z);
	TrashPositions[0].y = height;

	TrashPositions[1].x = rand() % 360 - 180;
	TrashPositions[1].z = rand() % 360 - 180;
	height = TheTerrain->getHeight(TrashPositions[1].x, TrashPositions[1].z);
	TrashPositions[1].y = height;

	TrashPositions[2].x = rand() % 360 - 180;
	TrashPositions[2].z = rand() % 360 - 180;
	height = TheTerrain->getHeight(TrashPositions[2].x, TrashPositions[2].z);
	TrashPositions[2].y = height;

	TrashPositions[3].x = rand() % 360 - 180;
	TrashPositions[3].z = rand() % 360 - 180;
	height = TheTerrain->getHeight(TrashPositions[3].x, TrashPositions[3].z);
	TrashPositions[3].y = height;

	TrashPositions[4].x = rand() % 360 - 180;
	TrashPositions[4].z = rand() % 360 - 180;
	height = TheTerrain->getHeight(TrashPositions[4].x, TrashPositions[4].z);
	TrashPositions[4].y = height;

	TrashPositions[5].x = rand() % 360 - 180;
	TrashPositions[5].z = rand() % 360 - 180;
	height = TheTerrain->getHeight(TrashPositions[5].x, TrashPositions[5].z);
	TrashPositions[5].y = height;

	TrashPositions[6].x = rand() % 360 - 180;
	TrashPositions[6].z = rand() % 360 - 180;
	height = TheTerrain->getHeight(TrashPositions[6].x, TrashPositions[6].z);
	TrashPositions[6].y = height;

	TrashPositions[7].x = rand() % 360 - 180;
	TrashPositions[7].z = rand() % 360 - 180;
	height = TheTerrain->getHeight(TrashPositions[7].x, TrashPositions[7].z);
	TrashPositions[7].y = height;

	TrashPositions[8].x = rand() % 360 - 180;
	TrashPositions[8].z = rand() % 360 - 180;
	height = TheTerrain->getHeight(TrashPositions[8].x, TrashPositions[8].z);
	TrashPositions[8].y = height;

	TrashPositions[9].x = rand() % 360 - 180;
	TrashPositions[9].z = rand() % 360 - 180;
	height = TheTerrain->getHeight(TrashPositions[9].x, TrashPositions[9].z);
	TrashPositions[9].y = height;

	for(int i = 0; i < numbertrees; i++)
	{
		TreePositions[i].x = rand() % 360 - 180;
		TreePositions[i].z = rand() % 360 - 180;
		height = TheTerrain->getHeight(TreePositions[i].x, TreePositions[i].z);
		TreePositions[i].y = height;
	}

	D3DXVECTOR3 lightDir(0.707f, -0.707f, 0.707f);
	D3DXCOLOR color(1.0f, 1.0f, 1.0f, 1.0f);
	D3DLIGHT9 light = d3d::InitDirectionalLight(&lightDir, &color);

	Device->SetLight(0, &light);
	Device->LightEnable(0, true);

	Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
	Device->SetRenderState(D3DRS_SPECULARENABLE, true);

	//build skybox
	BuildSkybox(Device);

	//
	// Set Camera.
	//

	D3DXVECTOR3    pos(-0.0f, -197.0f, -0.0f);
	D3DXVECTOR3 target(0.0, 0.0f, 0.0f);
	D3DXVECTOR3     up(0.0f, 1.0f, 0.0f);

	D3DXMATRIX V;
	D3DXMatrixLookAtLH(&V, &pos, &target, &up);

	Device->SetTransform(D3DTS_VIEW, &V);

	D3DXVECTOR3    pos2(-0.0f, -10.0f, 0.0f);
	D3DXVECTOR3 target2(0.0, 0.0f, 0.0f);
	D3DXVECTOR3     up2(0.0f, 1.0f, 0.0f);

//	D3DXMATRIX V;
	D3DXMatrixLookAtLH(&mview, &pos2, &target2, &up2);

	//Device->SetTransform(D3DTS_VIEW, &mview);

	//
	// Set projection matrix.
	//
	D3DXMATRIX proj;
	D3DXMatrixPerspectiveFovLH(
			&proj,
			D3DX_PI / 4.0f, // 45 - degree
			(float)Width / (float)Height,
			1.0f,
			20001.0f);
	Device->SetTransform(D3DTS_PROJECTION, &proj);

	D3DXMatrixPerspectiveFovLH(&mprojection, D3DX_PI / 4.0f, (float)Width / (float)Height, 1.0f, 20001.0f);

	//Device->SetTransform(D3DTS_PROJECTION, &mprojection);

	return true;
}
Beispiel #13
0
/* static */
GlfSimpleLightingContextRefPtr
px_vp20Utils::GetLightingContextFromDrawContext(
        const MHWRender::MDrawContext& context)
{
    const GfVec4f blackColor(0.0f, 0.0f, 0.0f, 1.0f);
    const GfVec4f whiteColor(1.0f, 1.0f, 1.0f, 1.0f);

    GlfSimpleLightingContextRefPtr lightingContext =
        GlfSimpleLightingContext::New();

    MStatus status;

    unsigned int numMayaLights =
        context.numberOfActiveLights(MHWRender::MDrawContext::kFilteredToLightLimit,
                                     &status);
    if (status != MS::kSuccess || numMayaLights < 1) {
        return lightingContext;
    }

    bool viewDirectionAlongNegZ = context.viewDirectionAlongNegZ(&status);
    if (status != MS::kSuccess) {
        // If we fail to find out the view direction for some reason, assume
        // that it's along the negative Z axis (OpenGL).
        viewDirectionAlongNegZ = true;
    }

    GlfSimpleLightVector lights;

    for (unsigned int i = 0; i < numMayaLights; ++i) {
        MHWRender::MLightParameterInformation* mayaLightParamInfo =
            context.getLightParameterInformation(i);

        if (!mayaLightParamInfo) {
            continue;
        }

        // Setup some default values before we read the light parameters.
        bool lightEnabled = true;

        bool    lightHasPosition = false;
        GfVec4f lightPosition(0.0f, 0.0f, 0.0f, 1.0f);
        bool    lightHasDirection = false;
        GfVec3f lightDirection(0.0f, 0.0f, -1.0f);
        if (!viewDirectionAlongNegZ) {
            // The convention for DirectX is positive Z.
            lightDirection[2] = 1.0f;
        }

        float   lightIntensity = 1.0f;
        GfVec4f lightColor = blackColor;
        bool    lightEmitsDiffuse = true;
        bool    lightEmitsSpecular = false;
        float   lightDecayRate = 0.0f;
        float   lightDropoff = 0.0f;
        // The cone angle is 180 degrees by default.
        GfVec2f lightCosineConeAngle(-1.0f);
        float   lightShadowBias = 0.0f;
        bool    lightShadowOn = false;

        bool globalShadowOn = false;

        MStringArray paramNames;
        mayaLightParamInfo->parameterList(paramNames);

        for (unsigned int paramIndex = 0; paramIndex < paramNames.length(); ++paramIndex) {
            const MString paramName = paramNames[paramIndex];
            const MHWRender::MLightParameterInformation::ParameterType paramType =
                mayaLightParamInfo->parameterType(paramName);
            const MHWRender::MLightParameterInformation::StockParameterSemantic paramSemantic =
                mayaLightParamInfo->parameterSemantic(paramName);

            MIntArray intValues;
            MFloatArray floatValues;

            switch (paramType) {
                case MHWRender::MLightParameterInformation::kBoolean:
                case MHWRender::MLightParameterInformation::kInteger:
                    mayaLightParamInfo->getParameter(paramName, intValues);
                    break;
                case MHWRender::MLightParameterInformation::kFloat:
                case MHWRender::MLightParameterInformation::kFloat2:
                case MHWRender::MLightParameterInformation::kFloat3:
                case MHWRender::MLightParameterInformation::kFloat4:
                    mayaLightParamInfo->getParameter(paramName, floatValues);
                    break;
                default:
                    // Unsupported paramType.
                    continue;
                    break;
            }

            switch (paramSemantic) {
                case MHWRender::MLightParameterInformation::kLightEnabled:
                    _GetLightingParam(intValues, floatValues, lightEnabled);
                    break;
                case MHWRender::MLightParameterInformation::kWorldPosition:
                    if (_GetLightingParam(intValues, floatValues, lightPosition)) {
                        lightHasPosition = true;
                    }
                    break;
                case MHWRender::MLightParameterInformation::kWorldDirection:
                    if (_GetLightingParam(intValues, floatValues, lightDirection)) {
                        lightHasDirection = true;
                    }
                    break;
                case MHWRender::MLightParameterInformation::kIntensity:
                    _GetLightingParam(intValues, floatValues, lightIntensity);
                    break;
                case MHWRender::MLightParameterInformation::kColor:
                    _GetLightingParam(intValues, floatValues, lightColor);
                    break;
                case MHWRender::MLightParameterInformation::kEmitsDiffuse:
                    _GetLightingParam(intValues, floatValues, lightEmitsDiffuse);
                    break;
                case MHWRender::MLightParameterInformation::kEmitsSpecular:
                    _GetLightingParam(intValues, floatValues, lightEmitsSpecular);
                    break;
                case MHWRender::MLightParameterInformation::kDecayRate:
                    _GetLightingParam(intValues, floatValues, lightDecayRate);
                    break;
                case MHWRender::MLightParameterInformation::kDropoff:
                    _GetLightingParam(intValues, floatValues, lightDropoff);
                    break;
                case MHWRender::MLightParameterInformation::kCosConeAngle:
                    _GetLightingParam(intValues, floatValues, lightCosineConeAngle);
                    break;
                case MHWRender::MLightParameterInformation::kShadowBias:
                    _GetLightingParam(intValues, floatValues, lightShadowBias);
                    break;
                case MHWRender::MLightParameterInformation::kShadowOn:
                    _GetLightingParam(intValues, floatValues, lightShadowOn);
                    break;
                case MHWRender::MLightParameterInformation::kGlobalShadowOn:
                    _GetLightingParam(intValues, floatValues, globalShadowOn);
                    break;
                default:
                    // Unsupported paramSemantic.
                    continue;
                    break;
            }

            if (!lightEnabled) {
                // Stop reading light parameters if the light is disabled.
                break;
            }
        }

        if (!lightEnabled) {
            // Skip to the next light if this light is disabled.
            continue;
        }

        lightColor[0] *= lightIntensity;
        lightColor[1] *= lightIntensity;
        lightColor[2] *= lightIntensity;

        // Populate a GlfSimpleLight from the light information from Maya.
        GlfSimpleLight light;

        GfVec4f lightAmbient = blackColor;
        GfVec4f lightDiffuse = blackColor;
        GfVec4f lightSpecular = blackColor;

        // We receive the cone angle from Maya as a pair of floats which
        // includes the penumbra, but GlfSimpleLights don't currently support
        // that, so we only use the primary cone angle value.
        float lightCutoff = GfRadiansToDegrees(std::acos(lightCosineConeAngle[0]));
        float lightFalloff = lightDropoff;

        // decayRate is actually an enum in Maya that we receive as a float:
        // - 0.0 = no attenuation
        // - 1.0 = linear attenuation
        // - 2.0 = quadratic attenuation
        // - 3.0 = cubic attenuation (not supported by GlfSimpleLight)
        GfVec3f lightAttenuation(0.0f);
        if (lightDecayRate > 1.5) {
            // Quadratic attenuation.
            lightAttenuation[2] = 1.0f;
        } else if (lightDecayRate > 0.5f) {
            // Linear attenuation.
            lightAttenuation[1] = 1.0f;
        } else {
            // No/constant attenuation.
            lightAttenuation[0] = 1.0f;
        }

        if (lightHasDirection && !lightHasPosition) {
            // This is a directional light. Set the direction as its position.
            lightPosition[0] = -lightDirection[0];
            lightPosition[1] = -lightDirection[1];
            lightPosition[2] = -lightDirection[2];
            lightPosition[3] = 0.0f;

            // Revert direction to the default value.
            lightDirection = GfVec3f(0.0f, 0.0f, -1.0f);
            if (!viewDirectionAlongNegZ) {
                lightDirection[2] = 1.0f;
            }
        }

        if (!lightHasPosition && !lightHasDirection) {
            // This is an ambient light.
            lightAmbient = lightColor;
        } else {
            if (lightEmitsDiffuse) {
                lightDiffuse = lightColor;
            }
            if (lightEmitsSpecular) {
                // XXX: It seems that the specular color cannot be specified
                // separately from the diffuse color on Maya lights.
                lightSpecular = lightColor;
            }
        }

        light.SetAmbient(lightAmbient);
        light.SetDiffuse(lightDiffuse);
        light.SetSpecular(lightSpecular);
        light.SetPosition(lightPosition);
        light.SetSpotDirection(lightDirection);
        light.SetSpotCutoff(lightCutoff);
        light.SetSpotFalloff(lightFalloff);
        light.SetAttenuation(lightAttenuation);
        light.SetShadowBias(lightShadowBias);
        light.SetHasShadow(lightShadowOn && globalShadowOn);

        lights.push_back(light);
    }

    lightingContext->SetLights(lights);

    // XXX: These material settings match what we used to get when we read the
    // material from OpenGL. This should probably eventually be something more
    // sophisticated.
    GlfSimpleMaterial material;
    material.SetAmbient(whiteColor);
    material.SetDiffuse(whiteColor);
    material.SetSpecular(blackColor);
    material.SetEmission(blackColor);
    material.SetShininess(0.0001f);

    lightingContext->SetMaterial(material);

    lightingContext->SetSceneAmbient(blackColor);

    return lightingContext;
}