123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- package hrt.shader;
- class ComputeSH extends h3d.shader.ScreenShader {
- static var SRC = {
- @param var environment : SamplerCube;
- @param var width : Int;
- @param var cubeDir : Array<Mat3, 6>;
- @const var ORDER : Int;
- @param var PI = 3.1416;
- var shCoefL00 : Float;
- var shCoefL1n1: Float;
- var shCoefL10 : Float;
- var shCoefL11 : Float;
- var shCoefL2n2 : Float;
- var shCoefL2n1 : Float;
- var shCoefL20 : Float;
- var shCoefL21 : Float;
- var shCoefL22 : Float;
- var coefL00Final : Vec3;
- var coefL1n1Final: Vec3;
- var coefL10Final : Vec3;
- var coefL11Final : Vec3;
- var coefL2n2Final : Vec3;
- var coefL2n1Final : Vec3;
- var coefL20Final : Vec3;
- var coefL21Final : Vec3;
- var coefL22Final : Vec3;
- function vertex() {
- var position = vec3(input.position.x, input.position.y * flipY, 0);
- output.position = vec4(position, 1.0);
- }
- function evalSH( dir : Vec3 ) {
- if (ORDER >= 1){
- shCoefL00 = evalCoefL00(dir);
- }
- if (ORDER >= 2){
- shCoefL1n1 = evalCoefL1n1(dir);
- shCoefL10 = evalCoefL10(dir);
- shCoefL11 = evalCoefL11(dir);
- }
- if (ORDER >= 3){
- shCoefL2n2 = evalCoefL2n2(dir);
- shCoefL2n1 = evalCoefL2n1(dir);
- shCoefL20 = evalCoefL20(dir);
- shCoefL21 = evalCoefL21(dir);
- shCoefL22 = evalCoefL22(dir);
- }
- }
- function getDir( u : Float, v : Float, face : Int ) : Vec3 {
- var dir = vec3(u, v, 1) * cubeDir[face];
- return dir.normalize();
- }
- function evalCoefL00(dir: Vec3) : Float { return 0.282095; }
- function evalCoefL1n1(dir: Vec3) : Float { return -0.488603 * dir.y; }
- function evalCoefL10(dir: Vec3) : Float { return 0.488603 * dir.z; }
- function evalCoefL11(dir: Vec3) : Float { return -0.488603 * dir.x; }
- function evalCoefL2n2(dir: Vec3) : Float { return 1.092548 * dir.y * dir.x; }
- function evalCoefL2n1(dir: Vec3) : Float { return -1.092548 * dir.y * dir.z; }
- function evalCoefL20(dir: Vec3) : Float { return 0.315392 * (-dir.x * dir.x - dir.y * dir.y + 2.0 * dir.z * dir.z); }
- function evalCoefL21(dir: Vec3) : Float { return -1.092548 * dir.x * dir.z; }
- function evalCoefL22(dir: Vec3) : Float { return 0.546274 * (dir.x * dir.x - dir.y * dir.y); }
- var out : {
- position : Vec4,
- coefL00 : Vec3,
- coefL1n1: Vec3,
- coefL10 : Vec3,
- coefL11 : Vec3,
- coefL2n2 : Vec3,
- coefL2n1 : Vec3,
- coefL20 : Vec3,
- coefL21 : Vec3,
- coefL22 : Vec3,
- };
- function fragment() {
- if( ORDER >= 1 ) {
- coefL00Final = vec3(0);
- }
- if( ORDER >= 2 ) {
- coefL1n1Final = vec3(0);
- coefL10Final = vec3(0);
- coefL11Final = vec3(0);
- }
- if( ORDER >= 3 ) {
- coefL2n2Final = vec3(0);
- coefL2n1Final = vec3(0);
- coefL20Final = vec3(0);
- coefL21Final = vec3(0);
- coefL22Final = vec3(0);
- }
- var weightSum = 0.0;
- var fWidth : Float = width;
- var invWidth : Float = 1.0 / fWidth;
- for( f in 0...6 ) {
- for( u in 0...width ) {
- var fU : Float = (u / fWidth - 0.5) * 2.0;// Texture coordinate U in range [-1 to 1]
- fU *= fU;
- var uCoord = 2.0 * u * invWidth + invWidth;
- for( v in 0...width ) {
- var fV : Float = (v / fWidth - 0.5) * 2.0;// Texture coordinate V in range [-1 to 1]
- fV *= fV;
- var vCoord = 2.0 * v * invWidth + invWidth;
- var dir = getDir(uCoord, vCoord, f);// Get direction from center of cube texture to current texel
- var diffSolid = 4.0 / ((1.0 + fU + fV) * sqrt(1.0 + fU + fV)); // Scale factor depending on distance from center of the face
- weightSum += diffSolid;
- var flippedDir = vec3(dir.x, dir.y, -dir.z);
- var color : Vec3 = environment.get(-flippedDir).rgb;// Get color from texture
- evalSH(dir);// Calculate coefficients of spherical harmonics for current direction
- if( ORDER >= 1 ) {
- coefL00Final += shCoefL00 * color * diffSolid;
- }
- if( ORDER >= 2 ) {
- coefL1n1Final += shCoefL1n1 * color * diffSolid;
- coefL10Final += shCoefL10 * color * diffSolid;
- coefL11Final += shCoefL11 * color * diffSolid;
- }
- if( ORDER >= 3 ) {
- coefL2n2Final += shCoefL2n2 * color * diffSolid;
- coefL2n1Final += shCoefL2n1 * color * diffSolid;
- coefL20Final += shCoefL20 * color * diffSolid;
- coefL21Final += shCoefL21 * color * diffSolid;
- coefL22Final += shCoefL22 * color * diffSolid;
- }
- }
- }
- }
- // Final scale for coefficients
- var normProj = (4.0 * PI) / weightSum;
- if( ORDER >= 1 ) {
- out.coefL00 = coefL00Final * normProj;
- }
- if( ORDER >= 2 ) {
- out.coefL1n1 = coefL1n1Final * normProj;
- out.coefL10 = coefL10Final * normProj;
- out.coefL11 = coefL11Final * normProj;
- }
- if( ORDER >= 3 ) {
- out.coefL2n2 = coefL2n2Final * normProj;
- out.coefL2n1 = coefL2n1Final * normProj;
- out.coefL20 = coefL20Final * normProj;
- out.coefL21 = coefL21Final * normProj;
- out.coefL22 = coefL22Final * normProj;
- }
- }
- }
- }
|