collada_scene: implement directional lighting
This commit is contained in:
parent
4d952b0a90
commit
b9cfcde9c7
Binary file not shown.
@ -9,6 +9,7 @@
|
||||
#include "new.hpp"
|
||||
|
||||
extern ID3D10Device * g_pd3dDevice;
|
||||
extern XMVECTOR g_Eye;
|
||||
extern XMMATRIX g_View;
|
||||
extern XMMATRIX g_Projection;
|
||||
|
||||
@ -22,6 +23,11 @@ namespace collada_scene {
|
||||
ID3D10EffectMatrixVariable * g_pViewVariable = NULL;
|
||||
ID3D10EffectMatrixVariable * g_pProjectionVariable = NULL;
|
||||
|
||||
ID3D10EffectVectorVariable * g_pViewEyeVariable = NULL;
|
||||
ID3D10EffectVectorVariable * g_pLightPosVariable = NULL;
|
||||
ID3D10EffectVectorVariable * g_pLightDirVariable = NULL;
|
||||
ID3D10EffectVectorVariable * g_pLightColorVariable = NULL;
|
||||
|
||||
ID3D10EffectVectorVariable * g_pEmissionVariable = NULL;
|
||||
ID3D10EffectVectorVariable * g_pAmbientVariable = NULL;
|
||||
ID3D10EffectVectorVariable * g_pDiffuseVariable = NULL;
|
||||
@ -67,8 +73,52 @@ namespace collada_scene {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void scene_state::update_light_instance_vectors(light const& light,
|
||||
node_instance const& node_instance,
|
||||
int light_index)
|
||||
{
|
||||
const XMVECTOR position = XMVectorSet(0, 0, 0, 1);
|
||||
const XMVECTOR direction = XMVectorSet(0, 0, -1, 0);
|
||||
XMVECTOR light_position = XMVector3Transform(position, node_instance.world);
|
||||
XMVECTOR light_direction = XMVector3TransformNormal(direction, node_instance.world);
|
||||
XMVECTOR light_color = XMLoadFloat3((XMFLOAT3 *)&light.color);
|
||||
|
||||
XMStoreFloat4(&m_lightPositions[light_index], light_position);
|
||||
XMStoreFloat4(&m_lightDirections[light_index], light_direction);
|
||||
XMStoreFloat4(&m_lightColors[light_index], light_color);
|
||||
}
|
||||
|
||||
void scene_state::update_light_instances()
|
||||
{
|
||||
int light_index = 0;
|
||||
for (int i = 0; i < m_descriptor->nodes_count; i++) {
|
||||
node const& node = *m_descriptor->nodes[i];
|
||||
node_instance const& node_instance = m_nodeInstances[i];
|
||||
for (int j = 0; j < node.instance_lights_count; j++) {
|
||||
light const& light = *node.instance_lights[j].light;
|
||||
update_light_instance_vectors(light, node_instance, light_index);
|
||||
light_index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void scene_state::allocate_light_instances()
|
||||
{
|
||||
// count light instances
|
||||
int count = 0;
|
||||
for (int i = 0; i < m_descriptor->nodes_count; i++) {
|
||||
count += m_descriptor->nodes[i]->instance_lights_count;
|
||||
}
|
||||
|
||||
// allocate
|
||||
m_lightInstancesCount = count;
|
||||
m_lightPositions = New<XMFLOAT4>(m_lightInstancesCount);
|
||||
m_lightDirections = New<XMFLOAT4>(m_lightInstancesCount);
|
||||
m_lightColors = New<XMFLOAT4>(m_lightInstancesCount);
|
||||
}
|
||||
|
||||
static void initialize_node_transforms(node const * const node,
|
||||
node_instance * node_instance)
|
||||
node_instance * const node_instance)
|
||||
{
|
||||
for (int i = 0; i < node->transforms_count; i++) {
|
||||
transform& transform = node_instance->transforms[i];
|
||||
@ -98,7 +148,7 @@ namespace collada_scene {
|
||||
}
|
||||
|
||||
void scene_state::allocate_node_instance(node const * const node,
|
||||
node_instance * node_instance)
|
||||
node_instance * const node_instance)
|
||||
{
|
||||
node_instance->transforms = New<transform>(node->transforms_count);
|
||||
initialize_node_transforms(node, node_instance);
|
||||
@ -133,6 +183,7 @@ namespace collada_scene {
|
||||
return E_FAIL;
|
||||
|
||||
allocate_node_instances();
|
||||
allocate_light_instances();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@ -143,6 +194,7 @@ namespace collada_scene {
|
||||
|
||||
D3D10_INPUT_ELEMENT_DESC layout[inputs.elements_count];
|
||||
|
||||
assert(inputs.elements_count == 3);
|
||||
int byte_offset = 0;
|
||||
for (int i = 0; i < inputs.elements_count; i++) {
|
||||
layout[i].SemanticName = inputs.elements[i].semantic;
|
||||
@ -200,6 +252,11 @@ namespace collada_scene {
|
||||
g_pViewVariable = g_pEffect->GetVariableByName("View")->AsMatrix();
|
||||
g_pProjectionVariable = g_pEffect->GetVariableByName("Projection")->AsMatrix();
|
||||
|
||||
g_pViewEyeVariable = g_pEffect->GetVariableByName("ViewEye")->AsVector();
|
||||
g_pLightPosVariable = g_pEffect->GetVariableByName("LightPos")->AsVector();
|
||||
g_pLightDirVariable = g_pEffect->GetVariableByName("LightDir")->AsVector();
|
||||
g_pLightColorVariable = g_pEffect->GetVariableByName("LightColor")->AsVector();
|
||||
|
||||
g_pEmissionVariable = g_pEffect->GetVariableByName("Emission")->AsVector();
|
||||
g_pAmbientVariable = g_pEffect->GetVariableByName("Ambient")->AsVector();
|
||||
g_pDiffuseVariable = g_pEffect->GetVariableByName("Diffuse")->AsVector();
|
||||
@ -559,28 +616,59 @@ namespace collada_scene {
|
||||
}
|
||||
}
|
||||
|
||||
void scene_state::render(float t)
|
||||
void scene_state::update(float t)
|
||||
{
|
||||
g_pViewVariable->SetMatrix((float *)&g_View);
|
||||
g_pProjectionVariable->SetMatrix((float *)&g_Projection);
|
||||
|
||||
g_pd3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
||||
t = loop(t / 2.0f, 3.333333f);
|
||||
|
||||
// animate and update all world transforms
|
||||
for (int i = 0; i < m_descriptor->nodes_count; i++) {
|
||||
node const& node = *m_descriptor->nodes[i];
|
||||
node_instance& node_instance = m_nodeInstances[i];
|
||||
|
||||
animate_node(node, node_instance, t);
|
||||
node_world_transform(node, node_instance);
|
||||
}
|
||||
|
||||
g_pWorldVariable->SetMatrix((float *)&node_instance.world);
|
||||
// update all lights (after world transforms are computed)
|
||||
update_light_instances();
|
||||
}
|
||||
|
||||
static int min(int a, int b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
void scene_state::render()
|
||||
{
|
||||
XMFLOAT4 eye;
|
||||
XMFLOAT4X4 projection;
|
||||
XMFLOAT4X4 view;
|
||||
XMStoreFloat4(&eye, g_Eye);
|
||||
XMStoreFloat4x4(&view, g_View);
|
||||
XMStoreFloat4x4(&projection, g_Projection);
|
||||
|
||||
g_pViewVariable->SetMatrix((float *)&view);
|
||||
g_pProjectionVariable->SetMatrix((float *)&projection);
|
||||
|
||||
g_pViewEyeVariable->SetFloatVector((float *)&eye);
|
||||
|
||||
int lights = min(2, m_lightInstancesCount);
|
||||
g_pLightPosVariable->SetFloatVectorArray((float *)m_lightPositions, 0, lights);
|
||||
g_pLightDirVariable->SetFloatVectorArray((float *)m_lightDirections, 0, lights);
|
||||
g_pLightColorVariable->SetFloatVectorArray((float *)m_lightColors, 0, lights);
|
||||
|
||||
g_pd3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
||||
for (int i = 0; i < m_descriptor->nodes_count; i++) {
|
||||
node const& node = *m_descriptor->nodes[i];
|
||||
node_instance& node_instance = m_nodeInstances[i];
|
||||
|
||||
// joints aren't rendered
|
||||
if (node.type != node_type::NODE)
|
||||
continue;
|
||||
|
||||
g_pWorldVariable->SetMatrix((float *)&node_instance.world);
|
||||
|
||||
render_geometries(node.instance_geometries, node.instance_geometries_count);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,12 @@ cbuffer cbEveryFrame
|
||||
{
|
||||
matrix View;
|
||||
matrix Projection;
|
||||
|
||||
float4 ViewEye;
|
||||
|
||||
float4 LightPos[2];
|
||||
float4 LightDir[2];
|
||||
float4 LightColor[2];
|
||||
};
|
||||
|
||||
cbuffer cbMultiplePerFrame
|
||||
@ -30,30 +36,39 @@ struct PS_INPUT
|
||||
float4 Pos : SV_POSITION;
|
||||
float3 Norm : NORMAL;
|
||||
float2 Tex : TEXCOORD0;
|
||||
float4 WPos : POSITION;
|
||||
};
|
||||
|
||||
PS_INPUT VS(VS_INPUT input)
|
||||
{
|
||||
PS_INPUT output;
|
||||
|
||||
output.Pos = mul(float4(input.Pos, 1), World);
|
||||
output.Pos = mul(output.Pos, View);
|
||||
float4 world_pos = mul(float4(input.Pos, 1), World);
|
||||
output.Pos = mul(world_pos, View);
|
||||
output.Pos = mul(output.Pos, Projection);
|
||||
|
||||
output.Norm = mul(input.Norm, (float3x3)World);
|
||||
output.Tex = input.Tex;
|
||||
|
||||
output.WPos = world_pos;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 PS(PS_INPUT input) : SV_Target
|
||||
{
|
||||
float4 color = Emission + Diffuse * 1.0 + Specular * 0.0;
|
||||
float3 normal = normalize(input.Norm);
|
||||
float3 view_dir = normalize(ViewEye.xyz - input.Pos.xyz);
|
||||
|
||||
float3 color = Emission.xyz;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
float3 light_dir = normalize(-LightDir[i].xyz);
|
||||
float diffuse_intensity = max(dot(normal, light_dir), 0.0);
|
||||
color += Diffuse.xyz * diffuse_intensity * LightColor[i].xyz;
|
||||
}
|
||||
|
||||
return float4(color.xyz, 1);
|
||||
|
||||
//return float4(input.Normal * 0.5 + 0.5, 1);
|
||||
//return float4(input.Tex.xy, 0, 1);
|
||||
}
|
||||
|
||||
BlendState DisableBlending
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
#include "collada.hpp"
|
||||
#include "collada_scene.hpp"
|
||||
|
||||
#include "scenes/curve_interpolation.hpp"
|
||||
#include "scenes/curve_interpolation/curve_interpolation.hpp"
|
||||
|
||||
HINSTANCE g_hInstance = NULL;
|
||||
HWND g_hWnd = NULL;
|
||||
@ -1843,7 +1843,8 @@ void Render(float t, float dt)
|
||||
|
||||
//collada::Render(t);
|
||||
|
||||
g_SceneState.render(t);
|
||||
g_SceneState.update(t);
|
||||
g_SceneState.render();
|
||||
|
||||
RenderFont(dt);
|
||||
|
||||
|
||||
@ -1008,8 +1008,8 @@ instance_light const instance_lights_node_cube[] = {
|
||||
};
|
||||
|
||||
channel const * const node_channels_node_cube[] = {
|
||||
&node_channel_node_cube_translation_x,
|
||||
&node_channel_node_cube_translation_y,
|
||||
&node_channel_node_cube_translation_x,
|
||||
};
|
||||
|
||||
node const node_node_cube = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user