Dispatch 没有 绑定GLOBAL set!!!修复renderer\pipeline\custom\NativeExecutor.cpp
void begin(const Dispatch& dispatch, RenderGraph::vertex_descriptor vertID) const {
std::ignore = vertID;
auto& programLib = *ctx.programLib;
CC_EXPECTS(dispatch.material);
CC_EXPECTS(dispatch.material->getPasses());
// get pass
auto& pass = *dispatch.material->getPasses()->at(static_cast<size_t>(dispatch.passID));
// get shader
auto& shader = *pass.getShaderVariant();
// get pso
auto* pso = programLib.getComputePipelineState(
pass.getDevice(), pass.getPhaseID(), pass.getProgram(), pass.getDefines(), nullptr);
CC_EXPECTS(pso);
// auto* perInstanceSet = ctx.perInstanceDescriptorSets.at(vertID);
// execution
ctx.cmdBuff->bindPipelineState(pso);
// 强制绑 GLOBAL set,从当前 node 的 PER_PASS 数据中取
{
const DescriptorSetKey pkey{vertID, UpdateFrequency::PER_PASS};
auto piter = ctx.ppl->nativeContext.graphNodeDescriptorSets.find(pkey);
if (piter != ctx.ppl->nativeContext.graphNodeDescriptorSets.end()) {
ctx.cmdBuff->bindDescriptorSet(
static_cast<uint32_t>(pipeline::SetIndex::GLOBAL), piter->second);
}
}
ctx.cmdBuff->bindDescriptorSet(
static_cast<uint32_t>(pipeline::SetIndex::MATERIAL), pass.getDescriptorSet());
// ctx.cmdBuff->bindDescriptorSet(
// static_cast<uint32_t>(pipeline::SetIndex::LOCAL), perInstanceSet);
ctx.cmdBuff->dispatch(gfx::DispatchInfo{
dispatch.threadGroupCountX,
dispatch.threadGroupCountY,
dispatch.threadGroupCountZ,
});
}
重新编译模拟器后 跟着文档抄一遍
private buildRayTracingComputePass(
camera: renderer.scene.Camera,
pipeline: rendering.Pipeline,
cameraConfigs: CameraConfigs,
) {
const rtMat = cameraConfigs.settings.rayTracingComputePass.rtMat;
if (!rtMat) return '';
const width = camera.window.width;
const height = camera.window.height;
const csOutput = 'rt_output';
if (!pipeline.containsResource(csOutput)) {
pipeline.addStorageTexture(csOutput,
gfx.Format.RGBA8,width, height,
rendering.ResourceResidency.MANAGED);
}else{
pipeline.updateStorageTexture(csOutput,
width, height,gfx.Format.RGBA8);
}
// compute pass
const cs = pipeline.addComputePass('user-ray-tracing');
cs.setMat4('projectInverse', camera.matProjInv);
cs.addStorageImage(csOutput, rendering.AccessType.WRITE, 'outputImage');
cs.addQueue()
.addDispatch(Math.ceil(width / 8), Math.ceil(height / 4), 1, rtMat);
return csOutput;
}
shader:
CCEffect %{
techniques:
- name: opaque
passes:
- compute: compute-main
pass: user-ray-tracing
}%
CCProgram compute-main %{
precision highp float;
precision mediump image2D;
layout(local_size_x = 8, local_size_y = 4, local_size_z = 1) in;
#pragma rate constants pass
uniform constants {
mat4 projectInverse;
};
#pragma rate outputImage pass
layout (rgba8) writeonly uniform image2D outputImage;
void main () {
vec3 spherePos = vec3(0, 0, -5);
vec3 lightPos = vec3(1, 1, -3);
vec3 camPos = vec3(0, 0, 0);
float sphereRadius = 1.0;
vec4 color = vec4(0, 0, 0, 0);
ivec2 screen = imageSize(outputImage);
ivec2 coords = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
vec2 uv = vec2(float(coords.x) / float(screen.x), float(coords.y) / float(screen.y));
vec4 ndc = vec4(uv * 2.0 - vec2(1.0), 1.0, 1.0);
vec4 pos = projectInverse * ndc;
vec3 camD = vec3(pos.xyz / pos.w);
vec3 rayL = normalize(camD - camPos);
vec3 dirS = spherePos - camPos;
vec3 rayS = normalize(dirS);
float lenS = length(dirS);
float dotLS = dot(rayL, rayS);
float angle = acos(dotLS);
float projDist = lenS * sin(angle);
if (projDist < sphereRadius) {
// intersection
vec3 rayI = rayL * (lenS * dotLS - sqrt(sphereRadius * sphereRadius - projDist * projDist));
vec3 N = normalize(rayI - dirS);
vec3 L = normalize(lightPos - rayI);
color = vec4(vec3(max(dot(N, L), 0.05)), 1.0);
}
imageStore(outputImage, coords, color);
}
}%
就能显示光追小球了:
