He adaptado el ejemplo que aparece en el libro ShaderX2 sobre iluminación por pixel y proyectores.
(http://www.telefonica.net/web/haddd/proyector.jpg)
Iluminación por pixel, con specular con una textura que actua como un proyector. En teoría se coloca en la luz, se le da unos parámetros de apertura y listos.
Si os fijais, existe el problema de que si la pared está en el otro lado de la luz, el proyector también muestra la imagen invertida ( pared de la derecha). ¿alguien se ha topado con este problema?
Ese problema que tienes (back-projection) es algo normal cuando hablamos de proyección de texturas. Si no recuerdo mal, la solución más sencilla es ver si el fragmento actual está delante o detras del proyector.
Supongo que en el pixel shader tendrás algo como esto:
float4 proj_color = tex2Dproj(proj_texture, proj_texCoord);
que lo que hace es recoger el color de la textura que haya en la posición indicada por las coordenadas de textura resultantes de la proyección.
Pues bien, lo que harías es cambiar eso por:
float4 proj_color = proj_texCoord.w < 0.0f ? 0 : tex2Dproj(proj_texture, proj_texCoord);
O sea que si el fragmento está por detras del proyector (coseno del ángulo menor que cero), el color será cero mientras que si está delante pues recogemos el color de la textura.
Creo que con eso deberías poder solventar el problema.
Saludos
Una pregunta de pixel lammer: eso en los PS < 2.0 no se podia hacer, ¿no? Porque veo una sentencia condicional.. :ph34r:
Entonces las proyecciones del Doom III, si no usa PS 2.0, tendrán que ser cúbicas por narices ¿no? Edit: bueno o eso o no usa PS para las proyecciones que yo vi en la alpha.. que parecian texturas precalculadas <_< .. mmm no recuerdo
Iluminadme ;)
PD: Haddd muy chula la captura
Con el HLSL sí se pueden poner condiciones en los ps < 2.0. Acabo de crear un pixel shader con el RenderMonkey con el perfil para ps_1_1 y funciona perfectamente.
Y sí, Doom3 utiliza proyección de texturas para cosas como las sombras de los ventiladores, proyección de las rejillas de una ventana, etc.
Saludos.
Haddd, leete esto:
http://www.imm.dtu.dk/visiondag/VD03/grafi...lfgangEngel.pdfCreo que tiene un apartado que explica justamente tu problema.
Las sentencias condicionales el HLSL las traduce a unas cuantas sentencias de tipo max, min, abs, slt, setp... etc, para poder conseguier el efecto de control de flujo. Con sólo disponer de esas funciones puedes simular un "if".
Ahora mismo no recuerdo donde vi un ejemplo muy claro que lo mostraba pero se puede observar esto con el RenderMonkey.
De todas formas en la web de
Humus acaban de poner una demo sobre dynamic branching para shaders menores que 3.0 usando alpha test y stencil test que funciona igual o mejor que con 3.0. Es bastante curiosa la forma en la que usa un shader para hacer la comparación y descartar otro renderizado de otro shader :)
Gracias, muy interesante la idea del stencil para hacer branching... :D