WWW.DOCX.LIB-I.RU
БЕСПЛАТНАЯ  ИНТЕРНЕТ  БИБЛИОТЕКА - Интернет материалы
 

«10.Моделирование рисования древесным углем Одной из характерных особенностей для изображений в этой технике является заметно увеличенная контрастность изображения. ...»

10.Моделирование рисования древесным углем

Одной из характерных особенностей для изображений в этой технике является заметно увеличенная контрастность изображения. Простейшим способом моделирования этого для изображений в оттенках серого цвета является преобразование интенсивности изображения по следующей формуле:

В этой формуле в качестве степени p используется величина, большая единицы. Типичным значением степени является 3.5.

Данное преобразование применяется к значению освещенности, полученной по формуле Фонга. В результате получается изображение с усиленным контрастом.

Полученная таким образом освещенность используется для индексирования в специальную текстуру, называемую Contrast Enhancement Texture. На следующем рисунке приводится пример такой текстуры.

Рис 3. Пример Contrast Enhancement Texture.

Наложением этой текстуры удается не только еще больше усилить контрастность, но и придать получившемуся изображению зернистость, характерную для рисунков углем по бумаге.

Однако, если t-координата для наложения СЕТ-текстуры задается явно как модифицированная освещенность, то какую величину следует взять в качестве первой текстурной координаты s ?

Если в качестве s для обращения к СЕТ взять одну из стандартных текстурных координат, связанных с изображаемым объектом, то это может привести к появлению заметных артефактов. Наиболее удобным было бы взять в качестве данной текстурной координаты случайное значение.

В качестве источника такого случайного значения удобно использовать дополнительную текстуру, значения цветовых компонент для которой были получены при помощи генератора псевдослучайных чисел.

Тогда, использовав обычные текстурные координаты для обращения к такой текстуре, на выходе мы получим фактически случайное значение цвета, одну из компонент которого можно использовать в качестве текстурной координаты s для обращения к СЕТ.

Еще одним характерным элементом рисунков углем является так называемое "размывание" (smuding), когда художник (обычно просто рукой) слегка размазывает уголь по бумаге для получения плавных полутонов.

Достаточно простым способом моделирования размывания является просто смешение (blending) текстурированного (при помощи СЕТ) изображения с нетекстурированным изображением с усиленной контрастностью.

Заключительным шагом является наложения рисунка на бумагу, которая задается при помощи отдельной текстуры, и также вносит свой вклад в получающееся изображения.

Данный алгоритм довольно легко реализуется при помощи шейдеров. При этом вершинный шейдер отвечает за вычисления освещенности в вершинах и преобразование ее для увеличения контраста.

Задачей фрагментного шейдера является наложение СЕТ, смешение текстурированной модели с нетекстурированной и наложения бумаги на получившееся значение.

Ниже приводятся листинги вершинного и фрагментного шейдеров на GLSL.

//

// Charcoal vertex shader//

uniform vec3 lightPos;

uniform vec3 eyePos;

varying vec3 color;

void main(void)

{

const vec3 ambient = vec3 ( 0.0 );

const vec3 diffuse = vec3 ( 1.0, 1.0, 1.0 );

const vec3 luminance = vec3 ( 0.3, 0.59, 0.11 );

vec3 p = vec3 ( gl_ModelViewMatrix * gl_Vertex );

vec3 l = normalize ( lightPos - p );

vec3 n = normalize ( gl_NormalMatrix * gl_Normal );

// compute illumination

color = ambient + diffuse * max ( dot ( n, l ), 0.0 );





// apply CEO

color = vec3 ( pow ( clamp ( dot ( color, luminance ), 0.0, 1.0 ), 3.5 ) );

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

gl_TexCoord [0] = gl_MultiTexCoord0;

}

//

// Charcoal fragment shader//

varying vec3 color;

uniform sampler2D randomTex;

uniform sampler2D cetTex;

uniform sampler2D paperTex;

void main (void)

{

vec4 random = texture2D ( randomTex, gl_TexCoord [0].xy );

vec3 contrast = texture2D ( cetTex, vec2 ( random.x, 1.0 - color.x ) ).rgb;

vec3 smudge = 0.5 * (contrast + color);

vec3 paper = texture2D ( paperTex, gl_FragCoord.xy / 512.0 ).rgb;

gl_FragColor.rgb = contrast + vec3 ( 1.0 ) - paper;

gl_FragColor.a = 1.0;

}

На следующем рисунке приводится изображение, построенное с использованием этих шейдеров.

Рис 4. Изображение в технике рисования углем по бумаге.

Для получения Contrast Enhancement Texture использовался простой скрипт на языке Python, приводимый на следующем листинге.

#

# Script to create contrast enhancement texture

#

import PIL, Image, random, math, ImageEnhance # basic parameters: bitmap size and contrast power

size = 512

contrastExp = 15

noiseDensity = 3.0

im = Image.new ( "RGB", (size, size) )

# fill it with white

for i in range (size):

for j in range (size):

im.putpixel ( (i,j), ( 255, 255, 255 ) )

numBlackPixels = int( noiseDensity * float(size) * float(size) )

for i in range ( numBlackPixels) :

x = random.random ()

y = random.random ()

# apply contrast enhansment y = math.pow ( y, contrastExp )

px = int(x*(size-1))

py = size - 1 - int(y*(size-1))

if py < 0:

py = 0

if py >= size:

py = size - 1

im.putpixel ( (px, py), (0, 0, 0))

sh = ImageEnhance.Sharpness ( im )

im2 = sh.enhance ( 0.2 )

im2.show ()

im2.save ( "cet.bmp", "bmp" )

Следующий скрипт используется для построения текстуры, состоящей из случайных значений.

#

# Script to random texture

#

import PIL, Image, random

# basic parameters: bitmap size

size = 256

im = Image.new ( "RGB", (size, size) )

for i in range (size):

for j in range (size):

r = int ( 255.0 * random.random () )

g = int ( 255.0 * random.random () )

b = int ( 255.0 * random.random () )

im.putpixel ( (i,j), ( r, g, b ) )

im.show ()

im.save ( "random.bmp", "bmp" )

10.1.Листинг программы для моделирования эффекта рисования углем

#include "libExt.h"

#include <glut.h>

#include <stdio.h>

#include <stdlib.h>

#include "libTexture.h"

#include "TypeDefs.h"

#include "Vector3D.h"

#include "Vector2D.h"

#include "GlslProgram.h"

Vector3D eye ( -0.5, -0.5, 1.5 ); // camera position

Vector3D light ( 5, 0, 4 ); // light position

unsigneddecalMap; // decal (diffuse) texture

unsigned stoneMap;

unsigned teapotMap;

unsigned randomMap;

unsigned cetMap;

unsigned paperMap;

Vector3D rot ( 0, 0, 0 );

float angle = 0;

int mouseOldX = 0;

int mouseOldY = 0;

bool useFilter = true;

GlslProgram program;

void startOrtho ()

{

glMatrixMode ( GL_PROJECTION ); // select the projection matrix

glPushMatrix (); // store the projection matrix

glLoadIdentity (); // reset the projection matrix

// set up an ortho screen

glOrtho ( 0, 512, 0, 512, -1, 1 );

glMatrixMode ( GL_MODELVIEW ); // select the modelview matrix

glPushMatrix (); // store the modelview matrix

glLoadIdentity (); // reset the modelview matrix

}

void endOrtho ()

{

glMatrixMode ( GL_PROJECTION ); // select the projection matrix

glPopMatrix (); // restore the old projection matrix

glMatrixMode ( GL_MODELVIEW ); // select the modelview matrix

glPopMatrix (); // restore the old projection matrix

}

void init ()

{

glClearColor ( 1.0, 1.0, 1.0, 1.0 );

glEnable ( GL_DEPTH_TEST );

glEnable ( GL_TEXTURE_2D );

glDepthFunc ( GL_LEQUAL );

glHint ( GL_POLYGON_SMOOTH_HINT, GL_NICEST );

glHint ( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );

}

void display ()

{

glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

startOrtho ();

glActiveTextureARB ( GL_TEXTURE1_ARB );

glDisable ( GL_TEXTURE_2D );

glActiveTextureARB ( GL_TEXTURE2_ARB );

glDisable ( GL_TEXTURE_2D );

glActiveTextureARB ( GL_TEXTURE0_ARB );

glBindTexture ( GL_TEXTURE_2D, paperMap );

glEnable ( GL_TEXTURE_2D );

glDepthMask ( GL_FALSE );

glColor4f ( 1, 1, 1, 1 );

glBegin ( GL_QUADS );

glTexCoord2f ( 0, 0 );

glVertex2f ( 0, 0 );

glTexCoord2f ( 1, 0 );

glVertex2f ( 511, 0 );

glTexCoord2f ( 1, 1 );

glVertex2f ( 511, 511 );

glTexCoord2f ( 0, 1 );

glVertex2f ( 0, 511 );

glEnd ();

endOrtho ();

glDepthMask ( GL_TRUE );

glActiveTextureARB ( GL_TEXTURE0_ARB );

glBindTexture ( GL_TEXTURE_2D, teapotMap );

glActiveTextureARB ( GL_TEXTURE1_ARB );

glBindTexture ( GL_TEXTURE_2D, randomMap );

glActiveTextureARB ( GL_TEXTURE2_ARB );

glBindTexture ( GL_TEXTURE_2D, cetMap );

glEnable ( GL_TEXTURE_2D );

glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,

GL_CLAMP_TO_EDGE );

glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,

GL_CLAMP_TO_EDGE );

glActiveTextureARB ( GL_TEXTURE3_ARB );

glBindTexture ( GL_TEXTURE_2D, paperMap );

glActiveTextureARB ( GL_TEXTURE0_ARB );

if ( useFilter )

program.bind ();

glMatrixMode ( GL_MODELVIEW );

glPushMatrix ();

glRotatef ( rot.x, 1, 0, 0 );

glRotatef ( rot.y, 0, 1, 0 );

glRotatef ( rot.z, 0, 0, 1 );

glutSolidTeapot ( 0.4 );

glPopMatrix ();

if ( useFilter )

program.unbind ();

glutSwapBuffers ();

}

void reshape ( int w, int h )

{

glViewport ( 0, 0, (GLsizei)w, (GLsizei)h );

glMatrixMode ( GL_PROJECTION );

glLoadIdentity ();

gluPerspective ( 60.0, (GLfloat)w/(GLfloat)h, 1.0, 60.0 );

glMatrixMode ( GL_MODELVIEW );

glLoadIdentity ();

gluLookAt ( eye.x, eye.y, eye.z, // eye

0, 0, 0, // center

0, 0, 1 ); // up

}

void key ( unsigned char key, int x, int y )

{

if ( key == 27 || key == 'q' || key == 'Q' ) // quit requested

exit ( 0 );

if ( key == 'f' || key == 'F' )

useFilter = !useFilter;

}

void animate ()

{

angle = 0.001f * glutGet ( GLUT_ELAPSED_TIME );

light.x = 2*cos ( angle );

light.y = 2*sin ( angle );

light.z = 3 + 0.3 * sin ( angle / 3 );

program.bind ();

program.setUniformVector ( "eyePos", eye );

program.setUniformVector ( "lightPos", light );

program.setUniformFloat ( "time", angle );

program.unbind ();

glutPostRedisplay ();

}

void motion ( int x, int y )

{

rot.y -= ((mouseOldY - y) * 180.0f) / 200.0f;

rot.z -= ((mouseOldX - x) * 180.0f) / 200.0f;

rot.x = 0;

if ( rot.z > 360 )

rot.z -= 360;

if ( rot.z < -360 )

rot.z += 360;

if ( rot.y > 360 )

rot.y -= 360;

if ( rot.y < -360 )

rot.y += 360;

mouseOldX = x;

mouseOldY = y;

glutPostRedisplay ();

}

void mouse ( int button, int state, int x, int y )

{

if ( state == GLUT_DOWN )

{

mouseOldX = x;

mouseOldY = y;

}

}

int main ( int argc, char * argv [] )

{

// initialize glut

glutInit ( &argc, argv );

glutInitDisplayMode ( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );

glutInitWindowSize ( 512, 512 );

// create window

glutCreateWindow ( "OpenGL charcoal effect" );

// register handlers

glutDisplayFunc ( display );

glutReshapeFunc ( reshape );

glutKeyboardFunc ( key );

glutMouseFunc ( mouse );

glutMotionFunc ( motion );

glutIdleFunc ( animate );

init ();

initExtensions ();

if ( !GlslProgram :: isSupported () )

{

printf ( "GLSL not supported.\n" );

return 1;

}

if ( !program.loadShaders ( "charcoal.vsh", "charcoal.fsh" ) )

{

printf ( "Error loading shaders:\n%s\n", program.getLog ().c_str () );

return 3;

}

decalMap = createTexture2D ( true, "../Textures/oak.bmp" );

stoneMap = createTexture2D ( true, "../Textures/block.bmp" );

teapotMap = createTexture2D ( true, "../Textures/Oxidated.jpg" );

randomMap = createTexture2D ( true, "random.bmp" );

cetMap = createTexture2D ( true, "cet.bmp" );

paperMap = createTexture2D ( true, "paper.dds" );

program.bind ();

program.setTexture ( "mainTex", 0 );

program.setTexture ( "randomTex", 1 );

program.setTexture ( "cetTex", 2 );

program.setTexture ( "paperTex", 3 );

program.unbind ();

printf ( "Render scene with charcoal effect\n" );

printf ( "Press F key to turn charcoal mode on/off\n" );

glutMainLoop ();

return 0;

}




Похожие работы:

«Упражнения на отработку HE IS Exercise 8 переведите предложение сделайте из него отрицательное предложение сделайте общий вопрос краткие ответы к нему альтернативный вопрос специальный вопрос1. Он студент.1.He is a student.2.He is not (isn’t) a student.3.Is he a student?4.Yes, he is. No,...»

«Johannesburg (1н) – Zimbabwe (2н) – Botswana (2н) Cape Town (3н) – Garden Route (2н) –Plettenberg (4н) (15 дней/14 ночей) 1 день Йоханнесбург 10:30Прибытие в международный аэропорт Йоханнесбурга, Южная Африка. Встреча представителем компании Трансфер в отель с англоговорящим водителем. Размещение в отеле Размещение Splice Riviera Hotel, 5*, B&B, 1...»

«Тема: Сигналы светофора и регулировщика. Применение авариной сигнализации и знака авариной остановки. Цель: Изучить основные сигналы светофоров, регулировщика, а так же в каких случаях применяется авариная сигнализация и знак авариной остановки....»

«25.10.2015г. "Оленетранспортные батальоны" В конце 1941 года для защиты северных рубежей Советского Союза на Карельском фронте поступил приказ сформировать оленетранспортные батальоны из числа местных жителей. К концу января 1942 года батальоны были сформированы. Своим ходом...»

«ABS 6 месяцев или 10 000 км пробега Ae Межсервисный ресурс, согласно рекомендациям автопроизводителя для данного автомобиля Airtex 3 месяца или 5 000 км при установке одного компонента (радиатор, водяной насос,...»

«Департамент природно-ресурсного регулирования, лесных отношений и развития нефтегазового комплекса Ямало-Ненецкого автономного округа, 629008, г. Салехард, ул. Матросова, д. 29, тел. (34922) 4-11-41, телефакс (34922) 4-11-41, в лице и.о. директора департамента...»

«Бинарный урок английского языка и географии: "Климат, внутренние воды, природные зоны Австралии. Climate, waters, natural zones of Australia" 7 класс. Цель: Ученик научится выделять особенности природы материка               Австралия через работу с картами, учебником и другими               источниками географической информации; научи...»







 
2017 www.docx.lib-i.ru - «Бесплатная электронная библиотека - интернет материалы»

Материалы этого сайта размещены для ознакомления, все права принадлежат их авторам.
Если Вы не согласны с тем, что Ваш материал размещён на этом сайте, пожалуйста, напишите нам, мы в течении 1-2 рабочих дней удалим его.