카테고리 없음

12_Normal [2/2]

컴맹학자 2021. 7. 3. 21:46
728x90

노말백터를 이용한 음영 표현 (ADSE)
Ambient : 주변 조명 인한 색 ex) 태양
Diffuse : 기본 물체의 색깔
Specular : 정반사광 (정구형태) 
Emissive : 외각선

 

Lambert 조명 (Diffuse)

기존 지형 노말벡터와 조명의 노말벡터와 내적을 해서 cos가 1에 가까우면 밝게 반대로는 어둡게


11_Terrain.fx 수정

더보기
matrix World, View, Projection;
struct VertexInput
{
    float4 Position : Position;
};
//-------------------------------------------------------
//Simple Terrain Color [원본]
//-------------------------------------------------------
struct VertexOutput
{
    float4 Position : SV_Position;
};

RasterizerState RS
{
    FillMode = WireFrame;
};

VertexOutput VS(VertexInput input)
{
    VertexOutput output;
    output.Position = mul(input.Position, World);
    output.Position = mul(output.Position, View);
    output.Position = mul(output.Position, Projection);

    return output;
}

float4 PS(VertexOutput input) : SV_Target
{
    return float4(1, 0, 0, 1);
}



//-------------------------------------------------------
//GetHeight Color [원본에 색상칠해줄꺼]
//-------------------------------------------------------
struct VertexOutput_GetHeight
{
    float4 Position : SV_Position;
    float4 Color : Color;
};

//높이값에 따른 색상 처리하는곳 
float4 GetHeightColor(float y)
{
    if(y > 20.0f)
        return float4(1, 0, 0, 1);
    
    if(y > 10.0f)
        return float4(0, 1, 0, 1);
    
    if(y > 5.0f)
        return float4(0, 0, 1, 1);
    
    return float4(1, 1, 1, 1);
}

VertexOutput_GetHeight VS_GetHeightColor(VertexInput input)
{
    VertexOutput_GetHeight output;
    
    output.Position = mul(input.Position, World);
    output.Color = GetHeightColor(output.Position.y); //넣는곳에 따라 처리방법이 다름
    output.Position = mul(output.Position, View);
    output.Position = mul(output.Position, Projection);
    
    
    return output;
}

float4 PS_GetHeightColor(VertexOutput_GetHeight input) : SV_Target
{
    return input.Color;
}

//-------------------------------------------------------
//Lambert Color (법선 벡터로 색상 입힘)
//-------------------------------------------------------
struct VertexInput_Normal
{
    float4 Position : Position;
    float3 Normal : Normal;
};

struct VertexOutput_Normal
{
    float4 Position : SV_Position;
    float3 Normal : Normal;
    float4 Color : Color;
};

VertexOutput_Normal VS_Lambert(VertexInput_Normal input)
{
    VertexOutput_Normal output;
    
    output.Position = mul(input.Position, World);
    output.Color = GetHeightColor(output.Position.y);  
    output.Position = mul(output.Position, View);
    output.Position = mul(output.Position, Projection);
    
    //법선벡터도 월드 위치에 따라 움직이게만듬
    output.Normal =mul(input.Normal, (float3x3) World);
    
    return output;
}

float3 LightDirection = float3(-1, -1, +1); 
float4 PS_Lambert(VertexOutput_Normal input) : SV_Target
{
    float3 normal = normalize(input.Normal); // 월드값(VS) 값이 다시 압축이됨
    //내적(벡터방향, 바라보는 방향)  1 ~ -1 / 1에 가까우면 밝아짐
    float Ndot = dot(normal, normalize(-LightDirection));
    
    return input.Color * Ndot;
}

float4 PS_HelfLambert(VertexOutput_Normal input) : SV_Target 
{
    //음영 반값
    float3 normal = normalize(input.Normal); 
    float Ndot = dot(normal, normalize(-LightDirection)) * 0.5f + 0.5f;
    
    return input.Color * Ndot;
}


technique11 T0
{
    pass P0
    {
        SetVertexShader(CompileShader(vs_5_0, VS()));
        SetPixelShader(CompileShader(ps_5_0, PS()));
    }

    pass P1
    {
        SetRasterizerState(RS);

        SetVertexShader(CompileShader(vs_5_0, VS()));
        SetPixelShader(CompileShader(ps_5_0, PS()));
    }

    pass P2
    {
        SetVertexShader(CompileShader(vs_5_0, VS_GetHeightColor()));
        SetPixelShader(CompileShader(ps_5_0, PS_GetHeightColor()));
    }

    pass P3
    {
        SetVertexShader(CompileShader(vs_5_0, VS_Lambert()));
        SetPixelShader(CompileShader(ps_5_0, PS_Lambert()));
    }

    pass P4
    {
        SetVertexShader(CompileShader(vs_5_0, VS_Lambert()));
        SetPixelShader(CompileShader(ps_5_0, PS_HelfLambert()));
    }
}

TerrainDemo.cpp (수정)


더보기
void TerrainDemo::Update()
{
	static UINT Pass = 0; //Pass의 마지막값 
	ImGui::InputInt("Pass", (int*)&Pass);
	Pass %= shader->PassCount();
	terrain->Pass() = Pass;

	static Vector3 LightDirection = Vector3(-1, -1, 1);
	ImGui::SliderFloat3("LightDirection", (float*)&LightDirection, -1, 1);
	shader->AsVector("LightDirection")->SetFloatVector(LightDirection);
	
	terrain->Update();
}

실행

 

 

 


Lambert 

장점 : 음영을 사용 할 수 있게됨

단점 : 극단적으로 어둡고 밝음

 

HelfLambert

장점 : Lambert 의 단점을 보완 해서 사용

단점 : 지점토 형식 (카툰렌더링 쪽에서 사용)