Working on custom physics layers + added default entity rendering
This commit is contained in:
@@ -41,6 +41,8 @@ Renderable :: struct {
|
|||||||
visible: bool = true;
|
visible: bool = true;
|
||||||
type : Renderable_Type; @DontSerialize
|
type : Renderable_Type; @DontSerialize
|
||||||
|
|
||||||
|
use_default_pipeline: bool = true;
|
||||||
|
|
||||||
model: Model_Handle; @DontSerialize
|
model: Model_Handle; @DontSerialize
|
||||||
nodes: [MAX_NODES] Node_Render_Data; @DontSerialize
|
nodes: [MAX_NODES] Node_Render_Data; @DontSerialize
|
||||||
num_nodes: s64; @DontSerialize
|
num_nodes: s64; @DontSerialize
|
||||||
@@ -55,7 +57,8 @@ MAX_CHILDREN :: 16;
|
|||||||
SPHERE;
|
SPHERE;
|
||||||
BOX;
|
BOX;
|
||||||
CAPSULE;
|
CAPSULE;
|
||||||
MESH;
|
TRIANGLE_MESH;
|
||||||
|
CONVEX_MESH;
|
||||||
}
|
}
|
||||||
|
|
||||||
Physics_Lock :: enum_flags u8 {
|
Physics_Lock :: enum_flags u8 {
|
||||||
|
|||||||
@@ -81,6 +81,19 @@ tick_physx :: (scene: *PhysX_Scene, dt: float) {
|
|||||||
PhysX.PxScene_fetchResults(scene.scene, true, null);
|
PhysX.PxScene_fetchResults(scene.scene, true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//custom_filter_shader :: (attributes0: u32, filterData0: PhysX.PxFilterData, attributes1: u32, filterData1: PhysX.PxFilterData, pairFlags: *PhysX.PxPairFlags, constantBlock: *void, constantBlockSize: u32) -> PhysX.PxFilterFlags #c_call {
|
||||||
|
// pairFlags.* = PhysX.PxPairFlags.ContactDefault;
|
||||||
|
// return PhysX.PxFilterFlags.Default;
|
||||||
|
//}
|
||||||
|
|
||||||
|
custom_filter_shader :: (attributes0: *u32, filterData0: *PhysX.PxFilterData, attributes1: *u32, filterData1: *PhysX.PxFilterData, pairFlags: *PhysX.PxPairFlags) -> u16 #c_call {
|
||||||
|
pairFlags.* = PhysX.PxPairFlags.ContactDefault;
|
||||||
|
push_context {
|
||||||
|
print("DUDE!\n");
|
||||||
|
}
|
||||||
|
return xx PhysX.PxFilterFlags.Default;
|
||||||
|
}
|
||||||
|
|
||||||
init_physx_scene :: (game_scene: *Scene) {
|
init_physx_scene :: (game_scene: *Scene) {
|
||||||
tolerance_scale : PhysX.PxTolerancesScale;
|
tolerance_scale : PhysX.PxTolerancesScale;
|
||||||
tolerance_scale.length = 1;
|
tolerance_scale.length = 1;
|
||||||
@@ -91,7 +104,10 @@ init_physx_scene :: (game_scene: *Scene) {
|
|||||||
|
|
||||||
scene_desc.cpuDispatcher = xx dispatcher;
|
scene_desc.cpuDispatcher = xx dispatcher;
|
||||||
scene_desc.simulationEventCallback = event_callback;
|
scene_desc.simulationEventCallback = event_callback;
|
||||||
PhysX.set_default_filter_shader(*scene_desc);
|
PhysX.set_custom_filter_shader(*scene_desc, PhysX.create_custom_filter_shader(custom_filter_shader));
|
||||||
|
//scene_desc.filterShader = custom_filter_shader;//
|
||||||
|
//scene_desc.filterShaderData = null;
|
||||||
|
//scene_desc.filterShaderDataSize = 0;
|
||||||
|
|
||||||
scene := PhysX.PxPhysics_createScene(physics, *scene_desc);
|
scene := PhysX.PxPhysics_createScene(physics, *scene_desc);
|
||||||
|
|
||||||
@@ -203,7 +219,7 @@ create_physx_actor :: (e: *Entity) {
|
|||||||
case .CAPSULE; {
|
case .CAPSULE; {
|
||||||
geo = PhysX.PxCapsuleGeometry_new(e.physics.capsule.radius, e.physics.capsule.half_height-e.physics.capsule.radius);
|
geo = PhysX.PxCapsuleGeometry_new(e.physics.capsule.radius, e.physics.capsule.half_height-e.physics.capsule.radius);
|
||||||
}
|
}
|
||||||
case .MESH; {
|
case .CONVEX_MESH; {
|
||||||
if e.flags & .RENDERABLE {
|
if e.flags & .RENDERABLE {
|
||||||
points : [..] Vector3;
|
points : [..] Vector3;
|
||||||
points.allocator = temp;
|
points.allocator = temp;
|
||||||
@@ -213,7 +229,6 @@ create_physx_actor :: (e: *Entity) {
|
|||||||
model := get_model_by_handle(e.renderable.model);
|
model := get_model_by_handle(e.renderable.model);
|
||||||
|
|
||||||
for node, node_index: model.nodes {
|
for node, node_index: model.nodes {
|
||||||
index_start : u32 = xx indices.count;
|
|
||||||
render_data := e.renderable.nodes[node_index];
|
render_data := e.renderable.nodes[node_index];
|
||||||
|
|
||||||
success, inv_matrix := inverse(e.transform.model_matrix);
|
success, inv_matrix := inverse(e.transform.model_matrix);
|
||||||
@@ -222,9 +237,63 @@ create_physx_actor :: (e: *Entity) {
|
|||||||
|
|
||||||
if node.meshes.count > 0 {
|
if node.meshes.count > 0 {
|
||||||
for m, mi: node.meshes {
|
for m, mi: node.meshes {
|
||||||
|
index_start : u32 = xx indices.count;
|
||||||
mesh := parray_get(*engine.renderer.meshes, m);
|
mesh := parray_get(*engine.renderer.meshes, m);
|
||||||
for v: mesh.positions {
|
for v: mesh.positions {
|
||||||
array_add(*points, transform_position(v, matrix));
|
array_add(*points, v);//transform_position(v, matrix));
|
||||||
|
}
|
||||||
|
|
||||||
|
for i: mesh.indices {
|
||||||
|
array_add(*indices, index_start + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mesh_desc := PhysX.PxConvexMeshDesc_new();
|
||||||
|
mesh_desc.points.count = xx points.count;
|
||||||
|
mesh_desc.points.stride = size_of(Vector3);
|
||||||
|
mesh_desc.points.data = points.data;
|
||||||
|
|
||||||
|
mesh_desc.polygons.count = cast(u32)(indices.count / 3);
|
||||||
|
mesh_desc.polygons.stride = 3 * size_of(u32);
|
||||||
|
mesh_desc.polygons.data = indices.data;
|
||||||
|
|
||||||
|
if !PhysX.PxValidateConvexMesh(*cooking_params, *mesh_desc) {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
stream : PhysX.PxOutputStream;
|
||||||
|
callback := PhysX.PxGetStandaloneInsertionCallback();
|
||||||
|
//read_buffer : PhysX.PxDefaultMemoryInputData_new(;
|
||||||
|
cond : s32;
|
||||||
|
mesh := PhysX.PxCreateConvexMesh(*cooking_params, *mesh_desc, callback, null);
|
||||||
|
scale := PhysX.PxMeshScale_new(*e.transform.scale);
|
||||||
|
geo = PhysX.PxConvexMeshGeometry_new(mesh, *scale, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case .TRIANGLE_MESH; {
|
||||||
|
if e.flags & .RENDERABLE {
|
||||||
|
points : [..] Vector3;
|
||||||
|
points.allocator = temp;
|
||||||
|
indices : [..] u32;
|
||||||
|
indices.allocator = temp;
|
||||||
|
|
||||||
|
model := get_model_by_handle(e.renderable.model);
|
||||||
|
|
||||||
|
for node, node_index: model.nodes {
|
||||||
|
render_data := e.renderable.nodes[node_index];
|
||||||
|
|
||||||
|
success, inv_matrix := inverse(e.transform.model_matrix);
|
||||||
|
// We need to undo the local to world part of every world matrix
|
||||||
|
matrix := inv_matrix * render_data.transform.world_matrix;
|
||||||
|
|
||||||
|
if node.meshes.count > 0 {
|
||||||
|
print("NUM MESHES %\n", node.meshes.count);
|
||||||
|
for m, mi: node.meshes {
|
||||||
|
index_start : u32 = xx indices.count;
|
||||||
|
mesh := parray_get(*engine.renderer.meshes, m);
|
||||||
|
for v: mesh.positions {
|
||||||
|
array_add(*points, v);//transform_position(v, matrix));
|
||||||
}
|
}
|
||||||
|
|
||||||
for i: mesh.indices {
|
for i: mesh.indices {
|
||||||
@@ -242,7 +311,7 @@ create_physx_actor :: (e: *Entity) {
|
|||||||
mesh_desc.triangles.stride = 3 * size_of(u32);
|
mesh_desc.triangles.stride = 3 * size_of(u32);
|
||||||
mesh_desc.triangles.data = indices.data;
|
mesh_desc.triangles.data = indices.data;
|
||||||
|
|
||||||
if PhysX.PxValidateTriangleMesh(*cooking_params, *mesh_desc) {
|
if !PhysX.PxValidateTriangleMesh(*cooking_params, *mesh_desc) {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,6 +328,16 @@ create_physx_actor :: (e: *Entity) {
|
|||||||
|
|
||||||
shape := PhysX.PxPhysics_createShape(physics, geo, material, false, ifx e.physics.trigger then PHYSX_DEFAULT_TRIGGER_SHAPE_FLAGS else PHYSX_DEFAULT_SIMULATION_SHAPE_FLAGS);
|
shape := PhysX.PxPhysics_createShape(physics, geo, material, false, ifx e.physics.trigger then PHYSX_DEFAULT_TRIGGER_SHAPE_FLAGS else PHYSX_DEFAULT_SIMULATION_SHAPE_FLAGS);
|
||||||
|
|
||||||
|
// Setup layers
|
||||||
|
filter_data := PhysX.PxFilterData_new();
|
||||||
|
filter_data.word0 = 1;
|
||||||
|
filter_data.word1 = 1;
|
||||||
|
filter_data.word2 = 1;
|
||||||
|
filter_data.word3 = 1;
|
||||||
|
|
||||||
|
//PhysX.PxShape_setSimulationFilterData(shape, *filter_data);
|
||||||
|
//PhysX.PxShape_setQueryFilterData(shape, *filter_data);
|
||||||
|
|
||||||
PhysX.PxRigidActor_attachShape(actor, shape);
|
PhysX.PxRigidActor_attachShape(actor, shape);
|
||||||
|
|
||||||
if e.physics.dynamic {
|
if e.physics.dynamic {
|
||||||
|
|||||||
@@ -624,6 +624,7 @@ Renderer :: struct {
|
|||||||
|
|
||||||
default_pipelines : struct {
|
default_pipelines : struct {
|
||||||
message_text : Pipeline_State_Handle;
|
message_text : Pipeline_State_Handle;
|
||||||
|
entity_pipeline : Pipeline_State_Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
default_samplers : struct {
|
default_samplers : struct {
|
||||||
@@ -684,6 +685,7 @@ create_renderer :: (window: *Window) -> *Renderer {
|
|||||||
init_freetype();
|
init_freetype();
|
||||||
init_default_meshes();
|
init_default_meshes();
|
||||||
init_trigger_line_rendering();
|
init_trigger_line_rendering();
|
||||||
|
init_default_pipelines();
|
||||||
|
|
||||||
array_reserve(*engine.renderer.command_buffer.commands, 4096);
|
array_reserve(*engine.renderer.command_buffer.commands, 4096);
|
||||||
|
|
||||||
@@ -698,35 +700,42 @@ create_renderer :: (window: *Window) -> *Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init_default_pipelines :: () {
|
init_default_pipelines :: () {
|
||||||
{
|
//{
|
||||||
vs := create_vertex_shader(renderer, "../modules/Coven/shaders/font.hlsl", "VS");
|
// vs := create_vertex_shader(renderer, "../modules/Coven/shaders/font.hlsl", "VS");
|
||||||
ps := create_pixel_shader(renderer, "../modules/Coven/shaders/font.hlsl", "PS");
|
// ps := create_pixel_shader(renderer, "../modules/Coven/shaders/font.hlsl", "PS");
|
||||||
|
|
||||||
layout : [3] Vertex_Data_Info;
|
// layout : [3] Vertex_Data_Info;
|
||||||
layout[0] = .{0,.POSITION2D, 0};
|
// layout[0] = .{0,.POSITION2D, 0};
|
||||||
layout[1] = .{0,.TEXCOORD0, 0};
|
// layout[1] = .{0,.TEXCOORD0, 0};
|
||||||
layout[2] = .{0,.COLOR_WITH_ALPHA, 0};
|
// layout[2] = .{0,.COLOR_WITH_ALPHA, 0};
|
||||||
|
|
||||||
params : [2] Shader_Parameter;
|
// params : [2] Shader_Parameter;
|
||||||
params[0].shader = .PIXEL;
|
// params[0].shader = .PIXEL;
|
||||||
params[0].type = .SAMPLER;
|
// params[0].type = .SAMPLER;
|
||||||
params[0].name = "ss";
|
// params[0].name = "ss";
|
||||||
params[0].slot = 0;
|
// params[0].slot = 0;
|
||||||
params[0].mapping = .CLAMP_SAMPLER;
|
// params[0].mapping = .CLAMP_SAMPLER;
|
||||||
|
|
||||||
params[1].shader = .PIXEL;
|
// params[1].shader = .PIXEL;
|
||||||
params[1].type = .TEXTURE;
|
// params[1].type = .TEXTURE;
|
||||||
params[1].name = "tex";
|
// params[1].name = "tex";
|
||||||
params[1].slot = 1;
|
// params[1].slot = 1;
|
||||||
|
|
||||||
engine.renderer.default_pipelines.message_text = create_pipeline_state(renderer, vs, ps, layout, params, blend_type=.TRANSPARENT);
|
// engine.renderer.default_pipelines.message_text = create_pipeline_state(renderer, vs, ps, layout, params, blend_type=.TRANSPARENT);
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
//{
|
||||||
|
// vs := create_vertex_shader_from_source(engine.renderer, "fallback", FALLBACK_SHADER, "VS", mesh_data_types = .[.POSITION]);
|
||||||
|
// ps := create_pixel_shader_from_source(engine.renderer, "fallback", FALLBACK_SHADER, "PS");
|
||||||
|
|
||||||
|
// projectile_pipeline = create_pipeline_state2(engine.renderer, vs, ps, blend_type=.OPAQUE);
|
||||||
|
//}
|
||||||
|
|
||||||
{
|
{
|
||||||
vs := create_vertex_shader_from_source(engine.renderer, FALLBACK_SHADER, "VS", mesh_data_types = .[.POSITION]);
|
vs := create_vertex_shader_from_source(engine.renderer, "default_entity", DEFAULT_ENTITY_SHADER, "VS", mesh_data_types = .[.POSITION, .NORMAL, .TEXCOORD]);
|
||||||
ps := create_pixel_shader_from_source(engine.renderer, FALLBACK_SHADER, "PS");
|
ps := create_pixel_shader_from_source(engine.renderer, "default_entity", DEFAULT_ENTITY_SHADER, "PS");
|
||||||
|
|
||||||
projectile_pipeline = create_pipeline_state2(engine.renderer, vs, ps, blend_type=.OPAQUE);
|
engine.renderer.default_pipelines.entity_pipeline = create_pipeline_state(engine.renderer, vs, ps, blend_type=.OPAQUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1689,6 +1698,55 @@ render :: () {
|
|||||||
// #load "ui.jai";
|
// #load "ui.jai";
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
render_default_renderable_entities :: () {
|
||||||
|
for e: engine.current_scene.entities {
|
||||||
|
if e.flags & .RENDERABLE && e.renderable.use_default_pipeline {
|
||||||
|
render_entity(e, engine.renderer.default_pipelines.entity_pipeline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render_entity :: (e: *Entity, pipeline: Pipeline_State_Handle) {
|
||||||
|
if e.renderable.type == {
|
||||||
|
case .MODEL; {
|
||||||
|
model := get_model_by_handle(e.renderable.model);
|
||||||
|
if model == null return;
|
||||||
|
|
||||||
|
for node, node_index: model.nodes {
|
||||||
|
render_data := e.renderable.nodes[node_index];
|
||||||
|
if !render_data.enabled continue;
|
||||||
|
|
||||||
|
if node.meshes.count > 0 {
|
||||||
|
for m, mi: node.meshes {
|
||||||
|
push_cmd_set_pipeline_state(engine.renderer, pipeline);
|
||||||
|
push_cmd_set_constant_buffer(engine.renderer, 1, engine.directional_light_buffer, .VERTEX);
|
||||||
|
push_cmd_set_constant_buffer(engine.renderer, 1, engine.directional_light_buffer, .PIXEL);
|
||||||
|
|
||||||
|
push_cmd_set_constant_buffer(engine.renderer, 2, render_data.transform_buffer, .VERTEX);
|
||||||
|
push_cmd_set_constant_buffer(engine.renderer, 3, render_data.material_buffer, .PIXEL);
|
||||||
|
|
||||||
|
if node.num_bones > 0 {
|
||||||
|
push_cmd_set_constant_buffer(engine.renderer, 4, render_data.bone_buffers[mi], .VERTEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh := parray_get(*engine.renderer.meshes, m);
|
||||||
|
|
||||||
|
vb := get_mesh_vb(mesh);
|
||||||
|
push_cmd_set_vertex_buffer(engine.renderer, vb);
|
||||||
|
|
||||||
|
if mesh.ib != 0 {
|
||||||
|
push_cmd_set_index_buffer(engine.renderer, mesh.ib);
|
||||||
|
push_cmd_draw_indexed(engine.renderer, mesh.indices.count);
|
||||||
|
} else {
|
||||||
|
push_cmd_draw(engine.renderer, mesh.positions.count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#scope_module
|
#scope_module
|
||||||
#load "dx11_renderer.jai";
|
#load "dx11_renderer.jai";
|
||||||
|
|
||||||
@@ -1724,3 +1782,146 @@ float4 PS(PSInput input) : SV_Target {
|
|||||||
return float4(1,0,1,1);
|
return float4(1,0,1,1);
|
||||||
}
|
}
|
||||||
DONE
|
DONE
|
||||||
|
|
||||||
|
DEFAULT_ENTITY_SHADER :: #string DONE
|
||||||
|
cbuffer CameraData : register(b0)
|
||||||
|
{
|
||||||
|
float4x4 projection;
|
||||||
|
float4x4 view;
|
||||||
|
float4 camera_position;
|
||||||
|
};
|
||||||
|
|
||||||
|
cbuffer Directional_Light_Data : register(b1)
|
||||||
|
{
|
||||||
|
float4 color_and_intensity;
|
||||||
|
float4 direction;
|
||||||
|
float4x4 light_matrix;
|
||||||
|
};
|
||||||
|
|
||||||
|
cbuffer Transform : register(b2)
|
||||||
|
{
|
||||||
|
float4x4 model;
|
||||||
|
};
|
||||||
|
|
||||||
|
cbuffer Material : register(b3)
|
||||||
|
{
|
||||||
|
float4 base_color;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef SKINNING
|
||||||
|
|
||||||
|
#define MAX_BONES 128
|
||||||
|
|
||||||
|
cbuffer Bone_Matrices : register(b4)
|
||||||
|
{
|
||||||
|
float4x4 bone_matrices[MAX_BONES];
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct VSInput {
|
||||||
|
float3 position : POSITION;
|
||||||
|
float3 normal : NORMAL;
|
||||||
|
float2 texcoord : TEXCOORD0;
|
||||||
|
|
||||||
|
#ifdef SKINNING
|
||||||
|
float4 bone_indices : TEXCOORD1;
|
||||||
|
float4 bone_weights : TEXCOORD2;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PSInput {
|
||||||
|
float4 position : SV_POSITION;
|
||||||
|
float2 texcoord : TEXCOORD1;
|
||||||
|
float3 normal : NORMAL;
|
||||||
|
float2 screen_pos : TEXCOORD0;
|
||||||
|
float4 light_view_position : TEXCOORD3;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PSOutput {
|
||||||
|
float4 color : SV_Target0;
|
||||||
|
};
|
||||||
|
|
||||||
|
sampler samp : register(s0);
|
||||||
|
Texture2D shadow_map: register(t0);
|
||||||
|
|
||||||
|
PSInput VS(VSInput input) {
|
||||||
|
PSInput output;
|
||||||
|
|
||||||
|
float3 position = input.position;
|
||||||
|
#ifdef SKINNING
|
||||||
|
float4x4 m = float4x4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
m += bone_matrices[int(input.bone_indices[i])] * input.bone_weights[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
output.position = mul(float4(position, 1.0), m);
|
||||||
|
#else
|
||||||
|
output.position = mul(float4(position, 1.0), model);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
output.light_view_position = mul(output.position, light_matrix);
|
||||||
|
|
||||||
|
output.position = mul(output.position, view);
|
||||||
|
output.position = mul(output.position, projection);
|
||||||
|
output.screen_pos = output.position.xy / output.position.w;
|
||||||
|
output.screen_pos = output.screen_pos * 0.5 + 0.5;
|
||||||
|
output.normal = normalize(mul(input.normal, model));
|
||||||
|
output.texcoord = input.texcoord;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
float calculate_shadow(float2 shadow_coord, float bias, float current_depth) {
|
||||||
|
if(current_depth > 1.0)
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
float2 texture_size;
|
||||||
|
shadow_map.GetDimensions(texture_size.x, texture_size.y);
|
||||||
|
float2 texel_size = 1.0 / texture_size;
|
||||||
|
float shadow = 0.0;
|
||||||
|
|
||||||
|
for(int x = -1; x <= 1; ++x)
|
||||||
|
{
|
||||||
|
for(int y = -1; y <= 1; ++y)
|
||||||
|
{
|
||||||
|
float pcf_depth = shadow_map.Sample(samp, shadow_coord + float2(x, y) * texel_size).r;
|
||||||
|
shadow += current_depth - bias > pcf_depth ? 1.0 : 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shadow /= 9.0;
|
||||||
|
|
||||||
|
|
||||||
|
return 1.0 - shadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
PSOutput PS(PSInput input) {
|
||||||
|
PSOutput output;
|
||||||
|
float ao = 1.0;//ssao.Sample(samp, float2(input.screen_pos.x, 1.0 - input.screen_pos.y));
|
||||||
|
//output.color = float4(ao, ao, ao, 1.0);
|
||||||
|
//return output;
|
||||||
|
float3 ambient = 0.1;
|
||||||
|
|
||||||
|
// Diffuse
|
||||||
|
float3 light_dir = normalize(-direction);
|
||||||
|
float diffuse_factor = max(0, dot(input.normal, light_dir));
|
||||||
|
float3 diffuse = 0.5 * diffuse_factor;
|
||||||
|
|
||||||
|
// Specular
|
||||||
|
float3 view_dir = normalize(-input.position.xyz);
|
||||||
|
float3 reflect_dir = reflect(-light_dir, input.normal);
|
||||||
|
float specular_factor = pow(max(dot(view_dir, reflect_dir), 0), 32.0);
|
||||||
|
float3 specular = 0.3 * specular_factor;
|
||||||
|
|
||||||
|
float2 shadow_coord;
|
||||||
|
shadow_coord.x = input.light_view_position.x / input.light_view_position.w * 0.5 + 0.5;
|
||||||
|
shadow_coord.y = -input.light_view_position.y / input.light_view_position.w * 0.5 + 0.5;
|
||||||
|
float current_depth = input.light_view_position.z / input.light_view_position.w;
|
||||||
|
|
||||||
|
float shadow_amount = calculate_shadow(shadow_coord, 0.01, current_depth);
|
||||||
|
|
||||||
|
output.color = base_color * color_and_intensity.w * float4(ao*(ambient + diffuse + specular), base_color.a);
|
||||||
|
output.color *= max(0.2, shadow_amount);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
DONE
|
||||||
|
|||||||
Reference in New Issue
Block a user