pretty much works now
This commit is contained in:
@@ -10,5 +10,6 @@ target_sources(RayTracer
|
||||
if(APPLE)
|
||||
add_subdirectory(metal/)
|
||||
endif()
|
||||
add_subdirectory(cpu/)
|
||||
add_subdirectory(scene/)
|
||||
add_subdirectory(util/)
|
||||
|
||||
@@ -2,5 +2,5 @@ target_sources(RayTracer
|
||||
PUBLIC
|
||||
CPURenderer.h
|
||||
CPURenderer.cpp
|
||||
CPURenderer.h
|
||||
CPURenderer.cpp)
|
||||
CPUScene.h
|
||||
CPUScene.cpp)
|
||||
+19
-2
@@ -1,21 +1,31 @@
|
||||
#include "CPURenderer.h"
|
||||
#include "scene/Renderer.h"
|
||||
#include "CPUScene.h"
|
||||
#include <imgui.h>
|
||||
#include <imgui_impl_glfw.h>
|
||||
#include <imgui_impl_opengl3.h>
|
||||
|
||||
#define GLSL(...) "#version 400\n" #__VA_ARGS__
|
||||
|
||||
static void glfw_error_callback(int error, const char* description)
|
||||
{
|
||||
fprintf(stderr, "Glfw Error %d: %s\n", error, description);
|
||||
}
|
||||
CPURenderer::CPURenderer()
|
||||
{
|
||||
width = 1920;
|
||||
height = 1080;
|
||||
glewExperimental = true;
|
||||
glfwSetErrorCallback(glfw_error_callback);
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // We don't want the old OpenGL
|
||||
window = glfwCreateWindow(width, height, "RayTracer", nullptr, nullptr);
|
||||
glfwSwapInterval(1);
|
||||
float xscale = 1, yscale = 1;
|
||||
glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xscale, &yscale);
|
||||
window = glfwCreateWindow(width / xscale, height / yscale, "RayTracer", nullptr, nullptr);
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSwapInterval(1);
|
||||
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
@@ -29,6 +39,8 @@ CPURenderer::CPURenderer()
|
||||
|
||||
glewInit();
|
||||
|
||||
scene = new CPUScene();
|
||||
|
||||
glGenVertexArrays(1, &vao);
|
||||
glBindVertexArray(vao);
|
||||
|
||||
@@ -91,6 +103,11 @@ CPURenderer::CPURenderer()
|
||||
glClearColor(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
CPURenderer::~CPURenderer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
glm::vec3 rand01(glm::uvec3 x)
|
||||
{ // pseudo-random number generator
|
||||
for (int i = 3; i-- > 0;)
|
||||
|
||||
+25
-28
@@ -1,12 +1,11 @@
|
||||
#include "scene/Renderer.h"
|
||||
#include "cpu/CPURenderer.h"
|
||||
#include "util/ModelLoader.h"
|
||||
#include "metal/MetalRenderer.h"
|
||||
#include <imgui.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::unique_ptr<Renderer> renderer = std::make_unique<MetalRenderer>();
|
||||
|
||||
std::unique_ptr<Renderer> renderer = std::make_unique<CPURenderer>();
|
||||
renderer->addDirectionalLight(DirectionalLight{
|
||||
.direction = glm::normalize(glm::vec3(-0.4f, -0.3f, -0.2f)),
|
||||
.color = glm::vec3(1, 1, 1),
|
||||
@@ -15,13 +14,12 @@ int main()
|
||||
renderer->addModels(ModelLoader::loadModel("../../res/models/cube.fbx"),
|
||||
glm::mat4(glm::vec4(1.0f, 0.0f, 0.0f, 0.0f), glm::vec4(0.0f, 1.0f, 0.0f, 0.0f), glm::vec4(0.0f, 0.0f, 1.0f, 0.0f),
|
||||
glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)));
|
||||
renderer->addModels(ModelLoader::loadModel("../../res/models/cube.fbx"),
|
||||
glm::mat4(glm::vec4(1.0f, 0.0f, 0.0f, 0.0f), glm::vec4(0.0f, 1.0f, 0.0f, 0.0f), glm::vec4(0.0f, 0.0f, 1.0f, 0.0f),
|
||||
glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)));
|
||||
renderer->generate();
|
||||
renderer->generate();
|
||||
Camera camera = Camera{
|
||||
.position = glm::vec3(5, 1, 2),
|
||||
.target = glm::vec3(0, 0, 0),
|
||||
.f = 0,
|
||||
.A = 0,
|
||||
.S_O = 6,
|
||||
};
|
||||
RenderParameter render = RenderParameter{
|
||||
@@ -33,27 +31,26 @@ int main()
|
||||
|
||||
while (true)
|
||||
{
|
||||
renderer->beginFrame();
|
||||
ImGui::Text("Camera Parameters");
|
||||
ImGui::InputFloat3("Position", &camera.position.x);
|
||||
ImGui::InputFloat3("Target", &camera.target.x);
|
||||
ImGui::InputFloat("Focal Length", &camera.f);
|
||||
ImGui::InputFloat("Aperture", &camera.A);
|
||||
ImGui::InputFloat("S_O", &camera.S_O);
|
||||
ImGui::Text("Render Parameters");
|
||||
ImGui::InputInt2("Dimensions", (int*)&render.width);
|
||||
ImGui::InputInt("Samples", (int*)&render.numSamples);
|
||||
if (ImGui::Button("Render"))
|
||||
{
|
||||
std::cout << "Test" << std::endl;
|
||||
renderer->startRender(camera, render);
|
||||
renderer->beginFrame();
|
||||
ImGui::Text("Camera Parameters");
|
||||
ImGui::InputFloat3("Position", &camera.position.x);
|
||||
ImGui::InputFloat3("Target", &camera.target.x);
|
||||
ImGui::InputFloat("Focal Length", &camera.f);
|
||||
ImGui::InputFloat("Aperture", &camera.A);
|
||||
ImGui::InputFloat("S_O", &camera.S_O);
|
||||
ImGui::Text("Render Parameters");
|
||||
ImGui::InputInt2("Dimensions", (int*)&render.width);
|
||||
ImGui::InputInt("Samples", (int*)&render.numSamples);
|
||||
if (ImGui::Button("Render"))
|
||||
{
|
||||
renderer->startRender(camera, render);
|
||||
}
|
||||
ImGui::Text("Render Stats");
|
||||
ImGui::Text("Last Sample Time: %.3f ms", renderer->getLastSampleTime());
|
||||
ImGui::Text("Average Sample Time: %.3f ms", renderer->getAverageSampleTime());
|
||||
ImGui::PlotLines("Sample Times", renderer->getSampleTimes().data(), renderer->getSampleTimes().size(), 0, 0, FLT_MAX, FLT_MAX,
|
||||
ImVec2(0, 40));
|
||||
renderer->update();
|
||||
}
|
||||
ImGui::Text("Render Stats");
|
||||
ImGui::Text("Last Sample Time: %.3f ms", renderer->getLastSampleTime());
|
||||
ImGui::Text("Average Sample Time: %.3f ms", renderer->getAverageSampleTime());
|
||||
ImGui::PlotLines("Sample Times", renderer->getSampleTimes().data(), renderer->getSampleTimes().size(), 0, 0, FLT_MAX, FLT_MAX,
|
||||
ImVec2(0, 40));
|
||||
renderer->update();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
+18
-13
@@ -68,7 +68,7 @@ struct BRDF
|
||||
float3 albedo = float3(1, 1, 1);
|
||||
float alpha = 1;
|
||||
float3 specularColor = float3(1, 1, 1);
|
||||
float shininess = 0.04;
|
||||
float shininess = 0.004;
|
||||
float3 emissive = float3(0, 0, 0);
|
||||
MaterialType materialType;
|
||||
float3 evaluate(HitInfo hit, float3 viewDir, float3 lightDir, float3 lightColor)
|
||||
@@ -76,7 +76,7 @@ struct BRDF
|
||||
float3 normal = hit.normal;
|
||||
float diffuse = max(dot(normal, lightDir), 0.0f);
|
||||
float3 h = normalize(lightDir + viewDir);
|
||||
float specular = pow(min(max(dot(normal, h), 0.0f), 1.0f), shininess);
|
||||
float specular = pow(clamp(dot(normal, h), 0.0f, 1.0f), shininess);
|
||||
|
||||
return (albedo * diffuse * lightColor) + float3(0.03, 0.03, 0.03);
|
||||
}
|
||||
@@ -117,7 +117,7 @@ inline T interpolateVertexAttribute(constant T *attributes,
|
||||
|
||||
// Compute the sum of the vertex attributes weighted by the barycentric coordinates.
|
||||
// The barycentric coordinates sum to one.
|
||||
return (1.0f - uv.x - uv.y) * T0 + uv.x * T1 + uv.y * T2;
|
||||
return (1.0f - uv.x - uv.y) * T2 + uv.x * T0 + uv.y * T1;
|
||||
}
|
||||
|
||||
kernel void computeKernel(
|
||||
@@ -129,10 +129,11 @@ kernel void computeKernel(
|
||||
constant packed_float2* texCoords [[buffer(2)]],
|
||||
constant packed_float3* normals [[buffer(3)]],
|
||||
constant ModelReference* modelRefs [[buffer(4)]],
|
||||
constant DirectionalLight* directionalLights [[buffer(5)]],
|
||||
constant PointLight* pointLights [[buffer(6)]],
|
||||
constant MTLAccelerationStructureInstanceDescriptor* instances [[buffer(7)]],
|
||||
instance_acceleration_structure accelerationStructure [[buffer(8)]],
|
||||
constant BRDF* materials [[buffer(5)]],
|
||||
constant DirectionalLight* directionalLights [[buffer(6)]],
|
||||
constant PointLight* pointLights [[buffer(7)]],
|
||||
constant MTLAccelerationStructureInstanceDescriptor* instances [[buffer(8)]],
|
||||
instance_acceleration_structure accelerationStructure [[buffer(9)]],
|
||||
texture2d<float, access::read_write> accumulator [[texture(0)]],
|
||||
texture2d<float, access::read_write> image [[texture(1)]]
|
||||
)
|
||||
@@ -201,11 +202,11 @@ kernel void computeKernel(
|
||||
const auto indices = indexBuffer[ref.indicesOffset + intersection.primitive_id];
|
||||
info.position = interpolateVertexAttribute(positions, ref.positionOffset, indices.x, indices.y, indices.z, intersection.triangle_barycentric_coord);
|
||||
info.texCoords = interpolateVertexAttribute(texCoords, ref.positionOffset, indices.x, indices.y, indices.z, intersection.triangle_barycentric_coord);
|
||||
info.normal = interpolateVertexAttribute(normals, ref.positionOffset, indices.x, indices.y, indices.z, intersection.triangle_barycentric_coord);
|
||||
info.normal = normalize(interpolateVertexAttribute(normals, ref.positionOffset, indices.x, indices.y, indices.z, intersection.triangle_barycentric_coord));
|
||||
info.normalLight = dot(info.normal, cam.direction) < 0 ? info.normal : -info.normal;
|
||||
|
||||
BRDF brdf;
|
||||
brdf.albedo = float3(0, 1, 0);
|
||||
brdf.albedo = float3(0, 1, 0);
|
||||
|
||||
float p = max(max(brdf.albedo.x, brdf.albedo.y), brdf.albedo.z);
|
||||
if (payload.depth > 5)
|
||||
@@ -229,9 +230,9 @@ kernel void computeKernel(
|
||||
shadowRay.max_distance = INFINITY;
|
||||
i.accept_any_intersection(true);
|
||||
intersection = i.intersect(shadowRay, accelerationStructure, 0xff);
|
||||
if(intersection.type != intersection_type::none)
|
||||
if(intersection.type == intersection_type::none)
|
||||
{
|
||||
payload.accumulatedRadiance += brdf.evaluate(info, -cam.direction, shadowRay.direction, directionalLights[l].color);
|
||||
payload.accumulatedRadiance += brdf.evaluate(info, -cam.direction, normalize(shadowRay.direction), directionalLights[l].color);
|
||||
}
|
||||
}
|
||||
for (uint l = 0; l < sample.numPointLights; ++l)
|
||||
@@ -243,7 +244,7 @@ kernel void computeKernel(
|
||||
shadowRay.max_distance = 1;
|
||||
i.accept_any_intersection(true);
|
||||
intersection = i.intersect(shadowRay, accelerationStructure, 0xff);
|
||||
if (intersection.type != intersection_type::none)
|
||||
if (intersection.type == intersection_type::none)
|
||||
{
|
||||
float d = length(lightDir);
|
||||
float illuminance = max(1 - d / pointLights[l].attenuation, 0.0f);
|
||||
@@ -267,7 +268,11 @@ kernel void computeKernel(
|
||||
payload.depth++;
|
||||
}
|
||||
float resolver = float(sample.samplesPerPixel) / float(sample.pass+1);
|
||||
float4 previous = accumulator.read(threadId);
|
||||
float4 previous = float4(0);
|
||||
if(sample.pass != 0)
|
||||
{
|
||||
previous = accumulator.read(threadId);
|
||||
}
|
||||
float4 result = previous + float4(payload.accumulatedRadiance / float(sample.samplesPerPixel), 0);
|
||||
accumulator.write(result, threadId);
|
||||
image.write(pow(max(result * resolver, 0), float4(0.45f)), threadId);
|
||||
|
||||
+99
-73
@@ -14,11 +14,10 @@ id<CAMetalDrawable> drawable;
|
||||
id<MTLDevice> device;
|
||||
id<MTLLibrary> library;
|
||||
id<MTLCommandQueue> queue;
|
||||
id<MTLCommandQueue> renderQueue;
|
||||
id<MTLFunction> function;
|
||||
id<MTLComputePipelineState> computePipeline;
|
||||
id<MTLTexture> accumulator;
|
||||
id<MTLTexture> resultTexture;
|
||||
id<MTLTexture> accumulator = nullptr;
|
||||
id<MTLTexture> resultTexture = nullptr;
|
||||
|
||||
MTLRenderPassDescriptor* renderPass;
|
||||
id<MTLRenderCommandEncoder> renderEncoder;
|
||||
@@ -38,20 +37,19 @@ MetalRenderer::MetalRenderer()
|
||||
library = [device newDefaultLibrary];
|
||||
|
||||
queue = [device newCommandQueue];
|
||||
renderQueue = [device newCommandQueue];
|
||||
|
||||
scene = new MetalScene(device, queue);
|
||||
|
||||
function = [library newFunctionWithName:@"computeKernel"];
|
||||
function = [library newFunctionWithName:@"computeKernel"];
|
||||
|
||||
NSError* error;
|
||||
computePipeline = [device newComputePipelineStateWithFunction:function error:&error];
|
||||
computePipeline = [device newComputePipelineStateWithFunction:function error:&error];
|
||||
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
glfwSetErrorCallback(glfw_error_callback);
|
||||
glfwInit();
|
||||
float xscale = 1, yscale = 1;
|
||||
@@ -59,29 +57,32 @@ MetalRenderer::MetalRenderer()
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
handle = glfwCreateWindow(width / xscale, height / yscale, "RayTracer", nullptr, nullptr);
|
||||
|
||||
|
||||
ImGui_ImplGlfw_InitForOpenGL(handle, false);
|
||||
ImGui_ImplGlfw_InitForOpenGL(handle, true);
|
||||
ImGui_ImplMetal_Init(device);
|
||||
|
||||
NSWindow* cocoaWindow = glfwGetCocoaWindow(handle);
|
||||
metalLayer = [CAMetalLayer layer];
|
||||
metalLayer.device = device;
|
||||
metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
|
||||
[[cocoaWindow contentView] setLayer:metalLayer];
|
||||
[[cocoaWindow contentView] setWantsLayer:true];
|
||||
renderPass = [[MTLRenderPassDescriptor alloc] init];
|
||||
[[cocoaWindow contentView] setLayer:metalLayer];
|
||||
[[cocoaWindow contentView] setWantsLayer:true];
|
||||
renderPass = [[MTLRenderPassDescriptor alloc] init];
|
||||
|
||||
MTLRenderPipelineDescriptor *renderDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
|
||||
MTLRenderPipelineDescriptor *renderDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
|
||||
|
||||
renderDescriptor.vertexFunction = [library newFunctionWithName:@"copyVertex"];
|
||||
renderDescriptor.fragmentFunction = [library newFunctionWithName:@"copyFragment"];
|
||||
renderDescriptor.vertexFunction = [library newFunctionWithName:@"copyVertex"];
|
||||
renderDescriptor.fragmentFunction = [library newFunctionWithName:@"copyFragment"];
|
||||
|
||||
renderDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
|
||||
renderDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
|
||||
|
||||
pipelineState = [device newRenderPipelineStateWithDescriptor:renderDescriptor error:&error];
|
||||
pipelineState = [device newRenderPipelineStateWithDescriptor:renderDescriptor error:&error];
|
||||
|
||||
[renderDescriptor release];
|
||||
}
|
||||
|
||||
MetalRenderer::~MetalRenderer() {}
|
||||
MetalRenderer::~MetalRenderer() {
|
||||
[renderPass release];
|
||||
}
|
||||
|
||||
void MetalRenderer::addPointLight(PointLight point) { scene->addPointLight(point); }
|
||||
void MetalRenderer::addDirectionalLight(DirectionalLight dir) { scene->addDirectionalLight(dir); }
|
||||
@@ -91,14 +92,16 @@ void MetalRenderer::generate() { scene->generate(); }
|
||||
|
||||
void MetalRenderer::beginFrame()
|
||||
{
|
||||
glfwPollEvents();
|
||||
@autoreleasepool {
|
||||
|
||||
glfwPollEvents();
|
||||
int w, h;
|
||||
glfwGetFramebufferSize(handle, &w, &h);
|
||||
framebufferWidth = width;
|
||||
framebufferHeight = height;
|
||||
metalLayer.drawableSize = CGSizeMake(framebufferWidth, framebufferHeight);
|
||||
drawable = [metalLayer nextDrawable];
|
||||
renderCmd = [renderQueue commandBuffer];
|
||||
drawable = [metalLayer nextDrawable];
|
||||
renderCmd = [queue commandBuffer];
|
||||
renderPass.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 0);
|
||||
renderPass.colorAttachments[0].texture = drawable.texture;
|
||||
renderPass.colorAttachments[0].loadAction = MTLLoadActionClear;
|
||||
@@ -113,18 +116,25 @@ drawable = [metalLayer nextDrawable];
|
||||
|
||||
// Draw a quad which fills the screen.
|
||||
[renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6];
|
||||
|
||||
[renderEncoder retain];
|
||||
[renderCmd retain];
|
||||
[drawable retain];
|
||||
}
|
||||
}
|
||||
|
||||
void MetalRenderer::update()
|
||||
{
|
||||
@autoreleasepool {
|
||||
ImGui::Render();
|
||||
ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), renderCmd, renderEncoder);
|
||||
[renderEncoder endEncoding];
|
||||
[renderEncoder release];
|
||||
[renderCmd presentDrawable:drawable];
|
||||
[renderCmd commit];
|
||||
[renderCmd release];
|
||||
[renderEncoder release];
|
||||
[drawable release];
|
||||
[renderCmd release];
|
||||
[drawable release];
|
||||
}
|
||||
}
|
||||
|
||||
void MetalRenderer::render(Camera camera, RenderParameter parameter)
|
||||
@@ -140,6 +150,11 @@ void MetalRenderer::render(Camera camera, RenderParameter parameter)
|
||||
.height = parameter.height,
|
||||
};
|
||||
|
||||
if(accumulator != nullptr)
|
||||
{
|
||||
[accumulator release];
|
||||
[resultTexture release];
|
||||
}
|
||||
MTLTextureDescriptor* texDescriptor = [[MTLTextureDescriptor alloc] init];
|
||||
[texDescriptor setWidth:parameter.width];
|
||||
[texDescriptor setHeight:parameter.height];
|
||||
@@ -147,58 +162,69 @@ void MetalRenderer::render(Camera camera, RenderParameter parameter)
|
||||
[texDescriptor setUsage:MTLTextureUsageShaderWrite | MTLTextureUsageShaderRead];
|
||||
accumulator = [device newTextureWithDescriptor:texDescriptor];
|
||||
resultTexture = [device newTextureWithDescriptor:texDescriptor];
|
||||
[texDescriptor release];
|
||||
for (uint i = 0; i < parameter.numSamples; ++i)
|
||||
{
|
||||
id<MTLCommandBuffer> cmdBuffer = [queue commandBuffer];
|
||||
id<MTLComputeCommandEncoder> encoder = [cmdBuffer computeCommandEncoder];
|
||||
// cmdBuffer->addCompletedHandler([this](MTL::CommandBuffer* cmdBuffer)
|
||||
// { std::memcpy(image.data(), resultTexture->buffer(), image.size() * sizeof(glm::vec3)); });
|
||||
if(!running)
|
||||
return;
|
||||
@autoreleasepool{
|
||||
id<MTLCommandBuffer> cmdBuffer = [queue commandBuffer];
|
||||
id<MTLComputeCommandEncoder> encoder = [cmdBuffer computeCommandEncoder];
|
||||
// cmdBuffer->addCompletedHandler([this](MTL::CommandBuffer* cmdBuffer)
|
||||
// { std::memcpy(image.data(), resultTexture->buffer(), image.size() * sizeof(glm::vec3)); });
|
||||
|
||||
SampleParams sample = {
|
||||
.pass = i,
|
||||
.samplesPerPixel = parameter.numSamples,
|
||||
.numDirectionalLights = scene->getNumDirLights(),
|
||||
.numPointLights = scene->getNumPointLights(),
|
||||
.pass = i,
|
||||
.samplesPerPixel = parameter.numSamples,
|
||||
.numDirectionalLights = scene->getNumDirLights(),
|
||||
.numPointLights = scene->getNumPointLights(),
|
||||
};
|
||||
[encoder setComputePipelineState:computePipeline];
|
||||
[encoder setBuffer:scene->indicesBuffer offset:0 atIndex:0];
|
||||
[encoder setBuffer:scene->positionBuffer offset:0 atIndex:1];
|
||||
[encoder setBuffer:scene->texCoordsBuffer offset:0 atIndex:2];
|
||||
[encoder setBuffer:scene->normalBuffer offset:0 atIndex:3];
|
||||
[encoder setBuffer:scene->modelRefsBuffer offset:0 atIndex:4];
|
||||
[encoder setBuffer:scene->directionalLightBuffer offset:0 atIndex:5];
|
||||
[encoder setBuffer:scene->pointLightBuffer offset:0 atIndex:6];
|
||||
[encoder setBuffer:scene->instanceBuffer offset:0 atIndex:7];
|
||||
[encoder setAccelerationStructure:scene->accelerationStructure atBufferIndex:8];
|
||||
[encoder setTexture:accumulator atIndex:0];
|
||||
[encoder setTexture:resultTexture atIndex:1];
|
||||
[encoder setBytes:&gpuCam length:sizeof(GPUCamera) atIndex:9];
|
||||
[encoder setBytes:&sample length:sizeof(SampleParams) atIndex:10];
|
||||
[encoder useResource:scene->instanceBuffer usage:MTLResourceUsageRead];
|
||||
[encoder useResource:scene->positionBuffer usage:MTLResourceUsageRead];
|
||||
[encoder useResource:scene->texCoordsBuffer usage:MTLResourceUsageRead];
|
||||
[encoder useResource:scene->normalBuffer usage:MTLResourceUsageRead];
|
||||
[encoder useResource:scene->modelRefsBuffer usage:MTLResourceUsageRead];
|
||||
if (scene->getNumDirLights() > 0)
|
||||
{
|
||||
[encoder useResource:scene->directionalLightBuffer usage:MTLResourceUsageRead];
|
||||
}
|
||||
if (scene->getNumPointLights() > 0)
|
||||
{
|
||||
[encoder setComputePipelineState:computePipeline];
|
||||
[encoder setBuffer:scene->indicesBuffer offset:0 atIndex:0];
|
||||
[encoder setBuffer:scene->positionBuffer offset:0 atIndex:1];
|
||||
[encoder setBuffer:scene->texCoordsBuffer offset:0 atIndex:2];
|
||||
[encoder setBuffer:scene->normalBuffer offset:0 atIndex:3];
|
||||
[encoder setBuffer:scene->modelRefsBuffer offset:0 atIndex:4];
|
||||
[encoder setBuffer:scene->directionalLightBuffer offset:0 atIndex:6];
|
||||
[encoder setBuffer:scene->pointLightBuffer offset:0 atIndex:7];
|
||||
[encoder setBuffer:scene->instanceBuffer offset:0 atIndex:8];
|
||||
[encoder setAccelerationStructure:scene->accelerationStructure atBufferIndex:9];
|
||||
[encoder setTexture:accumulator atIndex:0];
|
||||
[encoder setTexture:resultTexture atIndex:1];
|
||||
[encoder setBytes:&gpuCam length:sizeof(GPUCamera) atIndex:10];
|
||||
[encoder setBytes:&sample length:sizeof(SampleParams) atIndex:11];
|
||||
[encoder useResource:scene->instanceBuffer usage:MTLResourceUsageRead];
|
||||
[encoder useResource:scene->positionBuffer usage:MTLResourceUsageRead];
|
||||
[encoder useResource:scene->texCoordsBuffer usage:MTLResourceUsageRead];
|
||||
[encoder useResource:scene->normalBuffer usage:MTLResourceUsageRead];
|
||||
[encoder useResource:scene->modelRefsBuffer usage:MTLResourceUsageRead];
|
||||
if (scene->getNumDirLights() > 0)
|
||||
{
|
||||
[encoder useResource:scene->directionalLightBuffer usage:MTLResourceUsageRead];
|
||||
}
|
||||
if (scene->getNumPointLights() > 0)
|
||||
{
|
||||
[encoder useResource:scene->pointLightBuffer usage:MTLResourceUsageRead];
|
||||
}
|
||||
[encoder useResource:scene->instanceBuffer usage:MTLResourceUsageRead];
|
||||
[encoder useResource:scene->accelerationStructure usage:MTLResourceUsageRead];
|
||||
[encoder useResource:accumulator usage:MTLResourceUsageWrite];
|
||||
[encoder useResource:resultTexture usage:MTLResourceUsageWrite];
|
||||
NSUInteger width = (NSUInteger)parameter.width;
|
||||
NSUInteger height = (NSUInteger)parameter.height;
|
||||
MTLSize threadsPerThreadgroup = MTLSizeMake(8, 8, 1);
|
||||
MTLSize threadgroups = MTLSizeMake((width + threadsPerThreadgroup.width - 1) / threadsPerThreadgroup.width,
|
||||
(height + threadsPerThreadgroup.height - 1) / threadsPerThreadgroup.height, 1);
|
||||
[encoder dispatchThreadgroups:threadgroups threadsPerThreadgroup:threadsPerThreadgroup];
|
||||
[encoder endEncoding];
|
||||
[cmdBuffer commit];
|
||||
[cmdBuffer addCompletedHandler:^(id<MTLCommandBuffer> _Nonnull cmd) {
|
||||
sampleTimes.push_back((cmd.GPUEndTime - cmd.GPUStartTime) * 1000.f);
|
||||
if(sampleTimes.size() > 200)
|
||||
{
|
||||
sampleTimes.erase(sampleTimes.begin());
|
||||
}
|
||||
}];
|
||||
}
|
||||
[encoder useResource:scene->instanceBuffer usage:MTLResourceUsageRead];
|
||||
[encoder useResource:scene->accelerationStructure usage:MTLResourceUsageRead];
|
||||
[encoder useResource:accumulator usage:MTLResourceUsageWrite];
|
||||
[encoder useResource:resultTexture usage:MTLResourceUsageWrite];
|
||||
NSUInteger width = (NSUInteger)parameter.width;
|
||||
NSUInteger height = (NSUInteger)parameter.height;
|
||||
MTLSize threadsPerThreadgroup = MTLSizeMake(8, 8, 1);
|
||||
MTLSize threadgroups = MTLSizeMake((width + threadsPerThreadgroup.width - 1) / threadsPerThreadgroup.width,
|
||||
(height + threadsPerThreadgroup.height - 1) / threadsPerThreadgroup.height, 1);
|
||||
[encoder dispatchThreadgroups:threadgroups threadsPerThreadgroup:threadsPerThreadgroup];
|
||||
[encoder endEncoding];
|
||||
[cmdBuffer commit];
|
||||
sampleTimes.push_back(0);
|
||||
}
|
||||
}
|
||||
|
||||
+16
-15
@@ -6,24 +6,25 @@
|
||||
class MetalScene : public Scene
|
||||
{
|
||||
public:
|
||||
MetalScene(id<MTLDevice> device, id<MTLCommandQueue> queue);
|
||||
virtual ~MetalScene();
|
||||
MetalScene(id<MTLDevice> device, id<MTLCommandQueue> queue);
|
||||
virtual ~MetalScene();
|
||||
|
||||
virtual void createRayTracingHierarchy() override;
|
||||
virtual void createRayTracingHierarchy() override;
|
||||
|
||||
id<MTLAccelerationStructure> newAccelerationStructureWithDescriptor(MTLAccelerationStructureDescriptor* descriptor);
|
||||
id<MTLAccelerationStructure> newAccelerationStructureWithDescriptor(MTLAccelerationStructureDescriptor* descriptor);
|
||||
|
||||
id<MTLDevice> device;
|
||||
id<MTLCommandQueue> queue;
|
||||
id<MTLDevice> device;
|
||||
id<MTLCommandQueue> queue;
|
||||
|
||||
id<MTLBuffer> indicesBuffer;
|
||||
id<MTLBuffer> positionBuffer;
|
||||
id<MTLBuffer> texCoordsBuffer;
|
||||
id<MTLBuffer> normalBuffer;
|
||||
id<MTLBuffer> modelRefsBuffer;
|
||||
id<MTLBuffer> directionalLightBuffer;
|
||||
id<MTLBuffer> pointLightBuffer;
|
||||
id<MTLBuffer> instanceBuffer;
|
||||
id<MTLBuffer> indicesBuffer;
|
||||
id<MTLBuffer> positionBuffer;
|
||||
id<MTLBuffer> texCoordsBuffer;
|
||||
id<MTLBuffer> normalBuffer;
|
||||
id<MTLBuffer> modelRefsBuffer;
|
||||
id<MTLBuffer> materialsBuffer;
|
||||
id<MTLBuffer> directionalLightBuffer;
|
||||
id<MTLBuffer> pointLightBuffer;
|
||||
id<MTLBuffer> instanceBuffer;
|
||||
|
||||
id<MTLAccelerationStructure> accelerationStructure;
|
||||
id<MTLAccelerationStructure> accelerationStructure;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user