Oldestkon написал(а):Гугли Fresnel Effect.
Грубо говоря, тебе нужно написать шейдер, который будет менять прозрачность пикселя в зависимости от нормали (в пространстве камеры).
Формула коэффициента прозрачности (или непрозрачности, непомню) для каждого пикселя будет уровня dotProduct(векторОтКамерыДоПикселя, векторНормали). Мб придется возвести в степень, поиграйся.
Вектора должны быть нормализованными.
Вектор нормали возьмешь из вершинного шейдера, он просчитается для нужного пикселя исходя из нормалей вершин сферы. Второй - это тупо координаты пикселя в пространстве (камеры).
Шейдер должен подключаться (glUseProgram) перед отрисовкой твоей сферы, и выключаться после. Загрузка находится быстрым гуглением (lwjgl shader loader).
Без шейдера...
Oldestkon написал(а):многабукав...
Хотя вроде были способы проще, мож кто подскажет, но я сходу не вспомню, а думать лень.
Oldestkon написал(а):Гугли Fresnel Effect.
Грубо говоря, тебе нужно написать шейдер, который будет менять прозрачность пикселя в зависимости от нормали (в пространстве камеры).
Формула коэффициента прозрачности (или непрозрачности, непомню) для каждого пикселя будет уровня dotProduct(векторОтКамерыДоПикселя, векторНормали). Мб придется возвести в степень, поиграйся.
Вектора должны быть нормализованными.
Вектор нормали возьмешь из вершинного шейдера, он просчитается для нужного пикселя исходя из нормалей вершин сферы. Второй - это тупо координаты пикселя в пространстве (камеры).
Шейдер должен подключаться (glUseProgram) перед отрисовкой твоей сферы, и выключаться после. Загрузка находится быстрым гуглением (lwjgl shader loader).
Без шейдера можно обойтись, скорее всего моделькой сферы у которой по краям текстура прозрачная, и которая всегда поворачивается "лицом" к игроку, но это будет выглядеть заметно хуже.
#version 120
varying vec3 position;
varying vec3 normal;
void main()
{
gl_Position = ftransform();
position = (gl_ModelViewMatrix * gl_Vertex).xyz;
normal = normalize(gl_NormalMatrix * gl_Normal);
}
#version 120
varying vec3 position;
varying vec3 normal;
void main()
{
vec4 rimColor = vec4(1.0, 1.0, 1.0, 1.0);
float scale = 1.0;
vec3 cameraPos = -position;
vec3 ray = normalize(position - cameraPos);
float refFactor = max(0.0, min(1.0, scale * pow(1.0 + dot(ray, normal), 1.4)));
gl_FragColor = mix(vec4(1.0, 1.0, 1.0, 0.0), rimColor, refFactor);
}
Спасибо и если не сложно, кинь всю свою репозиторию, где у тебя сам шейдер и т.п., хочу глянуть живой пример.nikita488 написал(а):Oldestkon написал(а):Гугли Fresnel Effect.
Грубо говоря, тебе нужно написать шейдер, который будет менять прозрачность пикселя в зависимости от нормали (в пространстве камеры).
Формула коэффициента прозрачности (или непрозрачности, непомню) для каждого пикселя будет уровня dotProduct(векторОтКамерыДоПикселя, векторНормали). Мб придется возвести в степень, поиграйся.
Вектора должны быть нормализованными.
Вектор нормали возьмешь из вершинного шейдера, он просчитается для нужного пикселя исходя из нормалей вершин сферы. Второй - это тупо координаты пикселя в пространстве (камеры).
Шейдер должен подключаться (glUseProgram) перед отрисовкой твоей сферы, и выключаться после. Загрузка находится быстрым гуглением (lwjgl shader loader).
Без шейдера можно обойтись, скорее всего моделькой сферы у которой по краям текстура прозрачная, и которая всегда поворачивается "лицом" к игроку, но это будет выглядеть заметно хуже.
Я короче погуглил, нашел ЭТО и тут даже есть готовый шейдер, но для Юнити. Я в шейдерах не силён, но вроде переписал, получилось так ->
Вершинный шейдер:
Фрагментный шейдер:Код:#version 120 varying vec3 position; varying vec3 normal; void main() { gl_Position = ftransform(); position = (gl_ModelViewMatrix * gl_Vertex).xyz; normal = normalize(gl_NormalMatrix * gl_Normal); }
Результат... ну, не очень, не так как на картиночке в статье:Код:#version 120 varying vec3 position; varying vec3 normal; void main() { vec4 rimColor = vec4(1.0, 1.0, 1.0, 1.0); float scale = 1.0; vec3 cameraPos = -position; vec3 ray = normalize(position - cameraPos); float refFactor = max(0.0, min(1.0, scale * pow(1.0 + dot(ray, normal), 1.4))); gl_FragColor = mix(vec4(1.0, 1.0, 1.0, 0.0), rimColor, refFactor); }
Oldestkon написал(а):В шейдере их просто так не найдешь, там либо координаты в пространстве модели, либо спроецированные на плоскость.
Тебе нужны мировые (model-matrix трансформация), топик-стартеру в пространстве камеры (modelview).
Надо отдельно передавать различные матрицы (модели-вида и проекции), чтобы получать координаты в нужном пространстве.
Для этого, к сожалению, скорее всего, ещё придется написать свой стек матриц.
Подробнее тут.
http://stackoverflow.com/questions/4899555/glsl-how-to-get-pixel-x-y-z-world-position
Хотя вроде были способы проще, мож кто подскажет, но я сходу не вспомню, а думать лень.
GlStateManager.loadIdentity();
EntityRenderer.setupCameraTransform(partialTicks, 0); //На самом деле нужна рефлексия, все дела
GlStateManager.getFloat(GL11.GL_MODELVIEW_MATRIX, viewMatrixBuffer);
GlStateManager.loadIdentity();
GlStateManager.translate(-interpPlayerPosX, 16 - interpPlayerPosY, -interpPlayerPosZ);
GlStateManager.getFloat(GL11.GL_MODELVIEW_MATRIX, modelMatrixBuffer);
CoomingSoon написал(а):>#version 120
в 2017
nikita488 написал(а):Там написано что нужно трансформировать камеру через glLoadIdentity()[font=Arial,], [/font]glTranslate(), а какие значения то в glTranslate? Я нашел в EntityRenderer метод setupCameraTransform и попробовал в RenderWorldLastEvent'е сделать типа так:
Код:GlStateManager.loadIdentity(); EntityRenderer.setupCameraTransform(partialTicks, 0); //На самом деле нужна рефлексия, все дела GlStateManager.getFloat(GL11.GL_MODELVIEW_MATRIX, viewMatrixBuffer);
Но если я после этого сбрасываю матрицу и трансформирую модель вот так:
Код:GlStateManager.loadIdentity(); GlStateManager.translate(-interpPlayerPosX, 16 - interpPlayerPosY, -interpPlayerPosZ); GlStateManager.getFloat(GL11.GL_MODELVIEW_MATRIX, modelMatrixBuffer);
То модель начинает двигаться в зависимости от моего положения.