/*
* Copyright 2013 MovingBlocks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.terasology.rendering.shader;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.terasology.utilities.Assets;
import org.terasology.math.geom.Vector3d;
import org.terasology.math.geom.Vector3f;
import org.terasology.math.geom.Vector4f;
import org.terasology.registry.CoreRegistry;
import org.terasology.rendering.assets.material.Material;
import org.terasology.rendering.backdrop.BackdropProvider;
import org.terasology.rendering.nui.properties.Range;
import org.terasology.world.WorldProvider;
/**
* Parameters for the sky shader program.
*
*/
public class ShaderParametersSky extends ShaderParametersBase {
@Range(min = 1.0f, max = 8192.0f)
private float sunExponent = 512.0f;
@Range(min = 1.0f, max = 8192.0f)
private float moonExponent = 256.0f;
@Range(min = 0.0f, max = 10.0f)
private float skyDaylightBrightness = 0.6f;
@Range(min = 0.0f, max = 10.0f)
private float skyNightBrightness = 1.0f;
public static Vector3d getAllWeatherZenith(float thetaSunAngle, float turbidity) {
float thetaSun = (float) Math.acos(thetaSunAngle);
Vector4f cx1 = new Vector4f(0.0f, 0.00209f, -0.00375f, 0.00165f);
Vector4f cx2 = new Vector4f(0.00394f, -0.03202f, 0.06377f, -0.02903f);
Vector4f cx3 = new Vector4f(0.25886f, 0.06052f, -0.21196f, 0.11693f);
Vector4f cy1 = new Vector4f(0.0f, 0.00317f, -0.00610f, 0.00275f);
Vector4f cy2 = new Vector4f(0.00516f, -0.04153f, 0.08970f, -0.04214f);
Vector4f cy3 = new Vector4f(0.26688f, 0.06670f, -0.26756f, 0.15346f);
float t2 = turbidity * turbidity;
float chi = (4.0f / 9.0f - turbidity / 120.0f) * ((float) Math.PI - 2.0f * thetaSun);
Vector4f theta = new Vector4f(1, thetaSun, thetaSun * thetaSun, thetaSun * thetaSun * thetaSun);
float why = (4.0453f * turbidity - 4.9710f) * (float) Math.tan(chi) - 0.2155f * turbidity + 2.4192f;
float x = t2 * cx1.dot(theta) + turbidity * cx2.dot(theta) + cx3.dot(theta);
float y = t2 * cy1.dot(theta) + turbidity * cy2.dot(theta) + cy3.dot(theta);
return new Vector3d(why, x, y);
}
@Override
public void applyParameters(Material program) {
super.applyParameters(program);
// TODO: move to node and/or material?
// TODO: take advantage of Texture.subscribeToDisposal(Runnable) to reobtain the asset only if necessary
int texId = 0;
GL13.glActiveTexture(GL13.GL_TEXTURE0 + texId);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, Assets.getTexture("engine:sky90").get().getId());
program.setInt("texSky90", texId++, true);
GL13.glActiveTexture(GL13.GL_TEXTURE0 + texId);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, Assets.getTexture("engine:sky180").get().getId());
program.setInt("texSky180", texId++, true);
BackdropProvider backdropProvider = CoreRegistry.get(BackdropProvider.class);
WorldProvider worldProvider = CoreRegistry.get(WorldProvider.class);
// TODO: move the rest to material?
if (worldProvider != null && backdropProvider != null) {
program.setFloat("colorExp", backdropProvider.getColorExp(), true);
Vector3f sunDirection = backdropProvider.getSunDirection(false);
Vector3d zenithColor = getAllWeatherZenith(sunDirection.y, backdropProvider.getTurbidity());
program.setFloat("sunAngle", backdropProvider.getSunPositionAngle(), true);
program.setFloat("turbidity", backdropProvider.getTurbidity(), true);
program.setFloat3("zenith", (float) zenithColor.x, (float) zenithColor.y, (float) zenithColor.z, true);
}
program.setFloat4("skySettings", sunExponent, moonExponent, skyDaylightBrightness, skyNightBrightness, true);
}
}