Extend BRDF

This commit is contained in:
2026-07-27 12:10:11 -07:00
parent 0b4184ccc2
commit 7aeebf2008
24 changed files with 878 additions and 3 deletions

View File

@ -71,6 +71,11 @@ class Scene {
public var embedded: Map<String, kha.Image>;
#if (rp_renderer == "Deferred")
public var materialParamsBuffer: kha.arrays.Float32Array;
public var materialParamsDirty: Bool = true;
#end
public var ready: Bool; // Async in progress
public var traitInits: Array<Void->Void> = [];
@ -107,6 +112,9 @@ class Scene {
armatures = [];
#end
embedded = new Map();
#if (rp_renderer == "Deferred")
materialParamsBuffer = new kha.arrays.Float32Array(512);
#end
root = new Object();
root.name = "Root";
traitInits = [];
@ -204,6 +212,77 @@ class Scene {
root.remove();
}
#if (rp_renderer == "Deferred")
public function updateMaterialParams() {
if (!materialParamsDirty) return;
materialParamsDirty = false;
var buf = materialParamsBuffer;
for (i in 0...buf.length) buf[i] = 0.0;
for (m in meshes) {
if (m.materials == null) continue;
for (mat in m.materials) {
if (mat == null) continue;
if (mat.contexts == null) continue;
var slot = -1;
var bc = null;
for (ctx in mat.contexts) {
if (ctx == null || ctx.raw == null) continue;
if (ctx.raw.name == "mesh" && ctx.raw.bind_constants != null) {
bc = ctx.raw.bind_constants;
for (c in bc) {
if (c != null && c.name == "materialID" && c.intValue != null) {
slot = c.intValue;
}
}
break;
}
}
if (slot <= 0 || slot >= 16) continue;
var base = slot * 32;
if (base + 31 >= buf.length) continue;
if (bc == null) continue;
for (c in bc) {
if (c == null || c.name == null) continue;
switch (c.name) {
// matp0: vec4(anisotropy, anisoRot, sheen, sheenRough)
case "anisotropy": buf[base + 0] = c.floatValue;
case "anisoRot": buf[base + 1] = c.floatValue;
case "sheen": buf[base + 2] = c.floatValue;
case "sheenRough": buf[base + 3] = c.floatValue;
// matp1: vec4(clearcoat, clearcoatRough, coatIOR, coatTintR)
case "clearcoat": buf[base + 4] = c.floatValue;
case "clearcoatRough": buf[base + 5] = c.floatValue;
case "coatIOR": buf[base + 6] = c.floatValue;
case "coatTintR": buf[base + 7] = c.floatValue;
// matp2: vec4(coatTintG, coatTintB, transmission, transRough)
case "coatTintG": buf[base + 8] = c.floatValue;
case "coatTintB": buf[base + 9] = c.floatValue;
case "transmission": buf[base + 10] = c.floatValue;
case "transmissionRough": buf[base + 11] = c.floatValue;
// matp3: vec4(ior, thinWall, subsurface, subsurfaceAnisotropy)
case "ior": buf[base + 12] = c.floatValue;
case "thinWall": buf[base + 13] = c.floatValue;
case "subsurface": buf[base + 14] = c.floatValue;
case "subsurfaceAnisotropy": buf[base + 15] = c.floatValue;
// matp4: vec4(subsurfaceRadiusR, subsurfaceRadiusG, subsurfaceRadiusB, subsurfaceColorR)
case "subsurfaceRadiusR": buf[base + 16] = c.floatValue;
case "subsurfaceRadiusG": buf[base + 17] = c.floatValue;
case "subsurfaceRadiusB": buf[base + 18] = c.floatValue;
case "subsurfaceColorR": buf[base + 19] = c.floatValue;
// matp5: vec4(subsurfaceColorG, subsurfaceColorB, sheenTintR, sheenTintG)
case "subsurfaceColorG": buf[base + 20] = c.floatValue;
case "subsurfaceColorB": buf[base + 21] = c.floatValue;
case "sheenTintR": buf[base + 22] = c.floatValue;
case "sheenTintG": buf[base + 23] = c.floatValue;
// matp6: vec4(sheenTintB, 0, 0, 0)
case "sheenTintB": buf[base + 24] = c.floatValue;
}
}
}
}
}
#end
static var framePassed = true;
public static function setActive(sceneName: String, done: Object->Void = null) {
if (!framePassed) return;
@ -351,6 +430,9 @@ class Scene {
public function addMeshObject(data: MeshData, materials: Vector<MaterialData>, parent: Object = null): MeshObject {
var object = new MeshObject(data, materials);
parent != null ? object.setParent(parent) : object.setParent(root);
#if (rp_renderer == "Deferred")
materialParamsDirty = true;
#end
return object;
}

View File

@ -89,6 +89,9 @@ class MeshObject extends Object {
#end
if (tilesheet != null) tilesheet.remove();
if (Scene.active != null) Scene.active.meshes.remove(this);
#if (rp_renderer == "Deferred")
if (Scene.active != null) Scene.active.materialParamsDirty = true;
#end
data.refcount--;
super.remove();
}

View File

@ -887,6 +887,9 @@ class Uniforms {
case "_envmapIrradiance": {
fa = Scene.active.world == null ? WorldData.getEmptyIrradiance() : Scene.active.world.probe.irradiance;
}
case "_materialParams": {
fa = Scene.active.materialParamsBuffer;
}
#if lnx_clusters
case "_lightsArray": {
fa = LightObject.lightsArray;

View File

@ -26,7 +26,8 @@ class RenderPathDeferred {
"gbuffer1",
#if rp_gbuffer2 "gbuffer2", #end
#if rp_gbuffer_emission "gbuffer_emission", #end
#if (rp_ssrefr || lnx_voxelgi_refract) "gbuffer_refraction" #end
#if (rp_ssrefr || lnx_voxelgi_refract) "gbuffer_refraction", #end
#if lnx_anisotropy "gbuffer3" #end
]);
}
@ -173,6 +174,19 @@ class RenderPathDeferred {
}
#end
#if lnx_anisotropy
{
var t = new RenderTargetRaw();
t.name = "gbuffer3";
t.width = 0;
t.height = 0;
t.displayp = Inc.getDisplayp();
t.format = "RGBA64";
t.scale = Inc.getSuperSampling();
path.createRenderTarget(t);
}
#end
#if rp_material_solid
path.loadShader("shader_datas/deferred_light_solid/deferred_light");
#elseif rp_material_mobile
@ -566,6 +580,13 @@ class RenderPathDeferred {
}
#end
#if lnx_anisotropy
{
path.setTarget("gbuffer3");
path.clearTarget(0x00000000);
}
#end
RenderPathCreator.setTargetMeshes();
#if rp_dynres
@ -761,6 +782,10 @@ class RenderPathDeferred {
}
#end
#if lnx_anisotropy
path.bindTarget("gbuffer3", "gbuffer3");
#end
#if rp_ssao
{
if (leenkx.data.Config.raw.rp_ssao != false) {
@ -826,8 +851,10 @@ class RenderPathDeferred {
#if rp_material_solid
path.drawShader("shader_datas/deferred_light_solid/deferred_light");
#elseif rp_material_mobile
Scene.active.updateMaterialParams();
path.drawShader("shader_datas/deferred_light_mobile/deferred_light");
#else
Scene.active.updateMaterialParams();
voxelao_pass ?
path.drawShader("shader_datas/deferred_light/deferred_light_VoxelAOvar") :
path.drawShader("shader_datas/deferred_light/deferred_light");