View source
class DefaultForward
package h3d.shader.pbr
extends Shader
@:directlyUsed@:src({ @:import h3d.shader.pbr.Light.LightEvaluation; @:import h3d.shader.pbr.BDRF; var output:{ var color : Vec4; var metalness : Float; var roughness : Float; var occlusion : Float; var emissive : Float}; @const(256) var BUFFER_SIZE:Int = 1; @param var lightInfos:Buffer<Vec4,BUFFER_SIZE>; @param var dirLightCount:Int; @param var pointLightCount:Int; @param var spotLightCount:Int; @param var dirLightStride:Int; @param var pointLightStride:Int; @param var cameraPosition:Vec3; @param var emissivePower:Float; var albedoGamma:Vec3; var view:Vec3; var NdV:Float; var pbrSpecularColor:Vec3; var metalness:Float; var roughness:Float; var occlusion:Float; var emissive:Float; var F0:Vec3; @const var USE_INDIRECT = false; @param var irrLut:Sampler2D; @param var irrDiffuse:SamplerCube; @param var irrSpecular:SamplerCube; @param var irrSpecularLevels:Float; @param var irrPower:Float; @param var irrRotation:Vec2; var transformedNormal:Vec3; var transformedPosition:Vec3; var pixelColor:Vec4; function rotateNormal(n:Vec3):Vec3 { return vec3(n.x * irrRotation.x - n.y * irrRotation.y, n.x * irrRotation.y + n.y * irrRotation.x, n.z); }; function indirectLighting():Vec3 { var F = F0 + (max(vec3(1 - roughness), F0) - F0) * exp2((-5.55473 * NdV - 6.98316) * NdV); var rotatedNormal = rotateNormal(transformedNormal); var diffuse = irrDiffuse.get(rotatedNormal).rgb * albedoGamma; var reflectVec = reflect(-view, transformedNormal); var rotatedReflecVec = rotateNormal(reflectVec); var envSpec = textureLod(irrSpecular, rotatedReflecVec, roughness * irrSpecularLevels).rgb; var envBRDF = irrLut.get(vec2(roughness, NdV)); var specular = envSpec * (F * envBRDF.x + envBRDF.y); var indirect = (diffuse * (1 - metalness) * (1 - F) + specular) * irrPower; return indirect * occlusion; }; function directLighting(lightColor:Vec3, lightDirection:Vec3):Vec3 { var result = vec3(0); var NdL = clamp(transformedNormal.dot(lightDirection), 0.0, 1.0); if (lightColor.dot(lightColor) > 0.0001 && NdL > 0) { var half = (lightDirection + view).normalize(); var NdH = clamp(transformedNormal.dot(half), 0.0, 1.0); var VdH = clamp(view.dot(half), 0.0, 1.0); var diffuse = albedoGamma / PI; var D = normalDistributionGGX(NdH, roughness); var F = fresnelSchlick(VdH, F0); var G = geometrySchlickGGX(NdV, NdL, roughness); var specular = (D * F * G).max(0.); result = (diffuse * (1 - metalness) * (1 - F) + specular) * lightColor * NdL; }; return result; }; function __init__fragment() { pbrSpecularColor = vec3(0.04); albedoGamma = pixelColor.rgb * pixelColor.rgb; }; function init() { view = (cameraPosition - transformedPosition).normalize(); NdV = transformedNormal.dot(view).max(0.); }; function evaluateDirLight(index:Int):Vec3 { var i = index * 5; var lightColor = lightInfos[i].rgb; var lightDir = lightInfos[i + 1].xyz; var hasShadowMap = lightInfos[i].a > 0; var shadow = 1.0; return directLighting(lightColor, lightDir) * shadow; }; function evaluatePointLight(index:Int):Vec3 { var i = index * 3 + dirLightStride; var lightColor = lightInfos[i].rgb; var size = lightInfos[i].a; var lightPos = lightInfos[i + 1].rgb; var invRange4 = lightInfos[i + 1].a; var range = lightInfos[i + 2].r; var hasShadowMap = lightInfos[i + 2].g > 0; var delta = lightPos - transformedPosition; var shadow = 1.0; return directLighting(pointLightIntensity(delta, size, invRange4) * lightColor, delta.normalize()) * shadow; }; function evaluateSpotLight(index:Int):Vec3 { var i = index * 8 + dirLightStride + pointLightStride; var lightColor = lightInfos[i].rgb; var range = lightInfos[i].a; var lightPos = lightInfos[i + 1].xyz; var invRange4 = lightInfos[i + 1].a; var lightDir = lightInfos[i + 2].xyz; var angle = lightInfos[i + 3].r; var fallOff = lightInfos[i + 3].g; var hasShadowMap = lightInfos[i + 3].b > 0; var delta = lightPos - transformedPosition; var shadow = 1.0; var fallOffInfo = spotLightIntensity(delta, lightDir, range, invRange4, fallOff, angle); var fallOff = fallOffInfo.x; var fallOffInfoAngle = fallOffInfo.y; return directLighting(fallOff * lightColor * fallOffInfoAngle, delta.normalize()) * shadow; }; function evaluateLighting():Vec3 { var lightAccumulation = vec3(0); F0 = mix(pbrSpecularColor, albedoGamma, metalness); @unroll for (l in 0 ... dirLightCount) lightAccumulation += evaluateDirLight(l); @unroll for (l in 0 ... pointLightCount) lightAccumulation += evaluatePointLight(l); @unroll for (l in 0 ... spotLightCount) lightAccumulation += evaluateSpotLight(l); if (USE_INDIRECT) lightAccumulation += indirectLighting(); lightAccumulation += emissive * emissivePower; return lightAccumulation; }; function fragment() { init(); output.color = vec4(evaluateLighting(), pixelColor.a); }; })@: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.