DOTY

DirectX11. 8) Ambient Light, Specular Lighting 본문

DirectX

DirectX11. 8) Ambient Light, Specular Lighting

증식세포 2023. 6. 19. 11:59
728x90
반응형

주변광과 반사광을 구현.

주변광의 경우 표면을 직접 쬐지 않지만 반사되는 빛으로 인해 밝아지므로 이를 표현.

반사광의 경우 더욱 3D효과를 내기 위해서 구현

(코드가 크게 추가되는 것은 없었지만 벡터의 계산을 이해하는데 어려웠다.)

 

1. LightShaderClass.h

#pragma once
#ifndef _LIGHTSHADERCLASS_H_
#define _LIGHTSHADERCLASS_H_

#include <d3d11.h>
#include <d3dcompiler.h>
#include <directxmath.h>
#include <fstream>
using namespace DirectX;
using namespace std;

class LightShaderClass
{
private:
    struct MatrixBufferType
    {
        XMMATRIX world;
        XMMATRIX view;
        XMMATRIX projection;
    };

    struct CameraBufferType
    {
        XMFLOAT3 cameraPosition;
        float padding;
    };

    struct LightBufferType
    {
        XMFLOAT4 ambientColor;
        XMFLOAT4 diffuseColor;
        XMFLOAT3 lightDirection;
        float specularPower;
        XMFLOAT4 specularColor;
    };

public:
    LightShaderClass();
    LightShaderClass(const LightShaderClass&);
    ~LightShaderClass();

    bool Initialize(ID3D11Device*, HWND);
    void Shutdown();
    bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4, XMFLOAT4, XMFLOAT3, XMFLOAT4, float);

private:
    bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*);
    void ShutdownShader();
    void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);

    bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, XMFLOAT3, XMFLOAT4, XMFLOAT4, XMFLOAT3, XMFLOAT4, float);
    void RenderShader(ID3D11DeviceContext*, int);

private:
    ID3D11VertexShader* m_vertexShader;
    ID3D11PixelShader* m_pixelShader;
    ID3D11InputLayout* m_layout;
    ID3D11SamplerState* m_sampleState;
    ID3D11Buffer* m_matrixBuffer;
    ID3D11Buffer* m_lightBuffer;
    ID3D11Buffer* m_cameraBuffer;
};

#endif

주변광과 반사광을 위한 변수를 추가.

CameraBuffer를 추가한 이유는 반사광을 계산하는데 사용된다.

 

1-1. Light.vs

뷰어벡터(카메라가 보는 방향)은 정점 셰이더에서 계산된다. 정점의 World위치를 계산한 다음 카메라의 위치를 빼는 형식으로 계산된다. 픽셀 셰이더로 전달하기 전에 정규화를 거친 후 전달된다.

    // Calculate the position of the vertex in the world.
    worldPosition = mul(input.position, worldMatrix);

    // Determine the viewing direction based on the position of the camera and the position of the vertex in the world.
    output.viewDirection = cameraPosition.xyz - worldPosition.xyz;
	
    // Normalize the viewing direction vector.
    output.viewDirection = normalize(output.viewDirection);

 

1-2. Light.ps

주변광과 반사광을 위한 변수가 추가된다. 우선 주변광의 출력 색상은 주변의 색상에 의해 결정된다.

표면의 법선 벡터와 빛의 방향 벡터를 활용하여 빛의 세기를 결정하는데 이들의 내적은 방향이 얼마나 일치하는지를 알 수 있다. 직각인 경우 빛이 더 강해지고 직각에서 멀어질수록 약해진다. 적용하는 것은 0보다 큰 경우만 해당되는데 0보다 작을 경우 반대의 결과가 나올 수 있기 때문이다.

0보다 큰 경우 반사광에 대해서도 적용을 시키는데 specular Power의 거듭제곱 꼴로 계산된다. specular Power가 작을수록 최종 효과가 커진다. 

// Calculate the amount of light on this pixel.
lightIntensity = saturate(dot(input.normal, lightDir));

if(lightIntensity > 0.0f)
{
    // Determine the final diffuse color based on the diffuse color and the amount of light intensity.
    color += (diffuseColor * lightIntensity);

    // Saturate the ambient and diffuse color.
    color = saturate(color);

    // Calculate the reflection vector based on the light intensity, normal vector, and light direction.
    reflection = normalize(2.0f * lightIntensity * input.normal - lightDir);

    // Determine the amount of specular light based on the reflection vector, viewing direction, and specular power.
    specular = pow(saturate(dot(reflection, input.viewDirection)), specularPower);
}

 

1-3. SetShaderParameters

CameraBuffer를 추가했기 때문에 카메라 버퍼를 잠그고 그 안에 카메라 위치 값을 추가하는 과정을 거치고 이를 buffNumber 1번에 저장한다. 이제 버퍼는 MatrixBuffer과 CameraBuffer 두가지가 생기게 된다.

   

   

728x90
반응형

'DirectX' 카테고리의 다른 글

DirectX11. 7) 3D Model Rendering  (0) 2023.06.16
DirectX11. check 1) Back-Face culling  (0) 2023.06.14
DirectX11. 6) Light  (0) 2023.06.14
DirectX11. 5) Texture  (0) 2023.06.13
DirectX11. 4) Buffer, Shader II  (0) 2023.06.12
Comments