CUDA_DEVICE_INL vector4 GGXShade()

in libraries/hvvr/raycaster/shading.h [84:161]


CUDA_DEVICE_INL vector4 GGXShade(uint32_t materialIndex,
                                 const InterpolatedVertex& vInterp,
                                 vector2 dUVdX,
                                 vector2 dUVdY,
                                 vector3 cameraPos,
                                 const SimpleMaterial* CUDA_RESTRICT materials,
                                 cudaTextureObject_t* textures,
                                 const LightingEnvironment& env) {
    SimpleMaterial material = materials[materialIndex];
    uint64_t temp = material.textureIDsAndShadingModel;

    vector3 normal = normalize(vInterp.normal);

    ShadingModel shadingModel = ShadingModel(temp & SimpleMaterial::textureMask);
    if (shadingModel == ShadingModel::emissive) {
        uint32_t emissiveTextureIndex = (temp >> SimpleMaterial::diffuseBitShift) & SimpleMaterial::textureMask;

        vector4 emissiveColor = material.emissive;
        if (emissiveTextureIndex != SimpleMaterial::badTextureIndex) {
            emissiveColor = ReadTexture(textures, emissiveTextureIndex, vInterp.uv, dUVdX, dUVdY);
        }

        return emissiveColor;
    } else { // Phong which is GGX...
        uint32_t diffuseTextureIndex = (temp >> SimpleMaterial::diffuseBitShift) & SimpleMaterial::textureMask;
        uint32_t specularTextureIndex = (temp >> SimpleMaterial::specularBitShift) & SimpleMaterial::textureMask;
        uint32_t glossyTextureIndex = (temp >> SimpleMaterial::glossyBitShift) & SimpleMaterial::textureMask;

        vector3 BaseColor = vector3(material.diffuse);
        if (diffuseTextureIndex != SimpleMaterial::badTextureIndex) {
            BaseColor = vector3(ReadTexture(textures, diffuseTextureIndex, vInterp.uv, dUVdX, dUVdY));
        }

        vector3 V = normalize(cameraPos - vInterp.pos);

        vector3 F0 = vector3(material.specular);
        if (specularTextureIndex != SimpleMaterial::badTextureIndex) {
            F0 = vector3(ReadTexture(textures, specularTextureIndex, vInterp.uv, dUVdX, dUVdY));
        }

        float roughness = 1.0 - material.glossiness;
        if (glossyTextureIndex != SimpleMaterial::badTextureIndex) {
            roughness = 1.0f - ReadTexture(textures, glossyTextureIndex, vInterp.uv, dUVdX, dUVdY).x;
        }

        vector3 radiance = vector3(material.emissive);

        // ambient
        radiance += BaseColor * vector3(.15f, .15f, .165f);

        // Give the compiler a hint so it can unroll the loop and avoid attempting to
        // dynamically index the LightingEnvironment constants, which would force a local
        // memory spill.
        for (int i = 0; i < MAX_DIRECTIONAL_LIGHTS; ++i) {
            if (i >= env.directionalLightCount)
                break;

            radiance += DirectionalLightContribution(vInterp.pos, normal, V, BaseColor, roughness, F0,
                                                     env.directionalLights[i]);
        }

        for (int i = 0; i < MAX_POINT_LIGHTS; i++) {
            if (i >= env.pointLightCount)
                break;

            radiance += PointLightContribution(vInterp.pos, normal, V, BaseColor, roughness, F0, env.pointLights[i]);
        }

        for (int i = 0; i < MAX_SPOT_LIGHTS; ++i) {
            if (i >= env.spotLightCount)
                break;

            radiance += SpotLightContribution(vInterp.pos, normal, V, BaseColor, roughness, F0, env.spotLights[i]);
        }

        return vector4(max(radiance.x, 0.0f), max(radiance.y, 0.0f), max(radiance.z, 0.0f), 1.0f);
    }
}