#ifndef MATERIAL #define MATERIAL #include "utils.hlsl" struct Material { float3 color; float roughness; // refraction attenuation, w = 0 -> not reflective/transmissive, w = 0.5 -> reflective, w = 1 -> reflective and transmissive float4 attenuation; float eta; float3 emissive; float metallic; }; static Material material; void setMaterial(Material objectMaterial) { material = objectMaterial; } void setMaterial(bool evaluateMaterial, Material objectMaterial) { if (evaluateMaterial) setMaterial(objectMaterial); } void minMaterial(inout float currentDistance, float objectDistance, bool evaluateMaterial, Material objectMaterial) { if (objectDistance < currentDistance) { currentDistance = objectDistance; if (evaluateMaterial) { setMaterial(objectMaterial); } } } void maxMaterial(inout float currentDistance, float objectDistance, bool evaluateMaterial, Material objectMaterial) { if (objectDistance > currentDistance) { currentDistance = objectDistance; if (evaluateMaterial) { setMaterial(objectMaterial); } } } void minMaterialTransmissive(inout float currentDistance, float objectDistance, bool evaluateMaterial, Material objectMaterial) { minMaterial(currentDistance, abs(objectDistance), evaluateMaterial, objectMaterial); currentDistance *= objectDistance < 0 ? -1 : +1; } bool isReflectiveMaterial(Material m) { return m.attenuation.w >= 0.5; } bool isRefractiveMaterial(Material m) { return m.attenuation.w == 1; } Material makeSpecularMaterial(float3 color) { Material m; m.color = color; m.metallic = 0.0; m.roughness = 0.0; m.emissive = 0.0; m.attenuation = 0.0; return m; } Material makeDiffuseMaterial(float3 color) { Material m; m.color = color; m.metallic = 0.0; m.roughness = 1.0; m.emissive = 0.0; m.attenuation = 0.0; return m; } Material makeEmissiveMaterial(float3 emissive) { Material m; m.color = 0; m.metallic = 0; m.roughness = 0; m.emissive = emissive; m.attenuation = 0.0; return m; } Material makeWaterMaterial(float3 attenuation, float eta = 1.1, float roughness = 0.3) { Material m; m.color = 0.3; m.emissive = 0; m.metallic = 1; m.roughness = roughness; m.attenuation = float4(attenuation, 1); m.eta = eta; return m; } Material makeStrangeMaterial(float3 p, int seed) { float3 p1 = p + (0.009999999776 * fpn(p*1114.949951)); float3 p2 = p1 + (0.05000000075 * fpn(p1*228.9993286)); float3 p3 = p2 + (13.84500122 * fpn(p2*12.5)); float black = fpn(p3*16.49999237) * 0.5 + 0.5; const float3 colors[3] = { float3(1,0.2,0.0), float3(0.5,0.8,0.1), float3(1.0,1.0,1.0) }; float3 color = lerp( colors[(2+seed)%3], lerp( colors[(0+seed)%3], colors[(1+seed)%3], fpn((p3+p2)*15) * 0.5 + 0.5 ), fpn(p3*10) * 0.5 + 0.5 ); Material marble; marble.emissive = 0; marble.color = color * black; marble.metallic = 1.0; marble.roughness = saturate(black * -0.55 + 0.5); marble.attenuation = float4(3 * saturate(1 - color), 1); marble.eta = 1.2; return marble; } Material makeMarbleMaterial(float3 p, int seed) { float3 p1 = p + (0.009999999776 * fpn(p*1114.949951)); float3 p2 = p1 + (0.05000000075 * fpn(p1*228.9993286)); float3 p3 = p2 + (13.84500122 * fpn(p2*12.5)); float black = fpn(p3*16.49999237) * 0.5 + 0.5; const float3 colors[3] = { float3(1,0.2,0.0), float3(0.5,0.8,0.1), float3(1.0,1.0,1.0) }; float3 color = lerp( colors[(2+seed)%3], lerp( colors[(0+seed)%3], colors[(1+seed)%3], fpn((p3+p2)*15) * 0.5 + 0.5 ), fpn(p3*10) * 0.5 + 0.5 ); Material marble; marble.emissive = 0; marble.color = color * black; marble.metallic = 0; marble.roughness = saturate(black * -0.55 + 0.5); marble.attenuation = 0; return marble; } Material makeErrorTestMaterial(float3 p) { int seed = 0; float3 p1 = p + (0.009999999776 * fpn(p*1114.949951)); float3 p2 = p1 + (0.05000000075 * fpn(p1*228.9993286)); float3 p3 = p2 + (13.84500122 * fpn(p2*12.5)); float black = fpn(p3*16.49999237) * 0.5 + 0.5; const float3 colors[3] = { float3(1,0.2,0.0), float3(0.5,0.8,0.1), float3(1.0,1.0,1.0) }; float3 color = lerp( colors[(2+seed)%3], lerp( colors[(0+seed)%3], colors[(1+seed)%3], fpn((p3+p2)*15) * 0.5 + 0.5 ), fpn(p3*10) * 0.5 + 0.5 ); Material marble; marble.emissive = 0; marble.color = sin(p.z)*0.5 + 0.5;//color * black; marble.metallic = 0; marble.roughness = 0.3;//saturate(black * -0.55 + 0.5); marble.attenuation = 0; return marble; } #endif