DOTY

DirectX11. 6) Light 본문

DirectX

DirectX11. 6) Light

증식세포 2023. 6. 14. 15:53
728x90
반응형

Light는 이전의 Texture에서 Light가 추가되었고 이번 코드에서는 오브젝트의 회전을 추가되었다.

 

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 LightBufferType
    {
        XMFLOAT4 diffuseColor;
        XMFLOAT3 lightDirection;
        float padding;  // Added extra padding so structure is a multiple of 16 for CreateBuffer function requirements.
    };

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

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

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

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

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

#endif

TextureShaderClass대신 LightShaderClass로 바뀌고 추가된 Light에 대한 내용만 기록

 

1-1. Light.vs

cbuffer MatrixBuffer
{
    matrix worldMatrix;
    matrix viewMatrix;
    matrix projectionMatrix;
};

struct VertexInputType
{
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
};

struct PixelInputType
{
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
};

PixelInputType LightVertexShader(VertexInputType input)
{
    PixelInputType output;
    

    // Change the position vector to be 4 units for proper matrix calculations.
    input.position.w = 1.0f;

    // Calculate the position of the vertex against the world, view, and projection matrices.
    output.position = mul(input.position, worldMatrix);
    output.position = mul(output.position, viewMatrix);
    output.position = mul(output.position, projectionMatrix);
    
    // Store the texture coordinates for the pixel shader.
    output.tex = input.tex;

    // Calculate the normal vector against the world matrix only.
    output.normal = mul(input.normal, (float3x3)worldMatrix);
	
    // Normalize the normal vector.
    output.normal = normalize(output.normal);

    return output;
}

TextureVertexShader에서 normal Vector가 추가되었다. "법선 벡터"라고 하며 3D 모델 표면의 경사나 방향 등을 나타내는데 사용된다. 정규화된 법선 벡터는 빛의 방향과 각도, 개체 표면 등을 계산할 수 있게 도와준다.

output.normal = mul(input.normal, (float3x3)worldMatrix); 를 통해 객체의 법선 벡터를 월드 좌표계에서 표현할 수 있도록 하기 위해 둘을 곱한 다음에 정규화를 한 후에 사용된다.

 

1-2. Light.ps

Texture2D shaderTexture : register(t0);
SamplerState SampleType : register(s0);

cbuffer LightBuffer
{
    float4 diffuseColor;
    float3 lightDirection;
    float padding;
};

struct PixelInputType
{
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
};

float4 LightPixelShader(PixelInputType input) : SV_TARGET
{
    float4 textureColor;
    float3 lightDir;
    float lightIntensity;
    float4 color;


    // Sample the pixel color from the texture using the sampler at this texture coordinate location.
    textureColor = shaderTexture.Sample(SampleType, input.tex);

    // Invert the light direction for calculations.
    lightDir = -lightDirection;

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

    // Determine the final amount of diffuse color based on the diffuse color combined with the light intensity.
    color = saturate(diffuseColor * lightIntensity);

    // Multiply the texture pixel and the final diffuse color to get the final pixel color result.
    // Comment out if no textures are used.
    color = color * textureColor;

    return color;
}

광도의 값이 결정되는데 객체의 법선 벡터와 광방향 벡터 사이의 내적값으로 계산된다. 빛의 확산 값이 텍스쳐 픽셀 값과 결합되어 색상 결과를 생성한다. Texture도 같이 적용된 색을 저장하고 Texture를 적용하고 싶지 않은 경우 마지막줄을 주석처리하면 된다.

 

1-3. 추가점

  1. polygonLayout추가 (InitializeShader) - 기존 두가지(Position, Texture)에서 Normal이 추가되었다.
  2. LightBufferDesc (InitializeShader) - 픽셀 셰이더에 전달되는 빛 관련 상수 버퍼의 속성을 설정하는데 사용
  3. 빛 관련 dataPtr2 추가 (SetShaderParameters) - diffuseColor, lightDirection, padding을 정한다.

2. LightClass.h

#pragma once
#ifndef _LIGHTCLASS_H_
#define _LIGHTCLASS_H_

#include <directxmath.h>
using namespace DirectX;

class LightClass
{
public:
    LightClass();
    LightClass(const LightClass&);
    ~LightClass();

    void SetDiffuseColor(float, float, float, float);
    void SetDirection(float, float, float);

    XMFLOAT4 GetDiffuseColor();
    XMFLOAT3 GetDirection();

private:
    XMFLOAT4 m_diffuseColor;
    XMFLOAT3 m_direction;
};

#endif

 

2-1. SetDiffuseColor / GetDiffuseColor

빛에 대한 정보를 얻거나 빛의 색깔을 정하는 함수다. XMFLOAT4 타입.

 

2-2. SetDirection / GetDirection

빛의 벡터를 정하거나 얻는 함수. 빛의 방향을 알 수 있다. XMFLOAT3 타입.

728x90
반응형

'DirectX' 카테고리의 다른 글

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