View source
class ComputeIndirect
package h3d.scene
extends Shader
import h3d.scene.MeshBatch
@:directlyUsed@:src({ @global var camera:{ var position : Vec3}; @const var ENABLE_COUNT_BUFFER:Bool; @param var countBuffer:RWBuffer<Int>; @param var instanceOffsets:RWBuffer<Int>; @param var commandBuffer:RWBuffer<Int>; @param var instanceData:RWPartialBuffer<{ var modelView : Mat4}>; @param var radius:Float; @const var USING_SUB_PART:Bool = false; @const var MAX_SUB_PART_BUFFER_ELEMENT_COUNT:Int = 16; @param var subPartCount:Int; @param var startInstanceOffset:Int; @param var subPartInfos:Buffer<Vec4,MAX_SUB_PART_BUFFER_ELEMENT_COUNT>; @const var MAX_MATERIAL_COUNT:Int = 16; @param var materialCount:Int; @param var matIndex:Int; @param var matInfos:Buffer<Vec4,MAX_MATERIAL_COUNT>; @const var ENABLE_CULLING:Bool; @param var frustum:Buffer<Vec4,6>; @const var ENABLE_LOD:Bool; @param var lodCount:Int = 1; @const var ENABLE_DISTANCE_CLIPPING:Bool; @param var maxDistance:Float = -1; var modelView:Mat4; function __init__() { modelView = instanceData[computeVar.globalInvocation.x].modelView; }; function main() { var invocID = computeVar.globalInvocation.x; var lod:Int = 0; var pos = vec3(0) * modelView.mat3x4(); var vScale = abs(vec3(1) * modelView.mat3x4() - pos); var scaledRadius = max(max(vScale.x, vScale.y), vScale.z); var toCam = camera.position - pos.xyz; var distToCam = length(toCam); var radius = radius; var matOffset = matIndex * lodCount; var lodCount = lodCount; if (USING_SUB_PART) { var id = (invocID + startInstanceOffset) * 2; matOffset = instanceOffsets[id]; var subPartID = instanceOffsets[id + 1]; var subPartInfo = subPartInfos[subPartID / 2]; var packedID = (subPartID & 1) << 1; lodCount = int(subPartInfo[packedID]); radius = subPartInfo[packedID + 1]; }; scaledRadius *= radius; var culled = false; if (dot(scaledRadius, scaledRadius) < 1e-6) culled = true; if (ENABLE_CULLING) { for (i in 0 ... 6) { var plane = frustum[i]; if (plane.x * pos.x + plane.y * pos.y + plane.z * pos.z - plane.w < -scaledRadius) { culled = true; break; }; }; }; if (ENABLE_DISTANCE_CLIPPING) { culled = culled || distToCam > maxDistance + scaledRadius; }; if (ENABLE_LOD) { var screenRatio = scaledRadius / distToCam; screenRatio = screenRatio * screenRatio; for (i in 0 ... lodCount) { var minScreenRatio = matInfos[i + matOffset].z; if (screenRatio > minScreenRatio) break; lod++; }; lod = clamp(lod, 0, int(lodCount) - 1); }; var matInfo = ivec4(0.0); if (!culled) { matInfo = ivec4(matInfos[lod + matOffset]); culled = culled || matInfo.x <= 0; }; if (ENABLE_COUNT_BUFFER) { if (!culled) { var id = atomicAdd(countBuffer, 0, 1); commandBuffer[id * 5] = matInfo.x; commandBuffer[id * 5 + 1] = 1; commandBuffer[id * 5 + 2] = matInfo.y; commandBuffer[id * 5 + 3] = 0; commandBuffer[id * 5 + 4] = invocID; }; } else { if (!culled) { commandBuffer[invocID * 5] = matInfo.x; commandBuffer[invocID * 5 + 1] = 1; commandBuffer[invocID * 5 + 2] = matInfo.y; commandBuffer[invocID * 5 + 3] = 0; commandBuffer[invocID * 5 + 4] = invocID; } else { commandBuffer[invocID * 5] = 0; commandBuffer[invocID * 5 + 1] = 0; commandBuffer[invocID * 5 + 2] = 0; commandBuffer[invocID * 5 + 3] = 0; commandBuffer[invocID * 5 + 4] = 0; }; }; }; })@:build(hxsl.Macros.buildShader())@:autoBuild(hxsl.Macros.buildShader())Constructor
Variables
Methods
Inherited Variables
Inherited Methods
Defined by Shader
setPriority(v:Int):Void
Shader priority should only be changed before the shader is added to a material.